diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..f7b9ea8 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,35 @@ +## Summary + + + +## Problem + + + +## Solution + + + +## Risk + + + +## Testing + + + +- [ ] `pnpm lint` +- [ ] `pnpm build` if this PR touches runtime, bundling, or packaging code +- [ ] Manual verification for affected flows +- [ ] Screenshots or recordings for UI changes + +## AI Notice + + + +- [ ] I have used any AI/LLM tool to generate code or text in this PR. I understand that I am responsible for reviewing and validating any code generated by AI, and that I will be held accountable for any issues caused by this code. +- [ ] I have not used any AI to generate code in this PR. + +## Notes + + diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 91c195b..0000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,13 +0,0 @@ -version: 2 -updates: - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "weekly" - - package-ecosystem: npm - directory: "/" - schedule: - interval: monthly - time: "13:00" - open-pull-requests-limit: 99 - versioning-strategy: increase diff --git a/.github/workflows/flatpak-node.yml b/.github/workflows/flatpak-node.yml new file mode 100644 index 0000000..082ee4a --- /dev/null +++ b/.github/workflows/flatpak-node.yml @@ -0,0 +1,28 @@ +name: Upload generated-sources.json to release for Flatpak building + +on: + release: + types: + - published + workflow_dispatch: + +permissions: + contents: write + +jobs: + upload: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install flatpak-node-generator + run: pipx install git+https://github.com/flatpak/flatpak-builder-tools.git#subdirectory=node + + - name: Create generated-sources.json + run: /root/.local/bin/flatpak-node-generator pnpm pnpm-lock.yaml --node-sdk-extension org.freedesktop.Sdk.Extension.node26 --electron-node-headers + + - name: Upload generated-sources.json to release + run: | + gh release upload ${{ github.event.release.tag_name }} generated-sources.json + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 6c9f7ec..7c38240 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -7,10 +7,8 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Biome uses: biomejs/setup-biome@v2 - with: - version: 1.9.4 - name: Run Biome run: biome ci . --reporter=github diff --git a/.github/workflows/meta.yml b/.github/workflows/meta.yml index b5225d5..b199551 100644 --- a/.github/workflows/meta.yml +++ b/.github/workflows/meta.yml @@ -13,14 +13,14 @@ jobs: update: runs-on: ubuntu-latest env: - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} steps: - - uses: actions/checkout@v4 - - uses: pnpm/action-setup@v4 # Install pnpm using packageManager key in package.json + - uses: actions/checkout@v6 + - uses: pnpm/action-setup@v6 # Install pnpm using packageManager key in package.json - name: Use Node.js 22 - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version-file: package.json cache: pnpm diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 3e50acf..eb9cafa 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -1,122 +1,121 @@ name: Package on: push: - branches: - - dev - - stable + branches: + - dev + - stable jobs: - package: - continue-on-error: true - strategy: - matrix: - os: [macos-latest, windows-latest, ubuntu-latest] - runs-on: ${{matrix.os}} + package: + continue-on-error: true + strategy: + matrix: + os: [macos-latest, windows-latest, ubuntu-latest] + runs-on: ${{matrix.os}} + env: + SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_TOKEN }} + GH_TOKEN: ${{secrets.GITHUB_TOKEN}} + + steps: + - name: Checkout code + uses: actions/checkout@v6 + + - name: Add commit to version + if: github.ref_name == 'dev' + run: cat <<< $(jq --arg ver "$(jq -r '.version' package.json)-$(git rev-parse --short HEAD)" '.version = $ver' package.json) > package.json + shell: bash + + - name: Prepare PNPM + uses: pnpm/action-setup@v6 + + - name: Prepare Node.js + uses: actions/setup-node@v6 + with: + node-version-file: package.json + cache: pnpm + + - name: Install dependencies + run: pnpm i + + - name: Build TypeScript + run: pnpm build + + - name: Install SnapCraft + if: matrix.os == 'macos-latest' + uses: samuelmeuli/action-snapcraft@v3 + + - name: Load Electron cache + uses: actions/cache/restore@v5 + with: + path: .cache + key: electron-zips.${{matrix.os}} + + # Sadly, it makes more sense to separate builds per platform + - name: Build Electron for macOS (DMG & ZIP) + if: matrix.os == 'macos-latest' + run: pnpm electron-builder --universal -m zip dmg env: - SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_TOKEN }} - GH_TOKEN: ${{secrets.GITHUB_TOKEN}} + CSC_LINK: "https://legcord.app/NewSign.p12" + CSC_KEY_PASSWORD: ${{ secrets.MACOS_SIGN_PASS }} + APPLE_ID: ${{secrets.APPLE_ID}} + APPLE_APP_SPECIFIC_PASSWORD: ${{secrets.APPLE_ID_PASSWORD}} + APPLE_TEAM_ID: ${{secrets.APPLE_TEAM_ID}} - steps: - - name: Checkout code - uses: actions/checkout@v4 + - name: Build Electron for Windows (NSIS, AppX, & ZIP) + if: matrix.os == 'windows-latest' + run: pnpm electron-builder --ia32 --arm64 --x64 -w nsis appx zip - - name: Add commit to version - if: github.ref_name == 'dev' - run: cat <<< $(jq --arg ver "$(jq -r '.version' package.json)-$(git rev-parse --short HEAD)" '.version = $ver' package.json) > package.json - shell: bash + - name: Build Electron for Linux (RPM, DEB, AppImage & ZIP) + if: matrix.os == 'ubuntu-latest' + run: pnpm electron-builder --armv7l --arm64 --x64 -l rpm deb appimage zip tar.gz - - name: Prepare PNPM - uses: pnpm/action-setup@v4 - - - name: Prepare Node.js - uses: actions/setup-node@v4 - with: - node-version-file: package.json - cache: pnpm - - - name: Install dependencies - run: pnpm i - - - name: Build TypeScript - run: pnpm build + - name: Save Electron Cache + uses: actions/cache/save@v5 + with: + path: .cache + key: electron-zips.${{matrix.os}} - - name: Install SnapCraft - if: matrix.os == 'macos-latest' - uses: samuelmeuli/action-snapcraft@v3 + - name: Collect artifacts + run: mkdir artifacts | + find dist/. -maxdepth 1 -type f -exec mv {} artifacts \; + shell: bash - - name: Load Electron cache - uses: actions/cache/restore@v4 - with: - path: .cache - key: electron-zips.${{matrix.os}} + - name: Upload artifactsstable + uses: actions/upload-artifact@v6 + with: + name: ${{matrix.os}}-artifacts + path: artifacts/* - # Sadly, it makes more sense to separate builds per platform - - name: Build Electron for MacOS (DMG & ZIP) - if: matrix.os == 'macos-latest' - run: pnpm electron-builder --universal -m zip dmg - env: - CSC_LINK: "https://legcord.app/NewSign.p12" - CSC_KEY_PASSWORD: ${{ secrets.MACOS_SIGN_PASS }} - APPLE_ID: ${{secrets.APPLE_ID}} - APPLE_APP_SPECIFIC_PASSWORD: ${{secrets.APPLE_ID_PASSWORD}} - APPLE_TEAM_ID: ${{secrets.APPLE_TEAM_ID}} + release: + runs-on: ubuntu-latest + needs: + - package + env: + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + steps: + - name: Download artifacts + uses: actions/download-artifact@v6 + with: + path: release-files - - name: Build Electron for Windows (NSIS, AppX, & ZIP) - if: matrix.os == 'windows-latest' - run: pnpm electron-builder --ia32 --arm64 --x64 -w nsis appx zip + - name: Create release + if: github.ref_name == 'dev' + uses: ncipollo/release-action@v1 + with: + name: Rolling Dev Build + allowUpdates: true + removeArtifacts: true + prerelease: true + body: "Built against https://github.com/Legcord/Legcord/tree/dev on every commit. NOTE: tarballs do not update." + draft: false + tag: devbuild + artifacts: release-files/**/* - - name: Build Electron for Linux (RPM, DEB, AppImage & ZIP) - if: matrix.os == 'ubuntu-latest' - run: pnpm electron-builder --armv7l --arm64 --x64 -l rpm deb appimage zip tar.gz - - - name: Save Electron Cache - uses: actions/cache/save@v4 - with: - path: .cache - key: electron-zips.${{matrix.os}} - - - name: Collect artifacts - run: - mkdir artifacts | - find dist/. -maxdepth 1 -type f -exec mv {} artifacts \; - shell: bash - - - name: Upload artifactsstable - uses: actions/upload-artifact@v4 - with: - name: ${{matrix.os}}-artifacts - path: artifacts/* - - release: - runs-on: ubuntu-latest - needs: - - package - env: - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - steps: - - name: Download artifacts - uses: actions/download-artifact@v4 - with: - path: release-files - - - name: Create release - if: github.ref_name == 'dev' - uses: ncipollo/release-action@v1 - with: - name: Rolling Dev Build - allowUpdates: true - removeArtifacts: true - prerelease: true - body: "Built against https://github.com/Legcord/Legcord/tree/dev on every commit. NOTE: tarballs do not update." - draft: false - tag: devbuild - artifacts: release-files/**/* - - - name: Create release - if: github.ref_name == 'stable' - uses: ncipollo/release-action@v1 - with: - name: Stable Release Draft - prerelease: false - tag: stable - draft: true - artifacts: release-files/**/* \ No newline at end of file + - name: Create release + if: github.ref_name == 'stable' + uses: ncipollo/release-action@v1 + with: + name: Stable Release Draft + prerelease: false + tag: stable + draft: true + artifacts: release-files/**/* diff --git a/.gitignore b/.gitignore index 6114dc2..2acedeb 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,4 @@ package-lock.json .pnpm-store .cache .DS_Store -pnpm-workspace.yaml \ No newline at end of file +scripts/spdx-license.txt \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..7846fe0 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,18 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Launch Program", + "skipFiles": ["/**"], + "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron", + "args": ["."], + "outputCapture": "std", + "outFiles": ["${workspaceFolder}/**/*.js"] + } + ] +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..3a77d61 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,114 @@ +# Contributing to Legcord + +Legcord is an opinionated project. We welcome contributions from everyone, but we want your effort to land successfully and match the direction of the project. + +This guide explains what maintainers look for in pull requests, based on existing code patterns and CI rules. + +## How to contribute + +Contributions are accepted through pull requests. + +Pull requests should target the `dev` branch. +If you are fixing a critical bug or security issue, you may open fixes for both `stable` and `dev`. + +## Before you start a feature + +- Check open pull requests for overlap. +- Check [GitHub enhancement issues](https://github.com/Legcord/Legcord/issues?q=label%3Aenhancement) and the [feature requests Discord channel](https://discord.com/channels/820732039253852171/1261471243123818566). +- If the feature does not exist yet, [open an issue](https://github.com/Legcord/Legcord/issues), say you want to implement it, and wait for feedback before writing large changes. +- Familiarize yourself with the codebase rules below. + +## Codebase rules + +### Tooling and quality + +- Use modern ESM (not CommonJS aka require) where possible. +- Use pnpm (see `packageManager` in `package.json`). +- Run `pnpm lint` before opening a PR. +- Run `pnpm build` when your change touches runtime code, build output, bundling, or packaging behavior. +- Avoid introducing new dependencies unless absolutely necessary. + +### TypeScript and linting expectations + +- Keep TypeScript strictness intact. Do not weaken compiler settings. +- Avoid `@ts-ignore` and broad type escapes. If suppression is unavoidable, use the narrowest suppression possible and include a short reason. +- Any lint suppression (`biome-ignore`, `eslint-disable`, etc.) must include a clear explanation and preferably a tracking issue/URL when relevant. + +### Electron security expectations + +- Follow Electron security best practices. +- Keep preload APIs minimal and explicit when exposing APIs through `contextBridge`. +- Do not add broad permissions or relax security defaults without a strong reason. +- Be careful with injected JavaScript and user-controlled strings. Sanitize inputs (for example, use safe serialization patterns). +- Be extra cautious when changing CSP handling, protocol handling, permission handlers, or web request hooks. + +### Performance expectations + +- Preserve existing performance patterns (config/lang/theme/window-state caching, debounce behavior, startup order). +- Avoid changes that add repeated synchronous I/O in hot paths. +- Be careful with startup flow: some existing operations intentionally use `void` or deferred execution to avoid startup hangs. + +### Config and migration expectations + +- If you change settings shape/defaults, update related migration logic and defaults together. +- Keep backward compatibility with older config formats where possible. +- If your PR changes user data behavior, explain migration and fallback behavior in the PR description. + +### Cross-platform expectations + +- Legcord ships on Linux, macOS, and Windows. Keep platform-specific behavior safe and scoped. +- If your change is platform-specific, explicitly mention tested platform(s) in your PR. +- If you cannot test a platform, state that clearly so reviewers know what remains unverified. + +### i18n expectations + +- Add manual translation changes only to `assets/lang/en-US.json`. +- Update other translations on [Weblate](https://hosted.weblate.org/projects/armcord/). + +## Pull request rules + +### Scope and size + +- Keep PRs focused on one concern. +- Split unrelated refactors from feature or bugfix work. +- Prefer small, reviewable PRs over large mixed changes. + +### PR description (required) + +Include these sections in your PR body: + +- Problem: what user or developer issue is being solved. +- Solution: what changed and why this approach was chosen. +- Risk: what might regress. +- Validation: what you tested (`pnpm lint`, `pnpm build`, manual scenarios, and platform coverage). + +### Verification checklist + +Before requesting review, verify: + +- `pnpm lint` passes. +- `pnpm build` passes for runtime/build-affecting changes. +- Manual smoke test for affected flows is done (for example: startup, settings save/load, themes/mods behavior, tray/window behavior, CSP/security-sensitive paths if touched). +- For UI changes, include screenshots or short recordings. + +### Review readiness + +- Mark breaking changes clearly. +- Call out follow-up work explicitly if a workaround is temporary. +- Reference related issues and prior discussions. +- If you added a workaround/suppression, include the reason in code comments and in the PR description. + +## AI Notice + +While we welcome AI-assisted development, we expect contributors to review and validate any code generated by AI tools. You are responsible for ensuring that any AI-generated code meets our quality, security, and performance standards. +We don't allow vibecoded slop. There has to be at least slight human touch in the code you submit. If you use AI tools to generate code, please disclose it in your PR description. Don't lie about it. We can tell and we will not accept PRs that are entirely AI-generated. + +## Documentation + +We are still improving project and codebase documentation. +If you have experience building docs systems or contributor docs, contact @smartfrigde on Discord. + +## Help users in the Discord community + +We have an open support channel in our [Discord community](https://discord.gg/F25bc4RYDt). +Helping users there is always appreciated. diff --git a/README.md b/README.md index 4e3675d..e0c052c 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ Legcord is also available in [Pi-Apps](https://github.com/Botspot/pi-apps). ### Compiling - Alternatively, you can run Legcord from source ([NodeJS](https://nodejs.dev) and [pnpm](https://pnpm.io/installation#using-npm)) are required: + Alternatively, you can run Legcord from source ([NodeJS v26 and newer](https://nodejs.dev) and [pnpm](https://pnpm.io/installation#using-npm)) are required: 1. Clone Legcord repo: `git clone https://github.com/Legcord/Legcord.git` 2. Run `pnpm install` to install dependencies diff --git a/assets/app/css/baseTitlebar.css b/assets/app/css/baseTitlebar.css index 1d00859..c1b83e4 100644 --- a/assets/app/css/baseTitlebar.css +++ b/assets/app/css/baseTitlebar.css @@ -11,7 +11,7 @@ clear: both; height: var(--custom-app-top-bar-height); line-height: 30px; - -webkit-app-region: drag !important; + -webkit-app-region: drag; user-select: none; background-color: var(--background-base-lowest); -webkit-user-select: none; diff --git a/assets/app/css/darwinTitlebar.css b/assets/app/css/darwinTitlebar.css index f355555..e71cecd 100644 --- a/assets/app/css/darwinTitlebar.css +++ b/assets/app/css/darwinTitlebar.css @@ -1,9 +1,9 @@ [legcord-platform="darwin"] .sidebar-1tnWFu { - border-top-left-radius: 0px !important; + border-top-left-radius: 0px; } .platform-osx .wrapper_ef3116 { - margin-top: 0px !important; + margin-top: 0px; } [legcord-platform="darwin"] #window-controls-container { @@ -16,45 +16,6 @@ transform: translate(-82px, 0px); } -[legcord-platform="darwin"] #window-controls-container:hover #minimize #minimize-icon, -[legcord-platform="darwin"] #window-controls-container:hover #maximize #maximize-icon, -[legcord-platform="darwin"] #window-controls-container:hover #quit #quit-icon { - display: list-item; -} - -[legcord-platform="darwin"][unFocused] #window-controls-container #minimize, -[legcord-platform="darwin"][unFocused] #window-controls-container #maximize, -[legcord-platform="darwin"][unFocused] #window-controls-container #quit { - background-color: #d6d6d5 !important; - pointer-events: none; - transition: background-color 0.1s ease-in; -} - -[legcord-platform="darwin"]:not([unFocused]) #window-controls-container #quit #quit-icon { - background-color: #79282b; - -webkit-mask: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTIiIHZpZXdCb3g9IjAgMCAxMiAxMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNS4yOTI4OSA2TDIuODE4MDEgMy41MjUxM0wzLjUyNTEyIDIuODE4MDJMNS45OTk5OSA1LjI5Mjg5TDguNDc0ODcgMi44MTgwMkw5LjE4MTk3IDMuNTI1MTNMNi43MDcxIDZMOS4xODE5NyA4LjQ3NDg3TDguNDc0ODcgOS4xODE5OEw1Ljk5OTk5IDYuNzA3MTFMMy41MjUxMiA5LjE4MTk4TDIuODE4MDEgOC40NzQ4N0w1LjI5Mjg5IDZaIiBmaWxsPSJyZ2JhKDEyOCwgNiwgMCwgMSkiLz48L3N2Zz4=") - no-repeat 50% 50%; - mask: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTIiIHZpZXdCb3g9IjAgMCAxMiAxMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNS4yOTI4OSA2TDIuODE4MDEgMy41MjUxM0wzLjUyNTEyIDIuODE4MDJMNS45OTk5OSA1LjI5Mjg5TDguNDc0ODcgMi44MTgwMkw5LjE4MTk3IDMuNTI1MTNMNi43MDcxIDZMOS4xODE5NyA4LjQ3NDg3TDguNDc0ODcgOS4xODE5OEw1Ljk5OTk5IDYuNzA3MTFMMy41MjUxMiA5LjE4MTk4TDIuODE4MDEgOC40NzQ4N0w1LjI5Mjg5IDZaIiBmaWxsPSJyZ2JhKDEyOCwgNiwgMCwgMSkiLz48L3N2Zz4=") - no-repeat 50% 50%; - transform: translate(-0.4px, -7px); -} -[legcord-platform="darwin"]:not([unFocused]) #window-controls-container #minimize #minimize-icon { - background-color: #7d631b; - -webkit-mask: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTIiIHZpZXdCb3g9IjAgMCAxMiAxMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTAgNS4zOTk5OUgyVjYuNTk5OTlIMTBWNS4zOTk5OVoiIGZpbGw9IiM5ODY4MDEiLz48L3N2Zz4=") - no-repeat 50% 50%; - mask: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTIiIHZpZXdCb3g9IjAgMCAxMiAxMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTAgNS4zOTk5OUgyVjYuNTk5OTlIMTBWNS4zOTk5OVoiIGZpbGw9IiM5ODY4MDEiLz48L3N2Zz4=") - no-repeat 50% 50%; - transform: translate(-0px, -7px); -} -[legcord-platform="darwin"]:not([unFocused]) #window-controls-container #maximize #maximize-icon { - background-color: #1d7525; - -webkit-mask: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTIiIHZpZXdCb3g9IjAgMCAxMiAxMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNOC41ODgyMyA2Ljk5MDE1TDUuMDA5NzkgMy40MTE3QzQuODU1ODMgMy4yNTc3NCA0Ljk1ODYgMi45OTQyMiA1LjE3NjE0IDIuOTg1MTRMOC45MTA0MiAyLjgyOTMxQzkuMDU2NTggMi44MjMyMSA5LjE3NjczIDIuOTQzMzUgOS4xNzA2MyAzLjA4OTUyTDkuMDE0NzkgNi44MjM4QzkuMDA1NzEgNy4wNDEzNCA4Ljc0MjE5IDcuMTQ0MTEgOC41ODgyMyA2Ljk5MDE1WiIgZmlsbD0iIzEyNUUxRSIvPjxwYXRoIGQ9Ik0zLjQxMTc3IDUuMDA5ODJMNi45OTAyMSA4LjU4ODI3QzcuMTQ0MTcgOC43NDIyMyA3LjA0MTQgOS4wMDU3NSA2LjgyMzg2IDkuMDE0ODNMMy4wODk1OCA5LjE3MDY2QzIuOTQzNDIgOS4xNzY3NiAyLjgyMzI3IDkuMDU2NjEgMi44MjkzNyA4LjkxMDQ1TDIuOTg1MjEgNS4xNzYxN0MyLjk5NDI5IDQuOTU4NjMgMy4yNTc4MSA0Ljg1NTg2IDMuNDExNzcgNS4wMDk4MloiIGZpbGw9IiMxMjVFMUUiLz48L3N2Zz4=") - no-repeat 50% 50%; - mask: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTIiIHZpZXdCb3g9IjAgMCAxMiAxMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNOC41ODgyMyA2Ljk5MDE1TDUuMDA5NzkgMy40MTE3QzQuODU1ODMgMy4yNTc3NCA0Ljk1ODYgMi45OTQyMiA1LjE3NjE0IDIuOTg1MTRMOC45MTA0MiAyLjgyOTMxQzkuMDU2NTggMi44MjMyMSA5LjE3NjczIDIuOTQzMzUgOS4xNzA2MyAzLjA4OTUyTDkuMDE0NzkgNi44MjM4QzkuMDA1NzEgNy4wNDEzNCA4Ljc0MjE5IDcuMTQ0MTEgOC41ODgyMyA2Ljk5MDE1WiIgZmlsbD0iIzEyNUUxRSIvPjxwYXRoIGQ9Ik0zLjQxMTc3IDUuMDA5ODJMNi45OTAyMSA4LjU4ODI3QzcuMTQ0MTcgOC43NDIyMyA3LjA0MTQgOS4wMDU3NSA2LjgyMzg2IDkuMDE0ODNMMy4wODk1OCA5LjE3MDY2QzIuOTQzNDIgOS4xNzY3NiAyLjgyMzI3IDkuMDU2NjEgMi44MjkzNyA4LjkxMDQ1TDIuOTg1MjEgNS4xNzYxN0MyLjk5NDI5IDQuOTU4NjMgMy4yNTc4MSA0Ljg1NTg2IDMuNDExNzcgNS4wMDk4MloiIGZpbGw9IiMxMjVFMUUiLz48L3N2Zz4=") - no-repeat 50% 50%; - transform: translate(0px, -7px); -} - [legcord-platform="darwin"] #window-controls-container #minimize { background-color: #fac536; transition: background-color 0.1s ease-in; @@ -116,6 +77,45 @@ } div[class*="bar__"][class*="hidden__"] { - pointer-events: unset !important; - visibility: unset !important; + pointer-events: unset; + visibility: unset; +} + +[legcord-platform="darwin"] #window-controls-container:hover #minimize #minimize-icon, +[legcord-platform="darwin"] #window-controls-container:hover #maximize #maximize-icon, +[legcord-platform="darwin"] #window-controls-container:hover #quit #quit-icon { + display: list-item; +} + +[legcord-platform="darwin"][unFocused] #window-controls-container #minimize, +[legcord-platform="darwin"][unFocused] #window-controls-container #maximize, +[legcord-platform="darwin"][unFocused] #window-controls-container #quit { + background-color: #d6d6d5; + pointer-events: none; + transition: background-color 0.1s ease-in; +} + +[legcord-platform="darwin"]:not([unFocused]) #window-controls-container #quit #quit-icon { + background-color: #79282b; + -webkit-mask: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTIiIHZpZXdCb3g9IjAgMCAxMiAxMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNS4yOTI4OSA2TDIuODE4MDEgMy41MjUxM0wzLjUyNTEyIDIuODE4MDJMNS45OTk5OSA1LjI5Mjg5TDguNDc0ODcgMi44MTgwMkw5LjE4MTk3IDMuNTI1MTNMNi43MDcxIDZMOS4xODE5NyA4LjQ3NDg3TDguNDc0ODcgOS4xODE5OEw1Ljk5OTk5IDYuNzA3MTFMMy41MjUxMiA5LjE4MTk4TDIuODE4MDEgOC40NzQ4N0w1LjI5Mjg5IDZaIiBmaWxsPSJyZ2JhKDEyOCwgNiwgMCwgMSkiLz48L3N2Zz4=") + no-repeat 50% 50%; + mask: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTIiIHZpZXdCb3g9IjAgMCAxMiAxMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNS4yOTI4OSA2TDIuODE4MDEgMy41MjUxM0wzLjUyNTEyIDIuODE4MDJMNS45OTk5OSA1LjI5Mjg5TDguNDc0ODcgMi44MTgwMkw5LjE4MTk3IDMuNTI1MTNMNi43MDcxIDZMOS4xODE5NyA4LjQ3NDg3TDguNDc0ODcgOS4xODE5OEw1Ljk5OTk5IDYuNzA3MTFMMy41MjUxMiA5LjE4MTk4TDIuODE4MDEgOC40NzQ4N0w1LjI5Mjg5IDZaIiBmaWxsPSJyZ2JhKDEyOCwgNiwgMCwgMSkiLz48L3N2Zz4=") + no-repeat 50% 50%; + transform: translate(-0.4px, -7px); +} +[legcord-platform="darwin"]:not([unFocused]) #window-controls-container #minimize #minimize-icon { + background-color: #7d631b; + -webkit-mask: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTIiIHZpZXdCb3g9IjAgMCAxMiAxMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTAgNS4zOTk5OUgyVjYuNTk5OTlIMTBWNS4zOTk5OVoiIGZpbGw9IiM5ODY4MDEiLz48L3N2Zz4=") + no-repeat 50% 50%; + mask: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTIiIHZpZXdCb3g9IjAgMCAxMiAxMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTAgNS4zOTk5OUgyVjYuNTk5OTlIMTBWNS4zOTk5OVoiIGZpbGw9IiM5ODY4MDEiLz48L3N2Zz4=") + no-repeat 50% 50%; + transform: translate(-0px, -7px); +} +[legcord-platform="darwin"]:not([unFocused]) #window-controls-container #maximize #maximize-icon { + background-color: #1d7525; + -webkit-mask: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTIiIHZpZXdCb3g9IjAgMCAxMiAxMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNOC41ODgyMyA2Ljk5MDE1TDUuMDA5NzkgMy40MTE3QzQuODU1ODMgMy4yNTc3NCA0Ljk1ODYgMi45OTQyMiA1LjE3NjE0IDIuOTg1MTRMOC45MTA0MiAyLjgyOTMxQzkuMDU2NTggMi44MjMyMSA5LjE3NjczIDIuOTQzMzUgOS4xNzA2MyAzLjA4OTUyTDkuMDE0NzkgNi44MjM4QzkuMDA1NzEgNy4wNDEzNCA4Ljc0MjE5IDcuMTQ0MTEgOC41ODgyMyA2Ljk5MDE1WiIgZmlsbD0iIzEyNUUxRSIvPjxwYXRoIGQ9Ik0zLjQxMTc3IDUuMDA5ODJMNi45OTAyMSA4LjU4ODI3QzcuMTQ0MTcgOC43NDIyMyA3LjA0MTQgOS4wMDU3NSA2LjgyMzg2IDkuMDE0ODNMMy4wODk1OCA5LjE3MDY2QzIuOTQzNDIgOS4xNzY3NiAyLjgyMzI3IDkuMDU2NjEgMi44MjkzNyA4LjkxMDQ1TDIuOTg1MjEgNS4xNzYxN0MyLjk5NDI5IDQuOTU4NjMgMy4yNTc4MSA0Ljg1NTg2IDMuNDExNzcgNS4wMDk4MloiIGZpbGw9IiMxMjVFMUUiLz48L3N2Zz4=") + no-repeat 50% 50%; + mask: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTIiIHZpZXdCb3g9IjAgMCAxMiAxMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNOC41ODgyMyA2Ljk5MDE1TDUuMDA5NzkgMy40MTE3QzQuODU1ODMgMy4yNTc3NCA0Ljk1ODYgMi45OTQyMiA1LjE3NjE0IDIuOTg1MTRMOC45MTA0MiAyLjgyOTMxQzkuMDU2NTggMi44MjMyMSA5LjE3NjczIDIuOTQzMzUgOS4xNzA2MyAzLjA4OTUyTDkuMDE0NzkgNi44MjM4QzkuMDA1NzEgNy4wNDEzNCA4Ljc0MjE5IDcuMTQ0MTEgOC41ODgyMyA2Ljk5MDE1WiIgZmlsbD0iIzEyNUUxRSIvPjxwYXRoIGQ9Ik0zLjQxMTc3IDUuMDA5ODJMNi45OTAyMSA4LjU4ODI3QzcuMTQ0MTcgOC43NDIyMyA3LjA0MTQgOS4wMDU3NSA2LjgyMzg2IDkuMDE0ODNMMy4wODk1OCA5LjE3MDY2QzIuOTQzNDIgOS4xNzY3NiAyLjgyMzI3IDkuMDU2NjEgMi44MjkzNyA4LjkxMDQ1TDIuOTg1MjEgNS4xNzYxN0MyLjk5NDI5IDQuOTU4NjMgMy4yNTc4MSA0Ljg1NTg2IDMuNDExNzcgNS4wMDk4MloiIGZpbGw9IiMxMjVFMUUiLz48L3N2Zz4=") + no-repeat 50% 50%; + transform: translate(0px, -7px); } diff --git a/assets/app/css/discord.css b/assets/app/css/discord.css index 2968866..1a0f318 100644 --- a/assets/app/css/discord.css +++ b/assets/app/css/discord.css @@ -11,13 +11,13 @@ } div:has(> span [data-list-item-id="guildsnav___app-download-button"]) { - display: none !important; + display: none; } /* custom keybinds are not supported on web information */ .container__6436f.info__6436f.browserNotice__740f2 { visibility: hidden; - display: block !important; + display: block; } .container__6436f.info__6436f.browserNotice__740f2:after { content: "You can modify global keybinds using the keybind maker on the left sidebar"; diff --git a/assets/app/css/inviteBack.css b/assets/app/css/inviteBack.css new file mode 100644 index 0000000..2fc5622 --- /dev/null +++ b/assets/app/css/inviteBack.css @@ -0,0 +1,52 @@ +#legcord-invite-back { + position: fixed; + bottom: 24px; + left: 50%; + transform: translateX(-50%); + z-index: 2147483646; + display: none; + align-items: center; + justify-content: center; + gap: 8px; + margin: 0; + padding: 0 16px; + min-height: 38px; + border: none; + border-radius: 8px; + background: var(--brand-500, #5865f2); + color: var(--white-500, #fff); + font-family: var(--font-primary, "gg sans", "gg sans Fallback", "Noto Sans", Helvetica, Arial, sans-serif); + font-size: 14px; + font-weight: 500; + line-height: 18px; + letter-spacing: 0; + white-space: nowrap; + cursor: pointer; + box-shadow: + var(--elevation-high, 0 8px 16px rgba(0, 0, 0, 0.24)), + 0 0 0 1px rgba(0, 0, 0, 0.08); + -webkit-app-region: no-drag; + user-select: none; + transition: + background-color 0.17s ease, + box-shadow 0.17s ease, + transform 0.17s ease; +} + +#legcord-invite-back[data-visible="true"] { + display: inline-flex; +} + +#legcord-invite-back:hover { + background: var(--brand-560, #4752c4); +} + +#legcord-invite-back:active { + background: var(--brand-600, #3c45a5); + transform: translateX(-50%) translateY(1px); +} + +#legcord-invite-back:focus-visible { + outline: 2px solid var(--brand-500, #5865f2); + outline-offset: 2px; +} diff --git a/assets/app/css/linuxTitlebar.css b/assets/app/css/linuxTitlebar.css index 7935faa..e185c29 100644 --- a/assets/app/css/linuxTitlebar.css +++ b/assets/app/css/linuxTitlebar.css @@ -13,22 +13,6 @@ background-color: var(--interactive-background-hover); transition: 0.2s ease; } -[legcord-platform="linux"] #window-controls-container #minimize:hover #minimize-icon { - background-color: var(--interactive-text-hover); - transition: 0.2s ease; -} -[legcord-platform="linux"] #window-controls-container #maximize:hover #maximize-icon { - background-color: var(--interactive-text-hover); - transition: 0.2s ease; -} -[legcord-platform="linux"] #window-controls-container #quit:hover { - background-color: #e81123; - transition: 0.2s ease; -} -[legcord-platform="linux"] #window-controls-container #quit:hover #quit-icon { - background-color: #ffffff; - transition: 0.1s ease; -} [legcord-platform="linux"] #window-controls-container #minimize { background-color: transparent; transition: 0.1s ease; @@ -41,14 +25,6 @@ background-color: transparent; transition: 0.1s ease; } -[legcord-platform="linux"] #window-controls-container #quit:active { - background-color: #f1707a; - transition: 0.1s ease; -} -[legcord-platform="linux"] #window-controls-container #quit:active #quit-icon { - background-color: #000000cc; - transition: 0.1s ease; -} [legcord-platform="linux"] #window-controls-container #quit-icon { background-color: var(--interactive-icon-default); display: list-item; @@ -57,6 +33,14 @@ mask: url("data:image/svg+xml;charset=utf-8,") no-repeat 50% 50%; } +[legcord-platform="linux"] #window-controls-container #quit:active { + background-color: #f1707a; + transition: 0.1s ease; +} +[legcord-platform="linux"] #window-controls-container #quit:active #quit-icon { + background-color: #000000cc; + transition: 0.1s ease; +} [legcord-platform="linux"] #window-controls-container #minimize-icon { background-color: var(--interactive-icon-default); display: list-item; @@ -73,6 +57,22 @@ mask: url("data:image/svg+xml;charset=utf-8,") no-repeat 50% 50%; } +[legcord-platform="linux"] #window-controls-container #minimize:hover #minimize-icon { + background-color: var(--interactive-text-hover); + transition: 0.2s ease; +} +[legcord-platform="linux"] #window-controls-container #maximize:hover #maximize-icon { + background-color: var(--interactive-text-hover); + transition: 0.2s ease; +} +[legcord-platform="linux"] #window-controls-container #quit:hover { + background-color: #e81123; + transition: 0.2s ease; +} +[legcord-platform="linux"] #window-controls-container #quit:hover #quit-icon { + background-color: #ffffff; + transition: 0.1s ease; +} [legcord-platform="linux"][isMaximized] #window-controls-container #maximize-icon { background-color: var(--interactive-icon-default); diff --git a/assets/app/css/titlebar.css b/assets/app/css/titlebar.css index 21cc620..2492f52 100644 --- a/assets/app/css/titlebar.css +++ b/assets/app/css/titlebar.css @@ -11,7 +11,7 @@ clear: both; height: 30px; line-height: 30px; - -webkit-app-region: drag !important; + -webkit-app-region: drag; user-select: none; -webkit-user-select: none; position: fixed; @@ -58,6 +58,22 @@ line-height: 45px; transform: translateY(-8px); } +[legcord-platform="linux"] .titlebar #window-controls-container #minimize-icon { + background-color: var(--interactive-icon-default); + display: list-item; + -webkit-mask: url("data:image/svg+xml;charset=utf-8,") + no-repeat 50% 50%; + mask: url("data:image/svg+xml;charset=utf-8,") + no-repeat 50% 50%; +} +[legcord-platform="linux"] .titlebar #window-controls-container #maximize-icon { + background-color: var(--interactive-icon-default); + display: list-item; + -webkit-mask: url("data:image/svg+xml;charset=utf-8,") + no-repeat 50% 50%; + mask: url("data:image/svg+xml;charset=utf-8,") + no-repeat 50% 50%; +} [legcord-platform="linux"] .titlebar #window-controls-container #minimize:hover { background-color: var(--interactive-background-hover); transition: 0.2s ease; @@ -87,22 +103,6 @@ mask: url("data:image/svg+xml;charset=utf-8,") no-repeat 50% 50%; } -[legcord-platform="linux"] .titlebar #window-controls-container #minimize-icon { - background-color: var(--interactive-icon-default); - display: list-item; - -webkit-mask: url("data:image/svg+xml;charset=utf-8,") - no-repeat 50% 50%; - mask: url("data:image/svg+xml;charset=utf-8,") - no-repeat 50% 50%; -} -[legcord-platform="linux"] .titlebar #window-controls-container #maximize-icon { - background-color: var(--interactive-icon-default); - display: list-item; - -webkit-mask: url("data:image/svg+xml;charset=utf-8,") - no-repeat 50% 50%; - mask: url("data:image/svg+xml;charset=utf-8,") - no-repeat 50% 50%; -} [legcord-platform="linux"][isMaximized] .titlebar #window-controls-container #maximize-icon { background-color: var(--interactive-icon-default); @@ -145,30 +145,6 @@ [legcord-platform="win32"] .titlebar #window-controls-container { width: 142px; } -[legcord-platform="win32"] .titlebar #window-controls-container #minimize:hover { - background-color: var(--interactive-background-hover); - transition: 0.2s ease; -} -[legcord-platform="win32"] .titlebar #window-controls-container #maximize:hover { - background-color: var(--interactive-background-hover); - transition: 0.2s ease; -} -[legcord-platform="win32"] .titlebar #window-controls-container #minimize:hover #minimize-icon { - background-color: var(--interactive-text-hover); - transition: 0.2s ease; -} -[legcord-platform="win32"] .titlebar #window-controls-container #maximize:hover #maximize-icon { - background-color: var(--interactive-text-hover); - transition: 0.2s ease; -} -[legcord-platform="win32"] .titlebar #window-controls-container #quit:hover { - background-color: #e81123; - transition: 0.2s ease; -} -[legcord-platform="win32"] .titlebar #window-controls-container #quit:hover #quit-icon { - background-color: #ffffff; - transition: 0.1s ease; -} [legcord-platform="win32"] .titlebar #window-controls-container #minimize { background-color: transparent; transition: 0.1s ease; @@ -189,6 +165,7 @@ background-color: #000000cc; transition: 0.1s ease; } +/* biome-ignore lint/style/noDescendingSpecificity: cross-platform, linux [legcord-platform="linux"] only */ [legcord-platform="win32"] .titlebar #window-controls-container #quit-icon { background-color: var(--interactive-icon-default); display: list-item; @@ -213,6 +190,30 @@ mask: url("data:image/svg+xml;charset=utf-8,") no-repeat 50% 50%; } +[legcord-platform="win32"] .titlebar #window-controls-container #minimize:hover { + background-color: var(--interactive-background-hover); + transition: 0.2s ease; +} +[legcord-platform="win32"] .titlebar #window-controls-container #maximize:hover { + background-color: var(--interactive-background-hover); + transition: 0.2s ease; +} +[legcord-platform="win32"] .titlebar #window-controls-container #minimize:hover #minimize-icon { + background-color: var(--interactive-text-hover); + transition: 0.2s ease; +} +[legcord-platform="win32"] .titlebar #window-controls-container #maximize:hover #maximize-icon { + background-color: var(--interactive-text-hover); + transition: 0.2s ease; +} +[legcord-platform="win32"] .titlebar #window-controls-container #quit:hover { + background-color: #e81123; + transition: 0.2s ease; +} +[legcord-platform="win32"] .titlebar #window-controls-container #quit:hover #quit-icon { + background-color: #ffffff; + transition: 0.1s ease; +} [legcord-platform="win32"][isMaximized] .titlebar #window-controls-container #maximize-icon { background-color: var(--interactive-icon-default); @@ -226,11 +227,11 @@ /* Legcord on macOS */ [legcord-platform="darwin"] .sidebar-1tnWFu { - border-top-left-radius: 0px !important; + border-top-left-radius: 0px; } [legcord-platform="darwin"] .container__037ed { - overflow: unset !important; + overflow: unset; padding-top: 48px; top: -48px; } @@ -256,7 +257,7 @@ [legcord-platform="darwin"][unFocused] .titlebar #window-controls-container #minimize, [legcord-platform="darwin"][unFocused] .titlebar #window-controls-container #maximize, [legcord-platform="darwin"][unFocused] .titlebar #window-controls-container #quit { - background-color: #d6d6d5 !important; + background-color: #d6d6d5; pointer-events: none; transition: background-color 0.1s ease-in; } @@ -338,7 +339,11 @@ [legcord-platform="darwin"] .titlebar #window-controls-container #minimize-icon, [legcord-platform="darwin"] .titlebar #window-controls-container #maximize-icon, -[legcord-platform="darwin"] .titlebar #window-controls-container #quit-icon { +/* biome-ignore lint/style/noDescendingSpecificity: cross-platform */ + [legcord-platform="darwin"] + .titlebar + #window-controls-container + #quit-icon { display: none; } @@ -346,12 +351,6 @@ display: none; } -[legcord-platform="darwin"] .window-title { - float: none; - position: fixed; - left: 50%; -} - .window-title { content: url("legcord://assets/Wordmark.png"); height: 15px; @@ -362,6 +361,12 @@ filter: invert(30%); } +[legcord-platform="darwin"] .window-title { + float: none; + position: fixed; + left: 50%; +} + div#app-mount { height: calc(100% - 30px); position: absolute; diff --git a/assets/app/css/winTitlebar.css b/assets/app/css/winTitlebar.css index a947c74..655cdc2 100644 --- a/assets/app/css/winTitlebar.css +++ b/assets/app/css/winTitlebar.css @@ -15,22 +15,6 @@ background-color: var(--interactive-background-hover); transition: 0.2s ease; } -[legcord-platform="win32"] #window-controls-container #minimize:hover #minimize-icon { - background-color: var(--interactive-text-hover); - transition: 0.2s ease; -} -[legcord-platform="win32"] #window-controls-container #maximize:hover #maximize-icon { - background-color: var(--interactive-text-hover); - transition: 0.2s ease; -} -[legcord-platform="win32"] #window-controls-container #quit:hover { - background-color: #e81123; - transition: 0.2s ease; -} -[legcord-platform="win32"] #window-controls-container #quit:hover #quit-icon { - background-color: #ffffff; - transition: 0.1s ease; -} [legcord-platform="win32"] #window-controls-container #minimize { background-color: transparent; transition: 0.1s ease; @@ -43,14 +27,6 @@ background-color: transparent; transition: 0.1s ease; } -[legcord-platform="win32"] #window-controls-container #quit:active { - background-color: #f1707a; - transition: 0.1s ease; -} -[legcord-platform="win32"] #window-controls-container #quit:active #quit-icon { - background-color: #000000cc; - transition: 0.1s ease; -} [legcord-platform="win32"] #window-controls-container #quit-icon { background-color: var(--interactive-icon-default); display: list-item; @@ -59,6 +35,14 @@ mask: url("data:image/svg+xml;charset=utf-8,") no-repeat 50% 50%; } +[legcord-platform="win32"] #window-controls-container #quit:active { + background-color: #f1707a; + transition: 0.1s ease; +} +[legcord-platform="win32"] #window-controls-container #quit:active #quit-icon { + background-color: #000000cc; + transition: 0.1s ease; +} [legcord-platform="win32"] #window-controls-container #minimize-icon { background-color: var(--interactive-icon-default); display: list-item; @@ -75,6 +59,22 @@ mask: url("data:image/svg+xml;charset=utf-8,") no-repeat 50% 50%; } +[legcord-platform="win32"] #window-controls-container #minimize:hover #minimize-icon { + background-color: var(--interactive-text-hover); + transition: 0.2s ease; +} +[legcord-platform="win32"] #window-controls-container #maximize:hover #maximize-icon { + background-color: var(--interactive-text-hover); + transition: 0.2s ease; +} +[legcord-platform="win32"] #window-controls-container #quit:hover { + background-color: #e81123; + transition: 0.2s ease; +} +[legcord-platform="win32"] #window-controls-container #quit:hover #quit-icon { + background-color: #ffffff; + transition: 0.1s ease; +} [legcord-platform="win32"][isMaximized] #window-controls-container #maximize-icon { background-color: var(--interactive-icon-default); diff --git a/assets/app/desktop.png b/assets/app/desktop.png new file mode 100644 index 0000000..4ad0ad5 Binary files /dev/null and b/assets/app/desktop.png differ diff --git a/assets/app/js/monacoLoader.js b/assets/app/js/monacoLoader.js deleted file mode 100644 index 0ba3cc3..0000000 --- a/assets/app/js/monacoLoader.js +++ /dev/null @@ -1,11 +0,0 @@ -"use strict";/*!----------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1) - * Released under the MIT license - * https://github.com/microsoft/vscode/blob/main/LICENSE.txt - *-----------------------------------------------------------*/const _amdLoaderGlobal=this,_commonjsGlobal=typeof global=="object"?global:{};var AMDLoader;(function(u){u.global=_amdLoaderGlobal;class y{get isWindows(){return this._detect(),this._isWindows}get isNode(){return this._detect(),this._isNode}get isElectronRenderer(){return this._detect(),this._isElectronRenderer}get isWebWorker(){return this._detect(),this._isWebWorker}get isElectronNodeIntegrationWebWorker(){return this._detect(),this._isElectronNodeIntegrationWebWorker}constructor(){this._detected=!1,this._isWindows=!1,this._isNode=!1,this._isElectronRenderer=!1,this._isWebWorker=!1,this._isElectronNodeIntegrationWebWorker=!1}_detect(){this._detected||(this._detected=!0,this._isWindows=y._isWindows(),this._isNode=typeof module<"u"&&!!module.exports,this._isElectronRenderer=typeof process<"u"&&typeof process.versions<"u"&&typeof process.versions.electron<"u"&&process.type==="renderer",this._isWebWorker=typeof u.global.importScripts=="function",this._isElectronNodeIntegrationWebWorker=this._isWebWorker&&typeof process<"u"&&typeof process.versions<"u"&&typeof process.versions.electron<"u"&&process.type==="worker")}static _isWindows(){return typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.indexOf("Windows")>=0?!0:typeof process<"u"?process.platform==="win32":!1}}u.Environment=y})(AMDLoader||(AMDLoader={}));var AMDLoader;(function(u){class y{constructor(r,c,a){this.type=r,this.detail=c,this.timestamp=a}}u.LoaderEvent=y;class m{constructor(r){this._events=[new y(1,"",r)]}record(r,c){this._events.push(new y(r,c,u.Utilities.getHighPerformanceTimestamp()))}getEvents(){return this._events}}u.LoaderEventRecorder=m;class p{record(r,c){}getEvents(){return[]}}p.INSTANCE=new p,u.NullLoaderEventRecorder=p})(AMDLoader||(AMDLoader={}));var AMDLoader;(function(u){class y{static fileUriToFilePath(p,h){if(h=decodeURI(h).replace(/%23/g,"#"),p){if(/^file:\/\/\//.test(h))return h.substr(8);if(/^file:\/\//.test(h))return h.substr(5)}else if(/^file:\/\//.test(h))return h.substr(7);return h}static startsWith(p,h){return p.length>=h.length&&p.substr(0,h.length)===h}static endsWith(p,h){return p.length>=h.length&&p.substr(p.length-h.length)===h}static containsQueryString(p){return/^[^\#]*\?/gi.test(p)}static isAbsolutePath(p){return/^((http:\/\/)|(https:\/\/)|(file:\/\/)|(\/))/.test(p)}static forEachProperty(p,h){if(p){let r;for(r in p)p.hasOwnProperty(r)&&h(r,p[r])}}static isEmpty(p){let h=!0;return y.forEachProperty(p,()=>{h=!1}),h}static recursiveClone(p){if(!p||typeof p!="object"||p instanceof RegExp||!Array.isArray(p)&&Object.getPrototypeOf(p)!==Object.prototype)return p;let h=Array.isArray(p)?[]:{};return y.forEachProperty(p,(r,c)=>{c&&typeof c=="object"?h[r]=y.recursiveClone(c):h[r]=c}),h}static generateAnonymousModule(){return"===anonymous"+y.NEXT_ANONYMOUS_ID+++"==="}static isAnonymousModule(p){return y.startsWith(p,"===anonymous")}static getHighPerformanceTimestamp(){return this.PERFORMANCE_NOW_PROBED||(this.PERFORMANCE_NOW_PROBED=!0,this.HAS_PERFORMANCE_NOW=u.global.performance&&typeof u.global.performance.now=="function"),this.HAS_PERFORMANCE_NOW?u.global.performance.now():Date.now()}}y.NEXT_ANONYMOUS_ID=1,y.PERFORMANCE_NOW_PROBED=!1,y.HAS_PERFORMANCE_NOW=!1,u.Utilities=y})(AMDLoader||(AMDLoader={}));var AMDLoader;(function(u){function y(h){if(h instanceof Error)return h;const r=new Error(h.message||String(h)||"Unknown Error");return h.stack&&(r.stack=h.stack),r}u.ensureError=y;class m{static validateConfigurationOptions(r){function c(a){if(a.phase==="loading"){console.error('Loading "'+a.moduleId+'" failed'),console.error(a),console.error("Here are the modules that depend on it:"),console.error(a.neededBy);return}if(a.phase==="factory"){console.error('The factory function of "'+a.moduleId+'" has thrown an exception'),console.error(a),console.error("Here are the modules that depend on it:"),console.error(a.neededBy);return}}if(r=r||{},typeof r.baseUrl!="string"&&(r.baseUrl=""),typeof r.isBuild!="boolean"&&(r.isBuild=!1),typeof r.paths!="object"&&(r.paths={}),typeof r.config!="object"&&(r.config={}),typeof r.catchError>"u"&&(r.catchError=!1),typeof r.recordStats>"u"&&(r.recordStats=!1),typeof r.urlArgs!="string"&&(r.urlArgs=""),typeof r.onError!="function"&&(r.onError=c),Array.isArray(r.ignoreDuplicateModules)||(r.ignoreDuplicateModules=[]),r.baseUrl.length>0&&(u.Utilities.endsWith(r.baseUrl,"/")||(r.baseUrl+="/")),typeof r.cspNonce!="string"&&(r.cspNonce=""),typeof r.preferScriptTags>"u"&&(r.preferScriptTags=!1),r.nodeCachedData&&typeof r.nodeCachedData=="object"&&(typeof r.nodeCachedData.seed!="string"&&(r.nodeCachedData.seed="seed"),(typeof r.nodeCachedData.writeDelay!="number"||r.nodeCachedData.writeDelay<0)&&(r.nodeCachedData.writeDelay=1e3*7),!r.nodeCachedData.path||typeof r.nodeCachedData.path!="string")){const a=y(new Error("INVALID cached data configuration, 'path' MUST be set"));a.phase="configuration",r.onError(a),r.nodeCachedData=void 0}return r}static mergeConfigurationOptions(r=null,c=null){let a=u.Utilities.recursiveClone(c||{});return u.Utilities.forEachProperty(r,(t,e)=>{t==="ignoreDuplicateModules"&&typeof a.ignoreDuplicateModules<"u"?a.ignoreDuplicateModules=a.ignoreDuplicateModules.concat(e):t==="paths"&&typeof a.paths<"u"?u.Utilities.forEachProperty(e,(i,s)=>a.paths[i]=s):t==="config"&&typeof a.config<"u"?u.Utilities.forEachProperty(e,(i,s)=>a.config[i]=s):a[t]=u.Utilities.recursiveClone(e)}),m.validateConfigurationOptions(a)}}u.ConfigurationOptionsUtil=m;class p{constructor(r,c){if(this._env=r,this.options=m.mergeConfigurationOptions(c),this._createIgnoreDuplicateModulesMap(),this._createSortedPathsRules(),this.options.baseUrl===""&&this.options.nodeRequire&&this.options.nodeRequire.main&&this.options.nodeRequire.main.filename&&this._env.isNode){let a=this.options.nodeRequire.main.filename,t=Math.max(a.lastIndexOf("/"),a.lastIndexOf("\\"));this.options.baseUrl=a.substring(0,t+1)}}_createIgnoreDuplicateModulesMap(){this.ignoreDuplicateModulesMap={};for(let r=0;r{Array.isArray(c)?this.sortedPathsRules.push({from:r,to:c}):this.sortedPathsRules.push({from:r,to:[c]})}),this.sortedPathsRules.sort((r,c)=>c.from.length-r.from.length)}cloneAndMerge(r){return new p(this._env,m.mergeConfigurationOptions(r,this.options))}getOptionsLiteral(){return this.options}_applyPaths(r){let c;for(let a=0,t=this.sortedPathsRules.length;athis.triggerCallback(i),d=>this.triggerErrorback(i,d))}triggerCallback(e){let i=this._callbackMap[e];delete this._callbackMap[e];for(let s=0;s{e.removeEventListener("load",l),e.removeEventListener("error",d)},l=o=>{n(),i()},d=o=>{n(),s(o)};e.addEventListener("load",l),e.addEventListener("error",d)}load(e,i,s,n){if(/^node\|/.test(i)){let l=e.getConfig().getOptionsLiteral(),d=c(e.getRecorder(),l.nodeRequire||u.global.nodeRequire),o=i.split("|"),_=null;try{_=d(o[1])}catch(f){n(f);return}e.enqueueDefineAnonymousModule([],()=>_),s()}else{let l=document.createElement("script");l.setAttribute("async","async"),l.setAttribute("type","text/javascript"),this.attachListeners(l,s,n);const{trustedTypesPolicy:d}=e.getConfig().getOptionsLiteral();d&&(i=d.createScriptURL(i)),l.setAttribute("src",i);const{cspNonce:o}=e.getConfig().getOptionsLiteral();o&&l.setAttribute("nonce",o),document.getElementsByTagName("head")[0].appendChild(l)}}}function p(t){const{trustedTypesPolicy:e}=t.getConfig().getOptionsLiteral();try{return(e?self.eval(e.createScript("","true")):new Function("true")).call(self),!0}catch{return!1}}class h{constructor(){this._cachedCanUseEval=null}_canUseEval(e){return this._cachedCanUseEval===null&&(this._cachedCanUseEval=p(e)),this._cachedCanUseEval}load(e,i,s,n){if(/^node\|/.test(i)){const l=e.getConfig().getOptionsLiteral(),d=c(e.getRecorder(),l.nodeRequire||u.global.nodeRequire),o=i.split("|");let _=null;try{_=d(o[1])}catch(f){n(f);return}e.enqueueDefineAnonymousModule([],function(){return _}),s()}else{const{trustedTypesPolicy:l}=e.getConfig().getOptionsLiteral();if(!(/^((http:)|(https:)|(file:))/.test(i)&&i.substring(0,self.origin.length)!==self.origin)&&this._canUseEval(e)){fetch(i).then(o=>{if(o.status!==200)throw new Error(o.statusText);return o.text()}).then(o=>{o=`${o} -//# sourceURL=${i}`,(l?self.eval(l.createScript("",o)):new Function(o)).call(self),s()}).then(void 0,n);return}try{l&&(i=l.createScriptURL(i)),importScripts(i),s()}catch(o){n(o)}}}}class r{constructor(e){this._env=e,this._didInitialize=!1,this._didPatchNodeRequire=!1}_init(e){this._didInitialize||(this._didInitialize=!0,this._fs=e("fs"),this._vm=e("vm"),this._path=e("path"),this._crypto=e("crypto"))}_initNodeRequire(e,i){const{nodeCachedData:s}=i.getConfig().getOptionsLiteral();if(!s||this._didPatchNodeRequire)return;this._didPatchNodeRequire=!0;const n=this,l=e("module");function d(o){const _=o.constructor;let f=function(v){try{return o.require(v)}finally{}};return f.resolve=function(v,E){return _._resolveFilename(v,o,!1,E)},f.resolve.paths=function(v){return _._resolveLookupPaths(v,o)},f.main=process.mainModule,f.extensions=_._extensions,f.cache=_._cache,f}l.prototype._compile=function(o,_){const f=l.wrap(o.replace(/^#!.*/,"")),g=i.getRecorder(),v=n._getCachedDataPath(s,_),E={filename:_};let I;try{const D=n._fs.readFileSync(v);I=D.slice(0,16),E.cachedData=D.slice(16),g.record(60,v)}catch{g.record(61,v)}const C=new n._vm.Script(f,E),P=C.runInThisContext(E),w=n._path.dirname(_),R=d(this),U=[this.exports,R,this,_,w,process,_commonjsGlobal,Buffer],b=P.apply(this.exports,U);return n._handleCachedData(C,f,v,!E.cachedData,i),n._verifyCachedData(C,f,v,I,i),b}}load(e,i,s,n){const l=e.getConfig().getOptionsLiteral(),d=c(e.getRecorder(),l.nodeRequire||u.global.nodeRequire),o=l.nodeInstrumenter||function(f){return f};this._init(d),this._initNodeRequire(d,e);let _=e.getRecorder();if(/^node\|/.test(i)){let f=i.split("|"),g=null;try{g=d(f[1])}catch(v){n(v);return}e.enqueueDefineAnonymousModule([],()=>g),s()}else{i=u.Utilities.fileUriToFilePath(this._env.isWindows,i);const f=this._path.normalize(i),g=this._getElectronRendererScriptPathOrUri(f),v=!!l.nodeCachedData,E=v?this._getCachedDataPath(l.nodeCachedData,i):void 0;this._readSourceAndCachedData(f,E,_,(I,C,P,w)=>{if(I){n(I);return}let R;C.charCodeAt(0)===r._BOM?R=r._PREFIX+C.substring(1)+r._SUFFIX:R=r._PREFIX+C+r._SUFFIX,R=o(R,f);const U={filename:g,cachedData:P},b=this._createAndEvalScript(e,R,U,s,n);this._handleCachedData(b,R,E,v&&!P,e),this._verifyCachedData(b,R,E,w,e)})}}_createAndEvalScript(e,i,s,n,l){const d=e.getRecorder();d.record(31,s.filename);const o=new this._vm.Script(i,s),_=o.runInThisContext(s),f=e.getGlobalAMDDefineFunc();let g=!1;const v=function(){return g=!0,f.apply(null,arguments)};return v.amd=f.amd,_.call(u.global,e.getGlobalAMDRequireFunc(),v,s.filename,this._path.dirname(s.filename)),d.record(32,s.filename),g?n():l(new Error(`Didn't receive define call in ${s.filename}!`)),o}_getElectronRendererScriptPathOrUri(e){if(!this._env.isElectronRenderer)return e;let i=e.match(/^([a-z])\:(.*)/i);return i?`file:///${(i[1].toUpperCase()+":"+i[2]).replace(/\\/g,"/")}`:`file://${e}`}_getCachedDataPath(e,i){const s=this._crypto.createHash("md5").update(i,"utf8").update(e.seed,"utf8").update(process.arch,"").digest("hex"),n=this._path.basename(i).replace(/\.js$/,"");return this._path.join(e.path,`${n}-${s}.code`)}_handleCachedData(e,i,s,n,l){e.cachedDataRejected?this._fs.unlink(s,d=>{l.getRecorder().record(62,s),this._createAndWriteCachedData(e,i,s,l),d&&l.getConfig().onError(d)}):n&&this._createAndWriteCachedData(e,i,s,l)}_createAndWriteCachedData(e,i,s,n){let l=Math.ceil(n.getConfig().getOptionsLiteral().nodeCachedData.writeDelay*(1+Math.random())),d=-1,o=0,_;const f=()=>{setTimeout(()=>{_||(_=this._crypto.createHash("md5").update(i,"utf8").digest());const g=e.createCachedData();if(!(g.length===0||g.length===d||o>=5)){if(g.length{v&&n.getConfig().onError(v),n.getRecorder().record(63,s),f()})}},l*Math.pow(4,o++))};f()}_readSourceAndCachedData(e,i,s,n){if(!i)this._fs.readFile(e,{encoding:"utf8"},n);else{let l,d,o,_=2;const f=g=>{g?n(g):--_===0&&n(void 0,l,d,o)};this._fs.readFile(e,{encoding:"utf8"},(g,v)=>{l=v,f(g)}),this._fs.readFile(i,(g,v)=>{!g&&v&&v.length>0?(o=v.slice(0,16),d=v.slice(16),s.record(60,i)):s.record(61,i),f()})}}_verifyCachedData(e,i,s,n,l){n&&(e.cachedDataRejected||setTimeout(()=>{const d=this._crypto.createHash("md5").update(i,"utf8").digest();n.equals(d)||(l.getConfig().onError(new Error(`FAILED TO VERIFY CACHED DATA, deleting stale '${s}' now, but a RESTART IS REQUIRED`)),this._fs.unlink(s,o=>{o&&l.getConfig().onError(o)}))},Math.ceil(5e3*(1+Math.random()))))}}r._BOM=65279,r._PREFIX="(function (require, define, __filename, __dirname) { ",r._SUFFIX=` -});`;function c(t,e){if(e.__$__isRecorded)return e;const i=function(n){t.record(33,n);try{return e(n)}finally{t.record(34,n)}};return i.__$__isRecorded=!0,i}u.ensureRecordedNodeRequire=c;function a(t){return new y(t)}u.createScriptLoader=a})(AMDLoader||(AMDLoader={}));var AMDLoader;(function(u){class y{constructor(t){let e=t.lastIndexOf("/");e!==-1?this.fromModulePath=t.substr(0,e+1):this.fromModulePath=""}static _normalizeModuleId(t){let e=t,i;for(i=/\/\.\//;i.test(e);)e=e.replace(i,"/");for(e=e.replace(/^\.\//g,""),i=/\/(([^\/])|([^\/][^\/\.])|([^\/\.][^\/])|([^\/][^\/][^\/]+))\/\.\.\//;i.test(e);)e=e.replace(i,"/");return e=e.replace(/^(([^\/])|([^\/][^\/\.])|([^\/\.][^\/])|([^\/][^\/][^\/]+))\/\.\.\//,""),e}resolveModule(t){let e=t;return u.Utilities.isAbsolutePath(e)||(u.Utilities.startsWith(e,"./")||u.Utilities.startsWith(e,"../"))&&(e=y._normalizeModuleId(this.fromModulePath+e)),e}}y.ROOT=new y(""),u.ModuleIdResolver=y;class m{constructor(t,e,i,s,n,l){this.id=t,this.strId=e,this.dependencies=i,this._callback=s,this._errorback=n,this.moduleIdResolver=l,this.exports={},this.error=null,this.exportsPassedIn=!1,this.unresolvedDependenciesCount=this.dependencies.length,this._isComplete=!1}static _safeInvokeFunction(t,e){try{return{returnedValue:t.apply(u.global,e),producedError:null}}catch(i){return{returnedValue:null,producedError:i}}}static _invokeFactory(t,e,i,s){return t.shouldInvokeFactory(e)?t.shouldCatchError()?this._safeInvokeFunction(i,s):{returnedValue:i.apply(u.global,s),producedError:null}:{returnedValue:null,producedError:null}}complete(t,e,i,s){this._isComplete=!0;let n=null;if(this._callback)if(typeof this._callback=="function"){t.record(21,this.strId);let l=m._invokeFactory(e,this.strId,this._callback,i);n=l.producedError,t.record(22,this.strId),!n&&typeof l.returnedValue<"u"&&(!this.exportsPassedIn||u.Utilities.isEmpty(this.exports))&&(this.exports=l.returnedValue)}else this.exports=this._callback;if(n){let l=u.ensureError(n);l.phase="factory",l.moduleId=this.strId,l.neededBy=s(this.id),this.error=l,e.onError(l)}this.dependencies=null,this._callback=null,this._errorback=null,this.moduleIdResolver=null}onDependencyError(t){return this._isComplete=!0,this.error=t,this._errorback?(this._errorback(t),!0):!1}isComplete(){return this._isComplete}}u.Module=m;class p{constructor(){this._nextId=0,this._strModuleIdToIntModuleId=new Map,this._intModuleIdToStrModuleId=[],this.getModuleId("exports"),this.getModuleId("module"),this.getModuleId("require")}getMaxModuleId(){return this._nextId}getModuleId(t){let e=this._strModuleIdToIntModuleId.get(t);return typeof e>"u"&&(e=this._nextId++,this._strModuleIdToIntModuleId.set(t,e),this._intModuleIdToStrModuleId[e]=t),e}getStrModuleId(t){return this._intModuleIdToStrModuleId[t]}}class h{constructor(t){this.id=t}}h.EXPORTS=new h(0),h.MODULE=new h(1),h.REQUIRE=new h(2),u.RegularDependency=h;class r{constructor(t,e,i){this.id=t,this.pluginId=e,this.pluginParam=i}}u.PluginDependency=r;class c{constructor(t,e,i,s,n=0){this._env=t,this._scriptLoader=e,this._loaderAvailableTimestamp=n,this._defineFunc=i,this._requireFunc=s,this._moduleIdProvider=new p,this._config=new u.Configuration(this._env),this._hasDependencyCycle=!1,this._modules2=[],this._knownModules2=[],this._inverseDependencies2=[],this._inversePluginDependencies2=new Map,this._currentAnonymousDefineCall=null,this._recorder=null,this._buildInfoPath=[],this._buildInfoDefineStack=[],this._buildInfoDependencies=[],this._requireFunc.moduleManager=this}reset(){return new c(this._env,this._scriptLoader,this._defineFunc,this._requireFunc,this._loaderAvailableTimestamp)}getGlobalAMDDefineFunc(){return this._defineFunc}getGlobalAMDRequireFunc(){return this._requireFunc}static _findRelevantLocationInStack(t,e){let i=l=>l.replace(/\\/g,"/"),s=i(t),n=e.split(/\n/);for(let l=0;lthis._moduleIdProvider.getStrModuleId(_.id))),this._resolve(o)}_normalizeDependency(t,e){if(t==="exports")return h.EXPORTS;if(t==="module")return h.MODULE;if(t==="require")return h.REQUIRE;let i=t.indexOf("!");if(i>=0){let s=e.resolveModule(t.substr(0,i)),n=e.resolveModule(t.substr(i+1)),l=this._moduleIdProvider.getModuleId(s+"!"+n),d=this._moduleIdProvider.getModuleId(s);return new r(l,d,n)}return new h(this._moduleIdProvider.getModuleId(e.resolveModule(t)))}_normalizeDependencies(t,e){let i=[],s=0;for(let n=0,l=t.length;nthis._moduleIdProvider.getStrModuleId(l));const n=u.ensureError(e);return n.phase="loading",n.moduleId=i,n.neededBy=s,n}_onLoadError(t,e){const i=this._createLoadError(t,e);this._modules2[t]||(this._modules2[t]=new m(t,this._moduleIdProvider.getStrModuleId(t),[],()=>{},null,null));let s=[];for(let d=0,o=this._moduleIdProvider.getMaxModuleId();d0;){let d=l.shift(),o=this._modules2[d];o&&(n=o.onDependencyError(i)||n);let _=this._inverseDependencies2[d];if(_)for(let f=0,g=_.length;f0;){let d=n.shift().dependencies;if(d)for(let o=0,_=d.length;o<_;o++){let f=d[o];if(f.id===e)return!0;let g=this._modules2[f.id];g&&!s[f.id]&&(s[f.id]=!0,n.push(g))}}return!1}_findCyclePath(t,e,i){if(t===e||i===50)return[t];let s=this._modules2[t];if(!s)return null;let n=s.dependencies;if(n)for(let l=0,d=n.length;lthis._relativeRequire(t,i,s,n);return e.toUrl=i=>this._config.requireToUrl(t.resolveModule(i)),e.getStats=()=>this.getLoaderEvents(),e.hasDependencyCycle=()=>this._hasDependencyCycle,e.config=(i,s=!1)=>{this.configure(i,s)},e.__$__nodeRequire=u.global.nodeRequire,e}_loadModule(t){if(this._modules2[t]||this._knownModules2[t])return;this._knownModules2[t]=!0;let e=this._moduleIdProvider.getStrModuleId(t),i=this._config.moduleIdToPaths(e),s=/^@[^\/]+\/[^\/]+$/;this._env.isNode&&(e.indexOf("/")===-1||s.test(e))&&i.push("node|"+e);let n=-1,l=d=>{if(n++,n>=i.length)this._onLoadError(t,d);else{let o=i[n],_=this.getRecorder();if(this._config.isBuild()&&o==="empty:"){this._buildInfoPath[t]=o,this.defineModule(this._moduleIdProvider.getStrModuleId(t),[],null,null,null),this._onLoad(t);return}_.record(10,o),this._scriptLoader.load(this,o,()=>{this._config.isBuild()&&(this._buildInfoPath[t]=o),_.record(11,o),this._onLoad(t)},f=>{_.record(12,o),l(f)})}};l(null)}_loadPluginDependency(t,e){if(this._modules2[e.id]||this._knownModules2[e.id])return;this._knownModules2[e.id]=!0;let i=s=>{this.defineModule(this._moduleIdProvider.getStrModuleId(e.id),[],s,null,null)};i.error=s=>{this._config.onError(this._createLoadError(e.id,s))},t.load(e.pluginParam,this._createRequire(y.ROOT),i,this._config.getOptionsLiteral())}_resolve(t){let e=t.dependencies;if(e)for(let i=0,s=e.length;ithis._moduleIdProvider.getStrModuleId(o)).join(` => -`)),t.unresolvedDependenciesCount--;continue}if(this._inverseDependencies2[n.id]=this._inverseDependencies2[n.id]||[],this._inverseDependencies2[n.id].push(t.id),n instanceof r){let d=this._modules2[n.pluginId];if(d&&d.isComplete()){this._loadPluginDependency(d.exports,n);continue}let o=this._inversePluginDependencies2.get(n.pluginId);o||(o=[],this._inversePluginDependencies2.set(n.pluginId,o)),o.push(n),this._loadModule(n.pluginId);continue}this._loadModule(n.id)}t.unresolvedDependenciesCount===0&&this._onModuleComplete(t)}_onModuleComplete(t){let e=this.getRecorder();if(t.isComplete())return;let i=t.dependencies,s=[];if(i)for(let o=0,_=i.length;o<_;o++){let f=i[o];if(f===h.EXPORTS){s[o]=t.exports;continue}if(f===h.MODULE){s[o]={id:t.strId,config:()=>this._config.getConfigForModule(t.strId)};continue}if(f===h.REQUIRE){s[o]=this._createRequire(t.moduleIdResolver);continue}let g=this._modules2[f.id];if(g){s[o]=g.exports;continue}s[o]=null}const n=o=>(this._inverseDependencies2[o]||[]).map(_=>this._moduleIdProvider.getStrModuleId(_));t.complete(e,this._config,s,n);let l=this._inverseDependencies2[t.id];if(this._inverseDependencies2[t.id]=null,l)for(let o=0,_=l.length;o<_;o++){let f=l[o],g=this._modules2[f];g.unresolvedDependenciesCount--,g.unresolvedDependenciesCount===0&&this._onModuleComplete(g)}let d=this._inversePluginDependencies2.get(t.id);if(d){this._inversePluginDependencies2.delete(t.id);for(let o=0,_=d.length;o<_;o++)this._loadPluginDependency(t.exports,d[o])}}}u.ModuleManager=c})(AMDLoader||(AMDLoader={}));var define,AMDLoader;(function(u){const y=new u.Environment;let m=null;const p=function(a,t,e){typeof a!="string"&&(e=t,t=a,a=null),(typeof t!="object"||!Array.isArray(t))&&(e=t,t=null),t||(t=["require","exports","module"]),a?m.defineModule(a,t,e,null,null):m.enqueueDefineAnonymousModule(t,e)};p.amd={jQuery:!0};const h=function(a,t=!1){m.configure(a,t)},r=function(){if(arguments.length===1){if(arguments[0]instanceof Object&&!Array.isArray(arguments[0])){h(arguments[0]);return}if(typeof arguments[0]=="string")return m.synchronousRequire(arguments[0])}if((arguments.length===2||arguments.length===3)&&Array.isArray(arguments[0])){m.defineModule(u.Utilities.generateAnonymousModule(),arguments[0],arguments[1],arguments[2],null);return}throw new Error("Unrecognized require call")};r.config=h,r.getConfig=function(){return m.getConfig().getOptionsLiteral()},r.reset=function(){m=m.reset()},r.getBuildInfo=function(){return m.getBuildInfo()},r.getStats=function(){return m.getLoaderEvents()},r.define=p;function c(){if(typeof u.global.require<"u"||typeof require<"u"){const a=u.global.require||require;if(typeof a=="function"&&typeof a.resolve=="function"){const t=u.ensureRecordedNodeRequire(m.getRecorder(),a);u.global.nodeRequire=t,r.nodeRequire=t,r.__$__nodeRequire=t}}y.isNode&&!y.isElectronRenderer&&!y.isElectronNodeIntegrationWebWorker?module.exports=r:(y.isElectronRenderer||(u.global.define=p),u.global.require=r)}u.init=c,(typeof u.global.define!="function"||!u.global.define.amd)&&(m=new u.ModuleManager(y,u.createScriptLoader(y),p,r,u.Utilities.getHighPerformanceTimestamp()),typeof u.global.require<"u"&&typeof u.global.require!="function"&&r.config(u.global.require),define=function(){return p.apply(null,arguments)},define.amd=p.amd,typeof doNotInitLoader>"u"&&c())})(AMDLoader||(AMDLoader={})); - -//# sourceMappingURL=../../min-maps/vs/loader.js.map \ No newline at end of file diff --git a/assets/app/overlay.png b/assets/app/overlay.png new file mode 100644 index 0000000..041a109 Binary files /dev/null and b/assets/app/overlay.png differ diff --git a/assets/app/shelter.svg b/assets/app/shelter.svg new file mode 100644 index 0000000..997578f --- /dev/null +++ b/assets/app/shelter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/lang/de.json b/assets/lang/de.json index 0d2f27e..0da4f91 100644 --- a/assets/lang/de.json +++ b/assets/lang/de.json @@ -27,8 +27,8 @@ "settings-transparency-universal": "Universell", "settings-transparency-modern": "Modern", "settings-theme-transparent": "Transparent", - "settings-transparency-tahoe-warning": "Transparenz kann zu großem Lags auf MacOS 26 Tahoe führen.", - "settings-popoutPiP": "Popup-Fenster immer im Vordergrund anzeigen", + "settings-transparency-tahoe-warning": "Transparenz kann zu großem Lags auf macOS 26 Tahoe führen.", + "settings-popoutPiP": "Anruf Popup-Fenster immer im Vordergrund anzeigen", "settings-popoutPiP-desc": "Wenn diese Option aktiviert ist, wird das Anruf-Popup im Modus „Immer im Vordergrund“ angezeigt.", "settings-venmic-workaround": "Umgehungslösung", "settings-venmic-workaround-desc": "Aktivieren oder deaktivieren Sie die Problemumgehung für ein Problem, das dazu führt, dass das Mikrofon anstelle des korrekten Audiosignals geteilt wird.", @@ -52,8 +52,8 @@ "settings-csp-desc": "Legcord CSP ist unser System, der das Laden von benutzerdefinierten Inhalten in die Discord-App verwaltet. Dinge wie Client-Mods und Designs hängen davon ab. Deaktivieren Sie es, wenn Sie Mods und benutzerdefinierte Stile entfernen möchten.", "settings-mintoTray": "Im Hintergrund arbeiten", "settings-mintoTray-desc": "Wenn diese Option deaktiviert ist, wird Legcord wie jedes andere Fenster geschlossen, wenn es geschlossen wird. Andernfalls bleibt es in Ihrer Taskleiste für später gespeichert.", - "settings-startMinimized": "Minimiert starten", - "settings-startMinimized-desc": "Legcord startet im Hintergrund und bleibt Ihnen nicht im Weg.", + "settings-startMinimized": "Startfenster", + "settings-startMinimized-desc": "Legt fest, wie Legcord beim Start erscheint. Tray-Modus blendet das Fenster vollständig aus (Tray-Symbol muss aktiviert sein).", "settings-useSystemCssEditor": "System-CSS-Editor verwenden", "settings-useSystemCssEditor-desc": "Verwenden Sie den System-CSS-Editor, um CSS zu bearbeiten.", "settings-MultiInstance": "Mehrfachinstanz", @@ -89,7 +89,12 @@ "settings-prfmMode": "Leistungsmodus", "settings-prfmMode-desc": "Der Leistungsmodus ist eine experimentelle Funktion in Legcord, die darauf ausgelegt ist, die Reaktionsfähigkeit und Leistung entsprechend Ihren Anforderungen zu optimieren. Die Auswirkungen können je nach Ihrer Hardware und Nutzung variieren. Wir empfehlen Ihnen daher, jeden Modus auszuprobieren, um herauszufinden, welcher für Sie am besten geeignet ist.", "settings-prfmMode-performance": "Leistung", + "settings-prfmMode-balanced": "Ausgewogen", "settings-prfmMode-battery": "Batterie", + "settings-prfmMode-memory": "Speichersparer", + "settings-prfmMode-voip": "Sprache & Video", + "settings-prfmMode-latency": "Niedrige Latenz", + "settings-prfmMode-smoothScreenshare": "Flüssige Bildschirmfreigabe", "settings-prfmMode-dynamic": "Dynamisch", "settings-prfmMode-vaapi": "VAAPI", "settings-disableAutogain": "Automatische Verstärkung deaktivieren", @@ -229,5 +234,17 @@ "games-removeConfirmHeader": "Spiel entfernen?", "games-noExecutables": "Keine ausführbaren Dateien", "games-lastDetected": "Zuletzt erkannte Spiele", - "games-removeFromBlacklist": "Entfernen" + "games-removeFromBlacklist": "Entfernen", + "settings-material": "Fenster Material", + "settings-material-acrylic": "Acryl", + "settings-material-none": "Keine", + "settings-csp-strict": "Strikt", + "settings-csp-none": "Keine", + "settings-csp-vanilla": "Vanilla", + "settings-firstTimeCrash": "Wir richten Dinge für sie ein!", + "settings-automaticClientUpdates": "Automatische client updates", + "settings-automaticClientUpdates-desc": "Deaktiviert automatische Legcord Updates", + "settings-startMinimized-off": "Normal", + "settings-startMinimized-minimized": "Minimiert in die Taskleiste", + "settings-startMinimized-tray": "Im Tray versteckt" } diff --git a/assets/lang/en-US.json b/assets/lang/en-US.json index e930c47..e525f40 100644 --- a/assets/lang/en-US.json +++ b/assets/lang/en-US.json @@ -27,7 +27,7 @@ "settings-transparency-universal": "Universal", "settings-transparency-modern": "Modern", "settings-theme-transparent": "Transparent", - "settings-transparency-tahoe-warning": "Transparency may cause excessive lag on MacOS 26 Tahoe.", + "settings-transparency-tahoe-warning": "Transparency may cause excessive lag on macOS 26 Tahoe.", "settings-material": "Window Material", "settings-material-desc": "Set the Windows background material Legcord uses.", "settings-material-mica": "Mica", @@ -57,13 +57,20 @@ "settings-openCustomIconDialog": "Set desktop icon", "settings-mintoTray": "Work in background", "settings-mintoTray-desc": "When disabled, Legcord will close like any other window when closed, otherwise it'll sit back and relax in your system tray for later.", - "settings-startMinimized": "Start minimized", - "settings-startMinimized-desc": "Legcord starts in background and remains out of your way.", + "settings-startMinimized": "Startup window", + "settings-startMinimized-desc": "Choose how Legcord appears when it launches. Tray mode hides the window completely (needs a tray icon enabled).", + "settings-startMinimized-off": "Normal", + "settings-startMinimized-minimized": "Minimized to taskbar", + "settings-startMinimized-tray": "Hidden in tray", "settings-csp": "Content Security Policy", "settings-csp-desc": "Set the strictness of Legcord's Content Security Policy. Strict CSP provides better security but may cause compatibility issues with some client mods/themes/plugins.", "settings-csp-strict": "Strict", "settings-csp-none": "None", "settings-csp-vanilla": "Vanilla", + "settings-showExperimentalPluginMenu": "Show experimental plugin menu", + "settings-showExperimentalPluginMenu-desc": "Show the experimental plugin menu in settings. This is a temporary setting until the plugin system is fully implemented.", + "settings-firstTimeCrash": "We're setting things up for you!", + "settings-firstTimeCrash-desc": "Settings are not available on a first-time launch. Please use a button below to restart and settings should be ready after the restart.", "settings-useSystemCssEditor": "Use system CSS editor", "settings-useSystemCssEditor-desc": "Use system CSS editor to edit CSS.", "settings-MultiInstance": "Multi Instance", @@ -74,12 +81,14 @@ "settings-automaticClientUpdates-desc": "Disables automatic Legcord updates", "settings-hardwareAcceleration": "Hardware acceleration", "settings-hardwareAcceleration-desc": "Hardware acceleration uses your GPU to make Legcord run faster. If you're experiencing visual glitches, try disabling this.", + "settings-sdpH264BaselineRewrite": "H.264 Baseline SDP rewrite", + "settings-sdpH264BaselineRewrite-desc": "Rewrites Discord's Constrained Baseline H.264 profile in WebRTC SDP so screenshare can use hardware encode (VideoToolbox / Media Foundation) instead of OpenH264. Disable if Go Live fails to connect or video is broken, then restart Legcord.", "settings-processScanning": "Process scanning", - "settings-processScanning-desc": "Enables scanning for running games to improve Rich Presence detection.", + "settings-processScanning-desc": "Scan for running games to improve Rich Presence detection. Disable to reduce CPU usage. Requires a restart.", "settings-windowsLegacyScanning": "Windows legacy scanning", - "settings-windowsLegacyScanning-desc": "Uses legacy method for scanning processes on Windows (pre v1.1.6). May improve compatibility on some systems but is less efficient.", + "settings-windowsLegacyScanning-desc": "Uses legacy method for scanning processes on Windows (pre v1.1.6). May improve compatibility on some systems but is less efficient. Requires a restart.", "settings-scanInterval": "Scan interval (ms)", - "settings-scanInterval-desc": "Sets how often (in milliseconds) the process scanning occurs. Lower values may improve detection speed but can increase CPU usage.", + "settings-scanInterval-desc": "How often (in milliseconds) process scanning runs. Lower values detect games faster but use more CPU. Minimum 1000. Requires a restart.", "settings-blockPowerSavingInVoiceChat": "Block power saving in voice chat", "settings-blockPowerSavingInVoiceChat-desc": "Prevent Legcord from being suspended. Keeps system active but allows screen to be turned off.", "settings-mobileMode": "Mobile mode", @@ -87,7 +96,7 @@ "settings-spellcheck": "Spellcheck", "settings-spellcheck-desc": "Helps you correct misspelled words by highlighting them.", "settings-vaapi": "VAAPI", - "settings-vaapi-desc": "Use VAAPI (HW acceleration) for video decoding on Linux. This greatly reduces CPU usage during screenshare but may cause issues on some systems. Disable if you experience crashes or black screens during screenshare.", + "settings-vaapi-desc": "Use VAAPI for hardware video encode and decode on Linux (sharer and viewer). Greatly reduces CPU during screenshare, but some GPUs (notably older AMD) produce frozen or blocky streams for viewers — disable to force software OpenH264 encode if that happens.", "settings-channel": "Discord channel", "settings-channel-desc": "Use this setting to change current instance of Discord that Legcord is running.", "settings-bitrateMin": "Minimum bitrate", @@ -109,9 +118,14 @@ "settings-mod-vencord": "Lightweight, and easy to use client mod. Features a built-in store for plugins.", "settings-mod-equicord": "Forked and born from vencord contributors, featuring a pretty plugin-rich client.", "settings-prfmMode": "Performance mode", - "settings-prfmMode-desc": "Performance Mode is an experimental feature in Legcord designed to optimize responsiveness and performance based on your needs. The impact may vary depending on your hardware and usage, so we encourage you to try each mode to determine which works best for you.", + "settings-prfmMode-desc": "Optimizes responsiveness and GPU behavior. When Hardware Acceleration is on, Legcord always enables WebRTC hardware encode/decode for screenshare and calls; these modes add broader GPU, latency, or battery tradeoffs on top. Screenshare bitrate is auto-capped for stability — pick resolution and FPS in the share picker.", "settings-prfmMode-performance": "Performance", + "settings-prfmMode-balanced": "Balanced", "settings-prfmMode-battery": "Battery", + "settings-prfmMode-memory": "Memory saver", + "settings-prfmMode-voip": "Voice & video", + "settings-prfmMode-latency": "Low latency", + "settings-prfmMode-smoothScreenshare": "Smooth screenshare", "settings-prfmMode-dynamic": "Dynamic", "settings-prfmMode-vaapi": "VAAPI", "settings-disableAutogain": "Disable autogain", @@ -138,11 +152,14 @@ "settings-save": "Save Settings", "settings-experimental": "Experimental", "settings-restart": "Restart App", + "invite-goBackToApp": "Go back to the Discord app", "settings-updater": "Check for updates", "settings-skipSplash": "Skip Splash Screen", "settings-skipSplash-desc": "Skips Legcord splash screen when you start up the app.", "settings-copyDebugInfo": "Copy Debug Info", "settings-copyGPUInfo": "Copy GPU Info", + "settings-openWebRTCInternals": "Open WebRTC Internals", + "settings-openGPUInfo": "Open GPU Info", "settings-clearClientModCache": "Clear client mod cache", "settings-forceNativeCrash": "Force native crash", "settings-smoothScroll": "Use smooth scrolling", @@ -152,10 +169,39 @@ "settings-quickCss": "Quick CSS", "settings-quickCss-desc": "Quickly edit your CSS in a simple text editor. Changes are applied immediately after saving the file.", "settings-category-lookAndFeel": "Look and feel", + "settings-category-lookAndFeel-desc": "Window chrome, tray icon, splash screen, and mobile layout.", "settings-category-mods": "Mods", + "settings-category-mods-desc": "Client mods, CSP, and plugin capabilities.", "settings-category-behaviour": "Behaviour", + "settings-category-behaviour-desc": "Startup, tray, scrolling, spellcheck, and Discord channel.", "settings-category-legacy": "Legacy features", + "settings-category-networking": "Networking", + "settings-category-networking-desc": "HTTP(S) and SOCKS proxy settings for Discord and downloads.", "settings-category-debug": "Debug options", + "settings-category-powerManagement": "Power Management", + "settings-category-powerManagement-desc": "Performance presets and power-saving behaviour.", + "settings-category-arrpc": "Rich Presence", + "settings-category-arrpc-desc": "arRPC game activity detection and scanning.", + "settings-category-backup": "Backup and restore", + "settings-category-backup-desc": "Export or restore settings, themes, plugins, and mod data.", + "settings-category-advanced": "Advanced", + "settings-category-advanced-desc": "Audio capture, hardware, updates, flags, and debug tools.", + "settings-search": "Search settings", + "settings-search-desc": "Filter settings by name or description.", + "settings-noResults": "No settings match your search.", + "settings-proxyMode": "Proxy mode", + "settings-proxyMode-desc": "Choose how Legcord connects through a proxy. System uses your OS proxy (and HTTP(S)_PROXY environment variables). Fixed servers and PAC work like in a normal web browser. A restart is required.", + "settings-proxyMode-system": "System", + "settings-proxyMode-direct": "Direct (no proxy)", + "settings-proxyMode-fixed_servers": "Fixed servers", + "settings-proxyMode-pac_script": "PAC script", + "settings-proxyMode-auto_detect": "Auto-detect", + "settings-proxyRules": "Proxy server", + "settings-proxyRules-desc": "Proxy URL or Chromium proxy rules. Examples: http://127.0.0.1:8080, socks5://127.0.0.1:1080, or http=proxy:80;https=proxy:80", + "settings-proxyPacScript": "PAC script URL", + "settings-proxyPacScript-desc": "URL of a proxy auto-config (PAC) file, e.g. http://wpad/wpad.dat or file:///path/to/proxy.pac", + "settings-proxyBypassRules": "Proxy bypass list", + "settings-proxyBypassRules-desc": "Comma-separated hosts that skip the proxy. Use for localhost. Example: ,*.intranet.example,10.0.0.0/8", "menu-about": "About Legcord", "menu-developerTools": "Developer tools", "menu-openSettings": "Open settings", @@ -203,10 +249,13 @@ "setup-welcomeTitle": "Welcome to Legcord", "setup-welcomeSubtitle": "Let's get you set up with your perfect configuration.", "setup-getStarted": "Get Started", + "setup-windowStyle-overlayTitle": "Overlay Titlebar", + "setup-windowStyle-overlayDesc": "A modern titlebar that blends into Discord. Recommended for most users.", "setup-windowStyle-nativeTitle": "Native Window", "setup-windowStyle-nativeDesc": "Use your system's default window decorations", "setup-windowStyle-customTitle": "Custom Titlebar", "setup-windowStyle-customDesc": "Use Legcord's custom titlebar design", + "setup-recommended": "Recommended", "setup-chooseWindowStyle": "Choose Window Style", "setup-selectAppearance": "Select how Legcord appears on your machine", "setup-systemTray": "System Tray", @@ -222,6 +271,8 @@ "setup-launchLegcord": "Launch Legcord", "setup-modSelectorTitle": "Choose Your Client Mod", "setup-modSelectorSubtitle": "Legcord includes Shelter out of the box, but you can also choose another client mod if wanted.", + "setup-shelterOnlyTitle": "Shelter Only", + "setup-shelterOnlyDesc": "Legcord was built around Shelter. Most typical users won't need another client mod.", "setup-vencordTitle": "Vencord", "setup-vencordDesc": "Client mod with plugins and themes.", "setup-equicordTitle": "Equicord", @@ -239,8 +290,6 @@ "settings-channel-stable": "Stable", "settings-channel-canary": "Canary", "settings-channel-ptb": "PTB", - "settings-category-powerManagement": "Power Management", - "settings-category-arrpc": "arRPC", "settings-extendedPluginAbilities": "Extended plugin abilities", "settings-extendedPluginAbilities-desc": "Allows plugins to read and write files in a scoped folder on your computer (e.g. for caching deleted messages). Only enable for plugins you trust—they can store data locally. Data is stored per plugin in Legcord's plugin-storage folder.", "settings-audio-loopback": "Loopback", @@ -259,6 +308,7 @@ "keybind-navigateBack": "Navigate back", "keybind-runJavascript": "Run Javascript", "keybind-openQuickCss": "Open Quick CSS", + "keybind-openSettings": "Open Settings", "keybind-globalNote": "Allows you to assign a specific keyboard shortcut that can be used across different applications and programs.", "keybind-global": "Global", "keybind-enabled": "Enabled", @@ -271,12 +321,21 @@ "detectable-appName": "App Name*", "detectable-appId": "App ID*", "detectable-themes": "Themes", + "detectable-themes-note": "Optional genre tags for this game, comma-separated.", "detectable-aliases": "Aliases", + "detectable-aliases-note": "Optional alternate names Discord may match, comma-separated.", + "detectable-appId-note": "Discord application ID from the Developer Portal for this game’s rich presence.", "detectable-enabled": "Enabled", "detectable-placeholderName": "e.g. Discord", "detectable-placeholderId": "e.g. 1234567890", "detectable-placeholderThemes": "Action, Adventure", "detectable-placeholderAliases": "Alias1, Alias2", + "themes-pageTitle": "Themes", + "themes-pageDesc": "Install BetterDiscord themes or write Quick CSS to customize Discord’s look. Themes are .theme.css files; Quick CSS is a single stylesheet you can edit anytime.", + "themes-empty": "No themes installed yet.", + "themes-emptyDesc": "Import a .theme.css file or paste a raw theme URL below. You can also browse community themes online.", + "themes-browseThemes": "Browse themes on BetterDiscord", + "themes-importUrlNote": "Paste a direct link to a raw .theme.css file (for example from GitHub).", "themes-success": "Success!", "themes-updated": "Theme successfully updated!", "themes-bdInstalled": "BD theme successfully installed!", @@ -289,22 +348,48 @@ "themes-importFromFile": "Import from file", "themes-openThemesFolder": "Open themes folder", "themes-import": "Import", + "themes-refresh": "Refresh", "themes-importUrlPlaceholder": "https://raw.githubusercontent.com/... [.theme.css]", + "themes-installed": "Installed Themes", + "keybinds-pageTitle": "Keybinds", + "keybinds-pageDesc": "Create keyboard shortcuts for Legcord actions like mute, deafen, or opening Quick CSS. Enable Global on a keybind to use it even when Discord is in the background.", + "keybinds-empty": "No keybinds added yet.", + "keybinds-emptyDesc": "Start by adding one with the button above.", "games-registeredGames": "Registered Games", + "games-pageDesc": "Manage custom games for Rich Presence (arRPC). Pick a running process, then set its Discord application ID. Changes usually need a restart to apply.", "games-refreshList": "Refresh list", "games-add": "Add", "games-remove": "Remove", "games-removeConfirmHeader": "Remove game?", "games-removeConfirmBody": "This game will be removed from rich presence. The client must be restarted for changes to take effect.", "games-noExecutables": "No executables", - "games-empty": "No registered games. Add one using the dropdown above.", + "games-empty": "No registered games yet.", + "games-emptyDesc": "Choose a process from the dropdown above, then click Add to register it for rich presence.", "games-lastDetected": "Last detected games", - "games-lastDetectedEmpty": "No games detected yet. Start a game with rich presence to see them here.", + "games-lastDetectedEmpty": "No games detected yet.", + "games-lastDetectedEmptyDesc": "Start a game with rich presence while Legcord is running to see it listed here.", "games-blacklist": "Blacklist", "games-blacklisted": "Blacklisted games", "games-blacklistedEmpty": "No blacklisted games.", + "games-blacklistedEmptyDesc": "Games you blacklist won’t show up in last detected.", "games-removeFromBlacklist": "Remove", "games-application": "Application", + "plugins-pageTitle": "Plugins", + "plugins-pageDesc": "Experimental filesystem plugins loaded from your Legcord plugins folder. Each plugin can run code in the main process, preload, and/or renderer. Only enable plugins you trust.", + "plugins-empty": "No runtime plugins found.", + "plugins-emptyDesc": "Open the plugins folder and add a plugin directory with a manifest.json, then refresh this list.", + "plugins-refresh": "Refresh list", + "plugins-openFolder": "Open plugins folder", + "plugins-reload": "Reload", + "plugins-targets": "Targets", + "plugins-targetsNone": "none", + "plugins-incompatible": "Plugin is not compatible.", + "plugins-toastTitle": "Plugins", + "plugins-toastEnableFailed": "Failed to enable {name}.", + "plugins-toastDisableFailed": "Failed to disable {name}.", + "plugins-toastReloaded": "Reloaded {name}.", + "plugins-toastReloadFailed": "Failed to reload {name}.", + "plugins-toastIncompatible": "{name} is not compatible with this Legcord version.", "screenshare-selectSource": "Please select a source", "screenshare-venmicDisabled": "Venmic disabled", "screenshare-share": "Share", diff --git a/assets/lang/es_419.json b/assets/lang/es_419.json index 84674ae..0a79cce 100644 --- a/assets/lang/es_419.json +++ b/assets/lang/es_419.json @@ -27,7 +27,7 @@ "settings-transparency-universal": "Universal", "settings-transparency-modern": "Moderna", "settings-theme-transparent": "Transparente", - "settings-transparency-tahoe-warning": "La transparencia puede provocar lag excesivo en MacOS 26 Tahoe.", + "settings-transparency-tahoe-warning": "La transparencia puede provocar lag excesivo en macOS 26 Tahoe.", "settings-popoutPiP": "Ventana emergente siempre visible", "settings-popoutPiP-desc": "Cuanto está habilitado, la ventana emergente estará en modo siempre visible.", "settings-venmic-workaround": "Workaraound", @@ -52,8 +52,8 @@ "settings-csp-desc": "Legcord CSP es nuestro sistema que gestiona la carga de contenido personalizado en la aplicación Discord. Elementos como los mods y los temas del cliente dependen de él. Desactívalo si quieres deshacerte de los mods y los estilos personalizados.", "settings-mintoTray": "Trabajar en segundo plano", "settings-mintoTray-desc": "Cuando está desactivado, Legcord se cerrará como cualquier otra ventana al cerrarlo; de lo contrario, permanecerá en la bandeja del sistema para su uso posterior.", - "settings-startMinimized": "Iniciar minimizado", - "settings-startMinimized-desc": "Legcord se inicia en segundo plano y no interfiere en tu trabajo.", + "settings-startMinimized": "Ventana al iniciar", + "settings-startMinimized-desc": "Elige cómo aparece Legcord al iniciar. El modo bandeja oculta la ventana por completo (hace falta el icono de bandeja).", "settings-useSystemCssEditor": "Utilizar el editor CSS del sistema", "settings-useSystemCssEditor-desc": "Utilice el editor CSS del sistema para editar CSS.", "settings-MultiInstance": "Múltiples instancias", @@ -95,7 +95,12 @@ "settings-prfmMode": "Modo rendimiento", "settings-prfmMode-desc": "El modo de rendimiento es una función experimental de Legcord diseñada para optimizar la capacidad de respuesta y el rendimiento en función de tus necesidades. El impacto puede variar en función de tu hardware y uso, por lo que te recomendamos que pruebes cada modo para determinar cuál te conviene más.", "settings-prfmMode-performance": "Rendimiento", + "settings-prfmMode-balanced": "Equilibrado", "settings-prfmMode-battery": "Batería", + "settings-prfmMode-memory": "Ahorro de memoria", + "settings-prfmMode-voip": "Voz y vídeo", + "settings-prfmMode-latency": "Baja latencia", + "settings-prfmMode-smoothScreenshare": "Compartir pantalla fluido", "settings-prfmMode-dynamic": "Dinámico", "settings-prfmMode-vaapi": "VAAPI", "settings-disableAutogain": "Desactivar ganancia automática", @@ -298,5 +303,9 @@ "games-removeFromBlacklist": "Eliminar", "games-application": "Aplicación", "settings-vaapi": "VAAPI", - "settings-vaapi-desc": "Utiliza VAAPI (aceleración por hardware) para la decodificación de vídeo en Linux. Esto reduce considerablemente el uso de la CPU durante el uso compartido de pantalla, pero puede causar problemas en algunos sistemas. Desactívalo si experimentas bloqueos o pantallas en negro durante el uso compartido de pantalla." + "settings-vaapi-desc": "Utiliza VAAPI (aceleración por hardware) para la decodificación de vídeo en Linux. Esto reduce considerablemente el uso de la CPU durante el uso compartido de pantalla, pero puede causar problemas en algunos sistemas. Desactívalo si experimentas bloqueos o pantallas en negro durante el uso compartido de pantalla.", + "settings-material": "Material de Ventana", + "settings-startMinimized-off": "Normal", + "settings-startMinimized-minimized": "Minimizada en la barra de tareas", + "settings-startMinimized-tray": "Oculta en la bandeja" } diff --git a/assets/lang/fr.json b/assets/lang/fr.json index 734ec4d..250aea6 100644 --- a/assets/lang/fr.json +++ b/assets/lang/fr.json @@ -19,7 +19,7 @@ "settings-transparency-universal": "Universel", "settings-transparency-modern": "Moderne", "settings-theme-transparent": "Transparent", - "settings-transparency-tahoe-warning": "La transparence peut causer un lag excessif sur MacOS 26 Tahoe.", + "settings-transparency-tahoe-warning": "La transparence peut causer un lag excessif sur macOS 26 Tahoe.", "settings-venmic-deviceSelect": "Sélection du périphérique", "settings-venmic-deviceSelect-desc": "Autoriser la sélection d'un périphérique audio.", "settings-venmic-granularSelect-desc": "Autoriser la sélection d'une source d'entrée audio.", @@ -36,7 +36,7 @@ "settings-audio-loopback": "Loopback", "settings-audio-loopbackWithMute": "Loopback avec sourdine", "settings-openCustomIconDialog": "Définir une icône de bureau", - "settings-startMinimized-desc": "Legcord démarre en arrière-plan sans vous déranger.", + "settings-startMinimized-desc": "Choisit comment Legcord apparaît au lancement. Le mode tray masque complètement la fenêtre (icône de tray requise).", "settings-useSystemCssEditor": "Utiliser l'éditeur CSS du système", "settings-useSystemCssEditor-desc": "Utiliser l'éditeur CSS du système pour modifier le CSS.", "settings-MultiInstance": "Multi-instances", @@ -57,7 +57,12 @@ "settings-prfmMode": "Mode performance", "settings-prfmMode-desc": "Le mode performance est une fonctionnalité expérimentale de Legcord conçue pour optimiser la réactivité et les performances selon vos besoins. Son impact peut varier selon votre matériel et votre utilisation, c'est pourquoi nous vous encourageons à essayer chaque mode pour déterminer lequel vous correspond le mieux.", "settings-prfmMode-performance": "Performance", + "settings-prfmMode-balanced": "Équilibré", "settings-prfmMode-battery": "Batterie", + "settings-prfmMode-memory": "Économie mémoire", + "settings-prfmMode-voip": "Voix et vidéo", + "settings-prfmMode-latency": "Faible latence", + "settings-prfmMode-smoothScreenshare": "Partage d'écran fluide", "settings-prfmMode-dynamic": "Dynamique", "settings-prfmMode-vaapi": "VAAPI", "settings-disableHttpCache": "Désactiver le cache HTTP", @@ -104,7 +109,7 @@ "settings-csp-desc": "Legcord CSP est notre système qui gère le chargement du contenu personnalisé dans l'application Discord. Des éléments tels que les mods et les thèmes en dépendent. Désactivez-le si vous souhaitez vous débarrasser des mods et des styles personnalisés.", "settings-mintoTray": "Actif en arrière-plan", "settings-mintoTray-desc": "Si désactivé, Legcord se fermera comme n'importe quelle autre fenêtre, sinon il restera actif dans la barre d'état pour plus tard.", - "settings-startMinimized": "Démarrer en mode minimisé", + "settings-startMinimized": "Fenêtre au démarrage", "settings-noBundleUpdates": "Pas de mises à jour", "settings-noBundleUpdates-desc": "Désactive les mises à jour automatique des mods.", "settings-mobileMode-desc": "Si vous êtes sur un appareil doté d'un écran tactile cette fonctionnalité est faite pour vous ! Elle active le mode mobile caché de Discord conçu pour les téléphones et tablettes. La seule fonction majeure manquante est le tchat vocal. Idéal pour les utilisateurs de PinePhone ou équivalents.", @@ -339,5 +344,8 @@ "supportBanner-title": "Soutenir le projet", "supportBanner-subtitle": "Aidez-nous à continuer le développement de Legcord. Votre soutien permet de maintenir le projet en vie et nous permet de proposer plus de fonctionnalités.", "supportBanner-donate": "Faire un don", - "keybind-enabled": "Activé" + "keybind-enabled": "Activé", + "settings-startMinimized-off": "Normale", + "settings-startMinimized-minimized": "Réduite dans la barre des tâches", + "settings-startMinimized-tray": "Masquée dans le tray" } diff --git a/assets/lang/hu.json b/assets/lang/hu.json index 383e77a..af2ec99 100644 --- a/assets/lang/hu.json +++ b/assets/lang/hu.json @@ -27,7 +27,7 @@ "settings-theme-desc": "Az ablakstílus kezeli, hogy a Legcord milyen fejlécet használ.", "settings-sleepInBackground-desc": "Engedélyezi a Chromium háttérben történő lassítását. Ez segíthet az akkumulátor élettartamának megőrzésében, de egyben megszünteti az értesítéseket.", "settings-transparency-desc": "Állítsd be, milyen átlátszósági módot használjon a Legcord.", - "settings-transparency-tahoe-warning": "Az átlátszóság késleltetést okozhat MacOS 26 Tahoe rendszeren.", + "settings-transparency-tahoe-warning": "Az átlátszóság késleltetést okozhat macOS 26 Tahoe rendszeren.", "settings-popoutPiP": "A hívás felugró ablaka mindig felül", "settings-popoutPiP-desc": "Ha engedélyezve van, a hívás felugró ablaka mindig felül lesz.", "settings-venmic-workaround": "Ideiglenes megoldás", @@ -48,11 +48,11 @@ "settings-audio": "Hang", "settings-audio-desc": "Válassza ki, hogy a Legcord melyik módszert használja a hang rögzítéséhez a képernyőmegosztás közben.", "settings-openCustomIconDialog": "Asztali ikon beállítása", - "settings-csp-desc": "A Legcord CSP kezeli az egyéni tartalmak Discord alkalmazásba való betöltését. Olyan dolgok, mint a kliens bővítmények és témák, ettől függenek. Kapcsold ki, ha meg szeretnél szabadulni a bővítményektől és az egyéni stílusoktól.", + "settings-csp-desc": "Állítsd be a Legcord tartalombiztonsági szabályzatának szigorúságát. A szigorú CSP jobb biztonságot nyújt, de kompatibilitási problémákat okozhat egyes kliens modokkal/témákkal/bővítményekkel.", "settings-mintoTray": "Futás a háttérben", "settings-mintoTray-desc": "Ha le van tiltva, a Legcord a többi ablakhoz hasonlóan bezáródik, különben csak a tálcára csukódik le.", - "settings-startMinimized": "Kisablakos indítás", - "settings-startMinimized-desc": "A Legcord a háttérben indul el, és nem zavar.", + "settings-startMinimized": "Induló ablak", + "settings-startMinimized-desc": "Meghatározza, hogyan jelenik meg a Legcord indításkor. A tálca mód teljesen elrejti az ablakot (tálcaikon szükséges).", "settings-useSystemCssEditor": "Használja a rendszer CSS-szerkesztőjét", "settings-useSystemCssEditor-desc": "A CSS szerkesztéséhez használja a rendszer CSS-szerkesztőjét.", "settings-MultiInstance": "Több példány", @@ -83,8 +83,8 @@ "settings-bitrateTarget-desc": "Cél bitráta képernyőmegosztáshoz.", "settings-invitewebsocket": "Rich Presence", "settings-invitewebsocket-desc": "Az arRPC-t használja a Discord RPC (Rich Presence) támogatásához a gépeden futó helyi programokkal.", - "settings-useMacSystemPicker": "MacOS rendszerválasztó használata", - "settings-useMacSystemPicker-desc": "Amikor csak lehetséges, natív MacOS képernyőmegosztást használjon. Csak MacOS 15+ rendszeren.", + "settings-useMacSystemPicker": "macOS rendszerválasztó használata", + "settings-useMacSystemPicker-desc": "Amikor csak lehetséges, natív macOS képernyőmegosztást használjon. Csak macOS 15+ rendszeren.", "settings-additionalArguments": "További argumentumok", "settings-additionalArguments-desc": "A további argumentumok extra parancsok, amelyeket átadhatsz a Legcordnak. Használhatók funkciók engedélyezésére vagy letiltására, illetve problémák megoldására.", "settings-mod": "Kliens bővítmény", @@ -94,7 +94,12 @@ "settings-prfmMode": "Teljesítmény mód", "settings-prfmMode-desc": "A Teljesítmény mód egy kísérleti funkció a Legcordban, melynek célja a válaszidő és a teljesítmény optimalizálása az Ön igényei alapján. A hatás a hardvertől és a használattól függően változhat, ezért javasoljuk, hogy próbálja ki az egyes módokat, hogy megállapítsa, melyik működik legjobban az Ön számára.", "settings-prfmMode-performance": "Teljesítmény", + "settings-prfmMode-balanced": "Kiegyensúlyozott", "settings-prfmMode-battery": "Akkumulátor", + "settings-prfmMode-memory": "Memóriatakarékos", + "settings-prfmMode-voip": "Hang és videó", + "settings-prfmMode-latency": "Alacsony késleltetés", + "settings-prfmMode-smoothScreenshare": "Sima képernyőmegosztás", "settings-prfmMode-dynamic": "Dinamikus", "settings-prfmMode-vaapi": "VAAPI", "settings-disableAutogain": "Automatikus erősítés letiltása", @@ -290,9 +295,9 @@ "touchbar-servers": "Szerverek", "splash-title": "Legcord", "settings-venmic-granularSelect": "Részletes kiválasztás", - "settings-trayIcon-white-plug-alt": "Fehér Plug alternatíva", - "settings-trayIcon-black-plug": "Fekete Plug", - "settings-trayIcon-black-plug-alt": "Fekete Plug alternatíva", + "settings-trayIcon-white-plug-alt": "Fehér csatlakozó alternatíva", + "settings-trayIcon-black-plug": "Fekete csatlakozó", + "settings-trayIcon-black-plug-alt": "Fekete csatlakozó alternatíva", "menu-redo": "Újra", "setup-stepOf": "{current} / {total} lépés", "keybind-deafen": "Süketítés", @@ -339,5 +344,15 @@ "settings-material-mica": "Mica", "settings-material-mica-alt": "Mica Alt", "settings-material-acrylic": "Akril", - "settings-material-none": "None" + "settings-material-none": "Egyik sem", + "settings-csp-vanilla": "Vanilla", + "settings-csp": "Tartalombiztonsági irányelv", + "settings-csp-strict": "Szigorú", + "settings-csp-none": "Egyik sem", + "keybind-openSettings": "Beállítások megnyitása", + "settings-firstTimeCrash": "Mindent előkészítünk számodra!", + "settings-firstTimeCrash-desc": "Az első indításkor a beállítások még nem érhetők el. Kérjük, használd az alábbi gombot az újraindításhoz, és a beállítások az újraindítás után már elérhetőek lesznek.", + "settings-startMinimized-off": "Normál", + "settings-startMinimized-minimized": "Kis méretű a tálcán", + "settings-startMinimized-tray": "Elrejtve a rendszertálcán" } diff --git a/assets/lang/id.json b/assets/lang/id.json index 28144f7..569c1a5 100644 --- a/assets/lang/id.json +++ b/assets/lang/id.json @@ -27,7 +27,7 @@ "settings-transparency-universal": "Universal", "settings-transparency-modern": "Modern", "settings-theme-transparent": "Transparan", - "settings-transparency-tahoe-warning": "Transparansi dapat menyebabkan lag berlebihan pada MacOS 26 Tahoe.", + "settings-transparency-tahoe-warning": "Transparansi dapat menyebabkan lag berlebihan pada macOS 26 Tahoe.", "settings-popoutPiP": "Panggilan Popout Selalu di Atas", "settings-popoutPiP-desc": "Saat diaktifkan, jendela popout panggilan akan berada dalam mode Selalu di Atas.", "settings-venmic-workaround": "Solusi sementara", @@ -49,11 +49,11 @@ "settings-audio": "Audio", "settings-audio-desc": "Pilih metode yang digunakan Legcord untuk mengambil audio dari sistem Anda selama berbagi layar.", "settings-openCustomIconDialog": "Atur ikon desktop", - "settings-csp-desc": "Legcord CSP adalah sistem kami yang mengelola pemuatan konten kustom ke dalam aplikasi Discord. Fitur seperti mod klien dan tema bergantung padanya. Nonaktifkan jika Anda ingin menghapus mod dan gaya kustom.", + "settings-csp-desc": "Atur tingkat keketatan Kebijakan Keamanan Konten Legcord. CSP ketat memberikan keamanan lebih baik tetapi dapat menyebabkan masalah kompatibilitas dengan beberapa mod/tema/plugin klien.", "settings-mintoTray": "Bekerja di latar belakang", "settings-mintoTray-desc": "Ketika dinonaktifkan, Legcord akan ditutup seperti jendela lainnya saat ditutup, sedangkan jika tidak, ia akan tetap berada di area sistem tray Anda untuk digunakan nanti.", - "settings-startMinimized": "Mulai dalam mode minimized", - "settings-startMinimized-desc": "Legcord berjalan di latar belakang dan tidak mengganggu Anda.", + "settings-startMinimized": "Jendela saat mulai", + "settings-startMinimized-desc": "Pilih bagaimana Legcord muncul saat diluncurkan. Mode tray menyembunyikan jendela sepenuhnya (ikon tray harus diaktifkan).", "settings-useSystemCssEditor": "Gunakan editor CSS sistem", "settings-useSystemCssEditor-desc": "Gunakan editor CSS sistem untuk mengedit CSS.", "settings-MultiInstance": "Multi Instans", @@ -89,7 +89,12 @@ "settings-prfmMode": "Mode kinerja", "settings-prfmMode-desc": "Mode Kinerja adalah fitur eksperimental di Legcord yang dirancang untuk mengoptimalkan responsivitas dan kinerja sesuai dengan kebutuhan Anda. Dampak yang dihasilkan dapat bervariasi tergantung pada spesifikasi perangkat keras dan pola penggunaan Anda, jadi kami menyarankan Anda untuk mencoba setiap mode untuk menentukan mana yang paling sesuai dengan kebutuhan Anda.", "settings-prfmMode-performance": "Kinerja", + "settings-prfmMode-balanced": "Seimbang", "settings-prfmMode-battery": "Baterai", + "settings-prfmMode-memory": "Penghemat memori", + "settings-prfmMode-voip": "Suara & video", + "settings-prfmMode-latency": "Latensi rendah", + "settings-prfmMode-smoothScreenshare": "Berbagi layar mulus", "settings-prfmMode-dynamic": "Dinamis", "settings-prfmMode-vaapi": "VAAPI", "settings-disableAutogain": "Nonaktifkan autogain", @@ -286,5 +291,65 @@ "contextMenu-searchGoogle": "Cari dengan Google", "contextMenu-searchDuckDuckGo": "Cari dengan DuckDuckGo", "touchbar-servers": "Server", - "splash-title": "Legcord" + "splash-title": "Legcord", + "settings-material": "Material Jendela", + "settings-material-desc": "Atur material latar belakang Jendela yang digunakan Legcord.", + "settings-material-mica": "Mica", + "settings-material-mica-alt": "Mica Alt", + "settings-material-acrylic": "Acrylic", + "settings-material-none": "Tidak ada", + "settings-csp": "Kebijakan Keamanan Konten", + "settings-csp-strict": "Ketat", + "settings-csp-none": "Tidak ada", + "settings-csp-vanilla": "Vanilla", + "settings-automaticClientUpdates": "Pembaruan klien otomatis", + "settings-automaticClientUpdates-desc": "Menonaktifkan pembaruan Legcord otomatis", + "settings-vaapi": "VAAPI", + "settings-vaapi-desc": "Gunakan VAAPI (akselerasi HW) untuk decoding video di Linux. Ini sangat mengurangi penggunaan CPU selama berbagi layar tetapi dapat menyebabkan masalah pada beberapa sistem. Nonaktifkan jika Anda mengalami crash atau layar hitam selama berbagi layar.", + "settings-mod-shelter": "Shelter", + "settings-mod-custom": "Kustom", + "settings-quickCss": "CSS Cepat", + "settings-quickCss-desc": "Edit CSS Anda dengan cepat di editor teks sederhana. Perubahan diterapkan segera setelah menyimpan file.", + "keybind-pushToTalk": "Tekan untuk berbicara", + "games-lastDetected": "Game yang terakhir terdeteksi", + "games-lastDetectedEmpty": "Belum ada game yang terdeteksi. Mulai game dengan rich presence untuk melihatnya di sini.", + "games-blacklist": "Daftar hitam", + "games-blacklisted": "Game yang masuk daftar hitam", + "games-blacklistedEmpty": "Tidak ada game yang masuk daftar hitam.", + "games-removeFromBlacklist": "Hapus", + "games-application": "Aplikasi", + "backup-dialogSave-title": "Simpan cadangan Legcord", + "backup-dialogOpen-title": "Buka cadangan Legcord", + "backup-pageTitle": "Cadangan dan pemulihan", + "backup-pageSubtitle": "Simpan atau pulihkan pengaturan Legcord Anda, termasuk setelan, tema, plugin, dan data mod—semua dalam satu file.", + "backup-createBackup": "Buat cadangan", + "backup-restore": "Pulihkan", + "backup-modalTitle": "Pilih apa yang masuk ke dalam cadangan ini", + "backup-includeLegcordConfig": "Setelan", + "backup-includeLegcordThemes": "Tema dan CSS Cepat", + "backup-includeLegcordPlugins": "Ekstensi Chrome/Penyimpanan plugin", + "backup-includeVencord": "Data Vencord (sesi saat ini)", + "backup-includeEquicord": "Data Equicord (sesi saat ini)", + "backup-includeShelter": "Plugin Shelter", + "backup-includeModBundles": "File mod klien yang diunduh (Vencord, Equicord, Shelter, bundel kustom)", + "backup-confirmBackup": "Ekspor", + "backup-successTitle": "Cadangan tersimpan", + "backup-successBody": "Cadangan Anda telah berhasil disimpan.", + "backup-cancelledTitle": "Dibatalkan", + "backup-cancelledBody": "Tidak ada file yang disimpan.", + "backup-failedTitle": "Cadangan gagal", + "backup-invalidFile": "Tidak dapat membaca file cadangan tersebut.", + "backup-unknownError": "Terjadi kesalahan.", + "backup-restoreConfirmHeader": "Pulihkan dari cadangan?", + "backup-restoreConfirmBody": "File di disk akan diganti di mana cadangan ini memiliki data. Anda mungkin perlu memulai ulang Legcord agar semua perubahan diterapkan.", + "backup-restoreConfirm": "Pulihkan", + "backup-restoreCancel": "Batal", + "backup-restoreDoneTitle": "Pemulihan selesai", + "backup-restoreDoneBody": "Data Anda telah dipulihkan. Mulai ulang Legcord agar semua perubahan berlaku.", + "supportBanner-title": "Dukung Proyek", + "supportBanner-subtitle": "Bantu kami terus mengembangkan Legcord. Dukungan Anda menjaga proyek tetap hidup dan memungkinkan kami menghadirkan lebih banyak fitur.", + "supportBanner-donate": "Donasi", + "settings-startMinimized-off": "Normal", + "settings-startMinimized-minimized": "Diminimalkan ke bilah tugas", + "settings-startMinimized-tray": "Tersembunyi di tray" } diff --git a/assets/lang/ja.json b/assets/lang/ja.json index bc37a7a..715c6ac 100644 --- a/assets/lang/ja.json +++ b/assets/lang/ja.json @@ -31,6 +31,6 @@ "settings-transparency-desc": "Legcordの透明化モードを設定します。", "settings-transparency-universal": "ユニバーサル", "settings-transparency-modern": "モダン", - "settings-transparency-tahoe-warning": "MacOS 26 Tahoeにおいて、透明化は過度なラグを引き起こす可能性があります。", + "settings-transparency-tahoe-warning": "macOS 26 Tahoeにおいて、透明化は過度なラグを引き起こす可能性があります。", "detectable-themes": "テーマ" } diff --git a/assets/lang/pt_BR.json b/assets/lang/pt_BR.json index 4dd2a74..ae39f11 100644 --- a/assets/lang/pt_BR.json +++ b/assets/lang/pt_BR.json @@ -31,7 +31,7 @@ "settings-sleepInBackground": "Descansar em segundo plano", "settings-sleepInBackground-desc": "Ativa a limitação de recursos do Chromium em segundo plano. Isso pode ajudar com economia de bateria, mas pode quebrar funcionalidade das notificações.", "settings-transparency-modern": "Moderno", - "settings-transparency-tahoe-warning": "Transparência pode causar perda excessiva de performance em MacOS 26 (Tahoe).", + "settings-transparency-tahoe-warning": "Transparência pode causar perda excessiva de performance em macOS 26 (Tahoe).", "settings-venmic-workaround": "Solução alternativa/temporária", "settings-venmic-workaround-desc": "Ativa ou desativa a solução alternativa para um problema que causa o microfone ser compartilhado, invés do áudio escolhido.", "settings-venmic-deviceSelect": "Escolha o dispositivo", @@ -100,8 +100,8 @@ "settings-csp-desc": "\"Legcord CSP\" é o nosso sistema que cuida do carregamento de conteúdo customizado dentro do cliente do DIscord. Coisas como modificações e temas dependem desse sistema. Desabilite se quiser se livrar de modificações e estilos customizados.", "settings-mintoTray": "Funcionar em segundo plano", "settings-mintoTray-desc": "Quando desabilitado, Legcord será fechado como qualquer outra janela, do contrário, ele funcionará em segundo plano e ficará na bandeja do sistema disponível a qualquer momento.", - "settings-startMinimized": "Abrir minimizado", - "settings-startMinimized-desc": "Legcord inicia em segundo plano e fica fora do seu caminho.", + "settings-startMinimized": "Janela ao iniciar", + "settings-startMinimized-desc": "Escolha como o Legcord aparece ao iniciar. O modo bandeja oculta a janela por completo (é preciso o ícone da bandeja).", "settings-useSystemCssEditor": "Usar editor de estilo (CSS) do sistema", "settings-useSystemCssEditor-desc": "Usar editor de estilo padrão do sistema para editar CSS.", "settings-MultiInstance": "Múltiplas instâncias", @@ -145,7 +145,12 @@ "settings-prfmMode": "Modo de performance", "settings-prfmMode-desc": "Modo de performance é uma funcionalidade experimental do Legcord feita para otimizar responsitividade e performance baseado nas suas nescessidades. Impacto pode variar dependendo da configuração da sua máquina e seu uso, então recomendamos tentar cada modo e escolher um que sirva melhor para você.", "settings-prfmMode-performance": "Performance", + "settings-prfmMode-balanced": "Equilibrado", "settings-prfmMode-battery": "Bateria", + "settings-prfmMode-memory": "Economia de memória", + "settings-prfmMode-voip": "Voz e vídeo", + "settings-prfmMode-latency": "Baixa latência", + "settings-prfmMode-smoothScreenshare": "Compartilhamento de tela suave", "settings-prfmMode-dynamic": "Dinâmico", "settings-prfmMode-vaapi": "VAAPI", "settings-disableAutogain": "Desabilitar ganho automático", @@ -245,5 +250,8 @@ "setup-trayEnableDesc": "Mostrar o Legcord na bandeja do sistema", "setup-trayDisableTitle": "Desabilitar ícone de bandeja", "setup-trayDisableDesc": "Não mostrar o Legcord na bandeja do sistema", - "setup-finishTitle": "Você está pronto!" + "setup-finishTitle": "Você está pronto!", + "settings-startMinimized-off": "Normal", + "settings-startMinimized-minimized": "Minimizado na barra de tarefas", + "settings-startMinimized-tray": "Oculto na bandeja" } diff --git a/assets/lang/pt_PT.json b/assets/lang/pt_PT.json index f0807ff..f1173d5 100644 --- a/assets/lang/pt_PT.json +++ b/assets/lang/pt_PT.json @@ -25,7 +25,7 @@ "settings-transparency-universal": "Universal", "settings-transparency-modern": "Moderno", "settings-theme-transparent": "Transparente", - "settings-transparency-tahoe-warning": "Transparência pode causar perda excessiva de performance em MacOS 26 (Tahoe).", + "settings-transparency-tahoe-warning": "Transparência pode causar perda excessiva de performance em macOS 26 (Tahoe).", "settings-popoutPiP": "Elevação de Chamada sempre acima", "settings-venmic-workaround": "Solução alternativa/temporária", "settings-venmic-workaround-desc": "Ativa ou desativa a solução alternativa para um problema que causa o microfone ser partilhado, invés do áudio escolhido.", @@ -45,7 +45,12 @@ "settings-audio-desc": "Selecione o método que o Legcord usa para capturar o áudio do seu sistema durante o partilhamento de ecrã.", "settings-prfmMode": "Modo de desempenho", "settings-prfmMode-performance": "Desempenho", + "settings-prfmMode-balanced": "Equilibrado", "settings-prfmMode-dynamic": "Dinâmico", + "settings-prfmMode-latency": "Baixa latência", + "settings-prfmMode-memory": "Poupança de memória", + "settings-prfmMode-voip": "Voz e vídeo", + "settings-prfmMode-smoothScreenshare": "Partilha de ecrã fluida", "settings-none": "Nenjum", "settings-save": "Gravar configurações", "settings-restart": "Reiniciar a app", @@ -120,5 +125,234 @@ "contextMenu-searchGoogle": "Pesquisar com Google", "contextMenu-searchDuckDuckGo": "Pesquisar com DuckDuckGo", "touchbar-servers": "Servidores", - "splash-title": "Legcord" + "splash-title": "Legcord", + "settings-bounceOnPing": "Agitar na barra de tarefas às notificações", + "settings-bounceOnPing-desc": "Agitar a app na barra de tarefas quando receber uma notificação.", + "settings-material-none": "Nenhum", + "settings-popoutPiP-desc": "Quando ativado, a elevação da chamada atual sempre ficará acima de outros elementos.", + "settings-venmic-ignoreInputMedia": "Ignorar média de entrada", + "settings-venmic-onlyDefaultSpeakers-desc": "Usar apenas alto-falantes para seleção de áudio.", + "settings-openCustomIconDialog": "Definir ícone de desktop", + "settings-mintoTray": "Funcionar em segundo plano", + "settings-mintoTray-desc": "Quando desativado, Legcord será fechado como qualquer outra janela, do contrário, ele funcionará em segundo plano e ficará na bandeja do sistema disponível a qualquer momento.", + "settings-startMinimized": "Janela ao iniciar", + "settings-startMinimized-desc": "Escolha como o Legcord aparece ao iniciar. O modo tabuleiro oculta a janela por completo (é preciso o ícone do tabuleiro).", + "settings-csp-none": "Nenhum", + "settings-useSystemCssEditor": "Usar editor de estilo (CSS) do sistema", + "settings-useSystemCssEditor-desc": "Usar editor de estilo padrão do sistema para editar CSS.", + "settings-MultiInstance": "Múltiplas instâncias", + "settings-MultiInstance-desc": "Quando ativado, poderá iniciar quantas instâncias do Legcord que quiser, ao mesmo tempo.", + "settings-noBundleUpdates": "Sem updates em pacotes", + "settings-noBundleUpdates-desc": "Desativa updates automáticos para mods deste cliente.", + "settings-hardwareAcceleration": "Aceleração de Hardware", + "settings-hardwareAcceleration-desc": "Aceleração de Hardware usa a sua GPU para ajudar no desempenho gráfico. Se experienciar problemas ou bugs visuais, tente desativar esta opção.", + "settings-processScanning": "Escaneamento de processos ativos", + "settings-processScanning-desc": "Ativa o escaneamento de processos para encontrar jogos que executam para melhorar a detecção do RichPresence.", + "settings-windowsLegacyScanning": "Escaneamento antigo do Windows", + "settings-windowsLegacyScanning-desc": "Usa o escaneamento de processos antigo do Windows (prév. v1.1.6). Pode ajudar a compatibilidade de alguns sistemas mas esse método é menos eficiente.", + "settings-scanInterval": "Intervalo de escaneamento (ms)", + "settings-scanInterval-desc": "Configura o quão frequente (em milisegundos) o escaneamento de processos ocorre. Valores menores podem melhorar a rapidez da detecção de processos, mas vão aumentar o uso do processador.", + "settings-blockPowerSavingInVoiceChat": "Impedir economia de pilha em chats de voz", + "settings-blockPowerSavingInVoiceChat-desc": "Impede Legcord de ser suspenso. Mantém o sistema ativo mas permite que o ecrã seja desligado/descansado.", + "settings-mobileMode": "Modo de telemóvel", + "settings-mobileMode-desc": "Se está num dispositivo sensível ao toque, esta função é para si! Ativa a opção oculta do Discord para dispositivos móveis como tablets e telemóveis. Única função importante que falta é compatibilidade com chat de voz. Esta opção é ideal para\n utilizadores de PinePhone e outros.", + "settings-spellcheck": "Corretor automático", + "settings-spellcheck-desc": "Ajuda a corrigir palavras escritas incorretamente sublinhando-as.", + "settings-vaapi": "VAAPI", + "settings-vaapi-desc": "Use VAAPI (aceleração de hardware) para fazer decodificação de vídeo no Linux. Esta opção ajuda a reduzir drásticamente o uso de CPU durante o compartilhamento de ecrã, mas pode causar problemas em alguns sitemas. Desative esta opção caso expirencie travamentos ou \"ecrã-preto\" enquanto partilhar o ecrã.", + "settings-channel": "Canal do Discord", + "settings-channel-desc": "Ative esta configuração para mudar a instância atual do Discord que o Legcord está a usar.", + "settings-bitrateMin": "Birate mínimo", + "settings-bitrateMin-desc": "Bitrate mínimo para compartilhamento do ecrã.", + "settings-bitrateMax": "Bitrate máximo", + "settings-bitrateMax-desc": "Bitrate máximo para compartilhamento do ecrã.", + "settings-bitrateTarget": "Bitrate Alvo", + "settings-bitrateTarget-desc": "Bitrate alvo para compartilhamento do ecrã.", + "settings-invitewebsocket": "Rich Presence", + "settings-invitewebsocket-desc": "Usa arRPC para a função da Rich Presence do Discord com programas locais da sua máquina.", + "settings-useMacSystemPicker": "Usar o seletor de sistema padrão do macOS", + "settings-useMacSystemPicker-desc": "Usa o partilhamento de ecrã nativo do macOS quando possível. Apenas para macOS 15+", + "settings-additionalArguments": "Argumentos adicionais", + "settings-additionalArguments-desc": "Argumentos adicionais são comandos extras que pode adicionar ao Legcord. Eles podem ser usados para ativar ou desativar funções ou corrigir problemas.", + "settings-mod": "Modificação de Cliente", + "settings-mod-desc1": "Mods do cliente são programas que permitem customizar a sua experiência no Discord. Mods podem mudar a aparência do cliente, modificar comportamentos e até adicionar novas funcionalidades!", + "settings-mod-vencord": "Mod leve e fácil de usar. Vem com uma loja integrada para plugins.", + "settings-mod-equicord": "Nascido de uma fork de contribuidores do Vencord, traz um cliente rico em plugins.", + "settings-prfmMode-desc": "Modo de performance é uma funcionalidade experimental do Legcord feita para otimizar responsitividade e performance baseado nas suas nescessidades. Impacto pode variar dependendo da configuração da sua máquina e o seu uso, então recomendamos tentar cada modo e escolher um que sirva melhor para si.", + "settings-prfmMode-battery": "Pilha", + "settings-prfmMode-vaapi": "VAAPI", + "settings-disableAutogain": "Desativar ganho automático", + "settings-disableAutogain-desc": "Desativa ganho automático.", + "settings-disableHttpCache": "Desativar cache HTTP", + "settings-disableHttpCache-desc": "Desativa o cache HTTP do Chromium. Desative esta opção se mods não carregarem.", + "settings-trayIcon": "Ícone de bandeja", + "settings-trayIcon-desc": "Escolha um ícone de bandeja.", + "settings-trayIcon-disabled": "Desativar a bandeja", + "settings-trayIcon-dynamic": "Dinâmico", + "settings-trayIcon-normal": "Ícone do Discord", + "settings-trayIcon-classic": "Ícone clássico do Discord", + "settings-trayIcon-colored-plug": "Tomada colorida", + "settings-trayIcon-white-plug": "Tomada branca", + "settings-trayIcon-white-plug-alt": "Tomada branca (alternativa)", + "settings-trayIcon-black-plug": "Tomada preta", + "settings-trayIcon-black-plug-alt": "Tomada preta (alternativa)", + "settings-advanced": "Zona para utilizadores avançados", + "settings-pluginsFolder": "Abrir pasta de plugins", + "settings-crashesFolder": "Abrir pasta de crashes nativa", + "settings-themesFolder": "Abrir pasta de temas", + "settings-storageFolder": "Abrir pasta de armazenamento", + "settings-updater": "Verificar por updates", + "settings-skipSplash": "Pular ecrã de introdução", + "settings-skipSplash-desc": "Pula a ecrã de introdução do Legcord quando você o inicia.", + "settings-copyDebugInfo": "Copiar informação de debug", + "settings-copyGPUInfo": "Copiar informação de GPU", + "settings-clearClientModCache": "Limpar o cache de mods do cliente", + "settings-forceNativeCrash": "Forçar crash nativo", + "settings-smoothScroll": "Usar rolamento suave", + "settings-smoothScroll-desc": "Ativa o rolamento suave", + "settings-autoScroll": "Ativar rolamento automático", + "settings-autoScroll-desc": "Ativa o rolamento automático com o clique do meio do rato (Obs. O seu ambiente desktop ainda pode controlar esta operação com outra ação)", + "settings-quickCss": "CSS Rápido", + "settings-quickCss-desc": "Rapidamente edite o CSS do seu cliente com um editor de texto simples. Mudanças são aplicadas imediatamente depois de gravar o ficheiro.", + "settings-category-mods": "Mods", + "settings-category-behaviour": "Comportamento", + "settings-category-debug": "Opções de debug", + "menu-about": "Sobre o Legcord", + "menu-developerTools": "Ferramentas de programador", + "menu-paste": "Colar", + "menu-selectAll": "Selecionar tudo", + "menu-toggleFullscreen": "Ativar/desativar modo de ecrã cheio", + "menu-zoomIn": "Aumentar zoom", + "menu-zoomOut": "Diminuir zoom", + "menu-resetZoom": "Resetar zoom", + "menu-keybind": "Atalhos", + "menu-legcord": "Legcord", + "tray-openLegcord": "Abrir Legcord", + "tray-openSettings": "Abrir Configurações", + "tray-quitLegcord": "Fechar Legcord", + "tray-tooltip": "Legcord", + "dialog-openUrl-title": "Quer abrir esta ligação?", + "dialog-openUrl-message": "Deseja abrir {url}?", + "dialog-openUrl-detail": "Detetamos que este url não usa protocolos normais ded navegador. Isto pode significar que este url leva à um programa local no seu computador. Por favor, verifique se o reconhece antes de prosseguir!", + "dialog-openUrl-checkbox": "Lembrar a minha resposta e ignorar este aviso em sessões futuras", + "dialog-openUrl-no": "Não, não quero", + "title-unreadMessages": "Tem mensagens não lidas.", + "title-legcordSuffix": " - Legcord", + "dialog-importTheme-title": "Selecione um tema que deseja importar", + "dialog-importTheme-discordStyles": "Estilos do Discord", + "dialog-customIcon-filters": "Ícones", + "config-corrupted-title": "Opa, algo deu errado.", + "config-corrupted-message": "Legcord detetou que o seu ficheiro de configuração está corrompido, por favor, reinicie a app e ponha novamente as suas configurações, caso o erro persista, reporte no nosso servidor do Discord ou na guia de Problemas no Github.", + "setup-welcomeTitle": "Bem-vindo ao Legcord", + "setup-welcomeSubtitle": "Vamos nos preparar para a sua configuração perfeita.", + "setup-getStarted": "Começar", + "setup-windowStyle-nativeTitle": "Janela Nativa", + "setup-windowStyle-nativeDesc": "Usar o estilo de janela padrão do sistema", + "setup-windowStyle-customTitle": "Barra de título customizada", + "setup-windowStyle-customDesc": "Usa o design customizado do Legcord para a barra de título", + "setup-chooseWindowStyle": "Escolher estilo da Janela", + "setup-selectAppearance": "Escolher como o Legcord aparece na sua máquina", + "setup-systemTray": "Bandeja do sistema", + "setup-trayChoose": "Escolha se deseja ativar ou não a ícone na bandeja do sistema", + "setup-trayEnableTitle": "Ativar ícone de bandeja", + "setup-trayEnableDesc": "Mostrar o Legcord na bandeja do sistema", + "setup-trayDisableTitle": "Desativar ícone de bandeja", + "setup-trayDisableDesc": "Não mostrar o Legcord na bandeja do sistema", + "setup-finishTitle": "Está pronto!", + "setup-back": "Voltar", + "settings-restartRequired": "Reinicialização necessária", + "settings-theme-legacy": "Legado", + "settings-channel-stable": "Estável", + "keybind-mute": "Silenciar Microfone", + "keybind-runJavascript": "Executar Javascript", + "keybind-global": "Global", + "detectable-aliases": "Apelidos", + "backup-createBackup": "Criar backup", + "backup-restore": "Restaurar", + "backup-includeLegcordConfig": "Configurações", + "backup-confirmBackup": "Exportar", + "backup-cancelledTitle": "Cancelado", + "backup-unknownError": "Algo deu errado.", + "backup-restoreConfirm": "Restaurar", + "backup-restoreCancel": "Cancelar", + "supportBanner-donate": "Doar", + "settings-material": "Material de Janela", + "settings-material-desc": "Define o material de Janela de plano de fundo que o Legcord usa.", + "settings-material-mica": "Mica", + "settings-material-mica-alt": "Mica Alt", + "settings-material-acrylic": "Acrílico", + "settings-csp": "Política de Segurança de Conteúdo", + "settings-csp-desc": "Define o quão estrito a Política de Segurança do Legcord é. CSP estrito fornece melhor segurança mas pode causar problemas de compatibilidade com algumas modificações/temas/plugins de cliente.", + "settings-csp-strict": "Estrito", + "settings-csp-vanilla": "Vanilla", + "settings-firstTimeCrash": "Estamos a preparar tudo por si!", + "settings-firstTimeCrash-desc": "Definições não estão disponíveis num primeiro lançamento. Por favor use o botão abaixo para reiniciar e definições devem estar prontas após reiniciar.", + "settings-automaticClientUpdates": "Atualizações de cliente automáticas", + "settings-automaticClientUpdates-desc": "Desativa atualizações do Legcord automáticas", + "settings-mod-shelter": "Shelter", + "settings-mod-custom": "Personalizado", + "settings-experimental": "Experimental", + "settings-category-lookAndFeel": "Aparência e sensação", + "settings-category-legacy": "Funcionalidades antigas", + "tray-supportServer": "Suportar Servidor Discord", + "setup-linuxTrayWarning": "A funcionalidade da barra de tarefas do sistema podem ter problemas ou comportarem-se diferentemente em sistemas Linux.", + "setup-finishSubtitle": "A sua configuração Legcord está completa e personalizada de acordo com as suas preferências.", + "setup-finishSettingsNote": "Precisa de fazer alterações mais tarde? Encontrará todas estas opções no menu de definições do Discord abaixo do Legcord.", + "setup-launchLegcord": "Lançar Legcord", + "setup-modSelectorTitle": "Escolher o Seu Mod de Cliente", + "setup-modSelectorSubtitle": "O Legcord inclui Shelter como predefinição, mas também pode escolher outro mod de cliente se preferir.", + "setup-vencordTitle": "Vencord", + "setup-vencordDesc": "Mod de cliente com plugins e temas.", + "setup-equicordTitle": "Equicord", + "setup-equicordDesc": "Um fork do Vencord com mais plugins.", + "setup-useShelterOnly": "Usar Apenas Shelter", + "setup-stepOf": "Passo {current} de {total}", + "setup-windowTitle": "Configuração do Legcord", + "settings-restartRequiredBody": "Pode precisar de reiniciar para aplicar estas mudanças.", + "settings-restartLater": "Faço isso mais tarde", + "settings-channel-canary": "Canary", + "settings-channel-ptb": "PTB", + "settings-category-powerManagement": "Gestão de Energia", + "settings-category-arrpc": "arRPC", + "settings-extendedPluginAbilities": "Habilidades de plugin estendidas", + "settings-extendedPluginAbilities-desc": "Permite aos plugins a leitura e escrita de ficheiro no escopo de uma pasta do seu computador (p.ex. para caching de mensagens eliminadas). Apenas ative isto para plugins que confia—eles podem armazenar dados localmente. Dados são armazenados por cada plugin na pasta de armazenamento de plugins do Legcord.", + "settings-audio-loopback": "Loopback", + "settings-audio-loopbackWithMute": "Loopback com mute", + "keybind-addKeybind": "Adicionar um atalho de teclado", + "keybind-accelerator": "Acelerador", + "keybind-invalidCombo": "Esta combinação de teclas é inválida ou não é suportada.", + "keybind-deafen": "Silenciar Áudio", + "keybind-pushToTalk": "Carregar para falar", + "keybind-leaveCall": "Sair da chamada", + "keybind-navigateForward": "Navegar para a frente", + "keybind-navigateBack": "Navegar para trás", + "keybind-openQuickCss": "Abrir Quick CSS", + "keybind-openSettings": "Abrir Definições", + "keybind-globalNote": "Permite-lhe atribuir um atalho de teclado específico que pode ser usado entre diferentes aplicações e programas.", + "detectable-addApp": "Adicionar Aplicação Detetável", + "backup-dialogSave-title": "Guardar cópia de segurança do Legcord", + "backup-dialogOpen-title": "Abrir cópia de segurança do Legcord", + "backup-pageTitle": "Cópia de segurança e restaurar", + "backup-pageSubtitle": "Guardar ou restaurar a sua cópia de segurança Legcord, inclui definições, temas, plugins, e dados de mods—tudo em um ficheiro.", + "backup-modalTitle": "Escolher o que a cópia de segurança contém", + "backup-includeLegcordThemes": "Temas e Quick CSS", + "backup-includeLegcordPlugins": "Extensões Chrome/Armazenamento de Plugin", + "backup-includeVencord": "Dados Vencord (sessão atual)", + "backup-includeEquicord": "Dados Equicord (sessão atual)", + "backup-includeShelter": "Plugins Shelter", + "backup-includeModBundles": "Ficheiros de mod de cliente transferidos (Vencord, Equicord, Shelter, pacotes personalizados)", + "backup-successTitle": "Cópia de segurança guardada", + "backup-successBody": "A sua cópia de segurança foi guardada com sucesso.", + "backup-cancelledBody": "Nenhum ficheiro foi guardado.", + "backup-failedTitle": "Cópia de segurança falhada", + "backup-invalidFile": "Não foi possível ler esse ficheiro de cópia de segurança.", + "backup-restoreConfirmHeader": "Restaurar a partir da cópia de segurança?", + "backup-restoreConfirmBody": "Ficheiros em disco serão substituídos onde esta cópia de segurança contém dados. Poderá ter que reiniciar o Legcord para tudo ser aplicado.", + "backup-restoreDoneTitle": "Restauração completa", + "backup-restoreDoneBody": "Os seus dados foram restaurados. Reinicie o Legcord para que todas as mudanças tomem efeito.", + "supportBanner-title": "Suportar o Projeto", + "supportBanner-subtitle": "Ajude-nos a continuar a desenvolver o Legcord. O seu suporte mantém o projeto vivo e permite-nos introduzir mais funcionalidades.", + "settings-startMinimized-off": "Normal", + "settings-startMinimized-minimized": "Minimizado na barra de tarefas", + "settings-startMinimized-tray": "Oculto no tabuleiro" } diff --git a/assets/lang/ru.json b/assets/lang/ru.json index 54fdb41..a3d59d8 100644 --- a/assets/lang/ru.json +++ b/assets/lang/ru.json @@ -15,20 +15,20 @@ "setup_question5": "Хотите использовать значок в трее?", "settings-theme": "Стиль окна", "settings-theme-desc": "Стиль окна определяет, какой заголовок использует Legcord.", - "settings-theme-default": "По умолчанию (настраиваемая)", - "settings-theme-native": "Нативная", - "settings-autoHideMenuBar": "Авто-скрытие строки меню", - "settings-autoHideMenuBar-desc": "Авто-скрытие строки меню, когда она не используется.", + "settings-theme-default": "По умолчанию (Legcord)", + "settings-theme-native": "Системная", + "settings-autoHideMenuBar": "Автоскрытие строки меню", + "settings-autoHideMenuBar-desc": "Автоскрытие строки меню, когда она не используется.", "settings-sleepInBackground": "Переходить в спящий режим в фоне", "settings-sleepInBackground-desc": "Включает ограничение скорости фоновой работы Chromium. Может снизить энергопотребление, но приводит к некорректной работе уведомлений.", "settings-transparency": "Прозрачность", - "settings-transparency-desc": "Установите режим прозрачности Legcord.", + "settings-transparency-desc": "Выберите режим прозрачности, который будет использовать Legcord.", "settings-transparency-universal": "Универсальный", "settings-transparency-modern": "Современный", "settings-theme-transparent": "Прозрачный", - "settings-transparency-tahoe-warning": "Прозрачность может вызвать чрезмерные лаги на MacOS 26 Tahoe.", - "settings-popoutPiP": "Всплывающее окно вызова всегда сверху", - "settings-popoutPiP-desc": "При включении этой функции всплывающее окно вызова будет отображаться в режиме Всегда поверх других окон.", + "settings-transparency-tahoe-warning": "Прозрачность может вызывать чрезмерные лаги на macOS 26 Tahoe.", + "settings-popoutPiP": "Всплывающее окно вызова поверх всех окон", + "settings-popoutPiP-desc": "При включении этой функции всплывающее окно вызова всегда будет отображаться в режиме Поверх всех окон.", "settings-venmic-deviceSelect": "Выбор устройства", "settings-venmic-deviceSelect-desc": "Позволяет выбрать аудио устройство.", "settings-venmic-granularSelect-desc": "Позволить выбрать источник аудиовхода.", @@ -39,5 +39,190 @@ "settings-venmic-ignoreInputMedia-desc": "Игнорировать аудио вход из медиаисточников.", "settings-venmic-onlySpeakers": "Только динамики", "settings-venmic-onlySpeakers-desc": "Использовать только динамики для выбора аудиовыхода.", - "settings-audio": "Аудио" + "settings-audio": "Аудио", + "settings-theme-overlay": "Оверлей", + "settings-material": "Материал фона окна", + "settings-material-desc": "Выберите эффект прозрачности Windows, который будет использовать Legcord.", + "settings-material-mica": "Mica", + "settings-material-mica-alt": "Mica Alt", + "settings-material-acrylic": "Acrylic", + "settings-material-none": "Не использовать", + "settings-venmic-workaround": "Обход", + "settings-audio-desc": "Выберите метод захвата системного аудио во время демонстрации экрана.", + "settings-openCustomIconDialog": "Выберите иконку рабочего стола", + "settings-mintoTray": "Работа в фоне", + "settings-mintoTray-desc": "При выключенной настройке, закрытие окна будет полностью закрывать Legcord, а при включённой, Legcord просто пойдёт отдыхать в ваш системный трей.", + "settings-startMinimized": "Окно при запуске", + "settings-startMinimized-desc": "Как Legcord появляется при запуске. Режим трея полностью скрывает окно (нужна иконка в трее).", + "settings-csp": "Политика Защиты Данных (CSP)", + "settings-csp-desc": "Установите строгость защиты данных в Legcord. Строгий режим CSP безопаснее, но может быть несовместим с некоторыми модами/темами/плагинами.", + "settings-csp-strict": "Строгий", + "settings-csp-none": "Не использовать", + "settings-csp-vanilla": "Стандартный", + "settings-useSystemCssEditor": "Использовать системный редактор CSS", + "settings-useSystemCssEditor-desc": "Использовать системный редактор CSS для редактирования CSS в Legcord.", + "settings-MultiInstance": "Много сессий", + "settings-MultiInstance-desc": "При включённой настройке вы сможете начать несколько сессий Legcord одновременно.", + "settings-noBundleUpdates": "Не обновлять пакеты", + "settings-noBundleUpdates-desc": "Отключает автоматическое обновление модов.", + "settings-automaticClientUpdates": "Автообновление клиента", + "settings-automaticClientUpdates-desc": "Отключает автоматическое обновление Legcord.", + "settings-hardwareAcceleration": "Аппаратное ускорение", + "settings-hardwareAcceleration-desc": "Legcord будет использовать ваш GPU для ускорения работы программы. Если вам встречаются визуальные баги, попробуйте выключить эту функцию.", + "settings-mobileMode": "Мобильный режим", + "settings-mobileMode-desc": "Эта функция создана специально для тех, кто использует Legcord на устройствах с сенсорным экраном! Она активирует скрытый мобильный режим Discord, созданный для планшетов и смартфонов. Режим не поддерживает голосовые чаты. Идеально подходит для пользователей PinePhone и других подобных устройств.", + "settings-spellcheck": "Проверка орфографии", + "settings-spellcheck-desc": "Выделяет неправильно написанные слова.", + "settings-vaapi": "VAAPI", + "settings-vaapi-desc": "Использовать VAAPI (Аппаратное ускорение) для декодирования видео на Linux-системах. Значительно уменьшает нагрузку на CPU во время демонстрации экрана, но может вызывать проблемы на некоторых системах. Выключите эту настройку, если вы сталкиваетесь с вылетами или чёрным экраном во время демонстрации.", + "settings-bitrateMin": "Минимальный битрейт", + "settings-bitrateMin-desc": "Минимальный битрейт видео при демонстрации экрана.", + "settings-bitrateMax": "Максимальный битрейт", + "settings-bitrateMax-desc": "Максимальный битрейт видео при демонстрации экрана.", + "settings-mod-shelter": "Shelter", + "settings-prfmMode": "Режим Производительности", + "settings-prfmMode-desc": "Режимы Производительности - экспериментальная функция Legcord, оптимизирующая производительность и скорость работы программы под ваши нужды. Эффект может зависеть от вашей системной конфигурации и паттернов использования, поэтому мы рекомендуем вам попробовать каждый режим и выбрать тот, что лучше всего подходит именно вам.", + "settings-prfmMode-performance": "Производительный", + "settings-prfmMode-balanced": "Сбалансированный", + "settings-prfmMode-battery": "Энергосбережение", + "settings-prfmMode-memory": "Экономия памяти", + "settings-prfmMode-voip": "Голос и видео", + "settings-prfmMode-latency": "Низкая задержка", + "settings-prfmMode-smoothScreenshare": "Плавная демонстрация экрана", + "settings-prfmMode-dynamic": "Динамический", + "settings-prfmMode-vaapi": "VAAPI", + "settings-disableAutogain": "Выключить автоусиление", + "settings-disableAutogain-desc": "Отключает динамическое усиление (гейн) микрофона.", + "settings-trayIcon": "Иконка в трее", + "settings-trayIcon-desc": "Установите значок, который будет отображаться в меню трея.", + "settings-advanced": "Только для продвинутых пользователей", + "settings-pluginsFolder": "Открыть папку с плагинами", + "settings-themesFolder": "Открыть папку с темами", + "settings-experimental": "Экспериментальные настройки", + "settings-restart": "Перезапустить приложение", + "settings-updater": "Проверить наличие обновлений", + "settings-skipSplash": "Отключить сплеш", + "settings-skipSplash-desc": "Пропускает экран с логотипом Legcord, появляющийся при запуске приложения.", + "settings-copyDebugInfo": "Копировать данные для отладки", + "settings-copyGPUInfo": "Копировать информацию о GPU", + "settings-clearClientModCache": "Очистить кеш модов", + "settings-forceNativeCrash": "Вызвать принудительный сбой", + "settings-smoothScroll": "Использовать плавный скроллинг", + "settings-smoothScroll-desc": "Включить плавный скроллинг", + "settings-autoScroll": "Разрешить автоматическую прокрутку", + "settings-autoScroll-desc": "Разрешить автоматическую прокрутку при нажатии средней кнопки мыши (Примечание: Эта настройка не имеет приоритета над назначениями клавиш вашей среды рабочего стола)", + "settings-quickCss": "Quick CSS", + "settings-quickCss-desc": "Быстро внесите изменения в ваш CSS в базовом текстовом редакторе. Изменения вступят в силу сразу полсе сохранения файла.", + "settings-category-lookAndFeel": "Внешний вид", + "settings-category-debug": "Отладка", + "menu-about": "Про Legcord", + "menu-developerTools": "Настройки разработчика", + "menu-openSettings": "Открыть настройки", + "menu-reload": "Перезагрузка", + "menu-restart": "Перезапуск", + "menu-cut": "Вырезать", + "menu-copy": "Копировать", + "menu-paste": "Вставить", + "menu-selectAll": "Выбрать всё", + "menu-toggleFullscreen": "Полноэкранный режим", + "menu-zoomIn": "Приблизить", + "menu-zoomOut": "Отдалить", + "menu-resetZoom": "Сбросить приближение", + "menu-window": "Окно", + "menu-minimize": "Свернуть", + "menu-close": "Закрыть", + "menu-legcord": "Legcord", + "tray-openLegcord": "Открыть Legcord", + "tray-openSettings": "Открыть настройки", + "tray-supportServer": "Сервер поддержки в Discord", + "tray-restartLegcord": "Перезапустить Legcord", + "tray-quitLegcord": "Закрыть Legcord", + "tray-tooltip": "Legcord", + "dialog-openUrl-title": "Перейти по ссылке?", + "dialog-openUrl-message": "Перейти по адресу {url}?", + "dialog-openUrl-detail": "Данный url использует нестандартный сетевой протокол. Скорее всего, он пытается запустить локальную программу на вашем устройстве. Прежде чем продолжить, удостоверьтесь, что узнаёте её!", + "dialog-openUrl-checkbox": "Запомнить мой ответ и не предупреждать в дальнейшем", + "dialog-openUrl-yes": "Продолжить", + "dialog-openUrl-no": "Отмена", + "title-unreadMessages": "У вас есть непрочитанные сообщения.", + "title-legcordSuffix": " - Legcord", + "dialog-importTheme-title": "Выберите тему, которую вы хотите импортировать", + "dialog-importTheme-button": "Импортировать", + "dialog-importTheme-allFiles": "Все файлы", + "config-corrupted-title": "Упс, что-то пошло не так!", + "setup-welcomeTitle": "Добро пожаловать в Legcord", + "setup-windowStyle-nativeTitle": "Нативное окно", + "setup-windowStyle-nativeDesc": "Использовать системное оформление окна", + "setup-windowStyle-customTitle": "Кастомный заголовок", + "setup-windowStyle-customDesc": "Использовать кастомный стиль полосы заголовка Legcord", + "setup-chooseWindowStyle": "Выберите оформление окна", + "setup-selectAppearance": "Настройте, как Legcord будет выглядеть на вашем устройстве", + "setup-finishTitle": "Готово!", + "setup-finishSettingsNote": "Хотите что-то поменять? Все эти настройки всегда доступны в настройках Discord в разделе Legcord.", + "setup-launchLegcord": "Запустить Legcord", + "setup-vencordTitle": "Vencord", + "setup-equicordTitle": "Equicord", + "setup-loading": "Загрузка...", + "settings-restartRequired": "Необходим перезапуск", + "settings-restartRequiredBody": "Перезапустите Legcord, чтобы применить внесённые изменения.", + "settings-restartLater": "Перезапущу позже", + "settings-channel-stable": "Stable", + "settings-channel-canary": "Canary", + "settings-channel-ptb": "PTB", + "settings-category-powerManagement": "Энергосбережение", + "settings-category-arrpc": "arRPC", + "settings-extendedPluginAbilities": "Расширенные возможности плагинов", + "settings-extendedPluginAbilities-desc": "Даёт плагинам доступ к чтению и записи файлов в выделенной папке на вашем устройстве (например, для сохранения удалённых сообщений). Не включайте для плагинов, которым не доверяете, и не хотите, чтобы они сохраняли данные на вашем усторйстве. Данные будут сохраняться отдельно для каждого плагина в папке плагинов в файлах Legcord.", + "keybind-invalidCombo": "Данное сочетание клавиш некорректно или не поддерживается.", + "keybind-recording": "Запись", + "keybind-record": "Начать запись", + "keybind-action": "Действие", + "keybind-leaveCall": "Покинуть звонок", + "keybind-add": "Добавить", + "keybind-delete": "Удалить", + "detectable-missingFields": "Пропущено поле", + "detectable-fillAllFields": "Пожалуйста, заполните все поля, чтобы продолжить.", + "detectable-themes": "Темы", + "detectable-placeholderName": "например, Discord", + "detectable-placeholderId": "например, 1234567890", + "themes-updated": "Тема успешно обновлена!", + "themes-importFromFile": "Импортировать из файла", + "themes-openThemesFolder": "Открыть папку с темами", + "themes-import": "Импортировать", + "themes-importUrlPlaceholder": "https://raw.githubusercontent.com/... [.theme.css]", + "screenshare-share": "Поделиться", + "screenshare-title": "Демонстрация экрана", + "contextMenu-searchGoogle": "Поиск в Google", + "contextMenu-searchDuckDuckGo": "Поиск в DuckDuckGo", + "touchbar-servers": "Сервера", + "splash-title": "Legcord", + "backup-dialogSave-title": "Сохранить резервную копию Legcord", + "backup-dialogOpen-title": "Открыть резерную копию Legcord", + "backup-pageTitle": "Резервное копирование", + "backup-pageSubtitle": "Сохранение и восстановление ваших настроек Legcord, включая плагины и настройки модов — всё одним файлом.", + "backup-createBackup": "Создать резервную копию", + "backup-restore": "Восстановить", + "backup-modalTitle": "Выберите, что хотите сохранить", + "backup-includeLegcordConfig": "Настройки", + "backup-includeLegcordThemes": "Темы и Quick CSS", + "backup-includeVencord": "Данные Vencord (текущая сессия)", + "backup-includeEquicord": "Данные Equicord (текущая сессия)", + "backup-includeShelter": "Плагины Shelter", + "backup-unknownError": "Что-то пошло не так.", + "backup-restoreCancel": "Отмена", + "supportBanner-title": "Поддержать Проект", + "supportBanner-subtitle": "Ваша поддержка позволяет нам продолжать разработку Legcord и вводить всё больше и больше новых функций!", + "supportBanner-donate": "Задонатить", + "settings-trayIcon-normal": "Лого Discord", + "settings-trayIcon-classic": "Классическое лого Discord", + "settings-trayIcon-colored-plug": "Цветной Штекер", + "settings-trayIcon-white-plug": "Белый Штекер", + "settings-trayIcon-white-plug-alt": "Белый Штекер (Альт.)", + "settings-trayIcon-black-plug": "Чёрный Штекер", + "settings-trayIcon-black-plug-alt": "Чёрный Штекер (Альт.)", + "settings-category-behaviour": "Поведение", + "menu-quit": "Выход", + "settings-startMinimized-off": "Обычный", + "settings-startMinimized-minimized": "Свёрнуто в панель задач", + "settings-startMinimized-tray": "Скрыто в трее" } diff --git a/assets/lang/tr.json b/assets/lang/tr.json index 0967ef4..38db125 100644 --- a/assets/lang/tr.json +++ b/assets/lang/tr.json @@ -1 +1,8 @@ -{} +{ + "loading_screen_start": "Legcord başlatılıyor…", + "loading_screen_update": "Legcord’un yeni bir versiyonu var. Lütfen son versiyona güncelleyin.", + "setup_question1": "Legcord kurulumuna hoş geldiniz", + "yes": "Evet", + "no": "Hayır", + "next": "Sonraki" +} diff --git a/assets/lang/uk.json b/assets/lang/uk.json index ce6cdf4..47b2746 100644 --- a/assets/lang/uk.json +++ b/assets/lang/uk.json @@ -27,7 +27,7 @@ "settings-transparency-universal": "Універсальний", "settings-transparency-modern": "Сучасний", "settings-theme-transparent": "Прозорий", - "settings-transparency-tahoe-warning": "Прозорість може призвести до надмірного лагу на MacOS 26 Tahoe.", + "settings-transparency-tahoe-warning": "Прозорість може призвести до надмірного лагу на macOS 26 Tahoe.", "settings-popoutPiP": "Виклик спливаючого вікна завжди зверху", "settings-popoutPiP-desc": "Коли цю функцію ввімкнено, спливаюче вікно виклику буде в режимі «Завжди зверху».", "settings-venmic-workaround": "Тимчасове вирішення", @@ -52,8 +52,8 @@ "settings-csp-desc": "Legcord CSP – це наша система, яка керує завантаженням користувацького контенту в додаток Discord. Від неї залежать такі речі, як клієнтські моди та теми. Вимкніть, якщо хочете позбутися модів та користувацьких стилів.", "settings-mintoTray": "Робота у фоновому режимі", "settings-mintoTray-desc": "Якщо вимкнено, Legcord закриється, як і будь-яке інше вікно, якщо його закрити, інакше він залишиться в системному треї на потім.", - "settings-startMinimized": "Почати згорнутий", - "settings-startMinimized-desc": "Легкорд починається на задньому плані та залишається поза вашими перешкодами.", + "settings-startMinimized": "Вікно при запуску", + "settings-startMinimized-desc": "Як Legcord з’являється під час запуску. Режим трея повністю ховає вікно (потрібна іконка в треї).", "settings-useSystemCssEditor": "Використовуйте системний редактор CSS", "settings-useSystemCssEditor-desc": "Використовуйте системний редактор CSS для редагування CSS.", "settings-MultiInstance": "Багато екземплярів", @@ -89,7 +89,12 @@ "settings-prfmMode": "Режим продуктивності", "settings-prfmMode-desc": "Режим продуктивності – це експериментальна функція в Legcord, розроблена для оптимізації швидкості реагування та продуктивності відповідно до ваших потреб. Вплив може відрізнятися залежно від вашого обладнання та використання, тому ми рекомендуємо вам спробувати кожен режим, щоб визначити, який найкраще підходить саме вам.", "settings-prfmMode-performance": "Продуктивність", + "settings-prfmMode-balanced": "Збалансований", "settings-prfmMode-battery": "Батарея", + "settings-prfmMode-memory": "Економія пам'яті", + "settings-prfmMode-voip": "Голос і відео", + "settings-prfmMode-latency": "Низька затримка", + "settings-prfmMode-smoothScreenshare": "Плавна демонстрація екрана", "settings-prfmMode-dynamic": "Динамічний", "settings-prfmMode-vaapi": "VAAPI", "settings-disableAutogain": "Вимкнути автоматичне посилення", @@ -137,5 +142,8 @@ "settings-windowsLegacyScanning": "Сканування застарілих версій Windows", "settings-windowsLegacyScanning-desc": "Використовує застарілий метод для процесів сканування у Windows (до версії 1.1.6). Може покращити сумісність у деяких системах, але менш ефективний.", "settings-scanInterval": "Інтервал сканування (мс)", - "settings-scanInterval-desc": "Встановлює частоту (у мілісекундах) сканування процесу. Нижчі значення можуть покращити швидкість виявлення, але можуть збільшити використання процесора." + "settings-scanInterval-desc": "Встановлює частоту (у мілісекундах) сканування процесу. Нижчі значення можуть покращити швидкість виявлення, але можуть збільшити використання процесора.", + "settings-startMinimized-off": "Звичайний", + "settings-startMinimized-minimized": "Згорнуто на панель завдань", + "settings-startMinimized-tray": "Сховано в треї" } diff --git a/assets/lang/zh_Hans.json b/assets/lang/zh_Hans.json index f078935..86fd19f 100644 --- a/assets/lang/zh_Hans.json +++ b/assets/lang/zh_Hans.json @@ -25,6 +25,6 @@ "settings-transparency-universal": "通用", "settings-transparency-modern": "现代", "settings-theme-transparent": "透明", - "settings-transparency-tahoe-warning": "在 MacOS 26 Tahoe 上,启用透明效果可能会导致明显卡顿。", + "settings-transparency-tahoe-warning": "在 macOS 26 Tahoe 上,启用透明效果可能会导致明显卡顿。", "settings-popoutPiP": "通话窗口弹出时保持置顶" } diff --git a/biome.jsonc b/biome.jsonc index da9bc49..c07a47a 100644 --- a/biome.jsonc +++ b/biome.jsonc @@ -1,9 +1,9 @@ { - "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", + "$schema": "https://biomejs.dev/schemas/2.5.5/schema.json", "vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true }, "files": { "ignoreUnknown": false, - "ignore": ["assets/app/js"] + "includes": ["**", "!**/assets/app/js", "!**/assets/**/*.svg"] }, "formatter": { "enabled": true, @@ -16,11 +16,11 @@ "attributePosition": "auto", "bracketSpacing": true }, - "organizeImports": { "enabled": true }, + "assist": { "actions": { "source": { "organizeImports": "on" } } }, "linter": { "enabled": true, "rules": { - "recommended": true, + "preset": "recommended", "complexity": { "noForEach": "off" }, diff --git a/docker/Dockerfile.deb b/docker/Dockerfile.deb new file mode 100644 index 0000000..116b63f --- /dev/null +++ b/docker/Dockerfile.deb @@ -0,0 +1,21 @@ +FROM ubuntu + +WORKDIR /app + +COPY ./dist/*.deb . + +RUN apt-get update -y && apt-get upgrade -y + +RUN apt-get install ./*.deb -y + +RUN apt-get install -qqy x11-apps x11vnc xvfb + +RUN mkdir ~/.vnc +RUN x11vnc -storepasswd 1234 ~/.vnc/passwd + +COPY docker/start.sh /start.sh +RUN chmod +x /start.sh + +EXPOSE 5900 + +CMD ["/start.sh"] \ No newline at end of file diff --git a/docker/Dockerfile.pacman b/docker/Dockerfile.pacman new file mode 100644 index 0000000..425744c --- /dev/null +++ b/docker/Dockerfile.pacman @@ -0,0 +1,21 @@ +FROM archlinux + +WORKDIR /app + +COPY ./dist/*.pacman . + +RUN pacman -Syu --noconfirm + +RUN pacman -U --noconfirm ./*.pacman + +RUN pacman -Syu --noconfirm x11vnc xorg-server-xvfb + +RUN mkdir ~/.vnc +RUN x11vnc -storepasswd 1234 ~/.vnc/passwd + +COPY docker/start.sh /start.sh +RUN chmod +x /start.sh + +EXPOSE 5900 + +CMD ["/start.sh"] \ No newline at end of file diff --git a/docker/start.sh b/docker/start.sh new file mode 100644 index 0000000..6d21100 --- /dev/null +++ b/docker/start.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -e + +export DISPLAY=:99 + +Xvfb :99 -screen 0 1280x800x24 & +sleep 1 + +x11vnc -display :99 -forever -usepw -rfbport 5900 & + +legcord --no-sandbox & + +tail -f /dev/null \ No newline at end of file diff --git a/docs/examples/clipboard-fallback-plugin/README.md b/docs/examples/clipboard-fallback-plugin/README.md new file mode 100644 index 0000000..55d85b3 --- /dev/null +++ b/docs/examples/clipboard-fallback-plugin/README.md @@ -0,0 +1,82 @@ +# Legcord Clipboard Fallback Plugin + +Fixes Discord in-page copy actions in Legcord, including: + +- Copy User ID +- Copy Message ID +- Copy Message Link +- Other Discord menu actions that call `navigator.clipboard.writeText(...)` + +## Why this exists + +In affected Legcord/Electron environments, Discord's web UI calls: + +```js +navigator.clipboard.writeText(text) +``` + +but Chromium rejects it, commonly with errors like: + +```text +NotAllowedError: Failed to execute 'writeText' on 'Clipboard': Document is not focused. +``` + +or Legcord logs: + +```text +Unable to determine render window for element [object HTMLDocument] +``` + +This plugin patches `navigator.clipboard.writeText` in the Discord page and falls back to a selection-based `document.execCommand("copy")` copy path. + +## Known limitation + +Legcord's native **Copy Image** context-menu action does not go through `navigator.clipboard.writeText` or `navigator.clipboard.write` in the page. It is handled by Electron's main-process context menu (`webContents.copyImageAt(...)`), so a renderer/custom-bundle plugin cannot reliably fix image copying. That needs a Legcord main-process fix or a filesystem plugin with main/preload access on newer Legcord versions. + +## Install on Legcord versions with filesystem plugins + +1. Open the Legcord plugins folder: + + ```text + ~/Library/Application Support/legcord/plugins + ``` + +2. Create this folder: + + ```text + clipboard-fallback + ``` + +3. Copy these files into it: + + ```text + manifest.json + renderer.js + ``` + +4. Restart Legcord. +5. Enable **Clipboard Fallback** in Legcord's plugin settings. + +## Older Legcord workaround: custom bundle + +If your Legcord version does not have filesystem plugins yet, copy `custom-bundle.js` into: + +```text +~/Library/Application Support/legcord/custom.js +``` + +Do **not** use `renderer.js` as `custom.js`; `renderer.js` is the filesystem-plugin entry and expects Legcord's plugin loader to provide `module.exports`. + +and add `"custom"` to the `mods` array in: + +```text +~/Library/Application Support/legcord/storage/settings.json +``` + +Example: + +```json +"mods": ["equicord", "custom"] +``` + +Then restart Legcord. diff --git a/docs/examples/clipboard-fallback-plugin/custom-bundle.js b/docs/examples/clipboard-fallback-plugin/custom-bundle.js new file mode 100644 index 0000000..83cb93f --- /dev/null +++ b/docs/examples/clipboard-fallback-plugin/custom-bundle.js @@ -0,0 +1,216 @@ +(() => { + const module = { exports: {} }; + const api = { + logger: { + log: (...args) => console.log("[ClipboardFallback]", ...args), + warn: (...args) => console.warn("[ClipboardFallback]", ...args), + error: (...args) => console.error("[ClipboardFallback]", ...args), + }, + }; + + /** + * Legcord Clipboard Fallback + * + * Discord's web UI uses navigator.clipboard.writeText for actions such as + * "Copy User ID" and "Copy Message Link", and navigator.clipboard.write for + * richer clipboard payloads such as images. In some Legcord/Electron/macOS + * combinations Chromium rejects those calls because the document is not focused + * or the clipboard permission is not granted, leaving the clipboard unchanged. + * + * This renderer plugin replaces those APIs with selection-based copy fallbacks + * that run inside the original click gesture. + */ + module.exports.activate = (api) => { + const PATCH_KEY = Symbol.for("legcord.clipboardFallback.installed"); + + function install() { + try { + if (!navigator.clipboard) { + api.logger.warn("navigator.clipboard is unavailable"); + return; + } + + if (navigator.clipboard[PATCH_KEY]) return; + + const originalWriteText = navigator.clipboard.writeText?.bind(navigator.clipboard); + const originalWrite = navigator.clipboard.write?.bind(navigator.clipboard); + + async function blobToDataUrl(blob) { + if (typeof FileReader !== "undefined") { + return await new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onload = () => resolve(String(reader.result)); + reader.onerror = () => reject(reader.error ?? new Error("Failed to read clipboard image")); + reader.readAsDataURL(blob); + }); + } + + // Test/runtime fallback for environments with Blob but no FileReader. + const bytes = new Uint8Array(await blob.arrayBuffer()); + let binary = ""; + for (const byte of bytes) binary += String.fromCharCode(byte); + const base64 = typeof btoa === "function" ? btoa(binary) : Buffer.from(bytes).toString("base64"); + return `data:${blob.type || "application/octet-stream"};base64,${base64}`; + } + + function selectElementForCopy(element) { + const previousActiveElement = document.activeElement; + const selection = window.getSelection?.() ?? globalThis.getSelection?.(); + const range = document.createRange(); + + element.focus?.(); + range.selectNodeContents(element); + selection?.removeAllRanges(); + selection?.addRange(range); + + const copied = document.execCommand("copy"); + + selection?.removeAllRanges(); + if (previousActiveElement && typeof previousActiveElement.focus === "function") { + try { + previousActiveElement.focus(); + } catch {} + } + + if (!copied) throw new Error("document.execCommand('copy') returned false"); + } + + async function fallbackCopyText(text) { + const value = String(text); + const parent = document.body || document.documentElement; + if (!parent) throw new Error("No document body available for clipboard fallback"); + + const textarea = document.createElement("textarea"); + textarea.value = value; + textarea.setAttribute("readonly", ""); + textarea.setAttribute("aria-hidden", "true"); + textarea.style.position = "fixed"; + textarea.style.left = "-9999px"; + textarea.style.top = "0"; + textarea.style.width = "1px"; + textarea.style.height = "1px"; + textarea.style.opacity = "0"; + textarea.style.pointerEvents = "none"; + + parent.appendChild(textarea); + + const previousActiveElement = document.activeElement; + textarea.focus(); + textarea.select(); + textarea.setSelectionRange(0, value.length); + + const copied = document.execCommand("copy"); + textarea.remove(); + + if (previousActiveElement && typeof previousActiveElement.focus === "function") { + try { + previousActiveElement.focus(); + } catch {} + } + + if (!copied) throw new Error("document.execCommand('copy') returned false"); + } + + async function getClipboardItemType(item, type) { + if (!item?.types?.includes(type) || typeof item.getType !== "function") return null; + return await item.getType(type); + } + + async function fallbackCopyItems(items) { + const parent = document.body || document.documentElement; + if (!parent) throw new Error("No document body available for clipboard fallback"); + + const container = document.createElement("div"); + container.contentEditable = "true"; + container.setAttribute("aria-hidden", "true"); + container.style.position = "fixed"; + container.style.left = "-9999px"; + container.style.top = "0"; + container.style.width = "1px"; + container.style.height = "1px"; + container.style.overflow = "hidden"; + + for (const item of items) { + const htmlBlob = await getClipboardItemType(item, "text/html"); + if (htmlBlob) { + container.innerHTML += await htmlBlob.text(); + continue; + } + + const textBlob = await getClipboardItemType(item, "text/plain"); + if (textBlob) { + const span = document.createElement("span"); + span.textContent = await textBlob.text(); + container.appendChild(span); + continue; + } + + const imageType = item?.types?.find((type) => type.startsWith("image/")); + if (imageType && typeof item.getType === "function") { + const imageBlob = await item.getType(imageType); + const image = document.createElement("img"); + image.src = await blobToDataUrl(imageBlob); + image.alt = ""; + container.appendChild(image); + } + } + + if (!container.innerHTML && !container.textContent && !container.children?.length) { + throw new Error("No supported clipboard item types found"); + } + + parent.appendChild(container); + selectElementForCopy(container); + container.remove(); + } + + if (originalWriteText) { + Object.defineProperty(navigator.clipboard, "writeText", { + configurable: true, + value: async (text) => { + try { + await fallbackCopyText(text); + api.logger.log("copied text via fallback", text); + } catch (fallbackError) { + api.logger.warn("text fallback failed; trying original writeText", fallbackError); + return originalWriteText(text); + } + }, + }); + } + + if (originalWrite) { + Object.defineProperty(navigator.clipboard, "write", { + configurable: true, + value: async (items) => { + try { + await fallbackCopyItems(items); + api.logger.log("copied rich clipboard payload via fallback"); + } catch (fallbackError) { + api.logger.warn("rich clipboard fallback failed; trying original write", fallbackError); + return originalWrite(items); + } + }, + }); + } + + Object.defineProperty(navigator.clipboard, PATCH_KEY, { + configurable: false, + enumerable: false, + value: true, + }); + + api.logger.log("installed"); + } catch (error) { + api.logger.error("install failed", error); + } + } + + install(); + window.addEventListener("DOMContentLoaded", install, { once: true }); + }; + + if (typeof module.exports.activate === "function") { + module.exports.activate(api); + } +})(); diff --git a/docs/examples/clipboard-fallback-plugin/manifest.json b/docs/examples/clipboard-fallback-plugin/manifest.json new file mode 100644 index 0000000..7a509dd --- /dev/null +++ b/docs/examples/clipboard-fallback-plugin/manifest.json @@ -0,0 +1,9 @@ +{ + "id": "clipboard-fallback", + "name": "Clipboard Fallback", + "version": "1.1.0", + "description": "Fixes Discord in-page text copy actions in Legcord by falling back to document.execCommand('copy') when navigator.clipboard.writeText is blocked.", + "author": "Nigel Thornberry", + "compatibleVersions": ["*"], + "renderer": "renderer.js" +} diff --git a/docs/examples/clipboard-fallback-plugin/renderer.js b/docs/examples/clipboard-fallback-plugin/renderer.js new file mode 100644 index 0000000..33cdb01 --- /dev/null +++ b/docs/examples/clipboard-fallback-plugin/renderer.js @@ -0,0 +1,201 @@ +/** + * Legcord Clipboard Fallback + * + * Discord's web UI uses navigator.clipboard.writeText for actions such as + * "Copy User ID" and "Copy Message Link", and navigator.clipboard.write for + * richer clipboard payloads such as images. In some Legcord/Electron/macOS + * combinations Chromium rejects those calls because the document is not focused + * or the clipboard permission is not granted, leaving the clipboard unchanged. + * + * This renderer plugin replaces those APIs with selection-based copy fallbacks + * that run inside the original click gesture. + */ +module.exports.activate = (api) => { + const PATCH_KEY = Symbol.for("legcord.clipboardFallback.installed"); + + function install() { + try { + if (!navigator.clipboard) { + api.logger.warn("navigator.clipboard is unavailable"); + return; + } + + if (navigator.clipboard[PATCH_KEY]) return; + + const originalWriteText = navigator.clipboard.writeText?.bind(navigator.clipboard); + const originalWrite = navigator.clipboard.write?.bind(navigator.clipboard); + + async function blobToDataUrl(blob) { + if (typeof FileReader !== "undefined") { + return await new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onload = () => resolve(String(reader.result)); + reader.onerror = () => reject(reader.error ?? new Error("Failed to read clipboard image")); + reader.readAsDataURL(blob); + }); + } + + // Test/runtime fallback for environments with Blob but no FileReader. + const bytes = new Uint8Array(await blob.arrayBuffer()); + let binary = ""; + for (const byte of bytes) binary += String.fromCharCode(byte); + const base64 = typeof btoa === "function" ? btoa(binary) : Buffer.from(bytes).toString("base64"); + return `data:${blob.type || "application/octet-stream"};base64,${base64}`; + } + + function selectElementForCopy(element) { + const previousActiveElement = document.activeElement; + const selection = window.getSelection?.() ?? globalThis.getSelection?.(); + const range = document.createRange(); + + element.focus?.(); + range.selectNodeContents(element); + selection?.removeAllRanges(); + selection?.addRange(range); + + const copied = document.execCommand("copy"); + + selection?.removeAllRanges(); + if (previousActiveElement && typeof previousActiveElement.focus === "function") { + try { + previousActiveElement.focus(); + } catch {} + } + + if (!copied) throw new Error("document.execCommand('copy') returned false"); + } + + async function fallbackCopyText(text) { + const value = String(text); + const parent = document.body || document.documentElement; + if (!parent) throw new Error("No document body available for clipboard fallback"); + + const textarea = document.createElement("textarea"); + textarea.value = value; + textarea.setAttribute("readonly", ""); + textarea.setAttribute("aria-hidden", "true"); + textarea.style.position = "fixed"; + textarea.style.left = "-9999px"; + textarea.style.top = "0"; + textarea.style.width = "1px"; + textarea.style.height = "1px"; + textarea.style.opacity = "0"; + textarea.style.pointerEvents = "none"; + + parent.appendChild(textarea); + + const previousActiveElement = document.activeElement; + textarea.focus(); + textarea.select(); + textarea.setSelectionRange(0, value.length); + + const copied = document.execCommand("copy"); + textarea.remove(); + + if (previousActiveElement && typeof previousActiveElement.focus === "function") { + try { + previousActiveElement.focus(); + } catch {} + } + + if (!copied) throw new Error("document.execCommand('copy') returned false"); + } + + async function getClipboardItemType(item, type) { + if (!item?.types?.includes(type) || typeof item.getType !== "function") return null; + return await item.getType(type); + } + + async function fallbackCopyItems(items) { + const parent = document.body || document.documentElement; + if (!parent) throw new Error("No document body available for clipboard fallback"); + + const container = document.createElement("div"); + container.contentEditable = "true"; + container.setAttribute("aria-hidden", "true"); + container.style.position = "fixed"; + container.style.left = "-9999px"; + container.style.top = "0"; + container.style.width = "1px"; + container.style.height = "1px"; + container.style.overflow = "hidden"; + + for (const item of items) { + const htmlBlob = await getClipboardItemType(item, "text/html"); + if (htmlBlob) { + container.innerHTML += await htmlBlob.text(); + continue; + } + + const textBlob = await getClipboardItemType(item, "text/plain"); + if (textBlob) { + const span = document.createElement("span"); + span.textContent = await textBlob.text(); + container.appendChild(span); + continue; + } + + const imageType = item?.types?.find((type) => type.startsWith("image/")); + if (imageType && typeof item.getType === "function") { + const imageBlob = await item.getType(imageType); + const image = document.createElement("img"); + image.src = await blobToDataUrl(imageBlob); + image.alt = ""; + container.appendChild(image); + } + } + + if (!container.innerHTML && !container.textContent && !container.children?.length) { + throw new Error("No supported clipboard item types found"); + } + + parent.appendChild(container); + selectElementForCopy(container); + container.remove(); + } + + if (originalWriteText) { + Object.defineProperty(navigator.clipboard, "writeText", { + configurable: true, + value: async (text) => { + try { + await fallbackCopyText(text); + api.logger.log("copied text via fallback", text); + } catch (fallbackError) { + api.logger.warn("text fallback failed; trying original writeText", fallbackError); + return originalWriteText(text); + } + }, + }); + } + + if (originalWrite) { + Object.defineProperty(navigator.clipboard, "write", { + configurable: true, + value: async (items) => { + try { + await fallbackCopyItems(items); + api.logger.log("copied rich clipboard payload via fallback"); + } catch (fallbackError) { + api.logger.warn("rich clipboard fallback failed; trying original write", fallbackError); + return originalWrite(items); + } + }, + }); + } + + Object.defineProperty(navigator.clipboard, PATCH_KEY, { + configurable: false, + enumerable: false, + value: true, + }); + + api.logger.log("installed"); + } catch (error) { + api.logger.error("install failed", error); + } + } + + install(); + window.addEventListener("DOMContentLoaded", install, { once: true }); +}; diff --git a/docs/examples/hello-plugin/main.js b/docs/examples/hello-plugin/main.js new file mode 100644 index 0000000..e676944 --- /dev/null +++ b/docs/examples/hello-plugin/main.js @@ -0,0 +1,20 @@ +/** + * Main process entry example. + * Receives api from Legcord plugin manager. + */ +module.exports.activate = (api) => { + api.logger.log("main entry active"); + + // Example: patch BrowserWindow.getTitle globally in main process. + const unpatch = api.patcher.after("getTitle", api.electron.BrowserWindow.prototype, (_args, ret) => { + if (typeof ret === "string" && !ret.endsWith(" [HelloPlugin]")) { + return `${ret} [HelloPlugin]`; + } + return ret; + }); + + api.onCleanup(() => { + unpatch(); + api.logger.log("main entry cleaned up"); + }); +}; diff --git a/docs/examples/hello-plugin/manifest.json b/docs/examples/hello-plugin/manifest.json new file mode 100644 index 0000000..39964fe --- /dev/null +++ b/docs/examples/hello-plugin/manifest.json @@ -0,0 +1,11 @@ +{ + "id": "hello-plugin", + "name": "Hello Plugin", + "version": "1.0.0", + "description": "Example plugin showing main/preload/renderer entries and function patching.", + "author": "Legcord Docs", + "compatibleVersions": ["*"], + "main": "main.js", + "preload": "preload.js", + "renderer": "renderer.js" +} diff --git a/docs/examples/hello-plugin/preload.js b/docs/examples/hello-plugin/preload.js new file mode 100644 index 0000000..d8a7b6d --- /dev/null +++ b/docs/examples/hello-plugin/preload.js @@ -0,0 +1,29 @@ +/** + * Preload entry example. + * Runs in Legcord preload context with access to DOM and plugin API. + */ +module.exports.activate = (api) => { + api.logger.log("preload entry active"); + + // Example: patch document title setter for demonstration. + const descriptor = Object.getOwnPropertyDescriptor(Document.prototype, "title"); + if (!descriptor?.set) return; + + const patchTarget = { setTitle: descriptor.set }; + const unpatch = api.patcher.before("setTitle", patchTarget, (args) => { + if (typeof args[0] === "string" && !args[0].includes("[P]")) { + args[0] = `[P] ${args[0]}`; + } + }); + + Object.defineProperty(document, "title", { + configurable: true, + get: descriptor.get?.bind(document), + set: (value) => patchTarget.setTitle.call(document, value), + }); + + api.onCleanup(() => { + unpatch(); + api.logger.log("preload entry cleaned up"); + }); +}; diff --git a/docs/examples/hello-plugin/renderer.js b/docs/examples/hello-plugin/renderer.js new file mode 100644 index 0000000..3bd3c1a --- /dev/null +++ b/docs/examples/hello-plugin/renderer.js @@ -0,0 +1,18 @@ +/** + * Renderer entry example. + * Runs in the Discord page context. + * + * In renderer entries, expose activate function through module.exports. + */ +module.exports.activate = (api) => { + api.logger.log("renderer entry active"); + + // Example: patch console.log in renderer just to show before/instead/after usage. + const unpatchBefore = api.patcher.before("log", console, (args) => { + args.unshift("[HelloPlugin]"); + }); + + const unpatchAfter = api.patcher.after("log", console, (_args, ret) => ret); + void unpatchBefore; + void unpatchAfter; +}; diff --git a/docs/plugin-system.md b/docs/plugin-system.md new file mode 100644 index 0000000..bc47ed1 --- /dev/null +++ b/docs/plugin-system.md @@ -0,0 +1,130 @@ +# Legcord Plugin System + +Legcord now supports filesystem plugins loaded from: + +`/plugins//` + +Each plugin can provide separate runtime entries for: + +- `main` (Electron main process) +- `preload` (Legcord preload context) +- `renderer` (Discord page context) + +## Manifest + +Create a `manifest.json` in your plugin folder: + +```json +{ + "id": "example-plugin", + "name": "Example Plugin", + "version": "1.0.0", + "description": "Example plugin with all three targets", + "author": "you", + "compatibleVersions": ["1.3.x"], + "main": "main.js", + "preload": "preload.js", + "renderer": "renderer.js" +} +``` + +Required fields: + +- `id` +- `name` +- `version` + +Optional fields: + +- `description` +- `author` +- `compatibleVersions` +- `main` +- `preload` +- `renderer` + +`compatibleVersions` supports exact versions and `x` wildcard prefixes: + +- `"1.3.0"` (exact) +- `"1.3.x"` (any patch in `1.3`) +- `"*"` (all versions) + +If the running Legcord version does not match, the plugin is marked incompatible and cannot be enabled/loaded. +Plugins are disabled by default until explicitly enabled in the Plugins settings page. + +## Lifecycle + +Main and preload entries can export either: + +- `activate(api)` named export +- default export function + +Renderer entries run as plain script files and can expose: + +- `module.exports.activate = (api) => { ... }` +- `module.exports.default = (api) => { ... }` +- `globalThis.activatePlugin = (api) => { ... }` + +## Plugin Control API + +From `window.legcord.plugins`: + +- `list()` +- `setEnabled(id, enabled)` +- `reload(id)` + +Main-process entries are enabled/disabled live. Preload/renderer entries are loaded on startup/navigation and will reflect enable state on next load. + +## Patcher API (Spitroast-style) + +Plugin APIs include: + +- `api.patcher.before(name, parent, callback, oneTime?)` +- `api.patcher.after(name, parent, callback, oneTime?)` +- `api.patcher.instead(name, parent, callback, oneTime?)` + +Callbacks use the same semantics as Spitroast (`args` mutation/replacement, return value replacement, instead chaining). +The return value is an `unpatch()` function. + +### Example + +```js +export function activate(api) { + const unpatch = api.patcher.before("fetch", window, (args) => { + api.logger.log("fetch called with", args[0]); + }); + + api.onCleanup(() => { + unpatch(); + }); +} +``` + +## Notes + +- Plugin enable state is stored in config under `pluginStates`. +- Plugin folders are scanned from disk at startup. +- Invalid manifests or missing entry files are skipped safely. + +## Full Example Plugin + +A complete example is available at: + +- `docs/examples/hello-plugin/manifest.json` +- `docs/examples/hello-plugin/main.js` +- `docs/examples/hello-plugin/preload.js` +- `docs/examples/hello-plugin/renderer.js` + +A practical renderer-only workaround plugin is also available at: + +- `docs/examples/clipboard-fallback-plugin/manifest.json` +- `docs/examples/clipboard-fallback-plugin/renderer.js` + +To test it: + +1. Copy `docs/examples/hello-plugin` into your runtime plugins directory: + - `/plugins/hello-plugin` +2. Restart Legcord or use the Plugins settings page: + - enable/disable + - reload +3. Open DevTools and watch for `[Plugin:hello-plugin]` logs. diff --git a/electron-builder.ts b/electron-builder.ts index d836f87..de9b4ff 100644 --- a/electron-builder.ts +++ b/electron-builder.ts @@ -1,10 +1,33 @@ import type { Configuration } from "electron-builder"; +import { applyAppImageSandboxFix } from "./scripts/build/sandboxFix.mjs"; +import debianLicence from "./scripts/spdxLicenceDebianFormat"; +import { ACTION_FRIENDLY_NAMES, EXCLUDED_FROM_SHORTCUTS, ValidActions } from "./src/common/commandDefinitions"; + +const desktopActions = (exec: "AppRun" | "/opt/Legcord/legcord") => + Object.fromEntries( + (Object.values(ValidActions) as ValidActions[]) + .filter((action) => !EXCLUDED_FROM_SHORTCUTS.includes(action)) + .map((action) => [ + action, + { + Name: ACTION_FRIENDLY_NAMES[action], + Exec: `${exec} --${action} %U`, + }, + ]), + ); + +const availableActions = (Object.values(ValidActions) as ValidActions[]) + .filter((action) => !EXCLUDED_FROM_SHORTCUTS.includes(action)) + .join(";"); + export const config: Configuration = { appId: "app.legcord.Legcord", productName: "Legcord", + // Biome treats electron-builder macro placeholders as template syntax. + // biome-ignore lint/suspicious/noTemplateCurlyInString: electron-builder expands these placeholders. artifactName: "Legcord-${version}-${os}-${arch}.${ext}", - beforePack: "./scripts/build/sandboxFix.cjs", + beforePack: applyAppImageSandboxFix, protocols: [ { name: "Discord", @@ -18,6 +41,8 @@ export const config: Configuration = { extendInfo: { NSMicrophoneUsageDescription: "Legcord requires access to the microphone to function properly.", NSCameraUsageDescription: "Legcord requires access to the camera to function properly.", + NSAudioCaptureUsageDescription: + "Legcord requires access to system audio to share sound during screenshare.", NSCameraUseContinuityCameraDeviceType: true, "com.apple.security.device.audio-input": true, "com.apple.security.device.camera": true, @@ -37,6 +62,19 @@ export const config: Configuration = { }, }, + appImage: { + desktop: { + entry: { + Actions: availableActions, + }, + desktopActions: desktopActions("AppRun"), + }, + }, + + pacman: { + depends: ["gtk3", "libnotify", "xdg-utils", "at-spi2-core", "alsa-lib", "nspr", "nss"], + }, + nsis: { oneClick: false, allowToChangeInstallationDirectory: true, @@ -64,7 +102,14 @@ export const config: Configuration = { deb: { category: "Network", icon: "build/icon.icns", - depends: ["libgbm-dev", "libasound2", "libnspr4", "libnss3"], + depends: ["libasound2", "libnspr4", "libnss3", "libasound2t64", "libasound2-plugins"], + desktop: { + entry: { + Actions: availableActions, + }, + desktopActions: desktopActions("/opt/Legcord/legcord"), + }, + fpm: [`${debianLicence()}=/usr/share/doc/legcord/copyright`], }, files: [ @@ -81,6 +126,20 @@ export const config: Configuration = { electronDownload: { cache: ".cache", }, + + electronFuses: { + runAsNode: false, + enableCookieEncryption: false, + enableNodeOptionsEnvironmentVariable: false, + enableNodeCliInspectArguments: false, + enableEmbeddedAsarIntegrityValidation: false, + onlyLoadAppFromAsar: true, + loadBrowserProcessSpecificV8Snapshot: false, + grantFileProtocolExtraPrivileges: false, + }, + toolsets: { + appimage: "1.0.3", + }, }; export default config; diff --git a/meta/app.legcord.Legcord.metainfo.xml b/meta/app.legcord.Legcord.metainfo.xml index d30a1c1..278b8c0 100644 --- a/meta/app.legcord.Legcord.metainfo.xml +++ b/meta/app.legcord.Legcord.metainfo.xml @@ -4,7 +4,7 @@ app.legcord.Legcord Legcord Legcord is a custom client designed to enhance your Discord experience while keeping everything lightweight. - + Legcord Contributors CC0-1.0 @@ -16,19 +16,63 @@ - Legcord settings page on MacOS - https://github.com/Legcord/Legcord/blob/77e2ccafb221936a99654c237cb385d486780bc7/assets/screenshots/settings.png + Legcord settings page on macOS + https://raw.githubusercontent.com/Legcord/Legcord/refs/tags/v1.2.4/assets/screenshots/settings.png Legcord settings open with Shelter configs - https://github.com/Legcord/Legcord/blob/77e2ccafb221936a99654c237cb385d486780bc7/assets/screenshots/shelter.png + https://raw.githubusercontent.com/Legcord/Legcord/refs/tags/v1.2.4/assets/screenshots/shelter.png Legcord settings open with custom keybind settings shown - https://github.com/Legcord/Legcord/blob/77e2ccafb221936a99654c237cb385d486780bc7/assets/screenshots/keybinds.png + https://raw.githubusercontent.com/Legcord/Legcord/refs/tags/v1.2.4/assets/screenshots/keybinds.png + + https://github.com/Legcord/Legcord/releases/tag/v1.2.4 + +

What’s New in Legcord v1.2.4 ✨

+
    +
  • 🐧 **Huge streaming performance improvements on Linux**
  • +
+
    +
  • 🔄 **Separate “No Bundle Updates” setting for each client mod**
  • +
+
    +
  • 💾 **Backup & Restore added**
  • +
+
    +
  • 🎮 **Improved macOS game detection**
  • +
+
    +
  • 🛡️ **New CSP options setting**
  • +
+
    +
  • 🪟 **Window material setting added** for supported systems ([https://github.com/Legcord/Legcord/pull/1025](https://github.com/Legcord/Legcord/pull/1025) by @passionvine).
  • +
  • 📦 **OPTIONAL automatic Linux updates added** ([https://github.com/Legcord/Legcord/pull/1027](https://github.com/Legcord/Legcord/pull/1027) by @KarboXXX).
  • +
  • 🎛️ **Support banner popup added**
  • +
+
    +
  • 🖥️ Fixed Linux `StartupWMClass` to `legcord` ([https://github.com/Legcord/Legcord/pull/1021](https://github.com/Legcord/Legcord/pull/1021) by @khancyr).
  • +
  • 📺 Fixed screensharing quality, FPS, and audio ([https://github.com/Legcord/Legcord/pull/1026](https://github.com/Legcord/Legcord/pull/1026) by @KarboXXX).
  • +
  • 🎚️ Fixed scrollbar styling on file preview ([https://github.com/Legcord/Legcord/pull/1024](https://github.com/Legcord/Legcord/pull/1024) by @MahmodZE).
  • +
  • 🔊 Fixed mute toggle sound effect playback ([https://github.com/Legcord/Legcord/pull/1031](https://github.com/Legcord/Legcord/pull/1031) by @psw01).
  • +
  • 🎮 Fixed RPC status not disappearing properly ([https://github.com/Legcord/Legcord/pull/1032](https://github.com/Legcord/Legcord/pull/1032) by @Adrigamer2950).
  • +
  • 🔐 Fixed security prompt appearing with no passkey ([https://github.com/Legcord/Legcord/pull/1033](https://github.com/Legcord/Legcord/pull/1033) by @dequeues).
  • +
  • 🇫🇷 Added missing French translations for settings categories ([https://github.com/Legcord/Legcord/pull/1028](https://github.com/Legcord/Legcord/pull/1028) by @youtsuhodev).
  • +
  • ⌨️ Polished keybinds UI ([https://github.com/Legcord/Legcord/pull/1038](https://github.com/Legcord/Legcord/pull/1038) by @youtsuhodev).
  • +
  • 🎥 Fixed camera/mic device switching not working ([https://github.com/Legcord/Legcord/pull/1051](https://github.com/Legcord/Legcord/pull/1051) by @narasaka).
  • +
  • ⚙️ Fixed settings shortcut behavior ([https://github.com/Legcord/Legcord/pull/1046](https://github.com/Legcord/Legcord/pull/1046) by @KirobotDev).
  • +
  • 📏 Fixed dropdown height limit in Games settings ([https://github.com/Legcord/Legcord/pull/1045](https://github.com/Legcord/Legcord/pull/1045) by @youtsuhodev).
  • +
  • 📐 Fixed dropdown max height calculation ([https://github.com/Legcord/Legcord/pull/1059](https://github.com/Legcord/Legcord/pull/1059) by @MahmodZE).
  • +
  • 🧹 Cleanup of old fix-me notes and code polish ([https://github.com/Legcord/Legcord/pull/1060](https://github.com/Legcord/Legcord/pull/1060) by @KirobotDev).
  • +
  • 📂 Fixed restore zip path traversal issue ([https://github.com/Legcord/Legcord/pull/1061](https://github.com/Legcord/Legcord/pull/1061) by @youtsuhodev).
  • +
  • 🛡️ Added stricter CSP, better permission handling, and mod validation ([https://github.com/Legcord/Legcord/pull/1069](https://github.com/Legcord/Legcord/pull/1069) by @KirobotDev).
  • +
  • Fixed first time setup
  • +
+
+
https://github.com/Legcord/Legcord/releases/tag/v1.2.3 @@ -231,10 +275,6 @@ https://github.com/Legcord/Legcord/releases/tag/v1.0.2 - - https://github.com/Legcord/Legcord/releases/tag/devbuild - - https://github.com/Legcord/Legcord/releases/tag/v1.0.0 @@ -278,4 +318,4 @@ Legcord Equicord - \ No newline at end of file + diff --git a/package.json b/package.json index 4c6c26b..c656032 100644 --- a/package.json +++ b/package.json @@ -1,15 +1,15 @@ { "name": "legcord", - "version": "1.2.4", + "version": "1.3.0", "description": "Legcord is a custom client designed to enhance your Discord experience while keeping everything lightweight.", "main": "ts-out/main.js", "engines": { - "node": ">=22" + "node": ">=26" }, "scripts": { - "build:dev": "rollup -c --environment BUILD:dev && tsx scripts/copyVenmic.mts", + "build:dev": "rollup -c --environment BUILD:dev && node --experimental-strip-types scripts/copyVenmic.ts", "build:plugins": "lune ci --repoSubDir src/shelter --to ts-out/plugins", - "build": "pnpm build:plugins && rolldown -c rolldown.config.js && tsx scripts/copyVenmic.mts", + "build": "pnpm build:plugins && rolldown -c rolldown.config.ts && node --experimental-strip-types scripts/copyVenmic.ts", "start": "pnpm run build && electron --trace-warnings --ozone-platform-hint=auto ./ts-out/main.js", "startThemeManager": "pnpm run build:dev && electron ./ts-out/main.js themes", "package": "pnpm run build && electron-builder", @@ -18,7 +18,7 @@ "lint:fix": "biome check --write", "postinstall": "electron-builder install-app-deps", "CIbuild": "pnpm run build && electron-builder --linux zip && electron-builder --windows zip && electron-builder --macos zip", - "updateMeta": "tsx scripts/utils/updateMeta.mts" + "updateMeta": "node --experimental-strip-types scripts/utils/updateMeta.ts" }, "repository": { "type": "git", @@ -32,39 +32,45 @@ }, "homepage": "https://github.com/Legcord/Legcord#readme", "devDependencies": { - "@biomejs/biome": "1.9.4", - "@rolldown-plugin/solid": "^0.0.4", - "@rollup/plugin-esm-shim": "^0.1.7", + "@biomejs/biome": "2.5.5", + "@rolldown-plugin/solid": "^0.1.0", + "@rollup/plugin-esm-shim": "^0.1.8", "@types/adm-zip": "^0.5.8", - "@types/minimatch": "^6.0.0", - "@types/node": "^22.10.1", - "@types/ws": "^8.5.13", - "@uwu/lune": "^1.6.2", + "@types/node": "^26.1.1", + "@types/ws": "^8.18.1", + "@uwu/lune": "^1.6.3", "@uwu/shelter-defs": "^1.5.1", - "babel-preset-solid": "^1.9.3", - "electron": "41.2.0", - "electron-builder": "26.0.20", - "lucide-solid": "^0.475.0", - "rolldown": "1.0.0-rc.15", + "@uwu/shelter-ui": "^0.0.6", + "@xmldom/xmldom": "^0.9.10", + "app-builder-lib": "^26.15.3", + "babel-preset-solid": "^1.9.12", + "electron": "43.2.0", + "electron-builder": "26.15.7", + "lucide-solid": "^1.26.0", + "monaco-editor": "0.56.0", + "rolldown": "1.2.0", "rollup-plugin-copy": "^3.5.0", - "solid-js": "^1.9.3", - "solid-motionone": "^1.0.3", - "tsx": "^4.19.2", - "typescript": "^5.7.2", - "xml-formatter": "^3.6.6" + "solid-js": "^1.9.14", + "solid-motionone": "^1.0.4", + "spdx-license-list": "^6.11.0", + "typescript": "^7.0.2", + "xml-formatter": "^3.7.0" }, "dependencies": { - "adm-zip": "^0.5.16", - "arrpc": "https://github.com/Legcord/arrpc.git#efe7589762470d32b9ba10d529be5acc23cd0e19", - "electron-context-menu": "^4.0.4", + "@jellybrick/dbus-next": "^0.11.1", + "adm-zip": "^0.6.0", + "arrpc": "github:Legcord/arrpc#efe7589762470d32b9ba10d529be5acc23cd0e19", + "electron-context-menu": "^4.1.2", "electron-is-dev": "^3.0.1", + "electron-updater": "^6.8.9", + "ms": "^2.1.3", + "spitroast": "^2.1.6", "tslib": "^2.8.1", - "electron-updater": "^6.6.2", - "ws": "^8.18.0" + "ws": "^8.21.1" }, "optionalDependencies": { - "@vencord/venmic": "^6.1.0" + "@vencord/venmic": "^7.1.0" }, - "packageManager": "pnpm@10.11.0", + "packageManager": "pnpm@11.10.0", "package-manager-strict": false } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6b0dd48..b6830c8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,367 +4,380 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + yauzl: ^3.3.1 + importers: .: dependencies: + '@jellybrick/dbus-next': + specifier: ^0.11.1 + version: 0.11.1 adm-zip: - specifier: ^0.5.16 - version: 0.5.16 + specifier: ^0.6.0 + version: 0.6.0 arrpc: - specifier: https://github.com/Legcord/arrpc.git#efe7589762470d32b9ba10d529be5acc23cd0e19 + specifier: github:Legcord/arrpc#efe7589762470d32b9ba10d529be5acc23cd0e19 version: https://codeload.github.com/Legcord/arrpc/tar.gz/efe7589762470d32b9ba10d529be5acc23cd0e19 electron-context-menu: - specifier: ^4.0.4 + specifier: ^4.1.2 version: 4.1.2 electron-is-dev: specifier: ^3.0.1 version: 3.0.1 electron-updater: - specifier: ^6.6.2 - version: 6.8.3 + specifier: ^6.8.9 + version: 6.8.9 + ms: + specifier: ^2.1.3 + version: 2.1.3 + spitroast: + specifier: ^2.1.6 + version: 2.1.6 tslib: specifier: ^2.8.1 version: 2.8.1 ws: - specifier: ^8.18.0 - version: 8.20.0 - optionalDependencies: - '@vencord/venmic': - specifier: ^6.1.0 - version: 6.1.0 + specifier: ^8.21.1 + version: 8.21.1 devDependencies: '@biomejs/biome': - specifier: 1.9.4 - version: 1.9.4 + specifier: 2.5.5 + version: 2.5.5 '@rolldown-plugin/solid': - specifier: ^0.0.4 - version: 0.0.4(csstype@3.2.3)(rolldown@1.0.0-rc.15)(seroval@1.5.0)(solid-js@1.9.12) + specifier: ^0.1.0 + version: 0.1.0(csstype@3.2.3)(rolldown@1.2.0)(seroval@1.5.6)(solid-js@1.9.14) '@rollup/plugin-esm-shim': - specifier: ^0.1.7 + specifier: ^0.1.8 version: 0.1.8 '@types/adm-zip': specifier: ^0.5.8 version: 0.5.8 - '@types/minimatch': - specifier: ^6.0.0 - version: 6.0.0 '@types/node': - specifier: ^22.10.1 - version: 22.19.15 + specifier: ^26.1.1 + version: 26.1.1 '@types/ws': - specifier: ^8.5.13 + specifier: ^8.18.1 version: 8.18.1 '@uwu/lune': - specifier: ^1.6.2 - version: 1.6.2 + specifier: ^1.6.3 + version: 1.6.3 '@uwu/shelter-defs': specifier: ^1.5.1 version: 1.5.1 + '@uwu/shelter-ui': + specifier: ^0.0.6 + version: 0.0.6(solid-js@1.9.14) + '@xmldom/xmldom': + specifier: ^0.9.10 + version: 0.9.10 + app-builder-lib: + specifier: ^26.15.3 + version: 26.15.3(dmg-builder@26.15.3)(electron-builder-squirrel-windows@26.15.3) babel-preset-solid: - specifier: ^1.9.3 - version: 1.9.12(@babel/core@7.28.6)(solid-js@1.9.12) + specifier: ^1.9.12 + version: 1.9.12(@babel/core@8.0.1)(solid-js@1.9.14) electron: - specifier: 41.2.0 - version: 41.2.0 + specifier: 43.2.0 + version: 43.2.0 electron-builder: - specifier: 26.0.20 - version: 26.0.20(electron-builder-squirrel-windows@26.4.0) + specifier: 26.15.7 + version: 26.15.7(electron-builder-squirrel-windows@26.15.3) lucide-solid: - specifier: ^0.475.0 - version: 0.475.0(solid-js@1.9.12) + specifier: ^1.26.0 + version: 1.26.0(solid-js@1.9.14) + monaco-editor: + specifier: 0.56.0 + version: 0.56.0 rolldown: - specifier: 1.0.0-rc.15 - version: 1.0.0-rc.15 + specifier: 1.2.0 + version: 1.2.0 rollup-plugin-copy: specifier: ^3.5.0 version: 3.5.0 solid-js: - specifier: ^1.9.3 - version: 1.9.12 + specifier: ^1.9.14 + version: 1.9.14 solid-motionone: - specifier: ^1.0.3 - version: 1.0.4(solid-js@1.9.12) - tsx: - specifier: ^4.19.2 - version: 4.21.0 + specifier: ^1.0.4 + version: 1.0.4(solid-js@1.9.14) + spdx-license-list: + specifier: ^6.11.0 + version: 6.11.0 typescript: - specifier: ^5.7.2 - version: 5.9.3 + specifier: ^7.0.2 + version: 7.0.2 xml-formatter: - specifier: ^3.6.6 + specifier: ^3.7.0 version: 3.7.0 + optionalDependencies: + '@vencord/venmic': + specifier: ^7.1.0 + version: 7.1.0 packages: - 7zip-bin@5.2.0: - resolution: {integrity: sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A==} - - '@babel/code-frame@7.28.6': - resolution: {integrity: sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==} + '@babel/code-frame@7.29.7': + resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} engines: {node: '>=6.9.0'} - '@babel/code-frame@8.0.0-rc.3': - resolution: {integrity: sha512-585nwYQGQKKc+jMIAPeZJ+aGMn4FHmIUUjLZa9zI7mslvYmShnx0u7rFA4gliRip6S2vkwTYrMxPeXadkKW93Q==} - engines: {node: ^20.19.0 || >=22.12.0} + '@babel/code-frame@8.0.0': + resolution: {integrity: sha512-dYYg153EyN2Ekbqw2zAsbd6/JR+9N2SEoC7YV2GyyqMM7x9bLDTjBD6XBhSMLH0wtIVyJj03jWNriQhaN+eoCw==} + engines: {node: ^22.18.0 || >=24.11.0} - '@babel/compat-data@7.28.6': - resolution: {integrity: sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==} + '@babel/compat-data@7.29.7': + resolution: {integrity: sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==} engines: {node: '>=6.9.0'} - '@babel/compat-data@8.0.0-rc.3': - resolution: {integrity: sha512-TlS7d9xYz/93xC8ovkRBwTKPodbwPfzTn7TxUgZo4c3LwpPINnScqIlN0QRDE/x1S4C1bmyqxGmAZUIC0buW0A==} - engines: {node: ^20.19.0 || >=22.12.0} + '@babel/compat-data@8.0.0': + resolution: {integrity: sha512-DOjnob/cXOUgDOozCDeq/aK2p5y8dUIVdf6tNhEV1HQRd6I8aQ4f4fbtHRVEvb6lP3BGomrKHiS8ICAASSVQSw==} + engines: {node: ^22.18.0 || >=24.11.0} - '@babel/core@7.28.6': - resolution: {integrity: sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==} + '@babel/core@7.29.7': + resolution: {integrity: sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==} engines: {node: '>=6.9.0'} - '@babel/core@8.0.0-rc.3': - resolution: {integrity: sha512-ov5mBbHiosqX1eqt8nN0JM7VuhirO6V8lln5rUXNZpNB+a9NnPTVYeDqSTBkf9C6GmFq3fnFlGT8eg3QBI7jJQ==} - engines: {node: ^20.19.0 || >=22.12.0} - peerDependencies: - '@babel/preset-typescript': ^8.0.0-0 - peerDependenciesMeta: - '@babel/preset-typescript': - optional: true + '@babel/core@8.0.1': + resolution: {integrity: sha512-5FgxM4dLQpMJHSiVATk8foW263dVHQHBVpXYiimNECVWG01f4nFyEbQixeT6Mwvg7TayREJ2gpKl3o2RoMdnqw==} + engines: {node: ^22.18.0 || >=24.11.0} - '@babel/generator@7.28.6': - resolution: {integrity: sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==} + '@babel/generator@7.29.7': + resolution: {integrity: sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==} engines: {node: '>=6.9.0'} - '@babel/generator@8.0.0-rc.3': - resolution: {integrity: sha512-em37/13/nR320G4jab/nIIHZgc2Wz2y/D39lxnTyxB4/D/omPQncl/lSdlnJY1OhQcRGugTSIF2l/69o31C9dA==} - engines: {node: ^20.19.0 || >=22.12.0} + '@babel/generator@8.0.0': + resolution: {integrity: sha512-NT9NrVwJsbSV6Y2FSstWa71EETOnzrjkL5/wX3D2mYHtKM+qvqB1DvR4D0Setb/gDBsHzRICifwEWMO8CnTF6g==} + engines: {node: ^22.18.0 || >=24.11.0} - '@babel/helper-annotate-as-pure@7.27.3': - resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + '@babel/helper-annotate-as-pure@7.29.7': + resolution: {integrity: sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.28.6': - resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + '@babel/helper-compilation-targets@7.29.7': + resolution: {integrity: sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@8.0.0-rc.3': - resolution: {integrity: sha512-UXlT7t103KBJjiphN7Ij9DtELX2Q5uk1xMle7oN/eckxR8dmJyvbFsIm5u+cY0KZyF7qNkAiLsJljEPix1yfKg==} - engines: {node: ^20.19.0 || >=22.12.0} + '@babel/helper-compilation-targets@8.0.0': + resolution: {integrity: sha512-JwculLABZvyPvyLBpwU/E/IbH2uM3mnxNtIJpxnIfb24y1PrdVxK5Dqjle4DpgqpGRnwgC7G8IkzPdSXZrO1Ew==} + engines: {node: ^22.18.0 || >=24.11.0} - '@babel/helper-create-class-features-plugin@7.28.6': - resolution: {integrity: sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==} + '@babel/helper-create-class-features-plugin@7.29.7': + resolution: {integrity: sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-globals@7.28.0': - resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + '@babel/helper-globals@7.29.7': + resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==} engines: {node: '>=6.9.0'} - '@babel/helper-globals@8.0.0-rc.3': - resolution: {integrity: sha512-rwtdZPunoa/IAlcZhgDoLxROXPW5evSN7SXMdObS8vNt7Wu6fCf8nLPFcuuhLCzeRoIrGNKx08v/XEQ4riQDGg==} - engines: {node: ^20.19.0 || >=22.12.0} + '@babel/helper-globals@8.0.0': + resolution: {integrity: sha512-lLozHOM6sWWlxNo8CYqHy4MBZeTvHXNgVPBfPOGsjPKUzHC2Az9QwB6gxdQmpwHl6GlQtbGgS+lj5887guDiLw==} + engines: {node: ^22.18.0 || >=24.11.0} - '@babel/helper-member-expression-to-functions@7.28.5': - resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} + '@babel/helper-member-expression-to-functions@7.29.7': + resolution: {integrity: sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==} engines: {node: '>=6.9.0'} '@babel/helper-module-imports@7.18.6': resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.28.6': - resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + '@babel/helper-module-imports@7.29.7': + resolution: {integrity: sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@8.0.0-rc.3': - resolution: {integrity: sha512-D0kMl961jaPXb1Cb9ZehcoY4OOgPo1klsrry8BDuJWF6xO6a+72ZF6EH4Z5i94jcLYwJvApsKLytQvS4LtPAyg==} - engines: {node: ^20.19.0 || >=22.12.0} + '@babel/helper-module-imports@8.0.0': + resolution: {integrity: sha512-NZ7mSS93o4ndX4KrbD7W8Sf3QT8Qe24PrnFyUcuOPDzK6faqDFKjY9RG7he7+I7FdiQ4llpnosFqzrXa+Vy3Ew==} + engines: {node: ^22.18.0 || >=24.11.0} - '@babel/helper-module-transforms@7.28.6': - resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + '@babel/helper-module-transforms@7.29.7': + resolution: {integrity: sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-optimise-call-expression@7.27.1': - resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + '@babel/helper-optimise-call-expression@7.29.7': + resolution: {integrity: sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==} engines: {node: '>=6.9.0'} - '@babel/helper-plugin-utils@7.28.6': - resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} + '@babel/helper-plugin-utils@7.29.7': + resolution: {integrity: sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==} engines: {node: '>=6.9.0'} - '@babel/helper-plugin-utils@8.0.0-rc.3': - resolution: {integrity: sha512-1+lvhojDf75++IwFRWrch4BBaznB2Z99GCfggHFWEKJ8B40iovZ8KqP0kDeb60ThuAa7WxCbtuYHfP5BtJL1kA==} - engines: {node: ^20.19.0 || >=22.12.0} + '@babel/helper-plugin-utils@8.0.1': + resolution: {integrity: sha512-3PKFgjTyPlhFhorfP+SjKQxLViIL++zWjFOO4hGriYU+Bsm983DxEM1JmDRJVWXV0O9npu+xXRqz7Pbd3mh70g==} + engines: {node: ^22.18.0 || >=24.11.0} peerDependencies: - '@babel/core': ^8.0.0-rc.3 + '@babel/core': ^8.0.0 - '@babel/helper-replace-supers@7.28.6': - resolution: {integrity: sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==} + '@babel/helper-replace-supers@7.29.7': + resolution: {integrity: sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-skip-transparent-expression-wrappers@7.27.1': - resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + '@babel/helper-skip-transparent-expression-wrappers@7.29.7': + resolution: {integrity: sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==} engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.27.1': - resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + '@babel/helper-string-parser@7.29.7': + resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@8.0.0-rc.3': - resolution: {integrity: sha512-AmwWFx1m8G/a5cXkxLxTiWl+YEoWuoFLUCwqMlNuWO1tqAYITQAbCRPUkyBHv1VOFgfjVOqEj6L3u15J5ZCzTA==} - engines: {node: ^20.19.0 || >=22.12.0} + '@babel/helper-string-parser@8.0.0': + resolution: {integrity: sha512-6mJgmFFFIIO82vvoLt9XtRC7/TkzXfts1t/SpRX4IHSzMgqoPYCWesVu1udUPUWioAE/2fcG6WuI8zrkE1gwrg==} + engines: {node: ^22.18.0 || >=24.11.0} - '@babel/helper-validator-identifier@7.28.5': - resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + '@babel/helper-validator-identifier@7.29.7': + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@8.0.0-rc.3': - resolution: {integrity: sha512-8AWCJ2VJJyDFlGBep5GpaaQ9AAaE/FjAcrqI7jyssYhtL7WGV0DOKpJsQqM037xDbpRLHXsY8TwU7zDma7coOw==} - engines: {node: ^20.19.0 || >=22.12.0} + '@babel/helper-validator-identifier@8.0.4': + resolution: {integrity: sha512-4wFaiLd0bVo4cIoTXI3zKI038NIWE/cr3jvBjejOVYVxV/m8Ltav1USiGzG1fmS5J2RhgEOgXNNK46cRPnRsrg==} + engines: {node: ^22.18.0 || >=24.11.0} - '@babel/helper-validator-option@7.27.1': - resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + '@babel/helper-validator-option@7.29.7': + resolution: {integrity: sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@8.0.0-rc.3': - resolution: {integrity: sha512-wpzZ9KycQDqmJct4ee/ihua2KKdW/MXTDidD4Ya7HdUHL+Jp5zBZTj8oNrxc8wp5Qr4sofKgZF1GIyymfdq7+g==} - engines: {node: ^20.19.0 || >=22.12.0} + '@babel/helper-validator-option@8.0.0': + resolution: {integrity: sha512-U4Dybxh4WESWHt5XhBeExi4DrY0/DNK1aHpQbsrQXCUbFHuMweT0TpLEWKvaraV2Y6fS+ZXunsZ8zIuZIgvF2Q==} + engines: {node: ^22.18.0 || >=24.11.0} - '@babel/helpers@7.28.6': - resolution: {integrity: sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==} + '@babel/helpers@7.29.7': + resolution: {integrity: sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==} engines: {node: '>=6.9.0'} - '@babel/helpers@8.0.0-rc.3': - resolution: {integrity: sha512-dbPuulmsPOwIAXP4pGsKiAv1E50pKYmAJfWXYytCwLpgj6IDNUFAzGuVVemaphYP/WniKsCf42+Cfo4xpc4jjQ==} - engines: {node: ^20.19.0 || >=22.12.0} + '@babel/helpers@8.0.0': + resolution: {integrity: sha512-wfbi91pM3py96oIiJEz7qIpyXDytgr9zQC1HEWwlGNVRAEmItuU/0a41ZUKu1sJGyhhOIpc4t5vk4PYzt8wpsg==} + engines: {node: ^22.18.0 || >=24.11.0} - '@babel/parser@7.28.6': - resolution: {integrity: sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==} + '@babel/parser@7.29.7': + resolution: {integrity: sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/parser@8.0.0-rc.3': - resolution: {integrity: sha512-B20dvP3MfNc/XS5KKCHy/oyWl5IA6Cn9YjXRdDlCjNmUFrjvLXMNUfQq/QUy9fnG2gYkKKcrto2YaF9B32ToOQ==} - engines: {node: ^20.19.0 || >=22.12.0} + '@babel/parser@8.0.4': + resolution: {integrity: sha512-srpptsAkEbbNIC/q8nT7o+m6CQe8CJUTV/t7MYc9NnWlgYVtHOb7JH6SorxMhN0kuRJjVqXbKClG6xSbPtzz+g==} + engines: {node: ^22.18.0 || >=24.11.0} hasBin: true - '@babel/plugin-syntax-jsx@7.28.6': - resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==} + '@babel/plugin-syntax-jsx@7.29.7': + resolution: {integrity: sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-typescript@7.28.6': - resolution: {integrity: sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==} + '@babel/plugin-syntax-typescript@7.29.7': + resolution: {integrity: sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-commonjs@7.28.6': - resolution: {integrity: sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==} + '@babel/plugin-transform-modules-commonjs@7.29.7': + resolution: {integrity: sha512-j0vCldybPC5b5dwCQOJ21uKtHzt7hxLygJTg9eF1ScfaikEDNfzn94XoW5Fi+seBR0nCyL23xaBFFkq7dTM8XQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typescript@7.28.6': - resolution: {integrity: sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==} + '@babel/plugin-transform-typescript@7.29.7': + resolution: {integrity: sha512-jK52h8LaLc7JarhQV2ofeFMts4H7vnOXnqZNA6fYglBTZewRBE51KWt3BUltW1P+KoPsYkHoJeXePuz4zo2LMw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/preset-typescript@7.28.5': - resolution: {integrity: sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==} + '@babel/preset-typescript@7.29.7': + resolution: {integrity: sha512-/Foi8vKY2EVbed/1eZx0gJEEwHAIxogrySI7rULcRIvhZzbvoE/b5qG5Ghc0WKAFKOHA9SD1x7RsFlOYdutIiQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/template@7.28.6': - resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + '@babel/template@7.29.7': + resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==} engines: {node: '>=6.9.0'} - '@babel/template@8.0.0-rc.3': - resolution: {integrity: sha512-9iet2svxZhCGgmt/b6M3Fbmy2i+OgjhXMDWNqDTBrNvb9Cc60NgETNIaJq6b0wICiCqpsFdIt8NYXMXyCQU6jA==} - engines: {node: ^20.19.0 || >=22.12.0} + '@babel/template@8.0.0': + resolution: {integrity: sha512-eAD0QW/AlbamBbw0FeGiwasbCVPq5ncW0HNVyLP3B9czqLyh4gvw+5JTSNt6le9+ziAU7mqDZsKTHf3jTb4chQ==} + engines: {node: ^22.18.0 || >=24.11.0} - '@babel/traverse@7.28.6': - resolution: {integrity: sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==} + '@babel/traverse@7.29.7': + resolution: {integrity: sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==} engines: {node: '>=6.9.0'} - '@babel/traverse@8.0.0-rc.3': - resolution: {integrity: sha512-3gvZCynaX+zxYZ2v5odaBBcc9eT4Yr7Gf16l3QSEvvBPVyMSZbYhsGAZfO79kjOCNJY2j6rWvNkWl1ZwYa64lQ==} - engines: {node: ^20.19.0 || >=22.12.0} + '@babel/traverse@8.0.4': + resolution: {integrity: sha512-bZnmqzGG8UZneG1lLxBoWIH0G6Gr1D846Yu4/3XnY6FhCndMR49u26nTY08u/dAxWmLWF9vGQOuC+84FfIUoeg==} + engines: {node: ^22.18.0 || >=24.11.0} - '@babel/types@7.28.6': - resolution: {integrity: sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==} + '@babel/types@7.29.7': + resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==} engines: {node: '>=6.9.0'} - '@babel/types@7.29.0': - resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} - engines: {node: '>=6.9.0'} + '@babel/types@8.0.4': + resolution: {integrity: sha512-eY+Yn3dCqTGmyiq2QRU66lA5FL8lqqqvecHt0fF3uHONIa7ToYsaCiWV8lOKqAs0Rb2SjixiKFROngnulPtt2g==} + engines: {node: ^22.18.0 || >=24.11.0} - '@babel/types@8.0.0-rc.3': - resolution: {integrity: sha512-mOm5ZrYmphGfqVWoH5YYMTITb3cDXsFgmvFlvkvWDMsR9X8RFnt7a0Wb6yNIdoFsiMO9WjYLq+U/FMtqIYAF8Q==} - engines: {node: ^20.19.0 || >=22.12.0} - - '@biomejs/biome@1.9.4': - resolution: {integrity: sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==} + '@biomejs/biome@2.5.5': + resolution: {integrity: sha512-r1S8nFsAG1MY+vJFZALzIvwXAJv6ejDQ0mxP21Tgr9YK3ZFtjrvbBwDdNhx1rUqvccEIeNg20cYCNzl6Cr69pQ==} engines: {node: '>=14.21.3'} hasBin: true - '@biomejs/cli-darwin-arm64@1.9.4': - resolution: {integrity: sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==} + '@biomejs/cli-darwin-arm64@2.5.5': + resolution: {integrity: sha512-kUrAhXVWUrwmAUnV2iXSK7umxKFysTwvqK+Ty6ptUcLY/7T3SnCAjUowE4uvwaEej6nXZ7hu/dTtbokKdsPeag==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [darwin] - '@biomejs/cli-darwin-x64@1.9.4': - resolution: {integrity: sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==} + '@biomejs/cli-darwin-x64@2.5.5': + resolution: {integrity: sha512-DamiYc5bUYZ2uxlfc+RLEPtz1Abb6PO5eTbOkufLpSGwd/7AMQAdxhFYiXmwwkJL8IsT8S7GvdgwDHqaMFAvKw==} engines: {node: '>=14.21.3'} cpu: [x64] os: [darwin] - '@biomejs/cli-linux-arm64-musl@1.9.4': - resolution: {integrity: sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==} + '@biomejs/cli-linux-arm64-musl@2.5.5': + resolution: {integrity: sha512-U4WMl/sy/E/Q73vf15VspakLRRs2LDFcCeBxJnQfXzssb88zpV6PJPaQ3ezhQ7H6Ht2/8bvuZeHgJWzmoxllZg==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] + libc: [musl] - '@biomejs/cli-linux-arm64@1.9.4': - resolution: {integrity: sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==} + '@biomejs/cli-linux-arm64@2.5.5': + resolution: {integrity: sha512-lRKF/pH/1RiYiBKExi3TCZVAtvzEm77aifrvcNiDFrR9WxeAnDUjDnseb6y2XV85mjitLs6SILGm2XG77cHtSQ==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] + libc: [glibc] - '@biomejs/cli-linux-x64-musl@1.9.4': - resolution: {integrity: sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==} + '@biomejs/cli-linux-x64-musl@2.5.5': + resolution: {integrity: sha512-m7wC7tjX5Lrmo69dc4md8FeKpPU1NTCY1v7xUoQQ2vadWwNnBS0KZOG8471otFPHrTHihQJAjQPgMObpLvDe6A==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] + libc: [musl] - '@biomejs/cli-linux-x64@1.9.4': - resolution: {integrity: sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==} + '@biomejs/cli-linux-x64@2.5.5': + resolution: {integrity: sha512-H/O39nJEw/2Zm/fm7hrmxxoF8kK/aU1uCoPp70ruXVbomaAdLpJJnCmL11Q2JotT8QVHH06So04Oq53lCSwSwQ==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] + libc: [glibc] - '@biomejs/cli-win32-arm64@1.9.4': - resolution: {integrity: sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==} + '@biomejs/cli-win32-arm64@2.5.5': + resolution: {integrity: sha512-7BryINPuYypLUAH3o/o5ZdgomJ4zn3EDR0ChZJst7n32S6ZhKbgHXuYydLu+YAnx59ehGFR0z/MG6qnzQi3Yyw==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [win32] - '@biomejs/cli-win32-x64@1.9.4': - resolution: {integrity: sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==} + '@biomejs/cli-win32-x64@2.5.5': + resolution: {integrity: sha512-bIBFo+n6MIxdNcVFy5CrurbKiZQiUciK3bt8+O9I4wjFZNTfXLpi+giq47522eXqW5NBc9ulx7dR1SlZKi2J5g==} engines: {node: '>=14.21.3'} cpu: [x64] os: [win32] - '@develar/schema-utils@2.6.5': - resolution: {integrity: sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==} - engines: {node: '>= 8.9.0'} + '@electron-internal/extract-zip@1.0.4': + resolution: {integrity: sha512-Zr1Vs7E9tpCNhZHDAbFVXc2gEVCG9RqPDjrno5+bdgB6LRAuvgyMHJut4NCVyYwtAieapMzc3fiQ3CSTi75ARg==} + engines: {node: '>=22.12.0'} '@electron/asar@3.4.1': resolution: {integrity: sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA==} @@ -375,15 +388,13 @@ packages: resolution: {integrity: sha512-zx0EIq78WlY/lBb1uXlziZmDZI4ubcCXIMJ4uGjXzZW0nS19TjSPeXPAjzzTmKQlJUZm0SbmZhPKP7tuQ1SsEw==} hasBin: true - '@electron/get@2.0.3': - resolution: {integrity: sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==} - engines: {node: '>=12'} + '@electron/get@3.1.0': + resolution: {integrity: sha512-F+nKc0xW+kVbBRhFzaMgPy3KwmuNTYX1fx6+FxxoSnNgwYX6LD7AKBTWkU0MQ6IBoe7dz069CNkR673sPAgkCQ==} + engines: {node: '>=14'} - '@electron/node-gyp@https://codeload.github.com/electron/node-gyp/tar.gz/06b29aafb7708acef8b3669835c8a7857ebc92d2': - resolution: {tarball: https://codeload.github.com/electron/node-gyp/tar.gz/06b29aafb7708acef8b3669835c8a7857ebc92d2} - version: 10.2.0-electron.1 - engines: {node: '>=12.13.0'} - hasBin: true + '@electron/get@5.0.0': + resolution: {integrity: sha512-pjoBpru1KdEtcExBnuHAP1cAc/5faoedw0hzJkL3o4/IJp7HNF1+fbrdxT3gMYRX2oJfvnA/WXeCTVQpYYxyJA==} + engines: {node: '>=22.12.0'} '@electron/notarize@2.5.0': resolution: {integrity: sha512-jNT8nwH1f9X5GEITXaQ8IF/KdskvIkOFfB2CvwumsveVidzpSc+mvhhTMdAGSYF3O+Nq49lJ7y+ssODRXu06+A==} @@ -394,13 +405,8 @@ packages: engines: {node: '>=12.0.0'} hasBin: true - '@electron/rebuild@3.7.2': - resolution: {integrity: sha512-19/KbIR/DAxbsCkiaGMXIdPnMCJLkcf8AvGnduJtWBs/CBwiAjY1apCqOLVxrXg+rtXFCngbXhBanWjxLUt1Mg==} - engines: {node: '>=12.13.0'} - hasBin: true - - '@electron/rebuild@4.0.1': - resolution: {integrity: sha512-iMGXb6Ib7H/Q3v+BKZJoETgF9g6KMNZVbsO4b7Dmpgb5qTFqyFTzqW9F3TOSHdybv2vKYKzSS9OiZL+dcJb+1Q==} + '@electron/rebuild@4.2.0': + resolution: {integrity: sha512-RKL/O+jGoXJMxrx/5771y1n0xTKmFuOYGO3gMmwypBM6rsH0kou0mswwdXA2JrhIkE4xyC7v9vGk0n6NPzgOxQ==} engines: {node: '>=22.12.0'} hasBin: true @@ -413,29 +419,14 @@ packages: engines: {node: '>=14.14'} hasBin: true - '@emnapi/core@1.8.1': - resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==} + '@emnapi/core@1.11.2': + resolution: {integrity: sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==} - '@emnapi/core@1.9.2': - resolution: {integrity: sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==} + '@emnapi/runtime@1.11.2': + resolution: {integrity: sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==} - '@emnapi/runtime@1.8.1': - resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} - - '@emnapi/runtime@1.9.2': - resolution: {integrity: sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==} - - '@emnapi/wasi-threads@1.1.0': - resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} - - '@emnapi/wasi-threads@1.2.1': - resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} - - '@esbuild/aix-ppc64@0.27.2': - resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] + '@emnapi/wasi-threads@1.2.2': + resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} '@esbuild/android-arm64@0.17.19': resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} @@ -443,301 +434,140 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.27.2': - resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - '@esbuild/android-arm@0.17.19': resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} engines: {node: '>=12'} cpu: [arm] os: [android] - '@esbuild/android-arm@0.27.2': - resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - '@esbuild/android-x64@0.17.19': resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} engines: {node: '>=12'} cpu: [x64] os: [android] - '@esbuild/android-x64@0.27.2': - resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - '@esbuild/darwin-arm64@0.17.19': resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.27.2': - resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - '@esbuild/darwin-x64@0.17.19': resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} engines: {node: '>=12'} cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.27.2': - resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - '@esbuild/freebsd-arm64@0.17.19': resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.27.2': - resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - '@esbuild/freebsd-x64@0.17.19': resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.27.2': - resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - '@esbuild/linux-arm64@0.17.19': resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} engines: {node: '>=12'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.27.2': - resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - '@esbuild/linux-arm@0.17.19': resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} engines: {node: '>=12'} cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.27.2': - resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - '@esbuild/linux-ia32@0.17.19': resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} engines: {node: '>=12'} cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.27.2': - resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - '@esbuild/linux-loong64@0.17.19': resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} engines: {node: '>=12'} cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.27.2': - resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - '@esbuild/linux-mips64el@0.17.19': resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.27.2': - resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - '@esbuild/linux-ppc64@0.17.19': resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.27.2': - resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - '@esbuild/linux-riscv64@0.17.19': resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.27.2': - resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - '@esbuild/linux-s390x@0.17.19': resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} engines: {node: '>=12'} cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.27.2': - resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - '@esbuild/linux-x64@0.17.19': resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} engines: {node: '>=12'} cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.27.2': - resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-arm64@0.27.2': - resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - '@esbuild/netbsd-x64@0.17.19': resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.27.2': - resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.27.2': - resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - '@esbuild/openbsd-x64@0.17.19': resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.27.2': - resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openharmony-arm64@0.27.2': - resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - '@esbuild/sunos-x64@0.17.19': resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} engines: {node: '>=12'} cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.27.2': - resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - '@esbuild/win32-arm64@0.17.19': resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} engines: {node: '>=12'} cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.27.2': - resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - '@esbuild/win32-ia32@0.17.19': resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} engines: {node: '>=12'} cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.27.2': - resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - '@esbuild/win32-x64@0.17.19': resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} engines: {node: '>=12'} cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.27.2': - resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@gar/promisify@1.1.3': - resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==} - - '@isaacs/balanced-match@4.0.1': - resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} - engines: {node: 20 || >=22} - - '@isaacs/brace-expansion@5.0.0': - resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} - engines: {node: 20 || >=22} - - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - '@isaacs/fs-minipass@4.0.1': resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} engines: {node: '>=18.0.0'} + '@jellybrick/dbus-next@0.11.1': + resolution: {integrity: sha512-MEN8boAd/XN3nTaRULNh/QDWPi1LzDXLLl83EV6AXsdWpZhBzagl8CjBC85g8769JMDhJFytVX8RKyVjUk9nAw==} + engines: {node: '>=12.20.0'} + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -783,12 +613,23 @@ packages: '@napi-rs/wasm-runtime@0.2.12': resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} - '@napi-rs/wasm-runtime@1.1.3': - resolution: {integrity: sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ==} + '@napi-rs/wasm-runtime@1.1.6': + resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==} peerDependencies: '@emnapi/core': ^1.7.1 '@emnapi/runtime': ^1.7.1 + '@noble/hashes@1.4.0': + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} + + '@noble/hashes@2.2.0': + resolution: {integrity: sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg==} + engines: {node: '>= 20.19.0'} + + '@nodable/entities@3.0.0': + resolution: {integrity: sha512-8L9xFeTYKhm49xfIypoe2W5wV1m/3Z58kT+7kR9A8OyFxcPduI4VmxaUMQyKYrRjUoLLSXv6EKKID5Tvj9cUVw==} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -801,123 +642,116 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@npmcli/agent@3.0.0': - resolution: {integrity: sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==} - engines: {node: ^18.17.0 || >=20.5.0} + '@oxc-project/types@0.140.0': + resolution: {integrity: sha512-h5LUOzGArYemnW1NMz/DuuQhBi96J6JL2Bk8zE4kvqxB5Sg3jxmCiH4uyOWHDkiKSt5vWlG4FIwCR/DbstcNRQ==} - '@npmcli/fs@2.1.2': - resolution: {integrity: sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - - '@npmcli/fs@4.0.0': - resolution: {integrity: sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==} - engines: {node: ^18.17.0 || >=20.5.0} - - '@npmcli/move-file@2.0.1': - resolution: {integrity: sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - deprecated: This functionality has been moved to @npmcli/fs - - '@oxc-project/types@0.124.0': - resolution: {integrity: sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg==} - - '@parcel/watcher-android-arm64@2.5.6': - resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==} + '@parcel/watcher-android-arm64@2.6.0': + resolution: {integrity: sha512-trgpLSCKRC/huFjXX/Smh+0sWe4+YtKfktIToiMl59ghz7z+qkH6kMvNnUbLyRs9N11t8l4svSCs1+5B3rOAhA==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [android] - '@parcel/watcher-darwin-arm64@2.5.6': - resolution: {integrity: sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==} + '@parcel/watcher-darwin-arm64@2.6.0': + resolution: {integrity: sha512-Y3QV0gl7Q1zbfueunkWIERICbEojQFCgpyG7YqOGNFLsckXyI1xu9mAIUpKY9QBYzBtSkN8dBPwd3yiAO9ovMw==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [darwin] - '@parcel/watcher-darwin-x64@2.5.6': - resolution: {integrity: sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==} + '@parcel/watcher-darwin-x64@2.6.0': + resolution: {integrity: sha512-Ohv6OpzhUfKYD7Beb8kDvG0jbIxORCYY1JRdZnaBtnjjkJxgD7ZVL0nw2sCYd0yTMKTvz3nnTnOF3cDifK+kvw==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [darwin] - '@parcel/watcher-freebsd-x64@2.5.6': - resolution: {integrity: sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==} + '@parcel/watcher-freebsd-x64@2.6.0': + resolution: {integrity: sha512-5HmXvDgs8VK+74jF9y9/2FE3/OnlcKmc56tjmSrEuZjpSZOGL+fvAu+HKJBdPs9uwoP2hE6TlSUpXZ/C5jUFmQ==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [freebsd] - '@parcel/watcher-linux-arm-glibc@2.5.6': - resolution: {integrity: sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==} + '@parcel/watcher-linux-arm-glibc@2.6.0': + resolution: {integrity: sha512-Ps/hui3A+vMbjdqlqAowK2ZL8+BO8dBjxeWXj6npTBs3jx4wWmbPpaLuqwrQrSqIVMCnpWo238bJ1U37GhQOYg==} engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] + libc: [glibc] - '@parcel/watcher-linux-arm-musl@2.5.6': - resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==} + '@parcel/watcher-linux-arm-musl@2.6.0': + resolution: {integrity: sha512-9c6AUHgHoG+IY88MRIHupztQiQnrbqHYQjkM2btA+Bf/wQnQMuiD0Wfk1EVv3TlNT3x41uU71rn6E4xh/+zvkw==} engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] + libc: [musl] - '@parcel/watcher-linux-arm64-glibc@2.5.6': - resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==} + '@parcel/watcher-linux-arm64-glibc@2.6.0': + resolution: {integrity: sha512-yHRqS2owEXe6Hic9z6Mh1ECsCd+ODVOGvZDyciqRd21+v+o+DnXMOrw50DSpIG2sb8GPEaPPmfeCAWKPJdq46g==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] - '@parcel/watcher-linux-arm64-musl@2.5.6': - resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==} + '@parcel/watcher-linux-arm64-musl@2.6.0': + resolution: {integrity: sha512-WhB2e/V7rqdHHWZusBSPuy5Ei8S6lSz6FE5TKKQz5h3a0O+C+mhY7vxU9b/stqvMb8beLnPY82ZrFTLKs+SrKA==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] + libc: [musl] - '@parcel/watcher-linux-x64-glibc@2.5.6': - resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==} + '@parcel/watcher-linux-x64-glibc@2.6.0': + resolution: {integrity: sha512-ulGE6x6Oz6iAwg75T8YQSoguBWasniIbX+QWpaYPcCnDOpdWX3k+4xbEYPZVLxOuoJI+svJJPD3sEj8G7lrQ3A==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] + libc: [glibc] - '@parcel/watcher-linux-x64-musl@2.5.6': - resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==} + '@parcel/watcher-linux-x64-musl@2.6.0': + resolution: {integrity: sha512-tkBYKt7YQrjIJWYDnto2YgO8MRkjlMTSNoRHzsXinBqbLdeOM3L32wPZJvIZxqaLMfSlS/4sUjH/6STVP/XDLw==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] + libc: [musl] - '@parcel/watcher-win32-arm64@2.5.6': - resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==} + '@parcel/watcher-win32-arm64@2.6.0': + resolution: {integrity: sha512-gIZAP23jaHjGWasY/TY6yL7NHFClf0Ga7FN+iINvk+KN94rhm94lYZhFsbYFNcA04/onvGD9kKmiJLJB2HbNwQ==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [win32] - '@parcel/watcher-win32-ia32@2.5.6': - resolution: {integrity: sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==} - engines: {node: '>= 10.0.0'} - cpu: [ia32] - os: [win32] - - '@parcel/watcher-win32-x64@2.5.6': - resolution: {integrity: sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==} + '@parcel/watcher-win32-x64@2.6.0': + resolution: {integrity: sha512-cA+/pXV2YkfxlIcXOQ5fSWqAzzPyD78/x5qbK/I0vUkrlYHA8TIz+MXjAbGouguKVSI4bOmkTSJ1/poVSsgt+A==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [win32] - '@parcel/watcher@2.5.6': - resolution: {integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==} + '@parcel/watcher@2.6.0': + resolution: {integrity: sha512-7FNeNl8NCE7aINx7WXiKQrPYZWC/hvrTsmk6zmxbI7LTXE7hVek/n8AfVgpe2y82zl3w0HvCHN0bVKMBoJcC0w==} engines: {node: '>= 10.0.0'} - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} + '@peculiar/asn1-schema@2.8.0': + resolution: {integrity: sha512-7YT0U/ze0tF2QOBbE15gKZwy5tvgGyLRiRHLzhlbOpf7BT032oBSd0haZqXn5W6l26WLlu3dyxzjM+2638/z2Q==} - '@rolldown-plugin/solid@0.0.4': - resolution: {integrity: sha512-1SfABNnkkVYu+0sSuraZDjaonmylalAvopLN2o2vNTSaJh2q1KioCN+1BCzNgrDgiCa36dbzRz0IOoplyKa9uw==} - engines: {node: '>=22.12.0'} + '@peculiar/json-schema@1.1.12': + resolution: {integrity: sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==} + engines: {node: '>=8.0.0'} + + '@peculiar/utils@2.0.3': + resolution: {integrity: sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ==} + + '@peculiar/webcrypto@1.7.1': + resolution: {integrity: sha512-ODOov0sGMJMf3jPonOkgGqPknTsu+DdQ7kD++gz8aI+aFMOMHFbWAA2taqXXVTdP+OTOQR/znGvSpmkeI0WTYQ==} + engines: {node: '>=14.18.0'} + + '@rolldown-plugin/solid@0.1.0': + resolution: {integrity: sha512-EP4uOz8u6L0IuSY+JogcATZprRnovODAZ6xflgzqEEzD7Izvs8v192AWBo3K4e1jjKxitDknNg04eJxUVY8Heg==} + engines: {node: ^22.18.0 || >=24.11.0} peerDependencies: csstype: ^3.1.0 - rolldown: ^1.0.0-rc.12 + rolldown: ^1.0.0 seroval: ~1.5.0 - solid-js: '>=1.9.12' + solid-js: '>=1.9.13' - '@rolldown/binding-android-arm64@1.0.0-rc.15': - resolution: {integrity: sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA==} + '@rolldown/binding-android-arm64@1.2.0': + resolution: {integrity: sha512-9yB1l95IrJuNGDFdOYe79vdApdz6WWBCObE+rQ2LUliYUlcyFwSYIb2xb5/Ifw7dAtMy2ZqNyd8QTSOc7duAKw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] @@ -927,8 +761,8 @@ packages: cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-arm64@1.0.0-rc.15': - resolution: {integrity: sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg==} + '@rolldown/binding-darwin-arm64@1.2.0': + resolution: {integrity: sha512-pexNaW9ACLUOaBITOpU6qVu4VrsOFIjTv6bzgu0YUATo4eUJx0V605PxwZfndpPOn0ilqGqvGQ0M8UW0IE24jg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] @@ -938,8 +772,8 @@ packages: cpu: [x64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.0-rc.15': - resolution: {integrity: sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw==} + '@rolldown/binding-darwin-x64@1.2.0': + resolution: {integrity: sha512-NqKYaq0355ZmNMG4QGpxtEDxsc7tGDhjhCm4PpE0cwnBW+5Il95LJyq414niEiaKLVjnVHBEjSo1wngKxJNiFw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] @@ -949,8 +783,8 @@ packages: cpu: [x64] os: [freebsd] - '@rolldown/binding-freebsd-x64@1.0.0-rc.15': - resolution: {integrity: sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw==} + '@rolldown/binding-freebsd-x64@1.2.0': + resolution: {integrity: sha512-3vPoHzh6eBTz9IbB0/qZdSr0Qeks2echn+I4cHu2joV74VriPDdldswksEDzrl1mBB+oPRi+67+3Ib59paxIPQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] @@ -960,8 +794,8 @@ packages: cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15': - resolution: {integrity: sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA==} + '@rolldown/binding-linux-arm-gnueabihf@1.2.0': + resolution: {integrity: sha512-E6NNefZ1bUVmKJq2tJkf45J4Zyczj7qm9rUT7NY+Xo2474Y13qWAwc2tvBt0BAVbmtXR1llkxXg0Ou1jbDf2SQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] @@ -970,60 +804,70 @@ packages: resolution: {integrity: sha512-xkGD+YLH+vQZiqxKEsXe8xS/owQXkyARaNB9NfFrAacLoNIRZM5UEZGNKxXyRWd1kSEkYkJ3/WiqvGGCcqUg1A==} cpu: [arm64] os: [linux] + libc: [glibc] - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15': - resolution: {integrity: sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w==} + '@rolldown/binding-linux-arm64-gnu@1.2.0': + resolution: {integrity: sha512-D+TgkdgM1vu+7/Fpf8+v0ARW+RXEP9Ccazgm8zQ4JFFd9Q7SrYQ2TakU5S5ihazQDgpKyAgZDOcIFsvoHmTZ8w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-arm64-musl@1.0.0-beta.1': resolution: {integrity: sha512-Ey2UxKFL74JuWpdNl9stpV0kxHZIgCWCEUnDnpQ1hcBwO9KwDM5qicLtXfsjozD6vt+xzbrL2D/uTrziYZ7IDQ==} cpu: [arm64] os: [linux] + libc: [musl] - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.15': - resolution: {integrity: sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ==} + '@rolldown/binding-linux-arm64-musl@1.2.0': + resolution: {integrity: sha512-wUqdwJBbAv0APN87GecstdMUtLjjNTs0hBALpxETD73mccFxdmt/XeizXDtN5RAlBwNKmI+Tg+blect2G+8IeQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.15': - resolution: {integrity: sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ==} + '@rolldown/binding-linux-ppc64-gnu@1.2.0': + resolution: {integrity: sha512-9DtF35qR9/NrfhM4oxLplCzVVjE+KKm8Pjemi0i/sdhAWkUasjmSo8WTTubNJClhSHCfyk2yeyoXDQEDPtDAAw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] + libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.15': - resolution: {integrity: sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ==} + '@rolldown/binding-linux-s390x-gnu@1.2.0': + resolution: {integrity: sha512-RzuHrBh8X8Hntd2N4VR02QGEciq/9JhcZoTpR/Cee6otRrlILGCf3cg2ygHuih+ZebUnWmMrDX6ITI85btO6rQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] + libc: [glibc] '@rolldown/binding-linux-x64-gnu@1.0.0-beta.1': resolution: {integrity: sha512-a8QP35x/3mggWqCpFtaF3/PbWl5P9QKpP/muk3iMPgzrXto8zPsEl3imsP3EBh4KwanBVHIf8pEkBQ+/7iMTgQ==} cpu: [x64] os: [linux] + libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.15': - resolution: {integrity: sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA==} + '@rolldown/binding-linux-x64-gnu@1.2.0': + resolution: {integrity: sha512-MK7L0018jjh1jR3mh21G2j1zAVcpscJBlPo2z19pRjv2XOYGRhaV4LyiD8HO6nCDdZln9IFgCMIV5yt4E3klGQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-x64-musl@1.0.0-beta.1': resolution: {integrity: sha512-uIqKwnkZjTY8FmqGMaSjwtWlCdV88LV9bjdkv+mb7I+BBw+9cJlIQy0P8YnGEOEcnDPis/SiraCpkJ/eHYaSZw==} cpu: [x64] os: [linux] + libc: [musl] - '@rolldown/binding-linux-x64-musl@1.0.0-rc.15': - resolution: {integrity: sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw==} + '@rolldown/binding-linux-x64-musl@1.2.0': + resolution: {integrity: sha512-gyrxLQ9NfGb/9LoVnC4kb9miUghw1mghnkfYvNHSnVIXriabnfgGPUP4RLcJm87q3KgYz4FYUG8IDiWUT+CpSw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [musl] - '@rolldown/binding-openharmony-arm64@1.0.0-rc.15': - resolution: {integrity: sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg==} + '@rolldown/binding-openharmony-arm64@1.2.0': + resolution: {integrity: sha512-/6VFMQGRmrhP77KXDC+StIxGzcNp5JOIyYtw0CQ8gPlzhpiIRucYfoM5FaFamHd5BJYIdH86yfP46l1p3WdrFA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] @@ -1033,9 +877,9 @@ packages: engines: {node: '>=14.21.3'} cpu: [wasm32] - '@rolldown/binding-wasm32-wasi@1.0.0-rc.15': - resolution: {integrity: sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q==} - engines: {node: '>=14.0.0'} + '@rolldown/binding-wasm32-wasi@1.2.0': + resolution: {integrity: sha512-rwdbUL465kisF24WEJLvP3JrEG6E5GRuIHt5wpMwHGERtHe4Wm2CIvtf5gTBgr2tGOHKh5NdKEAFS2VkOPE91g==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.1': @@ -1043,8 +887,8 @@ packages: cpu: [arm64] os: [win32] - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15': - resolution: {integrity: sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA==} + '@rolldown/binding-win32-arm64-msvc@1.2.0': + resolution: {integrity: sha512-+5suHwRiKGmhwyUaNT8a5QbrBvLFh2DbO910TEmGRH1aSxwrCezodvGQnulv4uiWEIv1Kq4ypRsJ5+O+ry1DiA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] @@ -1059,14 +903,14 @@ packages: cpu: [x64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.15': - resolution: {integrity: sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g==} + '@rolldown/binding-win32-x64-msvc@1.2.0': + resolution: {integrity: sha512-WfFv6/qGufotqBSBzBYwgpCkJBk8Nj7697LL9vTz/XWc67e0r3oewu8iMRwQj3AUL45GVD7wVsPjCsAAtW66Wg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@rolldown/pluginutils@1.0.0-rc.15': - resolution: {integrity: sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g==} + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} '@rollup/plugin-esm-shim@0.1.8': resolution: {integrity: sha512-xEU0b/BShgDDSPjidhJd4R74J9xZ9jLVtFWNGtsUXyEsdwwwB1a3XOAwwGaNIyUHD6EhxPO21JMfUmJWoMn7SA==} @@ -1081,13 +925,13 @@ packages: resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} engines: {node: '>=10'} - '@solid-primitives/props@3.2.2': - resolution: {integrity: sha512-lZOTwFJajBrshSyg14nBMEP0h8MXzPowGO0s3OeiR3z6nXHTfj0FhzDtJMv+VYoRJKQHG2QRnJTgCzK6erARAw==} + '@solid-primitives/props@3.2.4': + resolution: {integrity: sha512-MXXdvi2TSB6d+0N6ueA/HP1j/Kh9SEc4WdF1ZDMLwPagxW6pIHHSS9xbRO0RjqSVpNP4j0nxCWT1hx3CkJNhNA==} peerDependencies: solid-js: ^1.6.12 - '@solid-primitives/refs@1.1.2': - resolution: {integrity: sha512-K7tf2thy7L+YJjdqXspXOg5xvNEOH8tgEWsp0+1mQk3obHBRD6hEjYZk7p7FlJphSZImS35je3UfmWuD7MhDfg==} + '@solid-primitives/refs@1.1.4': + resolution: {integrity: sha512-bLjwIs6ZPu8NQnuw04sU3Zc8qKSpbc0umUU/O4SHf6oWOdO4+dHY8vb1T7C4b/Tg103+9WGr6sEE0+NFlbaB/A==} peerDependencies: solid-js: ^1.6.12 @@ -1096,8 +940,8 @@ packages: peerDependencies: solid-js: ^1.6.12 - '@solid-primitives/utils@6.3.2': - resolution: {integrity: sha512-hZ/M/qr25QOCcwDPOHtGjxTD8w2mNyVAYvcfgwzBHq2RwNqHNdDNsMZYap20+ruRwW4A3Cdkczyoz0TSxLCAPQ==} + '@solid-primitives/utils@6.4.1': + resolution: {integrity: sha512-ISSB5QX1qP2ynrheIpYwc4oKR5Ny4siNuUyf1qZniy+Il+p/PtDB0QK1Dnle8noiHpwRD3gpPdubOC3qI/Zamg==} peerDependencies: solid-js: ^1.6.12 @@ -1105,12 +949,8 @@ packages: resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} engines: {node: '>=10'} - '@tootallnate/once@2.0.0': - resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} - engines: {node: '>= 10'} - - '@tybys/wasm-util@0.10.1': - resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@tybys/wasm-util@0.10.3': + resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} '@types/adm-zip@0.5.8': resolution: {integrity: sha512-RVVH7QvZYbN+ihqZ4kX/dMiowf6o+Jk1fNwiSdx0NahBJLU787zkULhGhJM8mf/obmLGmgdMM0bXsQTmyfbR7Q==} @@ -1127,8 +967,8 @@ packages: '@types/fs-extra@9.0.13': resolution: {integrity: sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==} - '@types/gensync@1.0.4': - resolution: {integrity: sha512-C3YYeRQWp2fmq9OryX+FoDy8nXS6scQ7dPptD8LnFDAUNcKWJjXQKDNJD3HVm+kOUsXhTOkpi69vI4EuAr95bA==} + '@types/gensync@1.0.5': + resolution: {integrity: sha512-MbsRCT7mTikHwKZ0X+LVUTLRrZZRLipTuXEO9qOYO+zmjMVk81axyClMROf6uoPD9MRVu46bx8zoR0Ad9q3NAg==} '@types/glob@7.2.0': resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} @@ -1149,59 +989,178 @@ packages: '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - '@types/node@22.19.15': - resolution: {integrity: sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==} + '@types/node@24.13.3': + resolution: {integrity: sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==} - '@types/node@24.12.0': - resolution: {integrity: sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==} - - '@types/plist@3.0.5': - resolution: {integrity: sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==} + '@types/node@26.1.1': + resolution: {integrity: sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw==} '@types/responselike@1.0.3': resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} - '@types/verror@1.10.11': - resolution: {integrity: sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg==} + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} - '@types/yauzl@2.10.3': - resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} + '@typescript/typescript-aix-ppc64@7.0.2': + resolution: {integrity: sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [aix] - '@uwu/lune@1.6.2': - resolution: {integrity: sha512-0/e1zFGm7pBISyuNvhKMqdg4gEQOpBtf8wdquJaUDqA0enrV55iwMWrrCdJHlfx77K1D8hjnAUGvCXxwFebg5Q==} + '@typescript/typescript-darwin-arm64@7.0.2': + resolution: {integrity: sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [darwin] + + '@typescript/typescript-darwin-x64@7.0.2': + resolution: {integrity: sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [darwin] + + '@typescript/typescript-freebsd-arm64@7.0.2': + resolution: {integrity: sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [freebsd] + + '@typescript/typescript-freebsd-x64@7.0.2': + resolution: {integrity: sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [freebsd] + + '@typescript/typescript-linux-arm64@7.0.2': + resolution: {integrity: sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [linux] + + '@typescript/typescript-linux-arm@7.0.2': + resolution: {integrity: sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==} + engines: {node: '>=16.20.0'} + cpu: [arm] + os: [linux] + + '@typescript/typescript-linux-loong64@7.0.2': + resolution: {integrity: sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==} + engines: {node: '>=16.20.0'} + cpu: [loong64] + os: [linux] + + '@typescript/typescript-linux-mips64el@7.0.2': + resolution: {integrity: sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==} + engines: {node: '>=16.20.0'} + cpu: [mips64el] + os: [linux] + + '@typescript/typescript-linux-ppc64@7.0.2': + resolution: {integrity: sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [linux] + + '@typescript/typescript-linux-riscv64@7.0.2': + resolution: {integrity: sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==} + engines: {node: '>=16.20.0'} + cpu: [riscv64] + os: [linux] + + '@typescript/typescript-linux-s390x@7.0.2': + resolution: {integrity: sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==} + engines: {node: '>=16.20.0'} + cpu: [s390x] + os: [linux] + + '@typescript/typescript-linux-x64@7.0.2': + resolution: {integrity: sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [linux] + + '@typescript/typescript-netbsd-arm64@7.0.2': + resolution: {integrity: sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [netbsd] + + '@typescript/typescript-netbsd-x64@7.0.2': + resolution: {integrity: sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [netbsd] + + '@typescript/typescript-openbsd-arm64@7.0.2': + resolution: {integrity: sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [openbsd] + + '@typescript/typescript-openbsd-x64@7.0.2': + resolution: {integrity: sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [openbsd] + + '@typescript/typescript-sunos-x64@7.0.2': + resolution: {integrity: sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [sunos] + + '@typescript/typescript-win32-arm64@7.0.2': + resolution: {integrity: sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [win32] + + '@typescript/typescript-win32-x64@7.0.2': + resolution: {integrity: sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [win32] + + '@uwu/lune@1.6.3': + resolution: {integrity: sha512-A4fc53Rlvi4rZxAT0tGF82MRcx9ebmYRlcVY4//++QWS92XHuc2535RkjpTnINWCF/bCX17RcpSWmdjOydjj5g==} hasBin: true '@uwu/shelter-defs@1.5.1': resolution: {integrity: sha512-bO3M5SgqEpuNZkjd/LZFtTNNATpmVle5uznVp0QNgi3o1w2ej/ieYmwFK6nBZqnZHd8/4aJN1Njl/JbTnZcY5A==} - '@vencord/venmic@6.1.0': - resolution: {integrity: sha512-YiCtzml/W8tYbGhu3jm5jfbbEnl2slKKARNK0jO+8qV979k9eFnfIRTxvhMN/SWq1h8ZNJdXVwvXpffQwq0RuA==} + '@uwu/shelter-ui@0.0.6': + resolution: {integrity: sha512-b9NsUC7A+n4jZJl8TmXv+UKPAtfS9JygtRNASnophDkSF7evligMc21HGm8A7fh3PdBzr9VrepvehgmyUgRnLg==} + peerDependencies: + solid-js: ^1.6.16 + + '@vencord/venmic@7.1.0': + resolution: {integrity: sha512-HQpZoUKGz8j7m1+1BCgE+7B6T/+/IArVO8km7SjsWxe/5+2YblAs0Fwgy9C9XqCCir/u0+F1FMqrQQUX2PATYw==} engines: {node: '>=14.15'} os: [linux] - '@xmldom/xmldom@0.8.11': - resolution: {integrity: sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==} + '@xmldom/xmldom@0.8.13': + resolution: {integrity: sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw==} engines: {node: '>=10.0.0'} - deprecated: this version has critical issues, please update to the latest version - abbrev@1.1.1: - resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + '@xmldom/xmldom@0.9.10': + resolution: {integrity: sha512-A9gOqLdi6cV4ibazAjcQufGj0B1y/vDqYrcuP6d/6x8P27gRS8643Dj9o1dEKtB6O7fwxb2FgBmJS2mX7gpvdw==} + engines: {node: '>=14.6'} - abbrev@3.0.1: - resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} - engines: {node: ^18.17.0 || >=20.5.0} + abbrev@4.0.0: + resolution: {integrity: sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==} + engines: {node: ^20.17.0 || >=22.9.0} - acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + acorn@8.17.0: + resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} engines: {node: '>=0.4.0'} hasBin: true - adm-zip@0.5.16: - resolution: {integrity: sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==} - engines: {node: '>=12.0'} + adm-zip@0.6.0: + resolution: {integrity: sha512-XleryMhbuksdKtofnWZ9Sk+4CUTbms4Mb/EU32SZwToAyZ5RgVos/ki8n+yr0LWHOGKuakbXTuuYNHLQjhddgg==} + engines: {node: '>=14.0'} agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} @@ -1211,21 +1170,8 @@ packages: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} - agentkeepalive@4.6.0: - resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} - engines: {node: '>= 8.0.0'} - - aggregate-error@3.1.0: - resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} - engines: {node: '>=8'} - - ajv-keywords@3.5.2: - resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} - peerDependencies: - ajv: ^6.9.1 - - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ajv@8.20.0: + resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} @@ -1247,22 +1193,22 @@ packages: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} - app-builder-bin@5.0.0-alpha.12: - resolution: {integrity: sha512-j87o0j6LqPL3QRr8yid6c+Tt5gC7xNfYo6uQIQkorAC6MpeayVMZrEDzKmJJ/Hlv7EnOQpaRm53k6ktDYZyB6w==} + anynum@1.0.1: + resolution: {integrity: sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A==} - app-builder-lib@26.0.20: - resolution: {integrity: sha512-MNEcm1M2+SAENsH2nxAAPt5qrGT4VwZNuvLC+GuwmcSDhDPWjrzsRPfx8/D0Juz446jVtTfAOguagv5EEssaaw==} + app-builder-lib@26.15.3: + resolution: {integrity: sha512-2VnyWkqsP5v5XbBhL3tD5Syx8iNPBYsoU7kY4S2fz7wg8Rj/nztWKCUzGKaFRTv0Xwf3/H058CR1Kvtd/3lRow==} engines: {node: '>=14.0.0'} peerDependencies: - dmg-builder: 26.0.20 - electron-builder-squirrel-windows: 26.0.20 + dmg-builder: 26.15.3 + electron-builder-squirrel-windows: 26.15.3 - app-builder-lib@26.4.0: - resolution: {integrity: sha512-Uas6hNe99KzP3xPWxh5LGlH8kWIVjZixzmMJHNB9+6hPyDpjc7NQMkVgi16rQDdpCFy22ZU5sp8ow7tvjeMgYQ==} + app-builder-lib@26.15.7: + resolution: {integrity: sha512-C7APoYISPExUmrEntNhDpz9Tccb4uWuEDfLaC0WPPc7/pwzz0WZGznCz/ycPfkkzw6tKOalceD8g6TgHmVz1QA==} engines: {node: '>=14.0.0'} peerDependencies: - dmg-builder: 26.4.0 - electron-builder-squirrel-windows: 26.4.0 + dmg-builder: 26.15.7 + electron-builder-squirrel-windows: 26.15.7 aproba@2.1.0: resolution: {integrity: sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==} @@ -1280,17 +1226,13 @@ packages: engines: {node: '>=8'} arrpc@https://codeload.github.com/Legcord/arrpc/tar.gz/efe7589762470d32b9ba10d529be5acc23cd0e19: - resolution: {tarball: https://codeload.github.com/Legcord/arrpc/tar.gz/efe7589762470d32b9ba10d529be5acc23cd0e19} + resolution: {gitHosted: true, integrity: sha512-oxxPz88l9/VDvmgkepTGlhstBkt2kAO4SqxUjRu+pql4mQ2GSagDCjsYv4Lg3KnuazbuqRkl0K5KzOUzdBBJZQ==, tarball: https://codeload.github.com/Legcord/arrpc/tar.gz/efe7589762470d32b9ba10d529be5acc23cd0e19} version: 3.5.0 hasBin: true - assert-plus@1.0.0: - resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} - engines: {node: '>=0.8'} - - astral-regex@2.0.0: - resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} - engines: {node: '>=8'} + asn1js@3.0.10: + resolution: {integrity: sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg==} + engines: {node: '>=12.0.0'} async-exit-hook@2.0.1: resolution: {integrity: sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==} @@ -1306,11 +1248,14 @@ packages: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} engines: {node: '>= 4.0.0'} - axios@1.13.4: - resolution: {integrity: sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg==} + aws4@1.13.2: + resolution: {integrity: sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==} - babel-plugin-jsx-dom-expressions@0.40.6: - resolution: {integrity: sha512-v3P1MW46Lm7VMpAkq0QfyzLWWkC8fh+0aE5Km4msIgDx5kjenHU0pF2s+4/NH8CQn/kla6+Hvws+2AF7bfV5qQ==} + axios@1.18.1: + resolution: {integrity: sha512-3nTvFlvpn9Zu/RkHUqtc7/+al4UpRW5az71ap5zccp6e8RAYEzhMTecX8Dz1wWDYrPpUoB1HAQEGEAEvUr7S9g==} + + babel-plugin-jsx-dom-expressions@0.40.7: + resolution: {integrity: sha512-/O6JWUmjv03OI9lL2ry9bUjpD5S3PclM55RRJEyCdcFZ5W2SEA/59d+l2hNsk3gI6kiWRdRPdOtqZmsQzFN1pQ==} peerDependencies: '@babel/core': ^7.20.12 @@ -1333,70 +1278,65 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.9.19: - resolution: {integrity: sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==} + baseline-browser-mapping@2.10.32: + resolution: {integrity: sha512-wbPvpyjJPC0zdfdKXxqEL3Ea+bOMD/87X4lftiJkkaBiuG6ALQy1SLmEd7BSmVCuwCQsBrCamgBoLyfFDD1EPg==} + engines: {node: '>=6.0.0'} + hasBin: true + + baseline-browser-mapping@2.11.1: + resolution: {integrity: sha512-HYXq73DDpCtNzOmrFsm9eSwCvWCql0RzqjpDzXN9EadiLJ4DNat0nsZ/Bzmy+Ud12mb4/zKDY0cQ805ZzN+i0A==} + engines: {node: '>=6.0.0'} hasBin: true binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} - bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} boolean@3.2.0: resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==} deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. - brace-expansion@1.1.12: - resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + brace-expansion@1.1.16: + resolution: {integrity: sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==} - brace-expansion@2.0.3: - resolution: {integrity: sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==} + brace-expansion@2.1.2: + resolution: {integrity: sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==} - brace-expansion@5.0.5: - resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} - engines: {node: 18 || 20 || >=22} + brace-expansion@5.0.8: + resolution: {integrity: sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==} + engines: {node: 20 || >=22} braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.28.1: - resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} + browserslist@4.28.2: + resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true - buffer-crc32@0.2.13: - resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + browserslist@4.28.7: + resolution: {integrity: sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - - builder-util-runtime@9.4.0: - resolution: {integrity: sha512-omkpaKbutPYqC0nwLEeGq540xND1YPhfVzwT6CFyCFzxhNDt/X+fykr17Yo3jxiuwI3zaAnY/1tKFoRN+FeHhg==} + builder-util-runtime@9.7.0: + resolution: {integrity: sha512-g/kR520giAFYkSXTzcmF3kqQq7wi8F6N6SzeDgZrqTBN+VHdmgWOyTdD1yD7AATDId/yXLvuP34CxW46/BwCdw==} engines: {node: '>=12.0.0'} - builder-util-runtime@9.5.1: - resolution: {integrity: sha512-qt41tMfgHTllhResqM5DcnHyDIWNgzHvuY2jDcYP9iaGpkWxTUzV6GQjDeLnlR1/DtdlcsWQbA7sByMpmJFTLQ==} - engines: {node: '>=12.0.0'} + builder-util@26.15.3: + resolution: {integrity: sha512-q2hn7Mbo2nFNkVekPiHFx6Nfo3hURmES3tfBn+k5Pqxl2RkmP3QGqZUhH/q9Pch/4G05NRhPjDlVj1O8q4Txvw==} + engines: {node: '>=14.0.0'} - builder-util@26.0.20: - resolution: {integrity: sha512-LxT2Q7dcNMdJ34Y7IrTWvkSL0UHMqs76ZjbDSmhuC8vpC9DZfWYzLtOHUFHmZ67Cx8/8mNWFmXG8QJ/e+itc0A==} - - builder-util@26.3.4: - resolution: {integrity: sha512-aRn88mYMktHxzdqDMF6Ayj0rKoX+ZogJ75Ck7RrIqbY/ad0HBvnS2xA4uHfzrGr5D2aLL3vU6OBEH4p0KMV2XQ==} - - cacache@16.1.3: - resolution: {integrity: sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - - cacache@19.0.1: - resolution: {integrity: sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ==} - engines: {node: ^18.17.0 || >=20.5.0} + bytestreamjs@2.0.1: + resolution: {integrity: sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==} + engines: {node: '>=6.0.0'} cacheable-lookup@5.0.4: resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} @@ -1410,8 +1350,11 @@ packages: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} - caniuse-lite@1.0.30001766: - resolution: {integrity: sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==} + caniuse-lite@1.0.30001793: + resolution: {integrity: sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==} + + caniuse-lite@1.0.30001806: + resolution: {integrity: sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==} chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} @@ -1421,9 +1364,9 @@ packages: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} - chokidar@4.0.3: - resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} - engines: {node: '>= 14.16.0'} + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} chownr@2.0.0: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} @@ -1444,22 +1387,6 @@ packages: resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} engines: {node: '>=8'} - clean-stack@2.2.0: - resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} - engines: {node: '>=6'} - - cli-cursor@3.1.0: - resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} - engines: {node: '>=8'} - - cli-spinners@2.9.2: - resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} - engines: {node: '>=6'} - - cli-truncate@2.1.0: - resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} - engines: {node: '>=8'} - cli-truncate@4.0.0: resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} engines: {node: '>=18'} @@ -1471,10 +1398,6 @@ packages: clone-response@1.0.3: resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} - clone@1.0.4: - resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} - engines: {node: '>=0.8'} - cmake-js@7.4.0: resolution: {integrity: sha512-Lw0JxEHrmk+qNj1n9W9d4IvkDdYTBn7l2BW6XmtLj7WPpIo2shvxUy+YokfjMxAAOELNonQwX3stkPhM5xSC2Q==} engines: {node: '>= 14.15.0'} @@ -1522,11 +1445,8 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - core-util-is@1.0.2: - resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} - - crc@3.8.0: - resolution: {integrity: sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==} + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} cross-dirname@0.1.0: resolution: {integrity: sha512-+R08/oI0nl3vfPcqftZRpytksBXDzOUveBq/NBVx0sUp1axwzPQrKinNx5yd5sxPu8j1wIy8AfnVQ+5eFdha6Q==} @@ -1538,8 +1458,8 @@ packages: csstype@3.2.3: resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} - date-fns@4.1.0: - resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} + date-fns@4.4.0: + resolution: {integrity: sha512-+1UMbeh68lH1SegH83CGWwpb6OHHbpSgr3+s5Eww5M4CAgswBpoWS0AjTOfEJ33HiYKz1hdj/KTFprzXHmq/6w==} debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} @@ -1558,9 +1478,6 @@ packages: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} - defaults@1.0.4: - resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} - defer-to-connect@2.0.1: resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} engines: {node: '>=10'} @@ -1594,14 +1511,14 @@ packages: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} - dmg-builder@26.0.20: - resolution: {integrity: sha512-8iiV/TMGoMqor9/54M/B5zRhyRsyTo2OUv/LalKGlKCZQ/0P96obvl5dQQg56AUlbVGzbMlu7hycLvpNXhqabA==} + dmg-builder@26.15.3: + resolution: {integrity: sha512-O3zJUFUYHJKgzPqioHxfxzBzlSC1eXCSr79gMSBKBP5AgjjpmrydMsMLotEg9fAJF36vdUncb+4ndRNxoPdlSQ==} - dmg-license@1.0.11: - resolution: {integrity: sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==} - engines: {node: '>=8'} - os: [darwin] - hasBin: true + dmg-builder@26.15.7: + resolution: {integrity: sha512-rfo1YyAWO0L3cZLKCqKQiLYbW6ZXebRUfK0kWp4oXxO7dDFLrf7alRkWImNuXvZVQhs6Idzy++cwOk8I+xPDhw==} + + dompurify@3.4.8: + resolution: {integrity: sha512-yb1cEmaOum7wFvOCSQxyfgVlv5D47Rc30iZWoMpbDIWTnJ6grDDQyu2KFJzB2k7u0pMuJcQ1zphH//fFnw2tjQ==} dotenv-expand@11.0.7: resolution: {integrity: sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==} @@ -1615,19 +1532,19 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + duplexer2@0.1.4: + resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} ejs@3.1.10: resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} engines: {node: '>=0.10.0'} hasBin: true - electron-builder-squirrel-windows@26.4.0: - resolution: {integrity: sha512-7dvalY38xBzWNaoOJ4sqy2aGIEpl2S1gLPkkB0MHu1Hu5xKQ82il1mKSFlXs6fLpXUso/NmyjdHGlSHDRoG8/w==} + electron-builder-squirrel-windows@26.15.3: + resolution: {integrity: sha512-Jc19XPV9y9+2bAdZPkXuVNGNIEFBq9poHC61l8Kv6FdK7DRG3+Ic0rerC0DXOaeHNz8yW0fg/JnF8GQROOF5MA==} - electron-builder@26.0.20: - resolution: {integrity: sha512-lntLb4ZuQ4UPVlOiWZKO+NhHlNf0T6Bn+6ZLo+wxTuhazKJSXycmIP6tp/xNZvE+0ApF0SizAgY4sLHZtrTJgw==} + electron-builder@26.15.7: + resolution: {integrity: sha512-DBpaNzxsPs1BvEblzFoNriSbzsBqDCy/gseIngeEhYzQG1IxfB7Hvc2tBBVmpWE2BTQGP9J1RrAvDT+Vc/uAxg==} engines: {node: '>=14.0.0'} hasBin: true @@ -1643,25 +1560,25 @@ packages: resolution: {integrity: sha512-8TjjAh8Ec51hUi3o4TaU0mD3GMTOESi866oRNavj9A3IQJ7pmv+MJVmdZBFGw4GFT36X7bkqnuDNYvkQgvyI8Q==} engines: {node: '>=18'} - electron-publish@26.0.20: - resolution: {integrity: sha512-2OAcMmawYZCxRSGnGMkyWOYAPLS2ZEL2F886fkilYojy1lFXLdRCkcyQVD5GV2KeEjNBsuhcvz9pddWcYT9JMw==} + electron-publish@26.15.3: + resolution: {integrity: sha512-g/2bn8YTavY4cuS5F+jOS7zmZbXXBV8KZ8yHKfJjFPoKtzBqrpCdNPxBd3tqdBwP7BVd0lGzf7Bk2s0KesWZ4Q==} - electron-publish@26.3.4: - resolution: {integrity: sha512-5/ouDPb73SkKuay2EXisPG60LTFTMNHWo2WLrK5GDphnWK9UC+yzYrzVeydj078Yk4WUXi0+TaaZsNd6Zt5k/A==} + electron-to-chromium@1.5.363: + resolution: {integrity: sha512-VjUKPyWzGnT1fujlkEGC/BvN70Hh70KXtAqcmniXviYlJC/ivcT+BWGPyxWVbJZLfvtKR6dqg1L7T7pgAMBtWA==} - electron-to-chromium@1.5.282: - resolution: {integrity: sha512-FCPkJtpst28UmFzd903iU7PdeVTfY0KAeJy+Lk0GLZRwgwYHn/irRcaCbQQOmr5Vytc/7rcavsYLvTM8RiHYhQ==} + electron-to-chromium@1.5.395: + resolution: {integrity: sha512-7zt9Aw+SrmxLWLN0zhaTWZQiCdryLVrYTq5R7iZakLvi2UQPYMMsROYV/2qVCzMeCiSXHwKOU+sZ4zOVVlrtKA==} - electron-updater@6.8.3: - resolution: {integrity: sha512-Z6sgw3jgbikWKXei1ENdqFOxBP0WlXg3TtKfz0rgw2vIZFJUyI4pD7ZN7jrkm7EoMK+tcm/qTnPUdqfZukBlBQ==} + electron-updater@6.8.9: + resolution: {integrity: sha512-ZhVxM9iGONUpZGI1FxdMRgJjUFXi7AYGVa5PwKlO1tV1/4zDxQmfKpXOHVztKrd6L9rLcFjERvi1Mf2vxyTkig==} electron-winstaller@5.4.0: resolution: {integrity: sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==} engines: {node: '>=8.0.0'} - electron@41.2.0: - resolution: {integrity: sha512-0OKLiymqfV0WK68RBXqAm3Myad2TpI5wwxLCBEUcH5Nugo3YfSk7p1Js/AL9266qTz5xZioUnxt9hG8FFwax0g==} - engines: {node: '>= 12.20.55'} + electron@43.2.0: + resolution: {integrity: sha512-80zvrgG7ZRXD+tD0IyLvrnN9n+veSxadMRsMaC9wKKP3iUbtC7rGM8+dVuCmOb0Rrwwv8ESW4awnUZh9Hbp1fA==} + engines: {node: '>= 22.12.0'} hasBin: true emoji-regex@10.6.0: @@ -1670,11 +1587,9 @@ packages: emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - - encoding@0.1.13: - resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + empathic@2.0.1: + resolution: {integrity: sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q==} + engines: {node: '>=14'} end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} @@ -1683,10 +1598,18 @@ packages: resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} engines: {node: '>=0.12'} + entities@8.0.0: + resolution: {integrity: sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==} + engines: {node: '>=20.19.0'} + env-paths@2.2.1: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} + env-paths@3.0.0: + resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + err-code@2.0.3: resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} @@ -1698,8 +1621,8 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} - es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + es-object-atoms@1.1.2: + resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} engines: {node: '>= 0.4'} es-set-tostringtag@2.1.0: @@ -1714,11 +1637,6 @@ packages: engines: {node: '>=12'} hasBin: true - esbuild@0.27.2: - resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} - engines: {node: '>=18'} - hasBin: true - escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -1746,15 +1664,6 @@ packages: resolution: {integrity: sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==} engines: {node: '>=4'} - extract-zip@2.0.1: - resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} - engines: {node: '>= 10.17.0'} - hasBin: true - - extsprintf@1.4.1: - resolution: {integrity: sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==} - engines: {'0': node >=0.6.0} - fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -1762,15 +1671,19 @@ packages: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + fast-uri@3.1.4: + resolution: {integrity: sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==} + + fast-xml-builder@1.3.0: + resolution: {integrity: sha512-F74cZEdCvuw9P41GAC3rod4X04jjWGM1JPEv/GWSqFTWLsdyMSBMBMlm9Hk3GLBgLBbdBNY8yee0pQh2RBVESQ==} + + fast-xml-parser@5.10.1: + resolution: {integrity: sha512-IEMIf7298kXuZSRFoGfMYrl7is8LpavODgbNz1cwIudv7KwVFnuU+UsMporfq6PD6aXSlawZlARiA3UywCTfMw==} + hasBin: true fastq@1.20.1: resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} - fd-slicer@1.1.0: - resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} - fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -1780,15 +1693,15 @@ packages: picomatch: optional: true - filelist@1.0.4: - resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + filelist@1.0.6: + resolution: {integrity: sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==} fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} - follow-redirects@1.15.11: - resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + follow-redirects@1.16.0: + resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -1796,20 +1709,20 @@ packages: debug: optional: true - foreground-child@3.3.1: - resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} - engines: {node: '>=14'} - - form-data@4.0.5: - resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + form-data@4.0.6: + resolution: {integrity: sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==} engines: {node: '>= 6'} fs-extra@10.1.0: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} - fs-extra@11.3.4: - resolution: {integrity: sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==} + fs-extra@11.3.1: + resolution: {integrity: sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==} + engines: {node: '>=14.14'} + + fs-extra@11.3.6: + resolution: {integrity: sha512-w8ZNZr2mKIc7qeNaQ9AVPT1+iFaI+Avd4xudVOvdDJ8VytREi1Ft5Ih7hd9jjehod8vAM5GMsfQ/TpPf4EyoEA==} engines: {node: '>=14.14'} fs-extra@7.0.1: @@ -1828,10 +1741,6 @@ packages: resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} engines: {node: '>= 8'} - fs-minipass@3.0.3: - resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -1856,8 +1765,8 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-east-asian-width@1.4.0: - resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==} + get-east-asian-width@1.6.0: + resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} engines: {node: '>=18'} get-intrinsic@1.3.0: @@ -1872,27 +1781,14 @@ packages: resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} engines: {node: '>=8'} - get-tsconfig@4.13.0: - resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} - glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} - glob@10.5.0: - resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} - deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me - hasBin: true - glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me - glob@8.1.0: - resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} - engines: {node: '>=12'} - deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me - global-agent@3.0.0: resolution: {integrity: sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==} engines: {node: '>=10.0'} @@ -1939,8 +1835,8 @@ packages: has-unicode@2.0.1: resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} engines: {node: '>= 0.4'} hey-listen@1.0.8: @@ -1959,10 +1855,6 @@ packages: http-cache-semantics@4.2.0: resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} - http-proxy-agent@5.0.0: - resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} - engines: {node: '>= 6'} - http-proxy-agent@7.0.2: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} @@ -1979,45 +1871,19 @@ packages: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} - humanize-ms@1.2.1: - resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} - - iconv-corefoundation@1.1.7: - resolution: {integrity: sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==} - engines: {node: ^8.11.2 || >=10} - os: [darwin] - - iconv-lite@0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} - idb@7.1.1: resolution: {integrity: sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==} - ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} - immutable@5.1.4: - resolution: {integrity: sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==} + immutable@5.1.9: + resolution: {integrity: sha512-m8nVez3rwrgmWxtLMt1ZYXB2Lv7OKYn/disyxAlSDYAlKSlFoPPfIAmAM/M5xqL4m4C/wAPw7S2/CNaUii1Hxg==} import-meta-resolve@4.2.0: resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - - indent-string@4.0.0: - resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} - engines: {node: '>=8'} - - infer-owner@1.0.4: - resolution: {integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==} - inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. @@ -2028,16 +1894,12 @@ packages: ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - ip-address@10.1.0: - resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} - engines: {node: '>= 12'} - is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} - is-core-module@2.16.1: - resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + is-core-module@2.16.2: + resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==} engines: {node: '>= 0.4'} is-extglob@2.1.1: @@ -2056,13 +1918,6 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} - is-interactive@1.0.0: - resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} - engines: {node: '>=8'} - - is-lambda@1.0.1: - resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} - is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -2075,9 +1930,11 @@ packages: resolution: {integrity: sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==} engines: {node: '>=0.10.0'} - is-unicode-supported@0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} + is-unsafe@2.0.0: + resolution: {integrity: sha512-2LdV822R+wmI86unXA93WCFpL6g+av8ynWk0nrHyJqGop5VoocYsSLFgN8jrfalT6iGeLNM4KXuVSsULP53kEA==} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} isbinaryfile@4.0.10: resolution: {integrity: sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==} @@ -2090,20 +1947,21 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - isexe@3.1.1: - resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} - engines: {node: '>=16'} + isexe@3.1.5: + resolution: {integrity: sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==} + engines: {node: '>=18'} - jackspeak@3.4.3: - resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + isexe@4.0.0: + resolution: {integrity: sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==} + engines: {node: '>=20'} jake@10.9.4: resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==} engines: {node: '>=10'} hasBin: true - jiti@2.6.1: - resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + jiti@2.7.0: + resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} hasBin: true js-tokens@10.0.0: @@ -2116,6 +1974,10 @@ packages: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true + js-yaml@4.3.0: + resolution: {integrity: sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==} + hasBin: true + jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} @@ -2124,8 +1986,8 @@ packages: json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} json-stringify-safe@5.0.1: resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} @@ -2138,86 +2000,90 @@ packages: jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} - jsonfile@6.2.0: - resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + jsonfile@6.2.1: + resolution: {integrity: sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==} keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - koffi@2.15.6: - resolution: {integrity: sha512-WQBpM5uo74UQ17UpsFN+PUOrQQg4/nYdey4SGVluQun2drYYfePziLLWdSmFb4wSdWlJC1aimXQnjhPCheRKuw==} + koffi@2.16.3: + resolution: {integrity: sha512-E9y1AsgYGlaxMhcZzHr8y96QF2U5XzA12GGVAfbWqIubTwPNMXQarfBzePNXHe0xtIEtNd6ifAv3GAKYGUeBAQ==} lazy-val@1.0.5: resolution: {integrity: sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==} - lightningcss-android-arm64@1.31.1: - resolution: {integrity: sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==} + lightningcss-android-arm64@1.33.0: + resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [android] - lightningcss-darwin-arm64@1.31.1: - resolution: {integrity: sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==} + lightningcss-darwin-arm64@1.33.0: + resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [darwin] - lightningcss-darwin-x64@1.31.1: - resolution: {integrity: sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==} + lightningcss-darwin-x64@1.33.0: + resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [darwin] - lightningcss-freebsd-x64@1.31.1: - resolution: {integrity: sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==} + lightningcss-freebsd-x64@1.33.0: + resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [freebsd] - lightningcss-linux-arm-gnueabihf@1.31.1: - resolution: {integrity: sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==} + lightningcss-linux-arm-gnueabihf@1.33.0: + resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==} engines: {node: '>= 12.0.0'} cpu: [arm] os: [linux] - lightningcss-linux-arm64-gnu@1.31.1: - resolution: {integrity: sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==} + lightningcss-linux-arm64-gnu@1.33.0: + resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] - lightningcss-linux-arm64-musl@1.31.1: - resolution: {integrity: sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==} + lightningcss-linux-arm64-musl@1.33.0: + resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] - lightningcss-linux-x64-gnu@1.31.1: - resolution: {integrity: sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==} + lightningcss-linux-x64-gnu@1.33.0: + resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] - lightningcss-linux-x64-musl@1.31.1: - resolution: {integrity: sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==} + lightningcss-linux-x64-musl@1.33.0: + resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] - lightningcss-win32-arm64-msvc@1.31.1: - resolution: {integrity: sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==} + lightningcss-win32-arm64-msvc@1.33.0: + resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [win32] - lightningcss-win32-x64-msvc@1.31.1: - resolution: {integrity: sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==} + lightningcss-win32-x64-msvc@1.33.0: + resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [win32] - lightningcss@1.31.1: - resolution: {integrity: sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==} + lightningcss@1.33.0: + resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==} engines: {node: '>= 12.0.0'} lodash.escaperegexp@4.1.2: @@ -2227,19 +2093,16 @@ packages: resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. - lodash@4.17.23: - resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} - - log-symbols@4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} lowercase-keys@2.0.0: resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} engines: {node: '>=8'} - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@11.5.2: + resolution: {integrity: sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==} + engines: {node: 20 || >=22} lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -2248,25 +2111,18 @@ packages: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} - lru-cache@7.18.3: - resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} - engines: {node: '>=12'} - - lucide-solid@0.475.0: - resolution: {integrity: sha512-iAelwwRgMJie0sj+qWWQzYOixbk6FUcxflF3od+ZMpQokmeCD+yywyNMMsqfCcsCD50PBKKhqBeFsdjUzlhfxw==} + lucide-solid@1.26.0: + resolution: {integrity: sha512-1xXTyA249ZhuxHQjRaBJGhVHNb9/82bOwOYSesxMIqN3pcES3HaXbcu6kLGksxUIy2tvl6ixYOevtsBsk7eZWg==} peerDependencies: solid-js: ^1.4.7 magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - make-fetch-happen@10.2.1: - resolution: {integrity: sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - - make-fetch-happen@14.0.3: - resolution: {integrity: sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==} - engines: {node: ^18.17.0 || >=20.5.0} + marked@14.0.0: + resolution: {integrity: sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==} + engines: {node: '>= 18'} + hasBin: true matcher@3.0.0: resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==} @@ -2304,10 +2160,6 @@ packages: engines: {node: '>=4.0.0'} hasBin: true - mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - mimic-response@1.0.1: resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} engines: {node: '>=4'} @@ -2316,16 +2168,12 @@ packages: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} - minimatch@10.1.1: - resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} - engines: {node: 20 || >=22} - - minimatch@10.2.4: - resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} + minimatch@10.2.5: + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} engines: {node: 18 || 20 || >=22} - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} minimatch@5.1.9: resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} @@ -2338,34 +2186,6 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass-collect@1.0.2: - resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} - engines: {node: '>= 8'} - - minipass-collect@2.0.1: - resolution: {integrity: sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==} - engines: {node: '>=16 || 14 >=14.17'} - - minipass-fetch@2.1.2: - resolution: {integrity: sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - - minipass-fetch@4.0.1: - resolution: {integrity: sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ==} - engines: {node: ^18.17.0 || >=20.5.0} - - minipass-flush@1.0.7: - resolution: {integrity: sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA==} - engines: {node: '>= 8'} - - minipass-pipeline@1.2.4: - resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} - engines: {node: '>=8'} - - minipass-sized@1.0.3: - resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} - engines: {node: '>=8'} - minipass@3.3.6: resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} engines: {node: '>=8'} @@ -2395,63 +2215,54 @@ packages: engines: {node: '>=10'} hasBin: true - mlly@1.8.0: - resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} + mlly@1.8.2: + resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} + + monaco-editor@0.56.0: + resolution: {integrity: sha512-sXboRm3BeBeLm938eaiyLMe0OxzfXIlZvbv4ir/jVgQy1zDhWjgmny0WoN45fuDKhCCQsYMbBJrv/A6jd8aCUg==} ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - negotiator@0.6.4: - resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} - engines: {node: '>= 0.6'} - - negotiator@1.0.0: - resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} - engines: {node: '>= 0.6'} - neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - node-abi@3.89.0: - resolution: {integrity: sha512-6u9UwL0HlAl21+agMN3YAMXcKByMqwGx+pq+P76vii5f7hTPtKDp08/H9py6DY+cfDw7kQNTGEj/rly3IgbNQA==} - engines: {node: '>=10'} - - node-abi@4.28.0: - resolution: {integrity: sha512-Qfp5XZL1cJDOabOT8H5gnqMTmM4NjvYzHp4I/Kt/Sl76OVkOBBHRFlPspGV0hYvMoqQsypFjT/Yp7Km0beXW9g==} + node-abi@4.33.0: + resolution: {integrity: sha512-vLBWCKb+7LWsX+TbfzWOkw0W81m377tyx3hOweBTjO43CXZnRGS1/JPWs20fr0PgZyDXk6ROYrylsEycK8raDA==} engines: {node: '>=22.12.0'} - node-addon-api@1.7.2: - resolution: {integrity: sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==} - node-addon-api@7.1.1: resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} - node-addon-api@8.5.0: - resolution: {integrity: sha512-/bRZty2mXUIFY/xU5HLvveNHlswNJej+RnxBjOMkidWfwZzgTbPG1E3K5TOxRLOR+5hX7bSofy8yf1hZevMS8A==} + node-addon-api@8.9.0: + resolution: {integrity: sha512-ekZMeaaIzSQTSpr7X2X3iJM7lTzgnx8ahAG9pJfT/7+14mlEM8ZYQ9cgCDvSSRbReFK0oHli3WrZdCiRsgAT9Q==} engines: {node: ^18 || ^20 || >= 21} - node-api-headers@1.8.0: - resolution: {integrity: sha512-jfnmiKWjRAGbdD1yQS28bknFM1tbHC1oucyuMPjmkEs+kpiu76aRs40WlTmBmyEgzDM76ge1DQ7XJ3R5deiVjQ==} + node-api-headers@1.9.0: + resolution: {integrity: sha512-2oNILP4jXwRB4ywnYKjVk1YyJ96n2D4EOVJO6S3oYZ5PtbJrw3Yt9TpAuX3nBLMuzn74rnfGQrv13pS9vC+YiA==} node-api-version@0.2.1: resolution: {integrity: sha512-2xP/IGGMmmSQpI1+O/k72jF/ykvZ89JeuKX3TLJAYPDVLUalrshrLHkeVcCCZqG/eEa635cr8IBYzgnDvM2O8Q==} - node-gyp@11.5.0: - resolution: {integrity: sha512-ra7Kvlhxn5V9Slyus0ygMa2h+UqExPqUIkfk7Pc8QTLT956JLSy51uWFwHtIYy0vI8cB4BDhc/S03+880My/LQ==} - engines: {node: ^18.17.0 || >=20.5.0} + node-gyp@12.4.0: + resolution: {integrity: sha512-OMcPNvqTCFUnNaBlmdgq+lfNqY7gTiSmNRDjY3uAXRyudeKZEZxu3CLtjMQrx4zZxCX2b/mpNqTtwuCJgXhHkw==} + engines: {node: ^20.17.0 || >=22.9.0} hasBin: true - node-releases@2.0.27: - resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - nopt@6.0.0: - resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - hasBin: true + node-releases@2.0.46: + resolution: {integrity: sha512-GYVXHE2KnrzAfsAjl4uP++evGFCrAU1jta4ubEjIG7YWt/64Gqv66a30yKwWczVjA6j3bM4nBwH7Pk1JmDHaxQ==} + engines: {node: '>=18'} - nopt@8.1.0: - resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==} - engines: {node: ^18.17.0 || >=20.5.0} + node-releases@2.0.51: + resolution: {integrity: sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==} + engines: {node: '>=18'} + + nopt@9.0.0: + resolution: {integrity: sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==} + engines: {node: ^20.17.0 || >=22.9.0} hasBin: true normalize-path@3.0.0: @@ -2477,14 +2288,6 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - - ora@5.4.1: - resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} - engines: {node: '>=10'} - p-cancelable@2.1.1: resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} engines: {node: '>=8'} @@ -2493,27 +2296,20 @@ packages: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} - p-map@4.0.0: - resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} - engines: {node: '>=10'} - - p-map@7.0.4: - resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==} - engines: {node: '>=18'} - - package-json-from-dist@1.0.1: - resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - parse5@7.3.0: resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} - parse5@8.0.0: - resolution: {integrity: sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==} + parse5@8.0.1: + resolution: {integrity: sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==} path-exists@5.0.0: resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + path-expression-matcher@1.6.2: + resolution: {integrity: sha512-enSlaiat05iasnzmgNxRj8reFdj3puY2QpNgP1aPIaVfT6nn9ICuPoFlKHk8EN22HcwewshO+mN2DGbkCEOtqQ==} + engines: {node: '>=14.0.0'} + path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} @@ -2525,10 +2321,6 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} - path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -2540,22 +2332,15 @@ packages: resolution: {integrity: sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw==} engines: {node: '>=12', npm: '>=6'} - pend@1.2.0: - resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} - picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} engines: {node: '>=8.6'} - picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} - engines: {node: '>=12'} - - picomatch@4.0.4: - resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + picomatch@4.0.5: + resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} engines: {node: '>=12'} pkg-prebuilds@0.2.1: @@ -2566,53 +2351,59 @@ packages: pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + pkijs@3.4.0: + resolution: {integrity: sha512-emEcLuomt2j03vxD54giVB4SxTjnsqkU692xZOZXHDVoYyypEm+b3jpiTcc+Cf+myooc+/Ly0z01jqeNHVgJGw==} + engines: {node: '>=16.0.0'} + plist@3.1.0: resolution: {integrity: sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==} engines: {node: '>=10.4.0'} + plist@3.1.1: + resolution: {integrity: sha512-ZIfcLJC+7E7FBFnDxm9MPmt7D+DidyQ26lewieO75AdhA2ayMtsJSES0iWzqJQbcVRSrTufQoy0DR94xHue0oA==} + engines: {node: '>=10.4.0'} + postject@1.0.0-alpha.6: resolution: {integrity: sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A==} engines: {node: '>=14.0.0'} hasBin: true - proc-log@2.0.1: - resolution: {integrity: sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + proc-log@6.1.0: + resolution: {integrity: sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==} + engines: {node: ^20.17.0 || >=22.9.0} - proc-log@5.0.0: - resolution: {integrity: sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==} - engines: {node: ^18.17.0 || >=20.5.0} + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} progress@2.0.3: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} - promise-inflight@1.0.1: - resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} - peerDependencies: - bluebird: '*' - peerDependenciesMeta: - bluebird: - optional: true - promise-retry@2.0.1: resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} engines: {node: '>=10'} - proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + proper-lockfile@4.1.2: + resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} - pump@3.0.3: - resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + proxy-from-env@2.1.0: + resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} + engines: {node: '>=10'} - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} pupa@3.3.0: resolution: {integrity: sha512-LjgDO2zPtoXP2wJpDjZrGdojii1uqO0cnwKoIoUzkfS98HDmbeiGmYiXo3lXeFlq2xvne1QFQhwYXSUCLKtEuA==} engines: {node: '>=12.20'} + pvtsutils@1.3.6: + resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} + + pvutils@1.1.5: + resolution: {integrity: sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==} + engines: {node: '>=16.0.0'} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -2628,6 +2419,9 @@ packages: resolution: {integrity: sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg==} hasBin: true + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -2636,14 +2430,18 @@ packages: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} - readdirp@4.1.2: - resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} - engines: {node: '>= 14.18.0'} + readdirp@5.0.0: + resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} + engines: {node: '>= 20.19.0'} require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + resedit@1.7.2: resolution: {integrity: sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA==} engines: {node: '>=12', npm: '>=6'} @@ -2651,21 +2449,14 @@ packages: resolve-alpn@1.2.1: resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} - resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - - resolve@1.22.11: - resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + resolve@1.22.12: + resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} engines: {node: '>= 0.4'} hasBin: true responselike@2.0.1: resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} - restore-cursor@3.1.0: - resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} - engines: {node: '>=8'} - retry@0.12.0: resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} engines: {node: '>= 4'} @@ -2679,11 +2470,6 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true - rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - deprecated: Rimraf versions prior to v4 are no longer supported - hasBin: true - roarr@2.15.4: resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==} engines: {node: '>=8.0'} @@ -2697,8 +2483,8 @@ packages: '@babel/runtime': optional: true - rolldown@1.0.0-rc.15: - resolution: {integrity: sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g==} + rolldown@1.2.0: + resolution: {integrity: sha512-u7tgm5l4Yw1iTqUL4EcYOAt7fFvCgQMLeidrnD4GALlC6aOznCjezYajgxeyKw27u0Q5N7fwgCzjVyPIWzwuBA==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -2709,22 +2495,22 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - sanitize-filename@1.6.4: resolution: {integrity: sha512-9ZyI08PsvdQl2r/bBIGubpVdR3RR9sY6RDiWFPreA21C/EFlQhmgo20UZlNjZMMZNubusLhAQozkA0Od5J21Eg==} - sass@1.97.3: - resolution: {integrity: sha512-fDz1zJpd5GycprAbu4Q2PV/RprsRtKC/0z82z0JLgdytmcq0+ujJbJ/09bPGDxCLkKY3Np5cRAOcWiVkLXJURg==} - engines: {node: '>=14.0.0'} + sass@1.101.6: + resolution: {integrity: sha512-j8qYug9WuX19eU5sxJWQlbR8RYhKgXiOYgGjkJRkcW35c3neWtxPdcUW0saN6Od2L0aqEp0AmH9R/QeAxrffMQ==} + engines: {node: '>=20.19.0'} hasBin: true - sax@1.4.4: - resolution: {integrity: sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==} + sax@1.6.0: + resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} engines: {node: '>=11.0.0'} semver-compare@1.0.0: @@ -2738,13 +2524,18 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.7.3: - resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} engines: {node: '>=10'} hasBin: true - semver@7.7.4: - resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + semver@7.8.1: + resolution: {integrity: sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==} + engines: {node: '>=10'} + hasBin: true + + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} engines: {node: '>=10'} hasBin: true @@ -2752,14 +2543,14 @@ packages: resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==} engines: {node: '>=10'} - seroval-plugins@1.5.0: - resolution: {integrity: sha512-EAHqADIQondwRZIdeW2I636zgsODzoBDwb3PT/+7TLDWyw1Dy/Xv7iGUIEXXav7usHDE9HVhOU61irI3EnyyHA==} + seroval-plugins@1.5.6: + resolution: {integrity: sha512-HXuLAX2pu/UByPpaeo/TaMfvMIi+1QqIoPJYCcAtU8QkVNwgR6MPlGuCQTErV1JwraaMbYaWVIBX7mppzGLATQ==} engines: {node: '>=10'} peerDependencies: seroval: ^1.0 - seroval@1.5.0: - resolution: {integrity: sha512-OE4cvmJ1uSPrKorFIH9/w/Qwuvi/IMcGbv5RKgcJ/zjA/IohDLU6SVaxFN9FwajbP7nsX0dQqMDes1whk3y+yw==} + seroval@1.5.6: + resolution: {integrity: sha512-rVQVWjjSvlINzaQPZH5JFqsqEsIWdTxY3iJZCnTL/5gQbXIRooVZKI60tVCkOVfzcRPejboxO2t0P89dg5mQaA==} engines: {node: '>=10'} set-blocking@2.0.0: @@ -2776,10 +2567,6 @@ packages: signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - simple-update-notifier@2.0.0: resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} engines: {node: '>=10'} @@ -2788,35 +2575,15 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} - slice-ansi@3.0.0: - resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} - engines: {node: '>=8'} - slice-ansi@5.0.0: resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} engines: {node: '>=12'} - smart-buffer@4.2.0: - resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} - engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} - - socks-proxy-agent@7.0.0: - resolution: {integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==} - engines: {node: '>= 10'} - - socks-proxy-agent@8.0.5: - resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} - engines: {node: '>= 14'} - - socks@2.8.7: - resolution: {integrity: sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==} - engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} - solid-js@1.6.16: resolution: {integrity: sha512-Ng4CahvLlpGA3BXIMiiMdwhI8WpObZ8gXqm97GCKR4+MpnODs6Pdpco+tmVCY/4ZDFaEKDxz7WRLAAdoXdlY7w==} - solid-js@1.9.12: - resolution: {integrity: sha512-QzKaSJq2/iDrWR1As6MHZQ8fQkdOBf8GReYb7L5iKwMGceg7HxDcaOHk0at66tNgn9U2U7dXo8ZZpLIAmGMzgw==} + solid-js@1.9.14: + resolution: {integrity: sha512-sAEXC0Kk0S1EDg+8ysEWJDbYhA3RRoEjwuySUGlKIemeo0I5YZfOyumNjNs9Sv3y2nmhD+0rW66ag2HsMuQiGQ==} solid-motionone@1.0.4: resolution: {integrity: sha512-aqEjgecoO9raDFznu/dEci7ORSmA26Kjj9J4Cn1Gyr0GZuOVdvsNxdxClTL9J40Aq/uYFx4GLwC8n70fMLHiuA==} @@ -2842,20 +2609,19 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + spdx-license-list@6.11.0: + resolution: {integrity: sha512-p5ICd51dSnh7zIMtPgbB9ShBg3HMT77OeI6WVhrFFvxa5KIFYNcqxD4joAE+n1zZ7wlJdEkrOMwC75JUMMmsJA==} + engines: {node: '>=8'} + spitroast@2.1.4: resolution: {integrity: sha512-IA987I3wS8RbrKrgag+NsxLUAttrqONF7UGOL+uQFmLLXlMhZl42LomTAltBQaev0jUXIaRiqShZ3hnJYT7OCQ==} + spitroast@2.1.6: + resolution: {integrity: sha512-xil2XeVh8WQoBlG8Lm8jT6ifqWGmSgTGq2clRcq2roycb0kg1h4fv5ydoiBId9kIQp4Y12PK/cjVzD8xpWXZvg==} + sprintf-js@1.1.3: resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} - ssri@12.0.0: - resolution: {integrity: sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==} - engines: {node: ^18.17.0 || >=20.5.0} - - ssri@9.0.1: - resolution: {integrity: sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - stat-mode@1.0.0: resolution: {integrity: sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==} engines: {node: '>= 6'} @@ -2864,14 +2630,13 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - string-width@7.2.0: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} @@ -2879,10 +2644,6 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.1.2: - resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} - engines: {node: '>=12'} - strip-ansi@7.2.0: resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} engines: {node: '>=12'} @@ -2891,6 +2652,9 @@ packages: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} + strnum@2.4.1: + resolution: {integrity: sha512-M9eUSMT2dCB2cTNPG7UYj6KuK7RJR2SN2+yCV/fTW3xzTCS6EaGZ5pSMgDIjB7r8zSfTGk+dvvn9rTjpVS9Mwg==} + sumchecker@3.0.1: resolution: {integrity: sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==} engines: {node: '>= 8.0'} @@ -2908,8 +2672,8 @@ packages: engines: {node: '>=10'} deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me - tar@7.5.13: - resolution: {integrity: sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==} + tar@7.5.21: + resolution: {integrity: sha512-XdhtCvlMywwxpCW8YEq3lOXBJpUPTR2OHHcwLPO3HwsJqOHa2Ok/oJ7ruGzp+JrKoRPVCzJwAdEjqLW/vNRPHA==} engines: {node: '>=18'} temp-file@3.4.0: @@ -2925,15 +2689,15 @@ packages: tiny-typed-emitter@2.1.0: resolution: {integrity: sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==} - tinyglobby@0.2.15: - resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} engines: {node: '>=12.0.0'} tmp-promise@3.0.3: resolution: {integrity: sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==} - tmp@0.2.5: - resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} + tmp@0.2.7: + resolution: {integrity: sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==} engines: {node: '>=14.14'} to-regex-range@5.0.1: @@ -2946,49 +2710,36 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - tsx@4.21.0: - resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} - engines: {node: '>=18.0.0'} - hasBin: true - type-fest@0.13.1: resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} engines: {node: '>=10'} - typescript@5.9.3: - resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} - engines: {node: '>=14.17'} + typescript@7.0.2: + resolution: {integrity: sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==} + engines: {node: '>=16.20.0'} hasBin: true - ufo@1.6.3: - resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} + ufo@1.6.4: + resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} uglify-js@3.19.3: resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} engines: {node: '>=0.8.0'} hasBin: true - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + undici-types@7.18.2: + resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} - undici-types@7.16.0: - resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + undici-types@8.3.0: + resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==} - unique-filename@2.0.1: - resolution: {integrity: sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + undici@6.27.0: + resolution: {integrity: sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==} + engines: {node: '>=18.17'} - unique-filename@4.0.0: - resolution: {integrity: sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ==} - engines: {node: ^18.17.0 || >=20.5.0} - - unique-slug@3.0.0: - resolution: {integrity: sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - - unique-slug@5.0.0: - resolution: {integrity: sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==} - engines: {node: ^18.17.0 || >=20.5.0} + undici@7.28.0: + resolution: {integrity: sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==} + engines: {node: '>=20.18.1'} universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} @@ -3002,15 +2753,15 @@ packages: resolution: {integrity: sha512-ZX6U1J04K1FoSUeoX1OicAhw4d0aro2qo+L8RhJkiGTNtBNkd/Fi1Wxoc9HzcVu6HfOzm0si/N15JjxFmD1z6A==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + unzipper@0.12.5: + resolution: {integrity: sha512-tXYOi9R57Uj/2Z25SOs5RRSzq886MBQj2gY8dPL+xl/kv6s6SvByoKfAtvfVeEuhntWDgjd2o9p2lb4TVPAz0A==} + update-browserslist-db@1.2.3: resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - url-join@4.0.1: resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==} @@ -3020,12 +2771,8 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - verror@1.10.1: - resolution: {integrity: sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==} - engines: {node: '>=0.6.0'} - - wcwidth@1.0.1: - resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + webcrypto-core@1.9.2: + resolution: {integrity: sha512-gsXecm82UQNlTBURJGuqOWy1Ww08S3kZUcr3aOJS02Pk0xLtkfeUAVC0u0xhgdonFme80edSJUIJyuvL/7250Q==} which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} @@ -3037,6 +2784,11 @@ packages: engines: {node: ^18.17.0 || >=20.5.0} hasBin: true + which@6.0.1: + resolution: {integrity: sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==} + engines: {node: ^20.17.0 || >=22.9.0} + hasBin: true + wide-align@1.1.5: resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} @@ -3047,15 +2799,11 @@ packages: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - ws@8.20.0: - resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} + ws@8.21.1: + resolution: {integrity: sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -3070,9 +2818,13 @@ packages: resolution: {integrity: sha512-+8qTc3zv2UcJ1v9IsSIce37Dl4MQG14Cp7tWrwmy202UaI1wqRukw5QMX1JHsV+DX64yw77EgGsj2s5wGvuMbQ==} engines: {node: '>= 16'} - xml-parser-xo@4.1.5: - resolution: {integrity: sha512-TxyRxk9sTOUg3glxSIY6f0nfuqRll2OEF8TspLgh5mZkLuBgheCn3zClcDSGJ58TvNmiwyCCuat4UajPud/5Og==} - engines: {node: '>= 16'} + xml-naming@0.3.0: + resolution: {integrity: sha512-ghig2TBE/H11aOVgmahA3MhimvkBr6JIYknH/Dhdk10nXwdbIqBJsbfMxpvFPG8bAw77gN29aQWvKpmVoPlvPQ==} + engines: {node: '>=16.0.0'} + + xml-parser-xo@4.1.6: + resolution: {integrity: sha512-mXbSNSM+rIwndoxSwmFa83bOdeP8G/cOGr7XvxA67X7ebCzoAuVez9JYDCDub3zRDNBZxIbfjuXLSsamr7NfwQ==} + engines: {node: '>= 20'} xmlbuilder@15.1.1: resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==} @@ -3096,13 +2848,10 @@ packages: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} - yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + yargs@17.7.3: + resolution: {integrity: sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==} engines: {node: '>=12'} - yauzl@2.10.0: - resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} - yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -3112,34 +2861,32 @@ packages: snapshots: - 7zip-bin@5.2.0: {} - - '@babel/code-frame@7.28.6': + '@babel/code-frame@7.29.7': dependencies: - '@babel/helper-validator-identifier': 7.28.5 + '@babel/helper-validator-identifier': 7.29.7 js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/code-frame@8.0.0-rc.3': + '@babel/code-frame@8.0.0': dependencies: - '@babel/helper-validator-identifier': 8.0.0-rc.3 + '@babel/helper-validator-identifier': 8.0.4 js-tokens: 10.0.0 - '@babel/compat-data@7.28.6': {} + '@babel/compat-data@7.29.7': {} - '@babel/compat-data@8.0.0-rc.3': {} + '@babel/compat-data@8.0.0': {} - '@babel/core@7.28.6': + '@babel/core@7.29.7': dependencies: - '@babel/code-frame': 7.28.6 - '@babel/generator': 7.28.6 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.28.6) - '@babel/helpers': 7.28.6 - '@babel/parser': 7.28.6 - '@babel/template': 7.28.6 - '@babel/traverse': 7.28.6 - '@babel/types': 7.28.6 + '@babel/code-frame': 7.29.7 + '@babel/generator': 7.29.7 + '@babel/helper-compilation-targets': 7.29.7 + '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) + '@babel/helpers': 7.29.7 + '@babel/parser': 7.29.7 + '@babel/template': 7.29.7 + '@babel/traverse': 7.29.7 + '@babel/types': 7.29.7 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 debug: 4.4.3 @@ -3149,301 +2896,298 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/core@8.0.0-rc.3': + '@babel/core@8.0.1': dependencies: - '@babel/code-frame': 8.0.0-rc.3 - '@babel/generator': 8.0.0-rc.3 - '@babel/helper-compilation-targets': 8.0.0-rc.3 - '@babel/helpers': 8.0.0-rc.3 - '@babel/parser': 8.0.0-rc.3 - '@babel/template': 8.0.0-rc.3 - '@babel/traverse': 8.0.0-rc.3 - '@babel/types': 8.0.0-rc.3 - '@jridgewell/remapping': 2.3.5 - '@types/gensync': 1.0.4 + '@babel/code-frame': 8.0.0 + '@babel/generator': 8.0.0 + '@babel/helper-compilation-targets': 8.0.0 + '@babel/helpers': 8.0.0 + '@babel/parser': 8.0.4 + '@babel/template': 8.0.0 + '@babel/traverse': 8.0.4 + '@babel/types': 8.0.4 + '@types/gensync': 1.0.5 convert-source-map: 2.0.0 + empathic: 2.0.1 gensync: 1.0.0-beta.2 import-meta-resolve: 4.2.0 json5: 2.2.3 obug: 2.1.1 - semver: 7.7.4 + semver: 7.8.1 - '@babel/generator@7.28.6': + '@babel/generator@7.29.7': dependencies: - '@babel/parser': 7.28.6 - '@babel/types': 7.28.6 + '@babel/parser': 7.29.7 + '@babel/types': 7.29.7 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 - '@babel/generator@8.0.0-rc.3': + '@babel/generator@8.0.0': dependencies: - '@babel/parser': 8.0.0-rc.3 - '@babel/types': 8.0.0-rc.3 + '@babel/parser': 8.0.4 + '@babel/types': 8.0.4 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 '@types/jsesc': 2.5.1 jsesc: 3.1.0 - '@babel/helper-annotate-as-pure@7.27.3': + '@babel/helper-annotate-as-pure@7.29.7': dependencies: - '@babel/types': 7.28.6 + '@babel/types': 7.29.7 - '@babel/helper-compilation-targets@7.28.6': + '@babel/helper-compilation-targets@7.29.7': dependencies: - '@babel/compat-data': 7.28.6 - '@babel/helper-validator-option': 7.27.1 - browserslist: 4.28.1 + '@babel/compat-data': 7.29.7 + '@babel/helper-validator-option': 7.29.7 + browserslist: 4.28.7 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-compilation-targets@8.0.0-rc.3': + '@babel/helper-compilation-targets@8.0.0': dependencies: - '@babel/compat-data': 8.0.0-rc.3 - '@babel/helper-validator-option': 8.0.0-rc.3 - browserslist: 4.28.1 - lru-cache: 7.18.3 - semver: 7.7.4 + '@babel/compat-data': 8.0.0 + '@babel/helper-validator-option': 8.0.0 + browserslist: 4.28.2 + lru-cache: 11.5.2 + semver: 7.8.1 - '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.28.6)': + '@babel/helper-create-class-features-plugin@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.28.6 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-member-expression-to-functions': 7.28.5 - '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/helper-replace-supers': 7.28.6(@babel/core@7.28.6) - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/traverse': 7.28.6 + '@babel/core': 7.29.7 + '@babel/helper-annotate-as-pure': 7.29.7 + '@babel/helper-member-expression-to-functions': 7.29.7 + '@babel/helper-optimise-call-expression': 7.29.7 + '@babel/helper-replace-supers': 7.29.7(@babel/core@7.29.7) + '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 + '@babel/traverse': 7.29.7 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/helper-globals@7.28.0': {} + '@babel/helper-globals@7.29.7': {} - '@babel/helper-globals@8.0.0-rc.3': {} + '@babel/helper-globals@8.0.0': {} - '@babel/helper-member-expression-to-functions@7.28.5': + '@babel/helper-member-expression-to-functions@7.29.7': dependencies: - '@babel/traverse': 7.28.6 - '@babel/types': 7.29.0 + '@babel/traverse': 7.29.7 + '@babel/types': 7.29.7 transitivePeerDependencies: - supports-color '@babel/helper-module-imports@7.18.6': dependencies: - '@babel/types': 7.29.0 + '@babel/types': 7.29.7 - '@babel/helper-module-imports@7.28.6': + '@babel/helper-module-imports@7.29.7': dependencies: - '@babel/traverse': 7.28.6 - '@babel/types': 7.28.6 + '@babel/traverse': 7.29.7 + '@babel/types': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/helper-module-imports@8.0.0-rc.3': + '@babel/helper-module-imports@8.0.0': dependencies: - '@babel/traverse': 8.0.0-rc.3 - '@babel/types': 8.0.0-rc.3 + '@babel/traverse': 8.0.4 + '@babel/types': 8.0.4 - '@babel/helper-module-transforms@7.28.6(@babel/core@7.28.6)': + '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.28.6 - '@babel/helper-module-imports': 7.28.6 - '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.28.6 + '@babel/core': 7.29.7 + '@babel/helper-module-imports': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/helper-optimise-call-expression@7.27.1': + '@babel/helper-optimise-call-expression@7.29.7': dependencies: - '@babel/types': 7.29.0 + '@babel/types': 7.29.7 - '@babel/helper-plugin-utils@7.28.6': {} + '@babel/helper-plugin-utils@7.29.7': {} - '@babel/helper-plugin-utils@8.0.0-rc.3(@babel/core@8.0.0-rc.3)': + '@babel/helper-plugin-utils@8.0.1(@babel/core@8.0.1)': dependencies: - '@babel/core': 8.0.0-rc.3 + '@babel/core': 8.0.1 - '@babel/helper-replace-supers@7.28.6(@babel/core@7.28.6)': + '@babel/helper-replace-supers@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.28.6 - '@babel/helper-member-expression-to-functions': 7.28.5 - '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/traverse': 7.28.6 + '@babel/core': 7.29.7 + '@babel/helper-member-expression-to-functions': 7.29.7 + '@babel/helper-optimise-call-expression': 7.29.7 + '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + '@babel/helper-skip-transparent-expression-wrappers@7.29.7': dependencies: - '@babel/traverse': 7.28.6 - '@babel/types': 7.28.6 + '@babel/traverse': 7.29.7 + '@babel/types': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/helper-string-parser@7.27.1': {} + '@babel/helper-string-parser@7.29.7': {} - '@babel/helper-string-parser@8.0.0-rc.3': {} + '@babel/helper-string-parser@8.0.0': {} - '@babel/helper-validator-identifier@7.28.5': {} + '@babel/helper-validator-identifier@7.29.7': {} - '@babel/helper-validator-identifier@8.0.0-rc.3': {} + '@babel/helper-validator-identifier@8.0.4': {} - '@babel/helper-validator-option@7.27.1': {} + '@babel/helper-validator-option@7.29.7': {} - '@babel/helper-validator-option@8.0.0-rc.3': {} + '@babel/helper-validator-option@8.0.0': {} - '@babel/helpers@7.28.6': + '@babel/helpers@7.29.7': dependencies: - '@babel/template': 7.28.6 - '@babel/types': 7.28.6 + '@babel/template': 7.29.7 + '@babel/types': 7.29.7 - '@babel/helpers@8.0.0-rc.3': + '@babel/helpers@8.0.0': dependencies: - '@babel/template': 8.0.0-rc.3 - '@babel/types': 8.0.0-rc.3 + '@babel/template': 8.0.0 + '@babel/types': 8.0.4 - '@babel/parser@7.28.6': + '@babel/parser@7.29.7': dependencies: - '@babel/types': 7.28.6 + '@babel/types': 7.29.7 - '@babel/parser@8.0.0-rc.3': + '@babel/parser@8.0.4': dependencies: - '@babel/types': 8.0.0-rc.3 + '@babel/types': 8.0.4 - '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.29.7 + '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-syntax-jsx@7.29.7(@babel/core@8.0.1)': dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 8.0.1 + '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.28.6 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.28.6) - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.29.7 + '@babel/helper-plugin-utils': 7.29.7 + + '@babel/plugin-transform-modules-commonjs@7.29.7(@babel/core@7.29.7)': + dependencies: + '@babel/core': 7.29.7 + '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) + '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.28.6)': + '@babel/plugin-transform-typescript@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.28.6 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.28.6) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.28.6) + '@babel/core': 7.29.7 + '@babel/helper-annotate-as-pure': 7.29.7 + '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.7) + '@babel/helper-plugin-utils': 7.29.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 + '@babel/plugin-syntax-typescript': 7.29.7(@babel/core@7.29.7) transitivePeerDependencies: - supports-color - '@babel/preset-typescript@7.28.5(@babel/core@7.28.6)': + '@babel/preset-typescript@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.28.6) - '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.28.6) + '@babel/core': 7.29.7 + '@babel/helper-plugin-utils': 7.29.7 + '@babel/helper-validator-option': 7.29.7 + '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-modules-commonjs': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-typescript': 7.29.7(@babel/core@7.29.7) transitivePeerDependencies: - supports-color - '@babel/template@7.28.6': + '@babel/template@7.29.7': dependencies: - '@babel/code-frame': 7.28.6 - '@babel/parser': 7.28.6 - '@babel/types': 7.28.6 + '@babel/code-frame': 7.29.7 + '@babel/parser': 7.29.7 + '@babel/types': 7.29.7 - '@babel/template@8.0.0-rc.3': + '@babel/template@8.0.0': dependencies: - '@babel/code-frame': 8.0.0-rc.3 - '@babel/parser': 8.0.0-rc.3 - '@babel/types': 8.0.0-rc.3 + '@babel/code-frame': 8.0.0 + '@babel/parser': 8.0.4 + '@babel/types': 8.0.4 - '@babel/traverse@7.28.6': + '@babel/traverse@7.29.7': dependencies: - '@babel/code-frame': 7.28.6 - '@babel/generator': 7.28.6 - '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.6 - '@babel/template': 7.28.6 - '@babel/types': 7.28.6 + '@babel/code-frame': 7.29.7 + '@babel/generator': 7.29.7 + '@babel/helper-globals': 7.29.7 + '@babel/parser': 7.29.7 + '@babel/template': 7.29.7 + '@babel/types': 7.29.7 debug: 4.4.3 transitivePeerDependencies: - supports-color - '@babel/traverse@8.0.0-rc.3': + '@babel/traverse@8.0.4': dependencies: - '@babel/code-frame': 8.0.0-rc.3 - '@babel/generator': 8.0.0-rc.3 - '@babel/helper-globals': 8.0.0-rc.3 - '@babel/parser': 8.0.0-rc.3 - '@babel/template': 8.0.0-rc.3 - '@babel/types': 8.0.0-rc.3 + '@babel/code-frame': 8.0.0 + '@babel/generator': 8.0.0 + '@babel/helper-globals': 8.0.0 + '@babel/parser': 8.0.4 + '@babel/template': 8.0.0 + '@babel/types': 8.0.4 obug: 2.1.1 - '@babel/types@7.28.6': + '@babel/types@7.29.7': dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.28.5 + '@babel/helper-string-parser': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 - '@babel/types@7.29.0': + '@babel/types@8.0.4': dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.28.5 + '@babel/helper-string-parser': 8.0.0 + '@babel/helper-validator-identifier': 8.0.4 - '@babel/types@8.0.0-rc.3': - dependencies: - '@babel/helper-string-parser': 8.0.0-rc.3 - '@babel/helper-validator-identifier': 8.0.0-rc.3 - - '@biomejs/biome@1.9.4': + '@biomejs/biome@2.5.5': optionalDependencies: - '@biomejs/cli-darwin-arm64': 1.9.4 - '@biomejs/cli-darwin-x64': 1.9.4 - '@biomejs/cli-linux-arm64': 1.9.4 - '@biomejs/cli-linux-arm64-musl': 1.9.4 - '@biomejs/cli-linux-x64': 1.9.4 - '@biomejs/cli-linux-x64-musl': 1.9.4 - '@biomejs/cli-win32-arm64': 1.9.4 - '@biomejs/cli-win32-x64': 1.9.4 + '@biomejs/cli-darwin-arm64': 2.5.5 + '@biomejs/cli-darwin-x64': 2.5.5 + '@biomejs/cli-linux-arm64': 2.5.5 + '@biomejs/cli-linux-arm64-musl': 2.5.5 + '@biomejs/cli-linux-x64': 2.5.5 + '@biomejs/cli-linux-x64-musl': 2.5.5 + '@biomejs/cli-win32-arm64': 2.5.5 + '@biomejs/cli-win32-x64': 2.5.5 - '@biomejs/cli-darwin-arm64@1.9.4': + '@biomejs/cli-darwin-arm64@2.5.5': optional: true - '@biomejs/cli-darwin-x64@1.9.4': + '@biomejs/cli-darwin-x64@2.5.5': optional: true - '@biomejs/cli-linux-arm64-musl@1.9.4': + '@biomejs/cli-linux-arm64-musl@2.5.5': optional: true - '@biomejs/cli-linux-arm64@1.9.4': + '@biomejs/cli-linux-arm64@2.5.5': optional: true - '@biomejs/cli-linux-x64-musl@1.9.4': + '@biomejs/cli-linux-x64-musl@2.5.5': optional: true - '@biomejs/cli-linux-x64@1.9.4': + '@biomejs/cli-linux-x64@2.5.5': optional: true - '@biomejs/cli-win32-arm64@1.9.4': + '@biomejs/cli-win32-arm64@2.5.5': optional: true - '@biomejs/cli-win32-x64@1.9.4': + '@biomejs/cli-win32-x64@2.5.5': optional: true - '@develar/schema-utils@2.6.5': - dependencies: - ajv: 6.12.6 - ajv-keywords: 3.5.2(ajv@6.12.6) + '@electron-internal/extract-zip@1.0.4': {} '@electron/asar@3.4.1': dependencies: commander: 5.1.0 glob: 7.2.3 - minimatch: 3.1.2 + minimatch: 3.1.5 '@electron/fuses@1.8.0': dependencies: @@ -3451,7 +3195,7 @@ snapshots: fs-extra: 9.1.0 minimist: 1.2.8 - '@electron/get@2.0.3': + '@electron/get@3.1.0': dependencies: debug: 4.4.3 env-paths: 2.2.1 @@ -3465,20 +3209,17 @@ snapshots: transitivePeerDependencies: - supports-color - '@electron/node-gyp@https://codeload.github.com/electron/node-gyp/tar.gz/06b29aafb7708acef8b3669835c8a7857ebc92d2': + '@electron/get@5.0.0': dependencies: - env-paths: 2.2.1 - exponential-backoff: 3.1.3 - glob: 8.1.0 + debug: 4.4.3 + env-paths: 3.0.0 graceful-fs: 4.2.11 - make-fetch-happen: 10.2.1 - nopt: 6.0.0 - proc-log: 2.0.1 - semver: 7.7.4 - tar: 6.2.1 - which: 2.0.2 + progress: 2.0.3 + semver: 7.8.5 + sumchecker: 3.0.1 + optionalDependencies: + undici: 7.28.0 transitivePeerDependencies: - - bluebird - supports-color '@electron/notarize@2.5.0': @@ -3496,46 +3237,18 @@ snapshots: fs-extra: 10.1.0 isbinaryfile: 4.0.10 minimist: 1.2.8 - plist: 3.1.0 + plist: 3.1.1 transitivePeerDependencies: - supports-color - '@electron/rebuild@3.7.2': - dependencies: - '@electron/node-gyp': https://codeload.github.com/electron/node-gyp/tar.gz/06b29aafb7708acef8b3669835c8a7857ebc92d2 - '@malept/cross-spawn-promise': 2.0.0 - chalk: 4.1.2 - debug: 4.4.3 - detect-libc: 2.1.2 - fs-extra: 10.1.0 - got: 11.8.6 - node-abi: 3.89.0 - node-api-version: 0.2.1 - ora: 5.4.1 - read-binary-file-arch: 1.0.6 - semver: 7.7.4 - tar: 6.2.1 - yargs: 17.7.2 - transitivePeerDependencies: - - bluebird - - supports-color - - '@electron/rebuild@4.0.1': + '@electron/rebuild@4.2.0': dependencies: '@malept/cross-spawn-promise': 2.0.0 - chalk: 4.1.2 debug: 4.4.3 - detect-libc: 2.1.2 - got: 11.8.6 - graceful-fs: 4.2.11 - node-abi: 4.28.0 + node-abi: 4.33.0 node-api-version: 0.2.1 - node-gyp: 11.5.0 - ora: 5.4.1 + node-gyp: 12.4.0 read-binary-file-arch: 1.0.6 - semver: 7.7.4 - tar: 6.2.1 - yargs: 17.7.2 transitivePeerDependencies: - supports-color @@ -3545,9 +3258,9 @@ snapshots: '@malept/cross-spawn-promise': 2.0.0 debug: 4.4.3 dir-compare: 4.2.0 - fs-extra: 11.3.4 + fs-extra: 11.3.6 minimatch: 9.0.9 - plist: 3.1.0 + plist: 3.1.1 transitivePeerDependencies: - supports-color @@ -3555,210 +3268,104 @@ snapshots: dependencies: cross-dirname: 0.1.0 debug: 4.4.3 - fs-extra: 11.3.4 + fs-extra: 11.3.6 minimist: 1.2.8 postject: 1.0.0-alpha.6 transitivePeerDependencies: - supports-color optional: true - '@emnapi/core@1.8.1': + '@emnapi/core@1.11.2': dependencies: - '@emnapi/wasi-threads': 1.1.0 + '@emnapi/wasi-threads': 1.2.2 tslib: 2.8.1 optional: true - '@emnapi/core@1.9.2': - dependencies: - '@emnapi/wasi-threads': 1.2.1 - tslib: 2.8.1 - optional: true - - '@emnapi/runtime@1.8.1': + '@emnapi/runtime@1.11.2': dependencies: tslib: 2.8.1 optional: true - '@emnapi/runtime@1.9.2': + '@emnapi/wasi-threads@1.2.2': dependencies: tslib: 2.8.1 optional: true - '@emnapi/wasi-threads@1.1.0': - dependencies: - tslib: 2.8.1 - optional: true - - '@emnapi/wasi-threads@1.2.1': - dependencies: - tslib: 2.8.1 - optional: true - - '@esbuild/aix-ppc64@0.27.2': - optional: true - '@esbuild/android-arm64@0.17.19': optional: true - '@esbuild/android-arm64@0.27.2': - optional: true - '@esbuild/android-arm@0.17.19': optional: true - '@esbuild/android-arm@0.27.2': - optional: true - '@esbuild/android-x64@0.17.19': optional: true - '@esbuild/android-x64@0.27.2': - optional: true - '@esbuild/darwin-arm64@0.17.19': optional: true - '@esbuild/darwin-arm64@0.27.2': - optional: true - '@esbuild/darwin-x64@0.17.19': optional: true - '@esbuild/darwin-x64@0.27.2': - optional: true - '@esbuild/freebsd-arm64@0.17.19': optional: true - '@esbuild/freebsd-arm64@0.27.2': - optional: true - '@esbuild/freebsd-x64@0.17.19': optional: true - '@esbuild/freebsd-x64@0.27.2': - optional: true - '@esbuild/linux-arm64@0.17.19': optional: true - '@esbuild/linux-arm64@0.27.2': - optional: true - '@esbuild/linux-arm@0.17.19': optional: true - '@esbuild/linux-arm@0.27.2': - optional: true - '@esbuild/linux-ia32@0.17.19': optional: true - '@esbuild/linux-ia32@0.27.2': - optional: true - '@esbuild/linux-loong64@0.17.19': optional: true - '@esbuild/linux-loong64@0.27.2': - optional: true - '@esbuild/linux-mips64el@0.17.19': optional: true - '@esbuild/linux-mips64el@0.27.2': - optional: true - '@esbuild/linux-ppc64@0.17.19': optional: true - '@esbuild/linux-ppc64@0.27.2': - optional: true - '@esbuild/linux-riscv64@0.17.19': optional: true - '@esbuild/linux-riscv64@0.27.2': - optional: true - '@esbuild/linux-s390x@0.17.19': optional: true - '@esbuild/linux-s390x@0.27.2': - optional: true - '@esbuild/linux-x64@0.17.19': optional: true - '@esbuild/linux-x64@0.27.2': - optional: true - - '@esbuild/netbsd-arm64@0.27.2': - optional: true - '@esbuild/netbsd-x64@0.17.19': optional: true - '@esbuild/netbsd-x64@0.27.2': - optional: true - - '@esbuild/openbsd-arm64@0.27.2': - optional: true - '@esbuild/openbsd-x64@0.17.19': optional: true - '@esbuild/openbsd-x64@0.27.2': - optional: true - - '@esbuild/openharmony-arm64@0.27.2': - optional: true - '@esbuild/sunos-x64@0.17.19': optional: true - '@esbuild/sunos-x64@0.27.2': - optional: true - '@esbuild/win32-arm64@0.17.19': optional: true - '@esbuild/win32-arm64@0.27.2': - optional: true - '@esbuild/win32-ia32@0.17.19': optional: true - '@esbuild/win32-ia32@0.27.2': - optional: true - '@esbuild/win32-x64@0.17.19': optional: true - '@esbuild/win32-x64@0.27.2': - optional: true - - '@gar/promisify@1.1.3': {} - - '@isaacs/balanced-match@4.0.1': {} - - '@isaacs/brace-expansion@5.0.0': - dependencies: - '@isaacs/balanced-match': 4.0.1 - - '@isaacs/cliui@8.0.2': - dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.2.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 - '@isaacs/fs-minipass@4.0.1': dependencies: minipass: 7.1.3 + '@jellybrick/dbus-next@0.11.1': + dependencies: + fast-xml-builder: 1.3.0 + fast-xml-parser: 5.10.1 + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -3786,7 +3393,7 @@ snapshots: dependencies: debug: 4.4.3 fs-extra: 9.1.0 - lodash: 4.17.23 + lodash: 4.18.1 tmp-promise: 3.0.3 transitivePeerDependencies: - supports-color @@ -3828,18 +3435,24 @@ snapshots: '@napi-rs/wasm-runtime@0.2.12': dependencies: - '@emnapi/core': 1.8.1 - '@emnapi/runtime': 1.8.1 - '@tybys/wasm-util': 0.10.1 + '@emnapi/core': 1.11.2 + '@emnapi/runtime': 1.11.2 + '@tybys/wasm-util': 0.10.3 optional: true - '@napi-rs/wasm-runtime@1.1.3(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)': + '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2)': dependencies: - '@emnapi/core': 1.9.2 - '@emnapi/runtime': 1.9.2 - '@tybys/wasm-util': 0.10.1 + '@emnapi/core': 1.11.2 + '@emnapi/runtime': 1.11.2 + '@tybys/wasm-util': 0.10.3 optional: true + '@noble/hashes@1.4.0': {} + + '@noble/hashes@2.2.0': {} + + '@nodable/entities@3.0.0': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -3852,172 +3465,161 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 - '@npmcli/agent@3.0.0': - dependencies: - agent-base: 7.1.4 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 - lru-cache: 10.4.3 - socks-proxy-agent: 8.0.5 - transitivePeerDependencies: - - supports-color + '@oxc-project/types@0.140.0': {} - '@npmcli/fs@2.1.2': - dependencies: - '@gar/promisify': 1.1.3 - semver: 7.7.4 - - '@npmcli/fs@4.0.0': - dependencies: - semver: 7.7.4 - - '@npmcli/move-file@2.0.1': - dependencies: - mkdirp: 1.0.4 - rimraf: 3.0.2 - - '@oxc-project/types@0.124.0': {} - - '@parcel/watcher-android-arm64@2.5.6': + '@parcel/watcher-android-arm64@2.6.0': optional: true - '@parcel/watcher-darwin-arm64@2.5.6': + '@parcel/watcher-darwin-arm64@2.6.0': optional: true - '@parcel/watcher-darwin-x64@2.5.6': + '@parcel/watcher-darwin-x64@2.6.0': optional: true - '@parcel/watcher-freebsd-x64@2.5.6': + '@parcel/watcher-freebsd-x64@2.6.0': optional: true - '@parcel/watcher-linux-arm-glibc@2.5.6': + '@parcel/watcher-linux-arm-glibc@2.6.0': optional: true - '@parcel/watcher-linux-arm-musl@2.5.6': + '@parcel/watcher-linux-arm-musl@2.6.0': optional: true - '@parcel/watcher-linux-arm64-glibc@2.5.6': + '@parcel/watcher-linux-arm64-glibc@2.6.0': optional: true - '@parcel/watcher-linux-arm64-musl@2.5.6': + '@parcel/watcher-linux-arm64-musl@2.6.0': optional: true - '@parcel/watcher-linux-x64-glibc@2.5.6': + '@parcel/watcher-linux-x64-glibc@2.6.0': optional: true - '@parcel/watcher-linux-x64-musl@2.5.6': + '@parcel/watcher-linux-x64-musl@2.6.0': optional: true - '@parcel/watcher-win32-arm64@2.5.6': + '@parcel/watcher-win32-arm64@2.6.0': optional: true - '@parcel/watcher-win32-ia32@2.5.6': + '@parcel/watcher-win32-x64@2.6.0': optional: true - '@parcel/watcher-win32-x64@2.5.6': - optional: true - - '@parcel/watcher@2.5.6': + '@parcel/watcher@2.6.0': dependencies: detect-libc: 2.1.2 is-glob: 4.0.3 node-addon-api: 7.1.1 - picomatch: 4.0.3 + picomatch: 4.0.5 optionalDependencies: - '@parcel/watcher-android-arm64': 2.5.6 - '@parcel/watcher-darwin-arm64': 2.5.6 - '@parcel/watcher-darwin-x64': 2.5.6 - '@parcel/watcher-freebsd-x64': 2.5.6 - '@parcel/watcher-linux-arm-glibc': 2.5.6 - '@parcel/watcher-linux-arm-musl': 2.5.6 - '@parcel/watcher-linux-arm64-glibc': 2.5.6 - '@parcel/watcher-linux-arm64-musl': 2.5.6 - '@parcel/watcher-linux-x64-glibc': 2.5.6 - '@parcel/watcher-linux-x64-musl': 2.5.6 - '@parcel/watcher-win32-arm64': 2.5.6 - '@parcel/watcher-win32-ia32': 2.5.6 - '@parcel/watcher-win32-x64': 2.5.6 + '@parcel/watcher-android-arm64': 2.6.0 + '@parcel/watcher-darwin-arm64': 2.6.0 + '@parcel/watcher-darwin-x64': 2.6.0 + '@parcel/watcher-freebsd-x64': 2.6.0 + '@parcel/watcher-linux-arm-glibc': 2.6.0 + '@parcel/watcher-linux-arm-musl': 2.6.0 + '@parcel/watcher-linux-arm64-glibc': 2.6.0 + '@parcel/watcher-linux-arm64-musl': 2.6.0 + '@parcel/watcher-linux-x64-glibc': 2.6.0 + '@parcel/watcher-linux-x64-musl': 2.6.0 + '@parcel/watcher-win32-arm64': 2.6.0 + '@parcel/watcher-win32-x64': 2.6.0 optional: true - '@pkgjs/parseargs@0.11.0': - optional: true - - '@rolldown-plugin/solid@0.0.4(csstype@3.2.3)(rolldown@1.0.0-rc.15)(seroval@1.5.0)(solid-js@1.9.12)': + '@peculiar/asn1-schema@2.8.0': dependencies: - '@babel/core': 8.0.0-rc.3 - '@babel/helper-module-imports': 8.0.0-rc.3 - '@babel/helper-plugin-utils': 8.0.0-rc.3(@babel/core@8.0.0-rc.3) - '@babel/helper-validator-option': 8.0.0-rc.3 - '@babel/template': 8.0.0-rc.3 - '@babel/traverse': 8.0.0-rc.3 - '@babel/types': 8.0.0-rc.3 + '@peculiar/utils': 2.0.3 + asn1js: 3.0.10 + tslib: 2.8.1 + + '@peculiar/json-schema@1.1.12': + dependencies: + tslib: 2.8.1 + + '@peculiar/utils@2.0.3': + dependencies: + tslib: 2.8.1 + + '@peculiar/webcrypto@1.7.1': + dependencies: + '@peculiar/asn1-schema': 2.8.0 + '@peculiar/json-schema': 1.1.12 + '@peculiar/utils': 2.0.3 + tslib: 2.8.1 + webcrypto-core: 1.9.2 + + '@rolldown-plugin/solid@0.1.0(csstype@3.2.3)(rolldown@1.2.0)(seroval@1.5.6)(solid-js@1.9.14)': + dependencies: + '@babel/core': 8.0.1 + '@babel/helper-module-imports': 8.0.0 + '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.1) + '@babel/helper-validator-option': 8.0.0 + '@babel/template': 8.0.0 + '@babel/traverse': 8.0.4 + '@babel/types': 8.0.4 csstype: 3.2.3 html-entities: 2.6.0 - parse5: 8.0.0 - rolldown: 1.0.0-rc.15 - seroval: 1.5.0 - solid-js: 1.9.12 - transitivePeerDependencies: - - '@babel/preset-typescript' + parse5: 8.0.1 + rolldown: 1.2.0 + seroval: 1.5.6 + solid-js: 1.9.14 - '@rolldown/binding-android-arm64@1.0.0-rc.15': + '@rolldown/binding-android-arm64@1.2.0': optional: true '@rolldown/binding-darwin-arm64@1.0.0-beta.1': optional: true - '@rolldown/binding-darwin-arm64@1.0.0-rc.15': + '@rolldown/binding-darwin-arm64@1.2.0': optional: true '@rolldown/binding-darwin-x64@1.0.0-beta.1': optional: true - '@rolldown/binding-darwin-x64@1.0.0-rc.15': + '@rolldown/binding-darwin-x64@1.2.0': optional: true '@rolldown/binding-freebsd-x64@1.0.0-beta.1': optional: true - '@rolldown/binding-freebsd-x64@1.0.0-rc.15': + '@rolldown/binding-freebsd-x64@1.2.0': optional: true '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.1': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15': + '@rolldown/binding-linux-arm-gnueabihf@1.2.0': optional: true '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.1': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15': + '@rolldown/binding-linux-arm64-gnu@1.2.0': optional: true '@rolldown/binding-linux-arm64-musl@1.0.0-beta.1': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.15': + '@rolldown/binding-linux-arm64-musl@1.2.0': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.15': + '@rolldown/binding-linux-ppc64-gnu@1.2.0': optional: true - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.15': + '@rolldown/binding-linux-s390x-gnu@1.2.0': optional: true '@rolldown/binding-linux-x64-gnu@1.0.0-beta.1': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.15': + '@rolldown/binding-linux-x64-gnu@1.2.0': optional: true '@rolldown/binding-linux-x64-musl@1.0.0-beta.1': optional: true - '@rolldown/binding-linux-x64-musl@1.0.0-rc.15': + '@rolldown/binding-linux-x64-musl@1.2.0': optional: true - '@rolldown/binding-openharmony-arm64@1.0.0-rc.15': + '@rolldown/binding-openharmony-arm64@1.2.0': optional: true '@rolldown/binding-wasm32-wasi@1.0.0-beta.1': @@ -4025,17 +3627,17 @@ snapshots: '@napi-rs/wasm-runtime': 0.2.12 optional: true - '@rolldown/binding-wasm32-wasi@1.0.0-rc.15': + '@rolldown/binding-wasm32-wasi@1.2.0': dependencies: - '@emnapi/core': 1.9.2 - '@emnapi/runtime': 1.9.2 - '@napi-rs/wasm-runtime': 1.1.3(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + '@emnapi/core': 1.11.2 + '@emnapi/runtime': 1.11.2 + '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2) optional: true '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.1': optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15': + '@rolldown/binding-win32-arm64-msvc@1.2.0': optional: true '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.1': @@ -4044,56 +3646,54 @@ snapshots: '@rolldown/binding-win32-x64-msvc@1.0.0-beta.1': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.15': + '@rolldown/binding-win32-x64-msvc@1.2.0': optional: true - '@rolldown/pluginutils@1.0.0-rc.15': {} + '@rolldown/pluginutils@1.0.1': {} '@rollup/plugin-esm-shim@0.1.8': dependencies: magic-string: 0.30.21 - mlly: 1.8.0 + mlly: 1.8.2 '@sindresorhus/is@4.6.0': {} - '@solid-primitives/props@3.2.2(solid-js@1.9.12)': + '@solid-primitives/props@3.2.4(solid-js@1.9.14)': dependencies: - '@solid-primitives/utils': 6.3.2(solid-js@1.9.12) - solid-js: 1.9.12 + '@solid-primitives/utils': 6.4.1(solid-js@1.9.14) + solid-js: 1.9.14 - '@solid-primitives/refs@1.1.2(solid-js@1.9.12)': + '@solid-primitives/refs@1.1.4(solid-js@1.9.14)': dependencies: - '@solid-primitives/utils': 6.3.2(solid-js@1.9.12) - solid-js: 1.9.12 + '@solid-primitives/utils': 6.4.1(solid-js@1.9.14) + solid-js: 1.9.14 - '@solid-primitives/transition-group@1.1.2(solid-js@1.9.12)': + '@solid-primitives/transition-group@1.1.2(solid-js@1.9.14)': dependencies: - solid-js: 1.9.12 + solid-js: 1.9.14 - '@solid-primitives/utils@6.3.2(solid-js@1.9.12)': + '@solid-primitives/utils@6.4.1(solid-js@1.9.14)': dependencies: - solid-js: 1.9.12 + solid-js: 1.9.14 '@szmarczak/http-timer@4.0.6': dependencies: defer-to-connect: 2.0.1 - '@tootallnate/once@2.0.0': {} - - '@tybys/wasm-util@0.10.1': + '@tybys/wasm-util@0.10.3': dependencies: tslib: 2.8.1 optional: true '@types/adm-zip@0.5.8': dependencies: - '@types/node': 22.19.15 + '@types/node': 26.1.1 '@types/cacheable-request@6.0.3': dependencies: '@types/http-cache-semantics': 4.2.0 '@types/keyv': 3.1.4 - '@types/node': 22.19.15 + '@types/node': 26.1.1 '@types/responselike': 1.0.3 '@types/debug@4.1.13': @@ -4102,18 +3702,18 @@ snapshots: '@types/fs-extra@8.1.5': dependencies: - '@types/node': 22.19.15 + '@types/node': 26.1.1 '@types/fs-extra@9.0.13': dependencies: - '@types/node': 22.19.15 + '@types/node': 26.1.1 - '@types/gensync@1.0.4': {} + '@types/gensync@1.0.5': {} '@types/glob@7.2.0': dependencies: '@types/minimatch': 6.0.0 - '@types/node': 22.19.15 + '@types/node': 26.1.1 '@types/http-cache-semantics@4.2.0': {} @@ -4121,57 +3721,106 @@ snapshots: '@types/keyv@3.1.4': dependencies: - '@types/node': 22.19.15 + '@types/node': 26.1.1 '@types/minimatch@6.0.0': dependencies: - minimatch: 10.1.1 + minimatch: 10.2.5 '@types/ms@2.1.0': {} - '@types/node@22.19.15': + '@types/node@24.13.3': dependencies: - undici-types: 6.21.0 + undici-types: 7.18.2 - '@types/node@24.12.0': + '@types/node@26.1.1': dependencies: - undici-types: 7.16.0 - - '@types/plist@3.0.5': - dependencies: - '@types/node': 22.19.15 - xmlbuilder: 15.1.1 - optional: true + undici-types: 8.3.0 '@types/responselike@1.0.3': dependencies: - '@types/node': 22.19.15 + '@types/node': 26.1.1 - '@types/verror@1.10.11': + '@types/trusted-types@2.0.7': optional: true '@types/ws@8.18.1': dependencies: - '@types/node': 22.19.15 + '@types/node': 26.1.1 - '@types/yauzl@2.10.3': - dependencies: - '@types/node': 22.19.15 + '@typescript/typescript-aix-ppc64@7.0.2': optional: true - '@uwu/lune@1.6.2': + '@typescript/typescript-darwin-arm64@7.0.2': + optional: true + + '@typescript/typescript-darwin-x64@7.0.2': + optional: true + + '@typescript/typescript-freebsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-freebsd-x64@7.0.2': + optional: true + + '@typescript/typescript-linux-arm64@7.0.2': + optional: true + + '@typescript/typescript-linux-arm@7.0.2': + optional: true + + '@typescript/typescript-linux-loong64@7.0.2': + optional: true + + '@typescript/typescript-linux-mips64el@7.0.2': + optional: true + + '@typescript/typescript-linux-ppc64@7.0.2': + optional: true + + '@typescript/typescript-linux-riscv64@7.0.2': + optional: true + + '@typescript/typescript-linux-s390x@7.0.2': + optional: true + + '@typescript/typescript-linux-x64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-sunos-x64@7.0.2': + optional: true + + '@typescript/typescript-win32-arm64@7.0.2': + optional: true + + '@typescript/typescript-win32-x64@7.0.2': + optional: true + + '@uwu/lune@1.6.3': dependencies: - '@babel/core': 7.28.6 - '@babel/preset-typescript': 7.28.5(@babel/core@7.28.6) + '@babel/core': 7.29.7 + '@babel/preset-typescript': 7.29.7(@babel/core@7.29.7) chokidar: 3.6.0 - date-fns: 4.1.0 + date-fns: 4.4.0 esbuild: 0.17.19 handlebars: 4.7.9 - lightningcss: 1.31.1 - resolve: 1.22.11 + lightningcss: 1.33.0 + resolve: 1.22.12 rolldown: 1.0.0-beta.1 - sass: 1.97.3 - ws: 8.20.0 + sass: 1.101.6 + ws: 8.21.1 transitivePeerDependencies: - '@babel/runtime' - bufferutil @@ -4184,52 +3833,44 @@ snapshots: solid-js: 1.6.16 spitroast: 2.1.4 - '@vencord/venmic@6.1.0': + '@uwu/shelter-ui@0.0.6(solid-js@1.9.14)': + dependencies: + solid-js: 1.9.14 + + '@vencord/venmic@7.1.0': dependencies: cmake-js: 7.4.0 - node-addon-api: 8.5.0 + node-addon-api: 8.9.0 pkg-prebuilds: 0.2.1 transitivePeerDependencies: - supports-color optional: true - '@xmldom/xmldom@0.8.11': {} + '@xmldom/xmldom@0.8.13': {} - abbrev@1.1.1: {} + '@xmldom/xmldom@0.9.10': {} - abbrev@3.0.1: {} + abbrev@4.0.0: {} - acorn@8.15.0: {} + acorn@8.17.0: {} - adm-zip@0.5.16: {} + adm-zip@0.6.0: {} agent-base@6.0.2: dependencies: debug: 4.4.3 transitivePeerDependencies: - supports-color + optional: true agent-base@7.1.4: {} - agentkeepalive@4.6.0: - dependencies: - humanize-ms: 1.2.1 - - aggregate-error@3.1.0: - dependencies: - clean-stack: 2.2.0 - indent-string: 4.0.0 - - ajv-keywords@3.5.2(ajv@6.12.6): - dependencies: - ajv: 6.12.6 - - ajv@6.12.6: + ajv@8.20.0: dependencies: fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 + fast-uri: 3.1.4 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 ansi-regex@5.0.1: {} @@ -4244,89 +3885,102 @@ snapshots: anymatch@3.1.3: dependencies: normalize-path: 3.0.0 - picomatch: 2.3.1 + picomatch: 2.3.2 - app-builder-bin@5.0.0-alpha.12: {} + anynum@1.0.1: {} - app-builder-lib@26.0.20(dmg-builder@26.0.20)(electron-builder-squirrel-windows@26.4.0): + app-builder-lib@26.15.3(dmg-builder@26.15.3)(electron-builder-squirrel-windows@26.15.3): dependencies: - '@develar/schema-utils': 2.6.5 '@electron/asar': 3.4.1 '@electron/fuses': 1.8.0 + '@electron/get': 3.1.0 '@electron/notarize': 2.5.0 '@electron/osx-sign': 1.3.3 - '@electron/rebuild': 3.7.2 + '@electron/rebuild': 4.2.0 '@electron/universal': 2.0.3 '@malept/flatpak-bundler': 0.4.0 + '@noble/hashes': 2.2.0 + '@peculiar/webcrypto': 1.7.1 '@types/fs-extra': 9.0.13 + ajv: 8.20.0 + asn1js: 3.0.10 async-exit-hook: 2.0.1 - builder-util: 26.0.20 - builder-util-runtime: 9.4.0 - chromium-pickle-js: 0.2.0 - ci-info: 4.4.0 - debug: 4.4.3 - dmg-builder: 26.0.20(electron-builder-squirrel-windows@26.4.0) - dotenv: 16.6.1 - dotenv-expand: 11.0.7 - ejs: 3.1.10 - electron-builder-squirrel-windows: 26.4.0(dmg-builder@26.0.20) - electron-publish: 26.0.20 - fs-extra: 10.1.0 - hosted-git-info: 4.1.0 - isbinaryfile: 5.0.7 - jiti: 2.6.1 - js-yaml: 4.1.1 - json5: 2.2.3 - lazy-val: 1.0.5 - minimatch: 10.2.4 - plist: 3.1.0 - resedit: 1.7.2 - semver: 7.7.4 - tar: 6.2.1 - temp-file: 3.4.0 - tiny-async-pool: 1.3.0 - which: 5.0.0 - transitivePeerDependencies: - - bluebird - - supports-color - - app-builder-lib@26.4.0(dmg-builder@26.0.20)(electron-builder-squirrel-windows@26.4.0): - dependencies: - '@develar/schema-utils': 2.6.5 - '@electron/asar': 3.4.1 - '@electron/fuses': 1.8.0 - '@electron/notarize': 2.5.0 - '@electron/osx-sign': 1.3.3 - '@electron/rebuild': 4.0.1 - '@electron/universal': 2.0.3 - '@malept/flatpak-bundler': 0.4.0 - '@types/fs-extra': 9.0.13 - async-exit-hook: 2.0.1 - builder-util: 26.3.4 - builder-util-runtime: 9.5.1 + builder-util: 26.15.3 + builder-util-runtime: 9.7.0 chromium-pickle-js: 0.2.0 ci-info: 4.3.1 debug: 4.4.3 - dmg-builder: 26.0.20(electron-builder-squirrel-windows@26.4.0) + dmg-builder: 26.15.3(electron-builder-squirrel-windows@26.15.3) dotenv: 16.6.1 dotenv-expand: 11.0.7 ejs: 3.1.10 - electron-builder-squirrel-windows: 26.4.0(dmg-builder@26.0.20) - electron-publish: 26.3.4 + electron-builder-squirrel-windows: 26.15.3(dmg-builder@26.15.3) + electron-publish: 26.15.3 fs-extra: 10.1.0 hosted-git-info: 4.1.0 isbinaryfile: 5.0.7 - jiti: 2.6.1 - js-yaml: 4.1.1 + jiti: 2.7.0 + js-yaml: 4.3.0 json5: 2.2.3 lazy-val: 1.0.5 - minimatch: 10.2.4 + minimatch: 10.2.5 + pkijs: 3.4.0 plist: 3.1.0 + proper-lockfile: 4.1.2 resedit: 1.7.2 semver: 7.7.4 - tar: 6.2.1 + tar: 7.5.21 temp-file: 3.4.0 tiny-async-pool: 1.3.0 + unzipper: 0.12.5 + which: 5.0.0 + transitivePeerDependencies: + - supports-color + + app-builder-lib@26.15.7(dmg-builder@26.15.7(electron-builder-squirrel-windows@26.15.3))(electron-builder-squirrel-windows@26.15.3): + dependencies: + '@electron/asar': 3.4.1 + '@electron/fuses': 1.8.0 + '@electron/get': 3.1.0 + '@electron/notarize': 2.5.0 + '@electron/osx-sign': 1.3.3 + '@electron/rebuild': 4.2.0 + '@electron/universal': 2.0.3 + '@malept/flatpak-bundler': 0.4.0 + '@noble/hashes': 2.2.0 + '@peculiar/webcrypto': 1.7.1 + '@types/fs-extra': 9.0.13 + ajv: 8.20.0 + asn1js: 3.0.10 + async-exit-hook: 2.0.1 + builder-util: 26.15.3 + builder-util-runtime: 9.7.0 + chromium-pickle-js: 0.2.0 + ci-info: 4.3.1 + debug: 4.4.3 + dmg-builder: 26.15.7(electron-builder-squirrel-windows@26.15.3) + dotenv: 16.6.1 + dotenv-expand: 11.0.7 + ejs: 3.1.10 + electron-builder-squirrel-windows: 26.15.3(dmg-builder@26.15.3) + electron-publish: 26.15.3 + fs-extra: 10.1.0 + hosted-git-info: 4.1.0 + isbinaryfile: 5.0.7 + jiti: 2.7.0 + js-yaml: 4.3.0 + json5: 2.2.3 + lazy-val: 1.0.5 + minimatch: 10.2.5 + pkijs: 3.4.0 + plist: 3.1.0 + proper-lockfile: 4.1.2 + resedit: 1.7.2 + semver: 7.7.4 + tar: 7.5.21 + temp-file: 3.4.0 + tiny-async-pool: 1.3.0 + unzipper: 0.12.5 which: 5.0.0 transitivePeerDependencies: - supports-color @@ -4346,17 +4000,17 @@ snapshots: arrpc@https://codeload.github.com/Legcord/arrpc/tar.gz/efe7589762470d32b9ba10d529be5acc23cd0e19: dependencies: - koffi: 2.15.6 - ws: 8.20.0 + koffi: 2.16.3 + ws: 8.21.1 transitivePeerDependencies: - bufferutil - utf-8-validate - assert-plus@1.0.0: - optional: true - - astral-regex@2.0.0: - optional: true + asn1js@3.0.10: + dependencies: + pvtsutils: 1.3.6 + pvutils: 1.1.5 + tslib: 2.8.1 async-exit-hook@2.0.1: {} @@ -4366,30 +4020,34 @@ snapshots: at-least-node@1.0.0: {} - axios@1.13.4(debug@4.4.3): + aws4@1.13.2: {} + + axios@1.18.1(debug@4.4.3): dependencies: - follow-redirects: 1.15.11(debug@4.4.3) - form-data: 4.0.5 - proxy-from-env: 1.1.0 + follow-redirects: 1.16.0(debug@4.4.3) + form-data: 4.0.6 + https-proxy-agent: 5.0.1 + proxy-from-env: 2.1.0 transitivePeerDependencies: - debug + - supports-color optional: true - babel-plugin-jsx-dom-expressions@0.40.6(@babel/core@7.28.6): + babel-plugin-jsx-dom-expressions@0.40.7(@babel/core@8.0.1): dependencies: - '@babel/core': 7.28.6 + '@babel/core': 8.0.1 '@babel/helper-module-imports': 7.18.6 - '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.28.6) - '@babel/types': 7.29.0 + '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@8.0.1) + '@babel/types': 7.29.7 html-entities: 2.3.3 parse5: 7.3.0 - babel-preset-solid@1.9.12(@babel/core@7.28.6)(solid-js@1.9.12): + babel-preset-solid@1.9.12(@babel/core@8.0.1)(solid-js@1.9.14): dependencies: - '@babel/core': 7.28.6 - babel-plugin-jsx-dom-expressions: 0.40.6(@babel/core@7.28.6) + '@babel/core': 8.0.1 + babel-plugin-jsx-dom-expressions: 0.40.7(@babel/core@8.0.1) optionalDependencies: - solid-js: 1.9.12 + solid-js: 1.9.14 balanced-match@1.0.2: {} @@ -4397,29 +4055,27 @@ snapshots: base64-js@1.5.1: {} - baseline-browser-mapping@2.9.19: {} + baseline-browser-mapping@2.10.32: {} + + baseline-browser-mapping@2.11.1: {} binary-extensions@2.3.0: {} - bl@4.1.0: - dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.2 + bluebird@3.7.2: {} boolean@3.2.0: optional: true - brace-expansion@1.1.12: + brace-expansion@1.1.16: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - brace-expansion@2.0.3: + brace-expansion@2.1.2: dependencies: balanced-match: 1.0.2 - brace-expansion@5.0.5: + brace-expansion@5.0.8: dependencies: balanced-match: 4.0.4 @@ -4427,51 +4083,42 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.28.1: + browserslist@4.28.2: dependencies: - baseline-browser-mapping: 2.9.19 - caniuse-lite: 1.0.30001766 - electron-to-chromium: 1.5.282 - node-releases: 2.0.27 - update-browserslist-db: 1.2.3(browserslist@4.28.1) + baseline-browser-mapping: 2.10.32 + caniuse-lite: 1.0.30001793 + electron-to-chromium: 1.5.363 + node-releases: 2.0.46 + update-browserslist-db: 1.2.3(browserslist@4.28.2) - buffer-crc32@0.2.13: {} + browserslist@4.28.7: + dependencies: + baseline-browser-mapping: 2.11.1 + caniuse-lite: 1.0.30001806 + electron-to-chromium: 1.5.395 + node-releases: 2.0.51 + update-browserslist-db: 1.2.3(browserslist@4.28.7) buffer-from@1.1.2: {} - buffer@5.7.1: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - - builder-util-runtime@9.4.0: + builder-util-runtime@9.7.0: dependencies: debug: 4.4.3 - sax: 1.4.4 + sax: 1.6.0 transitivePeerDependencies: - supports-color - builder-util-runtime@9.5.1: + builder-util@26.15.3: dependencies: - debug: 4.4.3 - sax: 1.4.4 - transitivePeerDependencies: - - supports-color - - builder-util@26.0.20: - dependencies: - 7zip-bin: 5.2.0 '@types/debug': 4.1.13 - app-builder-bin: 5.0.0-alpha.12 - builder-util-runtime: 9.4.0 + builder-util-runtime: 9.7.0 chalk: 4.1.2 - ci-info: 4.4.0 cross-spawn: 7.0.6 debug: 4.4.3 fs-extra: 10.1.0 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 - js-yaml: 4.1.1 + js-yaml: 4.3.0 sanitize-filename: 1.6.4 source-map-support: 0.5.21 stat-mode: 1.0.0 @@ -4480,64 +4127,7 @@ snapshots: transitivePeerDependencies: - supports-color - builder-util@26.3.4: - dependencies: - 7zip-bin: 5.2.0 - '@types/debug': 4.1.13 - app-builder-bin: 5.0.0-alpha.12 - builder-util-runtime: 9.5.1 - chalk: 4.1.2 - cross-spawn: 7.0.6 - debug: 4.4.3 - fs-extra: 10.1.0 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 - js-yaml: 4.1.1 - sanitize-filename: 1.6.4 - source-map-support: 0.5.21 - stat-mode: 1.0.0 - temp-file: 3.4.0 - tiny-async-pool: 1.3.0 - transitivePeerDependencies: - - supports-color - - cacache@16.1.3: - dependencies: - '@npmcli/fs': 2.1.2 - '@npmcli/move-file': 2.0.1 - chownr: 2.0.0 - fs-minipass: 2.1.0 - glob: 8.1.0 - infer-owner: 1.0.4 - lru-cache: 7.18.3 - minipass: 3.3.6 - minipass-collect: 1.0.2 - minipass-flush: 1.0.7 - 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.1 - tar: 6.2.1 - unique-filename: 2.0.1 - transitivePeerDependencies: - - bluebird - - cacache@19.0.1: - dependencies: - '@npmcli/fs': 4.0.0 - fs-minipass: 3.0.3 - glob: 10.5.0 - lru-cache: 10.4.3 - minipass: 7.1.3 - minipass-collect: 2.0.1 - minipass-flush: 1.0.7 - minipass-pipeline: 1.2.4 - p-map: 7.0.4 - ssri: 12.0.0 - tar: 7.5.13 - unique-filename: 4.0.0 + bytestreamjs@2.0.1: {} cacheable-lookup@5.0.4: {} @@ -4556,7 +4146,9 @@ snapshots: es-errors: 1.3.0 function-bind: 1.1.2 - caniuse-lite@1.0.30001766: {} + caniuse-lite@1.0.30001793: {} + + caniuse-lite@1.0.30001806: {} chalk@4.1.2: dependencies: @@ -4575,11 +4167,12 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - chokidar@4.0.3: + chokidar@5.0.0: dependencies: - readdirp: 4.1.2 + readdirp: 5.0.0 - chownr@2.0.0: {} + chownr@2.0.0: + optional: true chownr@3.0.0: {} @@ -4589,20 +4182,6 @@ snapshots: ci-info@4.4.0: {} - clean-stack@2.2.0: {} - - cli-cursor@3.1.0: - dependencies: - restore-cursor: 3.1.0 - - cli-spinners@2.9.2: {} - - cli-truncate@2.1.0: - dependencies: - slice-ansi: 3.0.0 - string-width: 4.2.3 - optional: true - cli-truncate@4.0.0: dependencies: slice-ansi: 5.0.0 @@ -4618,22 +4197,20 @@ snapshots: dependencies: mimic-response: 1.0.1 - clone@1.0.4: {} - cmake-js@7.4.0: dependencies: - axios: 1.13.4(debug@4.4.3) + axios: 1.18.1(debug@4.4.3) debug: 4.4.3 - fs-extra: 11.3.4 + fs-extra: 11.3.6 memory-stream: 1.0.0 - node-api-headers: 1.8.0 + node-api-headers: 1.9.0 npmlog: 6.0.2 rc: 1.2.8 - semver: 7.7.3 + semver: 7.8.5 tar: 6.2.1 url-join: 4.0.1 which: 2.0.2 - yargs: 17.7.2 + yargs: 17.7.3 transitivePeerDependencies: - supports-color optional: true @@ -4669,13 +4246,7 @@ snapshots: convert-source-map@2.0.0: {} - core-util-is@1.0.2: - optional: true - - crc@3.8.0: - dependencies: - buffer: 5.7.1 - optional: true + core-util-is@1.0.3: {} cross-dirname@0.1.0: optional: true @@ -4688,7 +4259,7 @@ snapshots: csstype@3.2.3: {} - date-fns@4.1.0: {} + date-fns@4.4.0: {} debug@4.4.3: dependencies: @@ -4701,10 +4272,6 @@ snapshots: deep-extend@0.6.0: optional: true - defaults@1.0.4: - dependencies: - clone: 1.0.4 - defer-to-connect@2.0.1: {} define-data-property@1.1.4: @@ -4733,38 +4300,36 @@ snapshots: dir-compare@4.2.0: dependencies: - minimatch: 3.1.2 + minimatch: 3.1.5 p-limit: 3.1.0 dir-glob@3.0.1: dependencies: path-type: 4.0.0 - dmg-builder@26.0.20(electron-builder-squirrel-windows@26.4.0): + dmg-builder@26.15.3(electron-builder-squirrel-windows@26.15.3): dependencies: - app-builder-lib: 26.0.20(dmg-builder@26.0.20)(electron-builder-squirrel-windows@26.4.0) - builder-util: 26.0.20 + app-builder-lib: 26.15.3(dmg-builder@26.15.3)(electron-builder-squirrel-windows@26.15.3) + builder-util: 26.15.3 fs-extra: 10.1.0 - iconv-lite: 0.6.3 js-yaml: 4.1.1 - optionalDependencies: - dmg-license: 1.0.11 transitivePeerDependencies: - - bluebird - electron-builder-squirrel-windows - supports-color - dmg-license@1.0.11: + dmg-builder@26.15.7(electron-builder-squirrel-windows@26.15.3): dependencies: - '@types/plist': 3.0.5 - '@types/verror': 1.10.11 - ajv: 6.12.6 - crc: 3.8.0 - iconv-corefoundation: 1.1.7 - plist: 3.1.0 - smart-buffer: 4.2.0 - verror: 1.10.1 - optional: true + app-builder-lib: 26.15.7(dmg-builder@26.15.7(electron-builder-squirrel-windows@26.15.3))(electron-builder-squirrel-windows@26.15.3) + builder-util: 26.15.3 + fs-extra: 10.1.0 + js-yaml: 4.3.0 + transitivePeerDependencies: + - electron-builder-squirrel-windows + - supports-color + + dompurify@3.4.8: + optionalDependencies: + '@types/trusted-types': 2.0.7 dotenv-expand@11.0.7: dependencies: @@ -4778,35 +4343,36 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 - eastasianwidth@0.2.0: {} + duplexer2@0.1.4: + dependencies: + readable-stream: 2.3.8 ejs@3.1.10: dependencies: jake: 10.9.4 - electron-builder-squirrel-windows@26.4.0(dmg-builder@26.0.20): + electron-builder-squirrel-windows@26.15.3(dmg-builder@26.15.3): dependencies: - app-builder-lib: 26.4.0(dmg-builder@26.0.20)(electron-builder-squirrel-windows@26.4.0) - builder-util: 26.3.4 + app-builder-lib: 26.15.3(dmg-builder@26.15.3)(electron-builder-squirrel-windows@26.15.3) + builder-util: 26.15.3 electron-winstaller: 5.4.0 transitivePeerDependencies: - dmg-builder - supports-color - electron-builder@26.0.20(electron-builder-squirrel-windows@26.4.0): + electron-builder@26.15.7(electron-builder-squirrel-windows@26.15.3): dependencies: - app-builder-lib: 26.0.20(dmg-builder@26.0.20)(electron-builder-squirrel-windows@26.4.0) - builder-util: 26.0.20 - builder-util-runtime: 9.4.0 + app-builder-lib: 26.15.7(dmg-builder@26.15.7(electron-builder-squirrel-windows@26.15.3))(electron-builder-squirrel-windows@26.15.3) + builder-util: 26.15.3 + builder-util-runtime: 9.7.0 chalk: 4.1.2 ci-info: 4.4.0 - dmg-builder: 26.0.20(electron-builder-squirrel-windows@26.4.0) + dmg-builder: 26.15.7(electron-builder-squirrel-windows@26.15.3) fs-extra: 10.1.0 lazy-val: 1.0.5 simple-update-notifier: 2.0.0 - yargs: 17.7.2 + yargs: 17.7.3 transitivePeerDependencies: - - bluebird - electron-builder-squirrel-windows - supports-color @@ -4824,43 +4390,33 @@ snapshots: electron-is-dev@3.0.1: {} - electron-publish@26.0.20: + electron-publish@26.15.3: dependencies: '@types/fs-extra': 9.0.13 - builder-util: 26.0.20 - builder-util-runtime: 9.4.0 + aws4: 1.13.2 + builder-util: 26.15.3 + builder-util-runtime: 9.7.0 chalk: 4.1.2 - form-data: 4.0.5 + form-data: 4.0.6 fs-extra: 10.1.0 lazy-val: 1.0.5 mime: 2.6.0 transitivePeerDependencies: - supports-color - electron-publish@26.3.4: - dependencies: - '@types/fs-extra': 9.0.13 - builder-util: 26.3.4 - builder-util-runtime: 9.5.1 - chalk: 4.1.2 - form-data: 4.0.5 - fs-extra: 10.1.0 - lazy-val: 1.0.5 - mime: 2.6.0 - transitivePeerDependencies: - - supports-color + electron-to-chromium@1.5.363: {} - electron-to-chromium@1.5.282: {} + electron-to-chromium@1.5.395: {} - electron-updater@6.8.3: + electron-updater@6.8.9: dependencies: - builder-util-runtime: 9.5.1 + builder-util-runtime: 9.7.0 fs-extra: 10.1.0 - js-yaml: 4.1.1 + js-yaml: 4.3.0 lazy-val: 1.0.5 lodash.escaperegexp: 4.1.2 lodash.isequal: 4.5.0 - semver: 7.7.3 + semver: 7.7.4 tiny-typed-emitter: 2.1.0 transitivePeerDependencies: - supports-color @@ -4870,18 +4426,18 @@ snapshots: '@electron/asar': 3.4.1 debug: 4.4.3 fs-extra: 7.0.1 - lodash: 4.17.23 + lodash: 4.18.1 temp: 0.9.4 optionalDependencies: '@electron/windows-sign': 1.2.2 transitivePeerDependencies: - supports-color - electron@41.2.0: + electron@43.2.0: dependencies: - '@electron/get': 2.0.3 - '@types/node': 24.12.0 - extract-zip: 2.0.1 + '@electron-internal/extract-zip': 1.0.4 + '@electron/get': 5.0.0 + '@types/node': 24.13.3 transitivePeerDependencies: - supports-color @@ -4889,12 +4445,7 @@ snapshots: emoji-regex@8.0.0: {} - emoji-regex@9.2.2: {} - - encoding@0.1.13: - dependencies: - iconv-lite: 0.6.3 - optional: true + empathic@2.0.1: {} end-of-stream@1.4.5: dependencies: @@ -4902,15 +4453,19 @@ snapshots: entities@6.0.1: {} + entities@8.0.0: {} + env-paths@2.2.1: {} + env-paths@3.0.0: {} + err-code@2.0.3: {} es-define-property@1.0.1: {} es-errors@1.3.0: {} - es-object-atoms@1.1.1: + es-object-atoms@1.1.2: dependencies: es-errors: 1.3.0 @@ -4919,7 +4474,7 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 has-tostringtag: 1.0.2 - hasown: 2.0.2 + hasown: 2.0.4 es6-error@4.1.1: optional: true @@ -4949,35 +4504,6 @@ snapshots: '@esbuild/win32-ia32': 0.17.19 '@esbuild/win32-x64': 0.17.19 - 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 - escalade@3.2.0: {} escape-goat@4.0.0: {} @@ -4998,19 +4524,6 @@ snapshots: ext-list: 2.2.2 sort-keys-length: 1.0.1 - extract-zip@2.0.1: - dependencies: - debug: 4.4.3 - get-stream: 5.2.0 - yauzl: 2.10.0 - optionalDependencies: - '@types/yauzl': 2.10.3 - transitivePeerDependencies: - - supports-color - - extsprintf@1.4.1: - optional: true - fast-deep-equal@3.1.3: {} fast-glob@3.3.3: @@ -5021,21 +4534,31 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.8 - fast-json-stable-stringify@2.1.0: {} + fast-uri@3.1.4: {} + + fast-xml-builder@1.3.0: + dependencies: + path-expression-matcher: 1.6.2 + xml-naming: 0.3.0 + + fast-xml-parser@5.10.1: + dependencies: + '@nodable/entities': 3.0.0 + fast-xml-builder: 1.3.0 + is-unsafe: 2.0.0 + path-expression-matcher: 1.6.2 + strnum: 2.4.1 + xml-naming: 0.3.0 fastq@1.20.1: dependencies: reusify: 1.1.0 - fd-slicer@1.1.0: - dependencies: - pend: 1.2.0 - - fdir@6.5.0(picomatch@4.0.4): + fdir@6.5.0(picomatch@4.0.5): optionalDependencies: - picomatch: 4.0.4 + picomatch: 4.0.5 - filelist@1.0.4: + filelist@1.0.6: dependencies: minimatch: 5.1.9 @@ -5043,34 +4566,35 @@ snapshots: dependencies: to-regex-range: 5.0.1 - follow-redirects@1.15.11(debug@4.4.3): + follow-redirects@1.16.0(debug@4.4.3): optionalDependencies: debug: 4.4.3 optional: true - foreground-child@3.3.1: - dependencies: - cross-spawn: 7.0.6 - signal-exit: 4.1.0 - - form-data@4.0.5: + form-data@4.0.6: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 es-set-tostringtag: 2.1.0 - hasown: 2.0.2 + hasown: 2.0.4 mime-types: 2.1.35 fs-extra@10.1.0: dependencies: graceful-fs: 4.2.11 - jsonfile: 6.2.0 + jsonfile: 6.2.1 universalify: 2.0.1 - fs-extra@11.3.4: + fs-extra@11.3.1: dependencies: graceful-fs: 4.2.11 - jsonfile: 6.2.0 + jsonfile: 6.2.1 + universalify: 2.0.1 + + fs-extra@11.3.6: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.1 universalify: 2.0.1 fs-extra@7.0.1: @@ -5089,16 +4613,13 @@ snapshots: dependencies: at-least-node: 1.0.0 graceful-fs: 4.2.11 - jsonfile: 6.2.0 + jsonfile: 6.2.1 universalify: 2.0.1 fs-minipass@2.1.0: dependencies: minipass: 3.3.6 - - fs-minipass@3.0.3: - dependencies: - minipass: 7.1.3 + optional: true fs.realpath@1.0.0: {} @@ -5123,71 +4644,50 @@ snapshots: get-caller-file@2.0.5: {} - get-east-asian-width@1.4.0: {} + get-east-asian-width@1.6.0: {} 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 + es-object-atoms: 1.1.2 function-bind: 1.1.2 get-proto: 1.0.1 gopd: 1.2.0 has-symbols: 1.1.0 - hasown: 2.0.2 + hasown: 2.0.4 math-intrinsics: 1.1.0 get-proto@1.0.1: dependencies: dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 + es-object-atoms: 1.1.2 get-stream@5.2.0: dependencies: - pump: 3.0.3 - - get-tsconfig@4.13.0: - dependencies: - resolve-pkg-maps: 1.0.0 + pump: 3.0.4 glob-parent@5.1.2: dependencies: is-glob: 4.0.3 - glob@10.5.0: - dependencies: - foreground-child: 3.3.1 - jackspeak: 3.4.3 - minimatch: 9.0.9 - minipass: 7.1.3 - package-json-from-dist: 1.0.1 - path-scurry: 1.11.1 - glob@7.2.3: dependencies: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 3.1.2 + minimatch: 3.1.5 once: 1.4.0 path-is-absolute: 1.0.1 - glob@8.1.0: - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 5.1.9 - once: 1.4.0 - global-agent@3.0.0: dependencies: boolean: 3.2.0 es6-error: 4.1.1 matcher: 3.0.0 roarr: 2.15.4 - semver: 7.7.4 + semver: 7.8.5 serialize-error: 7.0.1 optional: true @@ -5251,7 +4751,7 @@ snapshots: has-unicode@2.0.1: optional: true - hasown@2.0.2: + hasown@2.0.4: dependencies: function-bind: 1.1.2 @@ -5267,14 +4767,6 @@ snapshots: http-cache-semantics@4.2.0: {} - http-proxy-agent@5.0.0: - dependencies: - '@tootallnate/once': 2.0.0 - agent-base: 6.0.2 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.4 @@ -5293,6 +4785,7 @@ snapshots: debug: 4.4.3 transitivePeerDependencies: - supports-color + optional: true https-proxy-agent@7.0.6: dependencies: @@ -5301,36 +4794,14 @@ snapshots: transitivePeerDependencies: - supports-color - humanize-ms@1.2.1: - dependencies: - ms: 2.1.3 - - iconv-corefoundation@1.1.7: - dependencies: - cli-truncate: 2.1.0 - node-addon-api: 1.7.2 - optional: true - - iconv-lite@0.6.3: - dependencies: - safer-buffer: 2.1.2 - idb@7.1.1: {} - ieee754@1.2.1: {} - ignore@5.3.2: {} - immutable@5.1.4: {} + immutable@5.1.9: {} import-meta-resolve@4.2.0: {} - imurmurhash@0.1.4: {} - - indent-string@4.0.0: {} - - infer-owner@1.0.4: {} - inflight@1.0.6: dependencies: once: 1.4.0 @@ -5341,15 +4812,13 @@ snapshots: ini@1.3.8: optional: true - ip-address@10.1.0: {} - is-binary-path@2.1.0: dependencies: binary-extensions: 2.3.0 - is-core-module@2.16.1: + is-core-module@2.16.2: dependencies: - hasown: 2.0.2 + hasown: 2.0.4 is-extglob@2.1.1: {} @@ -5361,17 +4830,15 @@ snapshots: dependencies: is-extglob: 2.1.1 - is-interactive@1.0.0: {} - - is-lambda@1.0.1: {} - is-number@7.0.0: {} is-plain-obj@1.1.0: {} is-plain-object@3.0.1: {} - is-unicode-supported@0.1.0: {} + is-unsafe@2.0.0: {} + + isarray@1.0.0: {} isbinaryfile@4.0.10: {} @@ -5379,21 +4846,17 @@ snapshots: isexe@2.0.0: {} - isexe@3.1.1: {} + isexe@3.1.5: {} - jackspeak@3.4.3: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 + isexe@4.0.0: {} jake@10.9.4: dependencies: async: 3.2.6 - filelist: 1.0.4 + filelist: 1.0.6 picocolors: 1.1.1 - jiti@2.6.1: {} + jiti@2.7.0: {} js-tokens@10.0.0: {} @@ -5403,11 +4866,15 @@ snapshots: dependencies: argparse: 2.0.1 + js-yaml@4.3.0: + dependencies: + argparse: 2.0.1 + jsesc@3.1.0: {} json-buffer@3.0.1: {} - json-schema-traverse@0.4.1: {} + json-schema-traverse@1.0.0: {} json-stringify-safe@5.0.1: optional: true @@ -5418,7 +4885,7 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 - jsonfile@6.2.0: + jsonfile@6.2.1: dependencies: universalify: 2.0.1 optionalDependencies: @@ -5428,73 +4895,68 @@ snapshots: dependencies: json-buffer: 3.0.1 - koffi@2.15.6: {} + koffi@2.16.3: {} lazy-val@1.0.5: {} - lightningcss-android-arm64@1.31.1: + lightningcss-android-arm64@1.33.0: optional: true - lightningcss-darwin-arm64@1.31.1: + lightningcss-darwin-arm64@1.33.0: optional: true - lightningcss-darwin-x64@1.31.1: + lightningcss-darwin-x64@1.33.0: optional: true - lightningcss-freebsd-x64@1.31.1: + lightningcss-freebsd-x64@1.33.0: optional: true - lightningcss-linux-arm-gnueabihf@1.31.1: + lightningcss-linux-arm-gnueabihf@1.33.0: optional: true - lightningcss-linux-arm64-gnu@1.31.1: + lightningcss-linux-arm64-gnu@1.33.0: optional: true - lightningcss-linux-arm64-musl@1.31.1: + lightningcss-linux-arm64-musl@1.33.0: optional: true - lightningcss-linux-x64-gnu@1.31.1: + lightningcss-linux-x64-gnu@1.33.0: optional: true - lightningcss-linux-x64-musl@1.31.1: + lightningcss-linux-x64-musl@1.33.0: optional: true - lightningcss-win32-arm64-msvc@1.31.1: + lightningcss-win32-arm64-msvc@1.33.0: optional: true - lightningcss-win32-x64-msvc@1.31.1: + lightningcss-win32-x64-msvc@1.33.0: optional: true - lightningcss@1.31.1: + lightningcss@1.33.0: dependencies: detect-libc: 2.1.2 optionalDependencies: - lightningcss-android-arm64: 1.31.1 - lightningcss-darwin-arm64: 1.31.1 - lightningcss-darwin-x64: 1.31.1 - lightningcss-freebsd-x64: 1.31.1 - lightningcss-linux-arm-gnueabihf: 1.31.1 - lightningcss-linux-arm64-gnu: 1.31.1 - lightningcss-linux-arm64-musl: 1.31.1 - lightningcss-linux-x64-gnu: 1.31.1 - lightningcss-linux-x64-musl: 1.31.1 - lightningcss-win32-arm64-msvc: 1.31.1 - lightningcss-win32-x64-msvc: 1.31.1 + lightningcss-android-arm64: 1.33.0 + lightningcss-darwin-arm64: 1.33.0 + lightningcss-darwin-x64: 1.33.0 + lightningcss-freebsd-x64: 1.33.0 + lightningcss-linux-arm-gnueabihf: 1.33.0 + lightningcss-linux-arm64-gnu: 1.33.0 + lightningcss-linux-arm64-musl: 1.33.0 + lightningcss-linux-x64-gnu: 1.33.0 + lightningcss-linux-x64-musl: 1.33.0 + lightningcss-win32-arm64-msvc: 1.33.0 + lightningcss-win32-x64-msvc: 1.33.0 lodash.escaperegexp@4.1.2: {} lodash.isequal@4.5.0: {} - lodash@4.17.23: {} - - log-symbols@4.1.0: - dependencies: - chalk: 4.1.2 - is-unicode-supported: 0.1.0 + lodash@4.18.1: {} lowercase-keys@2.0.0: {} - lru-cache@10.4.3: {} + lru-cache@11.5.2: {} lru-cache@5.1.1: dependencies: @@ -5504,53 +4966,15 @@ snapshots: dependencies: yallist: 4.0.0 - lru-cache@7.18.3: {} - - lucide-solid@0.475.0(solid-js@1.9.12): + lucide-solid@1.26.0(solid-js@1.9.14): dependencies: - solid-js: 1.9.12 + solid-js: 1.9.14 magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - make-fetch-happen@10.2.1: - dependencies: - agentkeepalive: 4.6.0 - cacache: 16.1.3 - http-cache-semantics: 4.2.0 - http-proxy-agent: 5.0.0 - https-proxy-agent: 5.0.1 - is-lambda: 1.0.1 - lru-cache: 7.18.3 - minipass: 3.3.6 - minipass-collect: 1.0.2 - minipass-fetch: 2.1.2 - minipass-flush: 1.0.7 - minipass-pipeline: 1.2.4 - negotiator: 0.6.4 - promise-retry: 2.0.1 - socks-proxy-agent: 7.0.0 - ssri: 9.0.1 - transitivePeerDependencies: - - bluebird - - supports-color - - make-fetch-happen@14.0.3: - dependencies: - '@npmcli/agent': 3.0.0 - cacache: 19.0.1 - http-cache-semantics: 4.2.0 - minipass: 7.1.3 - minipass-fetch: 4.0.1 - minipass-flush: 1.0.7 - minipass-pipeline: 1.2.4 - negotiator: 1.0.0 - proc-log: 5.0.0 - promise-retry: 2.0.1 - ssri: 12.0.0 - transitivePeerDependencies: - - supports-color + marked@14.0.0: {} matcher@3.0.0: dependencies: @@ -5569,7 +4993,7 @@ snapshots: micromatch@4.0.8: dependencies: braces: 3.0.3 - picomatch: 2.3.1 + picomatch: 2.3.2 mime-db@1.52.0: {} @@ -5581,75 +5005,35 @@ snapshots: mime@2.6.0: {} - mimic-fn@2.1.0: {} - mimic-response@1.0.1: {} mimic-response@3.1.0: {} - minimatch@10.1.1: + minimatch@10.2.5: dependencies: - '@isaacs/brace-expansion': 5.0.0 + brace-expansion: 5.0.8 - minimatch@10.2.4: + minimatch@3.1.5: dependencies: - brace-expansion: 5.0.5 - - minimatch@3.1.2: - dependencies: - brace-expansion: 1.1.12 + brace-expansion: 1.1.16 minimatch@5.1.9: dependencies: - brace-expansion: 2.0.3 + brace-expansion: 2.1.2 minimatch@9.0.9: dependencies: - brace-expansion: 2.0.3 + brace-expansion: 2.1.2 minimist@1.2.8: {} - minipass-collect@1.0.2: - dependencies: - minipass: 3.3.6 - - minipass-collect@2.0.1: - dependencies: - minipass: 7.1.3 - - minipass-fetch@2.1.2: - dependencies: - minipass: 3.3.6 - minipass-sized: 1.0.3 - minizlib: 2.1.2 - optionalDependencies: - encoding: 0.1.13 - - minipass-fetch@4.0.1: - dependencies: - minipass: 7.1.3 - minipass-sized: 1.0.3 - minizlib: 3.1.0 - optionalDependencies: - encoding: 0.1.13 - - minipass-flush@1.0.7: - dependencies: - minipass: 3.3.6 - - minipass-pipeline@1.2.4: - dependencies: - minipass: 3.3.6 - - minipass-sized@1.0.3: - dependencies: - minipass: 3.3.6 - minipass@3.3.6: dependencies: yallist: 4.0.0 + optional: true - minipass@5.0.0: {} + minipass@5.0.0: + optional: true minipass@7.1.3: {} @@ -5657,6 +5041,7 @@ snapshots: dependencies: minipass: 3.3.6 yallist: 4.0.0 + optional: true minizlib@3.1.0: dependencies: @@ -5666,71 +5051,64 @@ snapshots: dependencies: minimist: 1.2.8 - mkdirp@1.0.4: {} + mkdirp@1.0.4: + optional: true - mlly@1.8.0: + mlly@1.8.2: dependencies: - acorn: 8.15.0 + acorn: 8.17.0 pathe: 2.0.3 pkg-types: 1.3.1 - ufo: 1.6.3 + ufo: 1.6.4 + + monaco-editor@0.56.0: + dependencies: + dompurify: 3.4.8 + marked: 14.0.0 ms@2.1.3: {} - negotiator@0.6.4: {} - - negotiator@1.0.0: {} - neo-async@2.6.2: {} - node-abi@3.89.0: + node-abi@4.33.0: dependencies: - semver: 7.7.4 - - node-abi@4.28.0: - dependencies: - semver: 7.7.4 - - node-addon-api@1.7.2: - optional: true + semver: 7.8.5 node-addon-api@7.1.1: optional: true - node-addon-api@8.5.0: + node-addon-api@8.9.0: optional: true - node-api-headers@1.8.0: + node-api-headers@1.9.0: optional: true node-api-version@0.2.1: dependencies: - semver: 7.7.4 + semver: 7.8.5 - node-gyp@11.5.0: + node-gyp@12.4.0: dependencies: env-paths: 2.2.1 exponential-backoff: 3.1.3 graceful-fs: 4.2.11 - make-fetch-happen: 14.0.3 - nopt: 8.1.0 - proc-log: 5.0.0 - semver: 7.7.4 - tar: 7.5.13 - tinyglobby: 0.2.15 - which: 5.0.0 - transitivePeerDependencies: - - supports-color + nopt: 9.0.0 + proc-log: 6.1.0 + semver: 7.8.5 + tar: 7.5.21 + tinyglobby: 0.2.17 + undici: 6.27.0 + which: 6.0.1 - node-releases@2.0.27: {} + node-int64@0.4.0: {} - nopt@6.0.0: + node-releases@2.0.46: {} + + node-releases@2.0.51: {} + + nopt@9.0.0: dependencies: - abbrev: 1.1.1 - - nopt@8.1.0: - dependencies: - abbrev: 3.0.1 + abbrev: 4.0.0 normalize-path@3.0.0: {} @@ -5753,88 +5131,71 @@ snapshots: dependencies: wrappy: 1.0.2 - onetime@5.1.2: - dependencies: - mimic-fn: 2.1.0 - - ora@5.4.1: - dependencies: - bl: 4.1.0 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-spinners: 2.9.2 - is-interactive: 1.0.0 - is-unicode-supported: 0.1.0 - log-symbols: 4.1.0 - strip-ansi: 6.0.1 - wcwidth: 1.0.1 - p-cancelable@2.1.1: {} p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 - p-map@4.0.0: - dependencies: - aggregate-error: 3.1.0 - - p-map@7.0.4: {} - - package-json-from-dist@1.0.1: {} - parse5@7.3.0: dependencies: entities: 6.0.1 - parse5@8.0.0: + parse5@8.0.1: dependencies: - entities: 6.0.1 + entities: 8.0.0 path-exists@5.0.0: {} + path-expression-matcher@1.6.2: {} + path-is-absolute@1.0.1: {} path-key@3.1.1: {} path-parse@1.0.7: {} - path-scurry@1.11.1: - dependencies: - lru-cache: 10.4.3 - minipass: 7.1.3 - path-type@4.0.0: {} pathe@2.0.3: {} pe-library@0.4.1: {} - pend@1.2.0: {} - picocolors@1.1.1: {} - picomatch@2.3.1: {} + picomatch@2.3.2: {} - picomatch@4.0.3: - optional: true - - picomatch@4.0.4: {} + picomatch@4.0.5: {} pkg-prebuilds@0.2.1: dependencies: - yargs: 17.7.2 + yargs: 17.7.3 optional: true pkg-types@1.3.1: dependencies: confbox: 0.1.8 - mlly: 1.8.0 + mlly: 1.8.2 pathe: 2.0.3 + pkijs@3.4.0: + dependencies: + '@noble/hashes': 1.4.0 + asn1js: 3.0.10 + bytestreamjs: 2.0.1 + pvtsutils: 1.3.6 + pvutils: 1.1.5 + tslib: 2.8.1 + plist@3.1.0: dependencies: - '@xmldom/xmldom': 0.8.11 + '@xmldom/xmldom': 0.8.13 + base64-js: 1.5.1 + xmlbuilder: 15.1.1 + + plist@3.1.1: + dependencies: + '@xmldom/xmldom': 0.9.10 base64-js: 1.5.1 xmlbuilder: 15.1.1 @@ -5843,33 +5204,41 @@ snapshots: commander: 9.5.0 optional: true - proc-log@2.0.1: {} + proc-log@6.1.0: {} - proc-log@5.0.0: {} + process-nextick-args@2.0.1: {} progress@2.0.3: {} - promise-inflight@1.0.1: {} - promise-retry@2.0.1: dependencies: err-code: 2.0.3 retry: 0.12.0 - proxy-from-env@1.1.0: + proper-lockfile@4.1.2: + dependencies: + graceful-fs: 4.2.11 + retry: 0.12.0 + signal-exit: 3.0.7 + + proxy-from-env@2.1.0: optional: true - pump@3.0.3: + pump@3.0.4: dependencies: end-of-stream: 1.4.5 once: 1.4.0 - punycode@2.3.1: {} - pupa@3.3.0: dependencies: escape-goat: 4.0.0 + pvtsutils@1.3.6: + dependencies: + tslib: 2.8.1 + + pvutils@1.1.5: {} + queue-microtask@1.2.3: {} quick-lru@5.1.1: {} @@ -5888,31 +5257,43 @@ snapshots: transitivePeerDependencies: - supports-color + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + readable-stream@3.6.2: dependencies: inherits: 2.0.4 string_decoder: 1.3.0 util-deprecate: 1.0.2 + optional: true readdirp@3.6.0: dependencies: - picomatch: 2.3.1 + picomatch: 2.3.2 - readdirp@4.1.2: {} + readdirp@5.0.0: {} require-directory@2.1.1: {} + require-from-string@2.0.2: {} + resedit@1.7.2: dependencies: pe-library: 0.4.1 resolve-alpn@1.2.1: {} - resolve-pkg-maps@1.0.0: {} - - resolve@1.22.11: + resolve@1.22.12: dependencies: - is-core-module: 2.16.1 + es-errors: 1.3.0 + is-core-module: 2.16.2 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 @@ -5920,11 +5301,6 @@ snapshots: dependencies: lowercase-keys: 2.0.0 - restore-cursor@3.1.0: - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - retry@0.12.0: {} reusify@1.1.0: {} @@ -5933,10 +5309,6 @@ snapshots: dependencies: glob: 7.2.3 - rimraf@3.0.2: - dependencies: - glob: 7.2.3 - roarr@2.15.4: dependencies: boolean: 3.2.0 @@ -5964,26 +5336,26 @@ snapshots: '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.1 '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.1 - rolldown@1.0.0-rc.15: + rolldown@1.2.0: dependencies: - '@oxc-project/types': 0.124.0 - '@rolldown/pluginutils': 1.0.0-rc.15 + '@oxc-project/types': 0.140.0 + '@rolldown/pluginutils': 1.0.1 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-rc.15 - '@rolldown/binding-darwin-arm64': 1.0.0-rc.15 - '@rolldown/binding-darwin-x64': 1.0.0-rc.15 - '@rolldown/binding-freebsd-x64': 1.0.0-rc.15 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.15 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.15 - '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.15 - '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.15 - '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.15 - '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.15 - '@rolldown/binding-linux-x64-musl': 1.0.0-rc.15 - '@rolldown/binding-openharmony-arm64': 1.0.0-rc.15 - '@rolldown/binding-wasm32-wasi': 1.0.0-rc.15 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.15 - '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.15 + '@rolldown/binding-android-arm64': 1.2.0 + '@rolldown/binding-darwin-arm64': 1.2.0 + '@rolldown/binding-darwin-x64': 1.2.0 + '@rolldown/binding-freebsd-x64': 1.2.0 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.0 + '@rolldown/binding-linux-arm64-gnu': 1.2.0 + '@rolldown/binding-linux-arm64-musl': 1.2.0 + '@rolldown/binding-linux-ppc64-gnu': 1.2.0 + '@rolldown/binding-linux-s390x-gnu': 1.2.0 + '@rolldown/binding-linux-x64-gnu': 1.2.0 + '@rolldown/binding-linux-x64-musl': 1.2.0 + '@rolldown/binding-openharmony-arm64': 1.2.0 + '@rolldown/binding-wasm32-wasi': 1.2.0 + '@rolldown/binding-win32-arm64-msvc': 1.2.0 + '@rolldown/binding-win32-x64-msvc': 1.2.0 rollup-plugin-copy@3.5.0: dependencies: @@ -5997,23 +5369,24 @@ snapshots: dependencies: queue-microtask: 1.2.3 - safe-buffer@5.2.1: {} + safe-buffer@5.1.2: {} - safer-buffer@2.1.2: {} + safe-buffer@5.2.1: + optional: true sanitize-filename@1.6.4: dependencies: truncate-utf8-bytes: 1.0.2 - sass@1.97.3: + sass@1.101.6: dependencies: - chokidar: 4.0.3 - immutable: 5.1.4 + chokidar: 5.0.0 + immutable: 5.1.9 source-map-js: 1.2.1 optionalDependencies: - '@parcel/watcher': 2.5.6 + '@parcel/watcher': 2.6.0 - sax@1.4.4: {} + sax@1.6.0: {} semver-compare@1.0.0: optional: true @@ -6022,20 +5395,22 @@ snapshots: semver@6.3.1: {} - semver@7.7.3: {} - semver@7.7.4: {} + semver@7.8.1: {} + + semver@7.8.5: {} + serialize-error@7.0.1: dependencies: type-fest: 0.13.1 optional: true - seroval-plugins@1.5.0(seroval@1.5.0): + seroval-plugins@1.5.6(seroval@1.5.6): dependencies: - seroval: 1.5.0 + seroval: 1.5.6 - seroval@1.5.0: {} + seroval@1.5.6: {} set-blocking@2.0.0: optional: true @@ -6048,68 +5423,36 @@ snapshots: signal-exit@3.0.7: {} - signal-exit@4.1.0: {} - simple-update-notifier@2.0.0: dependencies: - semver: 7.7.4 + semver: 7.8.5 slash@3.0.0: {} - slice-ansi@3.0.0: - dependencies: - ansi-styles: 4.3.0 - astral-regex: 2.0.0 - is-fullwidth-code-point: 3.0.0 - optional: true - slice-ansi@5.0.0: dependencies: ansi-styles: 6.2.3 is-fullwidth-code-point: 4.0.0 - smart-buffer@4.2.0: {} - - socks-proxy-agent@7.0.0: - dependencies: - agent-base: 6.0.2 - debug: 4.4.3 - socks: 2.8.7 - transitivePeerDependencies: - - supports-color - - socks-proxy-agent@8.0.5: - dependencies: - agent-base: 7.1.4 - debug: 4.4.3 - socks: 2.8.7 - transitivePeerDependencies: - - supports-color - - socks@2.8.7: - dependencies: - ip-address: 10.1.0 - smart-buffer: 4.2.0 - solid-js@1.6.16: dependencies: csstype: 3.2.3 - solid-js@1.9.12: + solid-js@1.9.14: dependencies: csstype: 3.2.3 - seroval: 1.5.0 - seroval-plugins: 1.5.0(seroval@1.5.0) + seroval: 1.5.6 + seroval-plugins: 1.5.6(seroval@1.5.6) - solid-motionone@1.0.4(solid-js@1.9.12): + solid-motionone@1.0.4(solid-js@1.9.14): dependencies: '@motionone/dom': 10.18.0 '@motionone/utils': 10.18.0 - '@solid-primitives/props': 3.2.2(solid-js@1.9.12) - '@solid-primitives/refs': 1.1.2(solid-js@1.9.12) - '@solid-primitives/transition-group': 1.1.2(solid-js@1.9.12) + '@solid-primitives/props': 3.2.4(solid-js@1.9.14) + '@solid-primitives/refs': 1.1.4(solid-js@1.9.14) + '@solid-primitives/transition-group': 1.1.2(solid-js@1.9.14) csstype: 3.2.3 - solid-js: 1.9.12 + solid-js: 1.9.14 sort-keys-length@1.0.1: dependencies: @@ -6128,19 +5471,15 @@ snapshots: source-map@0.6.1: {} + spdx-license-list@6.11.0: {} + spitroast@2.1.4: {} + spitroast@2.1.6: {} + sprintf-js@1.1.3: optional: true - ssri@12.0.0: - dependencies: - minipass: 7.1.3 - - ssri@9.0.1: - dependencies: - minipass: 3.3.6 - stat-mode@1.0.0: {} string-width@4.2.3: @@ -6149,30 +5488,25 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.2.0 - string-width@7.2.0: dependencies: emoji-regex: 10.6.0 - get-east-asian-width: 1.4.0 - strip-ansi: 7.1.2 + get-east-asian-width: 1.6.0 + strip-ansi: 7.2.0 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 + optional: true strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.1.2: - dependencies: - ansi-regex: 6.2.2 - strip-ansi@7.2.0: dependencies: ansi-regex: 6.2.2 @@ -6180,6 +5514,10 @@ snapshots: strip-json-comments@2.0.1: optional: true + strnum@2.4.1: + dependencies: + anynum: 1.0.1 + sumchecker@3.0.1: dependencies: debug: 4.4.3 @@ -6200,8 +5538,9 @@ snapshots: minizlib: 2.1.2 mkdirp: 1.0.4 yallist: 4.0.0 + optional: true - tar@7.5.13: + tar@7.5.21: dependencies: '@isaacs/fs-minipass': 4.0.1 chownr: 3.0.0 @@ -6225,16 +5564,16 @@ snapshots: tiny-typed-emitter@2.1.0: {} - tinyglobby@0.2.15: + tinyglobby@0.2.17: dependencies: - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 + fdir: 6.5.0(picomatch@4.0.5) + picomatch: 4.0.5 tmp-promise@3.0.3: dependencies: - tmp: 0.2.5 + tmp: 0.2.7 - tmp@0.2.5: {} + tmp@0.2.7: {} to-regex-range@5.0.1: dependencies: @@ -6246,42 +5585,45 @@ snapshots: tslib@2.8.1: {} - tsx@4.21.0: - dependencies: - esbuild: 0.27.2 - get-tsconfig: 4.13.0 - optionalDependencies: - fsevents: 2.3.3 - type-fest@0.13.1: optional: true - typescript@5.9.3: {} + typescript@7.0.2: + optionalDependencies: + '@typescript/typescript-aix-ppc64': 7.0.2 + '@typescript/typescript-darwin-arm64': 7.0.2 + '@typescript/typescript-darwin-x64': 7.0.2 + '@typescript/typescript-freebsd-arm64': 7.0.2 + '@typescript/typescript-freebsd-x64': 7.0.2 + '@typescript/typescript-linux-arm': 7.0.2 + '@typescript/typescript-linux-arm64': 7.0.2 + '@typescript/typescript-linux-loong64': 7.0.2 + '@typescript/typescript-linux-mips64el': 7.0.2 + '@typescript/typescript-linux-ppc64': 7.0.2 + '@typescript/typescript-linux-riscv64': 7.0.2 + '@typescript/typescript-linux-s390x': 7.0.2 + '@typescript/typescript-linux-x64': 7.0.2 + '@typescript/typescript-netbsd-arm64': 7.0.2 + '@typescript/typescript-netbsd-x64': 7.0.2 + '@typescript/typescript-openbsd-arm64': 7.0.2 + '@typescript/typescript-openbsd-x64': 7.0.2 + '@typescript/typescript-sunos-x64': 7.0.2 + '@typescript/typescript-win32-arm64': 7.0.2 + '@typescript/typescript-win32-x64': 7.0.2 - ufo@1.6.3: {} + ufo@1.6.4: {} uglify-js@3.19.3: optional: true - undici-types@6.21.0: {} + undici-types@7.18.2: {} - undici-types@7.16.0: {} + undici-types@8.3.0: {} - unique-filename@2.0.1: - dependencies: - unique-slug: 3.0.0 + undici@6.27.0: {} - unique-filename@4.0.0: - dependencies: - unique-slug: 5.0.0 - - unique-slug@3.0.0: - dependencies: - imurmurhash: 0.1.4 - - unique-slug@5.0.0: - dependencies: - imurmurhash: 0.1.4 + undici@7.28.0: + optional: true universalify@0.1.2: {} @@ -6292,15 +5634,25 @@ snapshots: escape-string-regexp: 5.0.0 path-exists: 5.0.0 - update-browserslist-db@1.2.3(browserslist@4.28.1): + unzipper@0.12.5: dependencies: - browserslist: 4.28.1 + bluebird: 3.7.2 + duplexer2: 0.1.4 + fs-extra: 11.3.1 + graceful-fs: 4.2.11 + node-int64: 0.4.0 + + update-browserslist-db@1.2.3(browserslist@4.28.2): + dependencies: + browserslist: 4.28.2 escalade: 3.2.0 picocolors: 1.1.1 - uri-js@4.4.1: + update-browserslist-db@1.2.3(browserslist@4.28.7): dependencies: - punycode: 2.3.1 + browserslist: 4.28.7 + escalade: 3.2.0 + picocolors: 1.1.1 url-join@4.0.1: optional: true @@ -6309,16 +5661,13 @@ snapshots: util-deprecate@1.0.2: {} - verror@1.10.1: + webcrypto-core@1.9.2: dependencies: - assert-plus: 1.0.0 - core-util-is: 1.0.2 - extsprintf: 1.4.1 - optional: true - - wcwidth@1.0.1: - dependencies: - defaults: 1.0.4 + '@peculiar/asn1-schema': 2.8.0 + '@peculiar/json-schema': 1.1.12 + '@peculiar/utils': 2.0.3 + asn1js: 3.0.10 + tslib: 2.8.1 which@2.0.2: dependencies: @@ -6326,7 +5675,11 @@ snapshots: which@5.0.0: dependencies: - isexe: 3.1.1 + isexe: 3.1.5 + + which@6.0.1: + dependencies: + isexe: 4.0.0 wide-align@1.1.5: dependencies: @@ -6341,21 +5694,17 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 - wrap-ansi@8.1.0: - dependencies: - ansi-styles: 6.2.3 - string-width: 5.1.2 - strip-ansi: 7.2.0 - wrappy@1.0.2: {} - ws@8.20.0: {} + ws@8.21.1: {} xml-formatter@3.7.0: dependencies: - xml-parser-xo: 4.1.5 + xml-parser-xo: 4.1.6 - xml-parser-xo@4.1.5: {} + xml-naming@0.3.0: {} + + xml-parser-xo@4.1.6: {} xmlbuilder@15.1.1: {} @@ -6369,7 +5718,7 @@ snapshots: yargs-parser@21.1.1: {} - yargs@17.7.2: + yargs@17.7.3: dependencies: cliui: 8.0.1 escalade: 3.2.0 @@ -6379,11 +5728,6 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 - yauzl@2.10.0: - dependencies: - buffer-crc32: 0.2.13 - fd-slicer: 1.1.0 - yocto-queue@0.1.0: {} zod@3.25.76: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..8a1bd03 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,12 @@ +allowBuilds: + "@parcel/watcher": true + "@vencord/venmic": true + electron-winstaller: true + esbuild: true + koffi: true + +minimumReleaseAgeExclude: + - electron@42.3.3 || 43.2.0 + +overrides: + yauzl: "^3.3.1" # Electron still can't get their shit together https://github.com/electron/electron/issues/51619 diff --git a/rolldown.config.js b/rolldown.config.ts similarity index 88% rename from rolldown.config.js rename to rolldown.config.ts index c63609e..c198230 100644 --- a/rolldown.config.js +++ b/rolldown.config.ts @@ -31,9 +31,13 @@ export default defineConfig([ targets: [ { src: "src/**/**/*.html", dest: "ts-out/html/" }, { src: "src/**/**/*.css", dest: "ts-out/css/" }, + { src: "src/setup/setup.css", dest: "ts-out/html/" }, + { src: "node_modules/@uwu/shelter-ui/compat.css", dest: "ts-out/html/" }, { src: "src/**/**/*.js", dest: "ts-out/js/" }, { src: "package.json", dest: "ts-out/" }, { src: "assets/**/**", dest: "ts-out/assets/" }, + // Monaco AMD tree for the offline Quick CSS editor (next to editor.html) + { src: "node_modules/monaco-editor/min/vs/**/*", dest: "ts-out/html/monaco/vs" }, ], }), ], diff --git a/scripts/build/sandboxFix.cjs b/scripts/build/sandboxFix.mjs similarity index 90% rename from scripts/build/sandboxFix.cjs rename to scripts/build/sandboxFix.mjs index bf118fd..1c118de 100644 --- a/scripts/build/sandboxFix.cjs +++ b/scripts/build/sandboxFix.mjs @@ -6,18 +6,21 @@ // Based on https://github.com/gergof/electron-builder-sandbox-fix/blob/master/lib/index.js -const fs = require("node:fs/promises"); -const path = require("node:path"); +import fs from "node:fs/promises"; +import path from "node:path"; +import AppImageTarget from "app-builder-lib/out/targets/appimage/AppImageTarget.js"; + let isApplied = false; -const hook = async () => { - if (isApplied) return; - isApplied = true; +export async function applyAppImageSandboxFix() { if (process.platform !== "linux") { // this fix is only required on linux return; } - const AppImageTarget = require("app-builder-lib/out/targets/AppImageTarget.js"); + + if (isApplied) return; + isApplied = true; + const oldBuildMethod = AppImageTarget.default.prototype.build; AppImageTarget.default.prototype.build = async function (...args) { console.log("Running AppImage builder hook", args); @@ -69,6 +72,4 @@ exec "$SCRIPT_DIR/${this.packager.executableName}.bin" "$([ "$IS_STEAMOS" == 1 ] return ret; }; -}; - -module.exports = hook; +} diff --git a/scripts/copyVenmic.mts b/scripts/copyVenmic.ts similarity index 100% rename from scripts/copyVenmic.mts rename to scripts/copyVenmic.ts diff --git a/scripts/spdxLicenceDebianFormat.ts b/scripts/spdxLicenceDebianFormat.ts new file mode 100644 index 0000000..d78e89d --- /dev/null +++ b/scripts/spdxLicenceDebianFormat.ts @@ -0,0 +1,66 @@ +// https://www.debian.org/doc/debian-policy/ch-docs.html#copyright-information +// https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ + +import { readFileSync, writeFileSync } from "node:fs"; +import path from "node:path"; +import spdxLicenseList from "spdx-license-list"; + +interface CopyrightConfig { + upstreamName: string; + source: string; + copyrightHolder: string; + licenseId: string; + comment: string; // optional but nice to have +} + +function indentText(text: string): string { + // formatted text fields follow the same rules as Debian control file + // long descriptions: each line indented with a single space, blank + // lines represented as " ." + return text + .split("\n") + .map((line) => (line.trim() === "" ? " ." : ` ${line}`)) + .join("\n"); +} + +function generateCopyrightFile(config: CopyrightConfig): string { + const license = spdxLicenseList[config.licenseId]; + if (!license) { + throw new Error(`Unknown SPDX license id: ${config.licenseId}`); + } + + const header = [ + "Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/", + `Upstream-Name: ${config.upstreamName}`, + `Source: ${config.source}`, + `Comment: ${indentText(config.comment)}`, // optional field + ].join("\n"); + + const licenseText = readFileSync("license.txt").toString(); + + const licenseStanza = [`License: ${config.licenseId}`, indentText(licenseText)].join("\n"); + + const filesStanza = ["Files: *", `Copyright: ${config.copyrightHolder}`, `License: ${config.licenseId}`].join("\n"); + + return `${[header, filesStanza, licenseStanza].join("\n\n")}\n`; +} + +/** + * Returns the Debian SPDX-formatted license for given license ID + * + * @export + * @return {*} {string} + */ +export default function (): string { + const copyrightContent: string = generateCopyrightFile({ + upstreamName: "Legcord", + source: "https://github.com/Legcord/Legcord", + copyrightHolder: `2020 - ${new Date().getFullYear()} Legcord Contributors`, // git log --reverse + licenseId: "OSL-3.0", + comment: "Open-Source Discord client alternative.", + }); + + const licensePath = path.join(__dirname, "spdx-license.txt"); + writeFileSync(licensePath, copyrightContent); + return licensePath; +} diff --git a/scripts/utils/updateMeta.mts b/scripts/utils/updateMeta.ts similarity index 90% rename from scripts/utils/updateMeta.mts rename to scripts/utils/updateMeta.ts index 788dfd8..17c243e 100644 --- a/scripts/utils/updateMeta.mts +++ b/scripts/utils/updateMeta.ts @@ -50,6 +50,17 @@ const latestReleaseInformation = await fetch("https://api.github.com/repos/Legco }, }).then((res) => res.json()); +// Ignore devbuild releases +if ( + latestReleaseInformation.name?.toLowerCase().includes("devbuild") || + latestReleaseInformation.tag_name?.toLowerCase().includes("devbuild") || + latestReleaseInformation.prerelease || + latestReleaseInformation.draft +) { + console.log("Latest release is a devbuild, nothing to be done"); + process.exit(0); +} + const metaInfo = await fs.readFile("./meta/app.legcord.Legcord.metainfo.xml", "utf-8"); const parser = new DOMParser().parseFromString(metaInfo, "text/xml"); diff --git a/src/@types/keybind.d.ts b/src/@types/keybind.d.ts index 2cd9f60..368035a 100644 --- a/src/@types/keybind.d.ts +++ b/src/@types/keybind.d.ts @@ -6,6 +6,7 @@ export type KeybindActions = | "navigateForward" | "openQuickCss" | "pushToTalk" + | "openSettings" | "runJavascript"; export interface Keybind { accelerator: Electron.Accelerator; diff --git a/src/@types/legcordWindow.d.ts b/src/@types/legcordWindow.d.ts index 8bcea1f..2becc98 100644 --- a/src/@types/legcordWindow.d.ts +++ b/src/@types/legcordWindow.d.ts @@ -5,6 +5,21 @@ import type { Keybind } from "./keybind.js"; import type { Settings } from "./settings.js"; import type { ThemeManifest } from "./themeManifest.js"; +export interface LegcordPluginInfo { + id: string; + name: string; + version: string; + description?: string; + author?: string; + enabled: boolean; + compatible: boolean; + compatibilityMessage?: string; + compatibleVersions: string[]; + hasMain: boolean; + hasPreload: boolean; + hasRenderer: boolean; +} + export interface LegcordWindow { window: { show: () => void; @@ -31,6 +46,8 @@ export interface LegcordWindow { openCustomIconDialog: () => void; copyDebugInfo: () => void; copyGPUInfo: () => void; + openWebRTCInternals: () => void; + openGPUInfo: () => void; setLang(lang: string): () => void; addKeybind: (keybind: Keybind) => void; toggleKeybind: (id: string) => void; @@ -63,6 +80,7 @@ export interface LegcordWindow { uninstall: (id: string) => void; set: (id: string, state: boolean) => void; getThemes: () => Readonly; + refresh: () => Readonly; openQuickCss: () => void; edit: (id: string) => void; folder: (id: string) => void; @@ -91,6 +109,12 @@ export interface LegcordWindow { save(data: string): Promise<{ ok: true } | { ok: false; error: string }>; restore(): Promise; }; + plugins: { + list: () => Promise; + setEnabled: (id: string, enabled: boolean) => Promise<{ ok: boolean }>; + reload: (id: string) => Promise<{ ok: boolean }>; + openFolder: () => void; + }; /** Plugin storage API. Requires user to enable "Extended plugin abilities" in Legcord settings. */ fs: { writeFile: ( diff --git a/src/@types/settings.d.ts b/src/@types/settings.d.ts index 642f4f2..557ff04 100644 --- a/src/@types/settings.d.ts +++ b/src/@types/settings.d.ts @@ -25,6 +25,9 @@ export interface AudioSettings { loopbackType: "loopback" | "loopbackWithMute"; } +/** Chromium/Electron proxy modes — mirrors browser proxy settings. */ +export type ProxyMode = "system" | "direct" | "fixed_servers" | "pac_script" | "auto_detect"; + export interface Settings { // Referenced for detecting a broken config. "0"?: string; @@ -43,12 +46,24 @@ export interface Settings { mods: ValidMods[]; mobileMode: boolean; skipSplash: boolean; - performanceMode: "battery" | "dynamic" | "performance" | "smoothScreenshare" | "none"; + performanceMode: + | "battery" + | "dynamic" + | "performance" + | "balanced" + | "memory" + | "voip" + | "latency" + | "smoothScreenshare" + | "none"; customJsBundle: RequestInfo | URL | string; customCssBundle: RequestInfo | URL | string; - startMinimized: boolean; + /** How the main window appears on launch: normal, taskbar minimized, or tray-only. */ + startMinimized: "off" | "minimized" | "tray"; keybinds: Keybind[]; hardwareAcceleration: boolean; + /** Rewrite H.264 Constrained Baseline (42e0) → Baseline (4200) in WebRTC SDP for HW encode. */ + sdpH264BaselineRewrite: boolean; useMacSystemPicker: boolean; inviteWebsocket: boolean; disableAutogain: boolean; @@ -67,6 +82,14 @@ export interface Settings { quickCss: boolean; autoScroll: boolean; additionalArguments: string; + /** How Legcord resolves HTTP(S) proxies (Chromium + main-process fetch). */ + proxyMode: ProxyMode; + /** Fixed proxy rules, e.g. `http://127.0.0.1:8080` or `socks5://host:1080`. */ + proxyRules: string; + /** Hosts that bypass the proxy (comma-separated), e.g. `,*.intranet.example`. */ + proxyBypassRules: string; + /** PAC script URL when proxyMode is `pac_script`. */ + proxyPacScript: string; noBundleUpdates: ValidMods[]; automaticUpdates: boolean; overlayButtonColor: string; @@ -76,4 +99,7 @@ export interface Settings { modCache?: Record; extendedPluginAbilities: boolean; supportBannerDismissed: boolean; + pluginStates?: Record; + // Remove below once the plugin system is fully implemented. + showExperimentalPluginMenu: boolean; } diff --git a/src/@types/windowState.d.ts b/src/@types/windowState.d.ts index 93eeb3f..6a82527 100644 --- a/src/@types/windowState.d.ts +++ b/src/@types/windowState.d.ts @@ -4,4 +4,6 @@ export interface WindowState { x: number; y: number; isMaximized: boolean; + displayId?: number; + displayScaleFactor?: number; } diff --git a/src/common/backup.ts b/src/common/backup.ts index b3458d8..5880ef8 100644 --- a/src/common/backup.ts +++ b/src/common/backup.ts @@ -1,4 +1,4 @@ -import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs"; +import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "node:fs"; import path from "node:path"; import AdmZip from "adm-zip"; import { app } from "electron"; @@ -38,6 +38,7 @@ export interface BackupManifest extends BackupSavePayload { export interface BackupPaths { userDataPath: string; themesPath: string; + extensionsPath: string; pluginsPath: string; pluginStoragePath: string; quickCssPath: string; @@ -114,7 +115,8 @@ export function buildBackupZipBuffer(payload: BackupSavePayload, paths: BackupPa entries.push(...walkFiles(paths.themesPath, "data/themes")); } if (includes.legcordExtensionPlugins) { - entries.push(...walkFiles(paths.pluginsPath, "data/plugins")); + entries.push(...walkFiles(paths.extensionsPath, "data/plugins")); + entries.push(...walkFiles(paths.pluginsPath, "data/runtime-plugins")); entries.push(...walkFiles(paths.pluginStoragePath, "data/plugin-storage")); } if (includes.modBundles) { @@ -197,7 +199,7 @@ export function applyBackupFromMap( if (name.startsWith("data/plugins/")) { if (!inc.legcordExtensionPlugins) continue; const rest = name.slice("data/plugins/".length); - const dest = resolvePathUnderBaseDir(paths.pluginsPath, rest); + const dest = resolvePathUnderBaseDir(paths.extensionsPath, rest); if (!dest) { console.warn(`[backup] Skipping unsafe zip path (plugins): ${name}`); continue; @@ -206,6 +208,18 @@ export function applyBackupFromMap( continue; } + if (name.startsWith("data/runtime-plugins/")) { + if (!inc.legcordExtensionPlugins) continue; + const rest = name.slice("data/runtime-plugins/".length); + const dest = resolvePathUnderBaseDir(paths.pluginsPath, rest); + if (!dest) { + console.warn(`[backup] Skipping unsafe zip path (runtime-plugins): ${name}`); + continue; + } + writeFileEnsuringDirs(dest, data); + continue; + } + if (name.startsWith("data/plugin-storage/")) { if (!inc.legcordExtensionPlugins) continue; const rest = name.slice("data/plugin-storage/".length); diff --git a/src/common/commandDefinitions.ts b/src/common/commandDefinitions.ts new file mode 100644 index 0000000..a301db9 --- /dev/null +++ b/src/common/commandDefinitions.ts @@ -0,0 +1,28 @@ +// static command definitions to retrieve at build-time without calling electron-dev indirectly + +export enum ValidActions { + mute = "mute", + deafen = "deafen", + leaveCall = "leave", + openSettings = "opensettings", + help = "help", +} + +export const actionDescriptions: Record = { + [ValidActions.mute]: "Toggle microphone mute", + [ValidActions.deafen]: "Toggle deafen (mute audio input/output)", + [ValidActions.leaveCall]: "Leave the current voice call", + [ValidActions.openSettings]: "Open the settings panel", + [ValidActions.help]: "Shows this help message", +}; + +export const ACTION_FRIENDLY_NAMES: Record = { + [ValidActions.mute]: "Toggle Mute", + [ValidActions.deafen]: "Toggle Deafen", + [ValidActions.leaveCall]: "Leave Call", + [ValidActions.openSettings]: "Open Settings", + [ValidActions.help]: "ignore (help)", +}; + +// we don't need a 'show help' shortcut do we? be fr +export const EXCLUDED_FROM_SHORTCUTS: ValidActions[] = [ValidActions.help]; diff --git a/src/common/config.ts b/src/common/config.ts index 709bf97..e23da14 100644 --- a/src/common/config.ts +++ b/src/common/config.ts @@ -10,9 +10,9 @@ export let firstRun: boolean; // Performance optimization: Cache config to avoid reading file on every call let configCache: Settings | null = null; let configCacheTime = 0; -const CONFIG_CACHE_TTL = 1000; // Cache for 1 second +const CONFIG_CACHE_TTL = 5000; // Cache for 5 seconds const defaults: Settings = { - windowStyle: "default", + windowStyle: "overlay", channel: "stable", bounceOnPing: false, csp: "none", @@ -34,22 +34,23 @@ const defaults: Settings = { loopbackType: "loopback", }, multiInstance: false, - mods: ["vencord"], + mods: [], transparency: "none", windowMaterial: "mica", spellcheck: true, hardwareAcceleration: true, + sdpH264BaselineRewrite: true, performanceMode: "none", skipSplash: false, inviteWebsocket: true, - startMinimized: false, + startMinimized: "off", disableHttpCache: false, customJsBundle: "https://legcord.app/placeholder.js", customCssBundle: "https://legcord.app/placeholder.css", disableAutogain: false, autoHideMenuBar: true, blockPowerSavingInVoiceChat: false, - useMacSystemPicker: true, + useMacSystemPicker: false, mobileMode: false, tray: "dynamic", doneSetup: false, @@ -60,6 +61,10 @@ const defaults: Settings = { noBundleUpdates: [], automaticUpdates: false, additionalArguments: "", + proxyMode: "system", + proxyRules: "", + proxyBypassRules: "", + proxyPacScript: "", customIcon: join(import.meta.dirname, "../", "/assets/desktop.png"), smoothScroll: true, autoScroll: false, @@ -67,6 +72,8 @@ const defaults: Settings = { extendedPluginAbilities: false, quickCss: true, supportBannerDismissed: false, + showExperimentalPluginMenu: false, + pluginStates: {}, }; const safeMode: Settings = { @@ -75,10 +82,12 @@ const safeMode: Settings = { windowStyle: "native", csp: "vanilla", hardwareAcceleration: false, + sdpH264BaselineRewrite: false, disableHttpCache: true, vaapi: false, additionalArguments: "", extendedPluginAbilities: false, + showExperimentalPluginMenu: false, quickCss: false, }; @@ -113,6 +122,31 @@ export function getConfig(object: K): Settings[K] { configCacheTime = now; return returnData[object]; } + +const START_MINIMIZED_MODES = new Set(["off", "minimized", "tray"]); + +/** Effective startup window mode (CLI overrides are session-only). */ +export function getStartMinimizedMode(): Settings["startMinimized"] { + if (process.argv.includes("--start-in-tray")) return "tray"; + if (process.argv.includes("--start-minimized")) return "minimized"; + const mode = getConfig("startMinimized"); + return START_MINIMIZED_MODES.has(mode) ? mode : "off"; +} + +/** True when startup should not show the window normally (skip splash). */ +export function isBackgroundStart(): boolean { + return getStartMinimizedMode() !== "off"; +} + +function migrateStartMinimized(settingsObject: Record): boolean { + const value = settingsObject.startMinimized; + if (typeof value === "boolean") { + settingsObject.startMinimized = value ? "tray" : "off"; + console.log(`[Config] Migrated startMinimized boolean → "${settingsObject.startMinimized}"`); + return true; + } + return false; +} export function setConfig(object: K, toSet: Settings[K]): void { const rawData = readFileSync(getConfigLocation(), "utf-8"); const parsed = JSON.parse(rawData) as Settings; @@ -175,10 +209,15 @@ export function checkIfConfigExists(): void { export function checkIfConfigIsBroken(): void { try { const settingsData = readFileSync(getConfigLocation(), "utf-8"); - const settingsObject = JSON.parse(settingsData) as Settings; + const settingsObject = JSON.parse(settingsData) as Settings & Record; + + // Migrate before typeof repair — boolean → "tray" | "off" + if (migrateStartMinimized(settingsObject)) { + writeFileSync(getConfigLocation(), JSON.stringify(settingsObject, null, 4), "utf-8"); + } // Performance optimization: Update cache after validation - configCache = settingsObject; + configCache = settingsObject as Settings; configCacheTime = Date.now(); let configWasFine = true; diff --git a/src/common/detectables.ts b/src/common/detectables.ts index 49f913a..75d23e1 100644 --- a/src/common/detectables.ts +++ b/src/common/detectables.ts @@ -1,8 +1,7 @@ import fs from "node:fs"; import path from "node:path"; -import { app } from "electron"; - import type { Game, GameList } from "arrpc"; +import { app } from "electron"; export function getDetectablesPath() { const userDataPath = app.getPath("userData"); const storagePath = path.join(userDataPath, "/storage/"); diff --git a/src/common/dom.ts b/src/common/dom.ts index 72ba7cf..880cb87 100644 --- a/src/common/dom.ts +++ b/src/common/dom.ts @@ -1,7 +1,12 @@ import type { BrowserWindow } from "electron"; +let scriptCounter = 0; + export function addStyle(styleUrl: string): void { + const id = `legcord-style-${styleUrl.replace(/[^a-zA-Z0-9]/g, "-")}`; + if (document.getElementById(id)) return; const style = document.createElement("link"); + style.id = id; style.rel = "stylesheet"; style.type = "text/css"; style.href = styleUrl; @@ -9,6 +14,7 @@ export function addStyle(styleUrl: string): void { } export function addTheme(id: string, styleString: string): void { + if (document.getElementById(id)) return; const style = document.createElement("style"); style.textContent = styleString; style.id = id; @@ -16,27 +22,33 @@ export function addTheme(id: string, styleString: string): void { } export function addScript(scriptString: string): void { + const id = `legcord-script-${++scriptCounter}`; + if (document.getElementById(id)) return; const script = document.createElement("script"); + script.id = id; script.appendChild(document.createTextNode(scriptString)); document.body.append(script); } export async function injectJS(inject: string): Promise { + const id = `legcord-inject-${inject.replace(/[^a-zA-Z0-9]/g, "-")}`; + if (document.getElementById(id)) return; const js = await (await fetch(`${inject}`)).text(); - const el = document.createElement("script"); - + el.id = id; el.appendChild(document.createTextNode(js)); - document.body.appendChild(el); } export function navigateTo(passedWindow: BrowserWindow, url: string): void { - console.log(`[legcord deeplink] Navigating to ${url}`); - const safeUrl = JSON.stringify(url); - passedWindow.webContents.executeJavaScript(` - history.pushState({}, null, ${safeUrl}); - window.dispatchEvent(new PopStateEvent("popstate", {})); - `); + // Sanitize: only allow path-like URLs (no protocol, no quotes) + const sanitized = url.replace(/[^a-zA-Z0-9/_\-@.]/g, ""); + console.log(`[legcord deeplink] Navigating to ${sanitized}`); + passedWindow.webContents.executeJavaScript( + `history.pushState({}, null, ${JSON.stringify(sanitized)});window.dispatchEvent(new PopStateEvent("popstate", {}));`, + ); + passedWindow.setSkipTaskbar(false); + if (passedWindow.isMinimized()) passedWindow.restore(); + passedWindow.show(); passedWindow.focus(); } diff --git a/src/common/flags.ts b/src/common/flags.ts index 3231cc1..507a2d9 100644 --- a/src/common/flags.ts +++ b/src/common/flags.ts @@ -1,4 +1,4 @@ -import { readFileSync } from "node:fs"; +import { existsSync, readFileSync } from "node:fs"; import { join } from "node:path"; import { app, powerMonitor } from "electron"; import isDev from "electron-is-dev"; @@ -32,16 +32,88 @@ const performance: Preset = { disableFeatures: ["Vulkan"], }; +/** Light GPU boost without forcing the discrete GPU — a middle ground. */ +const balanced: Preset = { + switches: [["enable-gpu-rasterization"], ["enable-zero-copy"], ["ignore-gpu-blocklist"]], + enableFeatures: [ + "CanvasOopRasterization", + "UseSkiaRenderer", + "WebAssemblyLazyCompilation", + "CalculateNativeWinOcclusion", + "ThrottleDisplayNoneAndVisibilityHiddenCrossOriginIframes", + ], + disableFeatures: ["Vulkan"], +}; + +/** Reduce RAM / CPU usage at the cost of some visual smoothness. */ +const memory: Preset = { + switches: [ + ["enable-low-end-device-mode"], + ["enable-low-res-tiling"], + ["process-per-site"], + ["renderer-process-limit", "2"], + ["force_low_power_gpu"], + ["disk-cache-size", "67108864"], // 64 MB + ["skia-resource-cache-limit-mb", "64"], + ], + enableFeatures: ["CalculateNativeWinOcclusion", "TurnOffStreamingMediaCachingOnBattery"], + disableFeatures: [], +}; + +/** Favor voice/video call quality. Platform-specific HW encode is layered on later. */ +const voip: Preset = { + switches: [ + ["enable-gpu-rasterization"], + ["enable-zero-copy"], + ["ignore-gpu-blocklist"], + ["enable-accelerated-video-decode"], + ["force_high_performance_gpu"], + ["disable-background-timer-throttling"], + ["disable-renderer-backgrounding"], + ["disable-backgrounding-occluded-windows"], + ["enable-gpu-memory-buffer-video-frames"], + ], + enableFeatures: [ + "WebRtcHWDecoding", + "WebRtcHWEncoding", + "AcceleratedVideoDecoder", + "AcceleratedVideoEncoder", + "ZeroCopyDesktopCapture", + ], + disableFeatures: ["UseChromeOSDirectVideoDecoder"], +}; + +/** Minimize input/render latency; keeps the app hot in the background. */ +const latency: Preset = { + switches: [ + ["enable-gpu-rasterization"], + ["enable-zero-copy"], + ["ignore-gpu-blocklist"], + ["force_high_performance_gpu"], + ["enable-hardware-overlays", "single-fullscreen,single-on-top,underlay"], + ["disable-background-timer-throttling"], + ["disable-renderer-backgrounding"], + ["disable-backgrounding-occluded-windows"], + ["disable-ipc-flooding-protection"], + ["disable-backing-store-limit"], + ], + enableFeatures: ["EnableDrDc", "CanvasOopRasterization", "UseSkiaRenderer", "WebAssemblyLazyCompilation"], + disableFeatures: ["Vulkan"], +}; + const smoothExperiment: Preset = { switches: [ ["enable-gpu-rasterization"], ["enable-zero-copy"], ["ignore-gpu-blocklist"], + ["enable-accelerated-video-decode"], ["disable-background-timer-throttling"], ["disable-renderer-backgrounding"], ["enable-hardware-overlays", "single-fullscreen,single-on-top,underlay"], ["force_high_performance_gpu"], - ["use-gl", "desktop"], + // Do NOT set use-gl=desktop here. On Electron 43+/macOS, Chromium only allows + // ANGLE (metal/opengl); use-gl=desktop fails GPU init and then disables all + // HW acceleration (including VideoToolbox encode) after repeated crashes. ], enableFeatures: [ "EnableDrDc", @@ -50,10 +122,11 @@ const smoothExperiment: Preset = { "ThrottleDisplayNoneAndVisibilityHiddenCrossOriginIframes", "UseSkiaRenderer", "WebAssemblyLazyCompilation", - "AcceleratedVideoDecodeLinuxGL", + "WebRtcHWEncoding", + "WebRtcHWDecoding", "AcceleratedVideoEncoder", "AcceleratedVideoDecoder", - "AcceleratedVideoDecodeLinuxZeroCopyGL", + "ZeroCopyDesktopCapture", ], disableFeatures: ["Vulkan", "UseChromeOSDirectVideoDecoder"], }; @@ -66,27 +139,178 @@ const battery: Preset = { ["enable-low-res-tiling"], ["process-per-site"], ], - enableFeatures: ["TurnOffStreamingMediaCachingOnBattery"], + enableFeatures: ["TurnOffStreamingMediaCachingOnBattery", "CalculateNativeWinOcclusion"], disableFeatures: [], }; -const vaapi: Preset = { +/** + * Shared WebRTC / screenshare baseline (no platform encode backend). + * Encode is added by macVideoToolbox / winVideoEncode / linux vaapi|software. + */ +const webrtcHwCommon: Preset = { switches: [ ["ignore-gpu-blocklist"], - ["enable-gpu-rasterization"], ["enable-zero-copy"], - ["force_high_performance_gpu"], - ["use-gl", "desktop"], - ], - enableFeatures: [ - "AcceleratedVideoDecodeLinuxGL", - "AcceleratedVideoEncoder", - "AcceleratedVideoDecoder", - "AcceleratedVideoDecodeLinuxZeroCopyGL", + ["enable-accelerated-video-decode"], + ["enable-gpu-memory-buffer-video-frames"], ], + enableFeatures: ["WebRtcHWDecoding", "AcceleratedVideoDecoder", "ZeroCopyDesktopCapture", "CanvasOopRasterization"], disableFeatures: ["UseChromeOSDirectVideoDecoder"], }; +/** Windows Media Foundation / Chromium HW encode path. */ +const winVideoEncode: Preset = { + switches: [ + // Legacy Chromium switches still honored by Electron's WebRTC stack + ["webrtc-hw-encoding"], + ["webrtc-hw-decoding"], + ], + enableFeatures: [ + "WebRtcHWEncoding", + "AcceleratedVideoEncoder", + // Off by default on Windows; without it CBP (Discord's 42e01f) stays on OpenH264. + // SDP munge prefers Baseline, but keep CBP HW as a fallback if negotiation reverts. + "PlatformH264CbpEncoding", + ], + disableFeatures: [], +}; + +/** + * Linux: force software OpenH264 encode when VAAPI is off. + * AMD VCE via VaapiVideoEncodeAccelerator can freeze Discord screenshare for viewers + * even when chrome://gpu lists encode profiles. + */ +const linuxSoftwareVideoEncode: Preset = { + switches: [], + enableFeatures: [], + disableFeatures: ["AcceleratedVideoEncoder", "VaapiVideoEncoder", "WebRtcHWEncoding"], +}; + +/** macOS VideoToolbox HW encode/decode (Intel + Apple Silicon). */ +const macVideoToolbox: Preset = { + switches: [ + ["ignore-gpu-blocklist"], + // After use-gl=desktop / other GPU init failures, Chromium may keep GPU disabled + // due to "frequent crashes" even once the bad flag is gone — clear that limit. + ["disable-gpu-process-crash-limit"], + ["enable-zero-copy"], + ["enable-accelerated-video-decode"], + // Legacy Chromium switches still honored by Electron's WebRTC stack + ["webrtc-hw-encoding"], + ["webrtc-hw-decoding"], + ["enable-gpu-memory-buffer-video-frames"], + ], + enableFeatures: [ + "MacosVideoToolbox", + "VideoToolboxVideoDecoder", + "WebRtcHWEncoding", + "WebRtcHWDecoding", + "AcceleratedVideoEncoder", + "AcceleratedVideoDecoder", + "ZeroCopyDesktopCapture", + // Helps enumerate platform HW encoders used by WebRTC on Apple GPUs + "PlatformHEVCEncoderSupport", + ], + disableFeatures: [], +}; + +/** Linux VA-API encode/decode (only applied when vaapi setting is on). */ +const linuxVaapi: Preset = { + switches: [ + ["ignore-gpu-blocklist"], + ["disable-gpu-process-crash-limit"], + ["enable-gpu-rasterization"], + ["enable-zero-copy"], + ["enable-accelerated-video-decode"], + ["force_high_performance_gpu"], + // ANGLE+OpenGL required for AcceleratedVideoDecodeLinuxGL on Wayland. + // Do NOT use use-gl=desktop (removed in Electron 43+ / breaks GPU init). + ["use-gl", "angle"], + ["use-angle", "gl"], + ["enable-gpu-memory-buffer-video-frames"], + ], + enableFeatures: [ + "VaapiIgnoreDriverChecks", + "VaapiVideoDecoder", + "VaapiVideoEncoder", + "AcceleratedVideoEncoder", + "AcceleratedVideoDecoder", + "AcceleratedVideoDecodeLinuxGL", + "AcceleratedVideoDecodeLinuxZeroCopyGL", + "WebRtcHWEncoding", + "WebRtcHWDecoding", + "ZeroCopyDesktopCapture", + "CanvasOopRasterization", + ], + // Vulkan is incompatible with ozone wayland and breaks VAAPI GL interop. + disableFeatures: ["UseChromeOSDirectVideoDecoder", "Vulkan"], +}; + +/** + * Fedora/RPM Fusion ships H.264/HEVC VA-API in dri-freeworld (patent-encumbered), while + * stock /usr/lib64/dri only exposes MPEG2/JPEG. Prefer freeworld so chrome://gpu lists + * real encode/decode profiles instead of an empty Video Acceleration Information block. + */ +export function configureLinuxVaapiEnvironment(): void { + if (process.platform !== "linux") return; + + const candidates = [ + "/usr/lib64/dri-freeworld", + "/usr/lib64/dri-nonfree", + "/usr/lib/dri-freeworld", + "/usr/lib/dri-nonfree", + ]; + const preferred = candidates.filter((dir) => existsSync(dir)); + if (preferred.length === 0) return; + + const stock = ["/usr/lib64/dri", "/usr/lib/dri"].filter((dir) => existsSync(dir)); + const parts = [...preferred, ...stock]; + const existing = process.env.LIBVA_DRIVERS_PATH; + process.env.LIBVA_DRIVERS_PATH = existing ? `${parts.join(":")}:${existing}` : parts.join(":"); + console.log(`VAAPI: using LIBVA_DRIVERS_PATH=${process.env.LIBVA_DRIVERS_PATH}`); +} + +/** Strip Linux encode features that shared presets may have enabled. */ +function withoutLinuxHwEncode(preset: Preset): Preset { + const block = new Set(["AcceleratedVideoEncoder", "VaapiVideoEncoder", "WebRtcHWEncoding"]); + return { + switches: preset.switches, + enableFeatures: preset.enableFeatures.filter((f) => !block.has(f)), + disableFeatures: [...new Set([...preset.disableFeatures, ...block])], + }; +} + +/** + * Apply the platform-tested WebRTC / screenshare encode+decode stack. + * macOS → VideoToolbox; Windows → Chromium HW encode; Linux → VAAPI toggle. + */ +function applyPlatformVideoStack(base: Preset | undefined): Preset | undefined { + if (!getConfig("hardwareAcceleration")) return base; + + const preset = base ? mergePresets(base, webrtcHwCommon) : webrtcHwCommon; + console.log("WebRTC HW baseline enabled"); + + switch (process.platform) { + case "darwin": + console.log("macOS VideoToolbox HW encode/decode flags enabled"); + return mergePresets(preset, macVideoToolbox); + case "win32": + console.log("Windows HW video encode flags enabled"); + return mergePresets(preset, winVideoEncode); + case "linux": + if (getConfig("vaapi")) { + console.log("Linux VAAPI HW encode/decode flags enabled"); + configureLinuxVaapiEnvironment(); + return mergePresets(preset, linuxVaapi); + } + console.log("Linux VAAPI off — forcing software WebRTC video encode"); + return withoutLinuxHwEncode(mergePresets(preset, linuxSoftwareVideoEncode)); + default: + // Other Unix-likes: keep decode baseline; enable generic HW encode. + return mergePresets(preset, winVideoEncode); + } +} + /** * Load custom flags from JSON file in user data directory (cached after first load) * Path: @@ -160,6 +384,14 @@ function mergeWithCustomFlags(preset: Preset): Preset { }; } +function mergePresets(base: Preset, extra: Preset): Preset { + return { + switches: [...base.switches, ...extra.switches], + enableFeatures: [...base.enableFeatures, ...extra.enableFeatures], + disableFeatures: [...base.disableFeatures, ...extra.disableFeatures], + }; +} + export function getPreset(): Preset | undefined { // MIT License @@ -182,31 +414,58 @@ export function getPreset(): Preset | undefined { // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. - if (getConfig("vaapi")) { - console.log("VAAPI mode enabled"); - mergeWithCustomFlags(vaapi); - } + let preset: Preset | undefined; + switch (getConfig("performanceMode")) { case "dynamic": if (powerMonitor.isOnBatteryPower()) { console.log("Battery mode enabled"); - return mergeWithCustomFlags(battery); + preset = battery; } else { console.log("Performance mode enabled"); - return mergeWithCustomFlags(performance); + preset = performance; } + break; case "performance": console.log("Performance mode enabled"); - return mergeWithCustomFlags(performance); + preset = performance; + break; + case "balanced": + console.log("Balanced mode enabled"); + preset = balanced; + break; case "battery": console.log("Battery mode enabled"); - return mergeWithCustomFlags(battery); + preset = battery; + break; + case "memory": + console.log("Memory saver mode enabled"); + preset = memory; + break; + case "voip": + console.log("Voice & video mode enabled"); + preset = voip; + break; + case "latency": + console.log("Low latency mode enabled"); + preset = latency; + break; case "smoothScreenshare": console.log("Smooth screenshare mode enabled"); - return mergeWithCustomFlags(smoothExperiment); + preset = smoothExperiment; + break; default: console.log("No performance modes set"); } + + // Platform-specific video encode/decode (macOS VideoToolbox / Win HW / Linux VAAPI). + // Shared voip/smoothScreenshare presets must not carry Linux-only or cross-platform + // encode flags that would undermine the macOS stack we just fixed. + preset = applyPlatformVideoStack(preset); + + if (preset) { + return mergeWithCustomFlags(preset); + } } /** diff --git a/src/common/handleCommands.ts b/src/common/handleCommands.ts new file mode 100644 index 0000000..c9cd3f1 --- /dev/null +++ b/src/common/handleCommands.ts @@ -0,0 +1,86 @@ +import { actionDescriptions, ValidActions } from "./commandDefinitions"; +import { deafenToggle, leaveCall, muteToggle, openSettings } from "./keybindActions"; + +export function isValidAction(value: string): value is ValidActions { + return Object.values(ValidActions).some((action) => value.includes(action)); +} + +function findValidAction(str: string): ValidActions | undefined { + return Object.values(ValidActions).find((action) => str.includes(action)); +} + +function sanitizeArguments(args: string[]): string[] { + return args.filter((arg) => arg.startsWith("--")).map((arg) => arg.replace("--", "")); +} + +/** + * Did the user pass any valid argument? + * + * @export + * @param {string[]} args List of arguments to validate + * @return {*} {boolean} + */ +export function passedValidArgument(args: string[]): boolean { + if (args.find((arg) => findValidAction(arg))) return true; + return false; +} + +export function handleAction(action: ValidActions): void { + switch (action) { + case ValidActions.mute: + muteToggle(); + break; + case ValidActions.deafen: + deafenToggle(); + break; + case ValidActions.leaveCall: + leaveCall(); + break; + case ValidActions.openSettings: + openSettings(); + break; + case ValidActions.help: + showHelpMessage(); + break; + default: { + // be completly sure we exaust every action possible at compile-time. + const exhaustiveCheck: never = action; + throw new Error(`Unhandled action: ${exhaustiveCheck}`); + } + } +} + +/** + * Handles command line arguments and applies actions accordingly, without spawning a new Legcord instance. + * + * @export + * @param {string[]} args List of all arguments to treat as possible commands + */ +export function handleCommands(args: string[]): void { + const sanitazed_args = sanitizeArguments(args); + const handledActions = new Set(); + + sanitazed_args.forEach((arg) => { + if (!arg) return; + + if (!isValidAction(arg)) return; + + const action = findValidAction(arg); + if (!action || handledActions.has(action)) return; + + console.log(`valid action: ${arg}`); + handledActions.add(action); + handleAction(action); + }); +} + +function showHelpMessage(): void { + const entries = Object.entries(actionDescriptions); + const width = Math.max(...entries.map(([cmd]) => cmd.length)); + + console.log("\nAvailable commands (ignore '--' if over dbus):\n"); + for (const [cmd, description] of entries) { + console.log(` --${cmd.padEnd(width)} ${description}`); + } + console.log(""); +} diff --git a/src/common/keybindActions.ts b/src/common/keybindActions.ts index 563451f..6534010 100644 --- a/src/common/keybindActions.ts +++ b/src/common/keybindActions.ts @@ -2,6 +2,8 @@ import path from "node:path"; import { app, shell } from "electron"; import type { Keybind } from "../@types/keybind.js"; import { mainWindows } from "../discord/window.js"; +import { navigateTo } from "./dom.js"; + let isAudioEngineEnabled = false; export function runAction(keybind: Keybind) { @@ -27,6 +29,9 @@ export function runAction(keybind: Keybind) { case "openQuickCss": openQuickCss(); break; + case "openSettings": + openSettings(); + break; case "runJavascript": if (!keybind.js) break; runJavascript(keybind.js); @@ -122,3 +127,10 @@ function runJavascript(js: string) { window.webContents.executeJavaScript(js); }); } + +export function openSettings() { + // won't load the correct page anyway (will just do /account) cause shelter doesn't hijack discord's routing + mainWindows.forEach((window) => { + navigateTo(window, "/settings/legcord-settings"); + }); +} diff --git a/src/common/proxy.ts b/src/common/proxy.ts new file mode 100644 index 0000000..564a9bc --- /dev/null +++ b/src/common/proxy.ts @@ -0,0 +1,201 @@ +import { app, type ProxyConfig, session } from "electron"; +import type { ProxyMode } from "../@types/settings.js"; +import { getConfig } from "./config.js"; + +function envProxy(): string | undefined { + return process.env.HTTPS_PROXY || process.env.https_proxy || process.env.HTTP_PROXY || process.env.http_proxy; +} + +function envNoProxy(): string | undefined { + return process.env.NO_PROXY || process.env.no_proxy; +} + +/** Convert Chromium-style bypass list to NO_PROXY form. */ +function toNoProxy(bypass: string): string { + return bypass + .split(/[,;]/) + .map((part) => part.trim()) + .filter(Boolean) + .map((part) => { + if (part === "") return "localhost,127.0.0.1,::1"; + return part.replace(/^\*\./, "."); + }) + .join(","); +} + +/** Pick a single proxy URL Node fetch can use from Chromium proxyRules. */ +function primaryProxyFromRules(rules: string): string | undefined { + const trimmed = rules.trim(); + if (!trimmed) return undefined; + + // Prefer an explicit https=/http=/socks= mapping, else first token. + const parts = trimmed + .split(";") + .map((p) => p.trim()) + .filter(Boolean); + for (const scheme of ["https", "http", "socks", "socks5", "socks4"]) { + const match = parts.find((p) => p.toLowerCase().startsWith(`${scheme}=`)); + if (match) { + const value = match + .slice(scheme.length + 1) + .split(",")[0] + ?.trim(); + if (value && value !== "direct://") return value.includes("://") ? value : `http://${value}`; + } + } + + const first = parts[0]?.split(",")[0]?.trim(); + if (!first || first === "direct://") return undefined; + if (first.includes("=")) { + const value = first.split("=")[1]?.trim(); + if (!value || value === "direct://") return undefined; + return value.includes("://") ? value : `http://${value}`; + } + return first.includes("://") ? first : `http://${first}`; +} + +function resolveProxyConfig(): ProxyConfig { + const mode = getConfig("proxyMode") as ProxyMode | undefined; + const proxyRules = (getConfig("proxyRules") ?? "").trim(); + const proxyBypassRules = (getConfig("proxyBypassRules") ?? "").trim(); + const proxyPacScript = (getConfig("proxyPacScript") ?? "").trim(); + + switch (mode) { + case "direct": + return { mode: "direct" }; + case "auto_detect": + return { + mode: "auto_detect", + ...(proxyBypassRules ? { proxyBypassRules } : {}), + }; + case "pac_script": + return { + mode: "pac_script", + pacScript: proxyPacScript, + ...(proxyBypassRules ? { proxyBypassRules } : {}), + }; + case "fixed_servers": + return { + mode: "fixed_servers", + proxyRules, + ...(proxyBypassRules ? { proxyBypassRules } : {}), + }; + default: { + // system — also honor HTTP(S)_PROXY so env-based setups work for Chromium + const fromEnv = envProxy(); + if (fromEnv) { + return { + mode: "fixed_servers", + proxyRules: fromEnv, + proxyBypassRules: proxyBypassRules || toNoProxy(envNoProxy() ?? ""), + }; + } + return { + mode: "system", + ...(proxyBypassRules ? { proxyBypassRules } : {}), + }; + } + } +} + +/** + * Configure Node.js fetch / http to honor proxy env vars, and sync env from settings + * when using a fixed proxy. Must run before main-process network (e.g. mod downloads). + */ +export function configureNodeProxyEnv(): void { + process.env.NODE_USE_ENV_PROXY = "1"; + + const mode = (getConfig("proxyMode") as ProxyMode | undefined) ?? "system"; + + if (mode === "direct") { + // Force no proxy for Node fetches + process.env.HTTP_PROXY = ""; + process.env.HTTPS_PROXY = ""; + process.env.http_proxy = ""; + process.env.https_proxy = ""; + process.env.NO_PROXY = "*"; + process.env.no_proxy = "*"; + console.log("[Proxy] Node fetch: direct (no proxy)"); + return; + } + + if (mode === "fixed_servers") { + const rules = (getConfig("proxyRules") ?? "").trim(); + const proxyUrl = primaryProxyFromRules(rules); + if (proxyUrl) { + process.env.HTTP_PROXY = proxyUrl; + process.env.HTTPS_PROXY = proxyUrl; + process.env.http_proxy = proxyUrl; + process.env.https_proxy = proxyUrl; + const bypass = (getConfig("proxyBypassRules") ?? "").trim(); + if (bypass) { + const noProxy = toNoProxy(bypass); + process.env.NO_PROXY = noProxy; + process.env.no_proxy = noProxy; + } + console.log(`[Proxy] Node fetch: ${proxyUrl}`); + return; + } + } + + // system / pac / auto_detect — keep existing env (HTTPS_PROXY etc.) + if (envProxy()) { + console.log(`[Proxy] Node fetch: using environment proxy (${envProxy()})`); + } else { + console.log("[Proxy] Node fetch: no HTTP(S)_PROXY in environment"); + } +} + +/** + * Apply Chromium command-line proxy switches early (before app ready). + * Session.setProxy still runs later for the authoritative config. + */ +export function applyProxyCommandLineSwitches(): void { + const mode = (getConfig("proxyMode") as ProxyMode | undefined) ?? "system"; + const proxyRules = (getConfig("proxyRules") ?? "").trim(); + const proxyBypassRules = (getConfig("proxyBypassRules") ?? "").trim(); + const proxyPacScript = (getConfig("proxyPacScript") ?? "").trim(); + + if (mode === "direct") { + app.commandLine.appendSwitch("no-proxy-server"); + return; + } + + if (mode === "auto_detect") { + app.commandLine.appendSwitch("proxy-auto-detect"); + if (proxyBypassRules) app.commandLine.appendSwitch("proxy-bypass-list", proxyBypassRules); + return; + } + + if (mode === "pac_script" && proxyPacScript) { + app.commandLine.appendSwitch("proxy-pac-url", proxyPacScript); + if (proxyBypassRules) app.commandLine.appendSwitch("proxy-bypass-list", proxyBypassRules); + return; + } + + if (mode === "fixed_servers" && proxyRules) { + app.commandLine.appendSwitch("proxy-server", proxyRules); + if (proxyBypassRules) app.commandLine.appendSwitch("proxy-bypass-list", proxyBypassRules); + return; + } + + // system — if HTTPS_PROXY is set, push it to Chromium too + const fromEnv = envProxy(); + if (fromEnv) { + app.commandLine.appendSwitch("proxy-server", fromEnv); + const bypass = proxyBypassRules || toNoProxy(envNoProxy() ?? ""); + app.commandLine.appendSwitch("proxy-bypass-list", bypass); + } +} + +/** Apply proxy to the default session once Electron is ready. */ +export async function applySessionProxy(): Promise { + const config = resolveProxyConfig(); + console.log(`[Proxy] Applying session proxy: ${JSON.stringify(config)}`); + try { + await session.defaultSession.setProxy(config); + await session.defaultSession.closeAllConnections(); + } catch (error) { + console.error("[Proxy] Failed to apply session proxy:", error); + } +} diff --git a/src/common/sanitization.ts b/src/common/sanitization.ts new file mode 100644 index 0000000..a5c69a1 --- /dev/null +++ b/src/common/sanitization.ts @@ -0,0 +1,88 @@ +/** True when hostname is exactly `domain` or a subdomain of it (case-insensitive). */ +export function hostnameMatches(hostname: string, domain: string): boolean { + const host = hostname.toLowerCase(); + const target = domain.toLowerCase(); + return host === target || host.endsWith(`.${target}`); +} + +export function tryParseUrl(urlString: string): URL | null { + try { + return new URL(urlString); + } catch { + return null; + } +} + +/** True when the frame is a YouTube embed (or Discord Activities YouTube proxy). */ +export function isYouTubeEmbedOrProxyFrame(frameUrl: string): boolean { + const url = tryParseUrl(frameUrl); + if (!url) return false; + + if (hostnameMatches(url.hostname, "youtube.com") && url.pathname.includes("/embed/")) { + return true; + } + + // Discord Activities may proxy YouTube through *.discordsays.com (youtube.com appears in the path/query) + if ( + hostnameMatches(url.hostname, "discordsays.com") && + (url.pathname.includes("youtube.com") || url.search.includes("youtube.com")) + ) { + return true; + } + + return false; +} + +/** Telemetry / noise hosts and Discord science endpoints we cancel in webRequest. */ +export function isTelemetryBlockedUrl(requestUrl: string): boolean { + const url = tryParseUrl(requestUrl); + if (url?.protocol !== "https:") return false; + + if (/^\/api\/v\d+\/science(?:\/|$)/.test(url.pathname)) return true; + if (hostnameMatches(url.hostname, "sentry.io")) return true; + if (hostnameMatches(url.hostname, "nel.cloudflare.com")) return true; + + return false; +} + +/** + * Blob downloads for Discord calendar (.ics) use `blob:https://discord.com/`. + * Parse the blob payload URL so `discord.com.evil` / userinfo tricks cannot match. + */ +export function isDiscordIcsBlobUrl(urlString: string): boolean { + const blobUrl = tryParseUrl(urlString); + if (blobUrl?.protocol !== "blob:") return false; + + const inner = tryParseUrl(blobUrl.pathname); + if (!inner || (inner.protocol !== "https:" && inner.protocol !== "http:")) return false; + + return hostnameMatches(inner.hostname, "discord.com"); +} + +/** Discord stream popout windows (stable / canary / PTB). */ +export function isDiscordPopoutUrl(urlString: string): boolean { + const url = tryParseUrl(urlString); + if (url?.protocol !== "https:" || url.pathname !== "/popout") return false; + + const host = url.hostname.toLowerCase(); + return host === "discord.com" || host === "canary.discord.com" || host === "ptb.discord.com"; +} + +const DEFAULT_ALLOWED_LOCALHOST_WS_PORTS = new Set([1211, 1112, 6888]); + +/** + * Block stray localhost WebSocket probes, except known Legcord/local RPC ports. + * Uses URL parsing instead of substring checks on the raw request URL. + */ +export function isBlockedLocalhostWebSocket( + requestUrl: string, + allowedPorts: ReadonlySet = DEFAULT_ALLOWED_LOCALHOST_WS_PORTS, +): boolean { + const url = tryParseUrl(requestUrl); + if (!url || (url.protocol !== "ws:" && url.protocol !== "wss:")) return false; + if (url.hostname !== "127.0.0.1" && url.hostname !== "localhost") return false; + + const port = url.port ? Number(url.port) : url.protocol === "wss:" ? 443 : 80; + if (!Number.isFinite(port)) return true; + return !allowedPorts.has(port); +} diff --git a/src/common/themes.ts b/src/common/themes.ts index 05efd63..8a79dce 100644 --- a/src/common/themes.ts +++ b/src/common/themes.ts @@ -1,6 +1,6 @@ import fs from "node:fs"; import path from "node:path"; -import { type BrowserWindow, app } from "electron"; +import { app, type BrowserWindow } from "electron"; import type { ThemeManifest } from "../@types/themeManifest.js"; import { mainWindows } from "../discord/window.js"; import { getConfig } from "./config.js"; @@ -112,6 +112,111 @@ function getThemeManifest(themeId: string): ThemeManifest | null { } } +// Performance optimization: Cached theme list with directory watcher +const THEME_LIST_CACHE_TTL = 2000; +let themeListCache: ThemeManifest[] | null = null; +let themeListCacheTime = 0; +let themeWatcher: fs.FSWatcher | null = null; +let themeListRefreshTimeout: NodeJS.Timeout | null = null; + +function importLooseThemeFiles(): void { + try { + if (!fs.existsSync(themesFolder)) return; + const entries = fs.readdirSync(themesFolder); + for (const entry of entries) { + const entryPath = path.join(themesFolder, entry); + const stat = fs.statSync(entryPath); + if (stat.isFile() && (entry.endsWith(".css") || entry.endsWith(".theme.css"))) { + const code = fs.readFileSync(entryPath, "utf8"); + installThemeFromCode(code); + try { + fs.unlinkSync(entryPath); + } catch {} + } + } + } catch (err) { + console.error("[Theme Manager] Failed to import loose theme files:", err); + } +} + +function refreshThemeListCache(): ThemeManifest[] { + try { + if (!fs.existsSync(themesFolder)) { + themeListCache = []; + themeListCacheTime = Date.now(); + return themeListCache; + } + const themes: ThemeManifest[] = []; + const entries = fs.readdirSync(themesFolder); + for (const entry of entries) { + const manifestPath = path.join(themesFolder, entry, "manifest.json"); + if (fs.existsSync(manifestPath)) { + const manifest = getThemeManifest(entry); + if (manifest) { + themes.push({ ...manifest, id: entry }); + } + } + } + themeListCache = themes; + themeListCacheTime = Date.now(); + return themes; + } catch (err) { + console.error("[Theme Manager] Failed to refresh theme list cache:", err); + return themeListCache ?? []; + } +} + +export function getCachedThemeList(): ThemeManifest[] { + const now = Date.now(); + if (themeListCache && now - themeListCacheTime < THEME_LIST_CACHE_TTL) { + return themeListCache; + } + importLooseThemeFiles(); + return refreshThemeListCache(); +} + +export function invalidateThemeListCache(): void { + themeListCache = null; +} + +function debouncedRefreshThemeList(): void { + if (themeListRefreshTimeout) { + clearTimeout(themeListRefreshTimeout); + } + themeListRefreshTimeout = setTimeout(() => { + refreshThemeListCache(); + themeListRefreshTimeout = null; + }, 500); +} + +export function startThemeWatcher(): void { + if (themeWatcher) return; + try { + if (!fs.existsSync(themesFolder)) { + fs.mkdirSync(themesFolder, { recursive: true }); + } + themeWatcher = fs.watch(themesFolder, { recursive: true }, (eventType, filename) => { + if (filename && (filename.endsWith("manifest.json") || eventType === "rename")) { + debouncedRefreshThemeList(); + } + }); + refreshThemeListCache(); + } catch (err) { + console.error("[Theme Manager] Failed to start theme watcher:", err); + } +} + +export function stopThemeWatcher(): void { + if (themeWatcher) { + themeWatcher.close(); + themeWatcher = null; + } + if (themeListRefreshTimeout) { + clearTimeout(themeListRefreshTimeout); + themeListRefreshTimeout = null; + } +} + export function injectThemesMain(browserWindow: BrowserWindow): void { if (process.argv.includes("--safe-mode")) return; if (!fs.existsSync(themesFolder)) { @@ -123,11 +228,13 @@ export function injectThemesMain(browserWindow: BrowserWindow): void { const files = fs.readdirSync(themesFolder); for (const file of files) { const themePath = path.join(themesFolder, file); - if (fs.statSync(themePath).isFile() && file.endsWith(".DS_Store")) { + if (fs.statSync(themePath).isFile() && (file.endsWith(".css") || file.endsWith(".theme.css"))) { console.log(`[Theme Manager] Local theme detected: ${themePath}`); - installTheme(themePath).then(() => { + const code = fs.readFileSync(themePath, "utf8"); + installThemeFromCode(code); + try { fs.unlinkSync(themePath); - }); + } catch {} } else { try { const themeFile = getThemeManifest(file); @@ -168,10 +275,11 @@ export function uninstallTheme(id: string) { fs.rmdirSync(path.join(themesFolder, `${id}-BD`), { recursive: true }); console.log(`Removed ${id} folder`); } + themeManifestCache.delete(id); + invalidateThemeListCache(); } export function setThemeEnabled(id: string, enabled: boolean) { - // Performance optimization: Use cached manifest if available let manifest = getThemeManifest(id); if (!manifest) { manifest = JSON.parse(fs.readFileSync(path.join(themesFolder, id, "/manifest.json"), "utf8")) as ThemeManifest; @@ -190,13 +298,31 @@ export function setThemeEnabled(id: string, enabled: boolean) { passedWindow.webContents.send("removeTheme", id); console.log(`[Theme Manager] Removing ${manifest.name} made by ${manifest.author}`); } + return true; }); } manifest.enabled = enabled; fs.writeFileSync(`${themesFolder}/${id}/manifest.json`, JSON.stringify(manifest)); - // Performance optimization: Invalidate cache themeManifestCache.delete(id); + invalidateThemeListCache(); +} + +function installThemeFromCode(code: string, linkOrPath?: string): void { + const manifest = parseBDManifest(code); + const themePath = path.join(themesFolder, `${manifest.name?.replace(" ", "-")}-BD`); + if (!fs.existsSync(themePath)) { + fs.mkdirSync(themePath); + console.log(`Created ${manifest.name} folder`); + } + if (linkOrPath && manifest.updateSrc === undefined) { + manifest.updateSrc = linkOrPath; + } + if (code.includes(".titlebar")) manifest.supportsLegcordTitlebar = true; + else manifest.supportsLegcordTitlebar = false; + fs.writeFileSync(path.join(themePath, "manifest.json"), JSON.stringify(manifest)); + fs.writeFileSync(path.join(themePath, "src.css"), code); + invalidateThemeListCache(); } export async function installTheme(linkOrPath: string) { @@ -208,19 +334,7 @@ export async function installTheme(linkOrPath: string) { } else { code = fs.readFileSync(linkOrPath, "utf8"); } - const manifest = parseBDManifest(code); - const themePath = path.join(themesFolder, `${manifest.name?.replace(" ", "-")}-BD`); - if (!fs.existsSync(themePath)) { - fs.mkdirSync(themePath); - console.log(`Created ${manifest.name} folder`); - } - if (isLinkImport && manifest.updateSrc === undefined) { - manifest.updateSrc = linkOrPath; - } - if (code.includes(".titlebar")) manifest.supportsLegcordTitlebar = true; - else manifest.supportsLegcordTitlebar = false; - fs.writeFileSync(path.join(themePath, "manifest.json"), JSON.stringify(manifest)); - fs.writeFileSync(path.join(themePath, "src.css"), code); + installThemeFromCode(code, isLinkImport ? linkOrPath : undefined); } export function initQuickCss(browserWindow: BrowserWindow) { diff --git a/src/common/windowBounds.ts b/src/common/windowBounds.ts new file mode 100644 index 0000000..0b8de5c --- /dev/null +++ b/src/common/windowBounds.ts @@ -0,0 +1,169 @@ +import type { Display, Rectangle } from "electron"; + +export const DEFAULT_WINDOW_WIDTH = 835; +export const DEFAULT_WINDOW_HEIGHT = 600; +export const MIN_WINDOW_WIDTH = 400; +export const MIN_WINDOW_HEIGHT = 300; + +/** At least this much of the window must sit inside the workArea to count as visible. */ +const MIN_VISIBLE_PX = 50; + +export type WindowBoundsInput = { + width?: unknown; + height?: unknown; + x?: unknown; + y?: unknown; + displayId?: unknown; +}; + +export type SanitizedWindowBounds = { + x: number; + y: number; + width: number; + height: number; + displayId: number; + displayScaleFactor: number; + usedFallback: boolean; +}; + +function isFiniteNumber(value: unknown): value is number { + return typeof value === "number" && Number.isFinite(value); +} + +function clamp(value: number, min: number, max: number): number { + return Math.min(Math.max(value, min), max); +} + +function intersectsWorkArea(rect: Rectangle, workArea: Rectangle, minVisible: number): boolean { + const left = Math.max(rect.x, workArea.x); + const top = Math.max(rect.y, workArea.y); + const right = Math.min(rect.x + rect.width, workArea.x + workArea.width); + const bottom = Math.min(rect.y + rect.height, workArea.y + workArea.height); + const visibleW = Math.max(0, right - left); + const visibleH = Math.max(0, bottom - top); + return visibleW >= minVisible && visibleH >= minVisible; +} + +function fitSizeToWorkArea(width: number, height: number, workArea: Rectangle): { width: number; height: number } { + const fittedWidth = Math.min(Math.max(width, MIN_WINDOW_WIDTH), Math.max(workArea.width, MIN_WINDOW_WIDTH)); + const fittedHeight = Math.min(Math.max(height, MIN_WINDOW_HEIGHT), Math.max(workArea.height, MIN_WINDOW_HEIGHT)); + // Prefer staying within the workArea when it is at least the minimum size. + return { + width: workArea.width >= MIN_WINDOW_WIDTH ? Math.min(fittedWidth, workArea.width) : fittedWidth, + height: workArea.height >= MIN_WINDOW_HEIGHT ? Math.min(fittedHeight, workArea.height) : fittedHeight, + }; +} + +function fitRectToWorkArea( + width: number, + height: number, + x: number | undefined, + y: number | undefined, + workArea: Rectangle, +): Rectangle { + const { width: fittedWidth, height: fittedHeight } = fitSizeToWorkArea(width, height, workArea); + + const maxX = workArea.x + Math.max(0, workArea.width - fittedWidth); + const maxY = workArea.y + Math.max(0, workArea.height - fittedHeight); + + if (isFiniteNumber(x) && isFiniteNumber(y)) { + const candidate = { x, y, width: fittedWidth, height: fittedHeight }; + if (intersectsWorkArea(candidate, workArea, MIN_VISIBLE_PX)) { + return { + x: clamp(x, workArea.x, maxX), + y: clamp(y, workArea.y, maxY), + width: fittedWidth, + height: fittedHeight, + }; + } + } + + // Missing / off-screen coords — center on this display. + return { + x: workArea.x + Math.round((workArea.width - fittedWidth) / 2), + y: workArea.y + Math.round((workArea.height - fittedHeight) / 2), + width: fittedWidth, + height: fittedHeight, + }; +} + +function findDisplayForPoint(displays: Display[], x: number, y: number): Display | undefined { + const containing = displays.find( + (d) => + x >= d.bounds.x && y >= d.bounds.y && x < d.bounds.x + d.bounds.width && y < d.bounds.y + d.bounds.height, + ); + if (containing) return containing; + + let best: Display | undefined; + let bestDist = Number.POSITIVE_INFINITY; + for (const d of displays) { + const cx = clamp(x, d.bounds.x, d.bounds.x + d.bounds.width); + const cy = clamp(y, d.bounds.y, d.bounds.y + d.bounds.height); + const dx = x - cx; + const dy = y - cy; + const dist = dx * dx + dy * dy; + if (dist < bestDist) { + bestDist = dist; + best = d; + } + } + return best; +} + +/** + * Sanitize saved/live window bounds so the window is always a usable size + * and visible on a connected display (preferring the remembered displayId). + */ +export function sanitizeWindowBounds(input: WindowBoundsInput, displays: Display[]): SanitizedWindowBounds { + const list = displays.length > 0 ? displays : []; + let usedFallback = false; + + let width = isFiniteNumber(input.width) ? input.width : DEFAULT_WINDOW_WIDTH; + let height = isFiniteNumber(input.height) ? input.height : DEFAULT_WINDOW_HEIGHT; + if (!isFiniteNumber(input.width) || !isFiniteNumber(input.height)) { + usedFallback = true; + } + width = Math.max(MIN_WINDOW_WIDTH, width); + height = Math.max(MIN_WINDOW_HEIGHT, height); + + const savedDisplayId = isFiniteNumber(input.displayId) ? input.displayId : undefined; + const x = isFiniteNumber(input.x) ? input.x : undefined; + const y = isFiniteNumber(input.y) ? input.y : undefined; + + let target: Display | undefined; + if (savedDisplayId !== undefined) { + target = list.find((d) => d.id === savedDisplayId); + if (!target) usedFallback = true; + } + if (!target && x !== undefined && y !== undefined && list.length > 0) { + target = findDisplayForPoint(list, x, y); + } + if (!target) { + target = list[0]; + usedFallback = true; + } + + if (!target) { + return { + x: 0, + y: 0, + width, + height, + displayId: 0, + displayScaleFactor: 1, + usedFallback: true, + }; + } + + const fitted = fitRectToWorkArea(width, height, x, y, target.workArea); + + return { + x: fitted.x, + y: fitted.y, + width: fitted.width, + height: fitted.height, + displayId: target.id, + displayScaleFactor: target.scaleFactor, + usedFallback, + }; +} diff --git a/src/common/windowState.ts b/src/common/windowState.ts index 9ff063b..7350856 100644 --- a/src/common/windowState.ts +++ b/src/common/windowState.ts @@ -6,7 +6,7 @@ import type { WindowState } from "../@types/windowState.js"; // Performance optimization: Cache window state to avoid reading file on every call let windowStateCache: WindowState | null = null; let windowStateCacheTime = 0; -const WINDOW_STATE_CACHE_TTL = 1000; // Cache for 1 second +const WINDOW_STATE_CACHE_TTL = 5000; // Cache for 5 seconds export function getWindowStateLocation() { const userDataPath = app.getPath("userData"); diff --git a/src/common/windowVisibility.ts b/src/common/windowVisibility.ts new file mode 100644 index 0000000..f3718e8 --- /dev/null +++ b/src/common/windowVisibility.ts @@ -0,0 +1,37 @@ +import type { BrowserWindow } from "electron"; +import { getConfig, getStartMinimizedMode } from "./config.js"; + +/** Show the main window and restore taskbar/dock presence after a tray-only start. */ +export function revealWindow(win: BrowserWindow): void { + if (win.isDestroyed()) return; + win.setSkipTaskbar(false); + if (win.isMinimized()) win.restore(); + win.show(); + win.focus(); +} + +/** Apply startMinimized mode when splash will not call splashEnd, or from splashEnd itself. */ +export function applyStartupWindowVisibility(win: BrowserWindow): void { + if (win.isDestroyed()) return; + const mode = getStartMinimizedMode(); + switch (mode) { + case "minimized": + win.setSkipTaskbar(false); + win.show(); + win.minimize(); + break; + case "tray": + if (getConfig("tray") === "disabled") { + console.warn( + '[Window] startMinimized is "tray" but the tray icon is disabled; the window will be hidden with no tray.', + ); + } + win.setSkipTaskbar(true); + win.hide(); + break; + default: + win.setSkipTaskbar(false); + win.show(); + break; + } +} diff --git a/src/cssEditor/editor.html b/src/cssEditor/editor.html index 86aa1a1..a02d850 100644 --- a/src/cssEditor/editor.html +++ b/src/cssEditor/editor.html @@ -1,36 +1,37 @@ - + Legcord Quick CSS Editor - +
- \ No newline at end of file + diff --git a/src/cssEditor/main.ts b/src/cssEditor/main.ts index c6609cd..9f20e16 100644 --- a/src/cssEditor/main.ts +++ b/src/cssEditor/main.ts @@ -14,7 +14,7 @@ export function openCssEditor(file: string) { preload: path.join(import.meta.dirname, "cssEditor", "preload.mjs"), }, }); - cssWindow.loadURL(`file://${import.meta.dirname}/html/editor.html`); + void cssWindow.loadFile(path.join(import.meta.dirname, "html", "editor.html")); ipcMain.on("editor-setCSS", (_event, css: string) => { fs.writeFileSync(file, css); diff --git a/src/dbus.ts b/src/dbus.ts new file mode 100644 index 0000000..ea25a0e --- /dev/null +++ b/src/dbus.ts @@ -0,0 +1,186 @@ +import { existsSync, mkdirSync, writeFileSync } from "node:fs"; +import { homedir } from "node:os"; +import { join } from "node:path"; +import { + interface as dbusInterface, + type MessageBus, + type ProxyInterface, + sessionBus, + Variant, +} from "@jellybrick/dbus-next"; +import { ACTION_FRIENDLY_NAMES, EXCLUDED_FROM_SHORTCUTS, ValidActions } from "./common/commandDefinitions"; +import { handleAction, isValidAction } from "./common/handleCommands"; + +const { Interface } = dbusInterface; + +export const DBUS_INTERFACE_NAME = "app.legcord.Legcord"; +export const DBUS_ADDRESS = "/app/legcord/Legcord"; + +const FREEDESKTOP_PORTAL_NAME = "org.freedesktop.portal.Desktop"; +const FREEDESKTOP_PORTAL_ADDRESS = "/org/freedesktop/portal/desktop"; + +const isLinux = process.platform === "linux"; + +// https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.GlobalShortcuts.html +type Shortcuts = [string, { description: Variant }]; +interface GlobalShortcuts extends ProxyInterface { + CreateSession(options: { handle_token: Variant; session_handle_token: Variant }): Promise; + + ConfigureShortcuts(session_handle: string, parent_window: string, options: object): Promise; + + BindShortcuts( + session_handle: string, + shortcuts: Shortcuts[], + parent_window: string, + options: { + handle_token: Variant; + }, + ): Promise; +} + +interface PropertiesInterface extends ProxyInterface { + Get(interface_name: string, property_name: string): Promise; + Set(interface_name: string, property_name: string, value: Variant): void; +} + +interface RegistryInterface extends ProxyInterface { + Register(app_id: string, options: object): void; +} + +// original way of doing it (requires extensive babel plugins and typescript decorators) +// class LegcordInterface extends Interface { +// @method({ inSignature: "s", outSignature: "", noReply: true, disabled: false }) +// TriggerAction(action: string): void { +// currentHandler(action); +// } +// } + +// THIS is nescessary only so we don't have to use babel +// plugins all over rolldown.config.ts in every file, and slow down build time. +// https://acrisci.github.io/doc/node-dbus-next/ +class LegcordInterface extends Interface { + constructor() { + super(DBUS_INTERFACE_NAME); + this.$methods = { + TriggerAction: { + name: "TriggerAction", + disabled: false, + noReply: true, + inSignature: "s", + outSignature: "", + inSignatureTree: [{ type: "s", child: [] }], + outSignatureTree: [], + fn: (action: string) => { + if (!isValidAction(action)) { + console.warn("Received unsupported action over DBus:", action); + return; + } + handleAction(action); + }, + }, + }; + } +} + +let bus: MessageBus | undefined; +let legcordInterface: LegcordInterface | undefined; + +function getBus(): MessageBus { + if (!bus) { + bus = sessionBus(); + legcordInterface = new LegcordInterface(); + } + return bus; +} + +function ensureDesktopFile(): void { + const dir = join(homedir(), ".local/share/applications"); + const path = join(dir, `${DBUS_INTERFACE_NAME}.desktop`); + if (existsSync(path)) return; + + mkdirSync(dir, { recursive: true }); + writeFileSync(path, `[Desktop Entry]\nType=Application\nName=Legcord\nExec=${process.execPath}\nNoDisplay=true\n`); +} + +function registerAppId(): Promise { + ensureDesktopFile(); // we need a desktop file at XDG_PATH so we can associate with legcord's app_id + return getBus() + .getProxyObject("org.freedesktop.portal.Desktop", "/org/freedesktop/portal/desktop") + .then((portalObj) => { + const registry: RegistryInterface = portalObj.getInterface("org.freedesktop.host.portal.Registry"); + return registry.Register(DBUS_INTERFACE_NAME, {}); + }); +} + +export async function setupGlobalShortcuts() { + if (!isLinux) return; + + const portalObj = await getBus().getProxyObject(FREEDESKTOP_PORTAL_NAME, FREEDESKTOP_PORTAL_ADDRESS); + + const properties: PropertiesInterface = portalObj.getInterface("org.freedesktop.DBus.Properties"); + const globalShortcuts: GlobalShortcuts = portalObj.getInterface("org.freedesktop.portal.GlobalShortcuts"); + + const freedesktopVersion = (await properties.Get("org.freedesktop.portal.GlobalShortcuts", "version")) + .value as number; + console.debug(`Connected with freedesktop portal version ${freedesktopVersion}`); + + await registerAppId(); + console.debug(`Registered ${DBUS_INTERFACE_NAME} in freedesktop Registry.`); + + function awaitResponse(requestPath: string): Promise> { + return getBus() + .getProxyObject(FREEDESKTOP_PORTAL_NAME, requestPath) + .then( + (requestObj) => + new Promise>((resolve, reject) => { + const requestIface = requestObj.getInterface("org.freedesktop.portal.Request"); + + requestIface.once("Response", (responseCode: number, results: Record) => { + if (responseCode === 0) resolve(results); + else reject(new Error(`Request failed with code ${responseCode}`)); + }); + }), + ); + } + + const sessionRequestPath = await globalShortcuts.CreateSession({ + handle_token: new Variant("s", "legcord_session"), + session_handle_token: new Variant("s", "legcord_shortcuts"), + }); + + const sessionResult = (await awaitResponse(sessionRequestPath)) as { session_handle: Variant }; // real response signature + + const actionList: [string, { description: Variant }][] = (Object.values(ValidActions) as ValidActions[]) + .filter((action) => !EXCLUDED_FROM_SHORTCUTS.includes(action)) + .map((action) => [action, { description: new Variant("s", ACTION_FRIENDLY_NAMES[action]) }]); + + const sessionHandle = sessionResult.session_handle.value; + const bindRequestPath = await globalShortcuts.BindShortcuts(sessionHandle, actionList, "", { + handle_token: new Variant("s", "legcord_bind"), + }); + + await awaitResponse(bindRequestPath); + + globalShortcuts.on("Activated", (activatedSession: string, shortcutId: string) => { + if (activatedSession !== sessionHandle || !isValidAction(shortcutId)) return; + handleAction(shortcutId); + }); +} + +export async function startDbusService(): Promise { + if (!isLinux) return; + + const dbus = getBus(); + await dbus.requestName(DBUS_INTERFACE_NAME); + dbus.export(DBUS_ADDRESS, legcordInterface!); + console.info(`Registered DBus service at ${DBUS_INTERFACE_NAME} ${DBUS_ADDRESS}`); + + // console.debug(legcordInterface) +} + +export function disconnectDbusService(): void { + if (!bus) return; + bus.disconnect(); + bus = undefined; + legcordInterface = undefined; +} diff --git a/src/discord/extensions/modloader.ts b/src/discord/extensions/modloader.ts index 1b2684b..98ee110 100644 --- a/src/discord/extensions/modloader.ts +++ b/src/discord/extensions/modloader.ts @@ -54,8 +54,7 @@ async function cacheCheck(mod: ValidMods) { } try { const latestRef = await getRef(modData[mod].repoData); - // biome-ignore lint/correctness/noConstantCondition: https://github.com/Legcord/Legcord/issues/763 - if (/*latestRef === modCache![mod]*/ false) { + if (latestRef === modCache![mod]) { console.log(`[Mod Loader]: ${mod} Cache hit!`); return; } else { diff --git a/src/discord/extensions/plugin.ts b/src/discord/extensions/plugin.ts index 818612b..96489b1 100644 --- a/src/discord/extensions/plugin.ts +++ b/src/discord/extensions/plugin.ts @@ -1,24 +1,25 @@ import { existsSync, mkdirSync, readdirSync } from "node:fs"; import { platform } from "node:os"; import { app, session } from "electron"; -const pluginFolder = `${app.getPath("userData")}/plugins`; + +const extensionFolder = `${app.getPath("userData")}/extensions`; let prefix = ""; -if (!existsSync(pluginFolder)) { - mkdirSync(pluginFolder); - console.log("Created missing plugin folder"); +if (!existsSync(extensionFolder)) { + mkdirSync(extensionFolder); + console.log("Created missing extensions folder"); } await app.whenReady().then(() => { - readdirSync(pluginFolder).forEach(async (file) => { + readdirSync(extensionFolder).forEach(async (file) => { try { // NOTE - The below type assertion is just what we need from the chrome manifest if (platform() === "win32") prefix = "file://"; - const manifest = (await import(`${prefix}${pluginFolder}/${file}/manifest.json`, { + const manifest = (await import(`${prefix}${extensionFolder}/${file}/manifest.json`, { with: { type: "json" }, })) as { name: string; author: string; type: "json" }; - void session.defaultSession.loadExtension(`${pluginFolder}/${file}`); // NOTE - Awaiting this will cause plugins to not inject + void session.defaultSession.loadExtension(`${extensionFolder}/${file}`); // NOTE - Awaiting this will cause plugins to not inject console.log(`[Mod loader] Loaded ${manifest.name} made by ${manifest.author}`); } catch (err) { console.error(err); diff --git a/src/discord/globalKeybinds.ts b/src/discord/globalKeybinds.ts index 40d6e76..c7b4ba4 100644 --- a/src/discord/globalKeybinds.ts +++ b/src/discord/globalKeybinds.ts @@ -19,7 +19,7 @@ export function registerGlobalKeybinds() { app.on("will-quit", () => { try { globalShortcut.unregisterAll(); - } catch (e) {} + } catch (_e) {} }); export function refreshGlobalKeybinds() { diff --git a/src/discord/ipc.ts b/src/discord/ipc.ts index d512d57..f576a4b 100644 --- a/src/discord/ipc.ts +++ b/src/discord/ipc.ts @@ -1,15 +1,15 @@ -import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs"; +import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs"; import os from "node:os"; import path from "node:path"; import type { Game } from "arrpc"; -import { type BrowserWindow, app, clipboard, dialog, ipcMain, shell } from "electron"; +import { app, BrowserWindow, clipboard, dialog, ipcMain, shell } from "electron"; import isDev from "electron-is-dev"; import type { Keybind } from "../@types/keybind.js"; import type { Settings } from "../@types/settings.js"; import type { ThemeManifest } from "../@types/themeManifest.js"; import { - type BackupSavePayload, applyBackupFromMap, + type BackupSavePayload, buildBackupZipBuffer, readBackupZipToMap, } from "../common/backup.js"; @@ -21,20 +21,32 @@ import { import { getConfig, getConfigLocation, setConfig, setConfigBulk } from "../common/config.js"; import { addDetectable, getDetectables, removeDetectable } from "../common/detectables.js"; import { getLang, getLangName, getRawLang, setLang } from "../common/lang.js"; -import { disableQuickCss, initQuickCss, installTheme, setThemeEnabled, uninstallTheme } from "../common/themes.js"; +import { + disableQuickCss, + getCachedThemeList, + initQuickCss, + installTheme, + invalidateThemeListCache, + setThemeEnabled, + startThemeWatcher, + uninstallTheme, +} from "../common/themes.js"; import { getDisplayVersion, getVersion } from "../common/version.js"; +import { applyStartupWindowVisibility, revealWindow } from "../common/windowVisibility.js"; import { openCssEditor } from "../cssEditor/main.js"; import { getAppliedFlags, handleRestart } from "../main.js"; import { isPowerSavingEnabled, setPowerSaving } from "../power.js"; import constPaths from "../shared/consts/paths.js"; import { splashWindow } from "../splash/main.js"; import { refreshGlobalKeybinds } from "./globalKeybinds.js"; +import { getRuntimeEntries, getRuntimeScript, listPlugins, reloadPlugin, setPluginEnabled } from "./plugins/manager.js"; import { processList, refreshProcessList } from "./rpcProcess.js"; import { importGuilds, mainTouchBar, setVoiceState, voiceTouchBar } from "./touchbar.js"; const userDataPath = app.getPath("userData"); const storagePath = path.join(userDataPath, "/storage/"); const themesPath = path.join(userDataPath, "/themes/"); +const extensionsPath = path.join(userDataPath, "/extensions/"); const pluginsPath = path.join(userDataPath, "/plugins/"); const pluginStoragePath = path.join(userDataPath, "/plugin-storage/"); const quickCssPath = path.join(userDataPath, "/quickCss.css"); @@ -58,7 +70,42 @@ function ifExistsRead(path: string): string | undefined { if (existsSync(path)) return readFileSync(path, "utf-8"); } +let ipcRegistered = false; + +const chromeInternalsWindows = new Map(); + +function openChromeInternalsPage(url: "chrome://webrtc-internals/" | "chrome://gpu/", title: string): void { + const existing = chromeInternalsWindows.get(url); + if (existing && !existing.isDestroyed()) { + if (existing.isMinimized()) existing.restore(); + existing.focus(); + return; + } + + const win = new BrowserWindow({ + width: 1100, + height: 800, + minWidth: 640, + minHeight: 480, + title, + autoHideMenuBar: true, + webPreferences: { + sandbox: true, + nodeIntegration: false, + contextIsolation: true, + }, + }); + void win.loadURL(url); + chromeInternalsWindows.set(url, win); + win.on("closed", () => { + chromeInternalsWindows.delete(url); + }); +} + export function registerIpc(passedWindow: BrowserWindow): void { + if (ipcRegistered) return; + ipcRegistered = true; + startThemeWatcher(); ipcMain.handle("getShelterBundle", () => { return { js: ifExistsRead(path.join(app.getPath("userData"), "shelter.js")), @@ -81,13 +128,11 @@ export function registerIpc(passedWindow: BrowserWindow): void { }); ipcMain.handle("getCustomBundle", () => { const enabled = getConfig("mods").includes("custom"); - if (enabled) { - return { - js: ifExistsRead(path.join(app.getPath("userData"), "custom.js")), - css: ifExistsRead(path.join(app.getPath("userData"), "custom.css")), - enabled, - }; - } + return { + js: enabled ? ifExistsRead(path.join(app.getPath("userData"), "custom.js")) : undefined, + css: enabled ? ifExistsRead(path.join(app.getPath("userData"), "custom.css")) : undefined, + enabled, + }; }); // theming @@ -165,26 +210,16 @@ export function registerIpc(passedWindow: BrowserWindow): void { }); ipcMain.on("getThemes", (event) => { - const themes = []; - const themeFolders = readdirSync(themesPath); - for (const folder of themeFolders) { - if (existsSync(`${themesPath}/${folder}/manifest.json`)) { - const manifest = JSON.parse( - readFileSync(`${themesPath}/${folder}/manifest.json`, "utf8"), - ) as ThemeManifest; - themes.push({ ...manifest, id: folder }); - } - } - event.returnValue = themes; + event.returnValue = getCachedThemeList(); + }); + ipcMain.on("refreshThemesCache", (event) => { + invalidateThemeListCache(); + event.returnValue = getCachedThemeList(); }); ipcMain.on("splashEnd", () => { - splashWindow.close(); - if (getConfig("startMinimized")) { - passedWindow.hide(); - } else { - passedWindow.show(); - } + splashWindow?.close(); + applyStartupWindowVisibility(passedWindow); }); ipcMain.on("setLang", (_event, lang: string) => { setLang(lang); @@ -232,7 +267,7 @@ export function registerIpc(passedWindow: BrowserWindow): void { passedWindow.unmaximize(); }); ipcMain.on("win-show", () => { - passedWindow.show(); + revealWindow(passedWindow); }); ipcMain.on("win-hide", () => { passedWindow.hide(); @@ -316,6 +351,9 @@ export function registerIpc(passedWindow: BrowserWindow): void { shell.showItemInFolder(themesPath); }); ipcMain.on("openPluginsFolder", () => { + shell.showItemInFolder(extensionsPath); + }); + ipcMain.on("openRuntimePluginsFolder", () => { shell.showItemInFolder(pluginsPath); }); ipcMain.on("openCrashesFolder", () => { @@ -344,6 +382,12 @@ export function registerIpc(passedWindow: BrowserWindow): void { ipcMain.on("copyGPUInfo", () => { clipboard.writeText(JSON.stringify(app.getGPUFeatureStatus())); }); + ipcMain.on("openWebRTCInternals", () => { + openChromeInternalsPage("chrome://webrtc-internals/", "WebRTC Internals"); + }); + ipcMain.on("openGPUInfo", () => { + openChromeInternalsPage("chrome://gpu/", "GPU"); + }); ipcMain.on("openCustomIconDialog", () => { dialog .showOpenDialog({ @@ -367,6 +411,25 @@ export function registerIpc(passedWindow: BrowserWindow): void { ipcMain.on("getProcessList", (event) => { event.returnValue = processList; }); + ipcMain.handle("plugins:list", () => listPlugins()); + ipcMain.handle("plugins:set-enabled", async (_event, pluginId: string, enabled: boolean) => { + if (typeof pluginId !== "string" || typeof enabled !== "boolean") { + return { ok: false }; + } + return { ok: await setPluginEnabled(pluginId, enabled) }; + }); + ipcMain.handle("plugins:reload", async (_event, pluginId: string) => { + if (typeof pluginId !== "string") return { ok: false }; + return { ok: await reloadPlugin(pluginId) }; + }); + ipcMain.handle("plugins:get-runtime-entries", (_event, target: "preload" | "renderer") => { + if (target !== "preload" && target !== "renderer") return []; + return getRuntimeEntries(target); + }); + ipcMain.handle("plugins:get-runtime-script", (_event, pluginId: string, target: "preload" | "renderer") => { + if (typeof pluginId !== "string" || (target !== "preload" && target !== "renderer")) return null; + return getRuntimeScript(pluginId, target); + }); // custom detectables control ipcMain.on("refreshProcessList", () => { @@ -451,6 +514,7 @@ export function registerIpc(passedWindow: BrowserWindow): void { const zipBuf = buildBackupZipBuffer(payload, { userDataPath, themesPath, + extensionsPath, pluginsPath, pluginStoragePath, quickCssPath, @@ -491,6 +555,7 @@ export function registerIpc(passedWindow: BrowserWindow): void { const { clientMods } = applyBackupFromMap(map, { userDataPath, themesPath, + extensionsPath, pluginsPath, pluginStoragePath, quickCssPath, diff --git a/src/discord/menu.ts b/src/discord/menu.ts index bee18d1..556ebbc 100644 --- a/src/discord/menu.ts +++ b/src/discord/menu.ts @@ -1,9 +1,10 @@ -import { BrowserWindow, Menu, type MenuItemConstructorOptions, app } from "electron"; +import { app, BrowserWindow, Menu, type MenuItemConstructorOptions } from "electron"; import type { Keybind, KeybindActions } from "../@types/keybind.js"; import { getConfig } from "../common/config.js"; import { setForceQuit } from "../common/forceQuit.js"; -import { runAction } from "../common/keybindActions.js"; +import { openSettings, runAction } from "../common/keybindActions.js"; import { getLang } from "../common/lang.js"; +import { revealWindow } from "../common/windowVisibility.js"; import { mainWindows } from "./window.js"; const keybindActionLabels: Record = { @@ -15,6 +16,7 @@ const keybindActionLabels: Record = { navigateBack: "keybind-navigateBack", runJavascript: "keybind-runJavascript", openQuickCss: "keybind-openQuickCss", + openSettings: "keybind-openSettings", }; export function setMenu(): void { @@ -52,17 +54,8 @@ export function setMenu(): void { accelerator: "Cmd+,", click() { mainWindows.forEach((mainWindow) => { - mainWindow.show(); - void mainWindow.webContents.executeJavaScript(`window.shelter.flux.dispatcher.dispatch({ - "type": "USER_SETTINGS_MODAL_OPEN", - "section": "legcord-settings", - "subsection": null, - "openWithoutBackstack": false - })`); - void mainWindow.webContents.executeJavaScript( - `window.shelter.flux.dispatcher.dispatch({type: "LAYER_PUSH", component: "USER_SETTINGS"})`, - ); - // this opens the legcord tab directly in the settings modal + revealWindow(mainWindow); + openSettings(); }); }, }, diff --git a/src/discord/plugins/manager.ts b/src/discord/plugins/manager.ts new file mode 100644 index 0000000..c2913a9 --- /dev/null +++ b/src/discord/plugins/manager.ts @@ -0,0 +1,310 @@ +import { existsSync, mkdirSync, readdirSync, readFileSync } from "node:fs"; +import path from "node:path"; +import { pathToFileURL } from "node:url"; +import { app, BrowserWindow, dialog, ipcMain, shell } from "electron"; +import { after, before, instead } from "spitroast/dist/index.mjs"; +import { getConfig, setConfig } from "../../common/config.js"; + +type PluginTarget = "main" | "preload" | "renderer"; +type Cleanup = () => void; + +interface PluginManifest { + id: string; + name: string; + version: string; + description?: string; + author?: string; + main?: string; + preload?: string; + renderer?: string; + compatibleVersions?: string[]; +} + +interface PluginRecord { + manifest: PluginManifest; + directory: string; + enabled: boolean; + compatible: boolean; + compatibilityMessage?: string; + loadedMain: boolean; + cleanups: Cleanup[]; +} + +interface PluginMainApi { + id: string; + manifest: PluginManifest; + logger: Pick; + patcher: { + before: typeof before; + after: typeof after; + instead: typeof instead; + }; + electron: { + app: typeof app; + BrowserWindow: typeof BrowserWindow; + ipcMain: typeof ipcMain; + dialog: typeof dialog; + shell: typeof shell; + }; + onCleanup: (cleanup: Cleanup) => void; +} + +const pluginFolder = path.join(app.getPath("userData"), "/plugins"); +const currentLegcordVersion = app.getVersion(); +const records = new Map(); +const VALID_PLUGIN_ID = /^[a-zA-Z0-9._-]{1,64}$/; +const VALID_ENTRY_PATH = /^[^<>:"|?*\0]+$/; + +function getPluginStates() { + const states = getConfig("pluginStates"); + if (states && typeof states === "object") { + return states as Record; + } + return {}; +} + +function setPluginState(pluginId: string, enabled: boolean) { + const states = getPluginStates(); + states[pluginId] = enabled; + setConfig("pluginStates", states); +} + +function getLogPrefix(id: string) { + return `[Plugin:${id}]`; +} + +function parseManifest(pluginDir: string): PluginManifest | null { + const manifestPath = path.join(pluginDir, "manifest.json"); + if (!existsSync(manifestPath)) return null; + try { + const parsed = JSON.parse(readFileSync(manifestPath, "utf-8")) as PluginManifest; + if (!parsed.id || !parsed.name || !parsed.version) return null; + if (!VALID_PLUGIN_ID.test(parsed.id)) { + console.error(`[Plugin Manager] Invalid plugin id "${parsed.id}"`); + return null; + } + if (typeof parsed.name !== "string" || parsed.name.length > 128) { + console.error(`[Plugin Manager] ${parsed.id}: invalid plugin name`); + return null; + } + if (typeof parsed.version !== "string" || parsed.version.length > 64) { + console.error(`[Plugin Manager] ${parsed.id}: invalid plugin version`); + return null; + } + if ( + typeof parsed.main === "undefined" && + typeof parsed.preload === "undefined" && + typeof parsed.renderer === "undefined" + ) { + console.error(`[Plugin Manager] ${parsed.id}: at least one of main/preload/renderer must be defined`); + return null; + } + if ( + (parsed.main && !VALID_ENTRY_PATH.test(parsed.main)) || + (parsed.preload && !VALID_ENTRY_PATH.test(parsed.preload)) || + (parsed.renderer && !VALID_ENTRY_PATH.test(parsed.renderer)) + ) { + console.error(`[Plugin Manager] ${parsed.id}: invalid entry path`); + return null; + } + if ( + typeof parsed.compatibleVersions !== "undefined" && + (!Array.isArray(parsed.compatibleVersions) || + parsed.compatibleVersions.some((version) => typeof version !== "string")) + ) { + console.error(`[Plugin Manager] ${parsed.id}: compatibleVersions must be an array of strings`); + return null; + } + return parsed; + } catch (error) { + console.error(`[Plugin Manager] Failed to parse manifest in ${pluginDir}`, error); + return null; + } +} + +function isCompatibleVersion(versionPattern: string, version: string): boolean { + if (versionPattern === "*" || versionPattern === version) return true; + if (versionPattern.endsWith(".x")) { + const prefix = versionPattern.slice(0, -2); + return version === prefix || version.startsWith(`${prefix}.`); + } + return false; +} + +function getCompatibility(manifest: PluginManifest): { compatible: boolean; message?: string } { + const supported = manifest.compatibleVersions; + if (!supported || supported.length === 0) { + return { compatible: true }; + } + const compatible = supported.some((pattern) => isCompatibleVersion(pattern, currentLegcordVersion)); + if (compatible) return { compatible: true }; + return { + compatible: false, + message: `Incompatible with Legcord ${currentLegcordVersion} (supports: ${supported.join(", ")})`, + }; +} + +function resolvePluginEntry(record: PluginRecord, target: PluginTarget) { + const entry = record.manifest[target]; + if (!entry) return null; + const resolved = path.resolve(record.directory, entry); + const relative = path.relative(record.directory, resolved); + if (relative.startsWith("..") || path.isAbsolute(relative)) return null; + if (!existsSync(resolved)) return null; + return resolved; +} + +async function loadMain(record: PluginRecord) { + if (record.loadedMain) return; + const entry = resolvePluginEntry(record, "main"); + if (!entry) return; + + const loggerPrefix = getLogPrefix(record.manifest.id); + const api: PluginMainApi = { + id: record.manifest.id, + manifest: record.manifest, + logger: { + log: (...args) => console.log(loggerPrefix, ...args), + warn: (...args) => console.warn(loggerPrefix, ...args), + error: (...args) => console.error(loggerPrefix, ...args), + }, + patcher: { + before, + after, + instead, + }, + electron: { + app, + BrowserWindow, + ipcMain, + dialog, + shell, + }, + onCleanup: (cleanup) => { + record.cleanups.push(cleanup); + }, + }; + + const moduleUrl = `${pathToFileURL(entry).href}?v=${Date.now()}`; + const mod = (await import(moduleUrl)) as { + default?: (api: PluginMainApi) => void | Promise; + activate?: (api: PluginMainApi) => void | Promise; + }; + const entrypoint = mod.activate ?? mod.default; + if (typeof entrypoint === "function") { + await entrypoint(api); + } + record.loadedMain = true; +} + +function disableMain(record: PluginRecord) { + if (!record.loadedMain) return; + for (const cleanup of record.cleanups.splice(0)) { + try { + cleanup(); + } catch (error) { + console.error(`[Plugin Manager] Cleanup failed for ${record.manifest.id}`, error); + } + } + record.loadedMain = false; +} + +export async function initializePluginSystem() { + if (!existsSync(pluginFolder)) { + mkdirSync(pluginFolder, { recursive: true }); + } + + const discovered: PluginRecord[] = []; + for (const child of readdirSync(pluginFolder)) { + const full = path.join(pluginFolder, child); + const manifest = parseManifest(full); + if (!manifest) continue; + const state = getPluginStates(); + const enabled = state[manifest.id] ?? false; + const compatibility = getCompatibility(manifest); + discovered.push({ + manifest, + directory: full, + enabled, + compatible: compatibility.compatible, + ...(compatibility.message !== undefined ? { compatibilityMessage: compatibility.message } : {}), + loadedMain: false, + cleanups: [], + }); + } + + records.clear(); + for (const record of discovered) { + records.set(record.manifest.id, record); + } + + for (const record of records.values()) { + if (!record.enabled || !record.compatible) continue; + await loadMain(record); + } +} + +export async function setPluginEnabled(pluginId: string, enabled: boolean) { + const record = records.get(pluginId); + if (!record) return false; + if (enabled && !record.compatible) return false; + setPluginState(pluginId, enabled); + record.enabled = enabled; + if (enabled) { + await loadMain(record); + } else { + disableMain(record); + } + return true; +} + +export async function reloadPlugin(pluginId: string) { + const record = records.get(pluginId); + if (!record) return false; + if (!record.compatible) return false; + disableMain(record); + if (record.enabled) { + await loadMain(record); + } + return true; +} + +export function listPlugins() { + return [...records.values()].map((record) => ({ + id: record.manifest.id, + name: record.manifest.name, + version: record.manifest.version, + description: record.manifest.description, + author: record.manifest.author, + enabled: record.enabled, + compatible: record.compatible, + compatibilityMessage: record.compatibilityMessage, + compatibleVersions: record.manifest.compatibleVersions ?? [], + hasMain: Boolean(record.manifest.main), + hasPreload: Boolean(record.manifest.preload), + hasRenderer: Boolean(record.manifest.renderer), + })); +} + +export function getRuntimeEntries(target: Exclude) { + return [...records.values()] + .filter((record) => record.enabled && record.compatible) + .map((record) => { + const entry = resolvePluginEntry(record, target); + if (!entry) return null; + return { + id: record.manifest.id, + name: record.manifest.name, + path: entry, + }; + }) + .filter((entry): entry is { id: string; name: string; path: string } => entry !== null); +} + +export function getRuntimeScript(pluginId: string, target: Exclude) { + const record = records.get(pluginId); + if (!record?.enabled || !record.compatible) return null; + const entry = resolvePluginEntry(record, target); + if (!entry) return null; + return readFileSync(entry, "utf-8"); +} diff --git a/src/discord/preload/bridge.ts b/src/discord/preload/bridge.ts index a9cc894..825cc27 100644 --- a/src/discord/preload/bridge.ts +++ b/src/discord/preload/bridge.ts @@ -1,4 +1,5 @@ const { contextBridge, ipcRenderer } = require("electron"); + import type { Game } from "arrpc"; import type { Keybind } from "../../@types/keybind.js"; import type { LegcordWindow } from "../../@types/legcordWindow.d.ts"; @@ -12,6 +13,20 @@ interface IPCSources { name: string; thumbnail: HTMLCanvasElement; } +interface LegcordPluginInfo { + id: string; + name: string; + version: string; + description?: string; + author?: string; + enabled: boolean; + compatible: boolean; + compatibilityMessage?: string; + compatibleVersions: string[]; + hasMain: boolean; + hasPreload: boolean; + hasRenderer: boolean; +} contextBridge.exposeInMainWorld("legcord", { window: { @@ -36,6 +51,8 @@ contextBridge.exposeInMainWorld("legcord", { openCustomIconDialog: () => ipcRenderer.send("openCustomIconDialog"), copyDebugInfo: () => ipcRenderer.send("copyDebugInfo"), copyGPUInfo: () => ipcRenderer.send("copyGPUInfo"), + openWebRTCInternals: () => ipcRenderer.send("openWebRTCInternals"), + openGPUInfo: () => ipcRenderer.send("openGPUInfo"), dumpFlags: () => ipcRenderer.sendSync("dumpFlags") as AppliedFlagsOutput, }, touchbar: { @@ -87,6 +104,7 @@ contextBridge.exposeInMainWorld("legcord", { uninstall: (id: string) => ipcRenderer.send("uninstallTheme", id), edit: (id: string) => ipcRenderer.send("editTheme", id), getThemes: () => ipcRenderer.sendSync("getThemes") as ThemeManifest[], + refresh: () => ipcRenderer.sendSync("refreshThemesCache") as ThemeManifest[], openImportPicker: () => ipcRenderer.send("openImportPicker"), set: (id: string, state: boolean) => ipcRenderer.send("setThemeEnabled", id, state), folder: (id: string) => ipcRenderer.send("openThemeFolder", id), @@ -110,6 +128,13 @@ contextBridge.exposeInMainWorld("legcord", { ipcRenderer.invoke("backupSave", data) as Promise<{ ok: true } | { ok: false; error: string }>, restore: () => ipcRenderer.invoke("backupRestore") as Promise, }, + plugins: { + list: () => ipcRenderer.invoke("plugins:list") as Promise, + setEnabled: (id: string, enabled: boolean) => + ipcRenderer.invoke("plugins:set-enabled", id, enabled) as Promise<{ ok: boolean }>, + reload: (id: string) => ipcRenderer.invoke("plugins:reload", id) as Promise<{ ok: boolean }>, + openFolder: () => ipcRenderer.send("openRuntimePluginsFolder"), + }, fs: { /** * Write a file in this plugin's scoped storage (e.g. "cache/deleted-messages.json"). diff --git a/src/discord/preload/inviteBackButton.mts b/src/discord/preload/inviteBackButton.mts new file mode 100644 index 0000000..06f0a30 --- /dev/null +++ b/src/discord/preload/inviteBackButton.mts @@ -0,0 +1,75 @@ +import { addScript, addStyle } from "../../common/dom.js"; + +const { ipcRenderer } = require("electron"); + +document.addEventListener("DOMContentLoaded", () => { + void (async () => { + const label = + ((await ipcRenderer.invoke("getLang", "invite-goBackToApp")) as string | undefined) || + "Go back to the Discord app"; + + addStyle("legcord://assets/css/inviteBack.css"); + + // Injected into the page world so Discord SPA history.pushState/replaceState is visible. + addScript(` +(() => { + const BTN_ID = "legcord-invite-back"; + const LABEL = ${JSON.stringify(label)}; + + function isInvitePath(pathname) { + const path = (pathname || "").toLowerCase(); + return path.startsWith("/invite/") || path.startsWith("/guest-invite/"); + } + + function ensureButton() { + let btn = document.getElementById(BTN_ID); + if (btn) return btn; + btn = document.createElement("button"); + btn.id = BTN_ID; + btn.type = "button"; + btn.textContent = LABEL; + btn.setAttribute("aria-label", LABEL); + btn.addEventListener("click", (event) => { + event.preventDefault(); + event.stopPropagation(); + try { + history.pushState({}, "", "/app"); + window.dispatchEvent(new PopStateEvent("popstate", { state: {} })); + } catch (_) { + location.assign("/app"); + } + }); + (document.body || document.documentElement).appendChild(btn); + return btn; + } + + function sync() { + const btn = ensureButton(); + const onInvite = isInvitePath(location.pathname); + btn.setAttribute("data-visible", onInvite ? "true" : "false"); + btn.hidden = !onInvite; + btn.setAttribute("aria-hidden", onInvite ? "false" : "true"); + } + + function patchHistory(method) { + const original = history[method]; + if (typeof original !== "function") return; + history[method] = function () { + const result = original.apply(this, arguments); + queueMicrotask(sync); + return result; + }; + } + + patchHistory("pushState"); + patchHistory("replaceState"); + window.addEventListener("popstate", sync); + window.addEventListener("hashchange", sync); + + sync(); + // Fallback for Discord navigations that do not go through history hooks. + setInterval(sync, 1000); +})(); +`); + })(); +}); diff --git a/src/discord/preload/mods/custom.mts b/src/discord/preload/mods/custom.mts index 97eef7c..df93878 100644 --- a/src/discord/preload/mods/custom.mts +++ b/src/discord/preload/mods/custom.mts @@ -1,9 +1,11 @@ const { ipcRenderer, webFrame } = require("electron"); + import type { ModBundle } from "../../../@types/ModBundle.js"; + async function inject() { try { await ipcRenderer.invoke("getCustomBundle").then(async (bundle: ModBundle) => { - if (bundle.enabled) { + if (bundle?.enabled) { await webFrame.executeJavaScript(bundle.js); if (bundle.css) { webFrame.insertCSS(bundle.css); //NOTE - Custom mods might require CSS. diff --git a/src/discord/preload/mods/equicord.mts b/src/discord/preload/mods/equicord.mts index 0bbecbf..4e83788 100644 --- a/src/discord/preload/mods/equicord.mts +++ b/src/discord/preload/mods/equicord.mts @@ -1,9 +1,11 @@ const { ipcRenderer, webFrame } = require("electron"); + import type { ModBundle } from "../../../@types/ModBundle.js"; + async function inject() { try { await ipcRenderer.invoke("getEquicordBundle").then(async (bundle: ModBundle) => { - if (bundle.enabled) { + if (bundle?.enabled) { await webFrame.executeJavaScript(bundle.js); webFrame.insertCSS(bundle.css!); //NOTE - Equicord requires CSS. } diff --git a/src/discord/preload/mods/shelter.mts b/src/discord/preload/mods/shelter.mts index 6b00dc1..90a2d54 100644 --- a/src/discord/preload/mods/shelter.mts +++ b/src/discord/preload/mods/shelter.mts @@ -1,4 +1,5 @@ const { ipcRenderer, webFrame } = require("electron"); + import type { ModBundle } from "../../../@types/ModBundle.js"; const requiredPlugins: Record }]> = { @@ -17,7 +18,7 @@ if (process.platform === "darwin") { async function inject() { try { await ipcRenderer.invoke("getShelterBundle").then(async (bundle: ModBundle) => { - if (bundle.enabled) { + if (bundle?.enabled) { await webFrame.executeJavaScript(`(()=>{ const SHELTER_INJECTOR_PLUGINS = ${JSON.stringify(requiredPlugins)}; ${bundle.js} diff --git a/src/discord/preload/mods/vencord.mts b/src/discord/preload/mods/vencord.mts index 60704f6..1612c9f 100644 --- a/src/discord/preload/mods/vencord.mts +++ b/src/discord/preload/mods/vencord.mts @@ -1,9 +1,11 @@ const { ipcRenderer, webFrame } = require("electron"); + import type { ModBundle } from "../../../@types/ModBundle.js"; + async function inject() { try { await ipcRenderer.invoke("getVencordBundle").then(async (bundle: ModBundle) => { - if (bundle.enabled) { + if (bundle?.enabled) { await webFrame.executeJavaScript(bundle.js); webFrame.insertCSS(bundle.css!); //NOTE - Vencord requires CSS. } diff --git a/src/discord/preload/newTitlebar.mts b/src/discord/preload/newTitlebar.mts index a68c1a7..1fdb1a1 100644 --- a/src/discord/preload/newTitlebar.mts +++ b/src/discord/preload/newTitlebar.mts @@ -1,16 +1,24 @@ const { ipcRenderer } = require("electron"); + import { addStyle } from "../../common/dom.js"; import { sleep } from "../../common/sleep.js"; -if ( - ipcRenderer.sendSync("getConfig", "windowStyle") === "default" || - ipcRenderer.sendSync("getConfig", "windowStyle") === "overlay" -) { +const windowStyle = ipcRenderer.sendSync("getConfig", "windowStyle") as string; +const transparency = ipcRenderer.sendSync("getConfig", "transparency") as string; +const os = ipcRenderer.sendSync("getOS") as string; + +// Native + transparency on macOS uses overlay chrome (see createWindow / Legcord#1095). +const usesOverlayChrome = + windowStyle === "default" || + windowStyle === "overlay" || + (windowStyle === "native" && os === "darwin" && transparency !== "none"); + +if (usesOverlayChrome) { document.addEventListener("DOMContentLoaded", () => { - document.body.setAttribute("legcord-platform", ipcRenderer.sendSync("getOS")); + document.body.setAttribute("legcord-platform", os); addStyle("legcord://assets/css/baseTitlebar.css"); sleep(500); - switch (ipcRenderer.sendSync("getOS")) { + switch (os) { case "darwin": // breaks traffic lights with bar__ and hidden__ classes // document.body.setAttribute("class", "platform-osx"); diff --git a/src/discord/preload/optimizer.ts b/src/discord/preload/optimizer.ts index 770524a..406ea3b 100644 --- a/src/discord/preload/optimizer.ts +++ b/src/discord/preload/optimizer.ts @@ -1,18 +1,10 @@ type OptimizableFunction = (child: T) => T; const optimize = (orig: OptimizableFunction) => { - return function (this: Element, ...args: [Element]): T | number { - if (typeof args[0]?.className === "string" && args[0].className.includes("activity")) { - // fix by xql.dev <@1356430365774053448> - setTimeout(() => orig.apply(this, args as unknown as [T]), 100); - return args[0] as unknown as T; - } + return function (this: Element, ...args: [Element]): T { return orig.apply(this, args as unknown as [T]); } as unknown as OptimizableFunction; }; -// We are taking in the function itself // eslint-disable-next-line @typescript-eslint/unbound-method Element.prototype.removeChild = optimize(Element.prototype.removeChild); - -// Thanks Ari - <@1249446413952225452> diff --git a/src/discord/preload/patches.mts b/src/discord/preload/patches.mts index ac75c65..c984a68 100644 --- a/src/discord/preload/patches.mts +++ b/src/discord/preload/patches.mts @@ -1,5 +1,6 @@ import { addScript, addStyle, injectJS } from "../../common/dom.js"; import { sleep } from "../../common/sleep.js"; + const { ipcRenderer } = require("electron"); const version = ipcRenderer.sendSync("displayVersion") as string; @@ -29,15 +30,123 @@ const version = ipcRenderer.sendSync("displayVersion") as string; } } +// Raise Chromium's ~2500kbps screenshare SDP cap before Discord binds RTCPeerConnection. +// Shelter plugins load too late / MediaEngine may keep the original method reference. +// On macOS/Windows also rewrite H.264 Constrained Baseline → Baseline on local *and* remote SDP: +// Discord's Go Live answer forces profile-level-id=42e01f (OpenH264); local-only munging +// is overwritten by setRemoteDescription, so the answer must be rewritten too. +// Without this, Windows burns CPU on OpenH264 even when Media Foundation HW encode is available. +// Gated by settings.sdpH264BaselineRewrite (default on) so users can disable if negotiation breaks. +{ + const rewriteBaselineSetting = ipcRenderer.sendSync("getConfig", "sdpH264BaselineRewrite") as boolean | undefined; + const preferHwH264 = + (process.platform === "darwin" || process.platform === "win32") && (rewriteBaselineSetting ?? true); + const bitrateScript = document.createElement("script"); + bitrateScript.textContent = `(function () { + var CAP = "80000"; + // Modest floor/start (kbps) so GCC probes above Discord's ~1–2.5 Mbps screenshare default + // without fighting congestion control. Max remains the hard ceiling. + var MIN_BR = "3000"; + var START_BR = "3000"; + // VideoToolbox (macOS) and Media Foundation (Windows) HW encode avoid OpenH264 CBP. + var preferHwH264 = ${preferHwH264 ? "true" : "false"}; + function setOrAppendFmtpParam(sdp, key, value) { + var re = new RegExp(key + "=\\\\d+", "g"); + if (sdp.indexOf(key + "=") !== -1) { + return sdp.replace(re, key + "=" + value); + } + return sdp.replace(/(a=fmtp:\\d+ [^\\r\\n]*)/g, function (line) { + if (line.indexOf(key + "=") !== -1) return line; + return line + ";" + key + "=" + value; + }); + } + function mungeSdp(sdp) { + if (!sdp || typeof sdp !== "string") return sdp; + var out = sdp; + // Chromium uses OpenH264 for Constrained Baseline (42e0xx). Rewrite to Baseline + // (4200xx) so VideoToolbox / Media Foundation HW H.264 can be selected. + // See discuss-webrtc: CBP uses software encoder for historical reasons. + if (preferHwH264) { + out = out.replace(/profile-level-id=42e0([0-9a-fA-F]{2})/gi, "profile-level-id=4200$1"); + } + out = setOrAppendFmtpParam(out, "x-google-max-bitrate", CAP); + out = setOrAppendFmtpParam(out, "x-google-min-bitrate", MIN_BR); + out = setOrAppendFmtpParam(out, "x-google-start-bitrate", START_BR); + return out; + } + function wrapDescription(desc) { + if (!desc || !desc.sdp) return desc; + var sdp = mungeSdp(desc.sdp); + if (sdp === desc.sdp) return desc; + try { + return new RTCSessionDescription({ type: desc.type, sdp: sdp }); + } catch (e) { + return Object.assign({}, desc, { sdp: sdp }); + } + } + var proto = window.RTCPeerConnection && window.RTCPeerConnection.prototype; + if (!proto) return; + var origSLD = proto.setLocalDescription; + proto.setLocalDescription = function (desc) { + var args = Array.prototype.slice.call(arguments); + if (args.length > 0) args[0] = wrapDescription(args[0]); + return origSLD.apply(this, args); + }; + var origSRD = proto.setRemoteDescription; + proto.setRemoteDescription = function (desc) { + var args = Array.prototype.slice.call(arguments); + if (args.length > 0) args[0] = wrapDescription(args[0]); + return origSRD.apply(this, args); + }; + var origOffer = proto.createOffer; + proto.createOffer = function () { + var self = this; + var args = arguments; + return Promise.resolve(origOffer.apply(self, args)).then(function (offer) { + return wrapDescription(offer) || offer; + }); + }; + var origAnswer = proto.createAnswer; + if (origAnswer) { + proto.createAnswer = function () { + var self = this; + var args = arguments; + return Promise.resolve(origAnswer.apply(self, args)).then(function (answer) { + return wrapDescription(answer) || answer; + }); + }; + } + // Do NOT patch RTCRtpSender.setParameters to force high maxBitrate — that fights + // Discord/WebRTC congestion control and collapses streams to tiny resolutions. + console.log("[Legcord] Early WebRTC screenshare SDP patch installed" + (preferHwH264 ? " (H264 CBP→Baseline on local+remote)" : "")); +})();`; + + if (document.documentElement) { + document.documentElement.prepend(bitrateScript); + } else { + const observer = new MutationObserver(() => { + if (document.documentElement) { + observer.disconnect(); + document.documentElement.prepend(bitrateScript); + } + }); + observer.observe(document, { childList: true }); + } +} + // Fix: Chromium on macOS ignores video deviceId when passed as an "ideal" constraint // (plain string), always returning the first camera. Discord passes deviceId this way. // This patch promotes "ideal" to "exact", stops active tracks before switching so macOS // releases the hardware, and falls back to the original behavior if "exact" fails. // Injected into the page context because contextIsolation is enabled. // See: https://github.com/electron/electron/issues/44502 +// Stopping prior audio streams on every new getUserMedia breaks Discord on Windows/Linux +// (multiple object-shaped audio requests); keep that behavior only on darwin. { + const stopPrevAudioStreams = process.platform === "darwin"; const cameraFixScript = document.createElement("script"); cameraFixScript.textContent = `(function() { + var legcordStopPrevAudioStreams = ${stopPrevAudioStreams}; var _origGUM = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices); var _activeVideoStreams = []; var _activeAudioStreams = []; @@ -58,16 +167,16 @@ const version = ipcRenderer.sendSync("displayVersion") as string; function trackStream(stream) { var ref = new WeakRef(stream); if (stream.getVideoTracks().length > 0) _activeVideoStreams.push(ref); - if (stream.getAudioTracks().length > 0) _activeAudioStreams.push(ref); + if (legcordStopPrevAudioStreams && stream.getAudioTracks().length > 0) _activeAudioStreams.push(ref); } navigator.mediaDevices.getUserMedia = async function(constraints) { var hasVideo = constraints && constraints.video && typeof constraints.video !== "boolean"; var hasAudio = constraints && constraints.audio && typeof constraints.audio !== "boolean"; - // Release previous hardware when new request comes in for the same kind + // Release previous hardware when new request comes in for the same kind (audio: darwin only) if (hasVideo && _activeVideoStreams.length > 0) stopTrackedStreams(_activeVideoStreams, "video"); - if (hasAudio && _activeAudioStreams.length > 0) stopTrackedStreams(_activeAudioStreams, "audio"); + if (legcordStopPrevAudioStreams && hasAudio && _activeAudioStreams.length > 0) stopTrackedStreams(_activeAudioStreams, "audio"); var hasStringVideoDeviceId = hasVideo && typeof constraints.video.deviceId === "string"; if (!hasStringVideoDeviceId) { @@ -127,40 +236,9 @@ const version = ipcRenderer.sendSync("displayVersion") as string; } } -export async function getVirtmic() { - try { - const devices = await navigator.mediaDevices.enumerateDevices(); - const audioDevice = devices.find(({ label }) => label === "vencord-screen-share"); - return audioDevice?.deviceId; - } catch (error) { - return null; - } -} - async function load() { await sleep(5000).then(() => { - const original = navigator.mediaDevices.getDisplayMedia; - navigator.mediaDevices.getDisplayMedia = async function (opts) { - const stream = await original.call(this, opts); - const id = await getVirtmic(); - - if (id) { - const audio = await navigator.mediaDevices.getUserMedia({ - audio: { - deviceId: { - exact: id, - }, - autoGainControl: false, - echoCancellation: false, - noiseSuppression: false, - }, - }); - audio.getAudioTracks().forEach((t) => stream.addTrack(t)); - } - - return stream; - }; - + // Venmic audio injection lives in the Shelter screenshare getDisplayMedia patch. // dirty hack to make clicking notifications focus Legcord addScript(` (() => { @@ -198,6 +276,7 @@ async function load() { el.id = "ac-ver"; el.textContent = `Legcord Version: ${version}`; info.after(el); + observer.disconnect(); }); observer.observe(document.body, { childList: true, subtree: true }); } diff --git a/src/discord/preload/plugins.mts b/src/discord/preload/plugins.mts new file mode 100644 index 0000000..4be0f75 --- /dev/null +++ b/src/discord/preload/plugins.mts @@ -0,0 +1,185 @@ +const { ipcRenderer, webFrame } = require("electron"); +const { after, before, instead } = require("spitroast/dist/index.js"); + +type RuntimeEntry = { + id: string; + name: string; + path: string; +}; + +const cleanupMap = new Map void>>(); + +function addCleanup(pluginId: string, cleanup: () => void) { + const current = cleanupMap.get(pluginId) ?? []; + current.push(cleanup); + cleanupMap.set(pluginId, current); +} + +function clearCleanup(pluginId: string) { + const cleanups = cleanupMap.get(pluginId); + if (!cleanups) return; + for (const cleanup of cleanups.splice(0)) { + try { + cleanup(); + } catch (error) { + console.error(`[Plugin:${pluginId}] cleanup failed`, error); + } + } +} + +function createApi(pluginId: string, pluginName: string) { + const loggerPrefix = `[Plugin:${pluginId}]`; + return { + id: pluginId, + name: pluginName, + logger: { + log: (...args: unknown[]) => console.log(loggerPrefix, ...args), + warn: (...args: unknown[]) => console.warn(loggerPrefix, ...args), + error: (...args: unknown[]) => console.error(loggerPrefix, ...args), + }, + patcher: { + before: (...args: Parameters) => { + const unpatch = before(...args); + addCleanup(pluginId, unpatch); + return unpatch; + }, + after: (...args: Parameters) => { + const unpatch = after(...args); + addCleanup(pluginId, unpatch); + return unpatch; + }, + instead: (...args: Parameters) => { + const unpatch = instead(...args); + addCleanup(pluginId, unpatch); + return unpatch; + }, + }, + onCleanup: (cleanup: () => void) => addCleanup(pluginId, cleanup), + }; +} + +async function executePreloadPluginSource(_pluginId: string, source: string, api: ReturnType) { + const runner = new Function( + "api", + ` +const mod = { exports: {} }; +const module = mod; +const exports = mod.exports; +${source} +const activate = mod.exports.activate ?? mod.exports.default ?? globalThis.activatePlugin; +if (typeof activate === "function") { + return activate(api); +} +`, + ) as (api: ReturnType) => unknown; + await Promise.resolve(runner(api)); +} + +async function loadPreloadPlugins() { + const entries = (await ipcRenderer.invoke("plugins:get-runtime-entries", "preload")) as RuntimeEntry[]; + for (const entry of entries) { + clearCleanup(entry.id); + try { + const source = (await ipcRenderer.invoke("plugins:get-runtime-script", entry.id, "preload")) as + | string + | null; + if (!source) continue; + await executePreloadPluginSource(entry.id, source, createApi(entry.id, entry.name)); + } catch (error) { + console.error(`[Plugin:${entry.id}] preload entry failed`, error); + } + } +} + +function getRendererBootstrap(pluginId: string, pluginName: string, source: string) { + return ` +(() => { + const g = globalThis; + const stores = g.__legcordPluginPatches ?? (g.__legcordPluginPatches = new WeakMap()); + const unpatchAll = () => { g.__legcordPluginPatches = new WeakMap(); }; + const patch = (type, name, parent, callback, oneTime = false) => { + if (!parent || typeof parent[name] !== "function") throw new Error(\`Cannot patch \${String(name)}\`); + const original = parent[name]; + let bucket = stores.get(original); + if (!bucket) { + bucket = { o: original, b: new Map(), i: new Map(), a: new Map(), c: [] }; + const proxy = new Proxy(original, { + apply(_target, thisArg, argArray) { + let args = [...argArray]; + for (const hook of bucket.b.values()) { + const next = hook.call(thisArg, args); + if (Array.isArray(next)) args = next; + } + const callOriginal = (...inner) => Reflect.apply(original, thisArg, inner); + let ret = [...bucket.i.values()].reduceRight((prev, cur) => (...inner) => cur.call(thisArg, inner, prev), callOriginal)(...args); + for (const hook of bucket.a.values()) ret = hook.call(thisArg, args, ret) ?? ret; + for (const cleanup of bucket.c) cleanup(); + bucket.c.length = 0; + return ret; + } + }); + stores.set(proxy, bucket); + parent[name] = proxy; + bucket.proxy = proxy; + bucket.name = name; + bucket.parent = parent; + } + const hookId = Symbol("hook"); + const remove = () => { + const map = type === "b" ? bucket.b : type === "i" ? bucket.i : bucket.a; + if (!map.delete(hookId)) return false; + if (bucket.b.size || bucket.i.size || bucket.a.size) return true; + bucket.parent[bucket.name] = bucket.o; + stores.delete(bucket.proxy); + return true; + }; + if (oneTime) bucket.c.push(remove); + (type === "b" ? bucket.b : type === "i" ? bucket.i : bucket.a).set(hookId, callback); + return remove; + }; + const api = { + id: "${pluginId}", + name: "${pluginName}", + logger: { + log: (...args) => console.log("[Plugin:${pluginId}]", ...args), + warn: (...args) => console.warn("[Plugin:${pluginId}]", ...args), + error: (...args) => console.error("[Plugin:${pluginId}]", ...args), + }, + patcher: { + before: (name, parent, cb, once) => patch("b", name, parent, cb, once), + instead: (name, parent, cb, once) => patch("i", name, parent, cb, once), + after: (name, parent, cb, once) => patch("a", name, parent, cb, once), + unpatchAll + } + }; + const mod = { exports: {} }; + const module = mod; + const exports = mod.exports; + ${source} + const activate = mod.exports.activate ?? mod.exports.default ?? g.activatePlugin; + if (typeof activate === "function") activate(api); +})(); +//# sourceURL=legcord-plugin-renderer-${pluginId}.js +`; +} + +async function loadRendererPlugins() { + const entries = (await ipcRenderer.invoke("plugins:get-runtime-entries", "renderer")) as RuntimeEntry[]; + for (const entry of entries) { + try { + const source = (await ipcRenderer.invoke("plugins:get-runtime-script", entry.id, "renderer")) as + | string + | null; + if (!source) continue; + const bootstrap = getRendererBootstrap(entry.id, entry.name, source); + await webFrame.executeJavaScript(bootstrap); + } catch (error) { + console.error(`[Plugin:${entry.id}] renderer entry failed`, error); + } + } +} + +void (async () => { + await loadPreloadPlugins(); + await loadRendererPlugins(); +})(); diff --git a/src/discord/preload/preload.mts b/src/discord/preload/preload.mts index b925c6e..a83fbde 100644 --- a/src/discord/preload/preload.mts +++ b/src/discord/preload/preload.mts @@ -4,10 +4,12 @@ import "./mods/shelter.mjs"; import "./mods/vencord.mjs"; import "./mods/equicord.mjs"; import "./mods/custom.mjs"; +import "./plugins.mjs"; import "./patches.mjs"; import "./newTitlebar.mjs"; import "./titlebar.mjs"; import "./themes.js"; +import "./inviteBackButton.mjs"; console.log("Legcord"); window.localStorage.setItem("hideNag", "true"); diff --git a/src/discord/preload/themes.ts b/src/discord/preload/themes.ts index 1c2dd17..b5c7ad5 100644 --- a/src/discord/preload/themes.ts +++ b/src/discord/preload/themes.ts @@ -1,4 +1,5 @@ import { addTheme } from "../../common/dom.js"; + const { ipcRenderer } = require("electron"); ipcRenderer.on("addTheme", (_event: unknown, name: string, css: string) => { diff --git a/src/discord/preload/titlebar.mts b/src/discord/preload/titlebar.mts index 04679f8..b31d48b 100644 --- a/src/discord/preload/titlebar.mts +++ b/src/discord/preload/titlebar.mts @@ -1,6 +1,8 @@ const { ipcRenderer } = require("electron"); + import type { Settings } from "../../@types/settings.js"; import { addStyle } from "../../common/dom.js"; + const titlebarHTML = `