diff --git a/PR_DESCRIPTION.md b/PR_DESCRIPTION.md new file mode 100644 index 0000000..ec44ee2 --- /dev/null +++ b/PR_DESCRIPTION.md @@ -0,0 +1,178 @@ +# Pull Request: feat: add preset system and microphone input for screen recording + +**Base:** `siddharthvaddem/openscreen:main` +**Head:** `julianromli/openscreen:feature/microphone-input` + +--- + +## Description + +This PR introduces two major features to enhance the screen recording experience: + +1. **Preset System** - Save, load, and manage video styling configurations with one-click application +2. **Microphone Input** - Record voice narration alongside screen capture with real-time audio level monitoring + +## Motivation + +### Preset System +Currently, users must manually reconfigure padding, shadow, rounded corners, background, and other styling settings every time they open a new video. This is repetitive and time-consuming. The preset system allows users to save their preferred styles and apply them instantly. + +### Microphone Input +Users often need to add voice narration to their screen recordings for tutorials, demos, or explanations. This feature adds native microphone support with device selection, real-time level meters, and seamless audio merging into the final video export. + +## Type of Change +- [x] New Feature +- [ ] Bug Fix +- [ ] Refactor / Code Cleanup +- [ ] Documentation Update +- [ ] Other (please specify) + +## Related Issue(s) + +N/A (Feature development from design docs) + +## Features Overview + +### 🎨 Preset System + +| Feature | Description | +|---------|-------------| +| Save Presets | Save current styling settings (padding, shadow, border radius, blur, wallpaper) as named presets | +| Load Presets | One-click application of saved presets | +| Default Preset | Set a preset as default to auto-apply on new videos | +| Preset Management | Rename, duplicate, delete, and manage presets via dropdown menu | +| Persistent Storage | Presets saved to Electron Store (survives app restarts) | + +**Settings included in presets:** +- Padding (0-100%) +- Shadow Intensity (0-1) +- Border Radius (0-16px) +- Motion Blur (on/off) +- Show Blur (on/off) +- Wallpaper (image/color/gradient) + +### 🎤 Microphone Input + +| Feature | Description | +|---------|-------------| +| Device Selection | Choose from available microphone devices | +| Real-time Level Meter | Visual audio level indicator | +| Mute Toggle | Quick mute/unmute control | +| Audio Merging | Audio track merged directly into WebM/MP4 output | +| State Persistence | Selected device and preferences saved across sessions | +| Separate Settings Window | Dedicated mic settings window for advanced configuration | +| Cross-window Sync | Settings synchronized between HUD and settings window | + +**Error Handling:** +- Graceful fallback when no microphone detected +- Permission denial handling with user guidance +- Mid-recording disconnection handling +- Auto-reconnect support + +## Screenshots / Video + +> Screenshots and video demos can be added by reviewers during testing. + +**Preset System UI:** +- Preset dropdown in Settings Panel (top of video editor) +- Save Preset modal with name input and default checkbox + +**Microphone UI:** +- Mic toggle button in HUD bar +- Device selection dropdown with level meter +- Separate mic settings window for advanced config + +## Testing + +### Prerequisites +```bash +bun install +bun run dev +``` + +### Test Preset System +1. Open the app and load a video in the editor +2. Adjust styling settings (padding, shadow, border radius, wallpaper) +3. Click "Save" button next to preset dropdown +4. Enter a name and optionally set as default +5. Verify preset appears in dropdown +6. Change settings, then select saved preset → Settings should restore +7. Close and reopen app → Default preset should auto-apply + +### Test Microphone Input +1. Click mic icon in HUD bar +2. Grant microphone permission if prompted +3. Verify device list populates (if microphones available) +4. Select a device → Level meter should respond to audio +5. Start recording with mic enabled +6. Stop recording → Export video +7. Verify exported video contains audio track + +### Test Cross-window Sync +1. Toggle mic on in HUD +2. Open mic settings window (gear icon) +3. Change device in settings window +4. Verify HUD reflects the change +5. Close settings window → Verify state persists + +## Technical Details + +### New Files (12 files) +| File | Purpose | +|------|---------| +| `src/components/video-editor/PresetSelector.tsx` | Preset dropdown component | +| `src/components/video-editor/SavePresetModal.tsx` | Save preset dialog | +| `src/hooks/usePresets.ts` | Preset state management hook | +| `electron/ipc/presets.ts` | Electron-side preset file operations | +| `src/hooks/useMicrophone.ts` | Mic device management & level meter | +| `src/hooks/useMicrophone.test.ts` | Unit tests for mic hook | +| `src/components/launch/MicrophoneSelector.tsx` | Device selection dropdown UI | +| `src/components/launch/MicrophoneSettingsPage.tsx` | Dedicated settings window | +| `src/stores/audioSettings.ts` | Audio preferences Zustand store | +| `src/stores/audioSettings.test.ts` | Unit tests for audio store | +| `src/lib/exporter/audioExtractor.ts` | Audio extraction utilities | +| `docs/plans/*.md` | Design documentation for both features | + +### Modified Files (8 files) +| File | Changes | +|------|---------| +| `electron/preload.ts` | Exposed preset & audio APIs to renderer | +| `electron/ipc/handlers.ts` | Added IPC handlers for mic settings window | +| `electron/windows.ts` | Added mic settings window creation & management | +| `electron/electron-env.d.ts` | Added type definitions for new APIs | +| `src/hooks/useScreenRecorder.ts` | Added audio stream combining support | +| `src/components/launch/LaunchWindow.tsx` | Integrated mic toggle in HUD | +| `src/components/video-editor/SettingsPanel.tsx` | Added preset selector at top | +| `src/components/video-editor/VideoEditor.tsx` | Added default preset loading on mount | +| `src/lib/exporter/videoExporter.ts` | Added audio track support for export | + +### Commits Summary (19 commits) +``` +feat: add preset system for saving and loading video styling configurations +docs: add preset feature design document +docs: add microphone input feature design document +feat(audio): add useMicrophone hook with TDD tests +feat(audio): add audioSettings store for mic preferences persistence +feat(ui): add MicrophoneSelector dropdown component +feat(audio): add audio stream support to useScreenRecorder +feat(ui): integrate MicrophoneSelector into LaunchWindow HUD +feat(audio): add track-ended handler for mid-use disconnection +feat(audio): add advanced audio settings for recording and export +feat(export): add audio track support to video export +feat(audio): implement separate mic settings window with cross-window sync +fix(audio): restore mic state in HUD window from saved settings +fix(audio): ensure all settings saved before closing mic settings window +fix(audio): prevent race conditions and ensure cleanup on window close ++ UI fixes for dropdown clipping issues +``` + +## Checklist +- [x] I have performed a self-review of my code. +- [x] I have added any necessary screenshots or videos. +- [x] I have linked related issue(s) and updated the changelog if applicable. +- [x] Added design documentation for both features +- [x] Added unit tests for core functionality +- [x] Tested on Windows (manual testing) + +--- +*Thank you for contributing!* diff --git a/bun.lock b/bun.lock new file mode 100644 index 0000000..5be7ebf --- /dev/null +++ b/bun.lock @@ -0,0 +1,2127 @@ +{ + "lockfileVersion": 1, + "configVersion": 0, + "workspaces": { + "": { + "name": "openscreen", + "dependencies": { + "@fix-webm-duration/fix": "^1.0.1", + "@pixi/filter-drop-shadow": "^5.2.0", + "@radix-ui/react-dialog": "^1.1.15", + "@radix-ui/react-dropdown-menu": "^2.1.16", + "@radix-ui/react-popover": "^1.1.15", + "@radix-ui/react-select": "^2.2.6", + "@radix-ui/react-slider": "^1.3.6", + "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-switch": "^1.2.6", + "@radix-ui/react-tabs": "^1.1.13", + "@radix-ui/react-toggle": "^1.1.10", + "@radix-ui/react-toggle-group": "^1.1.11", + "@types/gif.js": "^0.2.5", + "@uiw/color-convert": "^2.9.2", + "@uiw/react-color-block": "^2.9.2", + "assemblyai": "^4.22.1", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "dnd-timeline": "^2.2.0", + "emoji-picker-react": "^4.16.1", + "fix-webm-duration": "^1.0.6", + "gif.js": "^0.2.0", + "gsap": "^3.13.0", + "lucide-react": "^0.545.0", + "mediabunny": "^1.25.1", + "motion": "^12.23.24", + "mp4box": "^2.2.0", + "pixi.js": "^8.14.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-icons": "^5.5.0", + "react-resizable-panels": "^3.0.6", + "react-rnd": "^10.5.2", + "sonner": "^2.0.7", + "tailwind-merge": "^3.3.1", + "tailwindcss-animate": "^1.0.7", + "uuid": "^13.0.0", + }, + "devDependencies": { + "@types/node": "^25.0.3", + "@types/react": "^18.2.64", + "@types/react-dom": "^18.2.21", + "@types/uuid": "^10.0.0", + "@typescript-eslint/eslint-plugin": "^7.1.1", + "@typescript-eslint/parser": "^7.1.1", + "@vitejs/plugin-react": "^4.2.1", + "autoprefixer": "^10.4.21", + "electron": "^39.2.7", + "electron-builder": "^24.13.3", + "electron-icon-builder": "^2.0.1", + "electron-rebuild": "^3.2.9", + "eslint": "^8.57.0", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.5", + "fast-check": "^4.5.2", + "postcss": "^8.5.6", + "tailwindcss": "^3.4.18", + "terser": "^5.44.1", + "typescript": "^5.2.2", + "vite": "^5.1.6", + "vite-plugin-electron": "^0.28.6", + "vite-plugin-electron-renderer": "^0.14.5", + "vitest": "^4.0.16", + }, + }, + }, + "packages": { + "7zip-bin": ["7zip-bin@5.2.0", "", {}, "sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A=="], + + "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="], + + "@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="], + + "@babel/compat-data": ["@babel/compat-data@7.28.4", "", {}, "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw=="], + + "@babel/core": ["@babel/core@7.28.4", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.4", "@babel/parser": "^7.28.4", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.4", "@babel/types": "^7.28.4", "@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" } }, "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA=="], + + "@babel/generator": ["@babel/generator@7.28.3", "", { "dependencies": { "@babel/parser": "^7.28.3", "@babel/types": "^7.28.2", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw=="], + + "@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.27.2", "", { "dependencies": { "@babel/compat-data": "^7.27.2", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ=="], + + "@babel/helper-globals": ["@babel/helper-globals@7.28.0", "", {}, "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw=="], + + "@babel/helper-module-imports": ["@babel/helper-module-imports@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w=="], + + "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw=="], + + "@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.27.1", "", {}, "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw=="], + + "@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="], + + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.27.1", "", {}, "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow=="], + + "@babel/helper-validator-option": ["@babel/helper-validator-option@7.27.1", "", {}, "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg=="], + + "@babel/helpers": ["@babel/helpers@7.28.4", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/types": "^7.28.4" } }, "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w=="], + + "@babel/parser": ["@babel/parser@7.28.4", "", { "dependencies": { "@babel/types": "^7.28.4" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg=="], + + "@babel/plugin-transform-react-jsx-self": ["@babel/plugin-transform-react-jsx-self@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw=="], + + "@babel/plugin-transform-react-jsx-source": ["@babel/plugin-transform-react-jsx-source@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw=="], + + "@babel/runtime": ["@babel/runtime@7.28.4", "", {}, "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ=="], + + "@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "@babel/traverse": ["@babel/traverse@7.28.4", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.4", "@babel/template": "^7.27.2", "@babel/types": "^7.28.4", "debug": "^4.3.1" } }, "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ=="], + + "@babel/types": ["@babel/types@7.28.4", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q=="], + + "@develar/schema-utils": ["@develar/schema-utils@2.6.5", "", { "dependencies": { "ajv": "^6.12.0", "ajv-keywords": "^3.4.1" } }, "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig=="], + + "@dnd-kit/accessibility": ["@dnd-kit/accessibility@3.1.1", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw=="], + + "@dnd-kit/core": ["@dnd-kit/core@6.3.1", "", { "dependencies": { "@dnd-kit/accessibility": "^3.1.1", "@dnd-kit/utilities": "^3.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ=="], + + "@dnd-kit/utilities": ["@dnd-kit/utilities@3.2.2", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg=="], + + "@electron/asar": ["@electron/asar@3.4.1", "", { "dependencies": { "commander": "^5.0.0", "glob": "^7.1.6", "minimatch": "^3.0.4" }, "bin": { "asar": "bin/asar.js" } }, "sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA=="], + + "@electron/get": ["@electron/get@2.0.3", "", { "dependencies": { "debug": "^4.1.1", "env-paths": "^2.2.0", "fs-extra": "^8.1.0", "got": "^11.8.5", "progress": "^2.0.3", "semver": "^6.2.0", "sumchecker": "^3.0.1" }, "optionalDependencies": { "global-agent": "^3.0.0" } }, "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ=="], + + "@electron/notarize": ["@electron/notarize@2.2.1", "", { "dependencies": { "debug": "^4.1.1", "fs-extra": "^9.0.1", "promise-retry": "^2.0.1" } }, "sha512-aL+bFMIkpR0cmmj5Zgy0LMKEpgy43/hw5zadEArgmAMWWlKc5buwFvFT9G/o/YJkvXAJm5q3iuTuLaiaXW39sg=="], + + "@electron/osx-sign": ["@electron/osx-sign@1.0.5", "", { "dependencies": { "compare-version": "^0.1.2", "debug": "^4.3.4", "fs-extra": "^10.0.0", "isbinaryfile": "^4.0.8", "minimist": "^1.2.6", "plist": "^3.0.5" }, "bin": { "electron-osx-flat": "bin/electron-osx-flat.js", "electron-osx-sign": "bin/electron-osx-sign.js" } }, "sha512-k9ZzUQtamSoweGQDV2jILiRIHUu7lYlJ3c6IEmjv1hC17rclE+eb9U+f6UFlOOETo0JzY1HNlXy4YOlCvl+Lww=="], + + "@electron/universal": ["@electron/universal@1.5.1", "", { "dependencies": { "@electron/asar": "^3.2.1", "@malept/cross-spawn-promise": "^1.1.0", "debug": "^4.3.1", "dir-compare": "^3.0.0", "fs-extra": "^9.0.1", "minimatch": "^3.0.4", "plist": "^3.0.4" } }, "sha512-kbgXxyEauPJiQQUNG2VgUeyfQNFk6hBF11ISN2PNI6agUgPl55pv4eQmaqHzTAzchBvqZ2tQuRVaPStGf0mxGw=="], + + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="], + + "@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "", { "os": "android", "cpu": "arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="], + + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.21.5", "", { "os": "android", "cpu": "arm64" }, "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A=="], + + "@esbuild/android-x64": ["@esbuild/android-x64@0.21.5", "", { "os": "android", "cpu": "x64" }, "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA=="], + + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.21.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ=="], + + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.21.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw=="], + + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.21.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g=="], + + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.21.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ=="], + + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.21.5", "", { "os": "linux", "cpu": "arm" }, "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA=="], + + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.21.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q=="], + + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.21.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg=="], + + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg=="], + + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg=="], + + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.21.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w=="], + + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA=="], + + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.21.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A=="], + + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.21.5", "", { "os": "linux", "cpu": "x64" }, "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ=="], + + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.2", "", { "os": "none", "cpu": "arm64" }, "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw=="], + + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.21.5", "", { "os": "none", "cpu": "x64" }, "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg=="], + + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA=="], + + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.21.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow=="], + + "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.2", "", { "os": "none", "cpu": "arm64" }, "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag=="], + + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.21.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg=="], + + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.21.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A=="], + + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.21.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA=="], + + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="], + + "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g=="], + + "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="], + + "@eslint/eslintrc": ["@eslint/eslintrc@2.1.4", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ=="], + + "@eslint/js": ["@eslint/js@8.57.1", "", {}, "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q=="], + + "@fix-webm-duration/fix": ["@fix-webm-duration/fix@1.0.1", "", { "dependencies": { "@fix-webm-duration/parser": "1.0.1", "tslib": "^2.3.0" } }, "sha512-rRN4CpWQaXRbCXYqKIxnsUq8OSWSGq/SVlnxxkx0HxMZZ1u0qnB24P766o8QS5YaMMqAOFAzmsMmfZ2OWucOLQ=="], + + "@fix-webm-duration/parser": ["@fix-webm-duration/parser@1.0.1", "", { "dependencies": { "tslib": "^2.3.0" } }, "sha512-Z6el7ohBBpym4iOmxDxumN715cHzLcAbtOtYfIbvoyToVtAuxvHt3ELXGff83iAXEU1Yj7g+obQBdiKJYVhbWw=="], + + "@floating-ui/core": ["@floating-ui/core@1.7.3", "", { "dependencies": { "@floating-ui/utils": "^0.2.10" } }, "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w=="], + + "@floating-ui/dom": ["@floating-ui/dom@1.7.4", "", { "dependencies": { "@floating-ui/core": "^1.7.3", "@floating-ui/utils": "^0.2.10" } }, "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA=="], + + "@floating-ui/react-dom": ["@floating-ui/react-dom@2.1.6", "", { "dependencies": { "@floating-ui/dom": "^1.7.4" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw=="], + + "@floating-ui/utils": ["@floating-ui/utils@0.2.10", "", {}, "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="], + + "@gar/promisify": ["@gar/promisify@1.1.3", "", {}, "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw=="], + + "@humanwhocodes/config-array": ["@humanwhocodes/config-array@0.13.0", "", { "dependencies": { "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", "minimatch": "^3.0.5" } }, "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw=="], + + "@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="], + + "@humanwhocodes/object-schema": ["@humanwhocodes/object-schema@2.0.3", "", {}, "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA=="], + + "@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="], + + "@jimp/bmp": ["@jimp/bmp@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13", "bmp-js": "^0.1.0" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "sha512-9edAxu7N2FX7vzkdl5Jo1BbACfycUtBQX+XBMcHA2bk62P8R0otgkHg798frgAk/WxQIzwxqOH6wMiCwrlAzdQ=="], + + "@jimp/core": ["@jimp/core@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13", "any-base": "^1.1.0", "buffer": "^5.2.0", "exif-parser": "^0.1.12", "file-type": "^16.5.4", "load-bmfont": "^1.3.1", "mkdirp": "^0.5.1", "phin": "^2.9.1", "pixelmatch": "^4.0.2", "tinycolor2": "^1.4.1" } }, "sha512-qXpA1tzTnlkTku9yqtuRtS/wVntvE6f3m3GNxdTdtmc+O+Wcg9Xo2ABPMh7Nc0AHbMKzwvwgB2JnjZmlmJEObg=="], + + "@jimp/custom": ["@jimp/custom@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/core": "^0.16.13" } }, "sha512-LTATglVUPGkPf15zX1wTMlZ0+AU7cGEGF6ekVF1crA8eHUWsGjrYTB+Ht4E3HTrCok8weQG+K01rJndCp/l4XA=="], + + "@jimp/gif": ["@jimp/gif@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13", "gifwrap": "^0.9.2", "omggif": "^1.0.9" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "sha512-yFAMZGv3o+YcjXilMWWwS/bv1iSqykFahFMSO169uVMtfQVfa90kt4/kDwrXNR6Q9i6VHpFiGZMlF2UnHClBvg=="], + + "@jimp/jpeg": ["@jimp/jpeg@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13", "jpeg-js": "^0.4.2" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "sha512-BJHlDxzTlCqP2ThqP8J0eDrbBfod7npWCbJAcfkKqdQuFk0zBPaZ6KKaQKyKxmWJ87Z6ohANZoMKEbtvrwz1AA=="], + + "@jimp/plugin-blit": ["@jimp/plugin-blit@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "sha512-8Z1k96ZFxlhK2bgrY1JNWNwvaBeI/bciLM0yDOni2+aZwfIIiC7Y6PeWHTAvjHNjphz+XCt01WQmOYWCn0ML6g=="], + + "@jimp/plugin-blur": ["@jimp/plugin-blur@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "sha512-PvLrfa8vkej3qinlebyhLpksJgCF5aiysDMSVhOZqwH5nQLLtDE9WYbnsofGw4r0VVpyw3H/ANCIzYTyCtP9Cg=="], + + "@jimp/plugin-circle": ["@jimp/plugin-circle@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "sha512-RNave7EFgZrb5V5EpdvJGAEHMnDAJuwv05hKscNfIYxf0kR3KhViBTDy+MoTnMlIvaKFULfwIgaZWzyhuINMzA=="], + + "@jimp/plugin-color": ["@jimp/plugin-color@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13", "tinycolor2": "^1.4.1" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "sha512-xW+9BtEvoIkkH/Wde9ql4nAFbYLkVINhpgAE7VcBUsuuB34WUbcBl/taOuUYQrPEFQJ4jfXiAJZ2H/rvKjCVnQ=="], + + "@jimp/plugin-contain": ["@jimp/plugin-contain@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13" }, "peerDependencies": { "@jimp/custom": ">=0.3.5", "@jimp/plugin-blit": ">=0.3.5", "@jimp/plugin-resize": ">=0.3.5", "@jimp/plugin-scale": ">=0.3.5" } }, "sha512-QayTXw4tXMwU6q6acNTQrTTFTXpNRBe+MgTGMDU0lk+23PjlFCO/9sacflelG8lsp7vNHhAxFeHptDMAksEYzg=="], + + "@jimp/plugin-cover": ["@jimp/plugin-cover@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13" }, "peerDependencies": { "@jimp/custom": ">=0.3.5", "@jimp/plugin-crop": ">=0.3.5", "@jimp/plugin-resize": ">=0.3.5", "@jimp/plugin-scale": ">=0.3.5" } }, "sha512-BSsP71GTNaqWRcvkbWuIVH+zK7b3TSNebbhDkFK0fVaUTzHuKMS/mgY4hDZIEVt7Rf5FjadAYtsujHN9w0iSYA=="], + + "@jimp/plugin-crop": ["@jimp/plugin-crop@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "sha512-WEl2tPVYwzYL8OKme6Go2xqiWgKsgxlMwyHabdAU4tXaRwOCnOI7v4021gCcBb9zn/oWwguHuKHmK30Fw2Z/PA=="], + + "@jimp/plugin-displace": ["@jimp/plugin-displace@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "sha512-qt9WKq8vWrcjySa9DyQ0x/RBMHQeiVjdVSY1SJsMjssPUf0pS74qorcuAkGi89biN3YoGUgPkpqECnAWnYwgGA=="], + + "@jimp/plugin-dither": ["@jimp/plugin-dither@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "sha512-5/N3yJggbWQTlGZHQYJPmQXEwR52qaXjEzkp1yRBbtdaekXE3BG/suo0fqeoV/csf8ooI78sJzYmIrxNoWVtgQ=="], + + "@jimp/plugin-fisheye": ["@jimp/plugin-fisheye@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "sha512-2rZmTdFbT/cF9lEZIkXCYO0TsT114Q27AX5IAo0Sju6jVQbvIk1dFUTnwLDadTo8wkJlFzGqMQ24Cs8cHWOliA=="], + + "@jimp/plugin-flip": ["@jimp/plugin-flip@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13" }, "peerDependencies": { "@jimp/custom": ">=0.3.5", "@jimp/plugin-rotate": ">=0.3.5" } }, "sha512-EmcgAA74FTc5u7Z+hUO/sRjWwfPPLuOQP5O64x5g4j0T12Bd29IgsYZxoutZo/rb3579+JNa/3wsSEmyVv1EpA=="], + + "@jimp/plugin-gaussian": ["@jimp/plugin-gaussian@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "sha512-A1XKfGQD0iDdIiKqFYi8nZMv4dDVYdxbrmgR7y/CzUHhSYdcmoljLIIsZZM3Iks/Wa353W3vtvkWLuDbQbch1w=="], + + "@jimp/plugin-invert": ["@jimp/plugin-invert@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "sha512-xFMrIn7czEZbdbMzZWuaZFnlLGJDVJ82y5vlsKsXRTG2kcxRsMPXvZRWHV57nSs1YFsNqXSbrC8B98n0E32njQ=="], + + "@jimp/plugin-mask": ["@jimp/plugin-mask@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "sha512-wLRYKVBXql2GAYgt6FkTnCfE+q5NomM7Dlh0oIPGAoMBWDyTx0eYutRK6PlUrRK2yMHuroAJCglICTbxqGzowQ=="], + + "@jimp/plugin-normalize": ["@jimp/plugin-normalize@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "sha512-3tfad0n9soRna4IfW9NzQdQ2Z3ijkmo21DREHbE6CGcMIxOSvfRdSvf1qQPApxjTSo8LTU4MCi/fidx/NZ0GqQ=="], + + "@jimp/plugin-print": ["@jimp/plugin-print@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13", "load-bmfont": "^1.4.0" }, "peerDependencies": { "@jimp/custom": ">=0.3.5", "@jimp/plugin-blit": ">=0.3.5" } }, "sha512-0m6i3p01PGRkGAK9r53hDYrkyMq+tlhLOIbsSTmZyh6HLshUKlTB7eXskF5OpVd5ZUHoltlNc6R+ggvKIzxRFw=="], + + "@jimp/plugin-resize": ["@jimp/plugin-resize@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "sha512-qoqtN8LDknm3fJm9nuPygJv30O3vGhSBD2TxrsCnhtOsxKAqVPJtFVdGd/qVuZ8nqQANQmTlfqTiK9mVWQ7MiQ=="], + + "@jimp/plugin-rotate": ["@jimp/plugin-rotate@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13" }, "peerDependencies": { "@jimp/custom": ">=0.3.5", "@jimp/plugin-blit": ">=0.3.5", "@jimp/plugin-crop": ">=0.3.5", "@jimp/plugin-resize": ">=0.3.5" } }, "sha512-Ev+Jjmj1nHYw897z9C3R9dYsPv7S2/nxdgfFb/h8hOwK0Ovd1k/+yYS46A0uj/JCKK0pQk8wOslYBkPwdnLorw=="], + + "@jimp/plugin-scale": ["@jimp/plugin-scale@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13" }, "peerDependencies": { "@jimp/custom": ">=0.3.5", "@jimp/plugin-resize": ">=0.3.5" } }, "sha512-05POQaEJVucjTiSGMoH68ZiELc7QqpIpuQlZ2JBbhCV+WCbPFUBcGSmE7w4Jd0E2GvCho/NoMODLwgcVGQA97A=="], + + "@jimp/plugin-shadow": ["@jimp/plugin-shadow@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13" }, "peerDependencies": { "@jimp/custom": ">=0.3.5", "@jimp/plugin-blur": ">=0.3.5", "@jimp/plugin-resize": ">=0.3.5" } }, "sha512-nmu5VSZ9hsB1JchTKhnnCY+paRBnwzSyK5fhkhtQHHoFD5ArBQ/5wU8y6tCr7k/GQhhGq1OrixsECeMjPoc8Zw=="], + + "@jimp/plugin-threshold": ["@jimp/plugin-threshold@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13" }, "peerDependencies": { "@jimp/custom": ">=0.3.5", "@jimp/plugin-color": ">=0.8.0", "@jimp/plugin-resize": ">=0.8.0" } }, "sha512-+3zArBH0OE3Rhjm4HyAokMsZlIq5gpQec33CncyoSwxtRBM2WAhUVmCUKuBo+Lr/2/4ISoY4BWpHKhMLDix6cA=="], + + "@jimp/plugins": ["@jimp/plugins@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/plugin-blit": "^0.16.13", "@jimp/plugin-blur": "^0.16.13", "@jimp/plugin-circle": "^0.16.13", "@jimp/plugin-color": "^0.16.13", "@jimp/plugin-contain": "^0.16.13", "@jimp/plugin-cover": "^0.16.13", "@jimp/plugin-crop": "^0.16.13", "@jimp/plugin-displace": "^0.16.13", "@jimp/plugin-dither": "^0.16.13", "@jimp/plugin-fisheye": "^0.16.13", "@jimp/plugin-flip": "^0.16.13", "@jimp/plugin-gaussian": "^0.16.13", "@jimp/plugin-invert": "^0.16.13", "@jimp/plugin-mask": "^0.16.13", "@jimp/plugin-normalize": "^0.16.13", "@jimp/plugin-print": "^0.16.13", "@jimp/plugin-resize": "^0.16.13", "@jimp/plugin-rotate": "^0.16.13", "@jimp/plugin-scale": "^0.16.13", "@jimp/plugin-shadow": "^0.16.13", "@jimp/plugin-threshold": "^0.16.13", "timm": "^1.6.1" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "sha512-CJLdqODEhEVs4MgWCxpWL5l95sCBlkuSLz65cxEm56X5akIsn4LOlwnKoSEZioYcZUBvHhCheH67AyPTudfnQQ=="], + + "@jimp/png": ["@jimp/png@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/utils": "^0.16.13", "pngjs": "^3.3.3" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "sha512-8cGqINvbWJf1G0Her9zbq9I80roEX0A+U45xFby3tDWfzn+Zz8XKDF1Nv9VUwVx0N3zpcG1RPs9hfheG4Cq2kg=="], + + "@jimp/tiff": ["@jimp/tiff@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "utif": "^2.0.1" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "sha512-oJY8d9u95SwW00VPHuCNxPap6Q1+E/xM5QThb9Hu+P6EGuu6lIeLaNBMmFZyblwFbwrH+WBOZlvIzDhi4Dm/6Q=="], + + "@jimp/types": ["@jimp/types@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/bmp": "^0.16.13", "@jimp/gif": "^0.16.13", "@jimp/jpeg": "^0.16.13", "@jimp/png": "^0.16.13", "@jimp/tiff": "^0.16.13", "timm": "^1.6.1" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "sha512-mC0yVNUobFDjoYLg4hoUwzMKgNlxynzwt3cDXzumGvRJ7Kb8qQGOWJQjQFo5OxmGExqzPphkirdbBF88RVLBCg=="], + + "@jimp/utils": ["@jimp/utils@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "regenerator-runtime": "^0.13.3" } }, "sha512-VyCpkZzFTHXtKgVO35iKN0sYR10psGpV6SkcSeV4oF7eSYlR8Bl6aQLCzVeFjvESF7mxTmIiI3/XrMobVrtxDA=="], + + "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], + + "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], + + "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], + + "@jridgewell/source-map": ["@jridgewell/source-map@0.3.11", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" } }, "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA=="], + + "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], + + "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], + + "@malept/cross-spawn-promise": ["@malept/cross-spawn-promise@2.0.0", "", { "dependencies": { "cross-spawn": "^7.0.1" } }, "sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg=="], + + "@malept/flatpak-bundler": ["@malept/flatpak-bundler@0.4.0", "", { "dependencies": { "debug": "^4.1.1", "fs-extra": "^9.0.0", "lodash": "^4.17.15", "tmp-promise": "^3.0.2" } }, "sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q=="], + + "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], + + "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], + + "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], + + "@npmcli/fs": ["@npmcli/fs@2.1.2", "", { "dependencies": { "@gar/promisify": "^1.1.3", "semver": "^7.3.5" } }, "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ=="], + + "@npmcli/move-file": ["@npmcli/move-file@2.0.1", "", { "dependencies": { "mkdirp": "^1.0.4", "rimraf": "^3.0.2" } }, "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ=="], + + "@pixi/color": ["@pixi/color@7.4.3", "", { "dependencies": { "@pixi/colord": "^2.9.6" } }, "sha512-a6R+bXKeXMDcRmjYQoBIK+v2EYqxSX49wcjAY579EYM/WrFKS98nSees6lqVUcLKrcQh2DT9srJHX7XMny3voQ=="], + + "@pixi/colord": ["@pixi/colord@2.9.6", "", {}, "sha512-nezytU2pw587fQstUu1AsJZDVEynjskwOL+kibwcdxsMBFqPsFFNA7xl0ii/gXuDi6M0xj3mfRJj8pBSc2jCfA=="], + + "@pixi/constants": ["@pixi/constants@7.4.3", "", {}, "sha512-QGmwJUNQy/vVEHzL6VGQvnwawLZ1wceZMI8HwJAT4/I2uAzbBeFDdmCS8WsTpSWLZjF/DszDc1D8BFp4pVJ5UQ=="], + + "@pixi/core": ["@pixi/core@7.4.3", "", { "dependencies": { "@pixi/color": "7.4.3", "@pixi/constants": "7.4.3", "@pixi/extensions": "7.4.3", "@pixi/math": "7.4.3", "@pixi/runner": "7.4.3", "@pixi/settings": "7.4.3", "@pixi/ticker": "7.4.3", "@pixi/utils": "7.4.3" } }, "sha512-5YDs11faWgVVTL8VZtLU05/Fl47vaP5Tnsbf+y/WRR0VSW3KhRRGTBU1J3Gdc2xEWbJhUK07KGP7eSZpvtPVgA=="], + + "@pixi/extensions": ["@pixi/extensions@7.4.3", "", {}, "sha512-FhoiYkHQEDYHUE7wXhqfsTRz6KxLXjuMbSiAwnLb9uG1vAgp6q6qd6HEsf4X30YaZbLFY8a4KY6hFZWjF+4Fdw=="], + + "@pixi/filter-drop-shadow": ["@pixi/filter-drop-shadow@5.2.0", "", { "dependencies": { "@pixi/filter-kawase-blur": "5.1.1" }, "peerDependencies": { "@pixi/core": "^7.0.0-X" } }, "sha512-cYS2KDER7cwCu0V4VNSxTHGvzmNcEXdC9j3031YBOkUAE3+p17LMS/TAt6XeMfJV7KaPuusvXy2NFgGkv3RDbw=="], + + "@pixi/filter-kawase-blur": ["@pixi/filter-kawase-blur@5.1.1", "", { "peerDependencies": { "@pixi/core": "^7.0.0-X" } }, "sha512-nPnJ1ChBFP+4pgFCwC0RJgHAJCetiHcQU3INH7zCdq88cFABmVmhN+wCKRNg4H7lF1EJjaXgFDkTrTreOD/bnw=="], + + "@pixi/math": ["@pixi/math@7.4.3", "", {}, "sha512-/uJOVhR2DOZ+zgdI6Bs/CwcXT4bNRKsS+TqX3ekRIxPCwaLra+Qdm7aDxT5cTToDzdxbKL5+rwiLu3Y1egILDw=="], + + "@pixi/runner": ["@pixi/runner@7.4.3", "", {}, "sha512-TJyfp7y23u5vvRAyYhVSa7ytq0PdKSvPLXu4G3meoFh1oxTLHH6g/RIzLuxUAThPG2z7ftthuW3qWq6dRV+dhw=="], + + "@pixi/settings": ["@pixi/settings@7.4.3", "", { "dependencies": { "@pixi/constants": "7.4.3", "@types/css-font-loading-module": "^0.0.12", "ismobilejs": "^1.1.0" } }, "sha512-SmGK8smc0PxRB9nr0UJioEtE9hl4gvj9OedCvZx3bxBwA3omA5BmP3CyhQfN8XJ29+o2OUL01r3zAPVol4l4lA=="], + + "@pixi/ticker": ["@pixi/ticker@7.4.3", "", { "dependencies": { "@pixi/extensions": "7.4.3", "@pixi/settings": "7.4.3", "@pixi/utils": "7.4.3" } }, "sha512-tHsAD0iOUb6QSGGw+c8cyRBvxsq/NlfzIFBZLEHhWZ+Bx4a0MmXup6I/yJDGmyPCYE+ctCcAfY13wKAzdiVFgQ=="], + + "@pixi/utils": ["@pixi/utils@7.4.3", "", { "dependencies": { "@pixi/color": "7.4.3", "@pixi/constants": "7.4.3", "@pixi/settings": "7.4.3", "@types/earcut": "^2.1.0", "earcut": "^2.2.4", "eventemitter3": "^4.0.0", "url": "^0.11.0" } }, "sha512-NO3Y9HAn2UKS1YdxffqsPp+kDpVm8XWvkZcS/E+rBzY9VTLnNOI7cawSRm+dacdET3a8Jad3aDKEDZ0HmAqAFA=="], + + "@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="], + + "@radix-ui/number": ["@radix-ui/number@1.1.1", "", {}, "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g=="], + + "@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="], + + "@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w=="], + + "@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw=="], + + "@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg=="], + + "@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="], + + "@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw=="], + + "@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw=="], + + "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-escape-keydown": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg=="], + + "@radix-ui/react-dropdown-menu": ["@radix-ui/react-dropdown-menu@2.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-menu": "2.1.16", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw=="], + + "@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw=="], + + "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw=="], + + "@radix-ui/react-id": ["@radix-ui/react-id@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg=="], + + "@radix-ui/react-menu": ["@radix-ui/react-menu@2.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-callback-ref": "1.1.1", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg=="], + + "@radix-ui/react-popover": ["@radix-ui/react-popover@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA=="], + + "@radix-ui/react-popper": ["@radix-ui/react-popper@1.2.8", "", { "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-rect": "1.1.1", "@radix-ui/react-use-size": "1.1.1", "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw=="], + + "@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.9", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ=="], + + "@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.5", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ=="], + + "@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="], + + "@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA=="], + + "@radix-ui/react-select": ["@radix-ui/react-select@2.2.6", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ=="], + + "@radix-ui/react-slider": ["@radix-ui/react-slider@1.3.6", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw=="], + + "@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], + + "@radix-ui/react-switch": ["@radix-ui/react-switch@1.2.6", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ=="], + + "@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A=="], + + "@radix-ui/react-toggle": ["@radix-ui/react-toggle@1.1.10", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ=="], + + "@radix-ui/react-toggle-group": ["@radix-ui/react-toggle-group@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-toggle": "1.1.10", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q=="], + + "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="], + + "@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.2", "", { "dependencies": { "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg=="], + + "@radix-ui/react-use-effect-event": ["@radix-ui/react-use-effect-event@0.0.2", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA=="], + + "@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.1", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g=="], + + "@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ=="], + + "@radix-ui/react-use-previous": ["@radix-ui/react-use-previous@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ=="], + + "@radix-ui/react-use-rect": ["@radix-ui/react-use-rect@1.1.1", "", { "dependencies": { "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w=="], + + "@radix-ui/react-use-size": ["@radix-ui/react-use-size@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ=="], + + "@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.2.3", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug=="], + + "@radix-ui/rect": ["@radix-ui/rect@1.1.1", "", {}, "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw=="], + + "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.27", "", {}, "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA=="], + + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.52.4", "", { "os": "android", "cpu": "arm" }, "sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA=="], + + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.52.4", "", { "os": "android", "cpu": "arm64" }, "sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w=="], + + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.52.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg=="], + + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.52.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw=="], + + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.52.4", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ=="], + + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.52.4", "", { "os": "freebsd", "cpu": "x64" }, "sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw=="], + + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.52.4", "", { "os": "linux", "cpu": "arm" }, "sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ=="], + + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.52.4", "", { "os": "linux", "cpu": "arm" }, "sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q=="], + + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.52.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg=="], + + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.52.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g=="], + + "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.52.4", "", { "os": "linux", "cpu": "none" }, "sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ=="], + + "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.52.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g=="], + + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.52.4", "", { "os": "linux", "cpu": "none" }, "sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg=="], + + "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.52.4", "", { "os": "linux", "cpu": "none" }, "sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA=="], + + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.52.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA=="], + + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.52.4", "", { "os": "linux", "cpu": "x64" }, "sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg=="], + + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.52.4", "", { "os": "linux", "cpu": "x64" }, "sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw=="], + + "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.52.4", "", { "os": "none", "cpu": "arm64" }, "sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA=="], + + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.52.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ=="], + + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.52.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw=="], + + "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.52.4", "", { "os": "win32", "cpu": "x64" }, "sha512-UF9KfsH9yEam0UjTwAgdK0anlQ7c8/pWPU2yVjyWcF1I1thABt6WXE47cI71pGiZ8wGvxohBoLnxM04L/wj8mQ=="], + + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.52.4", "", { "os": "win32", "cpu": "x64" }, "sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w=="], + + "@sindresorhus/is": ["@sindresorhus/is@4.6.0", "", {}, "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw=="], + + "@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], + + "@szmarczak/http-timer": ["@szmarczak/http-timer@4.0.6", "", { "dependencies": { "defer-to-connect": "^2.0.0" } }, "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w=="], + + "@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="], + + "@tootallnate/once": ["@tootallnate/once@2.0.0", "", {}, "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A=="], + + "@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="], + + "@types/babel__generator": ["@types/babel__generator@7.27.0", "", { "dependencies": { "@babel/types": "^7.0.0" } }, "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg=="], + + "@types/babel__template": ["@types/babel__template@7.4.4", "", { "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A=="], + + "@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="], + + "@types/cacheable-request": ["@types/cacheable-request@6.0.3", "", { "dependencies": { "@types/http-cache-semantics": "*", "@types/keyv": "^3.1.4", "@types/node": "*", "@types/responselike": "^1.0.0" } }, "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw=="], + + "@types/chai": ["@types/chai@5.2.3", "", { "dependencies": { "@types/deep-eql": "*", "assertion-error": "^2.0.1" } }, "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA=="], + + "@types/css-font-loading-module": ["@types/css-font-loading-module@0.0.12", "", {}, "sha512-x2tZZYkSxXqWvTDgveSynfjq/T2HyiZHXb00j/+gy19yp70PHCizM48XFdjBCWH7eHBD0R5i/pw9yMBP/BH5uA=="], + + "@types/debug": ["@types/debug@4.1.12", "", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="], + + "@types/deep-eql": ["@types/deep-eql@4.0.2", "", {}, "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw=="], + + "@types/dom-mediacapture-transform": ["@types/dom-mediacapture-transform@0.1.11", "", { "dependencies": { "@types/dom-webcodecs": "*" } }, "sha512-Y2p+nGf1bF2XMttBnsVPHUWzRRZzqUoJAKmiP10b5umnO6DDrWI0BrGDJy1pOHoOULVmGSfFNkQrAlC5dcj6nQ=="], + + "@types/dom-webcodecs": ["@types/dom-webcodecs@0.1.13", "", {}, "sha512-O5hkiFIcjjszPIYyUSyvScyvrBoV3NOEEZx/pMlsu44TKzWNkLVBBxnxJz42in5n3QIolYOcBYFCPZZ0h8SkwQ=="], + + "@types/earcut": ["@types/earcut@3.0.0", "", {}, "sha512-k/9fOUGO39yd2sCjrbAJvGDEQvRwRnQIZlBz43roGwUZo5SHAmyVvSFyaVVZkicRVCaDXPKlbxrUcBuJoSWunQ=="], + + "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], + + "@types/events": ["@types/events@3.0.3", "", {}, "sha512-trOc4AAUThEz9hapPtSd7wf5tiQKvTtu5b371UxXdTuqzIh0ArcRspRP0i0Viu+LXstIQ1z96t1nsPxT9ol01g=="], + + "@types/fs-extra": ["@types/fs-extra@9.0.13", "", { "dependencies": { "@types/node": "*" } }, "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA=="], + + "@types/gif.js": ["@types/gif.js@0.2.5", "", { "dependencies": { "@types/events": "*" } }, "sha512-OdDQYh9v7td9ztjaooBSqjUBAyAuui2xwDDmQcyRLd6c9T0iWgkebAoCBEdEEBoZG3ekJE/6UnH63Dzq0S3bvw=="], + + "@types/http-cache-semantics": ["@types/http-cache-semantics@4.0.4", "", {}, "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA=="], + + "@types/keyv": ["@types/keyv@3.1.4", "", { "dependencies": { "@types/node": "*" } }, "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg=="], + + "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], + + "@types/node": ["@types/node@25.0.8", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-powIePYMmC3ibL0UJ2i2s0WIbq6cg6UyVFQxSCpaPxxzAaziRfimGivjdF943sSGV6RADVbk0Nvlm5P/FB44Zg=="], + + "@types/plist": ["@types/plist@3.0.5", "", { "dependencies": { "@types/node": "*", "xmlbuilder": ">=11.0.1" } }, "sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA=="], + + "@types/prop-types": ["@types/prop-types@15.7.15", "", {}, "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw=="], + + "@types/react": ["@types/react@18.3.26", "", { "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" } }, "sha512-RFA/bURkcKzx/X9oumPG9Vp3D3JUgus/d0b67KB0t5S/raciymilkOa66olh78MUI92QLbEJevO7rvqU/kjwKA=="], + + "@types/react-dom": ["@types/react-dom@18.3.7", "", { "peerDependencies": { "@types/react": "^18.0.0" } }, "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ=="], + + "@types/responselike": ["@types/responselike@1.0.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw=="], + + "@types/uuid": ["@types/uuid@10.0.0", "", {}, "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ=="], + + "@types/verror": ["@types/verror@1.10.11", "", {}, "sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg=="], + + "@types/yauzl": ["@types/yauzl@2.10.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q=="], + + "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@7.18.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "7.18.0", "@typescript-eslint/type-utils": "7.18.0", "@typescript-eslint/utils": "7.18.0", "@typescript-eslint/visitor-keys": "7.18.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^1.3.0" }, "peerDependencies": { "@typescript-eslint/parser": "^7.0.0", "eslint": "^8.56.0" } }, "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw=="], + + "@typescript-eslint/parser": ["@typescript-eslint/parser@7.18.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "7.18.0", "@typescript-eslint/types": "7.18.0", "@typescript-eslint/typescript-estree": "7.18.0", "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.56.0" } }, "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg=="], + + "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@7.18.0", "", { "dependencies": { "@typescript-eslint/types": "7.18.0", "@typescript-eslint/visitor-keys": "7.18.0" } }, "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA=="], + + "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@7.18.0", "", { "dependencies": { "@typescript-eslint/typescript-estree": "7.18.0", "@typescript-eslint/utils": "7.18.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, "peerDependencies": { "eslint": "^8.56.0" } }, "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA=="], + + "@typescript-eslint/types": ["@typescript-eslint/types@7.18.0", "", {}, "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ=="], + + "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@7.18.0", "", { "dependencies": { "@typescript-eslint/types": "7.18.0", "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^1.3.0" } }, "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA=="], + + "@typescript-eslint/utils": ["@typescript-eslint/utils@7.18.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "7.18.0", "@typescript-eslint/types": "7.18.0", "@typescript-eslint/typescript-estree": "7.18.0" }, "peerDependencies": { "eslint": "^8.56.0" } }, "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw=="], + + "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@7.18.0", "", { "dependencies": { "@typescript-eslint/types": "7.18.0", "eslint-visitor-keys": "^3.4.3" } }, "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg=="], + + "@uiw/color-convert": ["@uiw/color-convert@2.9.2", "", { "peerDependencies": { "@babel/runtime": ">=7.19.0" } }, "sha512-ibw9OS29S7GlL+vDwU3p5XG3vhR7XdzUecydpZbakUeg2Td6nfsnrCAX9sbLwQ73p0abO42v+V4qRaWq+7/BjQ=="], + + "@uiw/react-color-block": ["@uiw/react-color-block@2.9.2", "", { "dependencies": { "@uiw/color-convert": "2.9.2", "@uiw/react-color-editable-input": "2.9.2", "@uiw/react-color-swatch": "2.9.2" }, "peerDependencies": { "@babel/runtime": ">=7.19.0", "react": ">=16.9.0", "react-dom": ">=16.9.0" } }, "sha512-0EIZTELA5pnxyMlBOFo3hrpy73db+Qeq6E+QptNfD/8izor8OvY1Uquj2VqD6gDz+iVHMELIoKxpaQ8sZR7NOg=="], + + "@uiw/react-color-editable-input": ["@uiw/react-color-editable-input@2.9.2", "", { "peerDependencies": { "@babel/runtime": ">=7.19.0", "react": ">=16.9.0", "react-dom": ">=16.9.0" } }, "sha512-DY7pu12+LDRn6cxDMvsy1/quaPTxicAPz/kfODV7KBf8+Hq4rFWeJ4KS6m22IKIbQxrBQgmQG0WFJLaPeY7cPw=="], + + "@uiw/react-color-swatch": ["@uiw/react-color-swatch@2.9.2", "", { "dependencies": { "@uiw/color-convert": "2.9.2" }, "peerDependencies": { "@babel/runtime": ">=7.19.0", "react": ">=16.9.0", "react-dom": ">=16.9.0" } }, "sha512-6zBy+E9NzZR672M2wPsbbNRqKy9Wi9jOuuxxyzov1CEZp+pPX7UwMlCX6RUhKdO0PzTSPCVQmbz5bplu5vsW0w=="], + + "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], + + "@vitejs/plugin-react": ["@vitejs/plugin-react@4.7.0", "", { "dependencies": { "@babel/core": "^7.28.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-beta.27", "@types/babel__core": "^7.20.5", "react-refresh": "^0.17.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA=="], + + "@vitest/expect": ["@vitest/expect@4.0.17", "", { "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" } }, "sha512-mEoqP3RqhKlbmUmntNDDCJeTDavDR+fVYkSOw8qRwJFaW/0/5zA9zFeTrHqNtcmwh6j26yMmwx2PqUDPzt5ZAQ=="], + + "@vitest/mocker": ["@vitest/mocker@4.0.17", "", { "dependencies": { "@vitest/spy": "4.0.17", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^6.0.0 || ^7.0.0-0" }, "optionalPeers": ["msw", "vite"] }, "sha512-+ZtQhLA3lDh1tI2wxe3yMsGzbp7uuJSWBM1iTIKCbppWTSBN09PUC+L+fyNlQApQoR+Ps8twt2pbSSXg2fQVEQ=="], + + "@vitest/pretty-format": ["@vitest/pretty-format@4.0.17", "", { "dependencies": { "tinyrainbow": "^3.0.3" } }, "sha512-Ah3VAYmjcEdHg6+MwFE17qyLqBHZ+ni2ScKCiW2XrlSBV4H3Z7vYfPfz7CWQ33gyu76oc0Ai36+kgLU3rfF4nw=="], + + "@vitest/runner": ["@vitest/runner@4.0.17", "", { "dependencies": { "@vitest/utils": "4.0.17", "pathe": "^2.0.3" } }, "sha512-JmuQyf8aMWoo/LmNFppdpkfRVHJcsgzkbCA+/Bk7VfNH7RE6Ut2qxegeyx2j3ojtJtKIbIGy3h+KxGfYfk28YQ=="], + + "@vitest/snapshot": ["@vitest/snapshot@4.0.17", "", { "dependencies": { "@vitest/pretty-format": "4.0.17", "magic-string": "^0.30.21", "pathe": "^2.0.3" } }, "sha512-npPelD7oyL+YQM2gbIYvlavlMVWUfNNGZPcu0aEUQXt7FXTuqhmgiYupPnAanhKvyP6Srs2pIbWo30K0RbDtRQ=="], + + "@vitest/spy": ["@vitest/spy@4.0.17", "", {}, "sha512-I1bQo8QaP6tZlTomQNWKJE6ym4SHf3oLS7ceNjozxxgzavRAgZDc06T7kD8gb9bXKEgcLNt00Z+kZO6KaJ62Ew=="], + + "@vitest/utils": ["@vitest/utils@4.0.17", "", { "dependencies": { "@vitest/pretty-format": "4.0.17", "tinyrainbow": "^3.0.3" } }, "sha512-RG6iy+IzQpa9SB8HAFHJ9Y+pTzI+h8553MrciN9eC6TFBErqrQaTas4vG+MVj8S4uKk8uTT2p0vgZPnTdxd96w=="], + + "@webgpu/types": ["@webgpu/types@0.1.66", "", {}, "sha512-YA2hLrwLpDsRueNDXIMqN9NTzD6bCDkuXbOSe0heS+f8YE8usA6Gbv1prj81pzVHrbaAma7zObnIC+I6/sXJgA=="], + + "@xmldom/xmldom": ["@xmldom/xmldom@0.8.11", "", {}, "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw=="], + + "abbrev": ["abbrev@1.1.1", "", {}, "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="], + + "abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="], + + "acorn": ["acorn@8.15.0", "", { "bin": "bin/acorn" }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], + + "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], + + "agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="], + + "agentkeepalive": ["agentkeepalive@4.6.0", "", { "dependencies": { "humanize-ms": "^1.2.1" } }, "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ=="], + + "aggregate-error": ["aggregate-error@3.1.0", "", { "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" } }, "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA=="], + + "ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="], + + "ajv-keywords": ["ajv-keywords@3.5.2", "", { "peerDependencies": { "ajv": "^6.9.1" } }, "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="], + + "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + + "any-base": ["any-base@1.1.0", "", {}, "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg=="], + + "any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="], + + "anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="], + + "app-builder-bin": ["app-builder-bin@4.0.0", "", {}, "sha512-xwdG0FJPQMe0M0UA4Tz0zEB8rBJTRA5a476ZawAqiBkMv16GRK5xpXThOjMaEOFnZ6zabejjG4J3da0SXG63KA=="], + + "app-builder-lib": ["app-builder-lib@24.13.3", "", { "dependencies": { "@develar/schema-utils": "~2.6.5", "@electron/notarize": "2.2.1", "@electron/osx-sign": "1.0.5", "@electron/universal": "1.5.1", "@malept/flatpak-bundler": "^0.4.0", "@types/fs-extra": "9.0.13", "async-exit-hook": "^2.0.1", "bluebird-lst": "^1.0.9", "builder-util": "24.13.1", "builder-util-runtime": "9.2.4", "chromium-pickle-js": "^0.2.0", "debug": "^4.3.4", "ejs": "^3.1.8", "electron-publish": "24.13.1", "form-data": "^4.0.0", "fs-extra": "^10.1.0", "hosted-git-info": "^4.1.0", "is-ci": "^3.0.0", "isbinaryfile": "^5.0.0", "js-yaml": "^4.1.0", "lazy-val": "^1.0.5", "minimatch": "^5.1.1", "read-config-file": "6.3.2", "sanitize-filename": "^1.6.3", "semver": "^7.3.8", "tar": "^6.1.12", "temp-file": "^3.4.0" }, "peerDependencies": { "dmg-builder": "24.13.3", "electron-builder-squirrel-windows": "24.13.3" } }, "sha512-FAzX6IBit2POXYGnTCT8YHFO/lr5AapAII6zzhQO3Rw4cEDOgK+t1xhLc5tNcKlicTHlo9zxIwnYCX9X2DLkig=="], + + "aproba": ["aproba@2.1.0", "", {}, "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew=="], + + "archiver": ["archiver@5.3.2", "", { "dependencies": { "archiver-utils": "^2.1.0", "async": "^3.2.4", "buffer-crc32": "^0.2.1", "readable-stream": "^3.6.0", "readdir-glob": "^1.1.2", "tar-stream": "^2.2.0", "zip-stream": "^4.1.0" } }, "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw=="], + + "archiver-utils": ["archiver-utils@2.1.0", "", { "dependencies": { "glob": "^7.1.4", "graceful-fs": "^4.2.0", "lazystream": "^1.0.0", "lodash.defaults": "^4.2.0", "lodash.difference": "^4.5.0", "lodash.flatten": "^4.4.0", "lodash.isplainobject": "^4.0.6", "lodash.union": "^4.6.0", "normalize-path": "^3.0.0", "readable-stream": "^2.0.0" } }, "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw=="], + + "are-we-there-yet": ["are-we-there-yet@3.0.1", "", { "dependencies": { "delegates": "^1.0.0", "readable-stream": "^3.6.0" } }, "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg=="], + + "arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="], + + "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], + + "args": ["args@5.0.3", "", { "dependencies": { "camelcase": "5.0.0", "chalk": "2.4.2", "leven": "2.1.0", "mri": "1.1.4" } }, "sha512-h6k/zfFgusnv3i5TU08KQkVKuCPBtL/PWQbWkHUxvJrZ2nAyeaUupneemcrgn1xmqxPQsPIzwkUhOpoqPDRZuA=="], + + "aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="], + + "array-union": ["array-union@2.1.0", "", {}, "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw=="], + + "asn1": ["asn1@0.2.6", "", { "dependencies": { "safer-buffer": "~2.1.0" } }, "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ=="], + + "assemblyai": ["assemblyai@4.22.1", "", { "dependencies": { "ws": "^8.18.0" } }, "sha512-7IZuOxwxTWs3U+JjH8aBxhA6RM3tOFjEDKgxhvnNpHLjVIKEaxl4hqFd+g0eSNtz7QnHUZJQffaz7JCariC0MQ=="], + + "assert-plus": ["assert-plus@1.0.0", "", {}, "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw=="], + + "assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="], + + "astral-regex": ["astral-regex@2.0.0", "", {}, "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ=="], + + "async": ["async@3.2.6", "", {}, "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="], + + "async-exit-hook": ["async-exit-hook@2.0.1", "", {}, "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw=="], + + "asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="], + + "at-least-node": ["at-least-node@1.0.0", "", {}, "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg=="], + + "autoprefixer": ["autoprefixer@10.4.21", "", { "dependencies": { "browserslist": "^4.24.4", "caniuse-lite": "^1.0.30001702", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": "bin/autoprefixer" }, "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ=="], + + "aws-sign2": ["aws-sign2@0.7.0", "", {}, "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA=="], + + "aws4": ["aws4@1.13.2", "", {}, "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw=="], + + "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], + + "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], + + "baseline-browser-mapping": ["baseline-browser-mapping@2.8.15", "", { "bin": "dist/cli.js" }, "sha512-qsJ8/X+UypqxHXN75M7dF88jNK37dLBRW7LeUzCPz+TNs37G8cfWy9nWzS+LS//g600zrt2le9KuXt0rWfDz5Q=="], + + "bcrypt-pbkdf": ["bcrypt-pbkdf@1.0.2", "", { "dependencies": { "tweetnacl": "^0.14.3" } }, "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w=="], + + "binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="], + + "bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="], + + "bluebird": ["bluebird@3.7.2", "", {}, "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="], + + "bluebird-lst": ["bluebird-lst@1.0.9", "", { "dependencies": { "bluebird": "^3.5.5" } }, "sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw=="], + + "bmp-js": ["bmp-js@0.1.0", "", {}, "sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw=="], + + "boolean": ["boolean@3.2.0", "", {}, "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw=="], + + "brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="], + + "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], + + "browserslist": ["browserslist@4.26.3", "", { "dependencies": { "baseline-browser-mapping": "^2.8.9", "caniuse-lite": "^1.0.30001746", "electron-to-chromium": "^1.5.227", "node-releases": "^2.0.21", "update-browserslist-db": "^1.1.3" }, "bin": "cli.js" }, "sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w=="], + + "buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="], + + "buffer-crc32": ["buffer-crc32@0.2.13", "", {}, "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="], + + "buffer-equal": ["buffer-equal@1.0.1", "", {}, "sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg=="], + + "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="], + + "builder-util": ["builder-util@24.13.1", "", { "dependencies": { "7zip-bin": "~5.2.0", "@types/debug": "^4.1.6", "app-builder-bin": "4.0.0", "bluebird-lst": "^1.0.9", "builder-util-runtime": "9.2.4", "chalk": "^4.1.2", "cross-spawn": "^7.0.3", "debug": "^4.3.4", "fs-extra": "^10.1.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.1", "is-ci": "^3.0.0", "js-yaml": "^4.1.0", "source-map-support": "^0.5.19", "stat-mode": "^1.0.0", "temp-file": "^3.4.0" } }, "sha512-NhbCSIntruNDTOVI9fdXz0dihaqX2YuE1D6zZMrwiErzH4ELZHE6mdiB40wEgZNprDia+FghRFgKoAqMZRRjSA=="], + + "builder-util-runtime": ["builder-util-runtime@9.2.4", "", { "dependencies": { "debug": "^4.3.4", "sax": "^1.2.4" } }, "sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA=="], + + "cacache": ["cacache@16.1.3", "", { "dependencies": { "@npmcli/fs": "^2.1.0", "@npmcli/move-file": "^2.0.0", "chownr": "^2.0.0", "fs-minipass": "^2.1.0", "glob": "^8.0.1", "infer-owner": "^1.0.4", "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "mkdirp": "^1.0.4", "p-map": "^4.0.0", "promise-inflight": "^1.0.1", "rimraf": "^3.0.2", "ssri": "^9.0.0", "tar": "^6.1.11", "unique-filename": "^2.0.0" } }, "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ=="], + + "cacheable-lookup": ["cacheable-lookup@5.0.4", "", {}, "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA=="], + + "cacheable-request": ["cacheable-request@7.0.4", "", { "dependencies": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", "http-cache-semantics": "^4.0.0", "keyv": "^4.0.0", "lowercase-keys": "^2.0.0", "normalize-url": "^6.0.1", "responselike": "^2.0.0" } }, "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg=="], + + "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], + + "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="], + + "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], + + "camelcase": ["camelcase@5.0.0", "", {}, "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA=="], + + "camelcase-css": ["camelcase-css@2.0.1", "", {}, "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA=="], + + "caniuse-lite": ["caniuse-lite@1.0.30001749", "", {}, "sha512-0rw2fJOmLfnzCRbkm8EyHL8SvI2Apu5UbnQuTsJ0ClgrH8hcwFooJ1s5R0EP8o8aVrFu8++ae29Kt9/gZAZp/Q=="], + + "caseless": ["caseless@0.12.0", "", {}, "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="], + + "centra": ["centra@2.7.0", "", { "dependencies": { "follow-redirects": "^1.15.6" } }, "sha512-PbFMgMSrmgx6uxCdm57RUos9Tc3fclMvhLSATYN39XsDV29B89zZ3KA89jmY0vwSGazyU+uerqwa6t+KaodPcg=="], + + "chai": ["chai@6.2.2", "", {}, "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg=="], + + "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + + "chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], + + "chownr": ["chownr@2.0.0", "", {}, "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="], + + "chromium-pickle-js": ["chromium-pickle-js@0.2.0", "", {}, "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw=="], + + "ci-info": ["ci-info@3.9.0", "", {}, "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ=="], + + "class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "^2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="], + + "clean-stack": ["clean-stack@2.2.0", "", {}, "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A=="], + + "cli-cursor": ["cli-cursor@3.1.0", "", { "dependencies": { "restore-cursor": "^3.1.0" } }, "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw=="], + + "cli-spinners": ["cli-spinners@2.9.2", "", {}, "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg=="], + + "cli-truncate": ["cli-truncate@2.1.0", "", { "dependencies": { "slice-ansi": "^3.0.0", "string-width": "^4.2.0" } }, "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg=="], + + "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], + + "clone": ["clone@1.0.4", "", {}, "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg=="], + + "clone-response": ["clone-response@1.0.3", "", { "dependencies": { "mimic-response": "^1.0.0" } }, "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA=="], + + "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], + + "code-point-at": ["code-point-at@1.1.0", "", {}, "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA=="], + + "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], + + "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + + "color-support": ["color-support@1.1.3", "", { "bin": "bin.js" }, "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg=="], + + "combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="], + + "commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], + + "compare-version": ["compare-version@0.1.2", "", {}, "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A=="], + + "compress-commons": ["compress-commons@4.1.2", "", { "dependencies": { "buffer-crc32": "^0.2.13", "crc32-stream": "^4.0.2", "normalize-path": "^3.0.0", "readable-stream": "^3.6.0" } }, "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg=="], + + "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="], + + "concat-stream": ["concat-stream@1.6.2", "", { "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^2.2.2", "typedarray": "^0.0.6" } }, "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw=="], + + "config-file-ts": ["config-file-ts@0.2.6", "", { "dependencies": { "glob": "^10.3.10", "typescript": "^5.3.3" } }, "sha512-6boGVaglwblBgJqGyxm4+xCmEGcWgnWHSWHY5jad58awQhB6gftq0G8HbzU39YqCIYHMLAiL1yjwiZ36m/CL8w=="], + + "console-control-strings": ["console-control-strings@1.1.0", "", {}, "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="], + + "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], + + "core-util-is": ["core-util-is@1.0.2", "", {}, "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="], + + "crc": ["crc@3.8.0", "", { "dependencies": { "buffer": "^5.1.0" } }, "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ=="], + + "crc-32": ["crc-32@1.2.2", "", { "bin": { "crc32": "bin/crc32.njs" } }, "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ=="], + + "crc32-stream": ["crc32-stream@4.0.3", "", { "dependencies": { "crc-32": "^1.2.0", "readable-stream": "^3.4.0" } }, "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw=="], + + "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], + + "cssesc": ["cssesc@3.0.0", "", { "bin": "bin/cssesc" }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="], + + "csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="], + + "dashdash": ["dashdash@1.14.1", "", { "dependencies": { "assert-plus": "^1.0.0" } }, "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g=="], + + "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + + "decamelize": ["decamelize@1.2.0", "", {}, "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="], + + "decompress-response": ["decompress-response@6.0.0", "", { "dependencies": { "mimic-response": "^3.1.0" } }, "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ=="], + + "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="], + + "defaults": ["defaults@1.0.4", "", { "dependencies": { "clone": "^1.0.2" } }, "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A=="], + + "defer-to-connect": ["defer-to-connect@2.0.1", "", {}, "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg=="], + + "define-data-property": ["define-data-property@1.1.4", "", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" } }, "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A=="], + + "define-properties": ["define-properties@1.2.1", "", { "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="], + + "del": ["del@6.1.1", "", { "dependencies": { "globby": "^11.0.1", "graceful-fs": "^4.2.4", "is-glob": "^4.0.1", "is-path-cwd": "^2.2.0", "is-path-inside": "^3.0.2", "p-map": "^4.0.0", "rimraf": "^3.0.2", "slash": "^3.0.0" } }, "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg=="], + + "delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="], + + "delegates": ["delegates@1.0.0", "", {}, "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="], + + "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + + "detect-node": ["detect-node@2.1.0", "", {}, "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g=="], + + "detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="], + + "didyoumean": ["didyoumean@1.2.2", "", {}, "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="], + + "dir-compare": ["dir-compare@3.3.0", "", { "dependencies": { "buffer-equal": "^1.0.0", "minimatch": "^3.0.4" } }, "sha512-J7/et3WlGUCxjdnD3HAAzQ6nsnc0WL6DD7WcwJb7c39iH1+AWfg+9OqzJNaI6PkBwBvm1mhZNL9iY/nRiZXlPg=="], + + "dir-glob": ["dir-glob@3.0.1", "", { "dependencies": { "path-type": "^4.0.0" } }, "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA=="], + + "dlv": ["dlv@1.1.3", "", {}, "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="], + + "dmg-builder": ["dmg-builder@24.13.3", "", { "dependencies": { "app-builder-lib": "24.13.3", "builder-util": "24.13.1", "builder-util-runtime": "9.2.4", "fs-extra": "^10.1.0", "iconv-lite": "^0.6.2", "js-yaml": "^4.1.0" }, "optionalDependencies": { "dmg-license": "^1.0.11" } }, "sha512-rcJUkMfnJpfCboZoOOPf4L29TRtEieHNOeAbYPWPxlaBw/Z1RKrRA86dOI9rwaI4tQSc/RD82zTNHprfUHXsoQ=="], + + "dmg-license": ["dmg-license@1.0.11", "", { "dependencies": { "@types/plist": "^3.0.1", "@types/verror": "^1.10.3", "ajv": "^6.10.0", "crc": "^3.8.0", "iconv-corefoundation": "^1.1.7", "plist": "^3.0.4", "smart-buffer": "^4.0.2", "verror": "^1.10.0" }, "os": "darwin", "bin": "bin/dmg-license.js" }, "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q=="], + + "dnd-timeline": ["dnd-timeline@2.2.0", "", { "dependencies": { "@dnd-kit/core": "^6.1.0", "@dnd-kit/utilities": "^3.2.2", "resize-observer-polyfill": "^1.5.1" } }, "sha512-bQ/2bm70eA7YeztgdxoSpdpTwPzj8VT2/wTlYrnFpqJ71et7EVJZR35XPZIVzBqSyKK9T/QyUzE26gYck9ldxg=="], + + "doctrine": ["doctrine@3.0.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w=="], + + "dom-walk": ["dom-walk@0.1.2", "", {}, "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w=="], + + "dotenv": ["dotenv@9.0.2", "", {}, "sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg=="], + + "dotenv-expand": ["dotenv-expand@5.1.0", "", {}, "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA=="], + + "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], + + "earcut": ["earcut@3.0.2", "", {}, "sha512-X7hshQbLyMJ/3RPhyObLARM2sNxxmRALLKx1+NVFFnQ9gKzmCrxm9+uLIAdBcvc8FNLpctqlQ2V6AE92Ol9UDQ=="], + + "eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="], + + "ecc-jsbn": ["ecc-jsbn@0.1.2", "", { "dependencies": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" } }, "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw=="], + + "ejs": ["ejs@3.1.10", "", { "dependencies": { "jake": "^10.8.5" }, "bin": "bin/cli.js" }, "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA=="], + + "electron": ["electron@39.2.7", "", { "dependencies": { "@electron/get": "^2.0.0", "@types/node": "^22.7.7", "extract-zip": "^2.0.1" }, "bin": { "electron": "cli.js" } }, "sha512-KU0uFS6LSTh4aOIC3miolcbizOFP7N1M46VTYVfqIgFiuA2ilfNaOHLDS9tCMvwwHRowAsvqBrh9NgMXcTOHCQ=="], + + "electron-builder": ["electron-builder@24.13.3", "", { "dependencies": { "app-builder-lib": "24.13.3", "builder-util": "24.13.1", "builder-util-runtime": "9.2.4", "chalk": "^4.1.2", "dmg-builder": "24.13.3", "fs-extra": "^10.1.0", "is-ci": "^3.0.0", "lazy-val": "^1.0.5", "read-config-file": "6.3.2", "simple-update-notifier": "2.0.0", "yargs": "^17.6.2" }, "bin": { "electron-builder": "cli.js", "install-app-deps": "install-app-deps.js" } }, "sha512-yZSgVHft5dNVlo31qmJAe4BVKQfFdwpRw7sFp1iQglDRCDD6r22zfRJuZlhtB5gp9FHUxCMEoWGq10SkCnMAIg=="], + + "electron-builder-squirrel-windows": ["electron-builder-squirrel-windows@24.13.3", "", { "dependencies": { "app-builder-lib": "24.13.3", "archiver": "^5.3.1", "builder-util": "24.13.1", "fs-extra": "^10.1.0" } }, "sha512-oHkV0iogWfyK+ah9ZIvMDpei1m9ZRpdXcvde1wTpra2U8AFDNNpqJdnin5z+PM1GbQ5BoaKCWas2HSjtR0HwMg=="], + + "electron-icon-builder": ["electron-icon-builder@2.0.1", "", { "dependencies": { "args": "^5.0.1", "icon-gen": "^2.0.0", "jimp": "^0.16.1" }, "bin": "index.js" }, "sha512-rg9BxW2kJi3TXsMFFNXWXrwQEd5dzXmeD+w7Pj3k3z7aYRePLxE89qU4lvL/rK1X/NTY5KDn3+Dbgm1TU2dGXQ=="], + + "electron-publish": ["electron-publish@24.13.1", "", { "dependencies": { "@types/fs-extra": "^9.0.11", "builder-util": "24.13.1", "builder-util-runtime": "9.2.4", "chalk": "^4.1.2", "fs-extra": "^10.1.0", "lazy-val": "^1.0.5", "mime": "^2.5.2" } }, "sha512-2ZgdEqJ8e9D17Hwp5LEq5mLQPjqU3lv/IALvgp+4W8VeNhryfGhYEQC/PgDPMrnWUp+l60Ou5SJLsu+k4mhQ8A=="], + + "electron-rebuild": ["electron-rebuild@3.2.9", "", { "dependencies": { "@malept/cross-spawn-promise": "^2.0.0", "chalk": "^4.0.0", "debug": "^4.1.1", "detect-libc": "^2.0.1", "fs-extra": "^10.0.0", "got": "^11.7.0", "lzma-native": "^8.0.5", "node-abi": "^3.0.0", "node-api-version": "^0.1.4", "node-gyp": "^9.0.0", "ora": "^5.1.0", "semver": "^7.3.5", "tar": "^6.0.5", "yargs": "^17.0.1" }, "bin": "lib/src/cli.js" }, "sha512-FkEZNFViUem3P0RLYbZkUjC8LUFIK+wKq09GHoOITSJjfDAVQv964hwaNseTTWt58sITQX3/5fHNYcTefqaCWw=="], + + "electron-to-chromium": ["electron-to-chromium@1.5.234", "", {}, "sha512-RXfEp2x+VRYn8jbKfQlRImzoJU01kyDvVPBmG39eU2iuRVhuS6vQNocB8J0/8GrIMLnPzgz4eW6WiRnJkTuNWg=="], + + "emoji-picker-react": ["emoji-picker-react@4.16.1", "", { "dependencies": { "flairup": "1.0.0" }, "peerDependencies": { "react": ">=16" } }, "sha512-MrPX0tOCfRL3uYI4of/2GRZ7S6qS7YlacKiF78uFH84/C62vcuHE2DZyv5b4ZJMk0e06es1jjB4e31Bb+YSM8w=="], + + "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + + "encoding": ["encoding@0.1.13", "", { "dependencies": { "iconv-lite": "^0.6.2" } }, "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A=="], + + "end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="], + + "env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], + + "err-code": ["err-code@2.0.3", "", {}, "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA=="], + + "error-ex": ["error-ex@1.3.4", "", { "dependencies": { "is-arrayish": "^0.2.1" } }, "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ=="], + + "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="], + + "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], + + "es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="], + + "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="], + + "es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="], + + "es6-error": ["es6-error@4.1.1", "", {}, "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg=="], + + "es6-promise": ["es6-promise@4.2.8", "", {}, "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="], + + "esbuild": ["esbuild@0.21.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": "bin/esbuild" }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="], + + "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], + + "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], + + "eslint": ["eslint@8.57.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", "@eslint/js": "8.57.1", "@humanwhocodes/config-array": "^0.13.0", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.2.2", "eslint-visitor-keys": "^3.4.3", "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3", "strip-ansi": "^6.0.1", "text-table": "^0.2.0" }, "bin": "bin/eslint.js" }, "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA=="], + + "eslint-plugin-react-hooks": ["eslint-plugin-react-hooks@4.6.2", "", { "peerDependencies": { "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" } }, "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ=="], + + "eslint-plugin-react-refresh": ["eslint-plugin-react-refresh@0.4.23", "", { "peerDependencies": { "eslint": ">=8.40" } }, "sha512-G4j+rv0NmbIR45kni5xJOrYvCtyD3/7LjpVH8MPPcudXDcNu8gv+4ATTDXTtbRR8rTCM5HxECvCSsRmxKnWDsA=="], + + "eslint-scope": ["eslint-scope@7.2.2", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg=="], + + "eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], + + "espree": ["espree@9.6.1", "", { "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" } }, "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ=="], + + "esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="], + + "esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="], + + "estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="], + + "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], + + "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="], + + "event-target-shim": ["event-target-shim@5.0.1", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="], + + "eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="], + + "events": ["events@3.3.0", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="], + + "exif-parser": ["exif-parser@0.1.12", "", {}, "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw=="], + + "expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="], + + "exponential-backoff": ["exponential-backoff@3.1.3", "", {}, "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA=="], + + "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="], + + "extract-zip": ["extract-zip@2.0.1", "", { "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", "yauzl": "^2.10.0" }, "optionalDependencies": { "@types/yauzl": "^2.9.1" }, "bin": "cli.js" }, "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg=="], + + "extsprintf": ["extsprintf@1.4.1", "", {}, "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA=="], + + "fast-check": ["fast-check@4.5.3", "", { "dependencies": { "pure-rand": "^7.0.0" } }, "sha512-IE9csY7lnhxBnA8g/WI5eg/hygA6MGWJMSNfFRrBlXUciADEhS1EDB0SIsMSvzubzIlOBbVITSsypCsW717poA=="], + + "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], + + "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], + + "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="], + + "fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="], + + "fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="], + + "fd-slicer": ["fd-slicer@1.1.0", "", { "dependencies": { "pend": "~1.2.0" } }, "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g=="], + + "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + + "file-entry-cache": ["file-entry-cache@6.0.1", "", { "dependencies": { "flat-cache": "^3.0.4" } }, "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg=="], + + "file-type": ["file-type@16.5.4", "", { "dependencies": { "readable-web-to-node-stream": "^3.0.0", "strtok3": "^6.2.4", "token-types": "^4.1.1" } }, "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw=="], + + "file-url": ["file-url@2.0.2", "", {}, "sha512-x3989K8a1jM6vulMigE8VngH7C5nci0Ks5d9kVjUXmNF28gmiZUNujk5HjwaS8dAzN2QmUfX56riJKgN00dNRw=="], + + "filelist": ["filelist@1.0.4", "", { "dependencies": { "minimatch": "^5.0.1" } }, "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q=="], + + "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], + + "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="], + + "fix-webm-duration": ["fix-webm-duration@1.0.6", "", {}, "sha512-zVAqi4gE+8ywxJuAyV/rlJVX6CMtvyapEbQx6jyoeX9TMjdqAlt/FdG5d7rXSSkDVzTvS0H7CtwzHcH/vh4FPA=="], + + "flairup": ["flairup@1.0.0", "", {}, "sha512-IKlE+pNvL2R+kVL1kEhUYqRxVqeFnjiIvHWDMLFXNaqyUdFXQM2wte44EfMYJNHkW16X991t2Zg8apKkhv7OBA=="], + + "flat-cache": ["flat-cache@3.2.0", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", "rimraf": "^3.0.2" } }, "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw=="], + + "flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="], + + "follow-redirects": ["follow-redirects@1.15.11", "", {}, "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ=="], + + "foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="], + + "forever-agent": ["forever-agent@0.6.1", "", {}, "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw=="], + + "form-data": ["form-data@4.0.4", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow=="], + + "fraction.js": ["fraction.js@4.3.7", "", {}, "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew=="], + + "framer-motion": ["framer-motion@12.23.24", "", { "dependencies": { "motion-dom": "^12.23.23", "motion-utils": "^12.23.6", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid"] }, "sha512-HMi5HRoRCTou+3fb3h9oTLyJGBxHfW+HnNE25tAXOvVx/IvwMHK0cx7IR4a2ZU6sh3IX1Z+4ts32PcYBOqka8w=="], + + "fs-constants": ["fs-constants@1.0.0", "", {}, "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="], + + "fs-extra": ["fs-extra@10.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ=="], + + "fs-minipass": ["fs-minipass@2.1.0", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg=="], + + "fs.realpath": ["fs.realpath@1.0.0", "", {}, "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="], + + "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], + + "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], + + "gauge": ["gauge@4.0.4", "", { "dependencies": { "aproba": "^1.0.3 || ^2.0.0", "color-support": "^1.1.3", "console-control-strings": "^1.1.0", "has-unicode": "^2.0.1", "signal-exit": "^3.0.7", "string-width": "^4.2.3", "strip-ansi": "^6.0.1", "wide-align": "^1.1.5" } }, "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg=="], + + "gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="], + + "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], + + "get-intrinsic": ["get-intrinsic@1.3.0", "", { "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" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="], + + "get-nonce": ["get-nonce@1.0.1", "", {}, "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="], + + "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="], + + "get-stream": ["get-stream@5.2.0", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="], + + "getpass": ["getpass@0.1.7", "", { "dependencies": { "assert-plus": "^1.0.0" } }, "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng=="], + + "gif.js": ["gif.js@0.2.0", "", {}, "sha512-bYxCoT8OZKmbxY8RN4qDiYuj4nrQDTzgLRcFVovyona1PTWNePzI4nzOmotnlOFIzTk/ZxAHtv+TfVLiBWj/hw=="], + + "gifuct-js": ["gifuct-js@2.1.2", "", { "dependencies": { "js-binary-schema-parser": "^2.0.3" } }, "sha512-rI2asw77u0mGgwhV3qA+OEgYqaDn5UNqgs+Bx0FGwSpuqfYn+Ir6RQY5ENNQ8SbIiG/m5gVa7CD5RriO4f4Lsg=="], + + "gifwrap": ["gifwrap@0.9.4", "", { "dependencies": { "image-q": "^4.0.0", "omggif": "^1.0.10" } }, "sha512-MDMwbhASQuVeD4JKd1fKgNgCRL3fGqMM4WaqpNhWO0JiMOAjbQdumbs4BbBZEy9/M00EHEjKN3HieVhCUlwjeQ=="], + + "glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], + + "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], + + "global": ["global@4.4.0", "", { "dependencies": { "min-document": "^2.19.0", "process": "^0.11.10" } }, "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w=="], + + "global-agent": ["global-agent@3.0.0", "", { "dependencies": { "boolean": "^3.0.1", "es6-error": "^4.1.1", "matcher": "^3.0.0", "roarr": "^2.15.3", "semver": "^7.3.2", "serialize-error": "^7.0.1" } }, "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q=="], + + "globals": ["globals@13.24.0", "", { "dependencies": { "type-fest": "^0.20.2" } }, "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ=="], + + "globalthis": ["globalthis@1.0.4", "", { "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" } }, "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ=="], + + "globby": ["globby@11.1.0", "", { "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.2.9", "ignore": "^5.2.0", "merge2": "^1.4.1", "slash": "^3.0.0" } }, "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g=="], + + "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], + + "got": ["got@11.8.6", "", { "dependencies": { "@sindresorhus/is": "^4.0.0", "@szmarczak/http-timer": "^4.0.5", "@types/cacheable-request": "^6.0.1", "@types/responselike": "^1.0.0", "cacheable-lookup": "^5.0.3", "cacheable-request": "^7.0.2", "decompress-response": "^6.0.0", "http2-wrapper": "^1.0.0-beta.5.2", "lowercase-keys": "^2.0.0", "p-cancelable": "^2.0.0", "responselike": "^2.0.0" } }, "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g=="], + + "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], + + "graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="], + + "gsap": ["gsap@3.13.0", "", {}, "sha512-QL7MJ2WMjm1PHWsoFrAQH/J8wUeqZvMtHO58qdekHpCfhvhSL4gSiz6vJf5EeMP0LOn3ZCprL2ki/gjED8ghVw=="], + + "har-schema": ["har-schema@2.0.0", "", {}, "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q=="], + + "har-validator": ["har-validator@5.1.5", "", { "dependencies": { "ajv": "^6.12.3", "har-schema": "^2.0.0" } }, "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w=="], + + "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], + + "has-property-descriptors": ["has-property-descriptors@1.0.2", "", { "dependencies": { "es-define-property": "^1.0.0" } }, "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg=="], + + "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="], + + "has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="], + + "has-unicode": ["has-unicode@2.0.1", "", {}, "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="], + + "hasha": ["hasha@2.2.0", "", { "dependencies": { "is-stream": "^1.0.1", "pinkie-promise": "^2.0.0" } }, "sha512-jZ38TU/EBiGKrmyTNNZgnvCZHNowiRI4+w/I9noMlekHTZH3KyGgvJLmhSgykeAQ9j2SYPDosM0Bg3wHfzibAQ=="], + + "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], + + "hosted-git-info": ["hosted-git-info@4.1.0", "", { "dependencies": { "lru-cache": "^6.0.0" } }, "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA=="], + + "http-cache-semantics": ["http-cache-semantics@4.2.0", "", {}, "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ=="], + + "http-proxy-agent": ["http-proxy-agent@5.0.0", "", { "dependencies": { "@tootallnate/once": "2", "agent-base": "6", "debug": "4" } }, "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w=="], + + "http-signature": ["http-signature@1.2.0", "", { "dependencies": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", "sshpk": "^1.7.0" } }, "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ=="], + + "http2-wrapper": ["http2-wrapper@1.0.3", "", { "dependencies": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.0.0" } }, "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg=="], + + "https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="], + + "humanize-ms": ["humanize-ms@1.2.1", "", { "dependencies": { "ms": "^2.0.0" } }, "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ=="], + + "icon-gen": ["icon-gen@2.1.0", "", { "dependencies": { "commander": "^6.2.0", "del": "^6.0.0", "mkdirp": "^1.0.4", "pngjs": "^6.0.0", "svg2png": "4.1.1", "uuid": "^8.3.1" }, "bin": "dist/bin/index.js" }, "sha512-rqIVvq9MJ8X7wnJW0NO8Eau/+5RWV7AH6L5vEt/U5Ajv5WefdDNDxGwJhGokyHuyBWeX7JqRMQ03tG0gAco4Eg=="], + + "iconv-corefoundation": ["iconv-corefoundation@1.1.7", "", { "dependencies": { "cli-truncate": "^2.1.0", "node-addon-api": "^1.6.3" }, "os": "darwin" }, "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ=="], + + "iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], + + "ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], + + "ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], + + "image-q": ["image-q@4.0.0", "", { "dependencies": { "@types/node": "16.9.1" } }, "sha512-PfJGVgIfKQJuq3s0tTDOKtztksibuUEbJQIYT3by6wctQo+Rdlh7ef4evJ5NCdxY4CfMbvFkocEwbl4BF8RlJw=="], + + "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], + + "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], + + "indent-string": ["indent-string@4.0.0", "", {}, "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="], + + "infer-owner": ["infer-owner@1.0.4", "", {}, "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A=="], + + "inflight": ["inflight@1.0.6", "", { "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="], + + "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], + + "invert-kv": ["invert-kv@1.0.0", "", {}, "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ=="], + + "ip-address": ["ip-address@10.0.1", "", {}, "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA=="], + + "is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="], + + "is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="], + + "is-ci": ["is-ci@3.0.1", "", { "dependencies": { "ci-info": "^3.2.0" }, "bin": "bin.js" }, "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ=="], + + "is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="], + + "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], + + "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], + + "is-function": ["is-function@1.0.2", "", {}, "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ=="], + + "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], + + "is-interactive": ["is-interactive@1.0.0", "", {}, "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w=="], + + "is-lambda": ["is-lambda@1.0.1", "", {}, "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ=="], + + "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], + + "is-path-cwd": ["is-path-cwd@2.2.0", "", {}, "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ=="], + + "is-path-inside": ["is-path-inside@3.0.3", "", {}, "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ=="], + + "is-stream": ["is-stream@1.1.0", "", {}, "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ=="], + + "is-typedarray": ["is-typedarray@1.0.0", "", {}, "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="], + + "is-unicode-supported": ["is-unicode-supported@0.1.0", "", {}, "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw=="], + + "is-utf8": ["is-utf8@0.2.1", "", {}, "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q=="], + + "isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="], + + "isbinaryfile": ["isbinaryfile@5.0.6", "", {}, "sha512-I+NmIfBHUl+r2wcDd6JwE9yWje/PIVY/R5/CmV8dXLZd5K+L9X2klAOwfAHNnondLXkbHyTAleQAWonpTJBTtw=="], + + "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], + + "ismobilejs": ["ismobilejs@1.1.1", "", {}, "sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw=="], + + "isstream": ["isstream@0.1.2", "", {}, "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g=="], + + "jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], + + "jake": ["jake@10.9.4", "", { "dependencies": { "async": "^3.2.6", "filelist": "^1.0.4", "picocolors": "^1.1.1" }, "bin": "bin/cli.js" }, "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA=="], + + "jimp": ["jimp@0.16.13", "", { "dependencies": { "@babel/runtime": "^7.7.2", "@jimp/custom": "^0.16.13", "@jimp/plugins": "^0.16.13", "@jimp/types": "^0.16.13", "regenerator-runtime": "^0.13.3" } }, "sha512-Bxz8q7V4rnCky9A0ktTNGA9SkNFVWRHodddI/DaAWZJzF7sVUlFYKQ60y9JGqrKpi48ECA/TnfMzzc5C70VByA=="], + + "jiti": ["jiti@1.21.7", "", { "bin": "bin/jiti.js" }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="], + + "jpeg-js": ["jpeg-js@0.4.4", "", {}, "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg=="], + + "js-binary-schema-parser": ["js-binary-schema-parser@2.0.3", "", {}, "sha512-xezGJmOb4lk/M1ZZLTR/jaBHQ4gG/lqQnJqdIv4721DMggsa1bDVlHXNeHYogaIEHD9vCRv0fcL4hMA+Coarkg=="], + + "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], + + "js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": "bin/js-yaml.js" }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="], + + "jsbn": ["jsbn@0.1.1", "", {}, "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg=="], + + "jsesc": ["jsesc@3.1.0", "", { "bin": "bin/jsesc" }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="], + + "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="], + + "json-schema": ["json-schema@0.4.0", "", {}, "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="], + + "json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], + + "json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="], + + "json-stringify-safe": ["json-stringify-safe@5.0.1", "", {}, "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="], + + "json5": ["json5@2.2.3", "", { "bin": "lib/cli.js" }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="], + + "jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="], + + "jsprim": ["jsprim@1.4.2", "", { "dependencies": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", "json-schema": "0.4.0", "verror": "1.10.0" } }, "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw=="], + + "kew": ["kew@0.7.0", "", {}, "sha512-IG6nm0+QtAMdXt9KvbgbGdvY50RSrw+U4sGZg+KlrSKPJEwVE5JVoI3d7RWfSMdBQneRheeAOj3lIjX5VL/9RQ=="], + + "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="], + + "klaw": ["klaw@1.3.1", "", { "optionalDependencies": { "graceful-fs": "^4.1.9" } }, "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw=="], + + "lazy-val": ["lazy-val@1.0.5", "", {}, "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q=="], + + "lazystream": ["lazystream@1.0.1", "", { "dependencies": { "readable-stream": "^2.0.5" } }, "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw=="], + + "lcid": ["lcid@1.0.0", "", { "dependencies": { "invert-kv": "^1.0.0" } }, "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw=="], + + "leven": ["leven@2.1.0", "", {}, "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA=="], + + "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="], + + "lightningcss": ["lightningcss@1.30.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-darwin-arm64": "1.30.1", "lightningcss-darwin-x64": "1.30.1", "lightningcss-freebsd-x64": "1.30.1", "lightningcss-linux-arm-gnueabihf": "1.30.1", "lightningcss-linux-arm64-gnu": "1.30.1", "lightningcss-linux-arm64-musl": "1.30.1", "lightningcss-linux-x64-gnu": "1.30.1", "lightningcss-linux-x64-musl": "1.30.1", "lightningcss-win32-arm64-msvc": "1.30.1", "lightningcss-win32-x64-msvc": "1.30.1" } }, "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg=="], + + "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ=="], + + "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA=="], + + "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig=="], + + "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.1", "", { "os": "linux", "cpu": "arm" }, "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q=="], + + "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw=="], + + "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ=="], + + "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.1", "", { "os": "linux", "cpu": "x64" }, "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw=="], + + "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.1", "", { "os": "linux", "cpu": "x64" }, "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ=="], + + "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA=="], + + "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.1", "", { "os": "win32", "cpu": "x64" }, "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg=="], + + "lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="], + + "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], + + "load-bmfont": ["load-bmfont@1.4.2", "", { "dependencies": { "buffer-equal": "0.0.1", "mime": "^1.3.4", "parse-bmfont-ascii": "^1.0.3", "parse-bmfont-binary": "^1.0.5", "parse-bmfont-xml": "^1.1.4", "phin": "^3.7.1", "xhr": "^2.0.1", "xtend": "^4.0.0" } }, "sha512-qElWkmjW9Oq1F9EI5Gt7aD9zcdHb9spJCW1L/dmPf7KzCCEJxq8nhHz5eCgI9aMf7vrG/wyaCqdsI+Iy9ZTlog=="], + + "load-json-file": ["load-json-file@1.1.0", "", { "dependencies": { "graceful-fs": "^4.1.2", "parse-json": "^2.2.0", "pify": "^2.0.0", "pinkie-promise": "^2.0.0", "strip-bom": "^2.0.0" } }, "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A=="], + + "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="], + + "lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="], + + "lodash.defaults": ["lodash.defaults@4.2.0", "", {}, "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ=="], + + "lodash.difference": ["lodash.difference@4.5.0", "", {}, "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA=="], + + "lodash.flatten": ["lodash.flatten@4.4.0", "", {}, "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g=="], + + "lodash.isplainobject": ["lodash.isplainobject@4.0.6", "", {}, "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="], + + "lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="], + + "lodash.union": ["lodash.union@4.6.0", "", {}, "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw=="], + + "log-symbols": ["log-symbols@4.1.0", "", { "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" } }, "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg=="], + + "loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": "cli.js" }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="], + + "lowercase-keys": ["lowercase-keys@2.0.0", "", {}, "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA=="], + + "lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], + + "lucide-react": ["lucide-react@0.545.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-7r1/yUuflQDSt4f1bpn5ZAocyIxcTyVyBBChSVtBKn5M+392cPmI5YJMWOJKk/HUWGm5wg83chlAZtCcGbEZtw=="], + + "lzma-native": ["lzma-native@8.0.6", "", { "dependencies": { "node-addon-api": "^3.1.0", "node-gyp-build": "^4.2.1", "readable-stream": "^3.6.0" }, "bin": { "lzmajs": "bin/lzmajs" } }, "sha512-09xfg67mkL2Lz20PrrDeNYZxzeW7ADtpYFbwSQh9U8+76RIzx5QsJBMy8qikv3hbUPfpy6hqwxt6FcGK81g9AA=="], + + "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], + + "make-fetch-happen": ["make-fetch-happen@10.2.1", "", { "dependencies": { "agentkeepalive": "^4.2.1", "cacache": "^16.1.0", "http-cache-semantics": "^4.1.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", "is-lambda": "^1.0.1", "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-fetch": "^2.0.3", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^0.6.3", "promise-retry": "^2.0.1", "socks-proxy-agent": "^7.0.0", "ssri": "^9.0.0" } }, "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w=="], + + "matcher": ["matcher@3.0.0", "", { "dependencies": { "escape-string-regexp": "^4.0.0" } }, "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng=="], + + "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], + + "mediabunny": ["mediabunny@1.25.1", "", { "dependencies": { "@types/dom-mediacapture-transform": "^0.1.11", "@types/dom-webcodecs": "0.1.13" } }, "sha512-0Rrd47PMCVJbTPA7IJaXPCupV5/RZ/icgr+a0qExRJAr0n5vB4fsGSo+fdHIehG0CrddXtVRvNZwFtJz709yfA=="], + + "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], + + "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], + + "mime": ["mime@2.6.0", "", { "bin": "cli.js" }, "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg=="], + + "mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], + + "mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], + + "mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="], + + "mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="], + + "min-document": ["min-document@2.19.2", "", { "dependencies": { "dom-walk": "^0.1.0" } }, "sha512-8S5I8db/uZN8r9HSLFVWPdJCvYOejMcEC82VIzNUc6Zkklf/d1gg2psfE79/vyhWOj4+J8MtwmoOz3TmvaGu5A=="], + + "minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], + + "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], + + "minipass": ["minipass@5.0.0", "", {}, "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="], + + "minipass-collect": ["minipass-collect@1.0.2", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA=="], + + "minipass-fetch": ["minipass-fetch@2.1.2", "", { "dependencies": { "minipass": "^3.1.6", "minipass-sized": "^1.0.3", "minizlib": "^2.1.2" }, "optionalDependencies": { "encoding": "^0.1.13" } }, "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA=="], + + "minipass-flush": ["minipass-flush@1.0.5", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw=="], + + "minipass-pipeline": ["minipass-pipeline@1.2.4", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A=="], + + "minipass-sized": ["minipass-sized@1.0.3", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g=="], + + "minizlib": ["minizlib@2.1.2", "", { "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg=="], + + "mkdirp": ["mkdirp@1.0.4", "", { "bin": "bin/cmd.js" }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="], + + "motion": ["motion@12.23.24", "", { "dependencies": { "framer-motion": "^12.23.24", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid"] }, "sha512-Rc5E7oe2YZ72N//S3QXGzbnXgqNrTESv8KKxABR20q2FLch9gHLo0JLyYo2hZ238bZ9Gx6cWhj9VO0IgwbMjCw=="], + + "motion-dom": ["motion-dom@12.23.23", "", { "dependencies": { "motion-utils": "^12.23.6" } }, "sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA=="], + + "motion-utils": ["motion-utils@12.23.6", "", {}, "sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ=="], + + "mp4box": ["mp4box@2.2.0", "", {}, "sha512-tE+L7wdhSuwBKZGjUzj03Qzj4lWyOw8pHSPyLnvHTKx92NJGkJls0pcEusUHWEh5gWVBlhdu79STJh4Bubz9mQ=="], + + "mri": ["mri@1.1.4", "", {}, "sha512-6y7IjGPm8AzlvoUrwAaw1tLnUBudaS3752vcd8JtrpGGQn+rXIe63LFVHm/YMwtqAuh+LJPCFdlLYPWM1nYn6w=="], + + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="], + + "nanoid": ["nanoid@3.3.11", "", { "bin": "bin/nanoid.cjs" }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], + + "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="], + + "negotiator": ["negotiator@0.6.4", "", {}, "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w=="], + + "node-abi": ["node-abi@3.78.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-E2wEyrgX/CqvicaQYU3Ze1PFGjc4QYPGsjUrlYkqAE0WjHEZwgOsGMPMzkMse4LjJbDmaEuDX3CM036j5K2DSQ=="], + + "node-addon-api": ["node-addon-api@3.2.1", "", {}, "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A=="], + + "node-api-version": ["node-api-version@0.1.4", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-KGXihXdUChwJAOHO53bv9/vXcLmdUsZ6jIptbvYvkpKfth+r7jw44JkVxQFA3kX5nQjzjmGu1uAu/xNNLNlI5g=="], + + "node-gyp": ["node-gyp@9.4.1", "", { "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", "glob": "^7.1.4", "graceful-fs": "^4.2.6", "make-fetch-happen": "^10.0.3", "nopt": "^6.0.0", "npmlog": "^6.0.0", "rimraf": "^3.0.2", "semver": "^7.3.5", "tar": "^6.1.2", "which": "^2.0.2" }, "bin": "bin/node-gyp.js" }, "sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ=="], + + "node-gyp-build": ["node-gyp-build@4.8.4", "", { "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", "node-gyp-build-test": "build-test.js" } }, "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ=="], + + "node-releases": ["node-releases@2.0.23", "", {}, "sha512-cCmFDMSm26S6tQSDpBCg/NR8NENrVPhAJSf+XbxBG4rPFaaonlEoE9wHQmun+cls499TQGSb7ZyPBRlzgKfpeg=="], + + "nopt": ["nopt@6.0.0", "", { "dependencies": { "abbrev": "^1.0.0" }, "bin": "bin/nopt.js" }, "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g=="], + + "normalize-package-data": ["normalize-package-data@2.5.0", "", { "dependencies": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } }, "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA=="], + + "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], + + "normalize-range": ["normalize-range@0.1.2", "", {}, "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA=="], + + "normalize-url": ["normalize-url@6.1.0", "", {}, "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A=="], + + "npmlog": ["npmlog@6.0.2", "", { "dependencies": { "are-we-there-yet": "^3.0.0", "console-control-strings": "^1.1.0", "gauge": "^4.0.3", "set-blocking": "^2.0.0" } }, "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg=="], + + "number-is-nan": ["number-is-nan@1.0.1", "", {}, "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ=="], + + "oauth-sign": ["oauth-sign@0.9.0", "", {}, "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="], + + "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], + + "object-hash": ["object-hash@3.0.0", "", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="], + + "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="], + + "object-keys": ["object-keys@1.1.1", "", {}, "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="], + + "obug": ["obug@2.1.1", "", {}, "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ=="], + + "omggif": ["omggif@1.0.10", "", {}, "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw=="], + + "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], + + "onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="], + + "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="], + + "ora": ["ora@5.4.1", "", { "dependencies": { "bl": "^4.1.0", "chalk": "^4.1.0", "cli-cursor": "^3.1.0", "cli-spinners": "^2.5.0", "is-interactive": "^1.0.0", "is-unicode-supported": "^0.1.0", "log-symbols": "^4.1.0", "strip-ansi": "^6.0.0", "wcwidth": "^1.0.1" } }, "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ=="], + + "os-locale": ["os-locale@1.4.0", "", { "dependencies": { "lcid": "^1.0.0" } }, "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g=="], + + "p-cancelable": ["p-cancelable@2.1.1", "", {}, "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg=="], + + "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], + + "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], + + "p-map": ["p-map@4.0.0", "", { "dependencies": { "aggregate-error": "^3.0.0" } }, "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ=="], + + "package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="], + + "pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="], + + "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], + + "parse-bmfont-ascii": ["parse-bmfont-ascii@1.0.6", "", {}, "sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA=="], + + "parse-bmfont-binary": ["parse-bmfont-binary@1.0.6", "", {}, "sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA=="], + + "parse-bmfont-xml": ["parse-bmfont-xml@1.1.6", "", { "dependencies": { "xml-parse-from-string": "^1.0.0", "xml2js": "^0.5.0" } }, "sha512-0cEliVMZEhrFDwMh4SxIyVJpqYoOWDJ9P895tFuS+XuNzI5UBmBk5U5O4KuJdTnZpSBI4LFA2+ZiJaiwfSwlMA=="], + + "parse-headers": ["parse-headers@2.0.6", "", {}, "sha512-Tz11t3uKztEW5FEVZnj1ox8GKblWn+PvHY9TmJV5Mll2uHEwRdR/5Li1OlXoECjLYkApdhWy44ocONwXLiKO5A=="], + + "parse-json": ["parse-json@2.2.0", "", { "dependencies": { "error-ex": "^1.2.0" } }, "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ=="], + + "parse-svg-path": ["parse-svg-path@0.1.2", "", {}, "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ=="], + + "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], + + "path-is-absolute": ["path-is-absolute@1.0.1", "", {}, "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="], + + "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], + + "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="], + + "path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], + + "path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="], + + "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], + + "peek-readable": ["peek-readable@4.1.0", "", {}, "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg=="], + + "pend": ["pend@1.2.0", "", {}, "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="], + + "performance-now": ["performance-now@2.1.0", "", {}, "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow=="], + + "phantomjs-prebuilt": ["phantomjs-prebuilt@2.1.16", "", { "dependencies": { "es6-promise": "^4.0.3", "extract-zip": "^1.6.5", "fs-extra": "^1.0.0", "hasha": "^2.2.0", "kew": "^0.7.0", "progress": "^1.1.8", "request": "^2.81.0", "request-progress": "^2.0.1", "which": "^1.2.10" }, "bin": { "phantomjs": "bin/phantomjs" } }, "sha512-PIiRzBhW85xco2fuj41FmsyuYHKjKuXWmhjy3A/Y+CMpN/63TV+s9uzfVhsUwFe0G77xWtHBG8xmXf5BqEUEuQ=="], + + "phin": ["phin@2.9.3", "", {}, "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA=="], + + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], + + "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], + + "pify": ["pify@2.3.0", "", {}, "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="], + + "pinkie": ["pinkie@2.0.4", "", {}, "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg=="], + + "pinkie-promise": ["pinkie-promise@2.0.1", "", { "dependencies": { "pinkie": "^2.0.0" } }, "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw=="], + + "pirates": ["pirates@4.0.7", "", {}, "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA=="], + + "pixelmatch": ["pixelmatch@4.0.2", "", { "dependencies": { "pngjs": "^3.0.0" }, "bin": "bin/pixelmatch" }, "sha512-J8B6xqiO37sU/gkcMglv6h5Jbd9xNER7aHzpfRdNmV4IbQBzBpe4l9XmbG+xPF/znacgu2jfEw+wHffaq/YkXA=="], + + "pixi.js": ["pixi.js@8.14.0", "", { "dependencies": { "@pixi/colord": "^2.9.6", "@types/css-font-loading-module": "^0.0.12", "@types/earcut": "^3.0.0", "@webgpu/types": "^0.1.40", "@xmldom/xmldom": "^0.8.10", "earcut": "^3.0.2", "eventemitter3": "^5.0.1", "gifuct-js": "^2.1.2", "ismobilejs": "^1.1.1", "parse-svg-path": "^0.1.2", "tiny-lru": "^11.4.5" } }, "sha512-ituDiEBb1Oqx56RYwTtC6MjPUhPfF/i15fpUv5oEqmzC/ce3SaSumulJcOjKG7+y0J0Ekl9Rl4XTxaUw+MVFZw=="], + + "plist": ["plist@3.1.0", "", { "dependencies": { "@xmldom/xmldom": "^0.8.8", "base64-js": "^1.5.1", "xmlbuilder": "^15.1.1" } }, "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ=="], + + "pn": ["pn@1.1.0", "", {}, "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA=="], + + "pngjs": ["pngjs@6.0.0", "", {}, "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg=="], + + "postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="], + + "postcss-import": ["postcss-import@15.1.0", "", { "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", "resolve": "^1.1.7" }, "peerDependencies": { "postcss": "^8.0.0" } }, "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew=="], + + "postcss-js": ["postcss-js@4.1.0", "", { "dependencies": { "camelcase-css": "^2.0.1" }, "peerDependencies": { "postcss": "^8.4.21" } }, "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw=="], + + "postcss-load-config": ["postcss-load-config@6.0.1", "", { "dependencies": { "lilconfig": "^3.1.1" }, "peerDependencies": { "jiti": ">=1.21.0", "postcss": ">=8.0.9", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["tsx", "yaml"] }, "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g=="], + + "postcss-nested": ["postcss-nested@6.2.0", "", { "dependencies": { "postcss-selector-parser": "^6.1.1" }, "peerDependencies": { "postcss": "^8.2.14" } }, "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ=="], + + "postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], + + "postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="], + + "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="], + + "process": ["process@0.11.10", "", {}, "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="], + + "process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="], + + "progress": ["progress@2.0.3", "", {}, "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="], + + "promise-inflight": ["promise-inflight@1.0.1", "", {}, "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g=="], + + "promise-retry": ["promise-retry@2.0.1", "", { "dependencies": { "err-code": "^2.0.2", "retry": "^0.12.0" } }, "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g=="], + + "prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="], + + "psl": ["psl@1.15.0", "", { "dependencies": { "punycode": "^2.3.1" } }, "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w=="], + + "pump": ["pump@3.0.3", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA=="], + + "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], + + "pure-rand": ["pure-rand@7.0.1", "", {}, "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ=="], + + "qs": ["qs@6.14.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w=="], + + "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], + + "quick-lru": ["quick-lru@5.1.1", "", {}, "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA=="], + + "re-resizable": ["re-resizable@6.11.2", "", { "peerDependencies": { "react": "^16.13.1 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-2xI2P3OHs5qw7K0Ud1aLILK6MQxW50TcO+DetD9eIV58j84TqYeHoZcL9H4GXFXXIh7afhH8mv5iUCXII7OW7A=="], + + "react": ["react@18.3.1", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ=="], + + "react-dom": ["react-dom@18.3.1", "", { "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" }, "peerDependencies": { "react": "^18.3.1" } }, "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw=="], + + "react-draggable": ["react-draggable@4.4.6", "", { "dependencies": { "clsx": "^1.1.1", "prop-types": "^15.8.1" }, "peerDependencies": { "react": ">= 16.3.0", "react-dom": ">= 16.3.0" } }, "sha512-LtY5Xw1zTPqHkVmtM3X8MUOxNDOUhv/khTgBgrUvwaS064bwVvxT+q5El0uUFNx5IEPKXuRejr7UqLwBIg5pdw=="], + + "react-icons": ["react-icons@5.5.0", "", { "peerDependencies": { "react": "*" } }, "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw=="], + + "react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="], + + "react-refresh": ["react-refresh@0.17.0", "", {}, "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ=="], + + "react-remove-scroll": ["react-remove-scroll@2.7.1", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA=="], + + "react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.8", "", { "dependencies": { "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q=="], + + "react-resizable-panels": ["react-resizable-panels@3.0.6", "", { "peerDependencies": { "react": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-b3qKHQ3MLqOgSS+FRYKapNkJZf5EQzuf6+RLiq1/IlTHw99YrZ2NJZLk4hQIzTnnIkRg2LUqyVinu6YWWpUYew=="], + + "react-rnd": ["react-rnd@10.5.2", "", { "dependencies": { "re-resizable": "6.11.2", "react-draggable": "4.4.6", "tslib": "2.6.2" }, "peerDependencies": { "react": ">=16.3.0", "react-dom": ">=16.3.0" } }, "sha512-0Tm4x7k7pfHf2snewJA8x7Nwgt3LV+58MVEWOVsFjk51eYruFEa6Wy7BNdxt4/lH0wIRsu7Gm3KjSXY2w7YaNw=="], + + "react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="], + + "read-cache": ["read-cache@1.0.0", "", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="], + + "read-config-file": ["read-config-file@6.3.2", "", { "dependencies": { "config-file-ts": "^0.2.4", "dotenv": "^9.0.2", "dotenv-expand": "^5.1.0", "js-yaml": "^4.1.0", "json5": "^2.2.0", "lazy-val": "^1.0.4" } }, "sha512-M80lpCjnE6Wt6zb98DoW8WHR09nzMSpu8XHtPkiTHrJ5Az9CybfeQhTJ8D7saeBHpGhLPIVyA8lcL6ZmdKwY6Q=="], + + "read-pkg": ["read-pkg@1.1.0", "", { "dependencies": { "load-json-file": "^1.0.0", "normalize-package-data": "^2.3.2", "path-type": "^1.0.0" } }, "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ=="], + + "read-pkg-up": ["read-pkg-up@1.0.1", "", { "dependencies": { "find-up": "^1.0.0", "read-pkg": "^1.0.0" } }, "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A=="], + + "readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], + + "readable-web-to-node-stream": ["readable-web-to-node-stream@3.0.4", "", { "dependencies": { "readable-stream": "^4.7.0" } }, "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw=="], + + "readdir-glob": ["readdir-glob@1.1.3", "", { "dependencies": { "minimatch": "^5.1.0" } }, "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA=="], + + "readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], + + "regenerator-runtime": ["regenerator-runtime@0.13.11", "", {}, "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="], + + "request": ["request@2.88.2", "", { "dependencies": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", "caseless": "~0.12.0", "combined-stream": "~1.0.6", "extend": "~3.0.2", "forever-agent": "~0.6.1", "form-data": "~2.3.2", "har-validator": "~5.1.3", "http-signature": "~1.2.0", "is-typedarray": "~1.0.0", "isstream": "~0.1.2", "json-stringify-safe": "~5.0.1", "mime-types": "~2.1.19", "oauth-sign": "~0.9.0", "performance-now": "^2.1.0", "qs": "~6.5.2", "safe-buffer": "^5.1.2", "tough-cookie": "~2.5.0", "tunnel-agent": "^0.6.0", "uuid": "^3.3.2" } }, "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw=="], + + "request-progress": ["request-progress@2.0.1", "", { "dependencies": { "throttleit": "^1.0.0" } }, "sha512-dxdraeZVUNEn9AvLrxkgB2k6buTlym71dJk1fk4v8j3Ou3RKNm07BcgbHdj2lLgYGfqX71F+awb1MR+tWPFJzA=="], + + "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], + + "require-main-filename": ["require-main-filename@1.0.1", "", {}, "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug=="], + + "resize-observer-polyfill": ["resize-observer-polyfill@1.5.1", "", {}, "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="], + + "resolve": ["resolve@1.22.10", "", { "dependencies": { "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w=="], + + "resolve-alpn": ["resolve-alpn@1.2.1", "", {}, "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g=="], + + "resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], + + "responselike": ["responselike@2.0.1", "", { "dependencies": { "lowercase-keys": "^2.0.0" } }, "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw=="], + + "restore-cursor": ["restore-cursor@3.1.0", "", { "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" } }, "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA=="], + + "retry": ["retry@0.12.0", "", {}, "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow=="], + + "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], + + "rimraf": ["rimraf@3.0.2", "", { "dependencies": { "glob": "^7.1.3" }, "bin": "bin.js" }, "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="], + + "roarr": ["roarr@2.15.4", "", { "dependencies": { "boolean": "^3.0.1", "detect-node": "^2.0.4", "globalthis": "^1.0.1", "json-stringify-safe": "^5.0.1", "semver-compare": "^1.0.0", "sprintf-js": "^1.1.2" } }, "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A=="], + + "rollup": ["rollup@4.52.4", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.52.4", "@rollup/rollup-android-arm64": "4.52.4", "@rollup/rollup-darwin-arm64": "4.52.4", "@rollup/rollup-darwin-x64": "4.52.4", "@rollup/rollup-freebsd-arm64": "4.52.4", "@rollup/rollup-freebsd-x64": "4.52.4", "@rollup/rollup-linux-arm-gnueabihf": "4.52.4", "@rollup/rollup-linux-arm-musleabihf": "4.52.4", "@rollup/rollup-linux-arm64-gnu": "4.52.4", "@rollup/rollup-linux-arm64-musl": "4.52.4", "@rollup/rollup-linux-loong64-gnu": "4.52.4", "@rollup/rollup-linux-ppc64-gnu": "4.52.4", "@rollup/rollup-linux-riscv64-gnu": "4.52.4", "@rollup/rollup-linux-riscv64-musl": "4.52.4", "@rollup/rollup-linux-s390x-gnu": "4.52.4", "@rollup/rollup-linux-x64-gnu": "4.52.4", "@rollup/rollup-linux-x64-musl": "4.52.4", "@rollup/rollup-openharmony-arm64": "4.52.4", "@rollup/rollup-win32-arm64-msvc": "4.52.4", "@rollup/rollup-win32-ia32-msvc": "4.52.4", "@rollup/rollup-win32-x64-gnu": "4.52.4", "@rollup/rollup-win32-x64-msvc": "4.52.4", "fsevents": "~2.3.2" }, "bin": "dist/bin/rollup" }, "sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ=="], + + "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], + + "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], + + "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], + + "sanitize-filename": ["sanitize-filename@1.6.3", "", { "dependencies": { "truncate-utf8-bytes": "^1.0.0" } }, "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg=="], + + "sax": ["sax@1.4.1", "", {}, "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="], + + "scheduler": ["scheduler@0.23.2", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="], + + "semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], + + "semver-compare": ["semver-compare@1.0.0", "", {}, "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow=="], + + "serialize-error": ["serialize-error@7.0.1", "", { "dependencies": { "type-fest": "^0.13.1" } }, "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw=="], + + "set-blocking": ["set-blocking@2.0.0", "", {}, "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="], + + "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], + + "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], + + "side-channel": ["side-channel@1.1.0", "", { "dependencies": { "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" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="], + + "side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="], + + "side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="], + + "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "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" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="], + + "siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="], + + "signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], + + "simple-update-notifier": ["simple-update-notifier@2.0.0", "", { "dependencies": { "semver": "^7.5.3" } }, "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w=="], + + "slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="], + + "slice-ansi": ["slice-ansi@3.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", "is-fullwidth-code-point": "^3.0.0" } }, "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ=="], + + "smart-buffer": ["smart-buffer@4.2.0", "", {}, "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="], + + "socks": ["socks@2.8.7", "", { "dependencies": { "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" } }, "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A=="], + + "socks-proxy-agent": ["socks-proxy-agent@7.0.0", "", { "dependencies": { "agent-base": "^6.0.2", "debug": "^4.3.3", "socks": "^2.6.2" } }, "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww=="], + + "sonner": ["sonner@2.0.7", "", { "peerDependencies": { "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w=="], + + "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], + + "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], + + "source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="], + + "spdx-correct": ["spdx-correct@3.2.0", "", { "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA=="], + + "spdx-exceptions": ["spdx-exceptions@2.5.0", "", {}, "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w=="], + + "spdx-expression-parse": ["spdx-expression-parse@3.0.1", "", { "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q=="], + + "spdx-license-ids": ["spdx-license-ids@3.0.22", "", {}, "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ=="], + + "sprintf-js": ["sprintf-js@1.1.3", "", {}, "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="], + + "sshpk": ["sshpk@1.18.0", "", { "dependencies": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", "bcrypt-pbkdf": "^1.0.0", "dashdash": "^1.12.0", "ecc-jsbn": "~0.1.1", "getpass": "^0.1.1", "jsbn": "~0.1.0", "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" }, "bin": { "sshpk-conv": "bin/sshpk-conv", "sshpk-sign": "bin/sshpk-sign", "sshpk-verify": "bin/sshpk-verify" } }, "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ=="], + + "ssri": ["ssri@9.0.1", "", { "dependencies": { "minipass": "^3.1.1" } }, "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q=="], + + "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="], + + "stat-mode": ["stat-mode@1.0.0", "", {}, "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg=="], + + "std-env": ["std-env@3.10.0", "", {}, "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg=="], + + "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + + "string-width-cjs": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + + "string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="], + + "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "strip-ansi-cjs": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "strip-bom": ["strip-bom@2.0.0", "", { "dependencies": { "is-utf8": "^0.2.0" } }, "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g=="], + + "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], + + "strtok3": ["strtok3@6.3.0", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "peek-readable": "^4.1.0" } }, "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw=="], + + "sucrase": ["sucrase@3.35.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", "glob": "^10.3.10", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", "ts-interface-checker": "^0.1.9" }, "bin": { "sucrase": "bin/sucrase", "sucrase-node": "bin/sucrase-node" } }, "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA=="], + + "sumchecker": ["sumchecker@3.0.1", "", { "dependencies": { "debug": "^4.1.0" } }, "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg=="], + + "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], + + "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], + + "svg2png": ["svg2png@4.1.1", "", { "dependencies": { "file-url": "^2.0.0", "phantomjs-prebuilt": "^2.1.14", "pn": "^1.0.0", "yargs": "^6.5.0" }, "bin": "bin/svg2png-cli.js" }, "sha512-9tOp9Ugjlunuf1ugqkhiYboTmTaTI7p48dz5ZjNA5NQJ5xS1NLTZZ1tF8vkJOIBb/ZwxGJsKZvRWqVpo4q9z9Q=="], + + "tailwind-merge": ["tailwind-merge@3.3.1", "", {}, "sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g=="], + + "tailwindcss": ["tailwindcss@3.4.18", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", "chokidar": "^3.6.0", "didyoumean": "^1.2.2", "dlv": "^1.1.3", "fast-glob": "^3.3.2", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", "jiti": "^1.21.7", "lilconfig": "^3.1.3", "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.1.1", "postcss": "^8.4.47", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", "postcss-nested": "^6.2.0", "postcss-selector-parser": "^6.1.2", "resolve": "^1.22.8", "sucrase": "^3.35.0" }, "bin": { "tailwind": "lib/cli.js", "tailwindcss": "lib/cli.js" } }, "sha512-6A2rnmW5xZMdw11LYjhcI5846rt9pbLSabY5XPxo+XWdxwZaFEn47Go4NzFiHu9sNNmr/kXivP1vStfvMaK1GQ=="], + + "tailwindcss-animate": ["tailwindcss-animate@1.0.7", "", { "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders" } }, "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA=="], + + "tar": ["tar@6.2.1", "", { "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" } }, "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A=="], + + "tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="], + + "temp-file": ["temp-file@3.4.0", "", { "dependencies": { "async-exit-hook": "^2.0.1", "fs-extra": "^10.0.0" } }, "sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg=="], + + "terser": ["terser@5.44.1", "", { "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": "bin/terser" }, "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw=="], + + "text-table": ["text-table@0.2.0", "", {}, "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw=="], + + "thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="], + + "thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="], + + "throttleit": ["throttleit@1.0.1", "", {}, "sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ=="], + + "timm": ["timm@1.7.1", "", {}, "sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw=="], + + "tiny-lru": ["tiny-lru@11.4.5", "", {}, "sha512-hkcz3FjNJfKXjV4mjQ1OrXSLAehg8Hw+cEZclOVT+5c/cWQWImQ9wolzTjth+dmmDe++p3bme3fTxz6Q4Etsqw=="], + + "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], + + "tinycolor2": ["tinycolor2@1.6.0", "", {}, "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw=="], + + "tinyexec": ["tinyexec@1.0.2", "", {}, "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg=="], + + "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], + + "tinyrainbow": ["tinyrainbow@3.0.3", "", {}, "sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q=="], + + "tmp": ["tmp@0.2.5", "", {}, "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow=="], + + "tmp-promise": ["tmp-promise@3.0.3", "", { "dependencies": { "tmp": "^0.2.0" } }, "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ=="], + + "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], + + "token-types": ["token-types@4.2.1", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ=="], + + "tough-cookie": ["tough-cookie@2.5.0", "", { "dependencies": { "psl": "^1.1.28", "punycode": "^2.1.1" } }, "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g=="], + + "truncate-utf8-bytes": ["truncate-utf8-bytes@1.0.2", "", { "dependencies": { "utf8-byte-length": "^1.0.1" } }, "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ=="], + + "ts-api-utils": ["ts-api-utils@1.4.3", "", { "peerDependencies": { "typescript": ">=4.2.0" } }, "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw=="], + + "ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="], + + "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + + "tunnel-agent": ["tunnel-agent@0.6.0", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w=="], + + "tweetnacl": ["tweetnacl@0.14.5", "", {}, "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="], + + "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], + + "type-fest": ["type-fest@0.20.2", "", {}, "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ=="], + + "typedarray": ["typedarray@0.0.6", "", {}, "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA=="], + + "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + + "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], + + "unique-filename": ["unique-filename@2.0.1", "", { "dependencies": { "unique-slug": "^3.0.0" } }, "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A=="], + + "unique-slug": ["unique-slug@3.0.0", "", { "dependencies": { "imurmurhash": "^0.1.4" } }, "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w=="], + + "universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="], + + "update-browserslist-db": ["update-browserslist-db@1.1.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw=="], + + "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], + + "url": ["url@0.11.4", "", { "dependencies": { "punycode": "^1.4.1", "qs": "^6.12.3" } }, "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg=="], + + "use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="], + + "use-sidecar": ["use-sidecar@1.1.3", "", { "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ=="], + + "utf8-byte-length": ["utf8-byte-length@1.0.5", "", {}, "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA=="], + + "utif": ["utif@2.0.1", "", { "dependencies": { "pako": "^1.0.5" } }, "sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg=="], + + "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], + + "uuid": ["uuid@13.0.0", "", { "bin": "dist-node/bin/uuid" }, "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w=="], + + "validate-npm-package-license": ["validate-npm-package-license@3.0.4", "", { "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew=="], + + "verror": ["verror@1.10.1", "", { "dependencies": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" } }, "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg=="], + + "vite": ["vite@5.4.20", "", { "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", "rollup": "^4.20.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["less", "sass", "sass-embedded", "stylus", "sugarss"], "bin": "bin/vite.js" }, "sha512-j3lYzGC3P+B5Yfy/pfKNgVEg4+UtcIJcVRt2cDjIOmhLourAqPqf8P7acgxeiSgUB7E3p2P8/3gNIgDLpwzs4g=="], + + "vite-plugin-electron": ["vite-plugin-electron@0.28.8", "", { "peerDependencies": { "vite-plugin-electron-renderer": "*" } }, "sha512-ir+B21oSGK9j23OEvt4EXyco9xDCaF6OGFe0V/8Zc0yL2+HMyQ6mmNQEIhXsEsZCSfIowBpwQBeHH4wVsfraeg=="], + + "vite-plugin-electron-renderer": ["vite-plugin-electron-renderer@0.14.6", "", {}, "sha512-oqkWFa7kQIkvHXG7+Mnl1RTroA4sP0yesKatmAy0gjZC4VwUqlvF9IvOpHd1fpLWsqYX/eZlVxlhULNtaQ78Jw=="], + + "vitest": ["vitest@4.0.17", "", { "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" }, "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": "*" }, "optionalPeers": ["@edge-runtime/vm", "@opentelemetry/api", "@types/node", "@vitest/browser-playwright", "@vitest/browser-preview", "@vitest/browser-webdriverio", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-FQMeF0DJdWY0iOnbv466n/0BudNdKj1l5jYgl5JVTwjSsZSlqyXFt/9+1sEyhR6CLowbZpV7O1sCHrzBhucKKg=="], + + "wcwidth": ["wcwidth@1.0.1", "", { "dependencies": { "defaults": "^1.0.3" } }, "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg=="], + + "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], + + "which-module": ["which-module@1.0.0", "", {}, "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ=="], + + "why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="], + + "wide-align": ["wide-align@1.1.5", "", { "dependencies": { "string-width": "^1.0.2 || 2 || 3 || 4" } }, "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg=="], + + "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], + + "wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + + "wrap-ansi-cjs": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + + "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], + + "ws": ["ws@8.19.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg=="], + + "xhr": ["xhr@2.6.0", "", { "dependencies": { "global": "~4.4.0", "is-function": "^1.0.1", "parse-headers": "^2.0.0", "xtend": "^4.0.0" } }, "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA=="], + + "xml-parse-from-string": ["xml-parse-from-string@1.0.1", "", {}, "sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g=="], + + "xml2js": ["xml2js@0.5.0", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA=="], + + "xmlbuilder": ["xmlbuilder@15.1.1", "", {}, "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="], + + "xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="], + + "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], + + "yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + + "yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], + + "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], + + "yauzl": ["yauzl@2.10.0", "", { "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } }, "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g=="], + + "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], + + "zip-stream": ["zip-stream@4.1.1", "", { "dependencies": { "archiver-utils": "^3.0.4", "compress-commons": "^4.1.2", "readable-stream": "^3.6.0" } }, "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ=="], + + "@babel/core/semver": ["semver@6.3.1", "", { "bin": "bin/semver.js" }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": "bin/semver.js" }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@electron/asar/commander": ["commander@5.1.0", "", {}, "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg=="], + + "@electron/get/fs-extra": ["fs-extra@8.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g=="], + + "@electron/get/semver": ["semver@6.3.1", "", { "bin": "bin/semver.js" }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@electron/notarize/fs-extra": ["fs-extra@9.1.0", "", { "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ=="], + + "@electron/osx-sign/isbinaryfile": ["isbinaryfile@4.0.10", "", {}, "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw=="], + + "@electron/universal/@malept/cross-spawn-promise": ["@malept/cross-spawn-promise@1.1.1", "", { "dependencies": { "cross-spawn": "^7.0.1" } }, "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ=="], + + "@electron/universal/fs-extra": ["fs-extra@9.1.0", "", { "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ=="], + + "@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="], + + "@isaacs/cliui/strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="], + + "@isaacs/cliui/wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="], + + "@jimp/core/mkdirp": ["mkdirp@0.5.6", "", { "dependencies": { "minimist": "^1.2.6" }, "bin": "bin/cmd.js" }, "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw=="], + + "@jimp/png/pngjs": ["pngjs@3.4.0", "", {}, "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w=="], + + "@malept/flatpak-bundler/fs-extra": ["fs-extra@9.1.0", "", { "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ=="], + + "@pixi/utils/@types/earcut": ["@types/earcut@2.1.4", "", {}, "sha512-qp3m9PPz4gULB9MhjGID7wpo3gJ4bTGXm7ltNDsmOvsPduTeHp8wSW9YckBj3mljeOh4F0m2z/0JKAALRKbmLQ=="], + + "@pixi/utils/earcut": ["earcut@2.2.4", "", {}, "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ=="], + + "@pixi/utils/eventemitter3": ["eventemitter3@4.0.7", "", {}, "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="], + + "@types/cacheable-request/@types/node": ["@types/node@20.19.20", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-2Q7WS25j4pS1cS8yw3d6buNCVJukOTeQ39bAnwR6sOJbaxvyCGebzTMypDFN82CxBLnl+lSWVdCCWbRY6y9yZQ=="], + + "@types/dom-mediacapture-transform/@types/dom-webcodecs": ["@types/dom-webcodecs@0.1.17", "", {}, "sha512-IwKW5uKL0Zrv5ccUJpjIlqf7ppk2v29l/ZLQxLlwHxljBfnDD9Gxm+hzMkGM0AOAL/21H0pp7cTUYLiiVUGchA=="], + + "@types/fs-extra/@types/node": ["@types/node@20.19.20", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-2Q7WS25j4pS1cS8yw3d6buNCVJukOTeQ39bAnwR6sOJbaxvyCGebzTMypDFN82CxBLnl+lSWVdCCWbRY6y9yZQ=="], + + "@types/keyv/@types/node": ["@types/node@20.19.20", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-2Q7WS25j4pS1cS8yw3d6buNCVJukOTeQ39bAnwR6sOJbaxvyCGebzTMypDFN82CxBLnl+lSWVdCCWbRY6y9yZQ=="], + + "@types/plist/@types/node": ["@types/node@20.19.20", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-2Q7WS25j4pS1cS8yw3d6buNCVJukOTeQ39bAnwR6sOJbaxvyCGebzTMypDFN82CxBLnl+lSWVdCCWbRY6y9yZQ=="], + + "@types/responselike/@types/node": ["@types/node@20.19.20", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-2Q7WS25j4pS1cS8yw3d6buNCVJukOTeQ39bAnwR6sOJbaxvyCGebzTMypDFN82CxBLnl+lSWVdCCWbRY6y9yZQ=="], + + "@types/yauzl/@types/node": ["@types/node@20.19.20", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-2Q7WS25j4pS1cS8yw3d6buNCVJukOTeQ39bAnwR6sOJbaxvyCGebzTMypDFN82CxBLnl+lSWVdCCWbRY6y9yZQ=="], + + "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], + + "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + + "app-builder-lib/minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="], + + "archiver-utils/readable-stream": ["readable-stream@2.3.8", "", { "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" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], + + "args/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="], + + "cacache/glob": ["glob@8.1.0", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^5.0.1", "once": "^1.3.0" } }, "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ=="], + + "cacache/lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="], + + "cacache/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + + "clone-response/mimic-response": ["mimic-response@1.0.1", "", {}, "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ=="], + + "concat-stream/readable-stream": ["readable-stream@2.3.8", "", { "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" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], + + "config-file-ts/glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": "dist/esm/bin.mjs" }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="], + + "electron/@types/node": ["@types/node@22.19.6", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-qm+G8HuG6hOHQigsi7VGuLjUVu6TtBo/F05zvX04Mw2uCg9Dv0Qxy3Qw7j41SidlTcl5D/5yg0SEZqOB+EqZnQ=="], + + "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + + "filelist/minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="], + + "foreground-child/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + + "fs-minipass/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "hosted-git-info/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="], + + "icon-gen/commander": ["commander@6.2.1", "", {}, "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA=="], + + "icon-gen/uuid": ["uuid@8.3.2", "", { "bin": "dist/bin/uuid" }, "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="], + + "iconv-corefoundation/node-addon-api": ["node-addon-api@1.7.2", "", {}, "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg=="], + + "image-q/@types/node": ["@types/node@16.9.1", "", {}, "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g=="], + + "jsprim/extsprintf": ["extsprintf@1.3.0", "", {}, "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g=="], + + "jsprim/verror": ["verror@1.10.0", "", { "dependencies": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" } }, "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw=="], + + "lazystream/readable-stream": ["readable-stream@2.3.8", "", { "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" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], + + "load-bmfont/buffer-equal": ["buffer-equal@0.0.1", "", {}, "sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA=="], + + "load-bmfont/mime": ["mime@1.6.0", "", { "bin": "cli.js" }, "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="], + + "load-bmfont/phin": ["phin@3.7.1", "", { "dependencies": { "centra": "^2.7.0" } }, "sha512-GEazpTWwTZaEQ9RhL7Nyz0WwqilbqgLahDM3D0hxWwmVDI52nXEybHqiN6/elwpkJBhcuj+WbBu+QfT0uhPGfQ=="], + + "lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], + + "make-fetch-happen/lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="], + + "make-fetch-happen/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + + "minipass-collect/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "minipass-fetch/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "minipass-flush/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "minipass-pipeline/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "minipass-sized/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "normalize-package-data/hosted-git-info": ["hosted-git-info@2.8.9", "", {}, "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw=="], + + "normalize-package-data/semver": ["semver@5.7.2", "", { "bin": "bin/semver" }, "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="], + + "path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + + "phantomjs-prebuilt/extract-zip": ["extract-zip@1.7.0", "", { "dependencies": { "concat-stream": "^1.6.2", "debug": "^2.6.9", "mkdirp": "^0.5.4", "yauzl": "^2.10.0" }, "bin": "cli.js" }, "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA=="], + + "phantomjs-prebuilt/fs-extra": ["fs-extra@1.0.0", "", { "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^2.1.0", "klaw": "^1.0.0" } }, "sha512-VerQV6vEKuhDWD2HGOybV6v5I73syoc/cXAbKlgTC7M/oFVEtklWlp9QH2Ijw3IaWDOQcMkldSPa7zXy79Z/UQ=="], + + "phantomjs-prebuilt/progress": ["progress@1.1.8", "", {}, "sha512-UdA8mJ4weIkUBO224tIarHzuHs4HuYiJvsuGT7j/SPQiUJVjYvNDBIPa0hAorduOfjGohB/qHWRa/lrrWX/mXw=="], + + "phantomjs-prebuilt/which": ["which@1.3.1", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": "bin/which" }, "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ=="], + + "pixelmatch/pngjs": ["pngjs@3.4.0", "", {}, "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w=="], + + "react-draggable/clsx": ["clsx@1.2.1", "", {}, "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg=="], + + "react-rnd/tslib": ["tslib@2.6.2", "", {}, "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="], + + "read-pkg/path-type": ["path-type@1.1.0", "", { "dependencies": { "graceful-fs": "^4.1.2", "pify": "^2.0.0", "pinkie-promise": "^2.0.0" } }, "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg=="], + + "read-pkg-up/find-up": ["find-up@1.1.2", "", { "dependencies": { "path-exists": "^2.0.0", "pinkie-promise": "^2.0.0" } }, "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA=="], + + "readable-web-to-node-stream/readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="], + + "readdir-glob/minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="], + + "readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + + "request/form-data": ["form-data@2.3.3", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", "mime-types": "^2.1.12" } }, "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ=="], + + "request/qs": ["qs@6.5.3", "", {}, "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA=="], + + "request/uuid": ["uuid@3.4.0", "", { "bin": "bin/uuid" }, "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="], + + "serialize-error/type-fest": ["type-fest@0.13.1", "", {}, "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg=="], + + "ssri/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "sucrase/commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="], + + "sucrase/glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": "dist/esm/bin.mjs" }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="], + + "svg2png/yargs": ["yargs@6.6.0", "", { "dependencies": { "camelcase": "^3.0.0", "cliui": "^3.2.0", "decamelize": "^1.1.1", "get-caller-file": "^1.0.1", "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.0" } }, "sha512-6/QWTdisjnu5UHUzQGst+UOEuEVwIzFVGBjq3jMTFNs5WJQsH/X6nMURSaScIdF5txylr1Ao9bvbWiKi2yXbwA=="], + + "url/punycode": ["punycode@1.4.1", "", {}, "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ=="], + + "vitest/vite": ["vite@7.3.1", "", { "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" }, "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" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA=="], + + "xml2js/xmlbuilder": ["xmlbuilder@11.0.1", "", {}, "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="], + + "zip-stream/archiver-utils": ["archiver-utils@3.0.4", "", { "dependencies": { "glob": "^7.2.3", "graceful-fs": "^4.2.0", "lazystream": "^1.0.0", "lodash.defaults": "^4.2.0", "lodash.difference": "^4.5.0", "lodash.flatten": "^4.4.0", "lodash.isplainobject": "^4.0.6", "lodash.union": "^4.6.0", "normalize-path": "^3.0.0", "readable-stream": "^3.6.0" } }, "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw=="], + + "@electron/get/fs-extra/jsonfile": ["jsonfile@4.0.0", "", { "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg=="], + + "@electron/get/fs-extra/universalify": ["universalify@0.1.2", "", {}, "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="], + + "@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], + + "@isaacs/cliui/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], + + "@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], + + "@types/cacheable-request/@types/node/undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], + + "@types/fs-extra/@types/node/undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], + + "@types/keyv/@types/node/undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], + + "@types/plist/@types/node/undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], + + "@types/responselike/@types/node/undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], + + "@types/yauzl/@types/node/undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], + + "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + + "app-builder-lib/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + + "archiver-utils/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], + + "archiver-utils/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], + + "args/chalk/ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="], + + "args/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], + + "args/chalk/supports-color": ["supports-color@5.5.0", "", { "dependencies": { "has-flag": "^3.0.0" } }, "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="], + + "cacache/glob/minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="], + + "concat-stream/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], + + "concat-stream/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], + + "config-file-ts/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], + + "config-file-ts/glob/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="], + + "electron/@types/node/undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], + + "filelist/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + + "lazystream/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], + + "lazystream/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], + + "phantomjs-prebuilt/extract-zip/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], + + "phantomjs-prebuilt/extract-zip/mkdirp": ["mkdirp@0.5.6", "", { "dependencies": { "minimist": "^1.2.6" }, "bin": "bin/cmd.js" }, "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw=="], + + "phantomjs-prebuilt/fs-extra/jsonfile": ["jsonfile@2.4.0", "", { "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw=="], + + "read-pkg-up/find-up/path-exists": ["path-exists@2.1.0", "", { "dependencies": { "pinkie-promise": "^2.0.0" } }, "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ=="], + + "readable-web-to-node-stream/readable-stream/buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="], + + "readdir-glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + + "sucrase/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], + + "sucrase/glob/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="], + + "svg2png/yargs/camelcase": ["camelcase@3.0.0", "", {}, "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg=="], + + "svg2png/yargs/cliui": ["cliui@3.2.0", "", { "dependencies": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1", "wrap-ansi": "^2.0.0" } }, "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w=="], + + "svg2png/yargs/get-caller-file": ["get-caller-file@1.0.3", "", {}, "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w=="], + + "svg2png/yargs/string-width": ["string-width@1.0.2", "", { "dependencies": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", "strip-ansi": "^3.0.0" } }, "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw=="], + + "svg2png/yargs/y18n": ["y18n@3.2.2", "", {}, "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ=="], + + "svg2png/yargs/yargs-parser": ["yargs-parser@4.2.1", "", { "dependencies": { "camelcase": "^3.0.0" } }, "sha512-+QQWqC2xeL0N5/TE+TY6OGEqyNRM+g2/r712PDNYgiCdXYCApXf1vzfmDSLBxfGRwV+moTq/V8FnMI24JCm2Yg=="], + + "vitest/vite/esbuild": ["esbuild@0.27.2", "", { "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" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw=="], + + "args/chalk/ansi-styles/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="], + + "args/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="], + + "cacache/glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + + "config-file-ts/glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + + "phantomjs-prebuilt/extract-zip/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], + + "sucrase/glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + + "svg2png/yargs/cliui/strip-ansi": ["strip-ansi@3.0.1", "", { "dependencies": { "ansi-regex": "^2.0.0" } }, "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg=="], + + "svg2png/yargs/cliui/wrap-ansi": ["wrap-ansi@2.1.0", "", { "dependencies": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1" } }, "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw=="], + + "svg2png/yargs/string-width/is-fullwidth-code-point": ["is-fullwidth-code-point@1.0.0", "", { "dependencies": { "number-is-nan": "^1.0.0" } }, "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw=="], + + "svg2png/yargs/string-width/strip-ansi": ["strip-ansi@3.0.1", "", { "dependencies": { "ansi-regex": "^2.0.0" } }, "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg=="], + + "vitest/vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw=="], + + "vitest/vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.27.2", "", { "os": "android", "cpu": "arm" }, "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA=="], + + "vitest/vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.2", "", { "os": "android", "cpu": "arm64" }, "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA=="], + + "vitest/vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.27.2", "", { "os": "android", "cpu": "x64" }, "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A=="], + + "vitest/vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg=="], + + "vitest/vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA=="], + + "vitest/vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g=="], + + "vitest/vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA=="], + + "vitest/vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.2", "", { "os": "linux", "cpu": "arm" }, "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw=="], + + "vitest/vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw=="], + + "vitest/vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.2", "", { "os": "linux", "cpu": "ia32" }, "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w=="], + + "vitest/vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.2", "", { "os": "linux", "cpu": "none" }, "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg=="], + + "vitest/vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.2", "", { "os": "linux", "cpu": "none" }, "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw=="], + + "vitest/vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ=="], + + "vitest/vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.2", "", { "os": "linux", "cpu": "none" }, "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA=="], + + "vitest/vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w=="], + + "vitest/vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.2", "", { "os": "linux", "cpu": "x64" }, "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA=="], + + "vitest/vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.2", "", { "os": "none", "cpu": "x64" }, "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA=="], + + "vitest/vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg=="], + + "vitest/vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg=="], + + "vitest/vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg=="], + + "vitest/vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ=="], + + "vitest/vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.2", "", { "os": "win32", "cpu": "x64" }, "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ=="], + + "args/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="], + + "svg2png/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@2.1.1", "", {}, "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA=="], + + "svg2png/yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@2.1.1", "", {}, "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA=="], + } +} diff --git a/dist-electron/main.js b/dist-electron/main.js index 515edf4..0a8424b 100644 --- a/dist-electron/main.js +++ b/dist-electron/main.js @@ -1,423 +1,3366 @@ -import { ipcMain, screen, BrowserWindow, desktopCapturer, shell, app, dialog, nativeImage, Tray, Menu } from "electron"; -import { fileURLToPath } from "node:url"; -import path from "node:path"; -import fs from "node:fs/promises"; -const __dirname$1 = path.dirname(fileURLToPath(import.meta.url)); -const APP_ROOT = path.join(__dirname$1, ".."); -const VITE_DEV_SERVER_URL$1 = process.env["VITE_DEV_SERVER_URL"]; -const RENDERER_DIST$1 = path.join(APP_ROOT, "dist"); -let hudOverlayWindow = null; -ipcMain.on("hud-overlay-hide", () => { - if (hudOverlayWindow && !hudOverlayWindow.isDestroyed()) { - hudOverlayWindow.minimize(); - } +import { ipcMain as p, screen as Rt, BrowserWindow as Te, app as P, desktopCapturer as es, shell as ts, dialog as Ie, nativeImage as ss, Tray as rs, Menu as is } from "electron"; +import { fileURLToPath as Lt } from "node:url"; +import m from "node:path"; +import W from "node:fs/promises"; +import { WritableStream as It } from "stream/web"; +import ns from "events"; +import os from "https"; +import as from "http"; +import ls from "net"; +import cs from "tls"; +import Ke from "crypto"; +import le, { Readable as fs } from "stream"; +import hs from "url"; +import ds from "zlib"; +import us from "buffer"; +import * as je from "fs"; +import { createReadStream as ps } from "fs"; +import { spawn as ms } from "child_process"; +import * as Ut from "path"; +import * as _s from "os"; +const oe = m.dirname(Lt(import.meta.url)), gs = m.join(oe, ".."), Y = process.env.VITE_DEV_SERVER_URL, He = m.join(gs, "dist"); +let K = null; +p.on("hud-overlay-hide", () => { + K && !K.isDestroyed() && K.minimize(); }); -function createHudOverlayWindow() { - const primaryDisplay = screen.getPrimaryDisplay(); - const { workArea } = primaryDisplay; - const windowWidth = 500; - const windowHeight = 100; - const x = Math.floor(workArea.x + (workArea.width - windowWidth) / 2); - const y = Math.floor(workArea.y + workArea.height - windowHeight - 5); - const win = new BrowserWindow({ - width: windowWidth, - height: windowHeight, +function ys() { + const s = Rt.getPrimaryDisplay(), { workArea: e } = s, t = 500, i = 350, r = Math.floor(e.x + (e.width - t) / 2), n = Math.floor(e.y + e.height - i - 5), o = new Te({ + width: t, + height: i, minWidth: 500, maxWidth: 500, - minHeight: 100, - maxHeight: 100, - x, - y, - frame: false, - transparent: true, - resizable: false, - alwaysOnTop: true, - skipTaskbar: true, - hasShadow: false, + minHeight: 350, + maxHeight: 350, + x: r, + y: n, + frame: !1, + transparent: !0, + resizable: !1, + alwaysOnTop: !0, + skipTaskbar: !0, + hasShadow: !1, webPreferences: { - preload: path.join(__dirname$1, "preload.mjs"), - nodeIntegration: false, - contextIsolation: true, - backgroundThrottling: false + preload: m.join(oe, "preload.mjs"), + nodeIntegration: !1, + contextIsolation: !0, + backgroundThrottling: !1 } }); - win.webContents.on("did-finish-load", () => { - win == null ? void 0 : win.webContents.send("main-process-message", (/* @__PURE__ */ new Date()).toLocaleString()); - }); - hudOverlayWindow = win; - win.on("closed", () => { - if (hudOverlayWindow === win) { - hudOverlayWindow = null; + return o.webContents.on("did-finish-load", () => { + o == null || o.webContents.send("main-process-message", (/* @__PURE__ */ new Date()).toLocaleString()); + }), o.webContents.setWindowOpenHandler(({ url: a }) => a.includes("windowType=mic-settings") ? { + action: "allow", + overrideBrowserWindowOptions: { + width: 340, + height: 520, + frame: !1, + transparent: !0, + resizable: !1, + alwaysOnTop: !0, + skipTaskbar: !0, + parent: o, + modal: !1, + webPreferences: { + preload: m.join(oe, "preload.mjs"), + nodeIntegration: !1, + contextIsolation: !0 + } } - }); - if (VITE_DEV_SERVER_URL$1) { - win.loadURL(VITE_DEV_SERVER_URL$1 + "?windowType=hud-overlay"); - } else { - win.loadFile(path.join(RENDERER_DIST$1, "index.html"), { - query: { windowType: "hud-overlay" } - }); - } - return win; + } : { action: "deny" }), K = o, o.on("closed", () => { + K === o && (K = null); + }), Y ? o.loadURL(Y + "?windowType=hud-overlay") : o.loadFile(m.join(He, "index.html"), { + query: { windowType: "hud-overlay" } + }), o; } -function createEditorWindow() { - const isMac = process.platform === "darwin"; - const win = new BrowserWindow({ +function Ss() { + const s = process.platform === "darwin", e = new Te({ width: 1200, height: 800, minWidth: 800, minHeight: 600, - ...isMac && { + ...s && { titleBarStyle: "hiddenInset", trafficLightPosition: { x: 12, y: 12 } }, - transparent: false, - resizable: true, - alwaysOnTop: false, - skipTaskbar: false, + transparent: !1, + resizable: !0, + alwaysOnTop: !1, + skipTaskbar: !1, title: "OpenScreen", backgroundColor: "#000000", webPreferences: { - preload: path.join(__dirname$1, "preload.mjs"), - nodeIntegration: false, - contextIsolation: true, - webSecurity: false, - backgroundThrottling: false + preload: m.join(oe, "preload.mjs"), + nodeIntegration: !1, + contextIsolation: !0, + webSecurity: !1, + backgroundThrottling: !1 } }); - win.maximize(); - win.webContents.on("did-finish-load", () => { - win == null ? void 0 : win.webContents.send("main-process-message", (/* @__PURE__ */ new Date()).toLocaleString()); - }); - if (VITE_DEV_SERVER_URL$1) { - win.loadURL(VITE_DEV_SERVER_URL$1 + "?windowType=editor"); - } else { - win.loadFile(path.join(RENDERER_DIST$1, "index.html"), { - query: { windowType: "editor" } - }); - } - return win; + return e.maximize(), e.webContents.on("did-finish-load", () => { + e == null || e.webContents.send("main-process-message", (/* @__PURE__ */ new Date()).toLocaleString()); + }), Y ? e.loadURL(Y + "?windowType=editor") : e.loadFile(m.join(He, "index.html"), { + query: { windowType: "editor" } + }), e; } -function createSourceSelectorWindow() { - const { width, height } = screen.getPrimaryDisplay().workAreaSize; - const win = new BrowserWindow({ +function ws() { + const { width: s, height: e } = Rt.getPrimaryDisplay().workAreaSize, t = new Te({ width: 620, height: 420, minHeight: 350, maxHeight: 500, - x: Math.round((width - 620) / 2), - y: Math.round((height - 420) / 2), - frame: false, - resizable: false, - alwaysOnTop: true, - transparent: true, + x: Math.round((s - 620) / 2), + y: Math.round((e - 420) / 2), + frame: !1, + resizable: !1, + alwaysOnTop: !0, + transparent: !0, backgroundColor: "#00000000", webPreferences: { - preload: path.join(__dirname$1, "preload.mjs"), - nodeIntegration: false, - contextIsolation: true + preload: m.join(oe, "preload.mjs"), + nodeIntegration: !1, + contextIsolation: !0 } }); - if (VITE_DEV_SERVER_URL$1) { - win.loadURL(VITE_DEV_SERVER_URL$1 + "?windowType=source-selector"); - } else { - win.loadFile(path.join(RENDERER_DIST$1, "index.html"), { - query: { windowType: "source-selector" } + return Y ? t.loadURL(Y + "?windowType=source-selector") : t.loadFile(m.join(He, "index.html"), { + query: { windowType: "source-selector" } + }), t; +} +const Es = "presets.json", vs = 1; +function Ve() { + return m.join(P.getPath("userData"), Es); +} +function Ue() { + return { + version: vs, + defaultPresetId: null, + presets: [] + }; +} +async function X() { + try { + const s = Ve(), e = await W.readFile(s, "utf-8"), t = JSON.parse(e); + return !t.presets || !Array.isArray(t.presets) ? (console.warn("Invalid presets file, creating new store"), Ue()) : t; + } catch (s) { + if (s.code === "ENOENT") + return Ue(); + console.error("Failed to read presets file:", s); + try { + const e = Ve(), t = e + ".backup." + Date.now(); + await W.rename(e, t), console.log("Backed up corrupt presets file to:", t); + } catch { + } + return Ue(); + } +} +async function ce(s) { + const e = Ve(); + await W.writeFile(e, JSON.stringify(s, null, 2), "utf-8"); +} +async function bs() { + try { + const s = await X(); + return { + success: !0, + presets: s.presets, + defaultPresetId: s.defaultPresetId + }; + } catch (s) { + return console.error("Failed to get presets:", s), { + success: !1, + presets: [], + defaultPresetId: null + }; + } +} +async function xs(s) { + try { + const e = await X(), t = { + ...s, + id: crypto.randomUUID(), + createdAt: Date.now() + }; + return t.isDefault && (e.presets = e.presets.map((i) => ({ ...i, isDefault: !1 })), e.defaultPresetId = t.id), e.presets.push(t), await ce(e), { success: !0, preset: t }; + } catch (e) { + return console.error("Failed to save preset:", e), { success: !1, error: String(e) }; + } +} +async function Ts(s, e) { + try { + const t = await X(), i = t.presets.findIndex((r) => r.id === s); + return i === -1 ? { success: !1, error: "Preset not found" } : (e.isDefault === !0 ? (t.presets = t.presets.map((r) => ({ ...r, isDefault: !1 })), t.defaultPresetId = s) : e.isDefault === !1 && t.defaultPresetId === s && (t.defaultPresetId = null), t.presets[i] = { ...t.presets[i], ...e }, await ce(t), { success: !0, preset: t.presets[i] }); + } catch (t) { + return console.error("Failed to update preset:", t), { success: !1, error: String(t) }; + } +} +async function ks(s) { + try { + const e = await X(), t = e.presets.findIndex((i) => i.id === s); + return t === -1 ? { success: !1, error: "Preset not found" } : (e.defaultPresetId === s && (e.defaultPresetId = null), e.presets.splice(t, 1), await ce(e), { success: !0 }); + } catch (e) { + return console.error("Failed to delete preset:", e), { success: !1, error: String(e) }; + } +} +async function Os(s) { + try { + const e = await X(), t = e.presets.find((r) => r.id === s); + if (!t) + return { success: !1, error: "Preset not found" }; + const i = { + ...t, + id: crypto.randomUUID(), + name: `Copy of ${t.name}`, + createdAt: Date.now(), + isDefault: !1 + // Duplicates should never be default + }; + return e.presets.push(i), await ce(e), { success: !0, preset: i }; + } catch (e) { + return console.error("Failed to duplicate preset:", e), { success: !1, error: String(e) }; + } +} +async function Ps(s) { + try { + const e = await X(); + if (e.presets = e.presets.map((t) => ({ ...t, isDefault: !1 })), e.defaultPresetId = null, s) { + const t = e.presets.find((i) => i.id === s); + if (!t) + return { success: !1, error: "Preset not found" }; + t.isDefault = !0, e.defaultPresetId = s; + } + return await ce(e), { success: !0 }; + } catch (e) { + return console.error("Failed to set default preset:", e), { success: !1, error: String(e) }; + } +} +function Rs(s) { + return s && s.__esModule && Object.prototype.hasOwnProperty.call(s, "default") ? s.default : s; +} +var we = { exports: {} }; +const Nt = ["nodebuffer", "arraybuffer", "fragments"], Bt = typeof Blob < "u"; +Bt && Nt.push("blob"); +var D = { + BINARY_TYPES: Nt, + CLOSE_TIMEOUT: 3e4, + EMPTY_BUFFER: Buffer.alloc(0), + GUID: "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", + hasBlob: Bt, + kForOnEventAttribute: Symbol("kIsForOnEventAttribute"), + kListener: Symbol("kListener"), + kStatusCode: Symbol("status-code"), + kWebSocket: Symbol("websocket"), + NOOP: () => { + } +}, Ls, Is; +const { EMPTY_BUFFER: Us } = D, qe = Buffer[Symbol.species]; +function Ns(s, e) { + if (s.length === 0) return Us; + if (s.length === 1) return s[0]; + const t = Buffer.allocUnsafe(e); + let i = 0; + for (let r = 0; r < s.length; r++) { + const n = s[r]; + t.set(n, i), i += n.length; + } + return i < e ? new qe(t.buffer, t.byteOffset, i) : t; +} +function Ct(s, e, t, i, r) { + for (let n = 0; n < r; n++) + t[i + n] = s[n] ^ e[n & 3]; +} +function At(s, e) { + for (let t = 0; t < s.length; t++) + s[t] ^= e[t & 3]; +} +function Bs(s) { + return s.length === s.buffer.byteLength ? s.buffer : s.buffer.slice(s.byteOffset, s.byteOffset + s.length); +} +function Ge(s) { + if (Ge.readOnly = !0, Buffer.isBuffer(s)) return s; + let e; + return s instanceof ArrayBuffer ? e = new qe(s) : ArrayBuffer.isView(s) ? e = new qe(s.buffer, s.byteOffset, s.byteLength) : (e = Buffer.from(s), Ge.readOnly = !1), e; +} +we.exports = { + concat: Ns, + mask: Ct, + toArrayBuffer: Bs, + toBuffer: Ge, + unmask: At +}; +if (!process.env.WS_NO_BUFFER_UTIL) + try { + const s = require("bufferutil"); + Is = we.exports.mask = function(e, t, i, r, n) { + n < 48 ? Ct(e, t, i, r, n) : s.mask(e, t, i, r, n); + }, Ls = we.exports.unmask = function(e, t) { + e.length < 32 ? At(e, t) : s.unmask(e, t); + }; + } catch { + } +var ke = we.exports; +const tt = Symbol("kDone"), Ne = Symbol("kRun"); +let Cs = class { + /** + * Creates a new `Limiter`. + * + * @param {Number} [concurrency=Infinity] The maximum number of jobs allowed + * to run concurrently + */ + constructor(e) { + this[tt] = () => { + this.pending--, this[Ne](); + }, this.concurrency = e || 1 / 0, this.jobs = [], this.pending = 0; + } + /** + * Adds a job to the queue. + * + * @param {Function} job The job to run + * @public + */ + add(e) { + this.jobs.push(e), this[Ne](); + } + /** + * Removes a job from the queue and runs it if possible. + * + * @private + */ + [Ne]() { + if (this.pending !== this.concurrency && this.jobs.length) { + const e = this.jobs.shift(); + this.pending++, e(this[tt]); + } + } +}; +var As = Cs; +const te = ds, st = ke, Ds = As, { kStatusCode: Dt } = D, $s = Buffer[Symbol.species], Fs = Buffer.from([0, 0, 255, 255]), Ee = Symbol("permessage-deflate"), U = Symbol("total-length"), q = Symbol("callback"), C = Symbol("buffers"), H = Symbol("error"); +let de, Ms = class { + /** + * Creates a PerMessageDeflate instance. + * + * @param {Object} [options] Configuration options + * @param {(Boolean|Number)} [options.clientMaxWindowBits] Advertise support + * for, or request, a custom client window size + * @param {Boolean} [options.clientNoContextTakeover=false] Advertise/ + * acknowledge disabling of client context takeover + * @param {Number} [options.concurrencyLimit=10] The number of concurrent + * calls to zlib + * @param {(Boolean|Number)} [options.serverMaxWindowBits] Request/confirm the + * use of a custom server window size + * @param {Boolean} [options.serverNoContextTakeover=false] Request/accept + * disabling of server context takeover + * @param {Number} [options.threshold=1024] Size (in bytes) below which + * messages should not be compressed if context takeover is disabled + * @param {Object} [options.zlibDeflateOptions] Options to pass to zlib on + * deflate + * @param {Object} [options.zlibInflateOptions] Options to pass to zlib on + * inflate + * @param {Boolean} [isServer=false] Create the instance in either server or + * client mode + * @param {Number} [maxPayload=0] The maximum allowed message length + */ + constructor(e, t, i) { + if (this._maxPayload = i | 0, this._options = e || {}, this._threshold = this._options.threshold !== void 0 ? this._options.threshold : 1024, this._isServer = !!t, this._deflate = null, this._inflate = null, this.params = null, !de) { + const r = this._options.concurrencyLimit !== void 0 ? this._options.concurrencyLimit : 10; + de = new Ds(r); + } + } + /** + * @type {String} + */ + static get extensionName() { + return "permessage-deflate"; + } + /** + * Create an extension negotiation offer. + * + * @return {Object} Extension parameters + * @public + */ + offer() { + const e = {}; + return this._options.serverNoContextTakeover && (e.server_no_context_takeover = !0), this._options.clientNoContextTakeover && (e.client_no_context_takeover = !0), this._options.serverMaxWindowBits && (e.server_max_window_bits = this._options.serverMaxWindowBits), this._options.clientMaxWindowBits ? e.client_max_window_bits = this._options.clientMaxWindowBits : this._options.clientMaxWindowBits == null && (e.client_max_window_bits = !0), e; + } + /** + * Accept an extension negotiation offer/response. + * + * @param {Array} configurations The extension negotiation offers/reponse + * @return {Object} Accepted configuration + * @public + */ + accept(e) { + return e = this.normalizeParams(e), this.params = this._isServer ? this.acceptAsServer(e) : this.acceptAsClient(e), this.params; + } + /** + * Releases all resources used by the extension. + * + * @public + */ + cleanup() { + if (this._inflate && (this._inflate.close(), this._inflate = null), this._deflate) { + const e = this._deflate[q]; + this._deflate.close(), this._deflate = null, e && e( + new Error( + "The deflate stream was closed while data was being processed" + ) + ); + } + } + /** + * Accept an extension negotiation offer. + * + * @param {Array} offers The extension negotiation offers + * @return {Object} Accepted configuration + * @private + */ + acceptAsServer(e) { + const t = this._options, i = e.find((r) => !(t.serverNoContextTakeover === !1 && r.server_no_context_takeover || r.server_max_window_bits && (t.serverMaxWindowBits === !1 || typeof t.serverMaxWindowBits == "number" && t.serverMaxWindowBits > r.server_max_window_bits) || typeof t.clientMaxWindowBits == "number" && !r.client_max_window_bits)); + if (!i) + throw new Error("None of the extension offers can be accepted"); + return t.serverNoContextTakeover && (i.server_no_context_takeover = !0), t.clientNoContextTakeover && (i.client_no_context_takeover = !0), typeof t.serverMaxWindowBits == "number" && (i.server_max_window_bits = t.serverMaxWindowBits), typeof t.clientMaxWindowBits == "number" ? i.client_max_window_bits = t.clientMaxWindowBits : (i.client_max_window_bits === !0 || t.clientMaxWindowBits === !1) && delete i.client_max_window_bits, i; + } + /** + * Accept the extension negotiation response. + * + * @param {Array} response The extension negotiation response + * @return {Object} Accepted configuration + * @private + */ + acceptAsClient(e) { + const t = e[0]; + if (this._options.clientNoContextTakeover === !1 && t.client_no_context_takeover) + throw new Error('Unexpected parameter "client_no_context_takeover"'); + if (!t.client_max_window_bits) + typeof this._options.clientMaxWindowBits == "number" && (t.client_max_window_bits = this._options.clientMaxWindowBits); + else if (this._options.clientMaxWindowBits === !1 || typeof this._options.clientMaxWindowBits == "number" && t.client_max_window_bits > this._options.clientMaxWindowBits) + throw new Error( + 'Unexpected or invalid parameter "client_max_window_bits"' + ); + return t; + } + /** + * Normalize parameters. + * + * @param {Array} configurations The extension negotiation offers/reponse + * @return {Array} The offers/response with normalized parameters + * @private + */ + normalizeParams(e) { + return e.forEach((t) => { + Object.keys(t).forEach((i) => { + let r = t[i]; + if (r.length > 1) + throw new Error(`Parameter "${i}" must have only a single value`); + if (r = r[0], i === "client_max_window_bits") { + if (r !== !0) { + const n = +r; + if (!Number.isInteger(n) || n < 8 || n > 15) + throw new TypeError( + `Invalid value for parameter "${i}": ${r}` + ); + r = n; + } else if (!this._isServer) + throw new TypeError( + `Invalid value for parameter "${i}": ${r}` + ); + } else if (i === "server_max_window_bits") { + const n = +r; + if (!Number.isInteger(n) || n < 8 || n > 15) + throw new TypeError( + `Invalid value for parameter "${i}": ${r}` + ); + r = n; + } else if (i === "client_no_context_takeover" || i === "server_no_context_takeover") { + if (r !== !0) + throw new TypeError( + `Invalid value for parameter "${i}": ${r}` + ); + } else + throw new Error(`Unknown parameter "${i}"`); + t[i] = r; + }); + }), e; + } + /** + * Decompress data. Concurrency limited. + * + * @param {Buffer} data Compressed data + * @param {Boolean} fin Specifies whether or not this is the last fragment + * @param {Function} callback Callback + * @public + */ + decompress(e, t, i) { + de.add((r) => { + this._decompress(e, t, (n, o) => { + r(), i(n, o); + }); + }); + } + /** + * Compress data. Concurrency limited. + * + * @param {(Buffer|String)} data Data to compress + * @param {Boolean} fin Specifies whether or not this is the last fragment + * @param {Function} callback Callback + * @public + */ + compress(e, t, i) { + de.add((r) => { + this._compress(e, t, (n, o) => { + r(), i(n, o); + }); + }); + } + /** + * Decompress data. + * + * @param {Buffer} data Compressed data + * @param {Boolean} fin Specifies whether or not this is the last fragment + * @param {Function} callback Callback + * @private + */ + _decompress(e, t, i) { + const r = this._isServer ? "client" : "server"; + if (!this._inflate) { + const n = `${r}_max_window_bits`, o = typeof this.params[n] != "number" ? te.Z_DEFAULT_WINDOWBITS : this.params[n]; + this._inflate = te.createInflateRaw({ + ...this._options.zlibInflateOptions, + windowBits: o + }), this._inflate[Ee] = this, this._inflate[U] = 0, this._inflate[C] = [], this._inflate.on("error", js), this._inflate.on("data", $t); + } + this._inflate[q] = i, this._inflate.write(e), t && this._inflate.write(Fs), this._inflate.flush(() => { + const n = this._inflate[H]; + if (n) { + this._inflate.close(), this._inflate = null, i(n); + return; + } + const o = st.concat( + this._inflate[C], + this._inflate[U] + ); + this._inflate._readableState.endEmitted ? (this._inflate.close(), this._inflate = null) : (this._inflate[U] = 0, this._inflate[C] = [], t && this.params[`${r}_no_context_takeover`] && this._inflate.reset()), i(null, o); }); } - return win; -} -let selectedSource = null; -function registerIpcHandlers(createEditorWindow2, createSourceSelectorWindow2, getMainWindow, getSourceSelectorWindow, onRecordingStateChange) { - ipcMain.handle("get-sources", async (_, opts) => { - const sources = await desktopCapturer.getSources(opts); - return sources.map((source) => ({ - id: source.id, - name: source.name, - display_id: source.display_id, - thumbnail: source.thumbnail ? source.thumbnail.toDataURL() : null, - appIcon: source.appIcon ? source.appIcon.toDataURL() : null + /** + * Compress data. + * + * @param {(Buffer|String)} data Data to compress + * @param {Boolean} fin Specifies whether or not this is the last fragment + * @param {Function} callback Callback + * @private + */ + _compress(e, t, i) { + const r = this._isServer ? "server" : "client"; + if (!this._deflate) { + const n = `${r}_max_window_bits`, o = typeof this.params[n] != "number" ? te.Z_DEFAULT_WINDOWBITS : this.params[n]; + this._deflate = te.createDeflateRaw({ + ...this._options.zlibDeflateOptions, + windowBits: o + }), this._deflate[U] = 0, this._deflate[C] = [], this._deflate.on("data", Ws); + } + this._deflate[q] = i, this._deflate.write(e), this._deflate.flush(te.Z_SYNC_FLUSH, () => { + if (!this._deflate) + return; + let n = st.concat( + this._deflate[C], + this._deflate[U] + ); + t && (n = new $s(n.buffer, n.byteOffset, n.length - 4)), this._deflate[q] = null, this._deflate[U] = 0, this._deflate[C] = [], t && this.params[`${r}_no_context_takeover`] && this._deflate.reset(), i(null, n); + }); + } +}; +var Ye = Ms; +function Ws(s) { + this[C].push(s), this[U] += s.length; +} +function $t(s) { + if (this[U] += s.length, this[Ee]._maxPayload < 1 || this[U] <= this[Ee]._maxPayload) { + this[C].push(s); + return; + } + this[H] = new RangeError("Max payload size exceeded"), this[H].code = "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH", this[H][Dt] = 1009, this.removeListener("data", $t), this.reset(); +} +function js(s) { + if (this[Ee]._inflate = null, this[H]) { + this[q](this[H]); + return; + } + s[Dt] = 1007, this[q](s); +} +var ve = { exports: {} }, rt; +const { isUtf8: it } = us, { hasBlob: Vs } = D, qs = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + // 0 - 15 + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + // 16 - 31 + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + // 32 - 47 + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + // 48 - 63 + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + // 64 - 79 + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + // 80 - 95 + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + // 96 - 111 + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0 + // 112 - 127 +]; +function Gs(s) { + return s >= 1e3 && s <= 1014 && s !== 1004 && s !== 1005 && s !== 1006 || s >= 3e3 && s <= 4999; +} +function Je(s) { + const e = s.length; + let t = 0; + for (; t < e; ) + if (!(s[t] & 128)) + t++; + else if ((s[t] & 224) === 192) { + if (t + 1 === e || (s[t + 1] & 192) !== 128 || (s[t] & 254) === 192) + return !1; + t += 2; + } else if ((s[t] & 240) === 224) { + if (t + 2 >= e || (s[t + 1] & 192) !== 128 || (s[t + 2] & 192) !== 128 || s[t] === 224 && (s[t + 1] & 224) === 128 || // Overlong + s[t] === 237 && (s[t + 1] & 224) === 160) + return !1; + t += 3; + } else if ((s[t] & 248) === 240) { + if (t + 3 >= e || (s[t + 1] & 192) !== 128 || (s[t + 2] & 192) !== 128 || (s[t + 3] & 192) !== 128 || s[t] === 240 && (s[t + 1] & 240) === 128 || // Overlong + s[t] === 244 && s[t + 1] > 143 || s[t] > 244) + return !1; + t += 4; + } else + return !1; + return !0; +} +function Js(s) { + return Vs && typeof s == "object" && typeof s.arrayBuffer == "function" && typeof s.type == "string" && typeof s.stream == "function" && (s[Symbol.toStringTag] === "Blob" || s[Symbol.toStringTag] === "File"); +} +ve.exports = { + isBlob: Js, + isValidStatusCode: Gs, + isValidUTF8: Je, + tokenChars: qs +}; +if (it) + rt = ve.exports.isValidUTF8 = function(s) { + return s.length < 24 ? Je(s) : it(s); + }; +else if (!process.env.WS_NO_UTF_8_VALIDATE) + try { + const s = require("utf-8-validate"); + rt = ve.exports.isValidUTF8 = function(e) { + return e.length < 32 ? Je(e) : s(e); + }; + } catch { + } +var fe = ve.exports; +const { Writable: zs } = le, nt = Ye, { + BINARY_TYPES: Ks, + EMPTY_BUFFER: ot, + kStatusCode: Hs, + kWebSocket: Ys +} = D, { concat: Be, toArrayBuffer: Xs, unmask: Zs } = ke, { isValidStatusCode: Qs, isValidUTF8: at } = fe, ue = Buffer[Symbol.species], T = 0, lt = 1, ct = 2, ft = 3, Ce = 4, Ae = 5, pe = 6; +let er = class extends zs { + /** + * Creates a Receiver instance. + * + * @param {Object} [options] Options object + * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether + * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted + * multiple times in the same tick + * @param {String} [options.binaryType=nodebuffer] The type for binary data + * @param {Object} [options.extensions] An object containing the negotiated + * extensions + * @param {Boolean} [options.isServer=false] Specifies whether to operate in + * client or server mode + * @param {Number} [options.maxPayload=0] The maximum allowed message length + * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or + * not to skip UTF-8 validation for text and close messages + */ + constructor(e = {}) { + super(), this._allowSynchronousEvents = e.allowSynchronousEvents !== void 0 ? e.allowSynchronousEvents : !0, this._binaryType = e.binaryType || Ks[0], this._extensions = e.extensions || {}, this._isServer = !!e.isServer, this._maxPayload = e.maxPayload | 0, this._skipUTF8Validation = !!e.skipUTF8Validation, this[Ys] = void 0, this._bufferedBytes = 0, this._buffers = [], this._compressed = !1, this._payloadLength = 0, this._mask = void 0, this._fragmented = 0, this._masked = !1, this._fin = !1, this._opcode = 0, this._totalPayloadLength = 0, this._messageLength = 0, this._fragments = [], this._errored = !1, this._loop = !1, this._state = T; + } + /** + * Implements `Writable.prototype._write()`. + * + * @param {Buffer} chunk The chunk of data to write + * @param {String} encoding The character encoding of `chunk` + * @param {Function} cb Callback + * @private + */ + _write(e, t, i) { + if (this._opcode === 8 && this._state == T) return i(); + this._bufferedBytes += e.length, this._buffers.push(e), this.startLoop(i); + } + /** + * Consumes `n` bytes from the buffered data. + * + * @param {Number} n The number of bytes to consume + * @return {Buffer} The consumed bytes + * @private + */ + consume(e) { + if (this._bufferedBytes -= e, e === this._buffers[0].length) return this._buffers.shift(); + if (e < this._buffers[0].length) { + const i = this._buffers[0]; + return this._buffers[0] = new ue( + i.buffer, + i.byteOffset + e, + i.length - e + ), new ue(i.buffer, i.byteOffset, e); + } + const t = Buffer.allocUnsafe(e); + do { + const i = this._buffers[0], r = t.length - e; + e >= i.length ? t.set(this._buffers.shift(), r) : (t.set(new Uint8Array(i.buffer, i.byteOffset, e), r), this._buffers[0] = new ue( + i.buffer, + i.byteOffset + e, + i.length - e + )), e -= i.length; + } while (e > 0); + return t; + } + /** + * Starts the parsing loop. + * + * @param {Function} cb Callback + * @private + */ + startLoop(e) { + this._loop = !0; + do + switch (this._state) { + case T: + this.getInfo(e); + break; + case lt: + this.getPayloadLength16(e); + break; + case ct: + this.getPayloadLength64(e); + break; + case ft: + this.getMask(); + break; + case Ce: + this.getData(e); + break; + case Ae: + case pe: + this._loop = !1; + return; + } + while (this._loop); + this._errored || e(); + } + /** + * Reads the first two bytes of a frame. + * + * @param {Function} cb Callback + * @private + */ + getInfo(e) { + if (this._bufferedBytes < 2) { + this._loop = !1; + return; + } + const t = this.consume(2); + if (t[0] & 48) { + const r = this.createError( + RangeError, + "RSV2 and RSV3 must be clear", + !0, + 1002, + "WS_ERR_UNEXPECTED_RSV_2_3" + ); + e(r); + return; + } + const i = (t[0] & 64) === 64; + if (i && !this._extensions[nt.extensionName]) { + const r = this.createError( + RangeError, + "RSV1 must be clear", + !0, + 1002, + "WS_ERR_UNEXPECTED_RSV_1" + ); + e(r); + return; + } + if (this._fin = (t[0] & 128) === 128, this._opcode = t[0] & 15, this._payloadLength = t[1] & 127, this._opcode === 0) { + if (i) { + const r = this.createError( + RangeError, + "RSV1 must be clear", + !0, + 1002, + "WS_ERR_UNEXPECTED_RSV_1" + ); + e(r); + return; + } + if (!this._fragmented) { + const r = this.createError( + RangeError, + "invalid opcode 0", + !0, + 1002, + "WS_ERR_INVALID_OPCODE" + ); + e(r); + return; + } + this._opcode = this._fragmented; + } else if (this._opcode === 1 || this._opcode === 2) { + if (this._fragmented) { + const r = this.createError( + RangeError, + `invalid opcode ${this._opcode}`, + !0, + 1002, + "WS_ERR_INVALID_OPCODE" + ); + e(r); + return; + } + this._compressed = i; + } else if (this._opcode > 7 && this._opcode < 11) { + if (!this._fin) { + const r = this.createError( + RangeError, + "FIN must be set", + !0, + 1002, + "WS_ERR_EXPECTED_FIN" + ); + e(r); + return; + } + if (i) { + const r = this.createError( + RangeError, + "RSV1 must be clear", + !0, + 1002, + "WS_ERR_UNEXPECTED_RSV_1" + ); + e(r); + return; + } + if (this._payloadLength > 125 || this._opcode === 8 && this._payloadLength === 1) { + const r = this.createError( + RangeError, + `invalid payload length ${this._payloadLength}`, + !0, + 1002, + "WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH" + ); + e(r); + return; + } + } else { + const r = this.createError( + RangeError, + `invalid opcode ${this._opcode}`, + !0, + 1002, + "WS_ERR_INVALID_OPCODE" + ); + e(r); + return; + } + if (!this._fin && !this._fragmented && (this._fragmented = this._opcode), this._masked = (t[1] & 128) === 128, this._isServer) { + if (!this._masked) { + const r = this.createError( + RangeError, + "MASK must be set", + !0, + 1002, + "WS_ERR_EXPECTED_MASK" + ); + e(r); + return; + } + } else if (this._masked) { + const r = this.createError( + RangeError, + "MASK must be clear", + !0, + 1002, + "WS_ERR_UNEXPECTED_MASK" + ); + e(r); + return; + } + this._payloadLength === 126 ? this._state = lt : this._payloadLength === 127 ? this._state = ct : this.haveLength(e); + } + /** + * Gets extended payload length (7+16). + * + * @param {Function} cb Callback + * @private + */ + getPayloadLength16(e) { + if (this._bufferedBytes < 2) { + this._loop = !1; + return; + } + this._payloadLength = this.consume(2).readUInt16BE(0), this.haveLength(e); + } + /** + * Gets extended payload length (7+64). + * + * @param {Function} cb Callback + * @private + */ + getPayloadLength64(e) { + if (this._bufferedBytes < 8) { + this._loop = !1; + return; + } + const t = this.consume(8), i = t.readUInt32BE(0); + if (i > Math.pow(2, 21) - 1) { + const r = this.createError( + RangeError, + "Unsupported WebSocket frame: payload length > 2^53 - 1", + !1, + 1009, + "WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH" + ); + e(r); + return; + } + this._payloadLength = i * Math.pow(2, 32) + t.readUInt32BE(4), this.haveLength(e); + } + /** + * Payload length has been read. + * + * @param {Function} cb Callback + * @private + */ + haveLength(e) { + if (this._payloadLength && this._opcode < 8 && (this._totalPayloadLength += this._payloadLength, this._totalPayloadLength > this._maxPayload && this._maxPayload > 0)) { + const t = this.createError( + RangeError, + "Max payload size exceeded", + !1, + 1009, + "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH" + ); + e(t); + return; + } + this._masked ? this._state = ft : this._state = Ce; + } + /** + * Reads mask bytes. + * + * @private + */ + getMask() { + if (this._bufferedBytes < 4) { + this._loop = !1; + return; + } + this._mask = this.consume(4), this._state = Ce; + } + /** + * Reads data bytes. + * + * @param {Function} cb Callback + * @private + */ + getData(e) { + let t = ot; + if (this._payloadLength) { + if (this._bufferedBytes < this._payloadLength) { + this._loop = !1; + return; + } + t = this.consume(this._payloadLength), this._masked && this._mask[0] | this._mask[1] | this._mask[2] | this._mask[3] && Zs(t, this._mask); + } + if (this._opcode > 7) { + this.controlMessage(t, e); + return; + } + if (this._compressed) { + this._state = Ae, this.decompress(t, e); + return; + } + t.length && (this._messageLength = this._totalPayloadLength, this._fragments.push(t)), this.dataMessage(e); + } + /** + * Decompresses data. + * + * @param {Buffer} data Compressed data + * @param {Function} cb Callback + * @private + */ + decompress(e, t) { + this._extensions[nt.extensionName].decompress(e, this._fin, (r, n) => { + if (r) return t(r); + if (n.length) { + if (this._messageLength += n.length, this._messageLength > this._maxPayload && this._maxPayload > 0) { + const o = this.createError( + RangeError, + "Max payload size exceeded", + !1, + 1009, + "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH" + ); + t(o); + return; + } + this._fragments.push(n); + } + this.dataMessage(t), this._state === T && this.startLoop(t); + }); + } + /** + * Handles a data message. + * + * @param {Function} cb Callback + * @private + */ + dataMessage(e) { + if (!this._fin) { + this._state = T; + return; + } + const t = this._messageLength, i = this._fragments; + if (this._totalPayloadLength = 0, this._messageLength = 0, this._fragmented = 0, this._fragments = [], this._opcode === 2) { + let r; + this._binaryType === "nodebuffer" ? r = Be(i, t) : this._binaryType === "arraybuffer" ? r = Xs(Be(i, t)) : this._binaryType === "blob" ? r = new Blob(i) : r = i, this._allowSynchronousEvents ? (this.emit("message", r, !0), this._state = T) : (this._state = pe, setImmediate(() => { + this.emit("message", r, !0), this._state = T, this.startLoop(e); + })); + } else { + const r = Be(i, t); + if (!this._skipUTF8Validation && !at(r)) { + const n = this.createError( + Error, + "invalid UTF-8 sequence", + !0, + 1007, + "WS_ERR_INVALID_UTF8" + ); + e(n); + return; + } + this._state === Ae || this._allowSynchronousEvents ? (this.emit("message", r, !1), this._state = T) : (this._state = pe, setImmediate(() => { + this.emit("message", r, !1), this._state = T, this.startLoop(e); + })); + } + } + /** + * Handles a control message. + * + * @param {Buffer} data Data to handle + * @return {(Error|RangeError|undefined)} A possible error + * @private + */ + controlMessage(e, t) { + if (this._opcode === 8) { + if (e.length === 0) + this._loop = !1, this.emit("conclude", 1005, ot), this.end(); + else { + const i = e.readUInt16BE(0); + if (!Qs(i)) { + const n = this.createError( + RangeError, + `invalid status code ${i}`, + !0, + 1002, + "WS_ERR_INVALID_CLOSE_CODE" + ); + t(n); + return; + } + const r = new ue( + e.buffer, + e.byteOffset + 2, + e.length - 2 + ); + if (!this._skipUTF8Validation && !at(r)) { + const n = this.createError( + Error, + "invalid UTF-8 sequence", + !0, + 1007, + "WS_ERR_INVALID_UTF8" + ); + t(n); + return; + } + this._loop = !1, this.emit("conclude", i, r), this.end(); + } + this._state = T; + return; + } + this._allowSynchronousEvents ? (this.emit(this._opcode === 9 ? "ping" : "pong", e), this._state = T) : (this._state = pe, setImmediate(() => { + this.emit(this._opcode === 9 ? "ping" : "pong", e), this._state = T, this.startLoop(t); })); - }); - ipcMain.handle("select-source", (_, source) => { - selectedSource = source; - const sourceSelectorWin = getSourceSelectorWindow(); - if (sourceSelectorWin) { - sourceSelectorWin.close(); + } + /** + * Builds an error object. + * + * @param {function(new:Error|RangeError)} ErrorCtor The error constructor + * @param {String} message The error message + * @param {Boolean} prefix Specifies whether or not to add a default prefix to + * `message` + * @param {Number} statusCode The status code + * @param {String} errorCode The exposed error code + * @return {(Error|RangeError)} The error + * @private + */ + createError(e, t, i, r, n) { + this._loop = !1, this._errored = !0; + const o = new e( + i ? `Invalid WebSocket frame: ${t}` : t + ); + return Error.captureStackTrace(o, this.createError), o.code = n, o[Hs] = r, o; + } +}; +var tr = er; +const { Duplex: ji } = le, { randomFillSync: sr } = Ke, ht = Ye, { EMPTY_BUFFER: rr, kWebSocket: ir, NOOP: nr } = D, { isBlob: j, isValidStatusCode: or } = fe, { mask: dt, toBuffer: $ } = ke, k = Symbol("kByteLength"), ar = Buffer.alloc(4), ye = 8 * 1024; +let F, V = ye; +const O = 0, lr = 1, cr = 2; +let fr = class M { + /** + * Creates a Sender instance. + * + * @param {Duplex} socket The connection socket + * @param {Object} [extensions] An object containing the negotiated extensions + * @param {Function} [generateMask] The function used to generate the masking + * key + */ + constructor(e, t, i) { + this._extensions = t || {}, i && (this._generateMask = i, this._maskBuffer = Buffer.alloc(4)), this._socket = e, this._firstFragment = !0, this._compress = !1, this._bufferedBytes = 0, this._queue = [], this._state = O, this.onerror = nr, this[ir] = void 0; + } + /** + * Frames a piece of data according to the HyBi WebSocket protocol. + * + * @param {(Buffer|String)} data The data to frame + * @param {Object} options Options object + * @param {Boolean} [options.fin=false] Specifies whether or not to set the + * FIN bit + * @param {Function} [options.generateMask] The function used to generate the + * masking key + * @param {Boolean} [options.mask=false] Specifies whether or not to mask + * `data` + * @param {Buffer} [options.maskBuffer] The buffer used to store the masking + * key + * @param {Number} options.opcode The opcode + * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be + * modified + * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the + * RSV1 bit + * @return {(Buffer|String)[]} The framed data + * @public + */ + static frame(e, t) { + let i, r = !1, n = 2, o = !1; + t.mask && (i = t.maskBuffer || ar, t.generateMask ? t.generateMask(i) : (V === ye && (F === void 0 && (F = Buffer.alloc(ye)), sr(F, 0, ye), V = 0), i[0] = F[V++], i[1] = F[V++], i[2] = F[V++], i[3] = F[V++]), o = (i[0] | i[1] | i[2] | i[3]) === 0, n = 6); + let a; + typeof e == "string" ? (!t.mask || o) && t[k] !== void 0 ? a = t[k] : (e = Buffer.from(e), a = e.length) : (a = e.length, r = t.mask && t.readOnly && !o); + let c = a; + a >= 65536 ? (n += 8, c = 127) : a > 125 && (n += 2, c = 126); + const l = Buffer.allocUnsafe(r ? a + n : n); + return l[0] = t.fin ? t.opcode | 128 : t.opcode, t.rsv1 && (l[0] |= 64), l[1] = c, c === 126 ? l.writeUInt16BE(a, 2) : c === 127 && (l[2] = l[3] = 0, l.writeUIntBE(a, 4, 6)), t.mask ? (l[1] |= 128, l[n - 4] = i[0], l[n - 3] = i[1], l[n - 2] = i[2], l[n - 1] = i[3], o ? [l, e] : r ? (dt(e, i, l, n, a), [l]) : (dt(e, i, e, 0, a), [l, e])) : [l, e]; + } + /** + * Sends a close message to the other peer. + * + * @param {Number} [code] The status code component of the body + * @param {(String|Buffer)} [data] The message component of the body + * @param {Boolean} [mask=false] Specifies whether or not to mask the message + * @param {Function} [cb] Callback + * @public + */ + close(e, t, i, r) { + let n; + if (e === void 0) + n = rr; + else { + if (typeof e != "number" || !or(e)) + throw new TypeError("First argument must be a valid error code number"); + if (t === void 0 || !t.length) + n = Buffer.allocUnsafe(2), n.writeUInt16BE(e, 0); + else { + const a = Buffer.byteLength(t); + if (a > 123) + throw new RangeError("The message must not be greater than 123 bytes"); + n = Buffer.allocUnsafe(2 + a), n.writeUInt16BE(e, 0), typeof t == "string" ? n.write(t, 2) : n.set(t, 2); + } } - return selectedSource; - }); - ipcMain.handle("get-selected-source", () => { - return selectedSource; - }); - ipcMain.handle("open-source-selector", () => { - const sourceSelectorWin = getSourceSelectorWindow(); - if (sourceSelectorWin) { - sourceSelectorWin.focus(); + const o = { + [k]: n.length, + fin: !0, + generateMask: this._generateMask, + mask: i, + maskBuffer: this._maskBuffer, + opcode: 8, + readOnly: !1, + rsv1: !1 + }; + this._state !== O ? this.enqueue([this.dispatch, n, !1, o, r]) : this.sendFrame(M.frame(n, o), r); + } + /** + * Sends a ping message to the other peer. + * + * @param {*} data The message to send + * @param {Boolean} [mask=false] Specifies whether or not to mask `data` + * @param {Function} [cb] Callback + * @public + */ + ping(e, t, i) { + let r, n; + if (typeof e == "string" ? (r = Buffer.byteLength(e), n = !1) : j(e) ? (r = e.size, n = !1) : (e = $(e), r = e.length, n = $.readOnly), r > 125) + throw new RangeError("The data size must not be greater than 125 bytes"); + const o = { + [k]: r, + fin: !0, + generateMask: this._generateMask, + mask: t, + maskBuffer: this._maskBuffer, + opcode: 9, + readOnly: n, + rsv1: !1 + }; + j(e) ? this._state !== O ? this.enqueue([this.getBlobData, e, !1, o, i]) : this.getBlobData(e, !1, o, i) : this._state !== O ? this.enqueue([this.dispatch, e, !1, o, i]) : this.sendFrame(M.frame(e, o), i); + } + /** + * Sends a pong message to the other peer. + * + * @param {*} data The message to send + * @param {Boolean} [mask=false] Specifies whether or not to mask `data` + * @param {Function} [cb] Callback + * @public + */ + pong(e, t, i) { + let r, n; + if (typeof e == "string" ? (r = Buffer.byteLength(e), n = !1) : j(e) ? (r = e.size, n = !1) : (e = $(e), r = e.length, n = $.readOnly), r > 125) + throw new RangeError("The data size must not be greater than 125 bytes"); + const o = { + [k]: r, + fin: !0, + generateMask: this._generateMask, + mask: t, + maskBuffer: this._maskBuffer, + opcode: 10, + readOnly: n, + rsv1: !1 + }; + j(e) ? this._state !== O ? this.enqueue([this.getBlobData, e, !1, o, i]) : this.getBlobData(e, !1, o, i) : this._state !== O ? this.enqueue([this.dispatch, e, !1, o, i]) : this.sendFrame(M.frame(e, o), i); + } + /** + * Sends a data message to the other peer. + * + * @param {*} data The message to send + * @param {Object} options Options object + * @param {Boolean} [options.binary=false] Specifies whether `data` is binary + * or text + * @param {Boolean} [options.compress=false] Specifies whether or not to + * compress `data` + * @param {Boolean} [options.fin=false] Specifies whether the fragment is the + * last one + * @param {Boolean} [options.mask=false] Specifies whether or not to mask + * `data` + * @param {Function} [cb] Callback + * @public + */ + send(e, t, i) { + const r = this._extensions[ht.extensionName]; + let n = t.binary ? 2 : 1, o = t.compress, a, c; + typeof e == "string" ? (a = Buffer.byteLength(e), c = !1) : j(e) ? (a = e.size, c = !1) : (e = $(e), a = e.length, c = $.readOnly), this._firstFragment ? (this._firstFragment = !1, o && r && r.params[r._isServer ? "server_no_context_takeover" : "client_no_context_takeover"] && (o = a >= r._threshold), this._compress = o) : (o = !1, n = 0), t.fin && (this._firstFragment = !0); + const l = { + [k]: a, + fin: t.fin, + generateMask: this._generateMask, + mask: t.mask, + maskBuffer: this._maskBuffer, + opcode: n, + readOnly: c, + rsv1: o + }; + j(e) ? this._state !== O ? this.enqueue([this.getBlobData, e, this._compress, l, i]) : this.getBlobData(e, this._compress, l, i) : this._state !== O ? this.enqueue([this.dispatch, e, this._compress, l, i]) : this.dispatch(e, this._compress, l, i); + } + /** + * Gets the contents of a blob as binary data. + * + * @param {Blob} blob The blob + * @param {Boolean} [compress=false] Specifies whether or not to compress + * the data + * @param {Object} options Options object + * @param {Boolean} [options.fin=false] Specifies whether or not to set the + * FIN bit + * @param {Function} [options.generateMask] The function used to generate the + * masking key + * @param {Boolean} [options.mask=false] Specifies whether or not to mask + * `data` + * @param {Buffer} [options.maskBuffer] The buffer used to store the masking + * key + * @param {Number} options.opcode The opcode + * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be + * modified + * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the + * RSV1 bit + * @param {Function} [cb] Callback + * @private + */ + getBlobData(e, t, i, r) { + this._bufferedBytes += i[k], this._state = cr, e.arrayBuffer().then((n) => { + if (this._socket.destroyed) { + const a = new Error( + "The socket was closed while the blob was being read" + ); + process.nextTick(ze, this, a, r); + return; + } + this._bufferedBytes -= i[k]; + const o = $(n); + t ? this.dispatch(o, t, i, r) : (this._state = O, this.sendFrame(M.frame(o, i), r), this.dequeue()); + }).catch((n) => { + process.nextTick(dr, this, n, r); + }); + } + /** + * Dispatches a message. + * + * @param {(Buffer|String)} data The message to send + * @param {Boolean} [compress=false] Specifies whether or not to compress + * `data` + * @param {Object} options Options object + * @param {Boolean} [options.fin=false] Specifies whether or not to set the + * FIN bit + * @param {Function} [options.generateMask] The function used to generate the + * masking key + * @param {Boolean} [options.mask=false] Specifies whether or not to mask + * `data` + * @param {Buffer} [options.maskBuffer] The buffer used to store the masking + * key + * @param {Number} options.opcode The opcode + * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be + * modified + * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the + * RSV1 bit + * @param {Function} [cb] Callback + * @private + */ + dispatch(e, t, i, r) { + if (!t) { + this.sendFrame(M.frame(e, i), r); + return; + } + const n = this._extensions[ht.extensionName]; + this._bufferedBytes += i[k], this._state = lr, n.compress(e, i.fin, (o, a) => { + if (this._socket.destroyed) { + const c = new Error( + "The socket was closed while data was being compressed" + ); + ze(this, c, r); + return; + } + this._bufferedBytes -= i[k], this._state = O, i.readOnly = !1, this.sendFrame(M.frame(a, i), r), this.dequeue(); + }); + } + /** + * Executes queued send operations. + * + * @private + */ + dequeue() { + for (; this._state === O && this._queue.length; ) { + const e = this._queue.shift(); + this._bufferedBytes -= e[3][k], Reflect.apply(e[0], this, e.slice(1)); + } + } + /** + * Enqueues a send operation. + * + * @param {Array} params Send operation parameters. + * @private + */ + enqueue(e) { + this._bufferedBytes += e[3][k], this._queue.push(e); + } + /** + * Sends a frame. + * + * @param {(Buffer | String)[]} list The frame to send + * @param {Function} [cb] Callback + * @private + */ + sendFrame(e, t) { + e.length === 2 ? (this._socket.cork(), this._socket.write(e[0]), this._socket.write(e[1], t), this._socket.uncork()) : this._socket.write(e[0], t); + } +}; +var hr = fr; +function ze(s, e, t) { + typeof t == "function" && t(e); + for (let i = 0; i < s._queue.length; i++) { + const r = s._queue[i], n = r[r.length - 1]; + typeof n == "function" && n(e); + } +} +function dr(s, e, t) { + ze(s, e, t), s.onerror(e); +} +const { kForOnEventAttribute: se, kListener: De } = D, ut = Symbol("kCode"), pt = Symbol("kData"), mt = Symbol("kError"), _t = Symbol("kMessage"), gt = Symbol("kReason"), G = Symbol("kTarget"), yt = Symbol("kType"), St = Symbol("kWasClean"); +class Z { + /** + * Create a new `Event`. + * + * @param {String} type The name of the event + * @throws {TypeError} If the `type` argument is not specified + */ + constructor(e) { + this[G] = null, this[yt] = e; + } + /** + * @type {*} + */ + get target() { + return this[G]; + } + /** + * @type {String} + */ + get type() { + return this[yt]; + } +} +Object.defineProperty(Z.prototype, "target", { enumerable: !0 }); +Object.defineProperty(Z.prototype, "type", { enumerable: !0 }); +class Oe extends Z { + /** + * Create a new `CloseEvent`. + * + * @param {String} type The name of the event + * @param {Object} [options] A dictionary object that allows for setting + * attributes via object members of the same name + * @param {Number} [options.code=0] The status code explaining why the + * connection was closed + * @param {String} [options.reason=''] A human-readable string explaining why + * the connection was closed + * @param {Boolean} [options.wasClean=false] Indicates whether or not the + * connection was cleanly closed + */ + constructor(e, t = {}) { + super(e), this[ut] = t.code === void 0 ? 0 : t.code, this[gt] = t.reason === void 0 ? "" : t.reason, this[St] = t.wasClean === void 0 ? !1 : t.wasClean; + } + /** + * @type {Number} + */ + get code() { + return this[ut]; + } + /** + * @type {String} + */ + get reason() { + return this[gt]; + } + /** + * @type {Boolean} + */ + get wasClean() { + return this[St]; + } +} +Object.defineProperty(Oe.prototype, "code", { enumerable: !0 }); +Object.defineProperty(Oe.prototype, "reason", { enumerable: !0 }); +Object.defineProperty(Oe.prototype, "wasClean", { enumerable: !0 }); +class Xe extends Z { + /** + * Create a new `ErrorEvent`. + * + * @param {String} type The name of the event + * @param {Object} [options] A dictionary object that allows for setting + * attributes via object members of the same name + * @param {*} [options.error=null] The error that generated this event + * @param {String} [options.message=''] The error message + */ + constructor(e, t = {}) { + super(e), this[mt] = t.error === void 0 ? null : t.error, this[_t] = t.message === void 0 ? "" : t.message; + } + /** + * @type {*} + */ + get error() { + return this[mt]; + } + /** + * @type {String} + */ + get message() { + return this[_t]; + } +} +Object.defineProperty(Xe.prototype, "error", { enumerable: !0 }); +Object.defineProperty(Xe.prototype, "message", { enumerable: !0 }); +class Ft extends Z { + /** + * Create a new `MessageEvent`. + * + * @param {String} type The name of the event + * @param {Object} [options] A dictionary object that allows for setting + * attributes via object members of the same name + * @param {*} [options.data=null] The message content + */ + constructor(e, t = {}) { + super(e), this[pt] = t.data === void 0 ? null : t.data; + } + /** + * @type {*} + */ + get data() { + return this[pt]; + } +} +Object.defineProperty(Ft.prototype, "data", { enumerable: !0 }); +const ur = { + /** + * Register an event listener. + * + * @param {String} type A string representing the event type to listen for + * @param {(Function|Object)} handler The listener to add + * @param {Object} [options] An options object specifies characteristics about + * the event listener + * @param {Boolean} [options.once=false] A `Boolean` indicating that the + * listener should be invoked at most once after being added. If `true`, + * the listener would be automatically removed when invoked. + * @public + */ + addEventListener(s, e, t = {}) { + for (const r of this.listeners(s)) + if (!t[se] && r[De] === e && !r[se]) + return; + let i; + if (s === "message") + i = function(n, o) { + const a = new Ft("message", { + data: o ? n : n.toString() + }); + a[G] = this, me(e, this, a); + }; + else if (s === "close") + i = function(n, o) { + const a = new Oe("close", { + code: n, + reason: o.toString(), + wasClean: this._closeFrameReceived && this._closeFrameSent + }); + a[G] = this, me(e, this, a); + }; + else if (s === "error") + i = function(n) { + const o = new Xe("error", { + error: n, + message: n.message + }); + o[G] = this, me(e, this, o); + }; + else if (s === "open") + i = function() { + const n = new Z("open"); + n[G] = this, me(e, this, n); + }; + else + return; + i[se] = !!t[se], i[De] = e, t.once ? this.once(s, i) : this.on(s, i); + }, + /** + * Remove an event listener. + * + * @param {String} type A string representing the event type to remove + * @param {(Function|Object)} handler The listener to remove + * @public + */ + removeEventListener(s, e) { + for (const t of this.listeners(s)) + if (t[De] === e && !t[se]) { + this.removeListener(s, t); + break; + } + } +}; +var pr = { + EventTarget: ur +}; +function me(s, e, t) { + typeof s == "object" && s.handleEvent ? s.handleEvent.call(s, t) : s.call(e, t); +} +const { tokenChars: re } = fe; +function R(s, e, t) { + s[e] === void 0 ? s[e] = [t] : s[e].push(t); +} +function mr(s) { + const e = /* @__PURE__ */ Object.create(null); + let t = /* @__PURE__ */ Object.create(null), i = !1, r = !1, n = !1, o, a, c = -1, l = -1, h = -1, d = 0; + for (; d < s.length; d++) + if (l = s.charCodeAt(d), o === void 0) + if (h === -1 && re[l] === 1) + c === -1 && (c = d); + else if (d !== 0 && (l === 32 || l === 9)) + h === -1 && c !== -1 && (h = d); + else if (l === 59 || l === 44) { + if (c === -1) + throw new SyntaxError(`Unexpected character at index ${d}`); + h === -1 && (h = d); + const g = s.slice(c, h); + l === 44 ? (R(e, g, t), t = /* @__PURE__ */ Object.create(null)) : o = g, c = h = -1; + } else + throw new SyntaxError(`Unexpected character at index ${d}`); + else if (a === void 0) + if (h === -1 && re[l] === 1) + c === -1 && (c = d); + else if (l === 32 || l === 9) + h === -1 && c !== -1 && (h = d); + else if (l === 59 || l === 44) { + if (c === -1) + throw new SyntaxError(`Unexpected character at index ${d}`); + h === -1 && (h = d), R(t, s.slice(c, h), !0), l === 44 && (R(e, o, t), t = /* @__PURE__ */ Object.create(null), o = void 0), c = h = -1; + } else if (l === 61 && c !== -1 && h === -1) + a = s.slice(c, d), c = h = -1; + else + throw new SyntaxError(`Unexpected character at index ${d}`); + else if (r) { + if (re[l] !== 1) + throw new SyntaxError(`Unexpected character at index ${d}`); + c === -1 ? c = d : i || (i = !0), r = !1; + } else if (n) + if (re[l] === 1) + c === -1 && (c = d); + else if (l === 34 && c !== -1) + n = !1, h = d; + else if (l === 92) + r = !0; + else + throw new SyntaxError(`Unexpected character at index ${d}`); + else if (l === 34 && s.charCodeAt(d - 1) === 61) + n = !0; + else if (h === -1 && re[l] === 1) + c === -1 && (c = d); + else if (c !== -1 && (l === 32 || l === 9)) + h === -1 && (h = d); + else if (l === 59 || l === 44) { + if (c === -1) + throw new SyntaxError(`Unexpected character at index ${d}`); + h === -1 && (h = d); + let g = s.slice(c, h); + i && (g = g.replace(/\\/g, ""), i = !1), R(t, a, g), l === 44 && (R(e, o, t), t = /* @__PURE__ */ Object.create(null), o = void 0), a = void 0, c = h = -1; + } else + throw new SyntaxError(`Unexpected character at index ${d}`); + if (c === -1 || n || l === 32 || l === 9) + throw new SyntaxError("Unexpected end of input"); + h === -1 && (h = d); + const E = s.slice(c, h); + return o === void 0 ? R(e, E, t) : (a === void 0 ? R(t, E, !0) : i ? R(t, a, E.replace(/\\/g, "")) : R(t, a, E), R(e, o, t)), e; +} +function _r(s) { + return Object.keys(s).map((e) => { + let t = s[e]; + return Array.isArray(t) || (t = [t]), t.map((i) => [e].concat( + Object.keys(i).map((r) => { + let n = i[r]; + return Array.isArray(n) || (n = [n]), n.map((o) => o === !0 ? r : `${r}=${o}`).join("; "); + }) + ).join("; ")).join(", "); + }).join(", "); +} +var gr = { format: _r, parse: mr }; +const yr = ns, Sr = os, wr = as, Mt = ls, Er = cs, { randomBytes: vr, createHash: br } = Ke, { Duplex: Vi, Readable: qi } = le, { URL: $e } = hs, A = Ye, xr = tr, Tr = hr, { isBlob: kr } = fe, { + BINARY_TYPES: wt, + CLOSE_TIMEOUT: Or, + EMPTY_BUFFER: _e, + GUID: Pr, + kForOnEventAttribute: Fe, + kListener: Rr, + kStatusCode: Lr, + kWebSocket: S, + NOOP: Wt +} = D, { + EventTarget: { addEventListener: Ir, removeEventListener: Ur } +} = pr, { format: Nr, parse: Br } = gr, { toBuffer: Cr } = ke, jt = Symbol("kAborted"), Me = [8, 13], N = ["CONNECTING", "OPEN", "CLOSING", "CLOSED"], Ar = /^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/; +class f extends yr { + /** + * Create a new `WebSocket`. + * + * @param {(String|URL)} address The URL to which to connect + * @param {(String|String[])} [protocols] The subprotocols + * @param {Object} [options] Connection options + */ + constructor(e, t, i) { + super(), this._binaryType = wt[0], this._closeCode = 1006, this._closeFrameReceived = !1, this._closeFrameSent = !1, this._closeMessage = _e, this._closeTimer = null, this._errorEmitted = !1, this._extensions = {}, this._paused = !1, this._protocol = "", this._readyState = f.CONNECTING, this._receiver = null, this._sender = null, this._socket = null, e !== null ? (this._bufferedAmount = 0, this._isServer = !1, this._redirects = 0, t === void 0 ? t = [] : Array.isArray(t) || (typeof t == "object" && t !== null ? (i = t, t = []) : t = [t]), Vt(this, e, t, i)) : (this._autoPong = i.autoPong, this._closeTimeout = i.closeTimeout, this._isServer = !0); + } + /** + * For historical reasons, the custom "nodebuffer" type is used by the default + * instead of "blob". + * + * @type {String} + */ + get binaryType() { + return this._binaryType; + } + set binaryType(e) { + wt.includes(e) && (this._binaryType = e, this._receiver && (this._receiver._binaryType = e)); + } + /** + * @type {Number} + */ + get bufferedAmount() { + return this._socket ? this._socket._writableState.length + this._sender._bufferedBytes : this._bufferedAmount; + } + /** + * @type {String} + */ + get extensions() { + return Object.keys(this._extensions).join(); + } + /** + * @type {Boolean} + */ + get isPaused() { + return this._paused; + } + /** + * @type {Function} + */ + /* istanbul ignore next */ + get onclose() { + return null; + } + /** + * @type {Function} + */ + /* istanbul ignore next */ + get onerror() { + return null; + } + /** + * @type {Function} + */ + /* istanbul ignore next */ + get onopen() { + return null; + } + /** + * @type {Function} + */ + /* istanbul ignore next */ + get onmessage() { + return null; + } + /** + * @type {String} + */ + get protocol() { + return this._protocol; + } + /** + * @type {Number} + */ + get readyState() { + return this._readyState; + } + /** + * @type {String} + */ + get url() { + return this._url; + } + /** + * Set up the socket and the internal resources. + * + * @param {Duplex} socket The network socket between the server and client + * @param {Buffer} head The first packet of the upgraded stream + * @param {Object} options Options object + * @param {Boolean} [options.allowSynchronousEvents=false] Specifies whether + * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted + * multiple times in the same tick + * @param {Function} [options.generateMask] The function used to generate the + * masking key + * @param {Number} [options.maxPayload=0] The maximum allowed message size + * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or + * not to skip UTF-8 validation for text and close messages + * @private + */ + setSocket(e, t, i) { + const r = new xr({ + allowSynchronousEvents: i.allowSynchronousEvents, + binaryType: this.binaryType, + extensions: this._extensions, + isServer: this._isServer, + maxPayload: i.maxPayload, + skipUTF8Validation: i.skipUTF8Validation + }), n = new Tr(e, this._extensions, i.generateMask); + this._receiver = r, this._sender = n, this._socket = e, r[S] = this, n[S] = this, e[S] = this, r.on("conclude", Mr), r.on("drain", Wr), r.on("error", jr), r.on("message", Vr), r.on("ping", qr), r.on("pong", Gr), n.onerror = Jr, e.setTimeout && e.setTimeout(0), e.setNoDelay && e.setNoDelay(), t.length > 0 && e.unshift(t), e.on("close", Jt), e.on("data", Pe), e.on("end", zt), e.on("error", Kt), this._readyState = f.OPEN, this.emit("open"); + } + /** + * Emit the `'close'` event. + * + * @private + */ + emitClose() { + if (!this._socket) { + this._readyState = f.CLOSED, this.emit("close", this._closeCode, this._closeMessage); return; } - createSourceSelectorWindow2(); + this._extensions[A.extensionName] && this._extensions[A.extensionName].cleanup(), this._receiver.removeAllListeners(), this._readyState = f.CLOSED, this.emit("close", this._closeCode, this._closeMessage); + } + /** + * Start a closing handshake. + * + * +----------+ +-----------+ +----------+ + * - - -|ws.close()|-->|close frame|-->|ws.close()|- - - + * | +----------+ +-----------+ +----------+ | + * +----------+ +-----------+ | + * CLOSING |ws.close()|<--|close frame|<--+-----+ CLOSING + * +----------+ +-----------+ | + * | | | +---+ | + * +------------------------+-->|fin| - - - - + * | +---+ | +---+ + * - - - - -|fin|<---------------------+ + * +---+ + * + * @param {Number} [code] Status code explaining why the connection is closing + * @param {(String|Buffer)} [data] The reason why the connection is + * closing + * @public + */ + close(e, t) { + if (this.readyState !== f.CLOSED) { + if (this.readyState === f.CONNECTING) { + x(this, this._req, "WebSocket was closed before the connection was established"); + return; + } + if (this.readyState === f.CLOSING) { + this._closeFrameSent && (this._closeFrameReceived || this._receiver._writableState.errorEmitted) && this._socket.end(); + return; + } + this._readyState = f.CLOSING, this._sender.close(e, t, !this._isServer, (i) => { + i || (this._closeFrameSent = !0, (this._closeFrameReceived || this._receiver._writableState.errorEmitted) && this._socket.end()); + }), Gt(this); + } + } + /** + * Pause the socket. + * + * @public + */ + pause() { + this.readyState === f.CONNECTING || this.readyState === f.CLOSED || (this._paused = !0, this._socket.pause()); + } + /** + * Send a ping. + * + * @param {*} [data] The data to send + * @param {Boolean} [mask] Indicates whether or not to mask `data` + * @param {Function} [cb] Callback which is executed when the ping is sent + * @public + */ + ping(e, t, i) { + if (this.readyState === f.CONNECTING) + throw new Error("WebSocket is not open: readyState 0 (CONNECTING)"); + if (typeof e == "function" ? (i = e, e = t = void 0) : typeof t == "function" && (i = t, t = void 0), typeof e == "number" && (e = e.toString()), this.readyState !== f.OPEN) { + We(this, e, i); + return; + } + t === void 0 && (t = !this._isServer), this._sender.ping(e || _e, t, i); + } + /** + * Send a pong. + * + * @param {*} [data] The data to send + * @param {Boolean} [mask] Indicates whether or not to mask `data` + * @param {Function} [cb] Callback which is executed when the pong is sent + * @public + */ + pong(e, t, i) { + if (this.readyState === f.CONNECTING) + throw new Error("WebSocket is not open: readyState 0 (CONNECTING)"); + if (typeof e == "function" ? (i = e, e = t = void 0) : typeof t == "function" && (i = t, t = void 0), typeof e == "number" && (e = e.toString()), this.readyState !== f.OPEN) { + We(this, e, i); + return; + } + t === void 0 && (t = !this._isServer), this._sender.pong(e || _e, t, i); + } + /** + * Resume the socket. + * + * @public + */ + resume() { + this.readyState === f.CONNECTING || this.readyState === f.CLOSED || (this._paused = !1, this._receiver._writableState.needDrain || this._socket.resume()); + } + /** + * Send a data message. + * + * @param {*} data The message to send + * @param {Object} [options] Options object + * @param {Boolean} [options.binary] Specifies whether `data` is binary or + * text + * @param {Boolean} [options.compress] Specifies whether or not to compress + * `data` + * @param {Boolean} [options.fin=true] Specifies whether the fragment is the + * last one + * @param {Boolean} [options.mask] Specifies whether or not to mask `data` + * @param {Function} [cb] Callback which is executed when data is written out + * @public + */ + send(e, t, i) { + if (this.readyState === f.CONNECTING) + throw new Error("WebSocket is not open: readyState 0 (CONNECTING)"); + if (typeof t == "function" && (i = t, t = {}), typeof e == "number" && (e = e.toString()), this.readyState !== f.OPEN) { + We(this, e, i); + return; + } + const r = { + binary: typeof e != "string", + mask: !this._isServer, + compress: !0, + fin: !0, + ...t + }; + this._extensions[A.extensionName] || (r.compress = !1), this._sender.send(e || _e, r, i); + } + /** + * Forcibly close the connection. + * + * @public + */ + terminate() { + if (this.readyState !== f.CLOSED) { + if (this.readyState === f.CONNECTING) { + x(this, this._req, "WebSocket was closed before the connection was established"); + return; + } + this._socket && (this._readyState = f.CLOSING, this._socket.destroy()); + } + } +} +Object.defineProperty(f, "CONNECTING", { + enumerable: !0, + value: N.indexOf("CONNECTING") +}); +Object.defineProperty(f.prototype, "CONNECTING", { + enumerable: !0, + value: N.indexOf("CONNECTING") +}); +Object.defineProperty(f, "OPEN", { + enumerable: !0, + value: N.indexOf("OPEN") +}); +Object.defineProperty(f.prototype, "OPEN", { + enumerable: !0, + value: N.indexOf("OPEN") +}); +Object.defineProperty(f, "CLOSING", { + enumerable: !0, + value: N.indexOf("CLOSING") +}); +Object.defineProperty(f.prototype, "CLOSING", { + enumerable: !0, + value: N.indexOf("CLOSING") +}); +Object.defineProperty(f, "CLOSED", { + enumerable: !0, + value: N.indexOf("CLOSED") +}); +Object.defineProperty(f.prototype, "CLOSED", { + enumerable: !0, + value: N.indexOf("CLOSED") +}); +[ + "binaryType", + "bufferedAmount", + "extensions", + "isPaused", + "protocol", + "readyState", + "url" +].forEach((s) => { + Object.defineProperty(f.prototype, s, { enumerable: !0 }); +}); +["open", "error", "close", "message"].forEach((s) => { + Object.defineProperty(f.prototype, `on${s}`, { + enumerable: !0, + get() { + for (const e of this.listeners(s)) + if (e[Fe]) return e[Rr]; + return null; + }, + set(e) { + for (const t of this.listeners(s)) + if (t[Fe]) { + this.removeListener(s, t); + break; + } + typeof e == "function" && this.addEventListener(s, e, { + [Fe]: !0 + }); + } }); - ipcMain.handle("switch-to-editor", () => { - const mainWin = getMainWindow(); - if (mainWin) { - mainWin.close(); +}); +f.prototype.addEventListener = Ir; +f.prototype.removeEventListener = Ur; +var Dr = f; +function Vt(s, e, t, i) { + const r = { + allowSynchronousEvents: !0, + autoPong: !0, + closeTimeout: Or, + protocolVersion: Me[1], + maxPayload: 104857600, + skipUTF8Validation: !1, + perMessageDeflate: !0, + followRedirects: !1, + maxRedirects: 10, + ...i, + socketPath: void 0, + hostname: void 0, + protocol: void 0, + timeout: void 0, + method: "GET", + host: void 0, + path: void 0, + port: void 0 + }; + if (s._autoPong = r.autoPong, s._closeTimeout = r.closeTimeout, !Me.includes(r.protocolVersion)) + throw new RangeError( + `Unsupported protocol version: ${r.protocolVersion} (supported versions: ${Me.join(", ")})` + ); + let n; + if (e instanceof $e) + n = e; + else + try { + n = new $e(e); + } catch { + throw new SyntaxError(`Invalid URL: ${e}`); + } + n.protocol === "http:" ? n.protocol = "ws:" : n.protocol === "https:" && (n.protocol = "wss:"), s._url = n.href; + const o = n.protocol === "wss:", a = n.protocol === "ws+unix:"; + let c; + if (n.protocol !== "ws:" && !o && !a ? c = `The URL's protocol must be one of "ws:", "wss:", "http:", "https:", or "ws+unix:"` : a && !n.pathname ? c = "The URL's pathname is empty" : n.hash && (c = "The URL contains a fragment identifier"), c) { + const u = new SyntaxError(c); + if (s._redirects === 0) + throw u; + Se(s, u); + return; + } + const l = o ? 443 : 80, h = vr(16).toString("base64"), d = o ? Sr.request : wr.request, E = /* @__PURE__ */ new Set(); + let g; + if (r.createConnection = r.createConnection || (o ? Fr : $r), r.defaultPort = r.defaultPort || l, r.port = n.port || l, r.host = n.hostname.startsWith("[") ? n.hostname.slice(1, -1) : n.hostname, r.headers = { + ...r.headers, + "Sec-WebSocket-Version": r.protocolVersion, + "Sec-WebSocket-Key": h, + Connection: "Upgrade", + Upgrade: "websocket" + }, r.path = n.pathname + n.search, r.timeout = r.handshakeTimeout, r.perMessageDeflate && (g = new A( + r.perMessageDeflate !== !0 ? r.perMessageDeflate : {}, + !1, + r.maxPayload + ), r.headers["Sec-WebSocket-Extensions"] = Nr({ + [A.extensionName]: g.offer() + })), t.length) { + for (const u of t) { + if (typeof u != "string" || !Ar.test(u) || E.has(u)) + throw new SyntaxError( + "An invalid or duplicated subprotocol was specified" + ); + E.add(u); + } + r.headers["Sec-WebSocket-Protocol"] = t.join(","); + } + if (r.origin && (r.protocolVersion < 13 ? r.headers["Sec-WebSocket-Origin"] = r.origin : r.headers.Origin = r.origin), (n.username || n.password) && (r.auth = `${n.username}:${n.password}`), a) { + const u = r.path.split(":"); + r.socketPath = u[0], r.path = u[1]; + } + let _; + if (r.followRedirects) { + if (s._redirects === 0) { + s._originalIpc = a, s._originalSecure = o, s._originalHostOrSocketPath = a ? r.socketPath : n.host; + const u = i && i.headers; + if (i = { ...i, headers: {} }, u) + for (const [w, L] of Object.entries(u)) + i.headers[w.toLowerCase()] = L; + } else if (s.listenerCount("redirect") === 0) { + const u = a ? s._originalIpc ? r.socketPath === s._originalHostOrSocketPath : !1 : s._originalIpc ? !1 : n.host === s._originalHostOrSocketPath; + (!u || s._originalSecure && !o) && (delete r.headers.authorization, delete r.headers.cookie, u || delete r.headers.host, r.auth = void 0); + } + r.auth && !i.headers.authorization && (i.headers.authorization = "Basic " + Buffer.from(r.auth).toString("base64")), _ = s._req = d(r), s._redirects && s.emit("redirect", s.url, _); + } else + _ = s._req = d(r); + r.timeout && _.on("timeout", () => { + x(s, _, "Opening handshake has timed out"); + }), _.on("error", (u) => { + _ === null || _[jt] || (_ = s._req = null, Se(s, u)); + }), _.on("response", (u) => { + const w = u.headers.location, L = u.statusCode; + if (w && r.followRedirects && L >= 300 && L < 400) { + if (++s._redirects > r.maxRedirects) { + x(s, _, "Maximum redirects exceeded"); + return; + } + _.abort(); + let B; + try { + B = new $e(w, e); + } catch { + const I = new SyntaxError(`Invalid URL: ${w}`); + Se(s, I); + return; + } + Vt(s, B, t, i); + } else s.emit("unexpected-response", _, u) || x( + s, + _, + `Unexpected server response: ${u.statusCode}` + ); + }), _.on("upgrade", (u, w, L) => { + if (s.emit("upgrade", u), s.readyState !== f.CONNECTING) return; + _ = s._req = null; + const B = u.headers.upgrade; + if (B === void 0 || B.toLowerCase() !== "websocket") { + x(s, w, "Invalid Upgrade header"); + return; + } + const Q = br("sha1").update(h + Pr).digest("base64"); + if (u.headers["sec-websocket-accept"] !== Q) { + x(s, w, "Invalid Sec-WebSocket-Accept header"); + return; + } + const I = u.headers["sec-websocket-protocol"]; + let ee; + if (I !== void 0 ? E.size ? E.has(I) || (ee = "Server sent an invalid subprotocol") : ee = "Server sent a subprotocol but none was requested" : E.size && (ee = "Server sent no subprotocol"), ee) { + x(s, w, ee); + return; + } + I && (s._protocol = I); + const Qe = u.headers["sec-websocket-extensions"]; + if (Qe !== void 0) { + if (!g) { + x(s, w, "Server sent a Sec-WebSocket-Extensions header but no extension was requested"); + return; + } + let Re; + try { + Re = Br(Qe); + } catch { + x(s, w, "Invalid Sec-WebSocket-Extensions header"); + return; + } + const et = Object.keys(Re); + if (et.length !== 1 || et[0] !== A.extensionName) { + x(s, w, "Server indicated an extension that was not requested"); + return; + } + try { + g.accept(Re[A.extensionName]); + } catch { + x(s, w, "Invalid Sec-WebSocket-Extensions header"); + return; + } + s._extensions[A.extensionName] = g; + } + s.setSocket(w, L, { + allowSynchronousEvents: r.allowSynchronousEvents, + generateMask: r.generateMask, + maxPayload: r.maxPayload, + skipUTF8Validation: r.skipUTF8Validation + }); + }), r.finishRequest ? r.finishRequest(_, s) : _.end(); +} +function Se(s, e) { + s._readyState = f.CLOSING, s._errorEmitted = !0, s.emit("error", e), s.emitClose(); +} +function $r(s) { + return s.path = s.socketPath, Mt.connect(s); +} +function Fr(s) { + return s.path = void 0, !s.servername && s.servername !== "" && (s.servername = Mt.isIP(s.host) ? "" : s.host), Er.connect(s); +} +function x(s, e, t) { + s._readyState = f.CLOSING; + const i = new Error(t); + Error.captureStackTrace(i, x), e.setHeader ? (e[jt] = !0, e.abort(), e.socket && !e.socket.destroyed && e.socket.destroy(), process.nextTick(Se, s, i)) : (e.destroy(i), e.once("error", s.emit.bind(s, "error")), e.once("close", s.emitClose.bind(s))); +} +function We(s, e, t) { + if (e) { + const i = kr(e) ? e.size : Cr(e).length; + s._socket ? s._sender._bufferedBytes += i : s._bufferedAmount += i; + } + if (t) { + const i = new Error( + `WebSocket is not open: readyState ${s.readyState} (${N[s.readyState]})` + ); + process.nextTick(t, i); + } +} +function Mr(s, e) { + const t = this[S]; + t._closeFrameReceived = !0, t._closeMessage = e, t._closeCode = s, t._socket[S] !== void 0 && (t._socket.removeListener("data", Pe), process.nextTick(qt, t._socket), s === 1005 ? t.close() : t.close(s, e)); +} +function Wr() { + const s = this[S]; + s.isPaused || s._socket.resume(); +} +function jr(s) { + const e = this[S]; + e._socket[S] !== void 0 && (e._socket.removeListener("data", Pe), process.nextTick(qt, e._socket), e.close(s[Lr])), e._errorEmitted || (e._errorEmitted = !0, e.emit("error", s)); +} +function Et() { + this[S].emitClose(); +} +function Vr(s, e) { + this[S].emit("message", s, e); +} +function qr(s) { + const e = this[S]; + e._autoPong && e.pong(s, !this._isServer, Wt), e.emit("ping", s); +} +function Gr(s) { + this[S].emit("pong", s); +} +function qt(s) { + s.resume(); +} +function Jr(s) { + const e = this[S]; + e.readyState !== f.CLOSED && (e.readyState === f.OPEN && (e._readyState = f.CLOSING, Gt(e)), this._socket.end(), e._errorEmitted || (e._errorEmitted = !0, e.emit("error", s))); +} +function Gt(s) { + s._closeTimer = setTimeout( + s._socket.destroy.bind(s._socket), + s._closeTimeout + ); +} +function Jt() { + const s = this[S]; + if (this.removeListener("close", Jt), this.removeListener("data", Pe), this.removeListener("end", zt), s._readyState = f.CLOSING, !this._readableState.endEmitted && !s._closeFrameReceived && !s._receiver._writableState.errorEmitted && this._readableState.length !== 0) { + const e = this.read(this._readableState.length); + s._receiver.write(e); + } + s._receiver.end(), this[S] = void 0, clearTimeout(s._closeTimer), s._receiver._writableState.finished || s._receiver._writableState.errorEmitted ? s.emitClose() : (s._receiver.on("error", Et), s._receiver.on("finish", Et)); +} +function Pe(s) { + this[S]._receiver.write(s) || this.pause(); +} +function zt() { + const s = this[S]; + s._readyState = f.CLOSING, s._receiver.end(), this.end(); +} +function Kt() { + const s = this[S]; + this.removeListener("error", Kt), this.on("error", Wt), s && (s._readyState = f.CLOSING, this.destroy()); +} +const zr = /* @__PURE__ */ Rs(Dr), { Duplex: Gi } = le, { tokenChars: Ji } = fe, { Duplex: zi } = le, { createHash: Ki } = Ke, { CLOSE_TIMEOUT: Hi, GUID: Yi, kWebSocket: Xi } = D, ie = { + cache: "no-store" +}, Kr = (s) => ae + (s === !1 ? "" : " AssemblyAI/1.0 (" + Object.entries({ ...be, ...s }).map(([e, t]) => t ? `${e}=${t.name}/${t.version}` : "").join(" ") + ")"); +let ae = ""; +typeof navigator < "u" && navigator.userAgent && (ae += navigator.userAgent); +const be = { + sdk: { name: "JavaScript", version: "4.22.1" } +}; +typeof process < "u" && (process.versions.node && ae.indexOf("Node") === -1 && (be.runtime_env = { + name: "Node", + version: process.versions.node +}), process.versions.bun && ae.indexOf("Bun") === -1 && (be.runtime_env = { + name: "Bun", + version: process.versions.bun +})); +typeof Deno < "u" && process.versions.bun && ae.indexOf("Deno") === -1 && (be.runtime_env = { name: "Deno", version: Deno.version.deno }); +class he { + /** + * Create a new service. + * @param params - The parameters to use for the service. + */ + constructor(e) { + this.params = e, e.userAgent === !1 ? this.userAgent = void 0 : this.userAgent = Kr(e.userAgent || {}); + } + async fetch(e, t) { + t = { ...ie, ...t }; + let i = { + Authorization: this.params.apiKey, + "Content-Type": "application/json" + }; + ie != null && ie.headers && (i = { ...i, ...ie.headers }), t != null && t.headers && (i = { ...i, ...t.headers }), this.userAgent && (i["User-Agent"] = this.userAgent), t.headers = i, e.startsWith("http") || (e = this.params.baseUrl + e); + const r = await fetch(e, t); + if (r.status >= 400) { + let n; + const o = await r.text(); + if (o) { + try { + n = JSON.parse(o); + } catch { + } + throw n != null && n.error ? new Error(n.error) : new Error(o); + } + throw new Error(`HTTP Error: ${r.status} ${r.statusText}`); + } + return r; + } + async fetchJson(e, t) { + return (await this.fetch(e, t)).json(); + } +} +class Hr extends he { + summary(e, t) { + return this.fetchJson("/lemur/v3/generate/summary", { + method: "POST", + body: JSON.stringify(e), + signal: t + }); + } + questionAnswer(e, t) { + return this.fetchJson("/lemur/v3/generate/question-answer", { + method: "POST", + body: JSON.stringify(e), + signal: t + }); + } + actionItems(e, t) { + return this.fetchJson("/lemur/v3/generate/action-items", { + method: "POST", + body: JSON.stringify(e), + signal: t + }); + } + task(e, t) { + return this.fetchJson("/lemur/v3/generate/task", { + method: "POST", + body: JSON.stringify(e), + signal: t + }); + } + getResponse(e, t) { + return this.fetchJson(`/lemur/v3/${e}`, { signal: t }); + } + /** + * Delete the data for a previously submitted LeMUR request. + * @param id - ID of the LeMUR request + * @param signal - Optional AbortSignal to cancel the request + */ + purgeRequestData(e, t) { + return this.fetchJson(`/lemur/v3/${e}`, { + method: "DELETE", + signal: t + }); + } +} +const xe = (s, e) => new zr(s, e), y = { + BadSampleRate: 4e3, + AuthFailed: 4001, + InsufficientFunds: 4002, + FreeTierUser: 4003, + NonexistentSessionId: 4004, + SessionExpired: 4008, + ClosedSession: 4010, + RateLimited: 4029, + UniqueSessionViolation: 4030, + SessionTimeout: 4031, + AudioTooShort: 4032, + AudioTooLong: 4033, + AudioTooSmallToTranscode: 4034, + /** + * @deprecated Don't use + */ + BadJson: 4100, + BadSchema: 4101, + TooManyStreams: 4102, + Reconnected: 4103, + /** + * @deprecated Don't use + */ + ReconnectAttemptsExhausted: 1013, + WordBoostParameterParsingFailed: 4104 +}, vt = { + [y.BadSampleRate]: "Sample rate must be a positive integer", + [y.AuthFailed]: "Not Authorized", + [y.InsufficientFunds]: "Insufficient funds", + [y.FreeTierUser]: "This feature is paid-only and requires you to add a credit card. Please visit https://app.assemblyai.com/ to add a credit card to your account.", + [y.NonexistentSessionId]: "Session ID does not exist", + [y.SessionExpired]: "Session has expired", + [y.ClosedSession]: "Session is closed", + [y.RateLimited]: "Rate limited", + [y.UniqueSessionViolation]: "Unique session violation", + [y.SessionTimeout]: "Session Timeout", + [y.AudioTooShort]: "Audio too short", + [y.AudioTooLong]: "Audio too long", + [y.AudioTooSmallToTranscode]: "Audio too small to transcode", + [y.BadJson]: "Bad JSON", + [y.BadSchema]: "Bad schema", + [y.TooManyStreams]: "Too many streams", + [y.Reconnected]: "This session has been reconnected. This WebSocket is no longer valid.", + [y.ReconnectAttemptsExhausted]: "Reconnect attempts exhausted", + [y.WordBoostParameterParsingFailed]: "Could not parse word boost parameter" +}; +class Yr extends Error { +} +const v = { + BadSampleRate: 4e3, + AuthFailed: 4001, + InsufficientFunds: 4002, + FreeTierUser: 4003, + NonexistentSessionId: 4004, + SessionExpired: 4008, + ClosedSession: 4010, + RateLimited: 4029, + UniqueSessionViolation: 4030, + SessionTimeout: 4031, + AudioTooShort: 4032, + AudioTooLong: 4033, + AudioTooSmallToTranscode: 4034, + BadSchema: 4101, + TooManyStreams: 4102, + Reconnected: 4103 +}, bt = { + [v.BadSampleRate]: "Sample rate must be a positive integer", + [v.AuthFailed]: "Not Authorized", + [v.InsufficientFunds]: "Insufficient funds", + [v.FreeTierUser]: "This feature is paid-only and requires you to add a credit card. Please visit https://app.assemblyai.com/ to add a credit card to your account.", + [v.NonexistentSessionId]: "Session ID does not exist", + [v.SessionExpired]: "Session has expired", + [v.ClosedSession]: "Session is closed", + [v.RateLimited]: "Rate limited", + [v.UniqueSessionViolation]: "Unique session violation", + [v.SessionTimeout]: "Session Timeout", + [v.AudioTooShort]: "Audio too short", + [v.AudioTooLong]: "Audio too long", + [v.AudioTooSmallToTranscode]: "Audio too small to transcode", + [v.BadSchema]: "Bad schema", + [v.TooManyStreams]: "Too many streams", + [v.Reconnected]: "This session has been reconnected. This WebSocket is no longer valid." +}; +class Xr extends Error { +} +const Zr = "wss://api.assemblyai.com/v2/realtime/ws", Qr = '{"force_end_utterance":true}', xt = '{"terminate_session":true}'; +class ei { + /** + * Create a new RealtimeTranscriber. + * @param params - Parameters to configure the RealtimeTranscriber + */ + constructor(e) { + if (this.listeners = {}, this.realtimeUrl = e.realtimeUrl ?? Zr, this.sampleRate = e.sampleRate ?? 16e3, this.wordBoost = e.wordBoost, this.encoding = e.encoding, this.endUtteranceSilenceThreshold = e.endUtteranceSilenceThreshold, this.disablePartialTranscripts = e.disablePartialTranscripts, "token" in e && e.token && (this.token = e.token), "apiKey" in e && e.apiKey && (this.apiKey = e.apiKey), !(this.token || this.apiKey)) + throw new Error("API key or temporary token is required."); + } + connectionUrl() { + const e = new URL(this.realtimeUrl); + if (e.protocol !== "wss:") + throw new Error("Invalid protocol, must be wss"); + const t = new URLSearchParams(); + return this.token && t.set("token", this.token), t.set("sample_rate", this.sampleRate.toString()), this.wordBoost && this.wordBoost.length > 0 && t.set("word_boost", JSON.stringify(this.wordBoost)), this.encoding && t.set("encoding", this.encoding), t.set("enable_extra_session_information", "true"), this.disablePartialTranscripts && t.set("disable_partial_transcripts", this.disablePartialTranscripts.toString()), e.search = t.toString(), e; + } + /** + * Add a listener for an event. + * @param event - The event to listen for. + * @param listener - The function to call when the event is emitted. + */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + on(e, t) { + this.listeners[e] = t; + } + /** + * Connect to the server and begin a new session. + * @returns A promise that resolves when the connection is established and the session begins. + */ + connect() { + return new Promise((e) => { + if (this.socket) + throw new Error("Already connected"); + const t = this.connectionUrl(); + this.token ? this.socket = xe(t.toString()) : this.socket = xe(t.toString(), { + headers: { Authorization: this.apiKey } + }), this.socket.binaryType = "arraybuffer", this.socket.onopen = () => { + this.endUtteranceSilenceThreshold === void 0 || this.endUtteranceSilenceThreshold === null || this.configureEndUtteranceSilenceThreshold(this.endUtteranceSilenceThreshold); + }, this.socket.onclose = ({ code: i, reason: r }) => { + var n, o; + r || i in vt && (r = vt[i]), (o = (n = this.listeners).close) == null || o.call(n, i, r); + }, this.socket.onerror = (i) => { + var r, n, o, a; + i.error ? (n = (r = this.listeners).error) == null || n.call(r, i.error) : (a = (o = this.listeners).error) == null || a.call(o, new Error(i.message)); + }, this.socket.onmessage = ({ data: i }) => { + var n, o, a, c, l, h, d, E, g, _, u, w, L, B, Q; + const r = JSON.parse(i.toString()); + if ("error" in r) { + (o = (n = this.listeners).error) == null || o.call(n, new Yr(r.error)); + return; + } + switch (r.message_type) { + case "SessionBegins": { + const I = { + sessionId: r.session_id, + expiresAt: new Date(r.expires_at) + }; + e(I), (c = (a = this.listeners).open) == null || c.call(a, I); + break; + } + case "PartialTranscript": { + r.created = new Date(r.created), (h = (l = this.listeners).transcript) == null || h.call(l, r), (E = (d = this.listeners)["transcript.partial"]) == null || E.call(d, r); + break; + } + case "FinalTranscript": { + r.created = new Date(r.created), (_ = (g = this.listeners).transcript) == null || _.call(g, r), (w = (u = this.listeners)["transcript.final"]) == null || w.call(u, r); + break; + } + case "SessionInformation": { + (B = (L = this.listeners).session_information) == null || B.call(L, r); + break; + } + case "SessionTerminated": { + (Q = this.sessionTerminatedResolve) == null || Q.call(this); + break; + } + } + }; + }); + } + /** + * Send audio data to the server. + * @param audio - The audio data to send to the server. + */ + sendAudio(e) { + this.send(e); + } + /** + * Create a writable stream that can be used to send audio data to the server. + * @returns A writable stream that can be used to send audio data to the server. + */ + stream() { + return new It({ + write: (e) => { + this.sendAudio(e); + } + }); + } + /** + * Manually end an utterance + */ + forceEndUtterance() { + this.send(Qr); + } + /** + * Configure the threshold for how long to wait before ending an utterance. Default is 700ms. + * @param threshold - The duration of the end utterance silence threshold in milliseconds. + * This value must be an integer between 0 and 20_000. + */ + configureEndUtteranceSilenceThreshold(e) { + this.send(`{"end_utterance_silence_threshold":${e}}`); + } + send(e) { + if (!this.socket || this.socket.readyState !== this.socket.OPEN) + throw new Error("Socket is not open for communication"); + this.socket.send(e); + } + /** + * Close the connection to the server. + * @param waitForSessionTermination - If true, the method will wait for the session to be terminated before closing the connection. + * While waiting for the session to be terminated, you will receive the final transcript and session information. + */ + async close(e = !0) { + var t; + if (this.socket) { + if (this.socket.readyState === this.socket.OPEN) + if (e) { + const i = new Promise((r) => { + this.sessionTerminatedResolve = r; + }); + this.socket.send(xt), await i; + } else + this.socket.send(xt); + (t = this.socket) != null && t.removeAllListeners && this.socket.removeAllListeners(), this.socket.close(); + } + this.listeners = {}, this.socket = void 0; + } +} +class ti extends he { + constructor(e) { + super(e), this.rtFactoryParams = e; + } + /** + * @deprecated Use transcriber(...) instead + */ + createService(e) { + return this.transcriber(e); + } + transcriber(e) { + const t = { ...e }; + return !t.token && !t.apiKey && (t.apiKey = this.rtFactoryParams.apiKey), new ei(t); + } + async createTemporaryToken(e) { + return (await this.fetchJson("/v2/realtime/token", { + method: "POST", + body: JSON.stringify(e) + })).token; + } +} +function Tt(s) { + return s.startsWith("http") || s.startsWith("https") || s.startsWith("data:") ? null : s.startsWith("file://") ? s.substring(7) : s.startsWith("file:") ? s.substring(5) : s; +} +class si extends he { + constructor(e, t) { + super(e), this.files = t; + } + /** + * Transcribe an audio file. This will create a transcript and wait until the transcript status is "completed" or "error". + * @param params - The parameters to transcribe an audio file. + * @param options - The options to transcribe an audio file. + * @returns A promise that resolves to the transcript. The transcript status is "completed" or "error". + */ + async transcribe(e, t) { + const i = await this.submit(e); + return await this.waitUntilReady(i.id, t); + } + /** + * Submits a transcription job for an audio file. This will not wait until the transcript status is "completed" or "error". + * @param params - The parameters to start the transcription of an audio file. + * @returns A promise that resolves to the queued transcript. + */ + async submit(e) { + let t, i; + if ("audio" in e) { + const { audio: n, ...o } = e; + if (typeof n == "string") { + const a = Tt(n); + a !== null ? t = await this.files.upload(a) : n.startsWith("data:") ? t = await this.files.upload(n) : t = n; + } else + t = await this.files.upload(n); + i = { ...o, audio_url: t }; + } else + i = e; + return await this.fetchJson("/v2/transcript", { + method: "POST", + body: JSON.stringify(i) + }); + } + /** + * Create a transcript. + * @param params - The parameters to create a transcript. + * @param options - The options used for creating the new transcript. + * @returns A promise that resolves to the transcript. + * @deprecated Use `transcribe` instead to transcribe a audio file that includes polling, or `submit` to transcribe a audio file without polling. + */ + async create(e, t) { + const i = Tt(e.audio_url); + if (i !== null) { + const n = await this.files.upload(i); + e.audio_url = n; + } + const r = await this.fetchJson("/v2/transcript", { + method: "POST", + body: JSON.stringify(e) + }); + return (t == null ? void 0 : t.poll) ?? !0 ? await this.waitUntilReady(r.id, t) : r; + } + /** + * Wait until the transcript ready, either the status is "completed" or "error". + * @param transcriptId - The ID of the transcript. + * @param options - The options to wait until the transcript is ready. + * @returns A promise that resolves to the transcript. The transcript status is "completed" or "error". + */ + async waitUntilReady(e, t) { + const i = (t == null ? void 0 : t.pollingInterval) ?? 3e3, r = (t == null ? void 0 : t.pollingTimeout) ?? -1, n = Date.now(); + for (; ; ) { + const o = await this.get(e); + if (o.status === "completed" || o.status === "error") + return o; + if (r > 0 && Date.now() - n > r) + throw new Error("Polling timeout"); + await new Promise((a) => setTimeout(a, i)); + } + } + /** + * Retrieve a transcript. + * @param id - The identifier of the transcript. + * @returns A promise that resolves to the transcript. + */ + get(e) { + return this.fetchJson(`/v2/transcript/${e}`); + } + /** + * Retrieves a page of transcript listings. + * @param params - The parameters to filter the transcript list by, or the URL to retrieve the transcript list from. + */ + async list(e) { + let t = "/v2/transcript"; + typeof e == "string" ? t = e : e && (t = `${t}?${new URLSearchParams(Object.keys(e).map((r) => { + var n; + return [ + r, + ((n = e[r]) == null ? void 0 : n.toString()) || "" + ]; + }))}`); + const i = await this.fetchJson(t); + for (const r of i.transcripts) + r.created = new Date(r.created), r.completed && (r.completed = new Date(r.completed)); + return i; + } + /** + * Delete a transcript + * @param id - The identifier of the transcript. + * @returns A promise that resolves to the transcript. + */ + delete(e) { + return this.fetchJson(`/v2/transcript/${e}`, { method: "DELETE" }); + } + /** + * Search through the transcript for a specific set of keywords. + * You can search for individual words, numbers, or phrases containing up to five words or numbers. + * @param id - The identifier of the transcript. + * @param words - Keywords to search for. + * @returns A promise that resolves to the sentences. + */ + wordSearch(e, t) { + const i = new URLSearchParams({ words: t.join(",") }); + return this.fetchJson(`/v2/transcript/${e}/word-search?${i.toString()}`); + } + /** + * Retrieve all sentences of a transcript. + * @param id - The identifier of the transcript. + * @returns A promise that resolves to the sentences. + */ + sentences(e) { + return this.fetchJson(`/v2/transcript/${e}/sentences`); + } + /** + * Retrieve all paragraphs of a transcript. + * @param id - The identifier of the transcript. + * @returns A promise that resolves to the paragraphs. + */ + paragraphs(e) { + return this.fetchJson(`/v2/transcript/${e}/paragraphs`); + } + /** + * Retrieve subtitles of a transcript. + * @param id - The identifier of the transcript. + * @param format - The format of the subtitles. + * @param chars_per_caption - The maximum number of characters per caption. + * @returns A promise that resolves to the subtitles text. + */ + async subtitles(e, t = "srt", i) { + let r = `/v2/transcript/${e}/${t}`; + if (i) { + const o = new URLSearchParams(); + o.set("chars_per_caption", i.toString()), r += `?${o.toString()}`; + } + return await (await this.fetch(r)).text(); + } + /** + * Retrieve the redacted audio URL of a transcript. + * @param id - The identifier of the transcript. + * @returns A promise that resolves to the details of the redacted audio. + * @deprecated Use `redactedAudio` instead. + */ + redactions(e) { + return this.redactedAudio(e); + } + /** + * Retrieve the redacted audio URL of a transcript. + * @param id - The identifier of the transcript. + * @returns A promise that resolves to the details of the redacted audio. + */ + redactedAudio(e) { + return this.fetchJson(`/v2/transcript/${e}/redacted-audio`); + } + /** + * Retrieve the redacted audio file of a transcript. + * @param id - The identifier of the transcript. + * @returns A promise that resolves to the fetch HTTP response of the redacted audio file. + */ + async redactedAudioFile(e) { + const { redacted_audio_url: t, status: i } = await this.redactedAudio(e); + if (i !== "redacted_audio_ready") + throw new Error(`Redacted audio status is ${i}`); + const r = await fetch(t); + if (!r.ok) + throw new Error(`Failed to fetch redacted audio: ${r.statusText}`); + return { + arrayBuffer: r.arrayBuffer.bind(r), + blob: r.blob.bind(r), + body: r.body, + bodyUsed: r.bodyUsed + }; + } +} +const ri = async (s) => fs.toWeb(ps(s)); +class ii extends he { + /** + * Upload a local file to AssemblyAI. + * @param input - The local file path to upload, or a stream or buffer of the file to upload. + * @returns A promise that resolves to the uploaded file URL. + */ + async upload(e) { + let t; + return typeof e == "string" ? e.startsWith("data:") ? t = ni(e) : t = await ri(e) : t = e, (await this.fetchJson("/v2/upload", { + method: "POST", + body: t, + headers: { + "Content-Type": "application/octet-stream" + }, + duplex: "half" + })).upload_url; + } +} +function ni(s) { + const e = s.split(","), t = e[0].match(/:(.*?);/)[1], i = atob(e[1]); + let r = i.length; + const n = new Uint8Array(r); + for (; r--; ) + n[r] = i.charCodeAt(r); + return new Blob([n], { type: t }); +} +const oi = "wss://streaming.assemblyai.com/v3/ws", kt = '{"type":"Terminate"}'; +class ai { + constructor(e) { + if (this.listeners = {}, this.params = { + ...e, + websocketBaseUrl: e.websocketBaseUrl || oi + }, "token" in e && e.token && (this.token = e.token), "apiKey" in e && e.apiKey && (this.apiKey = e.apiKey), !(this.token || this.apiKey)) + throw new Error("API key or temporary token is required."); + } + connectionUrl() { + const e = new URL(this.params.websocketBaseUrl ?? ""); + if (e.protocol !== "wss:") + throw new Error("Invalid protocol, must be wss"); + const t = new URLSearchParams(); + return this.token && t.set("token", this.token), t.set("sample_rate", this.params.sampleRate.toString()), this.params.endOfTurnConfidenceThreshold && t.set("end_of_turn_confidence_threshold", this.params.endOfTurnConfidenceThreshold.toString()), this.params.minEndOfTurnSilenceWhenConfident && t.set("min_end_of_turn_silence_when_confident", this.params.minEndOfTurnSilenceWhenConfident.toString()), this.params.maxTurnSilence && t.set("max_turn_silence", this.params.maxTurnSilence.toString()), this.params.vadThreshold !== void 0 && t.set("vad_threshold", this.params.vadThreshold.toString()), this.params.formatTurns && t.set("format_turns", this.params.formatTurns.toString()), this.params.encoding && t.set("encoding", this.params.encoding.toString()), this.params.keytermsPrompt ? t.set("keyterms_prompt", JSON.stringify(this.params.keytermsPrompt)) : this.params.keyterms && (console.warn("[Deprecation Warning] `keyterms` is deprecated and will be removed in a future release. Please use `keytermsPrompt` instead."), t.set("keyterms_prompt", JSON.stringify(this.params.keyterms))), this.params.filterProfanity && t.set("filter_profanity", this.params.filterProfanity.toString()), this.params.speechModel && t.set("speech_model", this.params.speechModel.toString()), this.params.languageDetection !== void 0 && t.set("language_detection", this.params.languageDetection.toString()), this.params.inactivityTimeout !== void 0 && t.set("inactivity_timeout", this.params.inactivityTimeout.toString()), e.search = t.toString(), e; + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + on(e, t) { + this.listeners[e] = t; + } + connect() { + return new Promise((e) => { + if (this.socket) + throw new Error("Already connected"); + const t = this.connectionUrl(); + this.token ? this.socket = xe(t.toString()) : this.socket = xe(t.toString(), { + headers: { Authorization: this.apiKey } + }), this.socket.binaryType = "arraybuffer", this.socket.onopen = () => { + }, this.socket.onclose = ({ code: i, reason: r }) => { + var n, o; + r || i in bt && (r = bt[i]), (o = (n = this.listeners).close) == null || o.call(n, i, r); + }, this.socket.onerror = (i) => { + var r, n, o, a; + i.error ? (n = (r = this.listeners).error) == null || n.call(r, i.error) : (a = (o = this.listeners).error) == null || a.call(o, new Error(i.message)); + }, this.socket.onmessage = ({ data: i }) => { + var n, o, a, c, l, h, d; + const r = JSON.parse(i.toString()); + if ("error" in r) { + (o = (n = this.listeners).error) == null || o.call(n, new Xr(r.error)); + return; + } + switch (r.type) { + case "Begin": { + e(r), (c = (a = this.listeners).open) == null || c.call(a, r); + break; + } + case "Turn": { + (h = (l = this.listeners).turn) == null || h.call(l, r); + break; + } + case "Termination": { + (d = this.sessionTerminatedResolve) == null || d.call(this); + break; + } + } + }; + }); + } + stream() { + return new It({ + write: (e) => { + this.sendAudio(e); + } + }); + } + sendAudio(e) { + this.send(e); + } + send(e) { + if (!this.socket || this.socket.readyState !== this.socket.OPEN) + throw new Error("Socket is not open for communication"); + this.socket.send(e); + } + async close(e = !0) { + var t; + if (this.socket) { + if (this.socket.readyState === this.socket.OPEN) + if (e) { + const i = new Promise((r) => { + this.sessionTerminatedResolve = r; + }); + this.socket.send(kt), await i; + } else + this.socket.send(kt); + (t = this.socket) != null && t.removeAllListeners && this.socket.removeAllListeners(), this.socket.close(); } - createEditorWindow2(); + this.listeners = {}, this.socket = void 0; + } +} +class li extends he { + constructor(e) { + super(e), this.baseServiceParams = e; + } + transcriber(e) { + const t = { ...e }; + return !t.token && !t.apiKey && (t.apiKey = this.baseServiceParams.apiKey), new ai(t); + } + async createTemporaryToken(e) { + const t = new URLSearchParams(); + Object.entries(e).forEach(([o, a]) => { + a != null && t.append(o, String(a)); + }); + const i = t.toString(), r = i ? `/v3/token?${i}` : "/v3/token"; + return (await this.fetchJson(r, { + method: "GET" + })).token; + } +} +const ci = "https://api.assemblyai.com", fi = "https://streaming.assemblyai.com"; +class hi { + /** + * Create a new AssemblyAI client. + * @param params - The parameters for the service, including the API key and base URL, if any. + */ + constructor(e) { + e.baseUrl = e.baseUrl || ci, e.baseUrl && e.baseUrl.endsWith("/") && (e.baseUrl = e.baseUrl.slice(0, -1)), this.files = new ii(e), this.transcripts = new si(e, this.files), this.lemur = new Hr(e), this.realtime = new ti(e), this.streaming = new li({ + ...e, + baseUrl: e.streamingBaseUrl || fi + }); + } +} +function di() { + const { app: s } = require("electron"); + if (s.isPackaged) { + const t = process.platform === "win32" ? "ffmpeg.exe" : "ffmpeg", i = Ut.join(process.resourcesPath, "bin", t); + if (je.existsSync(i)) + return i; + } + return process.platform === "win32" ? "ffmpeg.exe" : "ffmpeg"; +} +async function ui(s) { + const e = _s.tmpdir(), t = Ut.join(e, `audio-${Date.now()}.wav`), i = di(); + return new Promise((r, n) => { + const o = ms(i, [ + "-i", + s, + "-vn", + // No video + "-acodec", + "pcm_s16le", + // WAV format + "-ar", + "16000", + // 16kHz sample rate (optimal for speech recognition) + "-ac", + "1", + // Mono audio + "-y", + // Overwrite output file + t + ]); + let a = ""; + o.stderr.on("data", (c) => { + a += c.toString(); + }), o.on("close", (c) => { + c === 0 ? r(t) : n(new Error(`FFmpeg exited with code ${c}: ${a}`)); + }), o.on("error", (c) => { + n(new Error(`Failed to spawn ffmpeg: ${c.message}. Make sure ffmpeg is installed and in PATH.`)); + }); }); - ipcMain.handle("store-recorded-video", async (_, videoData, fileName) => { +} +async function pi(s, e) { + try { + if (!s.videoPath) + return { success: !1, error: "Video path is required" }; + if (!s.apiKey) + return { success: !1, error: "AssemblyAI API key is required" }; + if (!je.existsSync(s.videoPath)) + return { success: !1, error: `Video file not found: ${s.videoPath}` }; + e == null || e({ + status: "extracting", + progress: 10, + message: "Extracting audio from video..." + }); + let t; try { - const videoPath = path.join(RECORDINGS_DIR, fileName); - await fs.writeFile(videoPath, Buffer.from(videoData)); - currentVideoPath = videoPath; + t = await ui(s.videoPath); + } catch (a) { return { - success: true, - path: videoPath, - message: "Video stored successfully" + success: !1, + error: `Failed to extract audio: ${a instanceof Error ? a.message : String(a)}` }; - } catch (error) { - console.error("Failed to store video:", error); + } + e == null || e({ + status: "uploading", + progress: 20, + message: "Uploading audio to AssemblyAI..." + }); + const i = new hi({ apiKey: s.apiKey }); + e == null || e({ + status: "transcribing", + progress: 30, + message: "Transcribing audio (this may take a few minutes)..." + }); + const r = { + audio: t + }; + s.language && s.language !== "auto" && (r.language_code = s.language); + const n = await i.transcripts.transcribe(r); + e == null || e({ + status: "processing", + progress: 90, + message: "Processing transcription results..." + }); + try { + je.unlinkSync(t); + } catch { + console.warn("Failed to cleanup temp audio file:", t); + } + if (n.status === "error") return { - success: false, - message: "Failed to store video", - error: String(error) + success: !1, + error: n.error || "Transcription failed" }; + const o = (n.words || []).map((a) => ({ + text: a.text, + startMs: a.start, + endMs: a.end, + confidence: a.confidence + })); + return e == null || e({ + status: "complete", + progress: 100, + message: `Transcription complete! ${o.length} words detected.` + }), { + success: !0, + words: o + }; + } catch (t) { + return console.error("Transcription error:", t), { + success: !1, + error: t instanceof Error ? t.message : "Unknown transcription error" + }; + } +} +let ge = null; +function mi(s, e, t, i, r) { + p.handle("get-sources", async (o, a) => (await es.getSources(a)).map((l) => ({ + id: l.id, + name: l.name, + display_id: l.display_id, + thumbnail: l.thumbnail ? l.thumbnail.toDataURL() : null, + appIcon: l.appIcon ? l.appIcon.toDataURL() : null + }))), p.handle("select-source", (o, a) => { + ge = a; + const c = i(); + return c && c.close(), ge; + }), p.handle("get-selected-source", () => ge), p.handle("open-source-selector", () => { + const o = i(); + if (o) { + o.focus(); + return; } - }); - ipcMain.handle("get-recorded-video-path", async () => { + e(); + }), p.handle("switch-to-editor", () => { + const o = t(); + o && o.close(), s(); + }), p.handle("store-recorded-video", async (o, a, c) => { try { - const files = await fs.readdir(RECORDINGS_DIR); - const videoFiles = files.filter((file) => file.endsWith(".webm")); - if (videoFiles.length === 0) { - return { success: false, message: "No recorded video found" }; - } - const latestVideo = videoFiles.sort().reverse()[0]; - const videoPath = path.join(RECORDINGS_DIR, latestVideo); - return { success: true, path: videoPath }; - } catch (error) { - console.error("Failed to get video path:", error); - return { success: false, message: "Failed to get video path", error: String(error) }; + const l = m.join(J, c); + return await W.writeFile(l, Buffer.from(a)), n = l, { + success: !0, + path: l, + message: "Video stored successfully" + }; + } catch (l) { + return console.error("Failed to store video:", l), { + success: !1, + message: "Failed to store video", + error: String(l) + }; } - }); - ipcMain.handle("set-recording-state", (_, recording) => { - const source = selectedSource || { name: "Screen" }; - if (onRecordingStateChange) { - onRecordingStateChange(recording, source.name); + }), p.handle("get-recorded-video-path", async () => { + try { + const a = (await W.readdir(J)).filter((h) => h.endsWith(".webm")); + if (a.length === 0) + return { success: !1, message: "No recorded video found" }; + const c = a.sort().reverse()[0]; + return { success: !0, path: m.join(J, c) }; + } catch (o) { + return console.error("Failed to get video path:", o), { success: !1, message: "Failed to get video path", error: String(o) }; } - }); - ipcMain.handle("open-external-url", async (_, url) => { + }), p.handle("set-recording-state", (o, a) => { + r && r(a, (ge || { name: "Screen" }).name); + }), p.handle("open-external-url", async (o, a) => { try { - await shell.openExternal(url); - return { success: true }; - } catch (error) { - console.error("Failed to open URL:", error); - return { success: false, error: String(error) }; + return await ts.openExternal(a), { success: !0 }; + } catch (c) { + return console.error("Failed to open URL:", c), { success: !1, error: String(c) }; } - }); - ipcMain.handle("get-asset-base-path", () => { + }), p.handle("get-asset-base-path", () => { try { - if (app.isPackaged) { - return path.join(process.resourcesPath, "assets"); - } - return path.join(app.getAppPath(), "public", "assets"); - } catch (err) { - console.error("Failed to resolve asset base path:", err); - return null; + return P.isPackaged ? m.join(process.resourcesPath, "assets") : m.join(P.getAppPath(), "public", "assets"); + } catch (o) { + return console.error("Failed to resolve asset base path:", o), null; } - }); - ipcMain.handle("save-exported-video", async (_, videoData, fileName) => { + }), p.handle("save-exported-video", async (o, a, c) => { try { - const mainWindow2 = getMainWindow(); - const isGif = fileName.toLowerCase().endsWith(".gif"); - const filters = isGif ? [{ name: "GIF Image", extensions: ["gif"] }] : [{ name: "MP4 Video", extensions: ["mp4"] }]; - const result = await dialog.showSaveDialog(mainWindow2 || void 0, { - title: isGif ? "Save Exported GIF" : "Save Exported Video", - defaultPath: path.join(app.getPath("downloads"), fileName), - filters, + const l = t(), h = c.toLowerCase().endsWith(".gif"), d = h ? [{ name: "GIF Image", extensions: ["gif"] }] : [{ name: "MP4 Video", extensions: ["mp4"] }], E = { + title: h ? "Save Exported GIF" : "Save Exported Video", + defaultPath: m.join(P.getPath("downloads"), c), + filters: d, properties: ["createDirectory", "showOverwriteConfirmation"] - }); - if (result.canceled || !result.filePath) { - return { - success: false, - cancelled: true, - message: "Export cancelled" - }; - } - await fs.writeFile(result.filePath, Buffer.from(videoData)); - return { - success: true, - path: result.filePath, + }, g = l ? await Ie.showSaveDialog(l, E) : await Ie.showSaveDialog(E); + return g.canceled || !g.filePath ? { + success: !1, + cancelled: !0, + message: "Export cancelled" + } : (await W.writeFile(g.filePath, Buffer.from(a)), { + success: !0, + path: g.filePath, message: "Video exported successfully" - }; - } catch (error) { - console.error("Failed to save exported video:", error); - return { - success: false, + }); + } catch (l) { + return console.error("Failed to save exported video:", l), { + success: !1, message: "Failed to save exported video", - error: String(error) + error: String(l) }; } - }); - ipcMain.handle("open-video-file-picker", async () => { + }), p.handle("open-video-file-picker", async () => { try { - const result = await dialog.showOpenDialog({ + const o = await Ie.showOpenDialog({ title: "Select Video File", - defaultPath: RECORDINGS_DIR, + defaultPath: J, filters: [ { name: "Video Files", extensions: ["webm", "mp4", "mov", "avi", "mkv"] }, { name: "All Files", extensions: ["*"] } ], properties: ["openFile"] }); - if (result.canceled || result.filePaths.length === 0) { - return { success: false, cancelled: true }; - } - return { - success: true, - path: result.filePaths[0] + return o.canceled || o.filePaths.length === 0 ? { success: !1, cancelled: !0 } : { + success: !0, + path: o.filePaths[0] }; - } catch (error) { - console.error("Failed to open file picker:", error); - return { - success: false, + } catch (o) { + return console.error("Failed to open file picker:", o), { + success: !1, message: "Failed to open file picker", - error: String(error) + error: String(o) }; } }); - let currentVideoPath = null; - ipcMain.handle("set-current-video-path", (_, path2) => { - currentVideoPath = path2; - return { success: true }; - }); - ipcMain.handle("get-current-video-path", () => { - return currentVideoPath ? { success: true, path: currentVideoPath } : { success: false }; - }); - ipcMain.handle("clear-current-video-path", () => { - currentVideoPath = null; - return { success: true }; - }); - ipcMain.handle("get-platform", () => { - return process.platform; - }); + let n = null; + p.handle("set-current-video-path", (o, a) => (n = a, { success: !0 })), p.handle("get-current-video-path", () => n ? { success: !0, path: n } : { success: !1 }), p.handle("clear-current-video-path", () => (n = null, { success: !0 })), p.handle("get-platform", () => process.platform), p.handle("presets:get", async () => await bs()), p.handle("presets:save", async (o, a) => await xs(a)), p.handle("presets:update", async (o, a, c) => await Ts(a, c)), p.handle("presets:delete", async (o, a) => await ks(a)), p.handle("presets:duplicate", async (o, a) => await Os(a)), p.handle("presets:setDefault", async (o, a) => await Ps(a)), p.handle("transcribe-video", async (o, a) => await pi(a, (c) => { + const l = t(); + l && !l.isDestroyed() && l.webContents.send("transcription-progress", c); + })); } -const __dirname = path.dirname(fileURLToPath(import.meta.url)); -const RECORDINGS_DIR = path.join(app.getPath("userData"), "recordings"); -async function ensureRecordingsDir() { +const _i = m.dirname(Lt(import.meta.url)), J = m.join(P.getPath("userData"), "recordings"); +async function gi() { try { - await fs.mkdir(RECORDINGS_DIR, { recursive: true }); - console.log("RECORDINGS_DIR:", RECORDINGS_DIR); - console.log("User Data Path:", app.getPath("userData")); - } catch (error) { - console.error("Failed to create recordings directory:", error); - } -} -process.env.APP_ROOT = path.join(__dirname, ".."); -const VITE_DEV_SERVER_URL = process.env["VITE_DEV_SERVER_URL"]; -const MAIN_DIST = path.join(process.env.APP_ROOT, "dist-electron"); -const RENDERER_DIST = path.join(process.env.APP_ROOT, "dist"); -process.env.VITE_PUBLIC = VITE_DEV_SERVER_URL ? path.join(process.env.APP_ROOT, "public") : RENDERER_DIST; -let mainWindow = null; -let sourceSelectorWindow = null; -let tray = null; -let selectedSourceName = ""; -const defaultTrayIcon = getTrayIcon("openscreen.png"); -const recordingTrayIcon = getTrayIcon("rec-button.png"); -function createWindow() { - mainWindow = createHudOverlayWindow(); -} -function createTray() { - tray = new Tray(defaultTrayIcon); -} -function getTrayIcon(filename) { - return nativeImage.createFromPath(path.join(process.env.VITE_PUBLIC || RENDERER_DIST, filename)).resize({ + await W.mkdir(J, { recursive: !0 }), console.log("RECORDINGS_DIR:", J), console.log("User Data Path:", P.getPath("userData")); + } catch (s) { + console.error("Failed to create recordings directory:", s); + } +} +process.env.APP_ROOT = m.join(_i, ".."); +const yi = process.env.VITE_DEV_SERVER_URL, Zi = m.join(process.env.APP_ROOT, "dist-electron"), Ht = m.join(process.env.APP_ROOT, "dist"); +process.env.VITE_PUBLIC = yi ? m.join(process.env.APP_ROOT, "public") : Ht; +let b = null, ne = null, z = null, Yt = ""; +const Xt = Zt("openscreen.png"), Si = Zt("rec-button.png"); +function Ze() { + b = ys(); +} +function Ot() { + z = new rs(Xt); +} +function Zt(s) { + return ss.createFromPath(m.join(process.env.VITE_PUBLIC || Ht, s)).resize({ width: 24, height: 24, quality: "best" }); } -function updateTrayMenu(recording = false) { - if (!tray) return; - const trayIcon = recording ? recordingTrayIcon : defaultTrayIcon; - const trayToolTip = recording ? `Recording: ${selectedSourceName}` : "OpenScreen"; - const menuTemplate = recording ? [ +function Pt(s = !1) { + if (!z) return; + const e = s ? Si : Xt, t = s ? `Recording: ${Yt}` : "OpenScreen", i = s ? [ { label: "Stop Recording", click: () => { - if (mainWindow && !mainWindow.isDestroyed()) { - mainWindow.webContents.send("stop-recording-from-tray"); - } + b && !b.isDestroyed() && b.webContents.send("stop-recording-from-tray"); } } ] : [ { label: "Open", click: () => { - if (mainWindow && !mainWindow.isDestroyed()) { - mainWindow.isMinimized() && mainWindow.restore(); - } else { - createWindow(); - } + b && !b.isDestroyed() ? b.isMinimized() && b.restore() : Ze(); } }, { label: "Quit", click: () => { - app.quit(); + P.quit(); } } ]; - tray.setImage(trayIcon); - tray.setToolTip(trayToolTip); - tray.setContextMenu(Menu.buildFromTemplate(menuTemplate)); + z.setImage(e), z.setToolTip(t), z.setContextMenu(is.buildFromTemplate(i)); } -function createEditorWindowWrapper() { - if (mainWindow) { - mainWindow.close(); - mainWindow = null; - } - mainWindow = createEditorWindow(); +function wi() { + b && (b.close(), b = null), b = Ss(); } -function createSourceSelectorWindowWrapper() { - sourceSelectorWindow = createSourceSelectorWindow(); - sourceSelectorWindow.on("closed", () => { - sourceSelectorWindow = null; - }); - return sourceSelectorWindow; +function Ei() { + return ne = ws(), ne.on("closed", () => { + ne = null; + }), ne; } -app.on("window-all-closed", () => { +P.on("window-all-closed", () => { }); -app.on("activate", () => { - if (BrowserWindow.getAllWindows().length === 0) { - createWindow(); - } +P.on("activate", () => { + Te.getAllWindows().length === 0 && Ze(); }); -app.whenReady().then(async () => { - const { ipcMain: ipcMain2 } = await import("electron"); - ipcMain2.on("hud-overlay-close", () => { - app.quit(); - }); - createTray(); - updateTrayMenu(); - await ensureRecordingsDir(); - registerIpcHandlers( - createEditorWindowWrapper, - createSourceSelectorWindowWrapper, - () => mainWindow, - () => sourceSelectorWindow, - (recording, sourceName) => { - selectedSourceName = sourceName; - if (!tray) createTray(); - updateTrayMenu(recording); - if (!recording) { - if (mainWindow) mainWindow.restore(); - } +P.whenReady().then(async () => { + const { ipcMain: s } = await import("electron"); + s.on("hud-overlay-close", () => { + P.quit(); + }), Ot(), Pt(), await gi(), mi( + wi, + Ei, + () => b, + () => ne, + (e, t) => { + Yt = t, z || Ot(), Pt(e), e || b && b.restore(); } - ); - createWindow(); + ), Ze(); }); export { - MAIN_DIST, - RECORDINGS_DIR, - RENDERER_DIST, - VITE_DEV_SERVER_URL + Zi as MAIN_DIST, + J as RECORDINGS_DIR, + Ht as RENDERER_DIST, + yi as VITE_DEV_SERVER_URL }; diff --git a/dist-electron/preload.mjs b/dist-electron/preload.mjs index cb59604..086f2e0 100644 --- a/dist-electron/preload.mjs +++ b/dist-electron/preload.mjs @@ -1,63 +1 @@ -"use strict"; -const electron = require("electron"); -electron.contextBridge.exposeInMainWorld("electronAPI", { - hudOverlayHide: () => { - electron.ipcRenderer.send("hud-overlay-hide"); - }, - hudOverlayClose: () => { - electron.ipcRenderer.send("hud-overlay-close"); - }, - getAssetBasePath: async () => { - return await electron.ipcRenderer.invoke("get-asset-base-path"); - }, - getSources: async (opts) => { - return await electron.ipcRenderer.invoke("get-sources", opts); - }, - switchToEditor: () => { - return electron.ipcRenderer.invoke("switch-to-editor"); - }, - openSourceSelector: () => { - return electron.ipcRenderer.invoke("open-source-selector"); - }, - selectSource: (source) => { - return electron.ipcRenderer.invoke("select-source", source); - }, - getSelectedSource: () => { - return electron.ipcRenderer.invoke("get-selected-source"); - }, - storeRecordedVideo: (videoData, fileName) => { - return electron.ipcRenderer.invoke("store-recorded-video", videoData, fileName); - }, - getRecordedVideoPath: () => { - return electron.ipcRenderer.invoke("get-recorded-video-path"); - }, - setRecordingState: (recording) => { - return electron.ipcRenderer.invoke("set-recording-state", recording); - }, - onStopRecordingFromTray: (callback) => { - const listener = () => callback(); - electron.ipcRenderer.on("stop-recording-from-tray", listener); - return () => electron.ipcRenderer.removeListener("stop-recording-from-tray", listener); - }, - openExternalUrl: (url) => { - return electron.ipcRenderer.invoke("open-external-url", url); - }, - saveExportedVideo: (videoData, fileName) => { - return electron.ipcRenderer.invoke("save-exported-video", videoData, fileName); - }, - openVideoFilePicker: () => { - return electron.ipcRenderer.invoke("open-video-file-picker"); - }, - setCurrentVideoPath: (path) => { - return electron.ipcRenderer.invoke("set-current-video-path", path); - }, - getCurrentVideoPath: () => { - return electron.ipcRenderer.invoke("get-current-video-path"); - }, - clearCurrentVideoPath: () => { - return electron.ipcRenderer.invoke("clear-current-video-path"); - }, - getPlatform: () => { - return electron.ipcRenderer.invoke("get-platform"); - } -}); +"use strict";const e=require("electron");e.contextBridge.exposeInMainWorld("electronAPI",{hudOverlayHide:()=>{e.ipcRenderer.send("hud-overlay-hide")},hudOverlayClose:()=>{e.ipcRenderer.send("hud-overlay-close")},getAssetBasePath:async()=>await e.ipcRenderer.invoke("get-asset-base-path"),getSources:async r=>await e.ipcRenderer.invoke("get-sources",r),switchToEditor:()=>e.ipcRenderer.invoke("switch-to-editor"),openSourceSelector:()=>e.ipcRenderer.invoke("open-source-selector"),selectSource:r=>e.ipcRenderer.invoke("select-source",r),getSelectedSource:()=>e.ipcRenderer.invoke("get-selected-source"),storeRecordedVideo:(r,t)=>e.ipcRenderer.invoke("store-recorded-video",r,t),getRecordedVideoPath:()=>e.ipcRenderer.invoke("get-recorded-video-path"),setRecordingState:r=>e.ipcRenderer.invoke("set-recording-state",r),onStopRecordingFromTray:r=>{const t=()=>r();return e.ipcRenderer.on("stop-recording-from-tray",t),()=>e.ipcRenderer.removeListener("stop-recording-from-tray",t)},openExternalUrl:r=>e.ipcRenderer.invoke("open-external-url",r),saveExportedVideo:(r,t)=>e.ipcRenderer.invoke("save-exported-video",r,t),openVideoFilePicker:()=>e.ipcRenderer.invoke("open-video-file-picker"),setCurrentVideoPath:r=>e.ipcRenderer.invoke("set-current-video-path",r),getCurrentVideoPath:()=>e.ipcRenderer.invoke("get-current-video-path"),clearCurrentVideoPath:()=>e.ipcRenderer.invoke("clear-current-video-path"),getPlatform:()=>e.ipcRenderer.invoke("get-platform"),presets:{get:()=>e.ipcRenderer.invoke("presets:get"),save:r=>e.ipcRenderer.invoke("presets:save",r),update:(r,t)=>e.ipcRenderer.invoke("presets:update",r,t),delete:r=>e.ipcRenderer.invoke("presets:delete",r),duplicate:r=>e.ipcRenderer.invoke("presets:duplicate",r),setDefault:r=>e.ipcRenderer.invoke("presets:setDefault",r)},transcribeVideo:r=>e.ipcRenderer.invoke("transcribe-video",r),onTranscriptionProgress:r=>{const t=(o,n)=>r(n);return e.ipcRenderer.on("transcription-progress",t),()=>e.ipcRenderer.removeListener("transcription-progress",t)}}); diff --git a/docs/plans/2026-01-11-preset-feature-design.md b/docs/plans/2026-01-11-preset-feature-design.md new file mode 100644 index 0000000..a5a598c --- /dev/null +++ b/docs/plans/2026-01-11-preset-feature-design.md @@ -0,0 +1,265 @@ +# Preset Feature Design + +**Date:** 2026-01-11 +**Status:** Approved +**Author:** Brainstorming session + +--- + +## Overview + +A preset system that lets users save, load, and manage video styling configurations with one-click application. Users can create unlimited custom presets and set one as the default that auto-applies to all new videos. + +## Problem Statement + +Currently, users must manually reconfigure padding, shadow, rounded corners, background image, and other styling settings every time they open a new video in the editor. This is repetitive and time-consuming for users who have a preferred style. + +## Goals + +- Enable users to save current settings as a named preset +- Allow one-click application of saved presets +- Support setting a default preset that auto-applies to new videos +- Provide full preset management (create, rename, delete, duplicate) + +--- + +## Design Decisions + +| Aspect | Decision | +| ------------ | --------------------------------------------------------- | +| **Use Case** | Quick recall - one-click to apply favorite style | +| **Preset Count** | Unlimited custom presets + one default | +| **UI Location** | Top of SettingsPanel (dropdown + save button) | +| **Actions** | Create, Select, Rename, Delete, Duplicate, Set as Default | +| **Storage** | Electron Store (JSON file in app data folder) | +| **Save Flow** | Modal dialog for naming | + +--- + +## Data Structure + +### Preset Interface + +```typescript +interface Preset { + id: string; // Unique identifier (uuid) + name: string; // User-defined name + createdAt: number; // Timestamp for sorting + isDefault: boolean; // Only one preset can be default + + settings: { + padding: number; // 0-100 + shadowIntensity: number; // 0-1 + borderRadius: number; // 0-16 + motionBlurEnabled: boolean; + showBlur: boolean; + wallpaper: string; // Image path, color hex, or gradient CSS + } +} +``` + +### Settings Scope + +**Included:** +- `padding` (0-100%) +- `shadowIntensity` (0-1) +- `borderRadius` (0-16px) +- `motionBlurEnabled` (boolean) +- `showBlur` (boolean) +- `wallpaper` (image/color/gradient string) + +**Excluded (intentionally):** +- `cropRegion` - Video-specific, not a style +- `zoomRegions`, `trimRegions`, `annotations` - Timeline edits, not presets +- `aspectRatio`, `exportQuality` - Export settings, not visual style + +--- + +## Storage + +### Location + +Presets stored in user's app data folder: +- Windows: `%APPDATA%/openscreen/presets.json` +- macOS: `~/Library/Application Support/openscreen/presets.json` +- Linux: `~/.config/openscreen/presets.json` + +### File Structure + +```json +{ + "version": 1, + "defaultPresetId": "uuid-of-default-preset", + "presets": [ + { + "id": "abc-123", + "name": "My Clean Style", + "createdAt": 1736582400000, + "isDefault": true, + "settings": { + "padding": 50, + "shadowIntensity": 0.3, + "borderRadius": 8, + "motionBlurEnabled": true, + "showBlur": false, + "wallpaper": "wallpapers/wallpaper5.jpg" + } + } + ] +} +``` + +--- + +## UI Design + +### Layout + +Located at top of `SettingsPanel.tsx`, before "Zoom Level" section: + +``` +┌─────────────────────────────────────────┐ +│ Presets │ +│ ┌─────────────────────┐ ┌──────────┐ │ +│ │ Select preset... ▼ │ │ + Save │ │ +│ └─────────────────────┘ └──────────┘ │ +└─────────────────────────────────────────┘ +``` + +### Dropdown Menu Contents + +``` +┌─────────────────────────────┐ +│ ★ My Clean Style (Default) │ ← Star icon for default +│ Minimal Look │ +│ Bold & Colorful │ +├─────────────────────────────┤ +│ Reset to defaults │ ← Resets to app defaults +└─────────────────────────────┘ +``` + +### Preset Item Actions (on hover/right-click) + +- Rename +- Duplicate +- Set as Default / Unset Default +- Delete + +### Save Preset Modal + +``` +┌────────────────────────────────────┐ +│ Save as Preset [X] │ +├────────────────────────────────────┤ +│ Name: │ +│ ┌──────────────────────────────┐ │ +│ │ My New Preset │ │ +│ └──────────────────────────────┘ │ +│ │ +│ [ ] Set as default preset │ +│ │ +│ [Cancel] [Save] │ +└────────────────────────────────────┘ +``` + +--- + +## File Structure + +### New Files + +``` +src/ +├── components/video-editor/ +│ ├── PresetSelector.tsx # Dropdown + Save button component +│ └── SavePresetModal.tsx # Modal dialog for naming presets +├── hooks/ +│ └── usePresets.ts # React hook for preset state & operations +electron/ +├── presets.ts # Electron-side preset file operations +``` + +### Modified Files + +| File | Changes | +| --------------------------------------------- | --------------------------------------- | +| `electron/main.ts` | Add IPC handlers for preset operations | +| `electron/preload.ts` | Expose preset API to renderer | +| `src/components/video-editor/VideoEditor.tsx` | Add preset state, load default on mount | +| `src/components/video-editor/SettingsPanel.tsx` | Add PresetSelector at top | +| `src/components/video-editor/types.ts` | Add Preset interface | + +--- + +## Data Flow + +### On App Start (VideoEditor mount) + +1. VideoEditor mounts +2. Call `electronAPI.getPresets()` +3. Find preset where `isDefault === true` +4. If found → Apply `preset.settings` to state +5. If not found → Use current hardcoded defaults + +### On Preset Select + +1. User selects preset from dropdown +2. Apply `preset.settings` to all relevant state: + - `setPadding(preset.settings.padding)` + - `setShadowIntensity(preset.settings.shadowIntensity)` + - `setBorderRadius(preset.settings.borderRadius)` + - `setMotionBlurEnabled(preset.settings.motionBlurEnabled)` + - `setShowBlur(preset.settings.showBlur)` + - `setWallpaper(preset.settings.wallpaper)` +3. Show toast: "Applied preset: {name}" + +### On Save Preset + +1. User clicks "Save" button → Opens modal +2. User enters name, optionally checks "Set as default" +3. On confirm: + - Collect current settings from state + - Call `electronAPI.savePreset({ name, settings, isDefault })` + - If `isDefault`, unset previous default + - Refresh presets list + - Show toast: "Preset saved: {name}" + +### On Delete/Rename/Duplicate + +- **Delete:** Confirm dialog → `electronAPI.deletePreset(id)` +- **Rename:** Inline edit or modal → `electronAPI.updatePreset(id, { name })` +- **Duplicate:** `electronAPI.savePreset({ ...existing, name: "Copy of X" })` +- **Set as Default:** `electronAPI.setDefaultPreset(id)` + +--- + +## Edge Cases & Error Handling + +| Scenario | Handling | +| ----------------------------- | ------------------------------------------------------------------------------ | +| No presets exist | Dropdown shows "No presets yet" placeholder, only "Save" button is actionable | +| Default preset deleted | Clear `defaultPresetId`, next video opens with hardcoded defaults | +| Wallpaper path invalid | On apply, if wallpaper file doesn't exist, fallback to first default wallpaper | +| Corrupt presets.json | Catch parse error, backup corrupt file, start fresh with empty presets | +| Duplicate preset name | Allow it (names don't need to be unique, we use UUID for identity) | +| Very long preset name | Truncate display in dropdown (max ~25 chars with ellipsis) | +| Preset file permissions error | Show toast error, presets work in-memory only for that session | + +## Future Considerations + +- `version: 1` in JSON allows future schema migrations +- If new settings are added later, old presets apply what they have, new settings use defaults +- Potential for preset import/export feature in the future +- Potential for community preset sharing + +--- + +## Implementation Order + +1. **Types & Interfaces** - Add Preset types to `types.ts` +2. **Electron Backend** - Create `electron/presets.ts` with file operations +3. **IPC Handlers** - Add handlers in `main.ts` and expose in `preload.ts` +4. **React Hook** - Create `usePresets.ts` for state management +5. **UI Components** - Build `PresetSelector.tsx` and `SavePresetModal.tsx` +6. **Integration** - Wire up to `SettingsPanel.tsx` and `VideoEditor.tsx` +7. **Testing** - Manual testing of all CRUD operations and edge cases diff --git a/docs/plans/2026-01-13-microphone-input-design.md b/docs/plans/2026-01-13-microphone-input-design.md new file mode 100644 index 0000000..4c5afee --- /dev/null +++ b/docs/plans/2026-01-13-microphone-input-design.md @@ -0,0 +1,174 @@ +# Microphone Input Feature Design + +**Date:** 2026-01-13 +**Status:** Ready for Implementation + +## Overview + +Add microphone input capability to screen recording, allowing users to record voice narration alongside screen capture. Audio is merged directly into the video file. + +## Requirements + +- Audio microphone merged into single WebM output file +- User can select from available microphone devices +- Toggle control in HUD bar (simple, non-intrusive) +- Dropdown menu for device selection +- Real-time audio level meter for visual feedback + +## User Flow + +1. User opens app → HUD bar appears +2. User clicks mic icon in HUD → Dropdown appears with: + - List of available microphone devices + - Real-time audio level meter + - Mute toggle +3. User selects mic device → Saved as preference +4. User starts recording → Screen + mic audio captured simultaneously +5. Stop recording → Output: single WebM file with video + audio merged + +## Technical Architecture + +### Stream Combining Approach + +``` +┌─────────────────────────────────────────────────────┐ +│ MediaStream │ +│ ┌─────────────────┐ ┌─────────────────────────┐ │ +│ │ Video Track │ │ Audio Track │ │ +│ │ (screen capture)│ │ (microphone input) │ │ +│ └────────┬────────┘ └───────────┬─────────────┘ │ +│ │ │ │ +│ └──────────┬──────────────┘ │ +│ ▼ │ +│ ┌─────────────────┐ │ +│ │ MediaRecorder │ │ +│ │ (combined) │ │ +│ └────────┬────────┘ │ +│ ▼ │ +│ ┌─────────────────┐ │ +│ │ WebM Output │ │ +│ │ (video+audio) │ │ +│ └─────────────────┘ │ +└─────────────────────────────────────────────────────┘ +``` + +### Key Technical Decisions + +1. **Stream Combining**: Use `MediaStream` constructor to combine video track (from screen) + audio track (from mic) +2. **Device Enumeration**: Use `navigator.mediaDevices.enumerateDevices()` to list microphones +3. **Audio Level Meter**: Use `AudioContext` + `AnalyserNode` for real-time level visualization +4. **State Persistence**: Save selected mic `deviceId` to localStorage or Electron store + +## File Structure + +### New Files + +``` +src/ +├── hooks/ +│ └── useMicrophone.ts # Mic device management & level meter +│ +├── components/ +│ └── launch/ +│ └── MicrophoneSelector.tsx # Dropdown with device list + level meter +│ +├── stores/ +│ └── audioSettings.ts # Persist mic preferences +``` + +### Modified Files + +``` +src/ +├── hooks/ +│ └── useScreenRecorder.ts # Add audio stream support +│ +├── components/ +│ └── launch/ +│ └── LaunchWindow.tsx # Add mic toggle button +``` + +## Component Responsibilities + +| Component | Responsibility | +|-----------|----------------| +| `useMicrophone` hook | Enumerate devices, get audio stream, compute audio level, manage state | +| `MicrophoneSelector` | Dropdown UI, device list, level meter bar, toggle on/off | +| `useScreenRecorder` (modified) | Accept audio stream, combine with video, encode to WebM | +| `audioSettings` store | Persist deviceId, enabled state | + +## UI Design + +### HUD Bar Layout + +``` +┌─────────────────────────────────────────────────────────────────────┐ +│ ⋮⋮ │ 🖥️ Screen 1 │ 🎙️ │ ⏺️ Record │ 📁 Open │ ─ │ ✕ │ +│ │ │ ▼ │ │ │ │ │ +└─────────────────────────────────────────────────────────────────────┘ + ↑ + Mic Toggle (new) +``` + +### Mic Dropdown + +``` +┌─────────────────────────────────┐ +│ 🎙️ Microphone │ +├─────────────────────────────────┤ +│ ○ MacBook Pro Microphone │ +│ ● USB Microphone (selected) │ +│ ○ AirPods Pro │ +├─────────────────────────────────┤ +│ Level: ████████░░░░░░ (68%) │ +├─────────────────────────────────┤ +│ [ ] Mute microphone │ +└─────────────────────────────────┘ +``` + +### Visual States + +| State | Appearance | +|-------|------------| +| Mic enabled | Blue/white icon, small green indicator dot | +| Mic disabled/muted | Gray icon with strikethrough | +| Recording + mic on | Level meter active, red indicator | +| No mic found | Disabled icon, tooltip "No microphone detected" | + +## Error Handling + +| Scenario | Handling | +|----------|----------| +| No microphone detected | Show disabled mic icon with tooltip, user can still record without audio | +| Mic permission denied | Show toast/alert, guide user to system preferences, fallback to video-only | +| Mic disconnected mid-recording | Continue recording video-only, show notification "Microphone disconnected" | +| Mic reconnected | Auto-reconnect if same device, or notify user for manual selection | +| Multiple mic devices | Default to last-used device, fallback to system default | +| Audio encoding failure | Fallback to video-only, log error, notify user | + +### Permission Flow + +1. First time click mic → Browser/Electron permission prompt +2. If granted → Enumerate devices, enable mic +3. If denied → Show "Permission denied" state, provide help link +4. User can retry anytime via dropdown + +## Implementation Order + +1. Create `useMicrophone` hook (device enumeration, audio stream, level meter) +2. Create `audioSettings` store (persistence) +3. Create `MicrophoneSelector` component (UI) +4. Modify `useScreenRecorder` to accept and combine audio stream +5. Modify `LaunchWindow` to include mic toggle +6. Add error handling and edge cases +7. Test on multiple platforms (Windows, macOS, Linux) + +## Testing Considerations + +- Test with no microphone connected +- Test permission denial flow +- Test device hot-plug (connect/disconnect during recording) +- Test audio sync with video +- Test with multiple microphones +- Test level meter accuracy +- Test persistence across app restarts diff --git a/docs/plans/2026-01-14-auto-subtitle-design.md b/docs/plans/2026-01-14-auto-subtitle-design.md new file mode 100644 index 0000000..b57cd42 --- /dev/null +++ b/docs/plans/2026-01-14-auto-subtitle-design.md @@ -0,0 +1,384 @@ +# Auto-Subtitle Feature Design + +**Date:** 2026-01-14 +**Status:** Approved +**Author:** AI Assistant with User Input + +--- + +## Overview + +Add CapCut-style auto-subtitle generation to the video editor. Users can automatically transcribe video audio to generate timed subtitles, then customize fonts, positioning, and styling. + +## Transcription Engine + +**Provider:** AssemblyAI (Cloud API) +**Key Management:** User provides their own API key on first use (saved locally) + +## Languages Supported + +| Code | Language | +|------|------------| +| auto | Auto-detect | +| en | English | +| id | Indonesian | +| zh | Chinese | +| ja | Japanese | +| ko | Korean | +| es | Spanish | +| pt | Portuguese | +| vi | Vietnamese | +| th | Thai | + +--- + +## Data Model + +### New Types (types.ts) + +```typescript +export type SubtitleLanguage = + | 'auto' + | 'en' | 'id' | 'zh' | 'ja' | 'ko' | 'es' | 'pt' | 'vi' | 'th'; + +export type SubtitlePositionPreset = + | 'bottom-center' + | 'top-center' + | 'middle-center' + | 'custom'; + +export interface SubtitleStyle { + color: string; // Text color (default: #FFFFFF) + backgroundColor: string; // Background box color or 'transparent' + fontSize: number; // In pixels (default: 32) + fontFamily: string; // Font family (default: 'Inter') + fontWeight: 'normal' | 'bold'; + textAlign: 'left' | 'center' | 'right'; + strokeColor: string; // Text outline color (default: #000000) + strokeWidth: number; // Outline width 0-4px +} + +export interface SubtitleWord { + text: string; + startMs: number; + endMs: number; + confidence: number; +} + +export interface SubtitleRegion { + id: string; + startMs: number; // From AssemblyAI word.start + endMs: number; // From AssemblyAI word.end + text: string; // Joined words respecting maxWordsPerLine + words: SubtitleWord[]; // Individual word timings for highlighting + positionPreset: SubtitlePositionPreset; + customPosition?: { x: number; y: number }; + style: SubtitleStyle; +} + +export interface SubtitleGenerationConfig { + language: SubtitleLanguage; + maxWordsPerLine: number; // 2-8 words, default 4 + defaultStyle: SubtitleStyle; + defaultPosition: SubtitlePositionPreset; +} + +// Default values +export const DEFAULT_SUBTITLE_STYLE: SubtitleStyle = { + color: '#FFFFFF', + backgroundColor: '#000000CC', // Semi-transparent black + fontSize: 32, + fontFamily: 'Inter', + fontWeight: 'bold', + textAlign: 'center', + strokeColor: '#000000', + strokeWidth: 0, +}; + +export const DEFAULT_SUBTITLE_CONFIG: SubtitleGenerationConfig = { + language: 'auto', + maxWordsPerLine: 4, + defaultStyle: DEFAULT_SUBTITLE_STYLE, + defaultPosition: 'bottom-center', +}; +``` + +--- + +## Architecture + +### New Files + +``` +src/ +├── components/video-editor/ +│ ├── subtitle/ +│ │ ├── SubtitleOverlay.tsx # Renders subtitle on video (like AnnotationOverlay) +│ │ ├── SubtitleSettingsPanel.tsx # Editing panel when subtitle selected +│ │ └── SubtitleGenerateDialog.tsx # Modal wizard for auto-generation +│ └── timeline/ +│ └── TimelineEditor.tsx # (Modified) Add subtitle row +├── lib/ +│ └── assemblyai.ts # AssemblyAI service wrapper +├── hooks/ +│ └── useSubtitles.ts # Subtitle state management hook +└── main/ + └── services/ + └── transcription.ts # Handles API calls + audio extraction +``` + +### Data Flow + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ VideoEditor.tsx │ +├─────────────────────────────────────────────────────────────────┤ +│ State: subtitleRegions[], selectedSubtitleId, subtitleConfig │ +│ │ +│ ┌──────────────┐ ┌──────────────┐ ┌────────────────────┐ │ +│ │ VideoPlayback │ │ TimelineRow │ │ SubtitleSettings │ │ +│ │ + Overlay │ │ (Subtitle) │ │ Panel │ │ +│ └──────────────┘ └──────────────┘ └────────────────────┘ │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ SubtitleGenerateDialog │ +│ - Language selection │ +│ - Max words per line slider │ +│ - Style presets │ +│ - Position presets │ +│ - "Generate" button → triggers transcription │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ Electron Main Process │ +│ 1. Extract audio from video (ffmpeg) │ +│ 2. Upload to AssemblyAI │ +│ 3. Poll for completion │ +│ 4. Return words[] with timestamps │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ Renderer: Process Response │ +│ 1. Group words by maxWordsPerLine │ +│ 2. Create SubtitleRegion[] with timing from word boundaries │ +│ 3. Apply default style & position │ +│ 4. Set state → subtitles appear in timeline + video │ +└─────────────────────────────────────────────────────────────────┘ +``` + +--- + +## User Interface + +### Timeline Integration + +New "Subtitle" row in TimelineEditor (alongside Zoom/Trim/Annotation): + +``` +┌────────────────────────────────────────────────────────────────────┐ +│ 🔍 Zoom │██████░░░░░░░░░██████████░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│ ✂️ Trim │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│ 📝 Annotation │░░░░░░░████░░░░░░░░░░░░░░░░░░░░█████░░░░░░░░░░░░░░│ +│ 💬 Subtitle │░░░██░░░██░░░██░░░██░░░██░░░░░░░░░░░░░░░░░░░░░░░░│ ← NEW +│ │ [🪄 Auto Generate] [+ Add Manual] │ +└────────────────────────────────────────────────────────────────────┘ +``` + +### SubtitleGenerateDialog (Modal) + +``` +┌──────────────────────────────────────────────────────────────┐ +│ 🎯 Generate Subtitles [✕] │ +├──────────────────────────────────────────────────────────────┤ +│ │ +│ Language │ +│ ┌──────────────────────────────────────────────────────┐ │ +│ │ 🌐 Auto-detect (Recommended) ▼ │ │ +│ └──────────────────────────────────────────────────────┘ │ +│ │ +│ Max Words Per Line │ +│ ──●──────────────────────── 4 words │ +│ 2 3 4 5 6 7 8 │ +│ │ +│ Position │ +│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ +│ │ Bottom │ │ Top │ │ Middle │ │ +│ │ Center● │ │ Center │ │ Center │ │ +│ └─────────┘ └─────────┘ └─────────┘ │ +│ │ +│ Style Preview │ +│ ┌──────────────────────────────────────────────────────┐ │ +│ │ ┌─────────────────────────────────────┐ │ │ +│ │ │ Sample subtitle text here │ │ │ +│ │ └─────────────────────────────────────┘ │ │ +│ └──────────────────────────────────────────────────────┘ │ +│ │ +│ ┌────────────────────────────────────────────────────────┐ │ +│ │ 🪄 Generate Subtitles │ │ +│ └────────────────────────────────────────────────────────┘ │ +│ │ +│ Processing takes ~30 seconds per minute of video │ +└──────────────────────────────────────────────────────────────┘ +``` + +### Progress State + +``` +┌──────────────────────────────────────────────────────────────┐ +│ 🎯 Generating Subtitles... [✕] │ +├──────────────────────────────────────────────────────────────┤ +│ │ +│ ████████████████████░░░░░░░░░░░░░░░░ 45% │ +│ │ +│ Transcribing audio... │ +│ │ +│ ┌────────────────────────────────────────────────────────┐ │ +│ │ Cancel │ │ +│ └────────────────────────────────────────────────────────┘ │ +└──────────────────────────────────────────────────────────────┘ +``` + +### SubtitleSettingsPanel (Edit Mode) + +When subtitle is selected: + +- **Text Content** - Editable textarea +- **Font Style** - Dropdown (Classic, Editor, Strong, etc.) +- **Font Size** - Dropdown (12px - 128px) +- **Formatting** - Bold/Italic/Underline toggles +- **Alignment** - Left/Center/Right +- **Text Color** - Color picker +- **Background Color** - Color picker with transparency +- **Position Presets** - Bottom/Top/Middle/Custom +- **Outline** - Width slider + color picker +- **Split at Max Words** - Re-split option with word count +- **Delete Button** + +--- + +## Backend Integration + +### Electron IPC API + +```typescript +// src/main/services/transcription.ts + +export interface TranscriptionRequest { + videoPath: string; + language: string; // 'auto', 'en', 'id', etc. +} + +export interface TranscriptionWord { + text: string; + startMs: number; + endMs: number; + confidence: number; +} + +export interface TranscriptionResult { + success: boolean; + words?: TranscriptionWord[]; + error?: string; +} +``` + +### Word Grouping Algorithm + +```typescript +function groupWordsIntoSubtitles( + words: TranscriptionWord[], + maxWordsPerLine: number, + defaultStyle: SubtitleStyle, + defaultPosition: SubtitlePositionPreset, +): SubtitleRegion[] { + const subtitles: SubtitleRegion[] = []; + let currentGroup: TranscriptionWord[] = []; + let idCounter = 1; + + for (const word of words) { + currentGroup.push(word); + + // Split when reaching maxWordsPerLine OR natural sentence end + const isSentenceEnd = /[.!?]$/.test(word.text); + const reachedMaxWords = currentGroup.length >= maxWordsPerLine; + + if (reachedMaxWords || isSentenceEnd) { + subtitles.push({ + id: `subtitle-${idCounter++}`, + startMs: currentGroup[0].startMs, + endMs: currentGroup[currentGroup.length - 1].endMs, + text: currentGroup.map(w => w.text).join(' '), + words: [...currentGroup], + positionPreset: defaultPosition, + style: { ...defaultStyle }, + }); + currentGroup = []; + } + } + + // Handle remaining words + if (currentGroup.length > 0) { + subtitles.push({ + id: `subtitle-${idCounter++}`, + startMs: currentGroup[0].startMs, + endMs: currentGroup[currentGroup.length - 1].endMs, + text: currentGroup.map(w => w.text).join(' '), + words: [...currentGroup], + positionPreset: defaultPosition, + style: { ...defaultStyle }, + }); + } + + return subtitles; +} +``` + +--- + +## API Key Flow + +1. User clicks "Auto Generate" button +2. If no API key stored, show input prompt: + - Text input for API key + - Link to AssemblyAI signup (https://www.assemblyai.com) + - "Save & Continue" button +3. Key saved to electron-store for future sessions +4. Proceed to generation dialog + +--- + +## Export Integration + +Subtitles render to canvas during export (similar to annotations): + +- **MP4 Export:** Render subtitle text on each frame +- **GIF Export:** Render subtitle text on each frame +- Respects all styling: font, color, background, outline, position + +--- + +## Implementation Phases + +| Phase | Description | Est. Time | +|-------|-------------|-----------| +| 1 | Core types & state management | 1 day | +| 2 | Manual subtitle creation (overlay + settings panel) | 2 days | +| 3 | AssemblyAI integration (main process + IPC) | 2 days | +| 4 | Auto-generation UI (dialog + word grouping) | 1 day | +| 5 | Export integration (MP4 + GIF) | 1 day | + +**Total Estimated Time:** ~7 days + +--- + +## Technical Notes + +- AssemblyAI provides word-level timestamps in milliseconds +- API key should be stored securely in electron-store (not plaintext config) +- Audio extraction uses existing ffmpeg integration +- Word grouping respects natural sentence boundaries (. ! ?) +- Subtitle rendering uses canvas 2D context for export diff --git a/electron/electron-env.d.ts b/electron/electron-env.d.ts index dba3f16..63b87f9 100644 --- a/electron/electron-env.d.ts +++ b/electron/electron-env.d.ts @@ -21,10 +21,11 @@ declare namespace NodeJS { } } -// Used in Renderer process, expose in `preload.ts` -interface Window { - electronAPI: { - getSources: (opts: Electron.SourcesOptions) => Promise +// Used in Renderer process, expose in `preload.ts` +interface Window { + electronAPI: { + getAssetBasePath: () => Promise + getSources: (opts: Electron.SourcesOptions) => Promise switchToEditor: () => Promise openSourceSelector: () => Promise selectSource: (source: any) => Promise @@ -39,16 +40,62 @@ interface Window { setCurrentVideoPath: (path: string) => Promise<{ success: boolean }> getCurrentVideoPath: () => Promise<{ success: boolean; path?: string }> clearCurrentVideoPath: () => Promise<{ success: boolean }> - getPlatform: () => Promise - hudOverlayHide: () => void; - hudOverlayClose: () => void; - } -} + getPlatform: () => Promise + hudOverlayHide: () => void; + hudOverlayClose: () => void; + presets: { + get: () => Promise<{ success: boolean; presets: Preset[]; defaultPresetId: string | null }> + save: (preset: { name: string; isDefault: boolean; settings: PresetSettings }) => Promise<{ success: boolean; preset?: Preset; error?: string }> + update: (id: string, updates: Partial<{ name: string; isDefault: boolean; settings: PresetSettings }>) => Promise<{ success: boolean; preset?: Preset; error?: string }> + delete: (id: string) => Promise<{ success: boolean; error?: string }> + duplicate: (id: string) => Promise<{ success: boolean; preset?: Preset; error?: string }> + setDefault: (id: string | null) => Promise<{ success: boolean; error?: string }> + } + // Transcription API + transcribeVideo: (request: { + videoPath: string; + language: string; + apiKey: string + }) => Promise<{ + success: boolean; + words?: Array<{ + text: string; + startMs: number; + endMs: number; + confidence: number; + }>; + error?: string; + }> + onTranscriptionProgress: (callback: (progress: { + status: string; + progress: number; + message: string; + }) => void) => () => void + } +} -interface ProcessedDesktopSource { - id: string - name: string - display_id: string - thumbnail: string | null - appIcon: string | null -} +interface ProcessedDesktopSource { + id: string + name: string + display_id: string + thumbnail: string | null + appIcon: string | null +} + +// Preset types for electronAPI +interface PresetSettings { + padding: number + shadowIntensity: number + borderRadius: number + motionBlurEnabled: boolean + showBlur: boolean + wallpaper: string +} + +interface Preset { + id: string + name: string + createdAt: number + isDefault: boolean + settings: PresetSettings +} diff --git a/electron/ipc/handlers.ts b/electron/ipc/handlers.ts index 666d147..7fe3aad 100644 --- a/electron/ipc/handlers.ts +++ b/electron/ipc/handlers.ts @@ -3,6 +3,18 @@ import { ipcMain, desktopCapturer, BrowserWindow, shell, app, dialog } from 'ele import fs from 'node:fs/promises' import path from 'node:path' import { RECORDINGS_DIR } from '../main' +import { + getPresets, + savePreset, + updatePreset, + deletePreset, + duplicatePreset, + setDefaultPreset, + type Preset, + type PresetSettings +} from './presets' +import { transcribeVideo } from '../services/transcription' +import type { TranscriptionRequest, TranscriptionProgress } from '../../src/types/transcription' let selectedSource: any = null @@ -138,12 +150,16 @@ export function registerIpcHandlers( ? [{ name: 'GIF Image', extensions: ['gif'] }] : [{ name: 'MP4 Video', extensions: ['mp4'] }]; - const result = await dialog.showSaveDialog(mainWindow || undefined, { + const dialogOptions: Electron.SaveDialogOptions = { title: isGif ? 'Save Exported GIF' : 'Save Exported Video', defaultPath: path.join(app.getPath('downloads'), fileName), filters, properties: ['createDirectory', 'showOverwriteConfirmation'] - }); + }; + + const result = mainWindow + ? await dialog.showSaveDialog(mainWindow, dialogOptions) + : await dialog.showSaveDialog(dialogOptions); if (result.canceled || !result.filePath) { return { @@ -219,4 +235,46 @@ export function registerIpcHandlers( ipcMain.handle('get-platform', () => { return process.platform; }); + + // ============================================ + // PRESET HANDLERS + // ============================================ + + ipcMain.handle('presets:get', async () => { + return await getPresets(); + }); + + ipcMain.handle('presets:save', async (_, preset: { name: string; isDefault: boolean; settings: PresetSettings }) => { + return await savePreset(preset); + }); + + ipcMain.handle('presets:update', async (_, id: string, updates: Partial>) => { + return await updatePreset(id, updates); + }); + + ipcMain.handle('presets:delete', async (_, id: string) => { + return await deletePreset(id); + }); + + ipcMain.handle('presets:duplicate', async (_, id: string) => { + return await duplicatePreset(id); + }); + + ipcMain.handle('presets:setDefault', async (_, id: string | null) => { + return await setDefaultPreset(id); + }); + + // ============================================ + // TRANSCRIPTION HANDLERS + // ============================================ + + ipcMain.handle('transcribe-video', async (_event, request: TranscriptionRequest) => { + return await transcribeVideo(request, (progress: TranscriptionProgress) => { + // Send progress updates to renderer + const mainWindow = getMainWindow(); + if (mainWindow && !mainWindow.isDestroyed()) { + mainWindow.webContents.send('transcription-progress', progress); + } + }); + }); } diff --git a/electron/ipc/presets.ts b/electron/ipc/presets.ts new file mode 100644 index 0000000..795e23f --- /dev/null +++ b/electron/ipc/presets.ts @@ -0,0 +1,228 @@ +import { app } from 'electron' +import fs from 'node:fs/promises' +import path from 'node:path' + +// Types matching src/components/video-editor/types.ts +export interface PresetSettings { + padding: number; + shadowIntensity: number; + borderRadius: number; + motionBlurEnabled: boolean; + showBlur: boolean; + wallpaper: string; +} + +export interface Preset { + id: string; + name: string; + createdAt: number; + isDefault: boolean; + settings: PresetSettings; +} + +export interface PresetStore { + version: number; + defaultPresetId: string | null; + presets: Preset[]; +} + +const PRESETS_FILE_NAME = 'presets.json' +const CURRENT_VERSION = 1 + +function getPresetsFilePath(): string { + return path.join(app.getPath('userData'), PRESETS_FILE_NAME) +} + +function createEmptyStore(): PresetStore { + return { + version: CURRENT_VERSION, + defaultPresetId: null, + presets: [] + } +} + +export async function readPresetsStore(): Promise { + try { + const filePath = getPresetsFilePath() + const data = await fs.readFile(filePath, 'utf-8') + const store = JSON.parse(data) as PresetStore + + // Basic validation + if (!store.presets || !Array.isArray(store.presets)) { + console.warn('Invalid presets file, creating new store') + return createEmptyStore() + } + + return store + } catch (error: any) { + if (error.code === 'ENOENT') { + // File doesn't exist, return empty store + return createEmptyStore() + } + + // Corrupt file - backup and start fresh + console.error('Failed to read presets file:', error) + try { + const filePath = getPresetsFilePath() + const backupPath = filePath + '.backup.' + Date.now() + await fs.rename(filePath, backupPath) + console.log('Backed up corrupt presets file to:', backupPath) + } catch { + // Ignore backup errors + } + return createEmptyStore() + } +} + +export async function writePresetsStore(store: PresetStore): Promise { + const filePath = getPresetsFilePath() + await fs.writeFile(filePath, JSON.stringify(store, null, 2), 'utf-8') +} + +export async function getPresets(): Promise<{ success: boolean; presets: Preset[]; defaultPresetId: string | null }> { + try { + const store = await readPresetsStore() + return { + success: true, + presets: store.presets, + defaultPresetId: store.defaultPresetId + } + } catch (error) { + console.error('Failed to get presets:', error) + return { + success: false, + presets: [], + defaultPresetId: null + } + } +} + +export async function savePreset(preset: Omit): Promise<{ success: boolean; preset?: Preset; error?: string }> { + try { + const store = await readPresetsStore() + + const newPreset: Preset = { + ...preset, + id: crypto.randomUUID(), + createdAt: Date.now() + } + + // If this preset is default, unset any existing default + if (newPreset.isDefault) { + store.presets = store.presets.map(p => ({ ...p, isDefault: false })) + store.defaultPresetId = newPreset.id + } + + store.presets.push(newPreset) + await writePresetsStore(store) + + return { success: true, preset: newPreset } + } catch (error) { + console.error('Failed to save preset:', error) + return { success: false, error: String(error) } + } +} + +export async function updatePreset(id: string, updates: Partial>): Promise<{ success: boolean; preset?: Preset; error?: string }> { + try { + const store = await readPresetsStore() + + const index = store.presets.findIndex(p => p.id === id) + if (index === -1) { + return { success: false, error: 'Preset not found' } + } + + // Handle isDefault change + if (updates.isDefault === true) { + store.presets = store.presets.map(p => ({ ...p, isDefault: false })) + store.defaultPresetId = id + } else if (updates.isDefault === false && store.defaultPresetId === id) { + store.defaultPresetId = null + } + + store.presets[index] = { ...store.presets[index], ...updates } + await writePresetsStore(store) + + return { success: true, preset: store.presets[index] } + } catch (error) { + console.error('Failed to update preset:', error) + return { success: false, error: String(error) } + } +} + +export async function deletePreset(id: string): Promise<{ success: boolean; error?: string }> { + try { + const store = await readPresetsStore() + + const index = store.presets.findIndex(p => p.id === id) + if (index === -1) { + return { success: false, error: 'Preset not found' } + } + + // Clear default if deleting the default preset + if (store.defaultPresetId === id) { + store.defaultPresetId = null + } + + store.presets.splice(index, 1) + await writePresetsStore(store) + + return { success: true } + } catch (error) { + console.error('Failed to delete preset:', error) + return { success: false, error: String(error) } + } +} + +export async function duplicatePreset(id: string): Promise<{ success: boolean; preset?: Preset; error?: string }> { + try { + const store = await readPresetsStore() + + const original = store.presets.find(p => p.id === id) + if (!original) { + return { success: false, error: 'Preset not found' } + } + + const newPreset: Preset = { + ...original, + id: crypto.randomUUID(), + name: `Copy of ${original.name}`, + createdAt: Date.now(), + isDefault: false // Duplicates should never be default + } + + store.presets.push(newPreset) + await writePresetsStore(store) + + return { success: true, preset: newPreset } + } catch (error) { + console.error('Failed to duplicate preset:', error) + return { success: false, error: String(error) } + } +} + +export async function setDefaultPreset(id: string | null): Promise<{ success: boolean; error?: string }> { + try { + const store = await readPresetsStore() + + // Unset all defaults + store.presets = store.presets.map(p => ({ ...p, isDefault: false })) + store.defaultPresetId = null + + // Set new default if id provided + if (id) { + const preset = store.presets.find(p => p.id === id) + if (!preset) { + return { success: false, error: 'Preset not found' } + } + preset.isDefault = true + store.defaultPresetId = id + } + + await writePresetsStore(store) + return { success: true } + } catch (error) { + console.error('Failed to set default preset:', error) + return { success: false, error: String(error) } + } +} diff --git a/electron/preload.ts b/electron/preload.ts index 02fcc97..4eb98db 100644 --- a/electron/preload.ts +++ b/electron/preload.ts @@ -63,4 +63,41 @@ contextBridge.exposeInMainWorld('electronAPI', { getPlatform: () => { return ipcRenderer.invoke('get-platform') }, + + // ============================================ + // PRESET API + // ============================================ + presets: { + get: () => { + return ipcRenderer.invoke('presets:get') + }, + save: (preset: { name: string; isDefault: boolean; settings: any }) => { + return ipcRenderer.invoke('presets:save', preset) + }, + update: (id: string, updates: any) => { + return ipcRenderer.invoke('presets:update', id, updates) + }, + delete: (id: string) => { + return ipcRenderer.invoke('presets:delete', id) + }, + duplicate: (id: string) => { + return ipcRenderer.invoke('presets:duplicate', id) + }, + setDefault: (id: string | null) => { + return ipcRenderer.invoke('presets:setDefault', id) + }, + }, + + // ============================================ + // TRANSCRIPTION API + // ============================================ + transcribeVideo: (request: { videoPath: string; language: string; apiKey: string }) => { + return ipcRenderer.invoke('transcribe-video', request) + }, + + onTranscriptionProgress: (callback: (progress: { status: string; progress: number; message: string }) => void) => { + const listener = (_event: Electron.IpcRendererEvent, progress: { status: string; progress: number; message: string }) => callback(progress) + ipcRenderer.on('transcription-progress', listener) + return () => ipcRenderer.removeListener('transcription-progress', listener) + }, }) \ No newline at end of file diff --git a/electron/services/transcription.ts b/electron/services/transcription.ts new file mode 100644 index 0000000..f4271e0 --- /dev/null +++ b/electron/services/transcription.ts @@ -0,0 +1,192 @@ +/** + * Transcription Service for AssemblyAI integration + * Handles audio extraction and transcription using AssemblyAI + */ + +import { AssemblyAI } from 'assemblyai'; +import { spawn } from 'child_process'; +import * as path from 'path'; +import * as fs from 'fs'; +import * as os from 'os'; +import type { TranscriptionRequest, TranscriptionResult, TranscriptionWord, TranscriptionProgress } from '../../src/types/transcription'; + +/** + * Get the ffmpeg binary path based on platform + * In development: uses system ffmpeg + * In production: uses bundled ffmpeg + */ +function getFFmpegPath(): string { + // Try to use bundled ffmpeg first in production + const { app } = require('electron'); + if (app.isPackaged) { + const platform = process.platform; + const ffmpegName = platform === 'win32' ? 'ffmpeg.exe' : 'ffmpeg'; + const resourcePath = path.join(process.resourcesPath, 'bin', ffmpegName); + if (fs.existsSync(resourcePath)) { + return resourcePath; + } + } + // Fallback to system ffmpeg + return process.platform === 'win32' ? 'ffmpeg.exe' : 'ffmpeg'; +} + +/** + * Extract audio from video using ffmpeg + * @param videoPath - Path to the source video file + * @returns Path to the extracted audio file (WAV format) + */ +async function extractAudio(videoPath: string): Promise { + const tempDir = os.tmpdir(); + const audioPath = path.join(tempDir, `audio-${Date.now()}.wav`); + const ffmpegPath = getFFmpegPath(); + + return new Promise((resolve, reject) => { + // Use ffmpeg to extract audio + const ffmpeg = spawn(ffmpegPath, [ + '-i', videoPath, + '-vn', // No video + '-acodec', 'pcm_s16le', // WAV format + '-ar', '16000', // 16kHz sample rate (optimal for speech recognition) + '-ac', '1', // Mono audio + '-y', // Overwrite output file + audioPath + ]); + + let stderr = ''; + + ffmpeg.stderr.on('data', (data) => { + stderr += data.toString(); + }); + + ffmpeg.on('close', (code) => { + if (code === 0) { + resolve(audioPath); + } else { + reject(new Error(`FFmpeg exited with code ${code}: ${stderr}`)); + } + }); + + ffmpeg.on('error', (err) => { + reject(new Error(`Failed to spawn ffmpeg: ${err.message}. Make sure ffmpeg is installed and in PATH.`)); + }); + }); +} + +/** + * Transcribe a video file using AssemblyAI + * @param request - Transcription request with video path, language, and API key + * @param onProgress - Optional callback for progress updates + * @returns Transcription result with word-level timestamps + */ +export async function transcribeVideo( + request: TranscriptionRequest, + onProgress?: (progress: TranscriptionProgress) => void +): Promise { + try { + // Validate inputs + if (!request.videoPath) { + return { success: false, error: 'Video path is required' }; + } + if (!request.apiKey) { + return { success: false, error: 'AssemblyAI API key is required' }; + } + + // Check if video file exists + if (!fs.existsSync(request.videoPath)) { + return { success: false, error: `Video file not found: ${request.videoPath}` }; + } + + // Step 1: Extract audio from video + onProgress?.({ + status: 'extracting', + progress: 10, + message: 'Extracting audio from video...' + }); + + let audioPath: string; + try { + audioPath = await extractAudio(request.videoPath); + } catch (error) { + return { + success: false, + error: `Failed to extract audio: ${error instanceof Error ? error.message : String(error)}` + }; + } + + // Step 2: Initialize AssemblyAI client + onProgress?.({ + status: 'uploading', + progress: 20, + message: 'Uploading audio to AssemblyAI...' + }); + + const client = new AssemblyAI({ apiKey: request.apiKey }); + + // Step 3: Transcribe with AssemblyAI + onProgress?.({ + status: 'transcribing', + progress: 30, + message: 'Transcribing audio (this may take a few minutes)...' + }); + + // Build transcription config + const transcriptConfig: Parameters[0] = { + audio: audioPath, + }; + + // Set language (undefined for auto-detection) + if (request.language && request.language !== 'auto') { + transcriptConfig.language_code = request.language as any; + } + + const transcript = await client.transcripts.transcribe(transcriptConfig); + + // Step 4: Process results + onProgress?.({ + status: 'processing', + progress: 90, + message: 'Processing transcription results...' + }); + + // Clean up temp audio file + try { + fs.unlinkSync(audioPath); + } catch { + // Ignore cleanup errors - temp file will be cleaned up by OS eventually + console.warn('Failed to cleanup temp audio file:', audioPath); + } + + // Check for transcription errors + if (transcript.status === 'error') { + return { + success: false, + error: transcript.error || 'Transcription failed', + }; + } + + // Map AssemblyAI words to our format + const words: TranscriptionWord[] = (transcript.words || []).map((w: { text: string; start: number; end: number; confidence: number }) => ({ + text: w.text, + startMs: w.start, + endMs: w.end, + confidence: w.confidence, + })); + + onProgress?.({ + status: 'complete', + progress: 100, + message: `Transcription complete! ${words.length} words detected.` + }); + + return { + success: true, + words, + }; + } catch (error) { + console.error('Transcription error:', error); + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown transcription error', + }; + } +} diff --git a/electron/windows.ts b/electron/windows.ts index f094fd6..babb45a 100644 --- a/electron/windows.ts +++ b/electron/windows.ts @@ -23,7 +23,7 @@ export function createHudOverlayWindow(): BrowserWindow { const windowWidth = 500; - const windowHeight = 100; + const windowHeight = 350; // Increased to accommodate mic popover const x = Math.floor(workArea.x + (workArea.width - windowWidth) / 2); const y = Math.floor(workArea.y + workArea.height - windowHeight - 5); @@ -33,8 +33,8 @@ export function createHudOverlayWindow(): BrowserWindow { height: windowHeight, minWidth: 500, maxWidth: 500, - minHeight: 100, - maxHeight: 100, + minHeight: 350, + maxHeight: 350, x: x, y: y, frame: false, @@ -56,6 +56,33 @@ export function createHudOverlayWindow(): BrowserWindow { win?.webContents.send('main-process-message', (new Date).toLocaleString()) }) + // Handle window.open() calls for child windows (e.g., mic settings) + win.webContents.setWindowOpenHandler(({ url }) => { + // Allow mic-settings window + if (url.includes('windowType=mic-settings')) { + return { + action: 'allow', + overrideBrowserWindowOptions: { + width: 340, + height: 520, + frame: false, + transparent: true, + resizable: false, + alwaysOnTop: true, + skipTaskbar: true, + parent: win, + modal: false, + webPreferences: { + preload: path.join(__dirname, 'preload.mjs'), + nodeIntegration: false, + contextIsolation: true, + }, + } + } + } + return { action: 'deny' } + }) + hudOverlayWindow = win; win.on('closed', () => { diff --git a/package.json b/package.json index 60c0521..f3fbe2e 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "@types/gif.js": "^0.2.5", "@uiw/color-convert": "^2.9.2", "@uiw/react-color-block": "^2.9.2", + "assemblyai": "^4.22.1", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "dnd-timeline": "^2.2.0", diff --git a/src/App.tsx b/src/App.tsx index 3ba8213..fe2786a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,30 +1,33 @@ -import { useEffect, useState } from "react"; -import { LaunchWindow } from "./components/launch/LaunchWindow"; -import { SourceSelector } from "./components/launch/SourceSelector"; -import VideoEditor from "./components/video-editor/VideoEditor"; +import { useEffect, useState } from "react"; +import { LaunchWindow } from "./components/launch/LaunchWindow"; +import { SourceSelector } from "./components/launch/SourceSelector"; +import { MicrophoneSettingsPage } from "./components/launch/MicrophoneSettingsPage"; +import VideoEditor from "./components/video-editor/VideoEditor"; export default function App() { const [windowType, setWindowType] = useState(''); - useEffect(() => { - const params = new URLSearchParams(window.location.search); - const type = params.get('windowType') || ''; - setWindowType(type); - if (type === 'hud-overlay' || type === 'source-selector') { - document.body.style.background = 'transparent'; - document.documentElement.style.background = 'transparent'; - document.getElementById('root')?.style.setProperty('background', 'transparent'); - } - }, []); + useEffect(() => { + const params = new URLSearchParams(window.location.search); + const type = params.get('windowType') || ''; + setWindowType(type); + if (type === 'hud-overlay' || type === 'source-selector' || type === 'mic-settings') { + document.body.style.background = 'transparent'; + document.documentElement.style.background = 'transparent'; + document.getElementById('root')?.style.setProperty('background', 'transparent'); + } + }, []); - switch (windowType) { - case 'hud-overlay': - return ; - case 'source-selector': - return ; - case 'editor': - return ; - default: + switch (windowType) { + case 'hud-overlay': + return ; + case 'source-selector': + return ; + case 'mic-settings': + return ; + case 'editor': + return ; + default: return (

Openscreen

diff --git a/src/components/launch/LaunchWindow.tsx b/src/components/launch/LaunchWindow.tsx index f82ae6c..183fbb6 100644 --- a/src/components/launch/LaunchWindow.tsx +++ b/src/components/launch/LaunchWindow.tsx @@ -1,6 +1,7 @@ import { useState, useEffect } from "react"; import styles from "./LaunchWindow.module.css"; import { useScreenRecorder } from "../../hooks/useScreenRecorder"; +import { useMicrophone } from "../../hooks/useMicrophone"; import { Button } from "../ui/button"; import { BsRecordCircle } from "react-icons/bs"; import { FaRegStopCircle } from "react-icons/fa"; @@ -9,9 +10,89 @@ import { RxDragHandleDots2 } from "react-icons/rx"; import { FaFolderMinus } from "react-icons/fa6"; import { FiMinus, FiX } from "react-icons/fi"; import { ContentClamp } from "../ui/content-clamp"; +import { MicrophoneSelector } from "./MicrophoneSelector"; +import { + getAudioSettings, + STORAGE_KEY, + type AudioSettings +} from "../../stores/audioSettings"; export function LaunchWindow() { - const { recording, toggleRecording } = useScreenRecorder(); + // Track audio settings in state so we can react to changes + const [audioSettings, setAudioSettings] = useState(() => getAudioSettings()); + + // Listen for localStorage changes from the settings window + useEffect(() => { + const handleStorageChange = (event: StorageEvent) => { + if (event.key === STORAGE_KEY) { + // Settings changed in another window, reload them + const newSettings = getAudioSettings(); + setAudioSettings(newSettings); + } + }; + + // Listen for storage events (fired when localStorage changes in another window) + window.addEventListener('storage', handleStorageChange); + + // Also poll for changes (backup for same-origin windows) + const pollInterval = setInterval(() => { + const currentSettings = getAudioSettings(); + setAudioSettings(prev => { + // Only update if settings actually changed + if (JSON.stringify(prev) !== JSON.stringify(currentSettings)) { + return currentSettings; + } + return prev; + }); + }, 500); + + return () => { + window.removeEventListener('storage', handleStorageChange); + clearInterval(pollInterval); + }; + }, []); + + // Get all microphone state from the hook + // Pass current audio settings as constraints + const { + stream: audioStream, + devices, + isEnabled, + selectDevice, + enable, + error: micError, + permissionState, + } = useMicrophone({ + sampleRate: audioSettings.sampleRate, + channelCount: audioSettings.channelCount, + noiseSuppression: audioSettings.noiseSuppression, + echoCancellation: audioSettings.echoCancellation, + autoGainControl: audioSettings.autoGainControl, + }); + + // Restore microphone state when settings change (including on mount) + // This ensures mic is enabled if user configured it in settings window + useEffect(() => { + // Only restore if settings say enabled but hook says disabled + if (audioSettings.enabled && !isEnabled) { + console.log('[LaunchWindow] Restoring mic state from settings:', audioSettings); + + if (audioSettings.deviceId) { + // Try to select the saved device + selectDevice(audioSettings.deviceId).catch((err) => { + console.warn('[LaunchWindow] Failed to select saved device, trying default:', err); + // If that fails, try enabling with default device + enable().catch(console.error); + }); + } else { + // No specific device, just enable with default + enable().catch(console.error); + } + } + }, [audioSettings.enabled, audioSettings.deviceId, isEnabled, selectDevice, enable]); + + // Pass audio stream to screen recorder for combined recording + const { recording, toggleRecording } = useScreenRecorder({ audioStream }); const [recordingStart, setRecordingStart] = useState(null); const [elapsed, setElapsed] = useState(0); @@ -94,7 +175,7 @@ export function LaunchWindow() { }; return ( -
+
+ {/* Microphone selector - opens separate settings window */} + + +
+ + ); +} + +export default MicrophoneSelector; diff --git a/src/components/launch/MicrophoneSettingsPage.tsx b/src/components/launch/MicrophoneSettingsPage.tsx new file mode 100644 index 0000000..d6b36e0 --- /dev/null +++ b/src/components/launch/MicrophoneSettingsPage.tsx @@ -0,0 +1,381 @@ +import { useEffect, useCallback, useState } from "react"; +import { Button } from "../ui/button"; +import { Switch } from "../ui/switch"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue +} from "../ui/select"; +import { + getAudioSettings, + setAudioSettings, + SAMPLE_RATE_OPTIONS, + CHANNEL_COUNT_OPTIONS, + type SampleRate, + type ChannelCount, +} from "../../stores/audioSettings"; +import { cn } from "@/lib/utils"; +import { FaMicrophone, FaCheck } from "react-icons/fa"; +import { X } from "lucide-react"; +import { useMicrophone } from "../../hooks/useMicrophone"; + +/** + * Standalone Microphone Settings Page + * Rendered in a separate Electron child window + */ +export function MicrophoneSettingsPage() { + // Load initial settings from localStorage into state + const [settings, setSettings] = useState(() => getAudioSettings()); + + // Use microphone hook with current settings + const { + devices, + selectedDeviceId, + selectDevice, + audioLevel, + isEnabled, + enable, + disable, + error, + permissionState, + } = useMicrophone({ + sampleRate: settings.sampleRate, + channelCount: settings.channelCount, + noiseSuppression: settings.noiseSuppression, + echoCancellation: settings.echoCancellation, + autoGainControl: settings.autoGainControl, + }); + + // Restore microphone state on mount + useEffect(() => { + const saved = getAudioSettings(); + if (saved.enabled && saved.deviceId) { + selectDevice(saved.deviceId).catch(() => { + if (saved.enabled) { + enable().catch(console.error); + } + }); + } else if (saved.enabled) { + enable().catch(console.error); + } + }, []); // eslint-disable-line react-hooks/exhaustive-deps + + // Persist enabled state and device + useEffect(() => { + setAudioSettings({ + deviceId: selectedDeviceId, + enabled: isEnabled, + }); + }, [selectedDeviceId, isEnabled]); + + // Save all settings before window closes (handles OS close button, Alt+F4, etc.) + // The useMicrophone hook's cleanup effect handles stream cleanup on unmount + useEffect(() => { + const handleBeforeUnload = () => { + // Persist all current settings before window closes + setAudioSettings({ + deviceId: selectedDeviceId, + enabled: isEnabled, + sampleRate: settings.sampleRate, + channelCount: settings.channelCount, + noiseSuppression: settings.noiseSuppression, + echoCancellation: settings.echoCancellation, + autoGainControl: settings.autoGainControl, + }); + }; + + window.addEventListener('beforeunload', handleBeforeUnload); + return () => window.removeEventListener('beforeunload', handleBeforeUnload); + }, [selectedDeviceId, isEnabled, settings]); + + // Handle device selection + const handleDeviceSelect = useCallback(async (deviceId: string) => { + await selectDevice(deviceId); + }, [selectDevice]); + + // Handle mute toggle + const handleMuteToggle = useCallback(() => { + if (isEnabled) { + disable(); + } else { + enable().catch(console.error); + } + }, [isEnabled, enable, disable]); + + // Settings change handlers - update both state and localStorage + const handleSampleRateChange = (value: SampleRate) => { + setSettings(prev => ({ ...prev, sampleRate: value })); + setAudioSettings({ sampleRate: value }); + }; + + const handleChannelCountChange = (value: ChannelCount) => { + setSettings(prev => ({ ...prev, channelCount: value })); + setAudioSettings({ channelCount: value }); + }; + + const handleNoiseSuppressionChange = (enabled: boolean) => { + setSettings(prev => ({ ...prev, noiseSuppression: enabled })); + setAudioSettings({ noiseSuppression: enabled }); + }; + + const handleEchoCancellationChange = (enabled: boolean) => { + setSettings(prev => ({ ...prev, echoCancellation: enabled })); + setAudioSettings({ echoCancellation: enabled }); + }; + + const handleAutoGainControlChange = (enabled: boolean) => { + setSettings(prev => ({ ...prev, autoGainControl: enabled })); + setAudioSettings({ autoGainControl: enabled }); + }; + + // Close window - save all settings before closing + const handleClose = useCallback(() => { + // Explicitly save ALL current settings to localStorage before closing + setAudioSettings({ + deviceId: selectedDeviceId, + enabled: isEnabled, + sampleRate: settings.sampleRate, + channelCount: settings.channelCount, + noiseSuppression: settings.noiseSuppression, + echoCancellation: settings.echoCancellation, + autoGainControl: settings.autoGainControl, + }); + + // Small delay to ensure localStorage write completes + setTimeout(() => { + window.close(); + }, 50); + }, [selectedDeviceId, isEnabled, settings]); + + return ( +
+ {/* Draggable Header */} +
+
+ + Microphone Settings +
+ +
+ + {/* Scrollable Content */} +
+ {/* Device List */} +
+
+ Select Device +
+
+ {devices.length === 0 ? ( +
+ No microphones found +
+ ) : ( + devices.map((device) => ( + + )) + )} +
+
+ + {/* Audio Level Meter */} + {isEnabled && ( +
+
+ Input Level + {Math.round(audioLevel)}% +
+
+
80 ? "bg-red-500" : + audioLevel > 50 ? "bg-yellow-500" : + "bg-emerald-400" + )} + style={{ width: `${audioLevel}%` }} + /> +
+
+ )} + + {/* Mute Toggle */} +
+ +
+ + {/* Audio Quality Settings */} +
+
+ Audio Quality +
+ +
+ {/* Sample Rate */} +
+ Sample Rate + +
+ + {/* Channel Count */} +
+ Channels + +
+
+
+ + {/* Processing Settings */} +
+
+ Processing +
+ +
+ {/* Noise Suppression */} +
+ Noise Suppression + +
+ + {/* Echo Cancellation */} +
+ Echo Cancellation + +
+ + {/* Auto Gain Control */} +
+ Auto Gain Control + +
+
+
+ + {/* Error Display */} + {error && ( +
+

+ {error.message} +

+
+ )} + + {/* Permission Denied Warning */} + {permissionState === 'denied' && ( +
+

+ Microphone access denied. Please enable in system settings. +

+
+ )} +
+
+ ); +} + +export default MicrophoneSettingsPage; diff --git a/src/components/video-editor/PresetSelector.tsx b/src/components/video-editor/PresetSelector.tsx new file mode 100644 index 0000000..cf67c37 --- /dev/null +++ b/src/components/video-editor/PresetSelector.tsx @@ -0,0 +1,260 @@ +import { useState } from 'react'; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuTrigger, + DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, +} from '@/components/ui/dropdown-menu'; +import { Button } from '@/components/ui/button'; +import { ChevronDown, Plus, Star, RotateCcw, Copy, Pencil, Trash2, Check } from 'lucide-react'; +import { toast } from 'sonner'; +import { SavePresetModal } from './SavePresetModal'; +import type { Preset, PresetSettings } from './types'; + +interface PresetSelectorProps { + presets: Preset[]; + defaultPresetId: string | null; + currentSettings: PresetSettings; + onApplyPreset: (preset: Preset) => void; + onSavePreset: (name: string, settings: PresetSettings, isDefault: boolean) => Promise; + onDeletePreset: (id: string) => Promise; + onDuplicatePreset: (id: string) => Promise; + onRenamePreset: (id: string, name: string) => Promise; + onSetDefaultPreset: (id: string | null) => Promise; + onResetToDefaults: () => void; +} + +export function PresetSelector({ + presets, + defaultPresetId, + currentSettings, + onApplyPreset, + onSavePreset, + onDeletePreset, + onDuplicatePreset, + onRenamePreset, + onSetDefaultPreset, + onResetToDefaults, +}: PresetSelectorProps) { + const [isModalOpen, setIsModalOpen] = useState(false); + const [editingPresetId, setEditingPresetId] = useState(null); + const [editingName, setEditingName] = useState(''); + + const handleSavePreset = async (name: string, isDefault: boolean) => { + const preset = await onSavePreset(name, currentSettings, isDefault); + if (preset) { + toast.success(`Preset "${name}" saved`); + } else { + toast.error('Failed to save preset'); + } + }; + + const handleApplyPreset = (preset: Preset) => { + onApplyPreset(preset); + toast.success(`Applied preset "${preset.name}"`); + }; + + const handleDeletePreset = async (preset: Preset) => { + const success = await onDeletePreset(preset.id); + if (success) { + toast.success(`Deleted preset "${preset.name}"`); + } else { + toast.error('Failed to delete preset'); + } + }; + + const handleDuplicatePreset = async (preset: Preset) => { + const newPreset = await onDuplicatePreset(preset.id); + if (newPreset) { + toast.success(`Duplicated as "${newPreset.name}"`); + } else { + toast.error('Failed to duplicate preset'); + } + }; + + const handleSetDefault = async (preset: Preset) => { + const newDefaultId = preset.isDefault ? null : preset.id; + const success = await onSetDefaultPreset(newDefaultId); + if (success) { + if (newDefaultId) { + toast.success(`"${preset.name}" set as default`); + } else { + toast.success(`Removed default preset`); + } + } else { + toast.error('Failed to update default preset'); + } + }; + + const handleStartRename = (preset: Preset) => { + setEditingPresetId(preset.id); + setEditingName(preset.name); + }; + + const handleFinishRename = async (presetId: string) => { + if (editingName.trim()) { + const success = await onRenamePreset(presetId, editingName.trim()); + if (success) { + toast.success('Preset renamed'); + } else { + toast.error('Failed to rename preset'); + } + } + setEditingPresetId(null); + setEditingName(''); + }; + + const handleResetToDefaults = () => { + onResetToDefaults(); + toast.success('Reset to default settings'); + }; + + const truncateName = (name: string, maxLength: number = 20) => { + if (name.length <= maxLength) return name; + return name.slice(0, maxLength) + '...'; + }; + + return ( +
+
+ Presets +
+ +
+ {/* Preset Dropdown */} + + + + + + {presets.length === 0 ? ( +
+ No presets saved yet +
+ ) : ( + presets.map((preset) => ( + + { + // Allow click to apply preset if not clicking submenu arrow + if (!(e.target as HTMLElement).closest('[data-radix-collection-item]')) { + handleApplyPreset(preset); + } + }} + > + {preset.id === defaultPresetId && ( + + )} + {editingPresetId === preset.id ? ( + setEditingName(e.target.value)} + onBlur={() => handleFinishRename(preset.id)} + onKeyDown={(e) => { + if (e.key === 'Enter') { + handleFinishRename(preset.id); + } else if (e.key === 'Escape') { + setEditingPresetId(null); + setEditingName(''); + } + }} + className="flex-1 bg-transparent border-b border-[#34B27B] outline-none text-sm" + autoFocus + onClick={(e) => e.stopPropagation()} + /> + ) : ( + {truncateName(preset.name)} + )} + + + handleApplyPreset(preset)} + className="cursor-pointer hover:bg-white/10 focus:bg-white/10" + > + + Apply + + handleStartRename(preset)} + className="cursor-pointer hover:bg-white/10 focus:bg-white/10" + > + + Rename + + handleDuplicatePreset(preset)} + className="cursor-pointer hover:bg-white/10 focus:bg-white/10" + > + + Duplicate + + handleSetDefault(preset)} + className="cursor-pointer hover:bg-white/10 focus:bg-white/10" + > + + {preset.id === defaultPresetId ? 'Remove Default' : 'Set as Default'} + + + handleDeletePreset(preset)} + className="cursor-pointer text-red-400 hover:bg-red-500/10 focus:bg-red-500/10 focus:text-red-400" + > + + Delete + + + + )) + )} + + {presets.length > 0 && } + + + + Reset to defaults + +
+
+ + {/* Save Button */} + +
+ + setIsModalOpen(false)} + onSave={handleSavePreset} + currentSettings={currentSettings} + /> +
+ ); +} diff --git a/src/components/video-editor/SavePresetModal.tsx b/src/components/video-editor/SavePresetModal.tsx new file mode 100644 index 0000000..6f903bf --- /dev/null +++ b/src/components/video-editor/SavePresetModal.tsx @@ -0,0 +1,123 @@ +import { useState } from 'react'; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + DialogFooter, + DialogDescription, +} from '@/components/ui/dialog'; +import { Button } from '@/components/ui/button'; +import { Switch } from '@/components/ui/switch'; +import type { PresetSettings } from './types'; + +interface SavePresetModalProps { + isOpen: boolean; + onClose: () => void; + onSave: (name: string, isDefault: boolean) => Promise; + currentSettings: PresetSettings; +} + +export function SavePresetModal({ + isOpen, + onClose, + onSave, +}: SavePresetModalProps) { + const [name, setName] = useState(''); + const [isDefault, setIsDefault] = useState(false); + const [saving, setSaving] = useState(false); + + const handleSave = async () => { + if (!name.trim()) return; + + setSaving(true); + try { + await onSave(name.trim(), isDefault); + // Reset form + setName(''); + setIsDefault(false); + onClose(); + } finally { + setSaving(false); + } + }; + + const handleClose = () => { + setName(''); + setIsDefault(false); + onClose(); + }; + + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter' && name.trim()) { + e.preventDefault(); + handleSave(); + } + }; + + return ( + !open && handleClose()}> + + + + Save as Preset + + + Save your current settings as a reusable preset. + + + +
+ {/* Name Input */} +
+ + setName(e.target.value)} + onKeyDown={handleKeyDown} + placeholder="My Preset" + autoFocus + className="w-full px-3 py-2 bg-white/5 border border-white/10 rounded-lg text-slate-200 placeholder:text-slate-500 focus:outline-none focus:ring-2 focus:ring-[#34B27B]/50 focus:border-[#34B27B] transition-all" + maxLength={50} + /> +
+ + {/* Set as Default Switch */} +
+
+
Set as default
+
Auto-apply to new videos
+
+ +
+
+ + + + + +
+
+ ); +} diff --git a/src/components/video-editor/SettingsPanel.tsx b/src/components/video-editor/SettingsPanel.tsx index 68f5bf6..966cc34 100644 --- a/src/components/video-editor/SettingsPanel.tsx +++ b/src/components/video-editor/SettingsPanel.tsx @@ -9,10 +9,12 @@ import { useState } from "react"; import Block from '@uiw/react-color-block'; import { Trash2, Download, Crop, X, Bug, Upload, Star, Film, Image } from "lucide-react"; import { toast } from "sonner"; -import type { ZoomDepth, CropRegion, AnnotationRegion, AnnotationType } from "./types"; +import type { ZoomDepth, CropRegion, AnnotationRegion, AnnotationType, Preset, PresetSettings, SubtitleRegion, SubtitleStyle, SubtitlePositionPreset } from "./types"; import { CropControl } from "./CropControl"; import { KeyboardShortcutsHelp } from "./KeyboardShortcutsHelp"; import { AnnotationSettingsPanel } from "./AnnotationSettingsPanel"; +import { SubtitleSettingsPanel } from "./subtitle/SubtitleSettingsPanel"; +import { PresetSelector } from "./PresetSelector"; import { type AspectRatio } from "@/utils/aspectRatioUtils"; import type { ExportQuality, ExportFormat, GifFrameRate, GifSizePreset } from "@/lib/exporter"; import { GIF_FRAME_RATES, GIF_SIZE_PRESETS } from "@/lib/exporter"; @@ -71,6 +73,9 @@ interface SettingsPanelProps { videoElement?: HTMLVideoElement | null; exportQuality?: ExportQuality; onExportQualityChange?: (quality: ExportQuality) => void; + // Audio export settings + audioBitrate?: 128 | 192 | 256 | 320; + onAudioBitrateChange?: (bitrate: 128 | 192 | 256 | 320) => void; // Export format settings exportFormat?: ExportFormat; onExportFormatChange?: (format: ExportFormat) => void; @@ -89,6 +94,23 @@ interface SettingsPanelProps { onAnnotationStyleChange?: (id: string, style: Partial) => void; onAnnotationFigureDataChange?: (id: string, figureData: any) => void; onAnnotationDelete?: (id: string) => void; + // Subtitle props + selectedSubtitleId?: string | null; + subtitleRegions?: SubtitleRegion[]; + onSubtitleContentChange?: (id: string, text: string) => void; + onSubtitleStyleChange?: (id: string, style: Partial) => void; + onSubtitlePositionChange?: (id: string, position: SubtitlePositionPreset, customPosition?: { x: number; y: number }) => void; + onSubtitleDelete?: (id: string) => void; + // Preset props + presets?: Preset[]; + defaultPresetId?: string | null; + onApplyPreset?: (preset: Preset) => void; + onSavePreset?: (name: string, settings: PresetSettings, isDefault: boolean) => Promise; + onDeletePreset?: (id: string) => Promise; + onDuplicatePreset?: (id: string) => Promise; + onRenamePreset?: (id: string, name: string) => Promise; + onSetDefaultPreset?: (id: string | null) => Promise; + onResetToDefaults?: () => void; } export default SettingsPanel; @@ -127,6 +149,8 @@ export function SettingsPanel({ videoElement, exportQuality = 'good', onExportQualityChange, + audioBitrate = 192, + onAudioBitrateChange, exportFormat = 'mp4', onExportFormatChange, gifFrameRate = 15, @@ -144,6 +168,23 @@ export function SettingsPanel({ onAnnotationStyleChange, onAnnotationFigureDataChange, onAnnotationDelete, + // Subtitle props + selectedSubtitleId, + subtitleRegions = [], + onSubtitleContentChange, + onSubtitleStyleChange, + onSubtitlePositionChange, + onSubtitleDelete, + // Preset props + presets = [], + defaultPresetId = null, + onApplyPreset, + onSavePreset, + onDeletePreset, + onDuplicatePreset, + onRenamePreset, + onSetDefaultPreset, + onResetToDefaults, }: SettingsPanelProps) { const [wallpaperPaths, setWallpaperPaths] = useState([]); const [customImages, setCustomImages] = useState([]); @@ -238,6 +279,11 @@ export function SettingsPanel({ ? annotationRegions.find(a => a.id === selectedAnnotationId) : null; + // Find selected subtitle + const selectedSubtitle = selectedSubtitleId + ? subtitleRegions.find(s => s.id === selectedSubtitleId) + : null; + // If an annotation is selected, show annotation settings instead if (selectedAnnotation && onAnnotationContentChange && onAnnotationTypeChange && onAnnotationStyleChange && onAnnotationDelete) { return ( @@ -252,8 +298,44 @@ export function SettingsPanel({ ); } + // If a subtitle is selected, show subtitle settings instead + if (selectedSubtitle && onSubtitleContentChange && onSubtitleStyleChange && onSubtitlePositionChange && onSubtitleDelete) { + return ( + onSubtitleContentChange(selectedSubtitle.id, text)} + onStyleChange={(style) => onSubtitleStyleChange(selectedSubtitle.id, style)} + onPositionChange={(position, customPosition) => onSubtitlePositionChange(selectedSubtitle.id, position, customPosition)} + onDelete={() => onSubtitleDelete(selectedSubtitle.id)} + /> + ); + } + return (
+ {/* Preset Selector - at top of settings panel */} + {onApplyPreset && onSavePreset && onDeletePreset && onDuplicatePreset && onRenamePreset && onSetDefaultPreset && onResetToDefaults && ( + + )} +
Zoom Level @@ -569,10 +651,10 @@ export function SettingsPanel({
-
+
{/* Format Selection */}
-
Export Format
+
Export Format
+ + {/* Audio Quality */} +
Audio Quality
+
+ {([128, 192, 256, 320] as const).map((bitrate) => ( + + ))} +
+
Audio bitrate in kbps
)} @@ -671,7 +773,7 @@ export function SettingsPanel({
Output Size
- {Object.entries(GIF_SIZE_PRESETS).map(([key, preset]) => ( + {Object.entries(GIF_SIZE_PRESETS).map(([key, _preset]) => (
@@ -829,6 +1036,14 @@ export default function VideoEditor() { onAnnotationDelete={handleAnnotationDelete} selectedAnnotationId={selectedAnnotationId} onSelectAnnotation={handleSelectAnnotation} + subtitleRegions={subtitleRegions} + onSubtitleAdded={handleSubtitleAdded} + onSubtitleSpanChange={handleSubtitleSpanChange} + onSubtitleDelete={handleSubtitleDelete} + selectedSubtitleId={selectedSubtitleId} + onSelectSubtitle={handleSelectSubtitle} + videoPath={getVideoFilePath()} + onAutoGenerateSubtitles={handleAutoGenerateSubtitles} aspectRatio={aspectRatio} onAspectRatioChange={setAspectRatio} /> @@ -865,6 +1080,8 @@ export default function VideoEditor() { onExportQualityChange={setExportQuality} exportFormat={exportFormat} onExportFormatChange={setExportFormat} + audioBitrate={audioBitrate} + onAudioBitrateChange={setAudioBitrate} gifFrameRate={gifFrameRate} onGifFrameRateChange={setGifFrameRate} gifLoop={gifLoop} @@ -885,6 +1102,23 @@ export default function VideoEditor() { onAnnotationStyleChange={handleAnnotationStyleChange} onAnnotationFigureDataChange={handleAnnotationFigureDataChange} onAnnotationDelete={handleAnnotationDelete} + // Subtitle props + selectedSubtitleId={selectedSubtitleId} + subtitleRegions={subtitleRegions} + onSubtitleContentChange={handleSubtitleContentChange} + onSubtitleStyleChange={handleSubtitleStyleChange} + onSubtitlePositionChange={handleSubtitlePositionChange} + onSubtitleDelete={handleSubtitleDelete} + // Preset props + presets={presets} + defaultPresetId={defaultPresetId} + onApplyPreset={handleApplyPreset} + onSavePreset={handleSavePreset} + onDeletePreset={deletePreset} + onDuplicatePreset={duplicatePreset} + onRenamePreset={handleRenamePreset} + onSetDefaultPreset={setDefaultPreset} + onResetToDefaults={handleResetToDefaults} />
diff --git a/src/components/video-editor/VideoPlayback.tsx b/src/components/video-editor/VideoPlayback.tsx index 357adc9..87887d7 100644 --- a/src/components/video-editor/VideoPlayback.tsx +++ b/src/components/video-editor/VideoPlayback.tsx @@ -2,7 +2,7 @@ import type React from "react"; import { useEffect, useRef, useImperativeHandle, forwardRef, useState, useMemo, useCallback } from "react"; import { getAssetPath } from "@/lib/assetPath"; import { Application, Container, Sprite, Graphics, BlurFilter, Texture, VideoSource } from 'pixi.js'; -import { ZOOM_DEPTH_SCALES, type ZoomRegion, type ZoomFocus, type ZoomDepth, type TrimRegion, type AnnotationRegion } from "./types"; +import { ZOOM_DEPTH_SCALES, type ZoomRegion, type ZoomFocus, type ZoomDepth, type TrimRegion, type AnnotationRegion, type SubtitleRegion, type SubtitlePositionPreset } from "./types"; import { DEFAULT_FOCUS, SMOOTHING_FACTOR, MIN_DELTA } from "./videoPlayback/constants"; import { clamp01 } from "./videoPlayback/mathUtils"; import { findDominantRegion } from "./videoPlayback/zoomRegionUtils"; @@ -13,6 +13,7 @@ import { applyZoomTransform } from "./videoPlayback/zoomTransform"; import { createVideoEventHandlers } from "./videoPlayback/videoEventHandlers"; import { type AspectRatio, formatAspectRatioForCSS } from "@/utils/aspectRatioUtils"; import { AnnotationOverlay } from "./AnnotationOverlay"; +import { SubtitleOverlay } from "./subtitle"; interface VideoPlaybackProps { videoPath: string; @@ -41,6 +42,11 @@ interface VideoPlaybackProps { onSelectAnnotation?: (id: string | null) => void; onAnnotationPositionChange?: (id: string, position: { x: number; y: number }) => void; onAnnotationSizeChange?: (id: string, size: { width: number; height: number }) => void; + // Subtitle props + subtitleRegions?: SubtitleRegion[]; + selectedSubtitleId?: string | null; + onSelectSubtitle?: (id: string | null) => void; + onSubtitlePositionChange?: (id: string, position: SubtitlePositionPreset, customPosition?: { x: number; y: number }) => void; } export interface VideoPlaybackRef { @@ -80,6 +86,10 @@ const VideoPlayback = forwardRef(({ onSelectAnnotation, onAnnotationPositionChange, onAnnotationSizeChange, + subtitleRegions = [], + selectedSubtitleId, + onSelectSubtitle, + onSubtitlePositionChange, }, ref) => { const videoRef = useRef(null); const containerRef = useRef(null); @@ -867,6 +877,31 @@ const VideoPlayback = forwardRef(({ /> )); })()} + {/* Subtitle Overlays */} + {(() => { + const timeMs = Math.round(currentTime * 1000); + const filtered = (subtitleRegions || []).filter((subtitle) => { + if (typeof subtitle.startMs !== 'number' || typeof subtitle.endMs !== 'number') return false; + + if (subtitle.id === selectedSubtitleId) return true; + + return timeMs >= subtitle.startMs && timeMs <= subtitle.endMs; + }); + + return filtered.map((subtitle) => ( + + onSubtitlePositionChange?.(id, position, customPosition) + } + onClick={(id) => onSelectSubtitle?.(id)} + /> + )); + })()}
)}