diff --git a/README.md b/README.md
index 51e85a5..167f451 100644
--- a/README.md
+++ b/README.md
@@ -53,55 +53,17 @@ docker compose -f docker-compose.client.yml logs -f
docker compose -f docker-compose.client.yml restart
```
-## Windows: standalone desktop client direction
+## Windows Desktop Client
-Windows app routing lives in a separate Tauri 2 desktop utility, not as
-`APP_MODE=windows` inside the current Node gateway/client server. The active
-workspace slice is `apps/windows-client`.
-
-Active design documents:
-
-- Product/tech brief: `docs/windows-client-product-tech-brief.md`
-- Execution plan: `docs/goals/windows-modular-client/PLAN.md`
-- Windows client README: `apps/windows-client/README.md`
-
-Target shape:
-
-- Control App: compact Windows UI for status, profiles, targets, components,
- logs, and diagnostics.
-- Proxyfier Layer: adapter boundary with ProxiFyre as the first engine for
- per-app TCP/UDP routing.
-- Local sing-box: optional local runtime; external SOCKS5/HTTP targets must
- work without it.
-
-Development checks:
+The Windows desktop client has been split out of this repository. Continue
+Windows-specific work in the sibling repository:
```powershell
-cd apps/windows-client
-npm install
-npm run build
-npm run tauri -- info
-
-cd src-tauri
-cargo test
+cd D:\repos\ProxyWarden
```
-Native Tauri build requires WebView2, Rust/rustup, and Visual Studio Build
-Tools with MSVC and Windows SDK components. In the current checkpoint, frontend
-builds pass, while native Rust/Tauri tests require that Windows toolchain.
-
-The three Windows pieces are installed and operated separately:
-
-```powershell
-cd apps/windows-client
-& .\scripts\install-control-app.ps1 -PlanOnly
-& .\scripts\install-proxyfier.ps1 -PlanOnly
-& .\scripts\install-singbox.ps1 -PlanOnly
-```
-
-`-PlanOnly` returns structured JSON without install side effects. Real install
-or service operations must be explicit; profile apply must not silently install
-Proxyfier or Local sing-box.
+This repository keeps the gateway and Docker client runtime; it no longer owns
+the Tauri Windows app, ProxiFyre adapter, or Local sing-box installer flow.
Windows source configuration is owned by JSON under
`C:\ProgramData\VpnProxy\config`. Generated ProxiFyre and sing-box files under
diff --git a/apps/windows-client/.gitignore b/apps/windows-client/.gitignore
deleted file mode 100644
index cfcc268..0000000
--- a/apps/windows-client/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-node_modules/
-dist/
-src-tauri/target/
-
diff --git a/apps/windows-client/README.md b/apps/windows-client/README.md
deleted file mode 100644
index 043a3bd..0000000
--- a/apps/windows-client/README.md
+++ /dev/null
@@ -1,138 +0,0 @@
-# VPN Proxy Windows Client
-
-Standalone Windows desktop utility for app-level proxy routing. This app is
-separate from the current Docker gateway/client runtime and must not be wired
-through `APP_MODE=windows`.
-
-## Components
-
-- Control App: Tauri 2 + React/TypeScript UI and Rust command layer.
-- Proxyfier Layer: ProxiFyre adapter for per-application routing.
-- Local sing-box: optional local runtime, used only by targets that explicitly
- require `singbox`.
-
-External SOCKS5 targets are the MVP path and do not require Local sing-box.
-
-## Source And Generated Files
-
-Source configuration is owned by Rust domain models and JSON files under:
-
-```text
-C:\ProgramData\VpnProxy\config\profiles.json
-C:\ProgramData\VpnProxy\config\targets.json
-C:\ProgramData\VpnProxy\config\components.json
-C:\ProgramData\VpnProxy\config\local-singbox.json
-C:\ProgramData\VpnProxy\state\singbox-subscription-cache.json
-C:\ProgramData\VpnProxy\state\activity.json
-```
-
-Generated artifacts are derived and can be recreated:
-
-```text
-C:\ProgramData\VpnProxy\generated\proxifyre-app-config.json
-C:\ProgramData\VpnProxy\generated\sing-box-config.json
-```
-
-## Development
-
-```powershell
-cd apps/windows-client
-npm install
-npm run build
-```
-
-Run the browser preview shell:
-
-```powershell
-npm run dev -- --host 127.0.0.1
-```
-
-Run Tauri checks when the native Windows toolchain is installed:
-
-```powershell
-npm run tauri -- info
-npm run tauri -- dev
-npm run tauri -- build
-```
-
-Run Rust tests when Rust/Cargo are installed:
-
-```powershell
-cd apps/windows-client/src-tauri
-cargo test
-```
-
-Native Tauri build requires WebView2, Rust via rustup, and Visual Studio Build
-Tools with MSVC and Windows SDK components.
-
-## Explicit Installer Boundaries
-
-Installer scripts are explicit per component and return structured JSON in
-`-PlanOnly` mode:
-
-```powershell
-& .\scripts\install-control-app.ps1 -PlanOnly
-& .\scripts\install-proxyfier.ps1 -PlanOnly
-& .\scripts\install-singbox.ps1 -PlanOnly
-```
-
-Installers must be launched intentionally by the user or by a future narrow
-helper permission. Profile apply must not silently install Control App,
-Proxyfier, or Local sing-box.
-
-Local sing-box install creates this optional runtime:
-
-```text
-C:\Program Files\VpnProxy\sing-box\sing-box.exe
-C:\Program Files\VpnProxy\sing-box\VpnProxySingBox.exe
-Windows service: VpnProxySingBox
-```
-
-The install flow downloads `sing-box` from `SagerNet/sing-box` releases and the
-WinSW service wrapper from `winsw/winsw` releases, then writes a service config
-that points at `C:\ProgramData\VpnProxy\generated\sing-box-config.json`. It
-requires UAC confirmation. Uninstall is scoped to the configured
-`VpnProxy\sing-box` install root.
-
-The external proxy route remains independent from Local sing-box. Choosing
-Local sing-box in the UI generates `sing-box-config.json`, ensures the
-`local-singbox` SOCKS5 target at `127.0.0.1:1080`, and then applies ProxiFyre
-to that local target.
-
-## Existing Proxyfier Detection
-
-The app detects an already installed Proxyfier layer before showing component
-status or applying profiles. Detection checks:
-
-- uninstall registry entries for `ProxiFyre` and `Proxifier`;
-- common install folders such as `C:\Tools\ProxiFyre`,
- `%ProgramFiles%\ProxiFyre`, and `%ProgramFiles%\Proxifier`;
-- running `ProxiFyre` / `Proxifier` processes and the `ProxiFyreService`
- service.
-
-For portable installs, set an override before launching the app:
-
-```powershell
-$env:VPN_PROXY_PROXIFYRE_ROOT = 'D:\Tools\ProxiFyre'
-npm run tauri -- dev
-```
-
-`ProxiFyre` installs are compatible with the current generated
-`app-config.json` apply path. Plain `Proxifier` installs are detected and shown,
-but automatic profile apply is not enabled for them yet because they use a
-different profile format.
-
-## MVP Verification Flow
-
-1. Start the Control App or browser preview.
-2. Confirm Components shows Control App, Proxyfier Layer, and optional Local
- sing-box separately.
-3. Add or keep an external SOCKS5 target.
-4. Add a process/folder/exe profile such as Discord.
-5. Apply profiles and verify generated ProxiFyre config plus activity entry.
-6. Install Proxyfier separately before applying to a real service.
-7. Install and start Local sing-box only when using a local target.
-
-Task evidence is recorded in
-`docs/goals/windows-modular-client/EVIDENCE.md` and
-`docs/goals/windows-local-singbox/EVIDENCE.md`.
diff --git a/apps/windows-client/index.html b/apps/windows-client/index.html
deleted file mode 100644
index be02298..0000000
--- a/apps/windows-client/index.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
- VPN Proxy для Windows
-
-
-
-
-
-
diff --git a/apps/windows-client/package-lock.json b/apps/windows-client/package-lock.json
deleted file mode 100644
index 73cf8ca..0000000
--- a/apps/windows-client/package-lock.json
+++ /dev/null
@@ -1,2126 +0,0 @@
-{
- "name": "vpn-proxy-windows-client",
- "version": "0.1.0",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "vpn-proxy-windows-client",
- "version": "0.1.0",
- "dependencies": {
- "@tauri-apps/api": "^2.0.0",
- "@tauri-apps/plugin-dialog": "^2.7.1",
- "lucide-react": "^1.23.0",
- "react": "^19.0.0",
- "react-dom": "^19.0.0"
- },
- "devDependencies": {
- "@tauri-apps/cli": "^2.0.0",
- "@types/react": "^19.0.0",
- "@types/react-dom": "^19.0.0",
- "@vitejs/plugin-react": "^5.0.0",
- "typescript": "^5.8.0",
- "vite": "^7.0.0"
- }
- },
- "node_modules/@babel/code-frame": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz",
- "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-validator-identifier": "^7.29.7",
- "js-tokens": "^4.0.0",
- "picocolors": "^1.1.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/compat-data": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz",
- "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/core": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz",
- "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@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/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.1.0",
- "gensync": "^1.0.0-beta.2",
- "json5": "^2.2.3",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/babel"
- }
- },
- "node_modules/@babel/generator": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz",
- "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.29.7",
- "@babel/types": "^7.29.7",
- "@jridgewell/gen-mapping": "^0.3.12",
- "@jridgewell/trace-mapping": "^0.3.28",
- "jsesc": "^3.0.2"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-compilation-targets": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz",
- "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/compat-data": "^7.29.7",
- "@babel/helper-validator-option": "^7.29.7",
- "browserslist": "^4.24.0",
- "lru-cache": "^5.1.1",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-globals": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz",
- "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-module-imports": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz",
- "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/traverse": "^7.29.7",
- "@babel/types": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-module-transforms": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz",
- "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-module-imports": "^7.29.7",
- "@babel/helper-validator-identifier": "^7.29.7",
- "@babel/traverse": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/helper-plugin-utils": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz",
- "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-string-parser": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
- "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
- "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-option": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz",
- "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helpers": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz",
- "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/template": "^7.29.7",
- "@babel/types": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/parser": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz",
- "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.29.7"
- },
- "bin": {
- "parser": "bin/babel-parser.js"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/plugin-transform-react-jsx-self": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz",
- "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-react-jsx-source": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz",
- "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/template": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz",
- "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.29.7",
- "@babel/parser": "^7.29.7",
- "@babel/types": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/traverse": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz",
- "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@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.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/types": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz",
- "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-string-parser": "^7.29.7",
- "@babel/helper-validator-identifier": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@esbuild/aix-ppc64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz",
- "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "aix"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-arm": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz",
- "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz",
- "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz",
- "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/darwin-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz",
- "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/darwin-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz",
- "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/freebsd-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz",
- "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/freebsd-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz",
- "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-arm": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz",
- "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz",
- "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-ia32": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz",
- "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-loong64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz",
- "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-mips64el": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz",
- "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==",
- "cpu": [
- "mips64el"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-ppc64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz",
- "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-riscv64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz",
- "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-s390x": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz",
- "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz",
- "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/netbsd-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz",
- "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/netbsd-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz",
- "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openbsd-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz",
- "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openbsd-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz",
- "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openharmony-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz",
- "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openharmony"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/sunos-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz",
- "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "sunos"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz",
- "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-ia32": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz",
- "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz",
- "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.13",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
- "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.0",
- "@jridgewell/trace-mapping": "^0.3.24"
- }
- },
- "node_modules/@jridgewell/remapping": {
- "version": "2.3.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
- "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.24"
- }
- },
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
- "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.31",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
- "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
- }
- },
- "node_modules/@rolldown/pluginutils": {
- "version": "1.0.0-rc.3",
- "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz",
- "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.2.tgz",
- "integrity": "sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ]
- },
- "node_modules/@rollup/rollup-android-arm64": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.2.tgz",
- "integrity": "sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ]
- },
- "node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.2.tgz",
- "integrity": "sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.2.tgz",
- "integrity": "sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@rollup/rollup-freebsd-arm64": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.2.tgz",
- "integrity": "sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ]
- },
- "node_modules/@rollup/rollup-freebsd-x64": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.2.tgz",
- "integrity": "sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.2.tgz",
- "integrity": "sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "libc": [
- "glibc"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm-musleabihf": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.2.tgz",
- "integrity": "sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "libc": [
- "musl"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.2.tgz",
- "integrity": "sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "libc": [
- "glibc"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.2.tgz",
- "integrity": "sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "libc": [
- "musl"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-loong64-gnu": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.2.tgz",
- "integrity": "sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "libc": [
- "glibc"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-loong64-musl": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.2.tgz",
- "integrity": "sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "libc": [
- "musl"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-ppc64-gnu": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.2.tgz",
- "integrity": "sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "libc": [
- "glibc"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-ppc64-musl": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.2.tgz",
- "integrity": "sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "libc": [
- "musl"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.2.tgz",
- "integrity": "sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "libc": [
- "glibc"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-riscv64-musl": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.2.tgz",
- "integrity": "sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "libc": [
- "musl"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-s390x-gnu": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.2.tgz",
- "integrity": "sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "libc": [
- "glibc"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.2.tgz",
- "integrity": "sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "libc": [
- "glibc"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.2.tgz",
- "integrity": "sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "libc": [
- "musl"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-openbsd-x64": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.2.tgz",
- "integrity": "sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ]
- },
- "node_modules/@rollup/rollup-openharmony-arm64": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.2.tgz",
- "integrity": "sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openharmony"
- ]
- },
- "node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.2.tgz",
- "integrity": "sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.2.tgz",
- "integrity": "sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@rollup/rollup-win32-x64-gnu": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.2.tgz",
- "integrity": "sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.2.tgz",
- "integrity": "sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@tauri-apps/api": {
- "version": "2.11.1",
- "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.11.1.tgz",
- "integrity": "sha512-M2FPuYND2m+wh5hfW9ZpSdxMPdEJovPBWwoHJmwUpysTYNHaOkVFN419m/K0LIgjb/7KU2vBgsUepJWugQCvAA==",
- "license": "Apache-2.0 OR MIT",
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/tauri"
- }
- },
- "node_modules/@tauri-apps/cli": {
- "version": "2.11.4",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.11.4.tgz",
- "integrity": "sha512-R8xGtMpwyetawSqm9kYOuMmEqkhUbvcUy8n0aNXIxollKBLESUu5f4Fx+64hgASYm1H+jSWq6jCW6zqTnH6hqQ==",
- "dev": true,
- "license": "Apache-2.0 OR MIT",
- "bin": {
- "tauri": "tauri.js"
- },
- "engines": {
- "node": ">= 10"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/tauri"
- },
- "optionalDependencies": {
- "@tauri-apps/cli-darwin-arm64": "2.11.4",
- "@tauri-apps/cli-darwin-x64": "2.11.4",
- "@tauri-apps/cli-linux-arm-gnueabihf": "2.11.4",
- "@tauri-apps/cli-linux-arm64-gnu": "2.11.4",
- "@tauri-apps/cli-linux-arm64-musl": "2.11.4",
- "@tauri-apps/cli-linux-riscv64-gnu": "2.11.4",
- "@tauri-apps/cli-linux-x64-gnu": "2.11.4",
- "@tauri-apps/cli-linux-x64-musl": "2.11.4",
- "@tauri-apps/cli-win32-arm64-msvc": "2.11.4",
- "@tauri-apps/cli-win32-ia32-msvc": "2.11.4",
- "@tauri-apps/cli-win32-x64-msvc": "2.11.4"
- }
- },
- "node_modules/@tauri-apps/cli-darwin-arm64": {
- "version": "2.11.4",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.11.4.tgz",
- "integrity": "sha512-1ryOF3ZhpZ/nemHV5zVwBQBz9jDGKmKPvWPADOhc83ig0P4bMc2iER4NbC6r9sjeIZ6RVQ4g3RZIYvezhcl4TQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "Apache-2.0 OR MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tauri-apps/cli-darwin-x64": {
- "version": "2.11.4",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.11.4.tgz",
- "integrity": "sha512-uFsGQAAfuyz1k/yGLmkWfkBlgKAqZfxqlHmLWx81QU27RJWfmbNHCIq8T8w1e+VClleIuZUjpHWfoE4E3DLo3A==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "Apache-2.0 OR MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tauri-apps/cli-linux-arm-gnueabihf": {
- "version": "2.11.4",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.11.4.tgz",
- "integrity": "sha512-IaHZn5CdBL21oUmjiVOS1ctw6Ip1O0pjp70FwOWmYz1myWe0SY96ZIj2FYf7pT0m8bI2h/hrs5ZbEXXh44/MkQ==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "Apache-2.0 OR MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tauri-apps/cli-linux-arm64-gnu": {
- "version": "2.11.4",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.11.4.tgz",
- "integrity": "sha512-N41/ukTRVe6XSuUTESuFdGeOW2i7k62tK+6gHK5Kd5/q5RPvvi19GaWAVPPb9u95HSGmTChSolBfzynUsssFaA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "libc": [
- "glibc"
- ],
- "license": "Apache-2.0 OR MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tauri-apps/cli-linux-arm64-musl": {
- "version": "2.11.4",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.11.4.tgz",
- "integrity": "sha512-v277UnT/fB64xAfSroL5N3Km3tLmvATWqJJw/wRI+g6o+HkeD0slyE7gOhNs1MbjE41R7bQOTxMVoL3aomUJmw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "libc": [
- "musl"
- ],
- "license": "Apache-2.0 OR MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tauri-apps/cli-linux-riscv64-gnu": {
- "version": "2.11.4",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.11.4.tgz",
- "integrity": "sha512-qqgNkQ2u1yZHxjhxsZaxUtRDW8dIqIYm33rx/mzwQv0SfY9x1B+iraj8vWeFiXjjSVVhEMepXSOts1TqPzvXNQ==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "libc": [
- "glibc"
- ],
- "license": "Apache-2.0 OR MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tauri-apps/cli-linux-x64-gnu": {
- "version": "2.11.4",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.11.4.tgz",
- "integrity": "sha512-2VRNWl84FOH0m2giiDkO2h0QXlcMJeX+zJDpI5kDIQAx6s+geF3v48F4DXfJez4GS/FdoDGnPnw1C2iYGbQ7bQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "libc": [
- "glibc"
- ],
- "license": "Apache-2.0 OR MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tauri-apps/cli-linux-x64-musl": {
- "version": "2.11.4",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.11.4.tgz",
- "integrity": "sha512-o9GyhYor/nc7xarmwDE3ka2szuW3uuZzXjHWh64Q8YX5AtSgxdQkFWzrY4O8KiGtVNvFBI14H3Q49Qj5TOIP/A==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "libc": [
- "musl"
- ],
- "license": "Apache-2.0 OR MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tauri-apps/cli-win32-arm64-msvc": {
- "version": "2.11.4",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.11.4.tgz",
- "integrity": "sha512-ld5Ehb598m0VkYyylRPNeCFsBe/km0jxis6KgMpl3IGY6I/i1RwQXO05I1AsXUXO2WC6AvB/Lw4qTf/asiuEiQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "Apache-2.0 OR MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tauri-apps/cli-win32-ia32-msvc": {
- "version": "2.11.4",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.11.4.tgz",
- "integrity": "sha512-12Hxi0XX/H5VFxO/bGgHkFWhml9VMgEOu9CidjeCeTNQ1l6fpUlbiGgSP7CLI3PFtW9/FfbeHieZ+kyWK5H7CA==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "Apache-2.0 OR MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tauri-apps/cli-win32-x64-msvc": {
- "version": "2.11.4",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.11.4.tgz",
- "integrity": "sha512-+vDiqBIU5dMISg/wNvX3sF+ZHfgJGJ5T0AcO+EHNXV9GGAG+P5fzodlDXD3QdKCRgZxMoCm5PPvj3BqLNjBthw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "Apache-2.0 OR MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tauri-apps/plugin-dialog": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.7.1.tgz",
- "integrity": "sha512-OK1UBXYt+ojcmxMktzzuyonYIFta8CmAASpX+CA+DTGK24KlHjhYI6x2iOJ/TjZF4N7/ACK1oFmEOjIY9IhzOQ==",
- "license": "MIT OR Apache-2.0",
- "dependencies": {
- "@tauri-apps/api": "^2.11.0"
- }
- },
- "node_modules/@types/babel__core": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
- "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.20.7",
- "@babel/types": "^7.20.7",
- "@types/babel__generator": "*",
- "@types/babel__template": "*",
- "@types/babel__traverse": "*"
- }
- },
- "node_modules/@types/babel__generator": {
- "version": "7.27.0",
- "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
- "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.0.0"
- }
- },
- "node_modules/@types/babel__template": {
- "version": "7.4.4",
- "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
- "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.1.0",
- "@babel/types": "^7.0.0"
- }
- },
- "node_modules/@types/babel__traverse": {
- "version": "7.28.0",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
- "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.28.2"
- }
- },
- "node_modules/@types/estree": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",
- "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/react": {
- "version": "19.2.17",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz",
- "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "csstype": "^3.2.2"
- }
- },
- "node_modules/@types/react-dom": {
- "version": "19.2.3",
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
- "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
- "dev": true,
- "license": "MIT",
- "peerDependencies": {
- "@types/react": "^19.2.0"
- }
- },
- "node_modules/@vitejs/plugin-react": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.2.0.tgz",
- "integrity": "sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/core": "^7.29.0",
- "@babel/plugin-transform-react-jsx-self": "^7.27.1",
- "@babel/plugin-transform-react-jsx-source": "^7.27.1",
- "@rolldown/pluginutils": "1.0.0-rc.3",
- "@types/babel__core": "^7.20.5",
- "react-refresh": "^0.18.0"
- },
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- },
- "peerDependencies": {
- "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
- }
- },
- "node_modules/baseline-browser-mapping": {
- "version": "2.10.41",
- "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.41.tgz",
- "integrity": "sha512-WwS7MHhqGHHlaVsqRZnhvCEMS0owDX+SxRlve7JkuH7My1Ara3ZriTmCQupPfYjxMZ8I/tgxtJYr2t7taHaH4A==",
- "dev": true,
- "license": "Apache-2.0",
- "bin": {
- "baseline-browser-mapping": "dist/cli.cjs"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/browserslist": {
- "version": "4.28.4",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.4.tgz",
- "integrity": "sha512-MTc8i/x9jBQd1iMw2CFGS+rwMa07eYjLR0CCTLDACl9xhxy+nIs3KeML/biicXtk9JrZ6dnnTatmc7ErPXIxqw==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "baseline-browser-mapping": "^2.10.38",
- "caniuse-lite": "^1.0.30001799",
- "electron-to-chromium": "^1.5.376",
- "node-releases": "^2.0.48",
- "update-browserslist-db": "^1.2.3"
- },
- "bin": {
- "browserslist": "cli.js"
- },
- "engines": {
- "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
- }
- },
- "node_modules/caniuse-lite": {
- "version": "1.0.30001800",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001800.tgz",
- "integrity": "sha512-MMHtuAz9Ys840zAY5F4k6fV5GaivZ9sPk+nz0mY+GYVzRBnYkN0mpqkSR92oWRQ19yQWo4HvBV/FnC16AJX8MA==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "CC-BY-4.0"
- },
- "node_modules/convert-source-map": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
- "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/csstype": {
- "version": "3.2.3",
- "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
- "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/debug": {
- "version": "4.4.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
- "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/electron-to-chromium": {
- "version": "1.5.385",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.385.tgz",
- "integrity": "sha512-78sa/M08MNAYHQfjoWMvOlKQqZ0ElhSm/L5HNUc96VZ3b+KvDVnngFm8sYQy0XrhTRgAhggHr5abA7yTvRdo4Q==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/esbuild": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz",
- "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "engines": {
- "node": ">=18"
- },
- "optionalDependencies": {
- "@esbuild/aix-ppc64": "0.28.1",
- "@esbuild/android-arm": "0.28.1",
- "@esbuild/android-arm64": "0.28.1",
- "@esbuild/android-x64": "0.28.1",
- "@esbuild/darwin-arm64": "0.28.1",
- "@esbuild/darwin-x64": "0.28.1",
- "@esbuild/freebsd-arm64": "0.28.1",
- "@esbuild/freebsd-x64": "0.28.1",
- "@esbuild/linux-arm": "0.28.1",
- "@esbuild/linux-arm64": "0.28.1",
- "@esbuild/linux-ia32": "0.28.1",
- "@esbuild/linux-loong64": "0.28.1",
- "@esbuild/linux-mips64el": "0.28.1",
- "@esbuild/linux-ppc64": "0.28.1",
- "@esbuild/linux-riscv64": "0.28.1",
- "@esbuild/linux-s390x": "0.28.1",
- "@esbuild/linux-x64": "0.28.1",
- "@esbuild/netbsd-arm64": "0.28.1",
- "@esbuild/netbsd-x64": "0.28.1",
- "@esbuild/openbsd-arm64": "0.28.1",
- "@esbuild/openbsd-x64": "0.28.1",
- "@esbuild/openharmony-arm64": "0.28.1",
- "@esbuild/sunos-x64": "0.28.1",
- "@esbuild/win32-arm64": "0.28.1",
- "@esbuild/win32-ia32": "0.28.1",
- "@esbuild/win32-x64": "0.28.1"
- }
- },
- "node_modules/escalade": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
- "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/fdir": {
- "version": "6.5.0",
- "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
- "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12.0.0"
- },
- "peerDependencies": {
- "picomatch": "^3 || ^4"
- },
- "peerDependenciesMeta": {
- "picomatch": {
- "optional": true
- }
- }
- },
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
- "node_modules/gensync": {
- "version": "1.0.0-beta.2",
- "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
- "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/js-tokens": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/jsesc": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
- "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "jsesc": "bin/jsesc"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/json5": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
- "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "json5": "lib/cli.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/lru-cache": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
- "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "yallist": "^3.0.2"
- }
- },
- "node_modules/lucide-react": {
- "version": "1.23.0",
- "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.23.0.tgz",
- "integrity": "sha512-38BpJcD0JhFosxHApP/BYsBetLpQFRoTRzEzstM/XCc3jsAG7wqaY1lgVwxiUe3xqYE+lNxo2PkCmYwXWrwwIw==",
- "license": "ISC",
- "peerDependencies": {
- "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
- }
- },
- "node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/nanoid": {
- "version": "3.3.15",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz",
- "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "bin": {
- "nanoid": "bin/nanoid.cjs"
- },
- "engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
- }
- },
- "node_modules/node-releases": {
- "version": "2.0.50",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.50.tgz",
- "integrity": "sha512-J6l92tKHX6w8Jy5nO1Vuc01NoIiRGi/d6qBKVxh+IQ8Cr3b6HbVNfKiF8ZpFKufTwpwxMmce2W3iQZ861ZRyTg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/picocolors": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
- "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/picomatch": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz",
- "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/postcss": {
- "version": "8.5.16",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.16.tgz",
- "integrity": "sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "nanoid": "^3.3.12",
- "picocolors": "^1.1.1",
- "source-map-js": "^1.2.1"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- }
- },
- "node_modules/react": {
- "version": "19.2.7",
- "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz",
- "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/react-dom": {
- "version": "19.2.7",
- "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz",
- "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==",
- "license": "MIT",
- "dependencies": {
- "scheduler": "^0.27.0"
- },
- "peerDependencies": {
- "react": "^19.2.7"
- }
- },
- "node_modules/react-refresh": {
- "version": "0.18.0",
- "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz",
- "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/rollup": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.2.tgz",
- "integrity": "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/estree": "1.0.9"
- },
- "bin": {
- "rollup": "dist/bin/rollup"
- },
- "engines": {
- "node": ">=18.0.0",
- "npm": ">=8.0.0"
- },
- "optionalDependencies": {
- "@rollup/rollup-android-arm-eabi": "4.62.2",
- "@rollup/rollup-android-arm64": "4.62.2",
- "@rollup/rollup-darwin-arm64": "4.62.2",
- "@rollup/rollup-darwin-x64": "4.62.2",
- "@rollup/rollup-freebsd-arm64": "4.62.2",
- "@rollup/rollup-freebsd-x64": "4.62.2",
- "@rollup/rollup-linux-arm-gnueabihf": "4.62.2",
- "@rollup/rollup-linux-arm-musleabihf": "4.62.2",
- "@rollup/rollup-linux-arm64-gnu": "4.62.2",
- "@rollup/rollup-linux-arm64-musl": "4.62.2",
- "@rollup/rollup-linux-loong64-gnu": "4.62.2",
- "@rollup/rollup-linux-loong64-musl": "4.62.2",
- "@rollup/rollup-linux-ppc64-gnu": "4.62.2",
- "@rollup/rollup-linux-ppc64-musl": "4.62.2",
- "@rollup/rollup-linux-riscv64-gnu": "4.62.2",
- "@rollup/rollup-linux-riscv64-musl": "4.62.2",
- "@rollup/rollup-linux-s390x-gnu": "4.62.2",
- "@rollup/rollup-linux-x64-gnu": "4.62.2",
- "@rollup/rollup-linux-x64-musl": "4.62.2",
- "@rollup/rollup-openbsd-x64": "4.62.2",
- "@rollup/rollup-openharmony-arm64": "4.62.2",
- "@rollup/rollup-win32-arm64-msvc": "4.62.2",
- "@rollup/rollup-win32-ia32-msvc": "4.62.2",
- "@rollup/rollup-win32-x64-gnu": "4.62.2",
- "@rollup/rollup-win32-x64-msvc": "4.62.2",
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/scheduler": {
- "version": "0.27.0",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
- "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
- "license": "MIT"
- },
- "node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- }
- },
- "node_modules/source-map-js": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
- "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
- "dev": true,
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/tinyglobby": {
- "version": "0.2.17",
- "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",
- "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fdir": "^6.5.0",
- "picomatch": "^4.0.4"
- },
- "engines": {
- "node": ">=12.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/SuperchupuDev"
- }
- },
- "node_modules/typescript": {
- "version": "5.9.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
- "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
- "dev": true,
- "license": "Apache-2.0",
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=14.17"
- }
- },
- "node_modules/update-browserslist-db": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
- "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "escalade": "^3.2.0",
- "picocolors": "^1.1.1"
- },
- "bin": {
- "update-browserslist-db": "cli.js"
- },
- "peerDependencies": {
- "browserslist": ">= 4.21.0"
- }
- },
- "node_modules/vite": {
- "version": "7.3.6",
- "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.6.tgz",
- "integrity": "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "esbuild": "^0.27.0 || ^0.28.0",
- "fdir": "^6.5.0",
- "picomatch": "^4.0.3",
- "postcss": "^8.5.6",
- "rollup": "^4.43.0",
- "tinyglobby": "^0.2.15"
- },
- "bin": {
- "vite": "bin/vite.js"
- },
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- },
- "funding": {
- "url": "https://github.com/vitejs/vite?sponsor=1"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.3"
- },
- "peerDependencies": {
- "@types/node": "^20.19.0 || >=22.12.0",
- "jiti": ">=1.21.0",
- "less": "^4.0.0",
- "lightningcss": "^1.21.0",
- "sass": "^1.70.0",
- "sass-embedded": "^1.70.0",
- "stylus": ">=0.54.8",
- "sugarss": "^5.0.0",
- "terser": "^5.16.0",
- "tsx": "^4.8.1",
- "yaml": "^2.4.2"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- },
- "jiti": {
- "optional": true
- },
- "less": {
- "optional": true
- },
- "lightningcss": {
- "optional": true
- },
- "sass": {
- "optional": true
- },
- "sass-embedded": {
- "optional": true
- },
- "stylus": {
- "optional": true
- },
- "sugarss": {
- "optional": true
- },
- "terser": {
- "optional": true
- },
- "tsx": {
- "optional": true
- },
- "yaml": {
- "optional": true
- }
- }
- },
- "node_modules/yallist": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
- "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
- "dev": true,
- "license": "ISC"
- }
- }
-}
diff --git a/apps/windows-client/package.json b/apps/windows-client/package.json
deleted file mode 100644
index 62c35bc..0000000
--- a/apps/windows-client/package.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "name": "vpn-proxy-windows-client",
- "version": "0.1.0",
- "private": true,
- "type": "module",
- "description": "Standalone Windows desktop proxy management app for VPN Proxy.",
- "scripts": {
- "dev": "vite",
- "build": "tsc && vite build",
- "preview": "vite preview",
- "tauri": "tauri"
- },
- "dependencies": {
- "@tauri-apps/api": "^2.0.0",
- "@tauri-apps/plugin-dialog": "^2.7.1",
- "lucide-react": "^1.23.0",
- "react": "^19.0.0",
- "react-dom": "^19.0.0"
- },
- "devDependencies": {
- "@tauri-apps/cli": "^2.0.0",
- "@types/react": "^19.0.0",
- "@types/react-dom": "^19.0.0",
- "@vitejs/plugin-react": "^5.0.0",
- "typescript": "^5.8.0",
- "vite": "^7.0.0"
- }
-}
diff --git a/apps/windows-client/scripts/install-control-app.ps1 b/apps/windows-client/scripts/install-control-app.ps1
deleted file mode 100644
index bef4573..0000000
--- a/apps/windows-client/scripts/install-control-app.ps1
+++ /dev/null
@@ -1,79 +0,0 @@
-param(
- [string]$InstallRoot = "C:\Program Files\VpnProxy\ControlApp",
- [string]$DataRoot = "C:\ProgramData\VpnProxy",
- [switch]$PlanOnly,
- [switch]$Force
-)
-
-$ErrorActionPreference = "Stop"
-
-function New-Result {
- param(
- [bool]$Success,
- [string]$Action,
- [bool]$Changed,
- [string]$Message,
- [hashtable]$Details = @{}
- )
-
- [ordered]@{
- success = $Success
- action = $Action
- changed = $Changed
- message = $Message
- details = $Details
- } | ConvertTo-Json -Depth 6
-}
-
-function Test-IsAdministrator {
- $identity = [Security.Principal.WindowsIdentity]::GetCurrent()
- $principal = [Security.Principal.WindowsPrincipal]::new($identity)
- $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
-}
-
-function Ensure-Directory {
- param([string]$Path)
- if (-not (Test-Path -LiteralPath $Path)) {
- New-Item -ItemType Directory -Path $Path -Force | Out-Null
- return $true
- }
- return $false
-}
-
-try {
- $details = @{
- installRoot = $InstallRoot
- dataRoot = $DataRoot
- planOnly = [bool]$PlanOnly
- }
-
- if ($PlanOnly) {
- New-Result -Success $true -Action "install-control-app" -Changed $false -Message "Control App install plan is ready." -Details $details
- exit 0
- }
-
- if (-not (Test-IsAdministrator)) {
- New-Result -Success $false -Action "install-control-app" -Changed $false -Message "Administrator rights are required." -Details $details
- exit 1
- }
-
- $changed = $false
- $changed = (Ensure-Directory -Path $InstallRoot) -or $changed
- $changed = (Ensure-Directory -Path (Join-Path $DataRoot "config")) -or $changed
- $changed = (Ensure-Directory -Path (Join-Path $DataRoot "state")) -or $changed
- $changed = (Ensure-Directory -Path (Join-Path $DataRoot "generated")) -or $changed
-
- $markerPath = Join-Path $InstallRoot "install-control-app.marker.json"
- if ((-not (Test-Path -LiteralPath $markerPath)) -or $Force) {
- @{ component = "control-app"; installedAt = (Get-Date).ToString("o") } |
- ConvertTo-Json -Depth 4 |
- Set-Content -LiteralPath $markerPath -Encoding UTF8
- $changed = $true
- }
-
- $details.markerPath = $markerPath
- New-Result -Success $true -Action "install-control-app" -Changed $changed -Message "Control App directories are installed." -Details $details
-} catch {
- New-Result -Success $false -Action "install-control-app" -Changed $false -Message $_.Exception.Message
- exit 1
-}
diff --git a/apps/windows-client/scripts/install-proxyfier.ps1 b/apps/windows-client/scripts/install-proxyfier.ps1
deleted file mode 100644
index 521c438..0000000
--- a/apps/windows-client/scripts/install-proxyfier.ps1
+++ /dev/null
@@ -1,96 +0,0 @@
-param(
- [string]$InstallRoot = "C:\Tools\ProxiFyre",
- [string]$PackagePath = "",
- [string]$ServiceName = "ProxiFyreService",
- [switch]$PlanOnly,
- [switch]$Force
-)
-
-$ErrorActionPreference = "Stop"
-
-function New-Result {
- param(
- [bool]$Success,
- [string]$Action,
- [bool]$Changed,
- [string]$Message,
- [hashtable]$Details = @{}
- )
-
- [ordered]@{
- success = $Success
- action = $Action
- changed = $Changed
- message = $Message
- details = $Details
- } | ConvertTo-Json -Depth 6
-}
-
-function Test-IsAdministrator {
- $identity = [Security.Principal.WindowsIdentity]::GetCurrent()
- $principal = [Security.Principal.WindowsPrincipal]::new($identity)
- $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
-}
-
-function Backup-File {
- param([string]$Path)
- if (Test-Path -LiteralPath $Path) {
- $backup = "$Path.bak"
- Copy-Item -LiteralPath $Path -Destination $backup -Force
- return $backup
- }
- return $null
-}
-
-try {
- $details = @{
- installRoot = $InstallRoot
- packagePath = $PackagePath
- serviceName = $ServiceName
- planOnly = [bool]$PlanOnly
- }
-
- if ($PlanOnly) {
- New-Result -Success $true -Action "install-proxyfier" -Changed $false -Message "Proxyfier install plan is ready." -Details $details
- exit 0
- }
-
- if (-not (Test-IsAdministrator)) {
- New-Result -Success $false -Action "install-proxyfier" -Changed $false -Message "Administrator rights are required." -Details $details
- exit 1
- }
-
- if ([string]::IsNullOrWhiteSpace($PackagePath) -or -not (Test-Path -LiteralPath $PackagePath)) {
- New-Result -Success $false -Action "install-proxyfier" -Changed $false -Message "PackagePath is required and must point to a local ProxiFyre package." -Details $details
- exit 2
- }
-
- $changed = $false
- if (-not (Test-Path -LiteralPath $InstallRoot)) {
- New-Item -ItemType Directory -Path $InstallRoot -Force | Out-Null
- $changed = $true
- }
-
- $configPath = Join-Path $InstallRoot "app-config.json"
- $backupPath = Backup-File -Path $configPath
- if ($backupPath) {
- $details.backupPath = $backupPath
- }
-
- $markerPath = Join-Path $InstallRoot "install-proxyfier.marker.json"
- if ((-not (Test-Path -LiteralPath $markerPath)) -or $Force) {
- @{
- component = "proxyfier"
- packagePath = $PackagePath
- serviceName = $ServiceName
- installedAt = (Get-Date).ToString("o")
- } | ConvertTo-Json -Depth 4 | Set-Content -LiteralPath $markerPath -Encoding UTF8
- $changed = $true
- }
-
- $details.markerPath = $markerPath
- New-Result -Success $true -Action "install-proxyfier" -Changed $changed -Message "Proxyfier install boundary completed." -Details $details
-} catch {
- New-Result -Success $false -Action "install-proxyfier" -Changed $false -Message $_.Exception.Message
- exit 1
-}
diff --git a/apps/windows-client/scripts/install-singbox.ps1 b/apps/windows-client/scripts/install-singbox.ps1
deleted file mode 100644
index f69eefe..0000000
--- a/apps/windows-client/scripts/install-singbox.ps1
+++ /dev/null
@@ -1,270 +0,0 @@
-param(
- [string]$InstallRoot = "C:\Program Files\VpnProxy\sing-box",
- [string]$ServiceName = "VpnProxySingBox",
- [string]$ConfigSource = "C:\ProgramData\VpnProxy\generated\sing-box-config.json",
- [switch]$PlanOnly,
- [switch]$Force,
- [switch]$Uninstall
-)
-
-$ErrorActionPreference = "Stop"
-
-$SingBoxReleaseApi = "https://api.github.com/repos/SagerNet/sing-box/releases/latest"
-$WinSwReleaseApi = "https://api.github.com/repos/winsw/winsw/releases/latest"
-$WrapperFile = "$ServiceName.exe"
-$ConfigFile = "config.json"
-
-function New-Result {
- param(
- [bool]$Success,
- [string]$Action,
- [bool]$Changed,
- [string]$Message,
- [hashtable]$Details = @{}
- )
-
- [ordered]@{
- success = $Success
- action = $Action
- changed = $Changed
- message = $Message
- details = $Details
- } | ConvertTo-Json -Depth 8
-}
-
-function Test-IsAdministrator {
- $identity = [Security.Principal.WindowsIdentity]::GetCurrent()
- $principal = [Security.Principal.WindowsPrincipal]::new($identity)
- $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
-}
-
-function Get-NativeArchitecture {
- $processor = Get-CimInstance Win32_Processor | Select-Object -First 1
- if ($null -ne $processor -and $processor.Architecture -eq 12) { return "arm64" }
- if ([Environment]::Is64BitOperatingSystem) { return "amd64" }
- return "386"
-}
-
-function Get-WinSwArchitecture {
- param([string]$Arch)
- if ($Arch -eq "arm64") { return "arm64" }
- if ($Arch -eq "386") { return "x86" }
- return "x64"
-}
-
-function Invoke-Download {
- param([string]$Uri, [string]$Path)
- Invoke-WebRequest -UseBasicParsing -Uri $Uri -OutFile $Path -Headers @{ "User-Agent" = "vpn-proxy-windows-client" }
-}
-
-function Select-Asset {
- param(
- [object[]]$Assets,
- [string]$Pattern,
- [string]$Label
- )
-
- $asset = $Assets | Where-Object { $_.name -match $Pattern } | Select-Object -First 1
- if ($null -eq $asset) {
- throw "Не найден release asset для $Label по шаблону $Pattern."
- }
- return $asset
-}
-
-function Test-SafeInstallRoot {
- param([string]$Path)
- $full = [System.IO.Path]::GetFullPath($Path).TrimEnd("\")
- $leaf = Split-Path -Leaf $full
- $parent = Split-Path -Parent $full
- if ($leaf -ne "sing-box") { return $false }
- return $parent -match "\\VpnProxy$|\\vpn-proxy$"
-}
-
-function Backup-File {
- param([string]$Path)
- if (Test-Path -LiteralPath $Path) {
- $backup = "$Path.bak"
- Copy-Item -LiteralPath $Path -Destination $backup -Force
- return $backup
- }
- return $null
-}
-
-function Write-Utf8NoBomFile {
- param(
- [string]$Path,
- [string]$Value
- )
-
- $encoding = New-Object System.Text.UTF8Encoding $false
- [System.IO.File]::WriteAllText($Path, $Value, $encoding)
-}
-
-function Write-WinSwConfig {
- param(
- [string]$Root,
- [string]$Name
- )
-
- $xmlPath = Join-Path $Root "$Name.xml"
- $logDir = Join-Path $Root "logs"
- New-Item -ItemType Directory -Path $logDir -Force | Out-Null
- $xml = @"
-
- $Name
- VPN Proxy Local sing-box
- Local sing-box runtime managed by VPN Proxy Windows client.
- %BASE%\sing-box.exe
- run -c "%BASE%\config.json"
- %BASE%\logs
-
- 10485760
- 4
-
-
-
-"@
- Write-Utf8NoBomFile -Path $xmlPath -Value $xml
- return $xmlPath
-}
-
-function Stop-And-Uninstall-Service {
- param(
- [string]$Root,
- [string]$Name
- )
-
- $wrapper = Join-Path $Root "$Name.exe"
- $service = Get-Service -Name $Name -ErrorAction SilentlyContinue
- if ($null -ne $service -and $service.Status -ne "Stopped") {
- Stop-Service -Name $Name -Force -ErrorAction SilentlyContinue
- $service = Get-Service -Name $Name -ErrorAction SilentlyContinue
- if ($null -ne $service) {
- try { $service.WaitForStatus("Stopped", [TimeSpan]::FromSeconds(15)) } catch {}
- }
- }
-
- if (Test-Path -LiteralPath $wrapper) {
- Push-Location $Root
- try { & $wrapper uninstall | Out-Null } finally { Pop-Location }
- }
-
- $service = Get-Service -Name $Name -ErrorAction SilentlyContinue
- if ($null -ne $service) {
- sc.exe delete $Name | Out-Null
- }
-}
-
-try {
- [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
- $installRootFull = [System.IO.Path]::GetFullPath($InstallRoot)
- $details = @{
- installRoot = $installRootFull
- serviceName = $ServiceName
- configSource = $ConfigSource
- singboxReleaseApi = $SingBoxReleaseApi
- winswReleaseApi = $WinSwReleaseApi
- planOnly = [bool]$PlanOnly
- uninstall = [bool]$Uninstall
- }
-
- if ($PlanOnly) {
- $details.items = @(
- @{ id = "sing-box-binary"; name = "sing-box.exe"; source = $SingBoxReleaseApi; target = (Join-Path $installRootFull "sing-box.exe") },
- @{ id = "winsw-wrapper"; name = $WrapperFile; source = $WinSwReleaseApi; target = (Join-Path $installRootFull $WrapperFile) },
- @{ id = "windows-service"; name = $ServiceName; target = "Windows Service" },
- @{ id = "config"; name = $ConfigFile; source = $ConfigSource; target = (Join-Path $installRootFull $ConfigFile) }
- )
- New-Result -Success $true -Action "install-singbox.plan" -Changed $false -Message "Local sing-box install plan is ready." -Details $details
- exit 0
- }
-
- if (-not (Test-IsAdministrator)) {
- New-Result -Success $false -Action "install-singbox" -Changed $false -Message "Administrator rights are required." -Details $details
- exit 1
- }
-
- if ($Uninstall) {
- if (-not (Test-SafeInstallRoot -Path $installRootFull)) {
- New-Result -Success $false -Action "uninstall-singbox" -Changed $false -Message "Unsafe InstallRoot for recursive uninstall." -Details $details
- exit 2
- }
-
- Stop-And-Uninstall-Service -Root $installRootFull -Name $ServiceName
- if (Test-Path -LiteralPath $installRootFull) {
- Remove-Item -LiteralPath $installRootFull -Recurse -Force
- }
- New-Result -Success $true -Action "uninstall-singbox" -Changed $true -Message "Local sing-box service and install folder were removed." -Details $details
- exit 0
- }
-
- $changed = $false
- New-Item -ItemType Directory -Path $installRootFull -Force | Out-Null
- $workDir = Join-Path ([System.IO.Path]::GetTempPath()) ("vpn-proxy-singbox-" + [guid]::NewGuid().ToString("N"))
- $extractDir = Join-Path $workDir "extract"
- New-Item -ItemType Directory -Path $extractDir -Force | Out-Null
-
- try {
- $arch = Get-NativeArchitecture
- $winswArch = Get-WinSwArchitecture -Arch $arch
- $details.architecture = $arch
- $details.winswArchitecture = $winswArch
-
- $singboxRelease = Invoke-RestMethod -Uri $SingBoxReleaseApi -Headers @{ "User-Agent" = "vpn-proxy-windows-client" }
- $singboxAsset = Select-Asset $singboxRelease.assets "windows-$arch\.zip$" "sing-box"
- $singboxZip = Join-Path $workDir $singboxAsset.name
- Invoke-Download $singboxAsset.browser_download_url $singboxZip
- Expand-Archive -LiteralPath $singboxZip -DestinationPath $extractDir -Force
- $singboxExe = Get-ChildItem -LiteralPath $extractDir -Recurse -Filter "sing-box.exe" | Select-Object -First 1
- if ($null -eq $singboxExe) { throw "В архиве sing-box не найден sing-box.exe." }
- Copy-Item -LiteralPath $singboxExe.FullName -Destination (Join-Path $installRootFull "sing-box.exe") -Force
- $changed = $true
-
- $winswRelease = Invoke-RestMethod -Uri $WinSwReleaseApi -Headers @{ "User-Agent" = "vpn-proxy-windows-client" }
- $winswAsset = Select-Asset $winswRelease.assets "WinSW-$winswArch\.exe$" "WinSW"
- Invoke-Download $winswAsset.browser_download_url (Join-Path $installRootFull $WrapperFile)
- $changed = $true
-
- $configTarget = Join-Path $installRootFull $ConfigFile
- $backupPath = Backup-File -Path $configTarget
- if ($backupPath) { $details.backupPath = $backupPath }
- if (Test-Path -LiteralPath $ConfigSource) {
- Copy-Item -LiteralPath $ConfigSource -Destination $configTarget -Force
- } elseif (-not (Test-Path -LiteralPath $configTarget)) {
- Write-Utf8NoBomFile -Path $configTarget -Value '{"log":{"level":"info","timestamp":true},"inbounds":[],"outbounds":[{"type":"direct","tag":"direct"}],"route":{"final":"direct"}}'
- }
-
- $xmlPath = Write-WinSwConfig -Root $installRootFull -Name $ServiceName
- $details.configPath = $configTarget
- $details.wrapperConfigPath = $xmlPath
-
- if ($Force) {
- Stop-And-Uninstall-Service -Root $installRootFull -Name $ServiceName
- }
-
- Push-Location $installRootFull
- try {
- $service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
- if ($null -eq $service) {
- & ".\$WrapperFile" install
- if ($LASTEXITCODE -ne 0) { throw "WinSW install завершился с кодом $LASTEXITCODE." }
- $changed = $true
- }
- & ".\$WrapperFile" start
- if ($LASTEXITCODE -ne 0) {
- Start-Service -Name $ServiceName -ErrorAction Stop
- }
- } finally {
- Pop-Location
- }
- } finally {
- if (Test-Path -LiteralPath $workDir) {
- Remove-Item -LiteralPath $workDir -Recurse -Force -ErrorAction SilentlyContinue
- }
- }
-
- New-Result -Success $true -Action "install-singbox" -Changed $changed -Message "Local sing-box service is installed and started." -Details $details
-} catch {
- New-Result -Success $false -Action "install-singbox" -Changed $false -Message $_.Exception.Message
- exit 1
-}
diff --git a/apps/windows-client/src-tauri/Cargo.lock b/apps/windows-client/src-tauri/Cargo.lock
deleted file mode 100644
index e13342c..0000000
--- a/apps/windows-client/src-tauri/Cargo.lock
+++ /dev/null
@@ -1,4850 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-version = 4
-
-[[package]]
-name = "adler2"
-version = "2.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
-
-[[package]]
-name = "aho-corasick"
-version = "1.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "alloc-no-stdlib"
-version = "2.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3"
-
-[[package]]
-name = "alloc-stdlib"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e76a019e91224d279006ff972f1e984179a6e9feb050adba6ce8274aef23195"
-dependencies = [
- "alloc-no-stdlib",
-]
-
-[[package]]
-name = "android_system_properties"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "anyhow"
-version = "1.0.103"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3"
-
-[[package]]
-name = "atk"
-version = "0.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "241b621213072e993be4f6f3a9e4b45f65b7e6faad43001be957184b7bb1824b"
-dependencies = [
- "atk-sys",
- "glib",
- "libc",
-]
-
-[[package]]
-name = "atk-sys"
-version = "0.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c5e48b684b0ca77d2bbadeef17424c2ea3c897d44d566a1617e7e8f30614d086"
-dependencies = [
- "glib-sys",
- "gobject-sys",
- "libc",
- "system-deps",
-]
-
-[[package]]
-name = "atomic-waker"
-version = "1.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
-
-[[package]]
-name = "autocfg"
-version = "1.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
-
-[[package]]
-name = "base64"
-version = "0.21.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
-
-[[package]]
-name = "base64"
-version = "0.22.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
-
-[[package]]
-name = "bit-set"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3"
-dependencies = [
- "bit-vec",
-]
-
-[[package]]
-name = "bit-vec"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
-
-[[package]]
-name = "bitflags"
-version = "1.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
-
-[[package]]
-name = "bitflags"
-version = "2.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8"
-dependencies = [
- "serde_core",
-]
-
-[[package]]
-name = "block-buffer"
-version = "0.10.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
-dependencies = [
- "generic-array",
-]
-
-[[package]]
-name = "block2"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5"
-dependencies = [
- "objc2",
-]
-
-[[package]]
-name = "brotli"
-version = "8.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5cc91aac060a7a1e25823bdccbfb6af1875b88f17c6daac97894eed8207166b3"
-dependencies = [
- "alloc-no-stdlib",
- "alloc-stdlib",
- "brotli-decompressor",
-]
-
-[[package]]
-name = "brotli-decompressor"
-version = "5.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a32acac15fe1967bc3986b2a6347dffc965602354ea6f450ad07e8bfd253583"
-dependencies = [
- "alloc-no-stdlib",
- "alloc-stdlib",
-]
-
-[[package]]
-name = "bs58"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4"
-dependencies = [
- "tinyvec",
-]
-
-[[package]]
-name = "bumpalo"
-version = "3.20.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
-
-[[package]]
-name = "bytemuck"
-version = "1.25.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec"
-
-[[package]]
-name = "byteorder"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
-
-[[package]]
-name = "bytes"
-version = "1.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "cairo-rs"
-version = "0.18.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2"
-dependencies = [
- "bitflags 2.13.0",
- "cairo-sys-rs",
- "glib",
- "libc",
- "once_cell",
- "thiserror 1.0.69",
-]
-
-[[package]]
-name = "cairo-sys-rs"
-version = "0.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "685c9fa8e590b8b3d678873528d83411db17242a73fccaed827770ea0fedda51"
-dependencies = [
- "glib-sys",
- "libc",
- "system-deps",
-]
-
-[[package]]
-name = "camino"
-version = "1.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f2d30e4173c4026932d51d31d6b0613b1fd3014bf3f9f8943d4ba139c437ba0"
-dependencies = [
- "serde_core",
-]
-
-[[package]]
-name = "cargo-platform"
-version = "0.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "cargo_metadata"
-version = "0.19.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba"
-dependencies = [
- "camino",
- "cargo-platform",
- "semver",
- "serde",
- "serde_json",
- "thiserror 2.0.18",
-]
-
-[[package]]
-name = "cargo_toml"
-version = "0.22.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77"
-dependencies = [
- "serde",
- "toml 0.9.12+spec-1.1.0",
-]
-
-[[package]]
-name = "cc"
-version = "1.2.65"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96"
-dependencies = [
- "find-msvc-tools",
- "shlex",
-]
-
-[[package]]
-name = "cesu8"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
-
-[[package]]
-name = "cfb"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f"
-dependencies = [
- "byteorder",
- "fnv",
- "uuid",
-]
-
-[[package]]
-name = "cfg-expr"
-version = "0.15.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02"
-dependencies = [
- "smallvec",
- "target-lexicon",
-]
-
-[[package]]
-name = "cfg-if"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
-
-[[package]]
-name = "cfg_aliases"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
-
-[[package]]
-name = "chacha20"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81"
-dependencies = [
- "cfg-if",
- "cpufeatures 0.3.0",
- "rand_core",
-]
-
-[[package]]
-name = "chrono"
-version = "0.4.45"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327"
-dependencies = [
- "iana-time-zone",
- "num-traits",
- "serde",
- "windows-link 0.2.1",
-]
-
-[[package]]
-name = "combine"
-version = "4.6.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd"
-dependencies = [
- "bytes",
- "memchr",
-]
-
-[[package]]
-name = "cookie"
-version = "0.18.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747"
-dependencies = [
- "time",
- "version_check",
-]
-
-[[package]]
-name = "core-foundation"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
-[[package]]
-name = "core-foundation-sys"
-version = "0.8.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
-
-[[package]]
-name = "core-graphics"
-version = "0.25.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "064badf302c3194842cf2c5d61f56cc88e54a759313879cdf03abdd27d0c3b97"
-dependencies = [
- "bitflags 2.13.0",
- "core-foundation",
- "core-graphics-types",
- "foreign-types",
- "libc",
-]
-
-[[package]]
-name = "core-graphics-types"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb"
-dependencies = [
- "bitflags 2.13.0",
- "core-foundation",
- "libc",
-]
-
-[[package]]
-name = "cpufeatures"
-version = "0.2.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "cpufeatures"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "crc32fast"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "crossbeam-channel"
-version = "0.5.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
-dependencies = [
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-utils"
-version = "0.8.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
-
-[[package]]
-name = "crypto-common"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
-dependencies = [
- "generic-array",
- "typenum",
-]
-
-[[package]]
-name = "cssparser"
-version = "0.36.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dae61cf9c0abb83bd659dab65b7e4e38d8236824c85f0f804f173567bda257d2"
-dependencies = [
- "cssparser-macros",
- "dtoa-short",
- "itoa",
- "phf",
- "smallvec",
-]
-
-[[package]]
-name = "cssparser-macros"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
-dependencies = [
- "quote",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "ctor"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "352d39c2f7bef1d6ad73db6f5160efcaed66d94ef8c6c573a8410c00bf909a98"
-dependencies = [
- "ctor-proc-macro",
- "dtor",
-]
-
-[[package]]
-name = "ctor-proc-macro"
-version = "0.0.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52560adf09603e58c9a7ee1fe1dcb95a16927b17c127f0ac02d6e768a0e25bc1"
-
-[[package]]
-name = "darling"
-version = "0.23.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d"
-dependencies = [
- "darling_core",
- "darling_macro",
-]
-
-[[package]]
-name = "darling_core"
-version = "0.23.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0"
-dependencies = [
- "ident_case",
- "proc-macro2",
- "quote",
- "strsim",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "darling_macro"
-version = "0.23.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d"
-dependencies = [
- "darling_core",
- "quote",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "dbus"
-version = "0.9.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ab69f03cc8c4340c9c8e315114e1658e6775a9b16a04357973aa21cec22b32e"
-dependencies = [
- "libc",
- "libdbus-sys",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "deranged"
-version = "0.5.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c"
-dependencies = [
- "serde_core",
-]
-
-[[package]]
-name = "derive_more"
-version = "2.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134"
-dependencies = [
- "derive_more-impl",
-]
-
-[[package]]
-name = "derive_more-impl"
-version = "2.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb"
-dependencies = [
- "proc-macro2",
- "quote",
- "rustc_version",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "digest"
-version = "0.10.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
-dependencies = [
- "block-buffer",
- "crypto-common",
-]
-
-[[package]]
-name = "dirs"
-version = "6.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
-dependencies = [
- "dirs-sys",
-]
-
-[[package]]
-name = "dirs-sys"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
-dependencies = [
- "libc",
- "option-ext",
- "redox_users",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "dispatch2"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38"
-dependencies = [
- "bitflags 2.13.0",
- "block2",
- "libc",
- "objc2",
-]
-
-[[package]]
-name = "displaydoc"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "dlopen2"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e2c5bd4158e66d1e215c49b837e11d62f3267b30c92f1d171c4d3105e3dc4d4"
-dependencies = [
- "dlopen2_derive",
- "libc",
- "once_cell",
- "winapi",
-]
-
-[[package]]
-name = "dlopen2_derive"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fbbb781877580993a8707ec48672673ec7b81eeba04cfd2310bd28c08e47c8f"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "dom_query"
-version = "0.27.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "521e380c0c8afb8d9a1e83a1822ee03556fc3e3e7dbc1fd30be14e37f9cb3f89"
-dependencies = [
- "bit-set",
- "cssparser",
- "foldhash",
- "html5ever",
- "precomputed-hash",
- "selectors",
- "tendril",
-]
-
-[[package]]
-name = "dpi"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "dtoa"
-version = "1.0.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c3cf4824e2d5f025c7b531afcb2325364084a16806f6d47fbc1f5fbd9960590"
-
-[[package]]
-name = "dtoa-short"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87"
-dependencies = [
- "dtoa",
-]
-
-[[package]]
-name = "dtor"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1057d6c64987086ff8ed0fd3fbf377a6b7d205cc7715868cd401705f715cbe4"
-dependencies = [
- "dtor-proc-macro",
-]
-
-[[package]]
-name = "dtor-proc-macro"
-version = "0.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f678cf4a922c215c63e0de95eb1ff08a958a81d47e485cf9da1e27bf6305cfa5"
-
-[[package]]
-name = "dunce"
-version = "1.0.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
-
-[[package]]
-name = "dyn-clone"
-version = "1.0.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555"
-
-[[package]]
-name = "embed-resource"
-version = "3.0.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fbfdaacccebec3b28e4866b8973543c7647797db5ada1bdab552e48fe665fbbd"
-dependencies = [
- "cc",
- "memchr",
- "rustc_version",
- "toml 1.1.2+spec-1.1.0",
- "vswhom",
- "winreg",
-]
-
-[[package]]
-name = "embed_plist"
-version = "1.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7"
-
-[[package]]
-name = "equivalent"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
-
-[[package]]
-name = "erased-serde"
-version = "0.4.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2add8a07dd6a8d93ff627029c51de145e12686fbc36ecb298ac22e74cf02dec"
-dependencies = [
- "serde",
- "serde_core",
- "typeid",
-]
-
-[[package]]
-name = "fastrand"
-version = "2.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
-
-[[package]]
-name = "fdeflate"
-version = "0.3.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c"
-dependencies = [
- "simd-adler32",
-]
-
-[[package]]
-name = "field-offset"
-version = "0.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f"
-dependencies = [
- "memoffset",
- "rustc_version",
-]
-
-[[package]]
-name = "find-msvc-tools"
-version = "0.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
-
-[[package]]
-name = "flate2"
-version = "1.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c"
-dependencies = [
- "crc32fast",
- "miniz_oxide",
-]
-
-[[package]]
-name = "fnv"
-version = "1.0.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
-
-[[package]]
-name = "foldhash"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
-
-[[package]]
-name = "foreign-types"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965"
-dependencies = [
- "foreign-types-macros",
- "foreign-types-shared",
-]
-
-[[package]]
-name = "foreign-types-macros"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "foreign-types-shared"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b"
-
-[[package]]
-name = "form_urlencoded"
-version = "1.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf"
-dependencies = [
- "percent-encoding",
-]
-
-[[package]]
-name = "futures-channel"
-version = "0.3.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d"
-dependencies = [
- "futures-core",
- "futures-sink",
-]
-
-[[package]]
-name = "futures-core"
-version = "0.3.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
-
-[[package]]
-name = "futures-executor"
-version = "0.3.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d"
-dependencies = [
- "futures-core",
- "futures-task",
- "futures-util",
-]
-
-[[package]]
-name = "futures-io"
-version = "0.3.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718"
-
-[[package]]
-name = "futures-macro"
-version = "0.3.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "futures-sink"
-version = "0.3.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893"
-
-[[package]]
-name = "futures-task"
-version = "0.3.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393"
-
-[[package]]
-name = "futures-util"
-version = "0.3.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
-dependencies = [
- "futures-core",
- "futures-io",
- "futures-macro",
- "futures-sink",
- "futures-task",
- "memchr",
- "pin-project-lite",
- "slab",
-]
-
-[[package]]
-name = "gdk"
-version = "0.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9f245958c627ac99d8e529166f9823fb3b838d1d41fd2b297af3075093c2691"
-dependencies = [
- "cairo-rs",
- "gdk-pixbuf",
- "gdk-sys",
- "gio",
- "glib",
- "libc",
- "pango",
-]
-
-[[package]]
-name = "gdk-pixbuf"
-version = "0.18.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50e1f5f1b0bfb830d6ccc8066d18db35c487b1b2b1e8589b5dfe9f07e8defaec"
-dependencies = [
- "gdk-pixbuf-sys",
- "gio",
- "glib",
- "libc",
- "once_cell",
-]
-
-[[package]]
-name = "gdk-pixbuf-sys"
-version = "0.18.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f9839ea644ed9c97a34d129ad56d38a25e6756f99f3a88e15cd39c20629caf7"
-dependencies = [
- "gio-sys",
- "glib-sys",
- "gobject-sys",
- "libc",
- "system-deps",
-]
-
-[[package]]
-name = "gdk-sys"
-version = "0.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c2d13f38594ac1e66619e188c6d5a1adb98d11b2fcf7894fc416ad76aa2f3f7"
-dependencies = [
- "cairo-sys-rs",
- "gdk-pixbuf-sys",
- "gio-sys",
- "glib-sys",
- "gobject-sys",
- "libc",
- "pango-sys",
- "pkg-config",
- "system-deps",
-]
-
-[[package]]
-name = "gdkwayland-sys"
-version = "0.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "140071d506d223f7572b9f09b5e155afbd77428cd5cc7af8f2694c41d98dfe69"
-dependencies = [
- "gdk-sys",
- "glib-sys",
- "gobject-sys",
- "libc",
- "pkg-config",
- "system-deps",
-]
-
-[[package]]
-name = "gdkx11"
-version = "0.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3caa00e14351bebbc8183b3c36690327eb77c49abc2268dd4bd36b856db3fbfe"
-dependencies = [
- "gdk",
- "gdkx11-sys",
- "gio",
- "glib",
- "libc",
- "x11",
-]
-
-[[package]]
-name = "gdkx11-sys"
-version = "0.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e2e7445fe01ac26f11601db260dd8608fe172514eb63b3b5e261ea6b0f4428d"
-dependencies = [
- "gdk-sys",
- "glib-sys",
- "libc",
- "system-deps",
- "x11",
-]
-
-[[package]]
-name = "generic-array"
-version = "0.14.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
-dependencies = [
- "typenum",
- "version_check",
-]
-
-[[package]]
-name = "getrandom"
-version = "0.2.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
-dependencies = [
- "cfg-if",
- "js-sys",
- "libc",
- "wasi",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "getrandom"
-version = "0.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
-dependencies = [
- "cfg-if",
- "libc",
- "r-efi 5.3.0",
- "wasip2",
-]
-
-[[package]]
-name = "getrandom"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099"
-dependencies = [
- "cfg-if",
- "js-sys",
- "libc",
- "r-efi 6.0.0",
- "rand_core",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "gio"
-version = "0.18.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4fc8f532f87b79cbc51a79748f16a6828fb784be93145a322fa14d06d354c73"
-dependencies = [
- "futures-channel",
- "futures-core",
- "futures-io",
- "futures-util",
- "gio-sys",
- "glib",
- "libc",
- "once_cell",
- "pin-project-lite",
- "smallvec",
- "thiserror 1.0.69",
-]
-
-[[package]]
-name = "gio-sys"
-version = "0.18.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37566df850baf5e4cb0dfb78af2e4b9898d817ed9263d1090a2df958c64737d2"
-dependencies = [
- "glib-sys",
- "gobject-sys",
- "libc",
- "system-deps",
- "winapi",
-]
-
-[[package]]
-name = "glib"
-version = "0.18.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5"
-dependencies = [
- "bitflags 2.13.0",
- "futures-channel",
- "futures-core",
- "futures-executor",
- "futures-task",
- "futures-util",
- "gio-sys",
- "glib-macros",
- "glib-sys",
- "gobject-sys",
- "libc",
- "memchr",
- "once_cell",
- "smallvec",
- "thiserror 1.0.69",
-]
-
-[[package]]
-name = "glib-macros"
-version = "0.18.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc"
-dependencies = [
- "heck 0.4.1",
- "proc-macro-crate 2.0.2",
- "proc-macro-error",
- "proc-macro2",
- "quote",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "glib-sys"
-version = "0.18.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "063ce2eb6a8d0ea93d2bf8ba1957e78dbab6be1c2220dd3daca57d5a9d869898"
-dependencies = [
- "libc",
- "system-deps",
-]
-
-[[package]]
-name = "glob"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
-
-[[package]]
-name = "gobject-sys"
-version = "0.18.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44"
-dependencies = [
- "glib-sys",
- "libc",
- "system-deps",
-]
-
-[[package]]
-name = "gtk"
-version = "0.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd56fb197bfc42bd5d2751f4f017d44ff59fbb58140c6b49f9b3b2bdab08506a"
-dependencies = [
- "atk",
- "cairo-rs",
- "field-offset",
- "futures-channel",
- "gdk",
- "gdk-pixbuf",
- "gio",
- "glib",
- "gtk-sys",
- "gtk3-macros",
- "libc",
- "pango",
- "pkg-config",
-]
-
-[[package]]
-name = "gtk-sys"
-version = "0.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f29a1c21c59553eb7dd40e918be54dccd60c52b049b75119d5d96ce6b624414"
-dependencies = [
- "atk-sys",
- "cairo-sys-rs",
- "gdk-pixbuf-sys",
- "gdk-sys",
- "gio-sys",
- "glib-sys",
- "gobject-sys",
- "libc",
- "pango-sys",
- "system-deps",
-]
-
-[[package]]
-name = "gtk3-macros"
-version = "0.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52ff3c5b21f14f0736fed6dcfc0bfb4225ebf5725f3c0209edeec181e4d73e9d"
-dependencies = [
- "proc-macro-crate 1.3.1",
- "proc-macro-error",
- "proc-macro2",
- "quote",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "hashbrown"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
-
-[[package]]
-name = "hashbrown"
-version = "0.17.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
-
-[[package]]
-name = "heck"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
-
-[[package]]
-name = "heck"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
-
-[[package]]
-name = "hex"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
-
-[[package]]
-name = "html5ever"
-version = "0.38.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1054432bae2f14e0061e33d23402fbaa67a921d319d56adc6bcf887ddad1cbc2"
-dependencies = [
- "log",
- "markup5ever",
-]
-
-[[package]]
-name = "http"
-version = "1.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425"
-dependencies = [
- "bytes",
- "itoa",
-]
-
-[[package]]
-name = "http-body"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
-dependencies = [
- "bytes",
- "http",
-]
-
-[[package]]
-name = "http-body-util"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
-dependencies = [
- "bytes",
- "futures-core",
- "http",
- "http-body",
- "pin-project-lite",
-]
-
-[[package]]
-name = "httparse"
-version = "1.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
-
-[[package]]
-name = "hyper"
-version = "1.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498"
-dependencies = [
- "atomic-waker",
- "bytes",
- "futures-channel",
- "futures-core",
- "http",
- "http-body",
- "httparse",
- "itoa",
- "pin-project-lite",
- "smallvec",
- "tokio",
- "want",
-]
-
-[[package]]
-name = "hyper-rustls"
-version = "0.27.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f"
-dependencies = [
- "http",
- "hyper",
- "hyper-util",
- "rustls",
- "tokio",
- "tokio-rustls",
- "tower-service",
- "webpki-roots",
-]
-
-[[package]]
-name = "hyper-util"
-version = "0.1.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0"
-dependencies = [
- "base64 0.22.1",
- "bytes",
- "futures-channel",
- "futures-util",
- "http",
- "http-body",
- "hyper",
- "ipnet",
- "libc",
- "percent-encoding",
- "pin-project-lite",
- "socket2",
- "tokio",
- "tower-service",
- "tracing",
-]
-
-[[package]]
-name = "iana-time-zone"
-version = "0.1.65"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
-dependencies = [
- "android_system_properties",
- "core-foundation-sys",
- "iana-time-zone-haiku",
- "js-sys",
- "log",
- "wasm-bindgen",
- "windows-core 0.62.2",
-]
-
-[[package]]
-name = "iana-time-zone-haiku"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
-dependencies = [
- "cc",
-]
-
-[[package]]
-name = "ico"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e795dff5605e0f04bff85ca41b51a96b83e80b281e96231bcaaf1ac35103371"
-dependencies = [
- "byteorder",
- "png 0.17.16",
-]
-
-[[package]]
-name = "icu_collections"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c"
-dependencies = [
- "displaydoc",
- "potential_utf",
- "utf8_iter",
- "yoke",
- "zerofrom",
- "zerovec",
-]
-
-[[package]]
-name = "icu_locale_core"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29"
-dependencies = [
- "displaydoc",
- "litemap",
- "tinystr",
- "writeable",
- "zerovec",
-]
-
-[[package]]
-name = "icu_normalizer"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4"
-dependencies = [
- "icu_collections",
- "icu_normalizer_data",
- "icu_properties",
- "icu_provider",
- "smallvec",
- "zerovec",
-]
-
-[[package]]
-name = "icu_normalizer_data"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38"
-
-[[package]]
-name = "icu_properties"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de"
-dependencies = [
- "icu_collections",
- "icu_locale_core",
- "icu_properties_data",
- "icu_provider",
- "zerotrie",
- "zerovec",
-]
-
-[[package]]
-name = "icu_properties_data"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14"
-
-[[package]]
-name = "icu_provider"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421"
-dependencies = [
- "displaydoc",
- "icu_locale_core",
- "writeable",
- "yoke",
- "zerofrom",
- "zerotrie",
- "zerovec",
-]
-
-[[package]]
-name = "ident_case"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
-
-[[package]]
-name = "idna"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de"
-dependencies = [
- "idna_adapter",
- "smallvec",
- "utf8_iter",
-]
-
-[[package]]
-name = "idna_adapter"
-version = "1.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714"
-dependencies = [
- "icu_normalizer",
- "icu_properties",
-]
-
-[[package]]
-name = "indexmap"
-version = "1.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
-dependencies = [
- "autocfg",
- "hashbrown 0.12.3",
- "serde",
-]
-
-[[package]]
-name = "indexmap"
-version = "2.14.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
-dependencies = [
- "equivalent",
- "hashbrown 0.17.1",
- "serde",
- "serde_core",
-]
-
-[[package]]
-name = "infer"
-version = "0.19.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7"
-dependencies = [
- "cfb",
-]
-
-[[package]]
-name = "ipnet"
-version = "2.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2"
-
-[[package]]
-name = "itoa"
-version = "1.0.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
-
-[[package]]
-name = "javascriptcore-rs"
-version = "1.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca5671e9ffce8ffba57afc24070e906da7fc4b1ba66f2cabebf61bf2ea257fcc"
-dependencies = [
- "bitflags 1.3.2",
- "glib",
- "javascriptcore-rs-sys",
-]
-
-[[package]]
-name = "javascriptcore-rs-sys"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af1be78d14ffa4b75b66df31840478fef72b51f8c2465d4ca7c194da9f7a5124"
-dependencies = [
- "glib-sys",
- "gobject-sys",
- "libc",
- "system-deps",
-]
-
-[[package]]
-name = "jni"
-version = "0.21.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97"
-dependencies = [
- "cesu8",
- "cfg-if",
- "combine",
- "jni-sys 0.3.1",
- "log",
- "thiserror 1.0.69",
- "walkdir",
- "windows-sys 0.45.0",
-]
-
-[[package]]
-name = "jni-sys"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258"
-dependencies = [
- "jni-sys 0.4.1",
-]
-
-[[package]]
-name = "jni-sys"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2"
-dependencies = [
- "jni-sys-macros",
-]
-
-[[package]]
-name = "jni-sys-macros"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264"
-dependencies = [
- "quote",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "js-sys"
-version = "0.3.103"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102"
-dependencies = [
- "cfg-if",
- "futures-util",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "json-patch"
-version = "3.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "863726d7afb6bc2590eeff7135d923545e5e964f004c2ccf8716c25e70a86f08"
-dependencies = [
- "jsonptr",
- "serde",
- "serde_json",
- "thiserror 1.0.69",
-]
-
-[[package]]
-name = "jsonptr"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5dea2b27dd239b2556ed7a25ba842fe47fd602e7fc7433c2a8d6106d4d9edd70"
-dependencies = [
- "serde",
- "serde_json",
-]
-
-[[package]]
-name = "keyboard-types"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a"
-dependencies = [
- "bitflags 2.13.0",
- "serde",
- "unicode-segmentation",
-]
-
-[[package]]
-name = "libappindicator"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03589b9607c868cc7ae54c0b2a22c8dc03dd41692d48f2d7df73615c6a95dc0a"
-dependencies = [
- "glib",
- "gtk",
- "gtk-sys",
- "libappindicator-sys",
- "log",
-]
-
-[[package]]
-name = "libappindicator-sys"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e9ec52138abedcc58dc17a7c6c0c00a2bdb4f3427c7f63fa97fd0d859155caf"
-dependencies = [
- "gtk-sys",
- "libloading",
- "once_cell",
-]
-
-[[package]]
-name = "libc"
-version = "0.2.186"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
-
-[[package]]
-name = "libdbus-sys"
-version = "0.2.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "328c4789d42200f1eeec05bd86c9c13c7f091d2ba9a6ea35acdf51f31bc0f043"
-dependencies = [
- "pkg-config",
-]
-
-[[package]]
-name = "libloading"
-version = "0.7.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
-dependencies = [
- "cfg-if",
- "winapi",
-]
-
-[[package]]
-name = "libredox"
-version = "0.1.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c943259e342f1e06ff2da7a83eabdfe7f92ce10262688dbf1895ff0b3e6e4652"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "litemap"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0"
-
-[[package]]
-name = "lock_api"
-version = "0.4.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
-dependencies = [
- "scopeguard",
-]
-
-[[package]]
-name = "log"
-version = "0.4.33"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad"
-
-[[package]]
-name = "lru-slab"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
-
-[[package]]
-name = "markup5ever"
-version = "0.38.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8983d30f2915feeaaab2d6babdd6bc7e9ed1a00b66b5e6d74df19aa9c0e91862"
-dependencies = [
- "log",
- "tendril",
- "web_atoms",
-]
-
-[[package]]
-name = "memchr"
-version = "2.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
-
-[[package]]
-name = "memoffset"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "mime"
-version = "0.3.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
-
-[[package]]
-name = "miniz_oxide"
-version = "0.8.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
-dependencies = [
- "adler2",
- "simd-adler32",
-]
-
-[[package]]
-name = "mio"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda"
-dependencies = [
- "libc",
- "wasi",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "muda"
-version = "0.19.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1dd04e60bc0b07438a6771710ee1698f98f6ebbc7f89b61264af1563b8aeb878"
-dependencies = [
- "crossbeam-channel",
- "dpi",
- "gtk",
- "keyboard-types",
- "objc2",
- "objc2-app-kit",
- "objc2-core-foundation",
- "objc2-foundation",
- "once_cell",
- "png 0.18.1",
- "serde",
- "thiserror 2.0.18",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "ndk"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4"
-dependencies = [
- "bitflags 2.13.0",
- "jni-sys 0.3.1",
- "log",
- "ndk-sys",
- "num_enum",
- "raw-window-handle",
- "thiserror 1.0.69",
-]
-
-[[package]]
-name = "ndk-sys"
-version = "0.6.0+11769913"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873"
-dependencies = [
- "jni-sys 0.3.1",
-]
-
-[[package]]
-name = "new_debug_unreachable"
-version = "1.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
-
-[[package]]
-name = "num-conv"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441"
-
-[[package]]
-name = "num-traits"
-version = "0.2.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "num_enum"
-version = "0.7.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26"
-dependencies = [
- "num_enum_derive",
- "rustversion",
-]
-
-[[package]]
-name = "num_enum_derive"
-version = "0.7.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8"
-dependencies = [
- "proc-macro-crate 3.5.0",
- "proc-macro2",
- "quote",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "objc2"
-version = "0.6.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f"
-dependencies = [
- "objc2-encode",
- "objc2-exception-helper",
-]
-
-[[package]]
-name = "objc2-app-kit"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c"
-dependencies = [
- "bitflags 2.13.0",
- "block2",
- "objc2",
- "objc2-core-foundation",
- "objc2-foundation",
-]
-
-[[package]]
-name = "objc2-cloud-kit"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c"
-dependencies = [
- "bitflags 2.13.0",
- "objc2",
- "objc2-foundation",
-]
-
-[[package]]
-name = "objc2-core-data"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa"
-dependencies = [
- "objc2",
- "objc2-foundation",
-]
-
-[[package]]
-name = "objc2-core-foundation"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536"
-dependencies = [
- "bitflags 2.13.0",
- "dispatch2",
- "objc2",
-]
-
-[[package]]
-name = "objc2-core-graphics"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807"
-dependencies = [
- "bitflags 2.13.0",
- "dispatch2",
- "objc2",
- "objc2-core-foundation",
- "objc2-io-surface",
-]
-
-[[package]]
-name = "objc2-core-image"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006"
-dependencies = [
- "objc2",
- "objc2-foundation",
-]
-
-[[package]]
-name = "objc2-core-location"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca347214e24bc973fc025fd0d36ebb179ff30536ed1f80252706db19ee452009"
-dependencies = [
- "objc2",
- "objc2-foundation",
-]
-
-[[package]]
-name = "objc2-core-text"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d"
-dependencies = [
- "bitflags 2.13.0",
- "objc2",
- "objc2-core-foundation",
- "objc2-core-graphics",
-]
-
-[[package]]
-name = "objc2-encode"
-version = "4.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33"
-
-[[package]]
-name = "objc2-exception-helper"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7a1c5fbb72d7735b076bb47b578523aedc40f3c439bea6dfd595c089d79d98a"
-dependencies = [
- "cc",
-]
-
-[[package]]
-name = "objc2-foundation"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272"
-dependencies = [
- "bitflags 2.13.0",
- "block2",
- "libc",
- "objc2",
- "objc2-core-foundation",
-]
-
-[[package]]
-name = "objc2-io-surface"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d"
-dependencies = [
- "bitflags 2.13.0",
- "objc2",
- "objc2-core-foundation",
-]
-
-[[package]]
-name = "objc2-quartz-core"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f"
-dependencies = [
- "bitflags 2.13.0",
- "objc2",
- "objc2-core-foundation",
- "objc2-foundation",
-]
-
-[[package]]
-name = "objc2-ui-kit"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22"
-dependencies = [
- "bitflags 2.13.0",
- "block2",
- "objc2",
- "objc2-cloud-kit",
- "objc2-core-data",
- "objc2-core-foundation",
- "objc2-core-graphics",
- "objc2-core-image",
- "objc2-core-location",
- "objc2-core-text",
- "objc2-foundation",
- "objc2-quartz-core",
- "objc2-user-notifications",
-]
-
-[[package]]
-name = "objc2-user-notifications"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9df9128cbbfef73cda168416ccf7f837b62737d748333bfe9ab71c245d76613e"
-dependencies = [
- "objc2",
- "objc2-foundation",
-]
-
-[[package]]
-name = "objc2-web-kit"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2e5aaab980c433cf470df9d7af96a7b46a9d892d521a2cbbb2f8a4c16751e7f"
-dependencies = [
- "bitflags 2.13.0",
- "block2",
- "objc2",
- "objc2-app-kit",
- "objc2-core-foundation",
- "objc2-foundation",
-]
-
-[[package]]
-name = "once_cell"
-version = "1.21.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
-
-[[package]]
-name = "option-ext"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
-
-[[package]]
-name = "pango"
-version = "0.18.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ca27ec1eb0457ab26f3036ea52229edbdb74dee1edd29063f5b9b010e7ebee4"
-dependencies = [
- "gio",
- "glib",
- "libc",
- "once_cell",
- "pango-sys",
-]
-
-[[package]]
-name = "pango-sys"
-version = "0.18.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "436737e391a843e5933d6d9aa102cb126d501e815b83601365a948a518555dc5"
-dependencies = [
- "glib-sys",
- "gobject-sys",
- "libc",
- "system-deps",
-]
-
-[[package]]
-name = "parking_lot"
-version = "0.12.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
-dependencies = [
- "lock_api",
- "parking_lot_core",
-]
-
-[[package]]
-name = "parking_lot_core"
-version = "0.9.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
-dependencies = [
- "cfg-if",
- "libc",
- "redox_syscall",
- "smallvec",
- "windows-link 0.2.1",
-]
-
-[[package]]
-name = "percent-encoding"
-version = "2.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
-
-[[package]]
-name = "phf"
-version = "0.13.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf"
-dependencies = [
- "phf_macros",
- "phf_shared",
- "serde",
-]
-
-[[package]]
-name = "phf_codegen"
-version = "0.13.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49aa7f9d80421bca176ca8dbfebe668cc7a2684708594ec9f3c0db0805d5d6e1"
-dependencies = [
- "phf_generator",
- "phf_shared",
-]
-
-[[package]]
-name = "phf_generator"
-version = "0.13.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737"
-dependencies = [
- "fastrand",
- "phf_shared",
-]
-
-[[package]]
-name = "phf_macros"
-version = "0.13.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef"
-dependencies = [
- "phf_generator",
- "phf_shared",
- "proc-macro2",
- "quote",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "phf_shared"
-version = "0.13.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266"
-dependencies = [
- "siphasher",
-]
-
-[[package]]
-name = "pin-project-lite"
-version = "0.2.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
-
-[[package]]
-name = "pkg-config"
-version = "0.3.33"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e"
-
-[[package]]
-name = "plist"
-version = "1.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "092791278e026273c1b65bbdcfbba3a300f2994c896bd01ab01da613c29c46f1"
-dependencies = [
- "base64 0.22.1",
- "indexmap 2.14.0",
- "quick-xml",
- "serde",
- "time",
-]
-
-[[package]]
-name = "png"
-version = "0.17.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526"
-dependencies = [
- "bitflags 1.3.2",
- "crc32fast",
- "fdeflate",
- "flate2",
- "miniz_oxide",
-]
-
-[[package]]
-name = "png"
-version = "0.18.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61"
-dependencies = [
- "bitflags 2.13.0",
- "crc32fast",
- "fdeflate",
- "flate2",
- "miniz_oxide",
-]
-
-[[package]]
-name = "potential_utf"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564"
-dependencies = [
- "zerovec",
-]
-
-[[package]]
-name = "powerfmt"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
-
-[[package]]
-name = "precomputed-hash"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
-
-[[package]]
-name = "proc-macro-crate"
-version = "1.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919"
-dependencies = [
- "once_cell",
- "toml_edit 0.19.15",
-]
-
-[[package]]
-name = "proc-macro-crate"
-version = "2.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24"
-dependencies = [
- "toml_datetime 0.6.3",
- "toml_edit 0.20.2",
-]
-
-[[package]]
-name = "proc-macro-crate"
-version = "3.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f"
-dependencies = [
- "toml_edit 0.25.12+spec-1.1.0",
-]
-
-[[package]]
-name = "proc-macro-error"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
-dependencies = [
- "proc-macro-error-attr",
- "proc-macro2",
- "quote",
- "syn 1.0.109",
- "version_check",
-]
-
-[[package]]
-name = "proc-macro-error-attr"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
-dependencies = [
- "proc-macro2",
- "quote",
- "version_check",
-]
-
-[[package]]
-name = "proc-macro2"
-version = "1.0.106"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
-dependencies = [
- "unicode-ident",
-]
-
-[[package]]
-name = "quick-xml"
-version = "0.39.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdcc8dd4e2f670d309a5f0e83fe36dfdc05af317008fea29144da1a2ac858e5e"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "quinn"
-version = "0.11.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8"
-dependencies = [
- "bytes",
- "cfg_aliases",
- "pin-project-lite",
- "quinn-proto",
- "quinn-udp",
- "rustc-hash",
- "rustls",
- "socket2",
- "thiserror 2.0.18",
- "tokio",
- "tracing",
- "web-time",
-]
-
-[[package]]
-name = "quinn-proto"
-version = "0.11.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f4bfc015262b9df63c8845072ce59068853ff5872180c2ce2f13038b970e560"
-dependencies = [
- "bytes",
- "getrandom 0.4.3",
- "lru-slab",
- "rand",
- "rand_pcg",
- "ring",
- "rustc-hash",
- "rustls",
- "rustls-pki-types",
- "slab",
- "thiserror 2.0.18",
- "tinyvec",
- "tracing",
- "web-time",
-]
-
-[[package]]
-name = "quinn-udp"
-version = "0.5.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "35a133f956daabe89a61a685c2649f13d82d5aa4bd5d12d1277e1072a21c0694"
-dependencies = [
- "cfg_aliases",
- "libc",
- "once_cell",
- "socket2",
- "tracing",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "quote"
-version = "1.0.46"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368"
-dependencies = [
- "proc-macro2",
-]
-
-[[package]]
-name = "r-efi"
-version = "5.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
-
-[[package]]
-name = "r-efi"
-version = "6.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
-
-[[package]]
-name = "rand"
-version = "0.10.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80"
-dependencies = [
- "chacha20",
- "getrandom 0.4.3",
- "rand_core",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
-
-[[package]]
-name = "rand_pcg"
-version = "0.10.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a"
-dependencies = [
- "rand_core",
-]
-
-[[package]]
-name = "raw-window-handle"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539"
-
-[[package]]
-name = "redox_syscall"
-version = "0.5.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
-dependencies = [
- "bitflags 2.13.0",
-]
-
-[[package]]
-name = "redox_users"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
-dependencies = [
- "getrandom 0.2.17",
- "libredox",
- "thiserror 2.0.18",
-]
-
-[[package]]
-name = "ref-cast"
-version = "1.0.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d"
-dependencies = [
- "ref-cast-impl",
-]
-
-[[package]]
-name = "ref-cast-impl"
-version = "1.0.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "regex"
-version = "1.12.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba"
-dependencies = [
- "aho-corasick",
- "memchr",
- "regex-automata",
- "regex-syntax",
-]
-
-[[package]]
-name = "regex-automata"
-version = "0.4.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
-dependencies = [
- "aho-corasick",
- "memchr",
- "regex-syntax",
-]
-
-[[package]]
-name = "regex-syntax"
-version = "0.8.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
-
-[[package]]
-name = "reqwest"
-version = "0.12.28"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147"
-dependencies = [
- "base64 0.22.1",
- "bytes",
- "futures-channel",
- "futures-core",
- "futures-util",
- "http",
- "http-body",
- "http-body-util",
- "hyper",
- "hyper-rustls",
- "hyper-util",
- "js-sys",
- "log",
- "percent-encoding",
- "pin-project-lite",
- "quinn",
- "rustls",
- "rustls-pki-types",
- "serde",
- "serde_json",
- "serde_urlencoded",
- "sync_wrapper",
- "tokio",
- "tokio-rustls",
- "tower",
- "tower-http",
- "tower-service",
- "url",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "web-sys",
- "webpki-roots",
-]
-
-[[package]]
-name = "reqwest"
-version = "0.13.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3"
-dependencies = [
- "base64 0.22.1",
- "bytes",
- "futures-core",
- "futures-util",
- "http",
- "http-body",
- "http-body-util",
- "hyper",
- "hyper-util",
- "js-sys",
- "log",
- "percent-encoding",
- "pin-project-lite",
- "serde",
- "serde_json",
- "sync_wrapper",
- "tokio",
- "tokio-util",
- "tower",
- "tower-http",
- "tower-service",
- "url",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "wasm-streams",
- "web-sys",
-]
-
-[[package]]
-name = "rfd"
-version = "0.16.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a15ad77d9e70a92437d8f74c35d99b4e4691128df018833e99f90bcd36152672"
-dependencies = [
- "block2",
- "dispatch2",
- "glib-sys",
- "gobject-sys",
- "gtk-sys",
- "js-sys",
- "log",
- "objc2",
- "objc2-app-kit",
- "objc2-core-foundation",
- "objc2-foundation",
- "raw-window-handle",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "web-sys",
- "windows-sys 0.60.2",
-]
-
-[[package]]
-name = "ring"
-version = "0.17.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
-dependencies = [
- "cc",
- "cfg-if",
- "getrandom 0.2.17",
- "libc",
- "untrusted",
- "windows-sys 0.52.0",
-]
-
-[[package]]
-name = "rustc-hash"
-version = "2.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d"
-
-[[package]]
-name = "rustc_version"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
-dependencies = [
- "semver",
-]
-
-[[package]]
-name = "rustls"
-version = "0.23.41"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f"
-dependencies = [
- "once_cell",
- "ring",
- "rustls-pki-types",
- "rustls-webpki",
- "subtle",
- "zeroize",
-]
-
-[[package]]
-name = "rustls-pki-types"
-version = "1.15.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "764899a24af3980067ee14bc143654f297b22eaebfe3c7b6b211920a5a59b046"
-dependencies = [
- "web-time",
- "zeroize",
-]
-
-[[package]]
-name = "rustls-webpki"
-version = "0.103.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e"
-dependencies = [
- "ring",
- "rustls-pki-types",
- "untrusted",
-]
-
-[[package]]
-name = "rustversion"
-version = "1.0.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
-
-[[package]]
-name = "ryu"
-version = "1.0.23"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
-
-[[package]]
-name = "same-file"
-version = "1.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
-dependencies = [
- "winapi-util",
-]
-
-[[package]]
-name = "schemars"
-version = "0.8.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615"
-dependencies = [
- "dyn-clone",
- "indexmap 1.9.3",
- "schemars_derive",
- "serde",
- "serde_json",
- "url",
- "uuid",
-]
-
-[[package]]
-name = "schemars"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f"
-dependencies = [
- "dyn-clone",
- "ref-cast",
- "serde",
- "serde_json",
-]
-
-[[package]]
-name = "schemars"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc"
-dependencies = [
- "dyn-clone",
- "ref-cast",
- "serde",
- "serde_json",
-]
-
-[[package]]
-name = "schemars_derive"
-version = "0.8.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d"
-dependencies = [
- "proc-macro2",
- "quote",
- "serde_derive_internals",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "scopeguard"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
-
-[[package]]
-name = "selectors"
-version = "0.36.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c5d9c0c92a92d33f08817311cf3f2c29a3538a8240e94a6a3c622ce652d7e00c"
-dependencies = [
- "bitflags 2.13.0",
- "cssparser",
- "derive_more",
- "log",
- "new_debug_unreachable",
- "phf",
- "phf_codegen",
- "precomputed-hash",
- "rustc-hash",
- "servo_arc",
- "smallvec",
-]
-
-[[package]]
-name = "semver"
-version = "1.0.28"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
-dependencies = [
- "serde",
- "serde_core",
-]
-
-[[package]]
-name = "serde"
-version = "1.0.228"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
-dependencies = [
- "serde_core",
- "serde_derive",
-]
-
-[[package]]
-name = "serde-untagged"
-version = "0.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f9faf48a4a2d2693be24c6289dbe26552776eb7737074e6722891fadbe6c5058"
-dependencies = [
- "erased-serde",
- "serde",
- "serde_core",
- "typeid",
-]
-
-[[package]]
-name = "serde_core"
-version = "1.0.228"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
-dependencies = [
- "serde_derive",
-]
-
-[[package]]
-name = "serde_derive"
-version = "1.0.228"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "serde_derive_internals"
-version = "0.29.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "serde_json"
-version = "1.0.150"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
-dependencies = [
- "itoa",
- "memchr",
- "serde",
- "serde_core",
- "zmij",
-]
-
-[[package]]
-name = "serde_repr"
-version = "0.1.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "serde_spanned"
-version = "0.6.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "serde_spanned"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26"
-dependencies = [
- "serde_core",
-]
-
-[[package]]
-name = "serde_urlencoded"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
-dependencies = [
- "form_urlencoded",
- "itoa",
- "ryu",
- "serde",
-]
-
-[[package]]
-name = "serde_with"
-version = "3.21.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "76a5c54c7310e7b8b9577c286d7e399ddd876c3e12b3ed917a8aabc4b96e9e8c"
-dependencies = [
- "base64 0.22.1",
- "bs58",
- "chrono",
- "hex",
- "indexmap 1.9.3",
- "indexmap 2.14.0",
- "schemars 0.9.0",
- "schemars 1.2.1",
- "serde_core",
- "serde_json",
- "serde_with_macros",
- "time",
-]
-
-[[package]]
-name = "serde_with_macros"
-version = "3.21.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "84d57bc0c8b9a17920c178daa6bb924850d54a9c97ab45194bb8c17ad66bb660"
-dependencies = [
- "darling",
- "proc-macro2",
- "quote",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "serialize-to-javascript"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04f3666a07a197cdb77cdf306c32be9b7f598d7060d50cfd4d5aa04bfd92f6c5"
-dependencies = [
- "serde",
- "serde_json",
- "serialize-to-javascript-impl",
-]
-
-[[package]]
-name = "serialize-to-javascript-impl"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "772ee033c0916d670af7860b6e1ef7d658a4629a6d0b4c8c3e67f09b3765b75d"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "servo_arc"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "170fb83ab34de17dc69aa7c67482b22218ddb85da56546f9bd6b929e32a05930"
-dependencies = [
- "stable_deref_trait",
-]
-
-[[package]]
-name = "sha2"
-version = "0.10.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
-dependencies = [
- "cfg-if",
- "cpufeatures 0.2.17",
- "digest",
-]
-
-[[package]]
-name = "shlex"
-version = "2.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
-
-[[package]]
-name = "simd-adler32"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214"
-
-[[package]]
-name = "siphasher"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649"
-
-[[package]]
-name = "slab"
-version = "0.4.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
-
-[[package]]
-name = "smallvec"
-version = "1.15.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90"
-
-[[package]]
-name = "socket2"
-version = "0.6.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51"
-dependencies = [
- "libc",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "softbuffer"
-version = "0.4.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aac18da81ebbf05109ab275b157c22a653bb3c12cf884450179942f81bcbf6c3"
-dependencies = [
- "bytemuck",
- "js-sys",
- "ndk",
- "objc2",
- "objc2-core-foundation",
- "objc2-core-graphics",
- "objc2-foundation",
- "objc2-quartz-core",
- "raw-window-handle",
- "redox_syscall",
- "tracing",
- "wasm-bindgen",
- "web-sys",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "soup3"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "471f924a40f31251afc77450e781cb26d55c0b650842efafc9c6cbd2f7cc4f9f"
-dependencies = [
- "futures-channel",
- "gio",
- "glib",
- "libc",
- "soup3-sys",
-]
-
-[[package]]
-name = "soup3-sys"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ebe8950a680a12f24f15ebe1bf70db7af98ad242d9db43596ad3108aab86c27"
-dependencies = [
- "gio-sys",
- "glib-sys",
- "gobject-sys",
- "libc",
- "system-deps",
-]
-
-[[package]]
-name = "stable_deref_trait"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
-
-[[package]]
-name = "string_cache"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a18596f8c785a729f2819c0f6a7eae6ebeebdfffbfe4214ae6b087f690e31901"
-dependencies = [
- "new_debug_unreachable",
- "parking_lot",
- "phf_shared",
- "precomputed-hash",
-]
-
-[[package]]
-name = "string_cache_codegen"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "585635e46db231059f76c5849798146164652513eb9e8ab2685939dd90f29b69"
-dependencies = [
- "phf_generator",
- "phf_shared",
- "proc-macro2",
- "quote",
-]
-
-[[package]]
-name = "strsim"
-version = "0.11.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
-
-[[package]]
-name = "subtle"
-version = "2.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
-
-[[package]]
-name = "swift-rs"
-version = "1.0.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4057c98e2e852d51fdcfca832aac7b571f6b351ad159f9eda5db1655f8d0c4d7"
-dependencies = [
- "base64 0.21.7",
- "serde",
- "serde_json",
-]
-
-[[package]]
-name = "syn"
-version = "1.0.109"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
-dependencies = [
- "proc-macro2",
- "unicode-ident",
-]
-
-[[package]]
-name = "syn"
-version = "2.0.118"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-ident",
-]
-
-[[package]]
-name = "sync_wrapper"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
-dependencies = [
- "futures-core",
-]
-
-[[package]]
-name = "synstructure"
-version = "0.13.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "system-deps"
-version = "6.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349"
-dependencies = [
- "cfg-expr",
- "heck 0.5.0",
- "pkg-config",
- "toml 0.8.2",
- "version-compare",
-]
-
-[[package]]
-name = "tao"
-version = "0.35.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d1c93047acf68669466a34690ac58cca7010bd1b201e1ec86f1fd0a75d3dd4a9"
-dependencies = [
- "bitflags 2.13.0",
- "block2",
- "core-foundation",
- "core-graphics",
- "crossbeam-channel",
- "dbus",
- "dispatch2",
- "dlopen2",
- "dpi",
- "gdkwayland-sys",
- "gdkx11-sys",
- "gtk",
- "jni",
- "libc",
- "log",
- "ndk",
- "ndk-sys",
- "objc2",
- "objc2-app-kit",
- "objc2-foundation",
- "objc2-ui-kit",
- "once_cell",
- "parking_lot",
- "percent-encoding",
- "raw-window-handle",
- "tao-macros",
- "unicode-segmentation",
- "url",
- "windows",
- "windows-core 0.61.2",
- "windows-version",
- "x11-dl",
-]
-
-[[package]]
-name = "tao-macros"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "target-lexicon"
-version = "0.12.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
-
-[[package]]
-name = "tauri"
-version = "2.11.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "667b20e2726d572dea2de7370da16e188eb06008faf9a92fab7cdc46791190b5"
-dependencies = [
- "anyhow",
- "bytes",
- "cookie",
- "dirs",
- "dunce",
- "embed_plist",
- "getrandom 0.3.4",
- "glob",
- "gtk",
- "heck 0.5.0",
- "http",
- "jni",
- "libc",
- "log",
- "mime",
- "muda",
- "objc2",
- "objc2-app-kit",
- "objc2-foundation",
- "objc2-ui-kit",
- "objc2-web-kit",
- "percent-encoding",
- "plist",
- "raw-window-handle",
- "reqwest 0.13.4",
- "serde",
- "serde_json",
- "serde_repr",
- "serialize-to-javascript",
- "swift-rs",
- "tauri-build",
- "tauri-macros",
- "tauri-runtime",
- "tauri-runtime-wry",
- "tauri-utils",
- "thiserror 2.0.18",
- "tokio",
- "tray-icon",
- "url",
- "webkit2gtk",
- "webview2-com",
- "window-vibrancy",
- "windows",
-]
-
-[[package]]
-name = "tauri-build"
-version = "2.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc9ce40b16101cb6ea63d3e221567affd1c3a9205f95d7bc574941a10636b632"
-dependencies = [
- "anyhow",
- "cargo_toml",
- "dirs",
- "glob",
- "heck 0.5.0",
- "json-patch",
- "schemars 0.8.22",
- "semver",
- "serde",
- "serde_json",
- "tauri-utils",
- "tauri-winres",
- "walkdir",
-]
-
-[[package]]
-name = "tauri-codegen"
-version = "2.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08279169ff42f8fc45a1dbc9dcae888893ba95288142e5880c59b93a26d2cfc5"
-dependencies = [
- "base64 0.22.1",
- "brotli",
- "ico",
- "json-patch",
- "plist",
- "png 0.17.16",
- "proc-macro2",
- "quote",
- "semver",
- "serde",
- "serde_json",
- "sha2",
- "syn 2.0.118",
- "tauri-utils",
- "thiserror 2.0.18",
- "time",
- "url",
- "uuid",
- "walkdir",
-]
-
-[[package]]
-name = "tauri-macros"
-version = "2.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8b394794f399a421811d06966343e7933fcae92d59f5180b9388d1174497a45"
-dependencies = [
- "heck 0.5.0",
- "proc-macro2",
- "quote",
- "syn 2.0.118",
- "tauri-codegen",
- "tauri-utils",
-]
-
-[[package]]
-name = "tauri-plugin"
-version = "2.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74be5dd4bed9afbd145e5716b5fa2ec28cbc29c34ffa61c258c9273d896c8020"
-dependencies = [
- "anyhow",
- "glob",
- "plist",
- "schemars 0.8.22",
- "serde",
- "serde_json",
- "tauri-utils",
- "walkdir",
-]
-
-[[package]]
-name = "tauri-plugin-dialog"
-version = "2.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "65981abb771e74e571a38196c3baa11c459379164791eba0e67abc1a5fac9884"
-dependencies = [
- "log",
- "raw-window-handle",
- "rfd",
- "serde",
- "serde_json",
- "tauri",
- "tauri-plugin",
- "tauri-plugin-fs",
- "thiserror 2.0.18",
- "url",
-]
-
-[[package]]
-name = "tauri-plugin-fs"
-version = "2.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7ecc274121aca0c036a2b42d1cbe83d368d348f54e0bb8a735c2b1548e8f371"
-dependencies = [
- "anyhow",
- "dunce",
- "glob",
- "log",
- "objc2-foundation",
- "percent-encoding",
- "schemars 0.8.22",
- "serde",
- "serde_json",
- "serde_repr",
- "tauri",
- "tauri-plugin",
- "tauri-utils",
- "thiserror 2.0.18",
- "toml 1.1.2+spec-1.1.0",
- "url",
-]
-
-[[package]]
-name = "tauri-runtime"
-version = "2.11.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0b4bc95aed361b0019067d189a1174a603d460d0f6c72606512d59fc9c12ec8"
-dependencies = [
- "cookie",
- "dpi",
- "gtk",
- "http",
- "jni",
- "objc2",
- "objc2-ui-kit",
- "objc2-web-kit",
- "raw-window-handle",
- "serde",
- "serde_json",
- "tauri-utils",
- "thiserror 2.0.18",
- "url",
- "webkit2gtk",
- "webview2-com",
- "windows",
-]
-
-[[package]]
-name = "tauri-runtime-wry"
-version = "2.11.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e6fac707727b7a2f48e4ded90976324267371073edbb415ffb73bb0458d203f"
-dependencies = [
- "gtk",
- "http",
- "jni",
- "log",
- "objc2",
- "objc2-app-kit",
- "once_cell",
- "percent-encoding",
- "raw-window-handle",
- "softbuffer",
- "tao",
- "tauri-runtime",
- "tauri-utils",
- "url",
- "webkit2gtk",
- "webview2-com",
- "windows",
- "wry",
-]
-
-[[package]]
-name = "tauri-utils"
-version = "2.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e176a18e67764923c4f1ce66f25ae4abe5f688384d5eb1a0fa6c77f3d90f887"
-dependencies = [
- "anyhow",
- "brotli",
- "cargo_metadata",
- "ctor",
- "dom_query",
- "dunce",
- "glob",
- "http",
- "infer",
- "json-patch",
- "log",
- "memchr",
- "phf",
- "plist",
- "proc-macro2",
- "quote",
- "regex",
- "schemars 0.8.22",
- "semver",
- "serde",
- "serde-untagged",
- "serde_json",
- "serde_with",
- "swift-rs",
- "thiserror 2.0.18",
- "toml 1.1.2+spec-1.1.0",
- "url",
- "urlpattern",
- "uuid",
- "walkdir",
-]
-
-[[package]]
-name = "tauri-winres"
-version = "0.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc65d45c68858bfe420dd29e834b5d15dbecf8a07a8a16cf4d532c7b1f69d4b6"
-dependencies = [
- "dunce",
- "embed-resource",
- "toml 1.1.2+spec-1.1.0",
-]
-
-[[package]]
-name = "tendril"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4790fc369d5a530f4b544b094e31388b9b3a37c0f4652ade4505945f5660d24"
-dependencies = [
- "new_debug_unreachable",
- "utf-8",
-]
-
-[[package]]
-name = "thiserror"
-version = "1.0.69"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
-dependencies = [
- "thiserror-impl 1.0.69",
-]
-
-[[package]]
-name = "thiserror"
-version = "2.0.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
-dependencies = [
- "thiserror-impl 2.0.18",
-]
-
-[[package]]
-name = "thiserror-impl"
-version = "1.0.69"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "thiserror-impl"
-version = "2.0.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "time"
-version = "0.3.53"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "18dfaaeddcb932337b5e7866ee7d0ce9b76d2fd092997146f187ec09b4558a50"
-dependencies = [
- "deranged",
- "num-conv",
- "powerfmt",
- "serde_core",
- "time-core",
- "time-macros",
-]
-
-[[package]]
-name = "time-core"
-version = "0.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109"
-
-[[package]]
-name = "time-macros"
-version = "0.2.31"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c431b87111666e491a90baa837f914fb45cd5dc3c268591b0220ff5057f2085f"
-dependencies = [
- "num-conv",
- "time-core",
-]
-
-[[package]]
-name = "tinystr"
-version = "0.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d"
-dependencies = [
- "displaydoc",
- "zerovec",
-]
-
-[[package]]
-name = "tinyvec"
-version = "1.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3"
-dependencies = [
- "tinyvec_macros",
-]
-
-[[package]]
-name = "tinyvec_macros"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
-
-[[package]]
-name = "tokio"
-version = "1.52.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe"
-dependencies = [
- "bytes",
- "libc",
- "mio",
- "pin-project-lite",
- "socket2",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "tokio-rustls"
-version = "0.26.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61"
-dependencies = [
- "rustls",
- "tokio",
-]
-
-[[package]]
-name = "tokio-util"
-version = "0.7.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098"
-dependencies = [
- "bytes",
- "futures-core",
- "futures-sink",
- "pin-project-lite",
- "tokio",
-]
-
-[[package]]
-name = "toml"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d"
-dependencies = [
- "serde",
- "serde_spanned 0.6.9",
- "toml_datetime 0.6.3",
- "toml_edit 0.20.2",
-]
-
-[[package]]
-name = "toml"
-version = "0.9.12+spec-1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863"
-dependencies = [
- "indexmap 2.14.0",
- "serde_core",
- "serde_spanned 1.1.1",
- "toml_datetime 0.7.5+spec-1.1.0",
- "toml_parser",
- "toml_writer",
- "winnow 0.7.15",
-]
-
-[[package]]
-name = "toml"
-version = "1.1.2+spec-1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee"
-dependencies = [
- "indexmap 2.14.0",
- "serde_core",
- "serde_spanned 1.1.1",
- "toml_datetime 1.1.1+spec-1.1.0",
- "toml_parser",
- "toml_writer",
- "winnow 1.0.3",
-]
-
-[[package]]
-name = "toml_datetime"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "toml_datetime"
-version = "0.7.5+spec-1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347"
-dependencies = [
- "serde_core",
-]
-
-[[package]]
-name = "toml_datetime"
-version = "1.1.1+spec-1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7"
-dependencies = [
- "serde_core",
-]
-
-[[package]]
-name = "toml_edit"
-version = "0.19.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
-dependencies = [
- "indexmap 2.14.0",
- "toml_datetime 0.6.3",
- "winnow 0.5.40",
-]
-
-[[package]]
-name = "toml_edit"
-version = "0.20.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338"
-dependencies = [
- "indexmap 2.14.0",
- "serde",
- "serde_spanned 0.6.9",
- "toml_datetime 0.6.3",
- "winnow 0.5.40",
-]
-
-[[package]]
-name = "toml_edit"
-version = "0.25.12+spec-1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7"
-dependencies = [
- "indexmap 2.14.0",
- "toml_datetime 1.1.1+spec-1.1.0",
- "toml_parser",
- "winnow 1.0.3",
-]
-
-[[package]]
-name = "toml_parser"
-version = "1.1.2+spec-1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526"
-dependencies = [
- "winnow 1.0.3",
-]
-
-[[package]]
-name = "toml_writer"
-version = "1.1.1+spec-1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db"
-
-[[package]]
-name = "tower"
-version = "0.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4"
-dependencies = [
- "futures-core",
- "futures-util",
- "pin-project-lite",
- "sync_wrapper",
- "tokio",
- "tower-layer",
- "tower-service",
-]
-
-[[package]]
-name = "tower-http"
-version = "0.6.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840"
-dependencies = [
- "bitflags 2.13.0",
- "bytes",
- "futures-util",
- "http",
- "http-body",
- "pin-project-lite",
- "tower",
- "tower-layer",
- "tower-service",
- "url",
-]
-
-[[package]]
-name = "tower-layer"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
-
-[[package]]
-name = "tower-service"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
-
-[[package]]
-name = "tracing"
-version = "0.1.44"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
-dependencies = [
- "pin-project-lite",
- "tracing-core",
-]
-
-[[package]]
-name = "tracing-core"
-version = "0.1.36"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
-dependencies = [
- "once_cell",
-]
-
-[[package]]
-name = "tray-icon"
-version = "0.24.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "65ba1e5f6b9ef9fd87e21b9c6f351554dbd717960089168fcfdef854686961dc"
-dependencies = [
- "crossbeam-channel",
- "dirs",
- "libappindicator",
- "muda",
- "objc2",
- "objc2-app-kit",
- "objc2-core-foundation",
- "objc2-core-graphics",
- "objc2-foundation",
- "once_cell",
- "png 0.18.1",
- "serde",
- "thiserror 2.0.18",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "try-lock"
-version = "0.2.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
-
-[[package]]
-name = "typeid"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c"
-
-[[package]]
-name = "typenum"
-version = "1.20.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20"
-
-[[package]]
-name = "unic-char-property"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221"
-dependencies = [
- "unic-char-range",
-]
-
-[[package]]
-name = "unic-char-range"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc"
-
-[[package]]
-name = "unic-common"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc"
-
-[[package]]
-name = "unic-ucd-ident"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e230a37c0381caa9219d67cf063aa3a375ffed5bf541a452db16e744bdab6987"
-dependencies = [
- "unic-char-property",
- "unic-char-range",
- "unic-ucd-version",
-]
-
-[[package]]
-name = "unic-ucd-version"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4"
-dependencies = [
- "unic-common",
-]
-
-[[package]]
-name = "unicode-ident"
-version = "1.0.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
-
-[[package]]
-name = "unicode-segmentation"
-version = "1.13.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8"
-
-[[package]]
-name = "untrusted"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
-
-[[package]]
-name = "url"
-version = "2.5.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed"
-dependencies = [
- "form_urlencoded",
- "idna",
- "percent-encoding",
- "serde",
- "serde_derive",
-]
-
-[[package]]
-name = "urlpattern"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70acd30e3aa1450bc2eece896ce2ad0d178e9c079493819301573dae3c37ba6d"
-dependencies = [
- "regex",
- "serde",
- "unic-ucd-ident",
- "url",
-]
-
-[[package]]
-name = "utf-8"
-version = "0.7.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
-
-[[package]]
-name = "utf8_iter"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
-
-[[package]]
-name = "uuid"
-version = "1.23.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53"
-dependencies = [
- "getrandom 0.4.3",
- "js-sys",
- "serde_core",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "version-compare"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03c2856837ef78f57382f06b2b8563a2f512f7185d732608fd9176cb3b8edf0e"
-
-[[package]]
-name = "version_check"
-version = "0.9.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
-
-[[package]]
-name = "vpn-proxy-windows-client"
-version = "0.1.0"
-dependencies = [
- "base64 0.22.1",
- "reqwest 0.12.28",
- "serde",
- "serde_json",
- "tauri",
- "tauri-build",
- "tauri-plugin-dialog",
- "url",
-]
-
-[[package]]
-name = "vswhom"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b"
-dependencies = [
- "libc",
- "vswhom-sys",
-]
-
-[[package]]
-name = "vswhom-sys"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb067e4cbd1ff067d1df46c9194b5de0e98efd2810bbc95c5d5e5f25a3231150"
-dependencies = [
- "cc",
- "libc",
-]
-
-[[package]]
-name = "walkdir"
-version = "2.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
-dependencies = [
- "same-file",
- "winapi-util",
-]
-
-[[package]]
-name = "want"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
-dependencies = [
- "try-lock",
-]
-
-[[package]]
-name = "wasi"
-version = "0.11.1+wasi-snapshot-preview1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
-
-[[package]]
-name = "wasip2"
-version = "1.0.4+wasi-0.2.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487"
-dependencies = [
- "wit-bindgen",
-]
-
-[[package]]
-name = "wasm-bindgen"
-version = "0.2.126"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4"
-dependencies = [
- "cfg-if",
- "once_cell",
- "rustversion",
- "wasm-bindgen-macro",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-futures"
-version = "0.4.76"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d"
-dependencies = [
- "js-sys",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "wasm-bindgen-macro"
-version = "0.2.126"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1"
-dependencies = [
- "quote",
- "wasm-bindgen-macro-support",
-]
-
-[[package]]
-name = "wasm-bindgen-macro-support"
-version = "0.2.126"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e"
-dependencies = [
- "bumpalo",
- "proc-macro2",
- "quote",
- "syn 2.0.118",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-shared"
-version = "0.2.126"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24"
-dependencies = [
- "unicode-ident",
-]
-
-[[package]]
-name = "wasm-streams"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb"
-dependencies = [
- "futures-util",
- "js-sys",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "web-sys",
-]
-
-[[package]]
-name = "web-sys"
-version = "0.3.103"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141"
-dependencies = [
- "js-sys",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "web-time"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
-dependencies = [
- "js-sys",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "web_atoms"
-version = "0.2.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "075474b12bcb3d2e3d4546580e9de478eeeead668a1761e2a8860c836b7ef297"
-dependencies = [
- "phf",
- "phf_codegen",
- "string_cache",
- "string_cache_codegen",
-]
-
-[[package]]
-name = "webkit2gtk"
-version = "2.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1027150013530fb2eaf806408df88461ae4815a45c541c8975e61d6f2fc4793"
-dependencies = [
- "bitflags 1.3.2",
- "cairo-rs",
- "gdk",
- "gdk-sys",
- "gio",
- "gio-sys",
- "glib",
- "glib-sys",
- "gobject-sys",
- "gtk",
- "gtk-sys",
- "javascriptcore-rs",
- "libc",
- "once_cell",
- "soup3",
- "webkit2gtk-sys",
-]
-
-[[package]]
-name = "webkit2gtk-sys"
-version = "2.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "916a5f65c2ef0dfe12fff695960a2ec3d4565359fdbb2e9943c974e06c734ea5"
-dependencies = [
- "bitflags 1.3.2",
- "cairo-sys-rs",
- "gdk-sys",
- "gio-sys",
- "glib-sys",
- "gobject-sys",
- "gtk-sys",
- "javascriptcore-rs-sys",
- "libc",
- "pkg-config",
- "soup3-sys",
- "system-deps",
-]
-
-[[package]]
-name = "webpki-roots"
-version = "1.0.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf85cb06032201fa7c6f829d7db5a7e5aa45bcc0655327713065f6f0576731bf"
-dependencies = [
- "rustls-pki-types",
-]
-
-[[package]]
-name = "webview2-com"
-version = "0.38.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7130243a7a5b33c54a444e54842e6a9e133de08b5ad7b5861cd8ed9a6a5bc96a"
-dependencies = [
- "webview2-com-macros",
- "webview2-com-sys",
- "windows",
- "windows-core 0.61.2",
- "windows-implement",
- "windows-interface",
-]
-
-[[package]]
-name = "webview2-com-macros"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67a921c1b6914c367b2b823cd4cde6f96beec77d30a939c8199bb377cf9b9b54"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "webview2-com-sys"
-version = "0.38.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "381336cfffd772377d291702245447a5251a2ffa5bad679c99e61bc48bacbf9c"
-dependencies = [
- "thiserror 2.0.18",
- "windows",
- "windows-core 0.61.2",
-]
-
-[[package]]
-name = "winapi"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
-dependencies = [
- "winapi-i686-pc-windows-gnu",
- "winapi-x86_64-pc-windows-gnu",
-]
-
-[[package]]
-name = "winapi-i686-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
-
-[[package]]
-name = "winapi-util"
-version = "0.1.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
-dependencies = [
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "winapi-x86_64-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
-
-[[package]]
-name = "window-vibrancy"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9bec5a31f3f9362f2258fd0e9c9dd61a9ca432e7306cc78c444258f0dce9a9c"
-dependencies = [
- "objc2",
- "objc2-app-kit",
- "objc2-core-foundation",
- "objc2-foundation",
- "raw-window-handle",
- "windows-sys 0.59.0",
- "windows-version",
-]
-
-[[package]]
-name = "windows"
-version = "0.61.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893"
-dependencies = [
- "windows-collections",
- "windows-core 0.61.2",
- "windows-future",
- "windows-link 0.1.3",
- "windows-numerics",
-]
-
-[[package]]
-name = "windows-collections"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8"
-dependencies = [
- "windows-core 0.61.2",
-]
-
-[[package]]
-name = "windows-core"
-version = "0.61.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
-dependencies = [
- "windows-implement",
- "windows-interface",
- "windows-link 0.1.3",
- "windows-result 0.3.4",
- "windows-strings 0.4.2",
-]
-
-[[package]]
-name = "windows-core"
-version = "0.62.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
-dependencies = [
- "windows-implement",
- "windows-interface",
- "windows-link 0.2.1",
- "windows-result 0.4.1",
- "windows-strings 0.5.1",
-]
-
-[[package]]
-name = "windows-future"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
-dependencies = [
- "windows-core 0.61.2",
- "windows-link 0.1.3",
- "windows-threading",
-]
-
-[[package]]
-name = "windows-implement"
-version = "0.60.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "windows-interface"
-version = "0.59.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "windows-link"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
-
-[[package]]
-name = "windows-link"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
-
-[[package]]
-name = "windows-numerics"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
-dependencies = [
- "windows-core 0.61.2",
- "windows-link 0.1.3",
-]
-
-[[package]]
-name = "windows-result"
-version = "0.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
-dependencies = [
- "windows-link 0.1.3",
-]
-
-[[package]]
-name = "windows-result"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
-dependencies = [
- "windows-link 0.2.1",
-]
-
-[[package]]
-name = "windows-strings"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
-dependencies = [
- "windows-link 0.1.3",
-]
-
-[[package]]
-name = "windows-strings"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
-dependencies = [
- "windows-link 0.2.1",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.45.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
-dependencies = [
- "windows-targets 0.42.2",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.52.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
-dependencies = [
- "windows-targets 0.52.6",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.59.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
-dependencies = [
- "windows-targets 0.52.6",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.60.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
-dependencies = [
- "windows-targets 0.53.5",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.61.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
-dependencies = [
- "windows-link 0.2.1",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
-dependencies = [
- "windows_aarch64_gnullvm 0.42.2",
- "windows_aarch64_msvc 0.42.2",
- "windows_i686_gnu 0.42.2",
- "windows_i686_msvc 0.42.2",
- "windows_x86_64_gnu 0.42.2",
- "windows_x86_64_gnullvm 0.42.2",
- "windows_x86_64_msvc 0.42.2",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
-dependencies = [
- "windows_aarch64_gnullvm 0.52.6",
- "windows_aarch64_msvc 0.52.6",
- "windows_i686_gnu 0.52.6",
- "windows_i686_gnullvm 0.52.6",
- "windows_i686_msvc 0.52.6",
- "windows_x86_64_gnu 0.52.6",
- "windows_x86_64_gnullvm 0.52.6",
- "windows_x86_64_msvc 0.52.6",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.53.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
-dependencies = [
- "windows-link 0.2.1",
- "windows_aarch64_gnullvm 0.53.1",
- "windows_aarch64_msvc 0.53.1",
- "windows_i686_gnu 0.53.1",
- "windows_i686_gnullvm 0.53.1",
- "windows_i686_msvc 0.53.1",
- "windows_x86_64_gnu 0.53.1",
- "windows_x86_64_gnullvm 0.53.1",
- "windows_x86_64_msvc 0.53.1",
-]
-
-[[package]]
-name = "windows-threading"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6"
-dependencies = [
- "windows-link 0.1.3",
-]
-
-[[package]]
-name = "windows-version"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e4060a1da109b9d0326b7262c8e12c84df67cc0dbc9e33cf49e01ccc2eb63631"
-dependencies = [
- "windows-link 0.2.1",
-]
-
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
-
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
-
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
-
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
-
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
-
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
-
-[[package]]
-name = "windows_i686_gnu"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
-
-[[package]]
-name = "windows_i686_gnu"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
-
-[[package]]
-name = "windows_i686_gnu"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
-
-[[package]]
-name = "windows_i686_gnullvm"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
-
-[[package]]
-name = "windows_i686_gnullvm"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
-
-[[package]]
-name = "windows_i686_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
-
-[[package]]
-name = "windows_i686_msvc"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
-
-[[package]]
-name = "windows_i686_msvc"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
-
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
-
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
-
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
-
-[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
-
-[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
-
-[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
-
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
-
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
-
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
-
-[[package]]
-name = "winnow"
-version = "0.5.40"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "winnow"
-version = "0.7.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945"
-
-[[package]]
-name = "winnow"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "winreg"
-version = "0.55.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb5a765337c50e9ec252c2069be9bf91c7df47afb103b642ba3a53bf8101be97"
-dependencies = [
- "cfg-if",
- "windows-sys 0.59.0",
-]
-
-[[package]]
-name = "wit-bindgen"
-version = "0.57.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
-
-[[package]]
-name = "writeable"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4"
-
-[[package]]
-name = "wry"
-version = "0.55.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "186f9871daa55fd9c016578b810d149de58367113db7fb72b462d2323ce19514"
-dependencies = [
- "base64 0.22.1",
- "block2",
- "cookie",
- "crossbeam-channel",
- "dirs",
- "dom_query",
- "dpi",
- "dunce",
- "gdkx11",
- "gtk",
- "http",
- "javascriptcore-rs",
- "jni",
- "libc",
- "ndk",
- "objc2",
- "objc2-app-kit",
- "objc2-core-foundation",
- "objc2-foundation",
- "objc2-ui-kit",
- "objc2-web-kit",
- "once_cell",
- "percent-encoding",
- "raw-window-handle",
- "sha2",
- "soup3",
- "tao-macros",
- "thiserror 2.0.18",
- "url",
- "webkit2gtk",
- "webkit2gtk-sys",
- "webview2-com",
- "windows",
- "windows-core 0.61.2",
- "windows-version",
- "x11-dl",
-]
-
-[[package]]
-name = "x11"
-version = "2.21.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e"
-dependencies = [
- "libc",
- "pkg-config",
-]
-
-[[package]]
-name = "x11-dl"
-version = "2.21.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f"
-dependencies = [
- "libc",
- "once_cell",
- "pkg-config",
-]
-
-[[package]]
-name = "yoke"
-version = "0.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5"
-dependencies = [
- "stable_deref_trait",
- "yoke-derive",
- "zerofrom",
-]
-
-[[package]]
-name = "yoke-derive"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.118",
- "synstructure",
-]
-
-[[package]]
-name = "zerofrom"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272"
-dependencies = [
- "zerofrom-derive",
-]
-
-[[package]]
-name = "zerofrom-derive"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.118",
- "synstructure",
-]
-
-[[package]]
-name = "zeroize"
-version = "1.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e"
-
-[[package]]
-name = "zerotrie"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf"
-dependencies = [
- "displaydoc",
- "yoke",
- "zerofrom",
-]
-
-[[package]]
-name = "zerovec"
-version = "0.11.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239"
-dependencies = [
- "yoke",
- "zerofrom",
- "zerovec-derive",
-]
-
-[[package]]
-name = "zerovec-derive"
-version = "0.11.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.118",
-]
-
-[[package]]
-name = "zmij"
-version = "1.0.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
diff --git a/apps/windows-client/src-tauri/Cargo.toml b/apps/windows-client/src-tauri/Cargo.toml
deleted file mode 100644
index 3eed604..0000000
--- a/apps/windows-client/src-tauri/Cargo.toml
+++ /dev/null
@@ -1,22 +0,0 @@
-[package]
-name = "vpn-proxy-windows-client"
-version = "0.1.0"
-description = "Standalone Windows desktop proxy management app for VPN Proxy."
-authors = ["VPN Proxy"]
-edition = "2021"
-
-[lib]
-name = "vpn_proxy_windows_client_lib"
-crate-type = ["staticlib", "cdylib", "rlib"]
-
-[build-dependencies]
-tauri-build = { version = "2", features = [] }
-
-[dependencies]
-tauri = { version = "2", features = [] }
-serde = { version = "1", features = ["derive"] }
-serde_json = "1"
-tauri-plugin-dialog = "2.7.1"
-base64 = "0.22"
-reqwest = { version = "0.12", default-features = false, features = ["blocking", "rustls-tls"] }
-url = "2"
diff --git a/apps/windows-client/src-tauri/build.rs b/apps/windows-client/src-tauri/build.rs
deleted file mode 100644
index 261851f..0000000
--- a/apps/windows-client/src-tauri/build.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-fn main() {
- tauri_build::build();
-}
diff --git a/apps/windows-client/src-tauri/capabilities/default.json b/apps/windows-client/src-tauri/capabilities/default.json
deleted file mode 100644
index eb4bbd8..0000000
--- a/apps/windows-client/src-tauri/capabilities/default.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "$schema": "../gen/schemas/desktop-schema.json",
- "identifier": "default",
- "description": "Default capability for the main VPN Proxy Windows shell. Task 8 keeps helper/install launch explicit: no shell or sidecar permission is granted here until a packaged helper is declared.",
- "windows": ["main"],
- "permissions": ["core:default", "dialog:allow-open"]
-}
diff --git a/apps/windows-client/src-tauri/gen/schemas/acl-manifests.json b/apps/windows-client/src-tauri/gen/schemas/acl-manifests.json
deleted file mode 100644
index f2f210a..0000000
--- a/apps/windows-client/src-tauri/gen/schemas/acl-manifests.json
+++ /dev/null
@@ -1 +0,0 @@
-{"core":{"default_permission":{"identifier":"default","description":"Default core plugins set.","permissions":["core:path:default","core:event:default","core:window:default","core:webview:default","core:app:default","core:image:default","core:resources:default","core:menu:default","core:tray:default"]},"permissions":{},"permission_sets":{},"global_scope_schema":null},"core:app":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-version","allow-name","allow-tauri-version","allow-identifier","allow-bundle-type","allow-register-listener","allow-remove-listener","allow-supports-multiple-windows"]},"permissions":{"allow-app-hide":{"identifier":"allow-app-hide","description":"Enables the app_hide command without any pre-configured scope.","commands":{"allow":["app_hide"],"deny":[]}},"allow-app-show":{"identifier":"allow-app-show","description":"Enables the app_show command without any pre-configured scope.","commands":{"allow":["app_show"],"deny":[]}},"allow-bundle-type":{"identifier":"allow-bundle-type","description":"Enables the bundle_type command without any pre-configured scope.","commands":{"allow":["bundle_type"],"deny":[]}},"allow-default-window-icon":{"identifier":"allow-default-window-icon","description":"Enables the default_window_icon command without any pre-configured scope.","commands":{"allow":["default_window_icon"],"deny":[]}},"allow-fetch-data-store-identifiers":{"identifier":"allow-fetch-data-store-identifiers","description":"Enables the fetch_data_store_identifiers command without any pre-configured scope.","commands":{"allow":["fetch_data_store_identifiers"],"deny":[]}},"allow-identifier":{"identifier":"allow-identifier","description":"Enables the identifier command without any pre-configured scope.","commands":{"allow":["identifier"],"deny":[]}},"allow-name":{"identifier":"allow-name","description":"Enables the name command without any pre-configured scope.","commands":{"allow":["name"],"deny":[]}},"allow-register-listener":{"identifier":"allow-register-listener","description":"Enables the register_listener command without any pre-configured scope.","commands":{"allow":["register_listener"],"deny":[]}},"allow-remove-data-store":{"identifier":"allow-remove-data-store","description":"Enables the remove_data_store command without any pre-configured scope.","commands":{"allow":["remove_data_store"],"deny":[]}},"allow-remove-listener":{"identifier":"allow-remove-listener","description":"Enables the remove_listener command without any pre-configured scope.","commands":{"allow":["remove_listener"],"deny":[]}},"allow-set-app-theme":{"identifier":"allow-set-app-theme","description":"Enables the set_app_theme command without any pre-configured scope.","commands":{"allow":["set_app_theme"],"deny":[]}},"allow-set-dock-visibility":{"identifier":"allow-set-dock-visibility","description":"Enables the set_dock_visibility command without any pre-configured scope.","commands":{"allow":["set_dock_visibility"],"deny":[]}},"allow-supports-multiple-windows":{"identifier":"allow-supports-multiple-windows","description":"Enables the supports_multiple_windows command without any pre-configured scope.","commands":{"allow":["supports_multiple_windows"],"deny":[]}},"allow-tauri-version":{"identifier":"allow-tauri-version","description":"Enables the tauri_version command without any pre-configured scope.","commands":{"allow":["tauri_version"],"deny":[]}},"allow-version":{"identifier":"allow-version","description":"Enables the version command without any pre-configured scope.","commands":{"allow":["version"],"deny":[]}},"deny-app-hide":{"identifier":"deny-app-hide","description":"Denies the app_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["app_hide"]}},"deny-app-show":{"identifier":"deny-app-show","description":"Denies the app_show command without any pre-configured scope.","commands":{"allow":[],"deny":["app_show"]}},"deny-bundle-type":{"identifier":"deny-bundle-type","description":"Denies the bundle_type command without any pre-configured scope.","commands":{"allow":[],"deny":["bundle_type"]}},"deny-default-window-icon":{"identifier":"deny-default-window-icon","description":"Denies the default_window_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["default_window_icon"]}},"deny-fetch-data-store-identifiers":{"identifier":"deny-fetch-data-store-identifiers","description":"Denies the fetch_data_store_identifiers command without any pre-configured scope.","commands":{"allow":[],"deny":["fetch_data_store_identifiers"]}},"deny-identifier":{"identifier":"deny-identifier","description":"Denies the identifier command without any pre-configured scope.","commands":{"allow":[],"deny":["identifier"]}},"deny-name":{"identifier":"deny-name","description":"Denies the name command without any pre-configured scope.","commands":{"allow":[],"deny":["name"]}},"deny-register-listener":{"identifier":"deny-register-listener","description":"Denies the register_listener command without any pre-configured scope.","commands":{"allow":[],"deny":["register_listener"]}},"deny-remove-data-store":{"identifier":"deny-remove-data-store","description":"Denies the remove_data_store command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_data_store"]}},"deny-remove-listener":{"identifier":"deny-remove-listener","description":"Denies the remove_listener command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_listener"]}},"deny-set-app-theme":{"identifier":"deny-set-app-theme","description":"Denies the set_app_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_app_theme"]}},"deny-set-dock-visibility":{"identifier":"deny-set-dock-visibility","description":"Denies the set_dock_visibility command without any pre-configured scope.","commands":{"allow":[],"deny":["set_dock_visibility"]}},"deny-supports-multiple-windows":{"identifier":"deny-supports-multiple-windows","description":"Denies the supports_multiple_windows command without any pre-configured scope.","commands":{"allow":[],"deny":["supports_multiple_windows"]}},"deny-tauri-version":{"identifier":"deny-tauri-version","description":"Denies the tauri_version command without any pre-configured scope.","commands":{"allow":[],"deny":["tauri_version"]}},"deny-version":{"identifier":"deny-version","description":"Denies the version command without any pre-configured scope.","commands":{"allow":[],"deny":["version"]}}},"permission_sets":{},"global_scope_schema":null},"core:event":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-listen","allow-unlisten","allow-emit","allow-emit-to"]},"permissions":{"allow-emit":{"identifier":"allow-emit","description":"Enables the emit command without any pre-configured scope.","commands":{"allow":["emit"],"deny":[]}},"allow-emit-to":{"identifier":"allow-emit-to","description":"Enables the emit_to command without any pre-configured scope.","commands":{"allow":["emit_to"],"deny":[]}},"allow-listen":{"identifier":"allow-listen","description":"Enables the listen command without any pre-configured scope.","commands":{"allow":["listen"],"deny":[]}},"allow-unlisten":{"identifier":"allow-unlisten","description":"Enables the unlisten command without any pre-configured scope.","commands":{"allow":["unlisten"],"deny":[]}},"deny-emit":{"identifier":"deny-emit","description":"Denies the emit command without any pre-configured scope.","commands":{"allow":[],"deny":["emit"]}},"deny-emit-to":{"identifier":"deny-emit-to","description":"Denies the emit_to command without any pre-configured scope.","commands":{"allow":[],"deny":["emit_to"]}},"deny-listen":{"identifier":"deny-listen","description":"Denies the listen command without any pre-configured scope.","commands":{"allow":[],"deny":["listen"]}},"deny-unlisten":{"identifier":"deny-unlisten","description":"Denies the unlisten command without any pre-configured scope.","commands":{"allow":[],"deny":["unlisten"]}}},"permission_sets":{},"global_scope_schema":null},"core:image":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-from-bytes","allow-from-path","allow-rgba","allow-size"]},"permissions":{"allow-from-bytes":{"identifier":"allow-from-bytes","description":"Enables the from_bytes command without any pre-configured scope.","commands":{"allow":["from_bytes"],"deny":[]}},"allow-from-path":{"identifier":"allow-from-path","description":"Enables the from_path command without any pre-configured scope.","commands":{"allow":["from_path"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-rgba":{"identifier":"allow-rgba","description":"Enables the rgba command without any pre-configured scope.","commands":{"allow":["rgba"],"deny":[]}},"allow-size":{"identifier":"allow-size","description":"Enables the size command without any pre-configured scope.","commands":{"allow":["size"],"deny":[]}},"deny-from-bytes":{"identifier":"deny-from-bytes","description":"Denies the from_bytes command without any pre-configured scope.","commands":{"allow":[],"deny":["from_bytes"]}},"deny-from-path":{"identifier":"deny-from-path","description":"Denies the from_path command without any pre-configured scope.","commands":{"allow":[],"deny":["from_path"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-rgba":{"identifier":"deny-rgba","description":"Denies the rgba command without any pre-configured scope.","commands":{"allow":[],"deny":["rgba"]}},"deny-size":{"identifier":"deny-size","description":"Denies the size command without any pre-configured scope.","commands":{"allow":[],"deny":["size"]}}},"permission_sets":{},"global_scope_schema":null},"core:menu":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-append","allow-prepend","allow-insert","allow-remove","allow-remove-at","allow-items","allow-get","allow-popup","allow-create-default","allow-set-as-app-menu","allow-set-as-window-menu","allow-text","allow-set-text","allow-is-enabled","allow-set-enabled","allow-set-accelerator","allow-set-as-windows-menu-for-nsapp","allow-set-as-help-menu-for-nsapp","allow-is-checked","allow-set-checked","allow-set-icon"]},"permissions":{"allow-append":{"identifier":"allow-append","description":"Enables the append command without any pre-configured scope.","commands":{"allow":["append"],"deny":[]}},"allow-create-default":{"identifier":"allow-create-default","description":"Enables the create_default command without any pre-configured scope.","commands":{"allow":["create_default"],"deny":[]}},"allow-get":{"identifier":"allow-get","description":"Enables the get command without any pre-configured scope.","commands":{"allow":["get"],"deny":[]}},"allow-insert":{"identifier":"allow-insert","description":"Enables the insert command without any pre-configured scope.","commands":{"allow":["insert"],"deny":[]}},"allow-is-checked":{"identifier":"allow-is-checked","description":"Enables the is_checked command without any pre-configured scope.","commands":{"allow":["is_checked"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-items":{"identifier":"allow-items","description":"Enables the items command without any pre-configured scope.","commands":{"allow":["items"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-popup":{"identifier":"allow-popup","description":"Enables the popup command without any pre-configured scope.","commands":{"allow":["popup"],"deny":[]}},"allow-prepend":{"identifier":"allow-prepend","description":"Enables the prepend command without any pre-configured scope.","commands":{"allow":["prepend"],"deny":[]}},"allow-remove":{"identifier":"allow-remove","description":"Enables the remove command without any pre-configured scope.","commands":{"allow":["remove"],"deny":[]}},"allow-remove-at":{"identifier":"allow-remove-at","description":"Enables the remove_at command without any pre-configured scope.","commands":{"allow":["remove_at"],"deny":[]}},"allow-set-accelerator":{"identifier":"allow-set-accelerator","description":"Enables the set_accelerator command without any pre-configured scope.","commands":{"allow":["set_accelerator"],"deny":[]}},"allow-set-as-app-menu":{"identifier":"allow-set-as-app-menu","description":"Enables the set_as_app_menu command without any pre-configured scope.","commands":{"allow":["set_as_app_menu"],"deny":[]}},"allow-set-as-help-menu-for-nsapp":{"identifier":"allow-set-as-help-menu-for-nsapp","description":"Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_help_menu_for_nsapp"],"deny":[]}},"allow-set-as-window-menu":{"identifier":"allow-set-as-window-menu","description":"Enables the set_as_window_menu command without any pre-configured scope.","commands":{"allow":["set_as_window_menu"],"deny":[]}},"allow-set-as-windows-menu-for-nsapp":{"identifier":"allow-set-as-windows-menu-for-nsapp","description":"Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_windows_menu_for_nsapp"],"deny":[]}},"allow-set-checked":{"identifier":"allow-set-checked","description":"Enables the set_checked command without any pre-configured scope.","commands":{"allow":["set_checked"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-text":{"identifier":"allow-set-text","description":"Enables the set_text command without any pre-configured scope.","commands":{"allow":["set_text"],"deny":[]}},"allow-text":{"identifier":"allow-text","description":"Enables the text command without any pre-configured scope.","commands":{"allow":["text"],"deny":[]}},"deny-append":{"identifier":"deny-append","description":"Denies the append command without any pre-configured scope.","commands":{"allow":[],"deny":["append"]}},"deny-create-default":{"identifier":"deny-create-default","description":"Denies the create_default command without any pre-configured scope.","commands":{"allow":[],"deny":["create_default"]}},"deny-get":{"identifier":"deny-get","description":"Denies the get command without any pre-configured scope.","commands":{"allow":[],"deny":["get"]}},"deny-insert":{"identifier":"deny-insert","description":"Denies the insert command without any pre-configured scope.","commands":{"allow":[],"deny":["insert"]}},"deny-is-checked":{"identifier":"deny-is-checked","description":"Denies the is_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["is_checked"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-items":{"identifier":"deny-items","description":"Denies the items command without any pre-configured scope.","commands":{"allow":[],"deny":["items"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-popup":{"identifier":"deny-popup","description":"Denies the popup command without any pre-configured scope.","commands":{"allow":[],"deny":["popup"]}},"deny-prepend":{"identifier":"deny-prepend","description":"Denies the prepend command without any pre-configured scope.","commands":{"allow":[],"deny":["prepend"]}},"deny-remove":{"identifier":"deny-remove","description":"Denies the remove command without any pre-configured scope.","commands":{"allow":[],"deny":["remove"]}},"deny-remove-at":{"identifier":"deny-remove-at","description":"Denies the remove_at command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_at"]}},"deny-set-accelerator":{"identifier":"deny-set-accelerator","description":"Denies the set_accelerator command without any pre-configured scope.","commands":{"allow":[],"deny":["set_accelerator"]}},"deny-set-as-app-menu":{"identifier":"deny-set-as-app-menu","description":"Denies the set_as_app_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_app_menu"]}},"deny-set-as-help-menu-for-nsapp":{"identifier":"deny-set-as-help-menu-for-nsapp","description":"Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_help_menu_for_nsapp"]}},"deny-set-as-window-menu":{"identifier":"deny-set-as-window-menu","description":"Denies the set_as_window_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_window_menu"]}},"deny-set-as-windows-menu-for-nsapp":{"identifier":"deny-set-as-windows-menu-for-nsapp","description":"Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_windows_menu_for_nsapp"]}},"deny-set-checked":{"identifier":"deny-set-checked","description":"Denies the set_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["set_checked"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-text":{"identifier":"deny-set-text","description":"Denies the set_text command without any pre-configured scope.","commands":{"allow":[],"deny":["set_text"]}},"deny-text":{"identifier":"deny-text","description":"Denies the text command without any pre-configured scope.","commands":{"allow":[],"deny":["text"]}}},"permission_sets":{},"global_scope_schema":null},"core:path":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-resolve-directory","allow-resolve","allow-normalize","allow-join","allow-dirname","allow-extname","allow-basename","allow-is-absolute"]},"permissions":{"allow-basename":{"identifier":"allow-basename","description":"Enables the basename command without any pre-configured scope.","commands":{"allow":["basename"],"deny":[]}},"allow-dirname":{"identifier":"allow-dirname","description":"Enables the dirname command without any pre-configured scope.","commands":{"allow":["dirname"],"deny":[]}},"allow-extname":{"identifier":"allow-extname","description":"Enables the extname command without any pre-configured scope.","commands":{"allow":["extname"],"deny":[]}},"allow-is-absolute":{"identifier":"allow-is-absolute","description":"Enables the is_absolute command without any pre-configured scope.","commands":{"allow":["is_absolute"],"deny":[]}},"allow-join":{"identifier":"allow-join","description":"Enables the join command without any pre-configured scope.","commands":{"allow":["join"],"deny":[]}},"allow-normalize":{"identifier":"allow-normalize","description":"Enables the normalize command without any pre-configured scope.","commands":{"allow":["normalize"],"deny":[]}},"allow-resolve":{"identifier":"allow-resolve","description":"Enables the resolve command without any pre-configured scope.","commands":{"allow":["resolve"],"deny":[]}},"allow-resolve-directory":{"identifier":"allow-resolve-directory","description":"Enables the resolve_directory command without any pre-configured scope.","commands":{"allow":["resolve_directory"],"deny":[]}},"deny-basename":{"identifier":"deny-basename","description":"Denies the basename command without any pre-configured scope.","commands":{"allow":[],"deny":["basename"]}},"deny-dirname":{"identifier":"deny-dirname","description":"Denies the dirname command without any pre-configured scope.","commands":{"allow":[],"deny":["dirname"]}},"deny-extname":{"identifier":"deny-extname","description":"Denies the extname command without any pre-configured scope.","commands":{"allow":[],"deny":["extname"]}},"deny-is-absolute":{"identifier":"deny-is-absolute","description":"Denies the is_absolute command without any pre-configured scope.","commands":{"allow":[],"deny":["is_absolute"]}},"deny-join":{"identifier":"deny-join","description":"Denies the join command without any pre-configured scope.","commands":{"allow":[],"deny":["join"]}},"deny-normalize":{"identifier":"deny-normalize","description":"Denies the normalize command without any pre-configured scope.","commands":{"allow":[],"deny":["normalize"]}},"deny-resolve":{"identifier":"deny-resolve","description":"Denies the resolve command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve"]}},"deny-resolve-directory":{"identifier":"deny-resolve-directory","description":"Denies the resolve_directory command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve_directory"]}}},"permission_sets":{},"global_scope_schema":null},"core:resources":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-close"]},"permissions":{"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}}},"permission_sets":{},"global_scope_schema":null},"core:tray":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-get-by-id","allow-remove-by-id","allow-set-icon","allow-set-menu","allow-set-tooltip","allow-set-title","allow-set-visible","allow-set-temp-dir-path","allow-set-icon-as-template","allow-set-icon-with-as-template","allow-set-show-menu-on-left-click"]},"permissions":{"allow-get-by-id":{"identifier":"allow-get-by-id","description":"Enables the get_by_id command without any pre-configured scope.","commands":{"allow":["get_by_id"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-remove-by-id":{"identifier":"allow-remove-by-id","description":"Enables the remove_by_id command without any pre-configured scope.","commands":{"allow":["remove_by_id"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-icon-as-template":{"identifier":"allow-set-icon-as-template","description":"Enables the set_icon_as_template command without any pre-configured scope.","commands":{"allow":["set_icon_as_template"],"deny":[]}},"allow-set-icon-with-as-template":{"identifier":"allow-set-icon-with-as-template","description":"Enables the set_icon_with_as_template command without any pre-configured scope.","commands":{"allow":["set_icon_with_as_template"],"deny":[]}},"allow-set-menu":{"identifier":"allow-set-menu","description":"Enables the set_menu command without any pre-configured scope.","commands":{"allow":["set_menu"],"deny":[]}},"allow-set-show-menu-on-left-click":{"identifier":"allow-set-show-menu-on-left-click","description":"Enables the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":["set_show_menu_on_left_click"],"deny":[]}},"allow-set-temp-dir-path":{"identifier":"allow-set-temp-dir-path","description":"Enables the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":["set_temp_dir_path"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-tooltip":{"identifier":"allow-set-tooltip","description":"Enables the set_tooltip command without any pre-configured scope.","commands":{"allow":["set_tooltip"],"deny":[]}},"allow-set-visible":{"identifier":"allow-set-visible","description":"Enables the set_visible command without any pre-configured scope.","commands":{"allow":["set_visible"],"deny":[]}},"deny-get-by-id":{"identifier":"deny-get-by-id","description":"Denies the get_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["get_by_id"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-remove-by-id":{"identifier":"deny-remove-by-id","description":"Denies the remove_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_by_id"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-icon-as-template":{"identifier":"deny-set-icon-as-template","description":"Denies the set_icon_as_template command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon_as_template"]}},"deny-set-icon-with-as-template":{"identifier":"deny-set-icon-with-as-template","description":"Denies the set_icon_with_as_template command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon_with_as_template"]}},"deny-set-menu":{"identifier":"deny-set-menu","description":"Denies the set_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_menu"]}},"deny-set-show-menu-on-left-click":{"identifier":"deny-set-show-menu-on-left-click","description":"Denies the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":[],"deny":["set_show_menu_on_left_click"]}},"deny-set-temp-dir-path":{"identifier":"deny-set-temp-dir-path","description":"Denies the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":[],"deny":["set_temp_dir_path"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-tooltip":{"identifier":"deny-set-tooltip","description":"Denies the set_tooltip command without any pre-configured scope.","commands":{"allow":[],"deny":["set_tooltip"]}},"deny-set-visible":{"identifier":"deny-set-visible","description":"Denies the set_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible"]}}},"permission_sets":{},"global_scope_schema":null},"core:webview":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-webviews","allow-webview-position","allow-webview-size","allow-internal-toggle-devtools"]},"permissions":{"allow-clear-all-browsing-data":{"identifier":"allow-clear-all-browsing-data","description":"Enables the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":["clear_all_browsing_data"],"deny":[]}},"allow-create-webview":{"identifier":"allow-create-webview","description":"Enables the create_webview command without any pre-configured scope.","commands":{"allow":["create_webview"],"deny":[]}},"allow-create-webview-window":{"identifier":"allow-create-webview-window","description":"Enables the create_webview_window command without any pre-configured scope.","commands":{"allow":["create_webview_window"],"deny":[]}},"allow-get-all-webviews":{"identifier":"allow-get-all-webviews","description":"Enables the get_all_webviews command without any pre-configured scope.","commands":{"allow":["get_all_webviews"],"deny":[]}},"allow-internal-toggle-devtools":{"identifier":"allow-internal-toggle-devtools","description":"Enables the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":["internal_toggle_devtools"],"deny":[]}},"allow-print":{"identifier":"allow-print","description":"Enables the print command without any pre-configured scope.","commands":{"allow":["print"],"deny":[]}},"allow-reparent":{"identifier":"allow-reparent","description":"Enables the reparent command without any pre-configured scope.","commands":{"allow":["reparent"],"deny":[]}},"allow-set-webview-auto-resize":{"identifier":"allow-set-webview-auto-resize","description":"Enables the set_webview_auto_resize command without any pre-configured scope.","commands":{"allow":["set_webview_auto_resize"],"deny":[]}},"allow-set-webview-background-color":{"identifier":"allow-set-webview-background-color","description":"Enables the set_webview_background_color command without any pre-configured scope.","commands":{"allow":["set_webview_background_color"],"deny":[]}},"allow-set-webview-focus":{"identifier":"allow-set-webview-focus","description":"Enables the set_webview_focus command without any pre-configured scope.","commands":{"allow":["set_webview_focus"],"deny":[]}},"allow-set-webview-position":{"identifier":"allow-set-webview-position","description":"Enables the set_webview_position command without any pre-configured scope.","commands":{"allow":["set_webview_position"],"deny":[]}},"allow-set-webview-size":{"identifier":"allow-set-webview-size","description":"Enables the set_webview_size command without any pre-configured scope.","commands":{"allow":["set_webview_size"],"deny":[]}},"allow-set-webview-zoom":{"identifier":"allow-set-webview-zoom","description":"Enables the set_webview_zoom command without any pre-configured scope.","commands":{"allow":["set_webview_zoom"],"deny":[]}},"allow-webview-close":{"identifier":"allow-webview-close","description":"Enables the webview_close command without any pre-configured scope.","commands":{"allow":["webview_close"],"deny":[]}},"allow-webview-hide":{"identifier":"allow-webview-hide","description":"Enables the webview_hide command without any pre-configured scope.","commands":{"allow":["webview_hide"],"deny":[]}},"allow-webview-position":{"identifier":"allow-webview-position","description":"Enables the webview_position command without any pre-configured scope.","commands":{"allow":["webview_position"],"deny":[]}},"allow-webview-show":{"identifier":"allow-webview-show","description":"Enables the webview_show command without any pre-configured scope.","commands":{"allow":["webview_show"],"deny":[]}},"allow-webview-size":{"identifier":"allow-webview-size","description":"Enables the webview_size command without any pre-configured scope.","commands":{"allow":["webview_size"],"deny":[]}},"deny-clear-all-browsing-data":{"identifier":"deny-clear-all-browsing-data","description":"Denies the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":[],"deny":["clear_all_browsing_data"]}},"deny-create-webview":{"identifier":"deny-create-webview","description":"Denies the create_webview command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview"]}},"deny-create-webview-window":{"identifier":"deny-create-webview-window","description":"Denies the create_webview_window command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview_window"]}},"deny-get-all-webviews":{"identifier":"deny-get-all-webviews","description":"Denies the get_all_webviews command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_webviews"]}},"deny-internal-toggle-devtools":{"identifier":"deny-internal-toggle-devtools","description":"Denies the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_devtools"]}},"deny-print":{"identifier":"deny-print","description":"Denies the print command without any pre-configured scope.","commands":{"allow":[],"deny":["print"]}},"deny-reparent":{"identifier":"deny-reparent","description":"Denies the reparent command without any pre-configured scope.","commands":{"allow":[],"deny":["reparent"]}},"deny-set-webview-auto-resize":{"identifier":"deny-set-webview-auto-resize","description":"Denies the set_webview_auto_resize command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_auto_resize"]}},"deny-set-webview-background-color":{"identifier":"deny-set-webview-background-color","description":"Denies the set_webview_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_background_color"]}},"deny-set-webview-focus":{"identifier":"deny-set-webview-focus","description":"Denies the set_webview_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_focus"]}},"deny-set-webview-position":{"identifier":"deny-set-webview-position","description":"Denies the set_webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_position"]}},"deny-set-webview-size":{"identifier":"deny-set-webview-size","description":"Denies the set_webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_size"]}},"deny-set-webview-zoom":{"identifier":"deny-set-webview-zoom","description":"Denies the set_webview_zoom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_zoom"]}},"deny-webview-close":{"identifier":"deny-webview-close","description":"Denies the webview_close command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_close"]}},"deny-webview-hide":{"identifier":"deny-webview-hide","description":"Denies the webview_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_hide"]}},"deny-webview-position":{"identifier":"deny-webview-position","description":"Denies the webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_position"]}},"deny-webview-show":{"identifier":"deny-webview-show","description":"Denies the webview_show command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_show"]}},"deny-webview-size":{"identifier":"deny-webview-size","description":"Denies the webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_size"]}}},"permission_sets":{},"global_scope_schema":null},"core:window":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-windows","allow-scale-factor","allow-inner-position","allow-outer-position","allow-inner-size","allow-outer-size","allow-is-fullscreen","allow-is-minimized","allow-is-maximized","allow-is-focused","allow-is-decorated","allow-is-resizable","allow-is-maximizable","allow-is-minimizable","allow-is-closable","allow-is-visible","allow-is-enabled","allow-title","allow-current-monitor","allow-primary-monitor","allow-monitor-from-point","allow-available-monitors","allow-cursor-position","allow-theme","allow-is-always-on-top","allow-activity-name","allow-scene-identifier","allow-internal-toggle-maximize"]},"permissions":{"allow-activity-name":{"identifier":"allow-activity-name","description":"Enables the activity_name command without any pre-configured scope.","commands":{"allow":["activity_name"],"deny":[]}},"allow-available-monitors":{"identifier":"allow-available-monitors","description":"Enables the available_monitors command without any pre-configured scope.","commands":{"allow":["available_monitors"],"deny":[]}},"allow-center":{"identifier":"allow-center","description":"Enables the center command without any pre-configured scope.","commands":{"allow":["center"],"deny":[]}},"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"allow-create":{"identifier":"allow-create","description":"Enables the create command without any pre-configured scope.","commands":{"allow":["create"],"deny":[]}},"allow-current-monitor":{"identifier":"allow-current-monitor","description":"Enables the current_monitor command without any pre-configured scope.","commands":{"allow":["current_monitor"],"deny":[]}},"allow-cursor-position":{"identifier":"allow-cursor-position","description":"Enables the cursor_position command without any pre-configured scope.","commands":{"allow":["cursor_position"],"deny":[]}},"allow-destroy":{"identifier":"allow-destroy","description":"Enables the destroy command without any pre-configured scope.","commands":{"allow":["destroy"],"deny":[]}},"allow-get-all-windows":{"identifier":"allow-get-all-windows","description":"Enables the get_all_windows command without any pre-configured scope.","commands":{"allow":["get_all_windows"],"deny":[]}},"allow-hide":{"identifier":"allow-hide","description":"Enables the hide command without any pre-configured scope.","commands":{"allow":["hide"],"deny":[]}},"allow-inner-position":{"identifier":"allow-inner-position","description":"Enables the inner_position command without any pre-configured scope.","commands":{"allow":["inner_position"],"deny":[]}},"allow-inner-size":{"identifier":"allow-inner-size","description":"Enables the inner_size command without any pre-configured scope.","commands":{"allow":["inner_size"],"deny":[]}},"allow-internal-toggle-maximize":{"identifier":"allow-internal-toggle-maximize","description":"Enables the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":["internal_toggle_maximize"],"deny":[]}},"allow-is-always-on-top":{"identifier":"allow-is-always-on-top","description":"Enables the is_always_on_top command without any pre-configured scope.","commands":{"allow":["is_always_on_top"],"deny":[]}},"allow-is-closable":{"identifier":"allow-is-closable","description":"Enables the is_closable command without any pre-configured scope.","commands":{"allow":["is_closable"],"deny":[]}},"allow-is-decorated":{"identifier":"allow-is-decorated","description":"Enables the is_decorated command without any pre-configured scope.","commands":{"allow":["is_decorated"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-is-focused":{"identifier":"allow-is-focused","description":"Enables the is_focused command without any pre-configured scope.","commands":{"allow":["is_focused"],"deny":[]}},"allow-is-fullscreen":{"identifier":"allow-is-fullscreen","description":"Enables the is_fullscreen command without any pre-configured scope.","commands":{"allow":["is_fullscreen"],"deny":[]}},"allow-is-maximizable":{"identifier":"allow-is-maximizable","description":"Enables the is_maximizable command without any pre-configured scope.","commands":{"allow":["is_maximizable"],"deny":[]}},"allow-is-maximized":{"identifier":"allow-is-maximized","description":"Enables the is_maximized command without any pre-configured scope.","commands":{"allow":["is_maximized"],"deny":[]}},"allow-is-minimizable":{"identifier":"allow-is-minimizable","description":"Enables the is_minimizable command without any pre-configured scope.","commands":{"allow":["is_minimizable"],"deny":[]}},"allow-is-minimized":{"identifier":"allow-is-minimized","description":"Enables the is_minimized command without any pre-configured scope.","commands":{"allow":["is_minimized"],"deny":[]}},"allow-is-resizable":{"identifier":"allow-is-resizable","description":"Enables the is_resizable command without any pre-configured scope.","commands":{"allow":["is_resizable"],"deny":[]}},"allow-is-visible":{"identifier":"allow-is-visible","description":"Enables the is_visible command without any pre-configured scope.","commands":{"allow":["is_visible"],"deny":[]}},"allow-maximize":{"identifier":"allow-maximize","description":"Enables the maximize command without any pre-configured scope.","commands":{"allow":["maximize"],"deny":[]}},"allow-minimize":{"identifier":"allow-minimize","description":"Enables the minimize command without any pre-configured scope.","commands":{"allow":["minimize"],"deny":[]}},"allow-monitor-from-point":{"identifier":"allow-monitor-from-point","description":"Enables the monitor_from_point command without any pre-configured scope.","commands":{"allow":["monitor_from_point"],"deny":[]}},"allow-outer-position":{"identifier":"allow-outer-position","description":"Enables the outer_position command without any pre-configured scope.","commands":{"allow":["outer_position"],"deny":[]}},"allow-outer-size":{"identifier":"allow-outer-size","description":"Enables the outer_size command without any pre-configured scope.","commands":{"allow":["outer_size"],"deny":[]}},"allow-primary-monitor":{"identifier":"allow-primary-monitor","description":"Enables the primary_monitor command without any pre-configured scope.","commands":{"allow":["primary_monitor"],"deny":[]}},"allow-request-user-attention":{"identifier":"allow-request-user-attention","description":"Enables the request_user_attention command without any pre-configured scope.","commands":{"allow":["request_user_attention"],"deny":[]}},"allow-scale-factor":{"identifier":"allow-scale-factor","description":"Enables the scale_factor command without any pre-configured scope.","commands":{"allow":["scale_factor"],"deny":[]}},"allow-scene-identifier":{"identifier":"allow-scene-identifier","description":"Enables the scene_identifier command without any pre-configured scope.","commands":{"allow":["scene_identifier"],"deny":[]}},"allow-set-always-on-bottom":{"identifier":"allow-set-always-on-bottom","description":"Enables the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":["set_always_on_bottom"],"deny":[]}},"allow-set-always-on-top":{"identifier":"allow-set-always-on-top","description":"Enables the set_always_on_top command without any pre-configured scope.","commands":{"allow":["set_always_on_top"],"deny":[]}},"allow-set-background-color":{"identifier":"allow-set-background-color","description":"Enables the set_background_color command without any pre-configured scope.","commands":{"allow":["set_background_color"],"deny":[]}},"allow-set-badge-count":{"identifier":"allow-set-badge-count","description":"Enables the set_badge_count command without any pre-configured scope.","commands":{"allow":["set_badge_count"],"deny":[]}},"allow-set-badge-label":{"identifier":"allow-set-badge-label","description":"Enables the set_badge_label command without any pre-configured scope.","commands":{"allow":["set_badge_label"],"deny":[]}},"allow-set-closable":{"identifier":"allow-set-closable","description":"Enables the set_closable command without any pre-configured scope.","commands":{"allow":["set_closable"],"deny":[]}},"allow-set-content-protected":{"identifier":"allow-set-content-protected","description":"Enables the set_content_protected command without any pre-configured scope.","commands":{"allow":["set_content_protected"],"deny":[]}},"allow-set-cursor-grab":{"identifier":"allow-set-cursor-grab","description":"Enables the set_cursor_grab command without any pre-configured scope.","commands":{"allow":["set_cursor_grab"],"deny":[]}},"allow-set-cursor-icon":{"identifier":"allow-set-cursor-icon","description":"Enables the set_cursor_icon command without any pre-configured scope.","commands":{"allow":["set_cursor_icon"],"deny":[]}},"allow-set-cursor-position":{"identifier":"allow-set-cursor-position","description":"Enables the set_cursor_position command without any pre-configured scope.","commands":{"allow":["set_cursor_position"],"deny":[]}},"allow-set-cursor-visible":{"identifier":"allow-set-cursor-visible","description":"Enables the set_cursor_visible command without any pre-configured scope.","commands":{"allow":["set_cursor_visible"],"deny":[]}},"allow-set-decorations":{"identifier":"allow-set-decorations","description":"Enables the set_decorations command without any pre-configured scope.","commands":{"allow":["set_decorations"],"deny":[]}},"allow-set-effects":{"identifier":"allow-set-effects","description":"Enables the set_effects command without any pre-configured scope.","commands":{"allow":["set_effects"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-focus":{"identifier":"allow-set-focus","description":"Enables the set_focus command without any pre-configured scope.","commands":{"allow":["set_focus"],"deny":[]}},"allow-set-focusable":{"identifier":"allow-set-focusable","description":"Enables the set_focusable command without any pre-configured scope.","commands":{"allow":["set_focusable"],"deny":[]}},"allow-set-fullscreen":{"identifier":"allow-set-fullscreen","description":"Enables the set_fullscreen command without any pre-configured scope.","commands":{"allow":["set_fullscreen"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-ignore-cursor-events":{"identifier":"allow-set-ignore-cursor-events","description":"Enables the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":["set_ignore_cursor_events"],"deny":[]}},"allow-set-max-size":{"identifier":"allow-set-max-size","description":"Enables the set_max_size command without any pre-configured scope.","commands":{"allow":["set_max_size"],"deny":[]}},"allow-set-maximizable":{"identifier":"allow-set-maximizable","description":"Enables the set_maximizable command without any pre-configured scope.","commands":{"allow":["set_maximizable"],"deny":[]}},"allow-set-min-size":{"identifier":"allow-set-min-size","description":"Enables the set_min_size command without any pre-configured scope.","commands":{"allow":["set_min_size"],"deny":[]}},"allow-set-minimizable":{"identifier":"allow-set-minimizable","description":"Enables the set_minimizable command without any pre-configured scope.","commands":{"allow":["set_minimizable"],"deny":[]}},"allow-set-overlay-icon":{"identifier":"allow-set-overlay-icon","description":"Enables the set_overlay_icon command without any pre-configured scope.","commands":{"allow":["set_overlay_icon"],"deny":[]}},"allow-set-position":{"identifier":"allow-set-position","description":"Enables the set_position command without any pre-configured scope.","commands":{"allow":["set_position"],"deny":[]}},"allow-set-progress-bar":{"identifier":"allow-set-progress-bar","description":"Enables the set_progress_bar command without any pre-configured scope.","commands":{"allow":["set_progress_bar"],"deny":[]}},"allow-set-resizable":{"identifier":"allow-set-resizable","description":"Enables the set_resizable command without any pre-configured scope.","commands":{"allow":["set_resizable"],"deny":[]}},"allow-set-shadow":{"identifier":"allow-set-shadow","description":"Enables the set_shadow command without any pre-configured scope.","commands":{"allow":["set_shadow"],"deny":[]}},"allow-set-simple-fullscreen":{"identifier":"allow-set-simple-fullscreen","description":"Enables the set_simple_fullscreen command without any pre-configured scope.","commands":{"allow":["set_simple_fullscreen"],"deny":[]}},"allow-set-size":{"identifier":"allow-set-size","description":"Enables the set_size command without any pre-configured scope.","commands":{"allow":["set_size"],"deny":[]}},"allow-set-size-constraints":{"identifier":"allow-set-size-constraints","description":"Enables the set_size_constraints command without any pre-configured scope.","commands":{"allow":["set_size_constraints"],"deny":[]}},"allow-set-skip-taskbar":{"identifier":"allow-set-skip-taskbar","description":"Enables the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":["set_skip_taskbar"],"deny":[]}},"allow-set-theme":{"identifier":"allow-set-theme","description":"Enables the set_theme command without any pre-configured scope.","commands":{"allow":["set_theme"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-title-bar-style":{"identifier":"allow-set-title-bar-style","description":"Enables the set_title_bar_style command without any pre-configured scope.","commands":{"allow":["set_title_bar_style"],"deny":[]}},"allow-set-visible-on-all-workspaces":{"identifier":"allow-set-visible-on-all-workspaces","description":"Enables the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":["set_visible_on_all_workspaces"],"deny":[]}},"allow-show":{"identifier":"allow-show","description":"Enables the show command without any pre-configured scope.","commands":{"allow":["show"],"deny":[]}},"allow-start-dragging":{"identifier":"allow-start-dragging","description":"Enables the start_dragging command without any pre-configured scope.","commands":{"allow":["start_dragging"],"deny":[]}},"allow-start-resize-dragging":{"identifier":"allow-start-resize-dragging","description":"Enables the start_resize_dragging command without any pre-configured scope.","commands":{"allow":["start_resize_dragging"],"deny":[]}},"allow-theme":{"identifier":"allow-theme","description":"Enables the theme command without any pre-configured scope.","commands":{"allow":["theme"],"deny":[]}},"allow-title":{"identifier":"allow-title","description":"Enables the title command without any pre-configured scope.","commands":{"allow":["title"],"deny":[]}},"allow-toggle-maximize":{"identifier":"allow-toggle-maximize","description":"Enables the toggle_maximize command without any pre-configured scope.","commands":{"allow":["toggle_maximize"],"deny":[]}},"allow-unmaximize":{"identifier":"allow-unmaximize","description":"Enables the unmaximize command without any pre-configured scope.","commands":{"allow":["unmaximize"],"deny":[]}},"allow-unminimize":{"identifier":"allow-unminimize","description":"Enables the unminimize command without any pre-configured scope.","commands":{"allow":["unminimize"],"deny":[]}},"deny-activity-name":{"identifier":"deny-activity-name","description":"Denies the activity_name command without any pre-configured scope.","commands":{"allow":[],"deny":["activity_name"]}},"deny-available-monitors":{"identifier":"deny-available-monitors","description":"Denies the available_monitors command without any pre-configured scope.","commands":{"allow":[],"deny":["available_monitors"]}},"deny-center":{"identifier":"deny-center","description":"Denies the center command without any pre-configured scope.","commands":{"allow":[],"deny":["center"]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}},"deny-create":{"identifier":"deny-create","description":"Denies the create command without any pre-configured scope.","commands":{"allow":[],"deny":["create"]}},"deny-current-monitor":{"identifier":"deny-current-monitor","description":"Denies the current_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["current_monitor"]}},"deny-cursor-position":{"identifier":"deny-cursor-position","description":"Denies the cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["cursor_position"]}},"deny-destroy":{"identifier":"deny-destroy","description":"Denies the destroy command without any pre-configured scope.","commands":{"allow":[],"deny":["destroy"]}},"deny-get-all-windows":{"identifier":"deny-get-all-windows","description":"Denies the get_all_windows command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_windows"]}},"deny-hide":{"identifier":"deny-hide","description":"Denies the hide command without any pre-configured scope.","commands":{"allow":[],"deny":["hide"]}},"deny-inner-position":{"identifier":"deny-inner-position","description":"Denies the inner_position command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_position"]}},"deny-inner-size":{"identifier":"deny-inner-size","description":"Denies the inner_size command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_size"]}},"deny-internal-toggle-maximize":{"identifier":"deny-internal-toggle-maximize","description":"Denies the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_maximize"]}},"deny-is-always-on-top":{"identifier":"deny-is-always-on-top","description":"Denies the is_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["is_always_on_top"]}},"deny-is-closable":{"identifier":"deny-is-closable","description":"Denies the is_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_closable"]}},"deny-is-decorated":{"identifier":"deny-is-decorated","description":"Denies the is_decorated command without any pre-configured scope.","commands":{"allow":[],"deny":["is_decorated"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-is-focused":{"identifier":"deny-is-focused","description":"Denies the is_focused command without any pre-configured scope.","commands":{"allow":[],"deny":["is_focused"]}},"deny-is-fullscreen":{"identifier":"deny-is-fullscreen","description":"Denies the is_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["is_fullscreen"]}},"deny-is-maximizable":{"identifier":"deny-is-maximizable","description":"Denies the is_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximizable"]}},"deny-is-maximized":{"identifier":"deny-is-maximized","description":"Denies the is_maximized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximized"]}},"deny-is-minimizable":{"identifier":"deny-is-minimizable","description":"Denies the is_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimizable"]}},"deny-is-minimized":{"identifier":"deny-is-minimized","description":"Denies the is_minimized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimized"]}},"deny-is-resizable":{"identifier":"deny-is-resizable","description":"Denies the is_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_resizable"]}},"deny-is-visible":{"identifier":"deny-is-visible","description":"Denies the is_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["is_visible"]}},"deny-maximize":{"identifier":"deny-maximize","description":"Denies the maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["maximize"]}},"deny-minimize":{"identifier":"deny-minimize","description":"Denies the minimize command without any pre-configured scope.","commands":{"allow":[],"deny":["minimize"]}},"deny-monitor-from-point":{"identifier":"deny-monitor-from-point","description":"Denies the monitor_from_point command without any pre-configured scope.","commands":{"allow":[],"deny":["monitor_from_point"]}},"deny-outer-position":{"identifier":"deny-outer-position","description":"Denies the outer_position command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_position"]}},"deny-outer-size":{"identifier":"deny-outer-size","description":"Denies the outer_size command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_size"]}},"deny-primary-monitor":{"identifier":"deny-primary-monitor","description":"Denies the primary_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["primary_monitor"]}},"deny-request-user-attention":{"identifier":"deny-request-user-attention","description":"Denies the request_user_attention command without any pre-configured scope.","commands":{"allow":[],"deny":["request_user_attention"]}},"deny-scale-factor":{"identifier":"deny-scale-factor","description":"Denies the scale_factor command without any pre-configured scope.","commands":{"allow":[],"deny":["scale_factor"]}},"deny-scene-identifier":{"identifier":"deny-scene-identifier","description":"Denies the scene_identifier command without any pre-configured scope.","commands":{"allow":[],"deny":["scene_identifier"]}},"deny-set-always-on-bottom":{"identifier":"deny-set-always-on-bottom","description":"Denies the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_bottom"]}},"deny-set-always-on-top":{"identifier":"deny-set-always-on-top","description":"Denies the set_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_top"]}},"deny-set-background-color":{"identifier":"deny-set-background-color","description":"Denies the set_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_background_color"]}},"deny-set-badge-count":{"identifier":"deny-set-badge-count","description":"Denies the set_badge_count command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_count"]}},"deny-set-badge-label":{"identifier":"deny-set-badge-label","description":"Denies the set_badge_label command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_label"]}},"deny-set-closable":{"identifier":"deny-set-closable","description":"Denies the set_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_closable"]}},"deny-set-content-protected":{"identifier":"deny-set-content-protected","description":"Denies the set_content_protected command without any pre-configured scope.","commands":{"allow":[],"deny":["set_content_protected"]}},"deny-set-cursor-grab":{"identifier":"deny-set-cursor-grab","description":"Denies the set_cursor_grab command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_grab"]}},"deny-set-cursor-icon":{"identifier":"deny-set-cursor-icon","description":"Denies the set_cursor_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_icon"]}},"deny-set-cursor-position":{"identifier":"deny-set-cursor-position","description":"Denies the set_cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_position"]}},"deny-set-cursor-visible":{"identifier":"deny-set-cursor-visible","description":"Denies the set_cursor_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_visible"]}},"deny-set-decorations":{"identifier":"deny-set-decorations","description":"Denies the set_decorations command without any pre-configured scope.","commands":{"allow":[],"deny":["set_decorations"]}},"deny-set-effects":{"identifier":"deny-set-effects","description":"Denies the set_effects command without any pre-configured scope.","commands":{"allow":[],"deny":["set_effects"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-focus":{"identifier":"deny-set-focus","description":"Denies the set_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_focus"]}},"deny-set-focusable":{"identifier":"deny-set-focusable","description":"Denies the set_focusable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_focusable"]}},"deny-set-fullscreen":{"identifier":"deny-set-fullscreen","description":"Denies the set_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["set_fullscreen"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-ignore-cursor-events":{"identifier":"deny-set-ignore-cursor-events","description":"Denies the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":[],"deny":["set_ignore_cursor_events"]}},"deny-set-max-size":{"identifier":"deny-set-max-size","description":"Denies the set_max_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_max_size"]}},"deny-set-maximizable":{"identifier":"deny-set-maximizable","description":"Denies the set_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_maximizable"]}},"deny-set-min-size":{"identifier":"deny-set-min-size","description":"Denies the set_min_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_min_size"]}},"deny-set-minimizable":{"identifier":"deny-set-minimizable","description":"Denies the set_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_minimizable"]}},"deny-set-overlay-icon":{"identifier":"deny-set-overlay-icon","description":"Denies the set_overlay_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_overlay_icon"]}},"deny-set-position":{"identifier":"deny-set-position","description":"Denies the set_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_position"]}},"deny-set-progress-bar":{"identifier":"deny-set-progress-bar","description":"Denies the set_progress_bar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_progress_bar"]}},"deny-set-resizable":{"identifier":"deny-set-resizable","description":"Denies the set_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_resizable"]}},"deny-set-shadow":{"identifier":"deny-set-shadow","description":"Denies the set_shadow command without any pre-configured scope.","commands":{"allow":[],"deny":["set_shadow"]}},"deny-set-simple-fullscreen":{"identifier":"deny-set-simple-fullscreen","description":"Denies the set_simple_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["set_simple_fullscreen"]}},"deny-set-size":{"identifier":"deny-set-size","description":"Denies the set_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size"]}},"deny-set-size-constraints":{"identifier":"deny-set-size-constraints","description":"Denies the set_size_constraints command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size_constraints"]}},"deny-set-skip-taskbar":{"identifier":"deny-set-skip-taskbar","description":"Denies the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_skip_taskbar"]}},"deny-set-theme":{"identifier":"deny-set-theme","description":"Denies the set_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_theme"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-title-bar-style":{"identifier":"deny-set-title-bar-style","description":"Denies the set_title_bar_style command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title_bar_style"]}},"deny-set-visible-on-all-workspaces":{"identifier":"deny-set-visible-on-all-workspaces","description":"Denies the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible_on_all_workspaces"]}},"deny-show":{"identifier":"deny-show","description":"Denies the show command without any pre-configured scope.","commands":{"allow":[],"deny":["show"]}},"deny-start-dragging":{"identifier":"deny-start-dragging","description":"Denies the start_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_dragging"]}},"deny-start-resize-dragging":{"identifier":"deny-start-resize-dragging","description":"Denies the start_resize_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_resize_dragging"]}},"deny-theme":{"identifier":"deny-theme","description":"Denies the theme command without any pre-configured scope.","commands":{"allow":[],"deny":["theme"]}},"deny-title":{"identifier":"deny-title","description":"Denies the title command without any pre-configured scope.","commands":{"allow":[],"deny":["title"]}},"deny-toggle-maximize":{"identifier":"deny-toggle-maximize","description":"Denies the toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["toggle_maximize"]}},"deny-unmaximize":{"identifier":"deny-unmaximize","description":"Denies the unmaximize command without any pre-configured scope.","commands":{"allow":[],"deny":["unmaximize"]}},"deny-unminimize":{"identifier":"deny-unminimize","description":"Denies the unminimize command without any pre-configured scope.","commands":{"allow":[],"deny":["unminimize"]}}},"permission_sets":{},"global_scope_schema":null},"dialog":{"default_permission":{"identifier":"default","description":"This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n","permissions":["allow-message","allow-save","allow-open"]},"permissions":{"allow-ask":{"identifier":"allow-ask","description":"Enables the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)","commands":{"allow":["message"],"deny":[]}},"allow-confirm":{"identifier":"allow-confirm","description":"Enables the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)","commands":{"allow":["message"],"deny":[]}},"allow-message":{"identifier":"allow-message","description":"Enables the message command without any pre-configured scope.","commands":{"allow":["message"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-save":{"identifier":"allow-save","description":"Enables the save command without any pre-configured scope.","commands":{"allow":["save"],"deny":[]}},"deny-ask":{"identifier":"deny-ask","description":"Denies the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)","commands":{"allow":[],"deny":["message"]}},"deny-confirm":{"identifier":"deny-confirm","description":"Denies the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)","commands":{"allow":[],"deny":["message"]}},"deny-message":{"identifier":"deny-message","description":"Denies the message command without any pre-configured scope.","commands":{"allow":[],"deny":["message"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-save":{"identifier":"deny-save","description":"Denies the save command without any pre-configured scope.","commands":{"allow":[],"deny":["save"]}}},"permission_sets":{},"global_scope_schema":null}}
\ No newline at end of file
diff --git a/apps/windows-client/src-tauri/gen/schemas/capabilities.json b/apps/windows-client/src-tauri/gen/schemas/capabilities.json
deleted file mode 100644
index 62e9233..0000000
--- a/apps/windows-client/src-tauri/gen/schemas/capabilities.json
+++ /dev/null
@@ -1 +0,0 @@
-{"default":{"identifier":"default","description":"Default capability for the main VPN Proxy Windows shell. Task 8 keeps helper/install launch explicit: no shell or sidecar permission is granted here until a packaged helper is declared.","local":true,"windows":["main"],"permissions":["core:default","dialog:allow-open"]}}
\ No newline at end of file
diff --git a/apps/windows-client/src-tauri/gen/schemas/desktop-schema.json b/apps/windows-client/src-tauri/gen/schemas/desktop-schema.json
deleted file mode 100644
index 24c9001..0000000
--- a/apps/windows-client/src-tauri/gen/schemas/desktop-schema.json
+++ /dev/null
@@ -1,2358 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-07/schema#",
- "title": "CapabilityFile",
- "description": "Capability formats accepted in a capability file.",
- "anyOf": [
- {
- "description": "A single capability.",
- "allOf": [
- {
- "$ref": "#/definitions/Capability"
- }
- ]
- },
- {
- "description": "A list of capabilities.",
- "type": "array",
- "items": {
- "$ref": "#/definitions/Capability"
- }
- },
- {
- "description": "A list of capabilities.",
- "type": "object",
- "required": [
- "capabilities"
- ],
- "properties": {
- "capabilities": {
- "description": "The list of capabilities.",
- "type": "array",
- "items": {
- "$ref": "#/definitions/Capability"
- }
- }
- }
- }
- ],
- "definitions": {
- "Capability": {
- "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows' and webviews' fine grained access to the Tauri core, application, or plugin commands. If a webview or its window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programmatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, ], \"platforms\": [\"macOS\",\"windows\"] } ```",
- "type": "object",
- "required": [
- "identifier",
- "permissions"
- ],
- "properties": {
- "identifier": {
- "description": "Identifier of the capability.\n\n## Example\n\n`main-user-files-write`",
- "type": "string"
- },
- "description": {
- "description": "Description of what the capability is intended to allow on associated windows.\n\nIt should contain a description of what the grouped permissions should allow.\n\n## Example\n\nThis capability allows the `main` window access to `filesystem` write related commands and `dialog` commands to enable programmatic access to files selected by the user.",
- "default": "",
- "type": "string"
- },
- "remote": {
- "description": "Configure remote URLs that can use the capability permissions.\n\nThis setting is optional and defaults to not being set, as our default use case is that the content is served from our local application.\n\n:::caution Make sure you understand the security implications of providing remote sources with local system access. :::\n\n## Example\n\n```json { \"urls\": [\"https://*.mydomain.dev\"] } ```",
- "anyOf": [
- {
- "$ref": "#/definitions/CapabilityRemote"
- },
- {
- "type": "null"
- }
- ]
- },
- "local": {
- "description": "Whether this capability is enabled for local app URLs or not. Defaults to `true`.",
- "default": true,
- "type": "boolean"
- },
- "windows": {
- "description": "List of windows that are affected by this capability. Can be a glob pattern.\n\nIf a window label matches any of the patterns in this list, the capability will be enabled on all the webviews of that window, regardless of the value of [`Self::webviews`].\n\nOn multiwebview windows, prefer specifying [`Self::webviews`] and omitting [`Self::windows`] for a fine grained access control.\n\n## Example\n\n`[\"main\"]`",
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "webviews": {
- "description": "List of webviews that are affected by this capability. Can be a glob pattern.\n\nThe capability will be enabled on all the webviews whose label matches any of the patterns in this list, regardless of whether the webview's window label matches a pattern in [`Self::windows`].\n\n## Example\n\n`[\"sub-webview-one\", \"sub-webview-two\"]`",
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "permissions": {
- "description": "List of permissions attached to this capability.\n\nMust include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`. For commands directly implemented in the application itself only `${permission-name}` is required.\n\n## Example\n\n```json [ \"core:default\", \"shell:allow-open\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] } ] ```",
- "type": "array",
- "items": {
- "$ref": "#/definitions/PermissionEntry"
- },
- "uniqueItems": true
- },
- "platforms": {
- "description": "Limit which target platforms this capability applies to.\n\nBy default all platforms are targeted.\n\n## Example\n\n`[\"macOS\",\"windows\"]`",
- "type": [
- "array",
- "null"
- ],
- "items": {
- "$ref": "#/definitions/Target"
- }
- }
- }
- },
- "CapabilityRemote": {
- "description": "Configuration for remote URLs that are associated with the capability.",
- "type": "object",
- "required": [
- "urls"
- ],
- "properties": {
- "urls": {
- "description": "Remote domains this capability refers to using the [URLPattern standard](https://urlpattern.spec.whatwg.org/).\n\n## Examples\n\n- \"https://*.mydomain.dev\": allows subdomains of mydomain.dev - \"https://mydomain.dev/api/*\": allows any subpath of mydomain.dev/api",
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- }
- },
- "PermissionEntry": {
- "description": "An entry for a permission value in a [`Capability`] can be either a raw permission [`Identifier`] or an object that references a permission and extends its scope.",
- "anyOf": [
- {
- "description": "Reference a permission or permission set by identifier.",
- "allOf": [
- {
- "$ref": "#/definitions/Identifier"
- }
- ]
- },
- {
- "description": "Reference a permission or permission set by identifier and extends its scope.",
- "type": "object",
- "allOf": [
- {
- "properties": {
- "identifier": {
- "description": "Identifier of the permission or permission set.",
- "allOf": [
- {
- "$ref": "#/definitions/Identifier"
- }
- ]
- },
- "allow": {
- "description": "Data that defines what is allowed by the scope.",
- "type": [
- "array",
- "null"
- ],
- "items": {
- "$ref": "#/definitions/Value"
- }
- },
- "deny": {
- "description": "Data that defines what is denied by the scope. This should be prioritized by validation logic.",
- "type": [
- "array",
- "null"
- ],
- "items": {
- "$ref": "#/definitions/Value"
- }
- }
- }
- }
- ],
- "required": [
- "identifier"
- ]
- }
- ]
- },
- "Identifier": {
- "description": "Permission identifier",
- "oneOf": [
- {
- "description": "Default core plugins set.\n#### This default permission set includes:\n\n- `core:path:default`\n- `core:event:default`\n- `core:window:default`\n- `core:webview:default`\n- `core:app:default`\n- `core:image:default`\n- `core:resources:default`\n- `core:menu:default`\n- `core:tray:default`",
- "type": "string",
- "const": "core:default",
- "markdownDescription": "Default core plugins set.\n#### This default permission set includes:\n\n- `core:path:default`\n- `core:event:default`\n- `core:window:default`\n- `core:webview:default`\n- `core:app:default`\n- `core:image:default`\n- `core:resources:default`\n- `core:menu:default`\n- `core:tray:default`"
- },
- {
- "description": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-version`\n- `allow-name`\n- `allow-tauri-version`\n- `allow-identifier`\n- `allow-bundle-type`\n- `allow-register-listener`\n- `allow-remove-listener`\n- `allow-supports-multiple-windows`",
- "type": "string",
- "const": "core:app:default",
- "markdownDescription": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-version`\n- `allow-name`\n- `allow-tauri-version`\n- `allow-identifier`\n- `allow-bundle-type`\n- `allow-register-listener`\n- `allow-remove-listener`\n- `allow-supports-multiple-windows`"
- },
- {
- "description": "Enables the app_hide command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-app-hide",
- "markdownDescription": "Enables the app_hide command without any pre-configured scope."
- },
- {
- "description": "Enables the app_show command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-app-show",
- "markdownDescription": "Enables the app_show command without any pre-configured scope."
- },
- {
- "description": "Enables the bundle_type command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-bundle-type",
- "markdownDescription": "Enables the bundle_type command without any pre-configured scope."
- },
- {
- "description": "Enables the default_window_icon command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-default-window-icon",
- "markdownDescription": "Enables the default_window_icon command without any pre-configured scope."
- },
- {
- "description": "Enables the fetch_data_store_identifiers command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-fetch-data-store-identifiers",
- "markdownDescription": "Enables the fetch_data_store_identifiers command without any pre-configured scope."
- },
- {
- "description": "Enables the identifier command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-identifier",
- "markdownDescription": "Enables the identifier command without any pre-configured scope."
- },
- {
- "description": "Enables the name command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-name",
- "markdownDescription": "Enables the name command without any pre-configured scope."
- },
- {
- "description": "Enables the register_listener command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-register-listener",
- "markdownDescription": "Enables the register_listener command without any pre-configured scope."
- },
- {
- "description": "Enables the remove_data_store command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-remove-data-store",
- "markdownDescription": "Enables the remove_data_store command without any pre-configured scope."
- },
- {
- "description": "Enables the remove_listener command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-remove-listener",
- "markdownDescription": "Enables the remove_listener command without any pre-configured scope."
- },
- {
- "description": "Enables the set_app_theme command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-set-app-theme",
- "markdownDescription": "Enables the set_app_theme command without any pre-configured scope."
- },
- {
- "description": "Enables the set_dock_visibility command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-set-dock-visibility",
- "markdownDescription": "Enables the set_dock_visibility command without any pre-configured scope."
- },
- {
- "description": "Enables the supports_multiple_windows command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-supports-multiple-windows",
- "markdownDescription": "Enables the supports_multiple_windows command without any pre-configured scope."
- },
- {
- "description": "Enables the tauri_version command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-tauri-version",
- "markdownDescription": "Enables the tauri_version command without any pre-configured scope."
- },
- {
- "description": "Enables the version command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-version",
- "markdownDescription": "Enables the version command without any pre-configured scope."
- },
- {
- "description": "Denies the app_hide command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-app-hide",
- "markdownDescription": "Denies the app_hide command without any pre-configured scope."
- },
- {
- "description": "Denies the app_show command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-app-show",
- "markdownDescription": "Denies the app_show command without any pre-configured scope."
- },
- {
- "description": "Denies the bundle_type command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-bundle-type",
- "markdownDescription": "Denies the bundle_type command without any pre-configured scope."
- },
- {
- "description": "Denies the default_window_icon command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-default-window-icon",
- "markdownDescription": "Denies the default_window_icon command without any pre-configured scope."
- },
- {
- "description": "Denies the fetch_data_store_identifiers command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-fetch-data-store-identifiers",
- "markdownDescription": "Denies the fetch_data_store_identifiers command without any pre-configured scope."
- },
- {
- "description": "Denies the identifier command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-identifier",
- "markdownDescription": "Denies the identifier command without any pre-configured scope."
- },
- {
- "description": "Denies the name command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-name",
- "markdownDescription": "Denies the name command without any pre-configured scope."
- },
- {
- "description": "Denies the register_listener command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-register-listener",
- "markdownDescription": "Denies the register_listener command without any pre-configured scope."
- },
- {
- "description": "Denies the remove_data_store command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-remove-data-store",
- "markdownDescription": "Denies the remove_data_store command without any pre-configured scope."
- },
- {
- "description": "Denies the remove_listener command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-remove-listener",
- "markdownDescription": "Denies the remove_listener command without any pre-configured scope."
- },
- {
- "description": "Denies the set_app_theme command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-set-app-theme",
- "markdownDescription": "Denies the set_app_theme command without any pre-configured scope."
- },
- {
- "description": "Denies the set_dock_visibility command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-set-dock-visibility",
- "markdownDescription": "Denies the set_dock_visibility command without any pre-configured scope."
- },
- {
- "description": "Denies the supports_multiple_windows command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-supports-multiple-windows",
- "markdownDescription": "Denies the supports_multiple_windows command without any pre-configured scope."
- },
- {
- "description": "Denies the tauri_version command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-tauri-version",
- "markdownDescription": "Denies the tauri_version command without any pre-configured scope."
- },
- {
- "description": "Denies the version command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-version",
- "markdownDescription": "Denies the version command without any pre-configured scope."
- },
- {
- "description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-listen`\n- `allow-unlisten`\n- `allow-emit`\n- `allow-emit-to`",
- "type": "string",
- "const": "core:event:default",
- "markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-listen`\n- `allow-unlisten`\n- `allow-emit`\n- `allow-emit-to`"
- },
- {
- "description": "Enables the emit command without any pre-configured scope.",
- "type": "string",
- "const": "core:event:allow-emit",
- "markdownDescription": "Enables the emit command without any pre-configured scope."
- },
- {
- "description": "Enables the emit_to command without any pre-configured scope.",
- "type": "string",
- "const": "core:event:allow-emit-to",
- "markdownDescription": "Enables the emit_to command without any pre-configured scope."
- },
- {
- "description": "Enables the listen command without any pre-configured scope.",
- "type": "string",
- "const": "core:event:allow-listen",
- "markdownDescription": "Enables the listen command without any pre-configured scope."
- },
- {
- "description": "Enables the unlisten command without any pre-configured scope.",
- "type": "string",
- "const": "core:event:allow-unlisten",
- "markdownDescription": "Enables the unlisten command without any pre-configured scope."
- },
- {
- "description": "Denies the emit command without any pre-configured scope.",
- "type": "string",
- "const": "core:event:deny-emit",
- "markdownDescription": "Denies the emit command without any pre-configured scope."
- },
- {
- "description": "Denies the emit_to command without any pre-configured scope.",
- "type": "string",
- "const": "core:event:deny-emit-to",
- "markdownDescription": "Denies the emit_to command without any pre-configured scope."
- },
- {
- "description": "Denies the listen command without any pre-configured scope.",
- "type": "string",
- "const": "core:event:deny-listen",
- "markdownDescription": "Denies the listen command without any pre-configured scope."
- },
- {
- "description": "Denies the unlisten command without any pre-configured scope.",
- "type": "string",
- "const": "core:event:deny-unlisten",
- "markdownDescription": "Denies the unlisten command without any pre-configured scope."
- },
- {
- "description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-from-bytes`\n- `allow-from-path`\n- `allow-rgba`\n- `allow-size`",
- "type": "string",
- "const": "core:image:default",
- "markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-from-bytes`\n- `allow-from-path`\n- `allow-rgba`\n- `allow-size`"
- },
- {
- "description": "Enables the from_bytes command without any pre-configured scope.",
- "type": "string",
- "const": "core:image:allow-from-bytes",
- "markdownDescription": "Enables the from_bytes command without any pre-configured scope."
- },
- {
- "description": "Enables the from_path command without any pre-configured scope.",
- "type": "string",
- "const": "core:image:allow-from-path",
- "markdownDescription": "Enables the from_path command without any pre-configured scope."
- },
- {
- "description": "Enables the new command without any pre-configured scope.",
- "type": "string",
- "const": "core:image:allow-new",
- "markdownDescription": "Enables the new command without any pre-configured scope."
- },
- {
- "description": "Enables the rgba command without any pre-configured scope.",
- "type": "string",
- "const": "core:image:allow-rgba",
- "markdownDescription": "Enables the rgba command without any pre-configured scope."
- },
- {
- "description": "Enables the size command without any pre-configured scope.",
- "type": "string",
- "const": "core:image:allow-size",
- "markdownDescription": "Enables the size command without any pre-configured scope."
- },
- {
- "description": "Denies the from_bytes command without any pre-configured scope.",
- "type": "string",
- "const": "core:image:deny-from-bytes",
- "markdownDescription": "Denies the from_bytes command without any pre-configured scope."
- },
- {
- "description": "Denies the from_path command without any pre-configured scope.",
- "type": "string",
- "const": "core:image:deny-from-path",
- "markdownDescription": "Denies the from_path command without any pre-configured scope."
- },
- {
- "description": "Denies the new command without any pre-configured scope.",
- "type": "string",
- "const": "core:image:deny-new",
- "markdownDescription": "Denies the new command without any pre-configured scope."
- },
- {
- "description": "Denies the rgba command without any pre-configured scope.",
- "type": "string",
- "const": "core:image:deny-rgba",
- "markdownDescription": "Denies the rgba command without any pre-configured scope."
- },
- {
- "description": "Denies the size command without any pre-configured scope.",
- "type": "string",
- "const": "core:image:deny-size",
- "markdownDescription": "Denies the size command without any pre-configured scope."
- },
- {
- "description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-append`\n- `allow-prepend`\n- `allow-insert`\n- `allow-remove`\n- `allow-remove-at`\n- `allow-items`\n- `allow-get`\n- `allow-popup`\n- `allow-create-default`\n- `allow-set-as-app-menu`\n- `allow-set-as-window-menu`\n- `allow-text`\n- `allow-set-text`\n- `allow-is-enabled`\n- `allow-set-enabled`\n- `allow-set-accelerator`\n- `allow-set-as-windows-menu-for-nsapp`\n- `allow-set-as-help-menu-for-nsapp`\n- `allow-is-checked`\n- `allow-set-checked`\n- `allow-set-icon`",
- "type": "string",
- "const": "core:menu:default",
- "markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-append`\n- `allow-prepend`\n- `allow-insert`\n- `allow-remove`\n- `allow-remove-at`\n- `allow-items`\n- `allow-get`\n- `allow-popup`\n- `allow-create-default`\n- `allow-set-as-app-menu`\n- `allow-set-as-window-menu`\n- `allow-text`\n- `allow-set-text`\n- `allow-is-enabled`\n- `allow-set-enabled`\n- `allow-set-accelerator`\n- `allow-set-as-windows-menu-for-nsapp`\n- `allow-set-as-help-menu-for-nsapp`\n- `allow-is-checked`\n- `allow-set-checked`\n- `allow-set-icon`"
- },
- {
- "description": "Enables the append command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-append",
- "markdownDescription": "Enables the append command without any pre-configured scope."
- },
- {
- "description": "Enables the create_default command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-create-default",
- "markdownDescription": "Enables the create_default command without any pre-configured scope."
- },
- {
- "description": "Enables the get command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-get",
- "markdownDescription": "Enables the get command without any pre-configured scope."
- },
- {
- "description": "Enables the insert command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-insert",
- "markdownDescription": "Enables the insert command without any pre-configured scope."
- },
- {
- "description": "Enables the is_checked command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-is-checked",
- "markdownDescription": "Enables the is_checked command without any pre-configured scope."
- },
- {
- "description": "Enables the is_enabled command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-is-enabled",
- "markdownDescription": "Enables the is_enabled command without any pre-configured scope."
- },
- {
- "description": "Enables the items command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-items",
- "markdownDescription": "Enables the items command without any pre-configured scope."
- },
- {
- "description": "Enables the new command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-new",
- "markdownDescription": "Enables the new command without any pre-configured scope."
- },
- {
- "description": "Enables the popup command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-popup",
- "markdownDescription": "Enables the popup command without any pre-configured scope."
- },
- {
- "description": "Enables the prepend command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-prepend",
- "markdownDescription": "Enables the prepend command without any pre-configured scope."
- },
- {
- "description": "Enables the remove command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-remove",
- "markdownDescription": "Enables the remove command without any pre-configured scope."
- },
- {
- "description": "Enables the remove_at command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-remove-at",
- "markdownDescription": "Enables the remove_at command without any pre-configured scope."
- },
- {
- "description": "Enables the set_accelerator command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-set-accelerator",
- "markdownDescription": "Enables the set_accelerator command without any pre-configured scope."
- },
- {
- "description": "Enables the set_as_app_menu command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-set-as-app-menu",
- "markdownDescription": "Enables the set_as_app_menu command without any pre-configured scope."
- },
- {
- "description": "Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-set-as-help-menu-for-nsapp",
- "markdownDescription": "Enables the set_as_help_menu_for_nsapp command without any pre-configured scope."
- },
- {
- "description": "Enables the set_as_window_menu command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-set-as-window-menu",
- "markdownDescription": "Enables the set_as_window_menu command without any pre-configured scope."
- },
- {
- "description": "Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-set-as-windows-menu-for-nsapp",
- "markdownDescription": "Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope."
- },
- {
- "description": "Enables the set_checked command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-set-checked",
- "markdownDescription": "Enables the set_checked command without any pre-configured scope."
- },
- {
- "description": "Enables the set_enabled command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-set-enabled",
- "markdownDescription": "Enables the set_enabled command without any pre-configured scope."
- },
- {
- "description": "Enables the set_icon command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-set-icon",
- "markdownDescription": "Enables the set_icon command without any pre-configured scope."
- },
- {
- "description": "Enables the set_text command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-set-text",
- "markdownDescription": "Enables the set_text command without any pre-configured scope."
- },
- {
- "description": "Enables the text command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-text",
- "markdownDescription": "Enables the text command without any pre-configured scope."
- },
- {
- "description": "Denies the append command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-append",
- "markdownDescription": "Denies the append command without any pre-configured scope."
- },
- {
- "description": "Denies the create_default command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-create-default",
- "markdownDescription": "Denies the create_default command without any pre-configured scope."
- },
- {
- "description": "Denies the get command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-get",
- "markdownDescription": "Denies the get command without any pre-configured scope."
- },
- {
- "description": "Denies the insert command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-insert",
- "markdownDescription": "Denies the insert command without any pre-configured scope."
- },
- {
- "description": "Denies the is_checked command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-is-checked",
- "markdownDescription": "Denies the is_checked command without any pre-configured scope."
- },
- {
- "description": "Denies the is_enabled command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-is-enabled",
- "markdownDescription": "Denies the is_enabled command without any pre-configured scope."
- },
- {
- "description": "Denies the items command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-items",
- "markdownDescription": "Denies the items command without any pre-configured scope."
- },
- {
- "description": "Denies the new command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-new",
- "markdownDescription": "Denies the new command without any pre-configured scope."
- },
- {
- "description": "Denies the popup command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-popup",
- "markdownDescription": "Denies the popup command without any pre-configured scope."
- },
- {
- "description": "Denies the prepend command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-prepend",
- "markdownDescription": "Denies the prepend command without any pre-configured scope."
- },
- {
- "description": "Denies the remove command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-remove",
- "markdownDescription": "Denies the remove command without any pre-configured scope."
- },
- {
- "description": "Denies the remove_at command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-remove-at",
- "markdownDescription": "Denies the remove_at command without any pre-configured scope."
- },
- {
- "description": "Denies the set_accelerator command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-set-accelerator",
- "markdownDescription": "Denies the set_accelerator command without any pre-configured scope."
- },
- {
- "description": "Denies the set_as_app_menu command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-set-as-app-menu",
- "markdownDescription": "Denies the set_as_app_menu command without any pre-configured scope."
- },
- {
- "description": "Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-set-as-help-menu-for-nsapp",
- "markdownDescription": "Denies the set_as_help_menu_for_nsapp command without any pre-configured scope."
- },
- {
- "description": "Denies the set_as_window_menu command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-set-as-window-menu",
- "markdownDescription": "Denies the set_as_window_menu command without any pre-configured scope."
- },
- {
- "description": "Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-set-as-windows-menu-for-nsapp",
- "markdownDescription": "Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope."
- },
- {
- "description": "Denies the set_checked command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-set-checked",
- "markdownDescription": "Denies the set_checked command without any pre-configured scope."
- },
- {
- "description": "Denies the set_enabled command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-set-enabled",
- "markdownDescription": "Denies the set_enabled command without any pre-configured scope."
- },
- {
- "description": "Denies the set_icon command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-set-icon",
- "markdownDescription": "Denies the set_icon command without any pre-configured scope."
- },
- {
- "description": "Denies the set_text command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-set-text",
- "markdownDescription": "Denies the set_text command without any pre-configured scope."
- },
- {
- "description": "Denies the text command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-text",
- "markdownDescription": "Denies the text command without any pre-configured scope."
- },
- {
- "description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-resolve-directory`\n- `allow-resolve`\n- `allow-normalize`\n- `allow-join`\n- `allow-dirname`\n- `allow-extname`\n- `allow-basename`\n- `allow-is-absolute`",
- "type": "string",
- "const": "core:path:default",
- "markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-resolve-directory`\n- `allow-resolve`\n- `allow-normalize`\n- `allow-join`\n- `allow-dirname`\n- `allow-extname`\n- `allow-basename`\n- `allow-is-absolute`"
- },
- {
- "description": "Enables the basename command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:allow-basename",
- "markdownDescription": "Enables the basename command without any pre-configured scope."
- },
- {
- "description": "Enables the dirname command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:allow-dirname",
- "markdownDescription": "Enables the dirname command without any pre-configured scope."
- },
- {
- "description": "Enables the extname command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:allow-extname",
- "markdownDescription": "Enables the extname command without any pre-configured scope."
- },
- {
- "description": "Enables the is_absolute command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:allow-is-absolute",
- "markdownDescription": "Enables the is_absolute command without any pre-configured scope."
- },
- {
- "description": "Enables the join command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:allow-join",
- "markdownDescription": "Enables the join command without any pre-configured scope."
- },
- {
- "description": "Enables the normalize command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:allow-normalize",
- "markdownDescription": "Enables the normalize command without any pre-configured scope."
- },
- {
- "description": "Enables the resolve command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:allow-resolve",
- "markdownDescription": "Enables the resolve command without any pre-configured scope."
- },
- {
- "description": "Enables the resolve_directory command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:allow-resolve-directory",
- "markdownDescription": "Enables the resolve_directory command without any pre-configured scope."
- },
- {
- "description": "Denies the basename command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:deny-basename",
- "markdownDescription": "Denies the basename command without any pre-configured scope."
- },
- {
- "description": "Denies the dirname command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:deny-dirname",
- "markdownDescription": "Denies the dirname command without any pre-configured scope."
- },
- {
- "description": "Denies the extname command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:deny-extname",
- "markdownDescription": "Denies the extname command without any pre-configured scope."
- },
- {
- "description": "Denies the is_absolute command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:deny-is-absolute",
- "markdownDescription": "Denies the is_absolute command without any pre-configured scope."
- },
- {
- "description": "Denies the join command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:deny-join",
- "markdownDescription": "Denies the join command without any pre-configured scope."
- },
- {
- "description": "Denies the normalize command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:deny-normalize",
- "markdownDescription": "Denies the normalize command without any pre-configured scope."
- },
- {
- "description": "Denies the resolve command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:deny-resolve",
- "markdownDescription": "Denies the resolve command without any pre-configured scope."
- },
- {
- "description": "Denies the resolve_directory command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:deny-resolve-directory",
- "markdownDescription": "Denies the resolve_directory command without any pre-configured scope."
- },
- {
- "description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-close`",
- "type": "string",
- "const": "core:resources:default",
- "markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-close`"
- },
- {
- "description": "Enables the close command without any pre-configured scope.",
- "type": "string",
- "const": "core:resources:allow-close",
- "markdownDescription": "Enables the close command without any pre-configured scope."
- },
- {
- "description": "Denies the close command without any pre-configured scope.",
- "type": "string",
- "const": "core:resources:deny-close",
- "markdownDescription": "Denies the close command without any pre-configured scope."
- },
- {
- "description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-get-by-id`\n- `allow-remove-by-id`\n- `allow-set-icon`\n- `allow-set-menu`\n- `allow-set-tooltip`\n- `allow-set-title`\n- `allow-set-visible`\n- `allow-set-temp-dir-path`\n- `allow-set-icon-as-template`\n- `allow-set-icon-with-as-template`\n- `allow-set-show-menu-on-left-click`",
- "type": "string",
- "const": "core:tray:default",
- "markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-get-by-id`\n- `allow-remove-by-id`\n- `allow-set-icon`\n- `allow-set-menu`\n- `allow-set-tooltip`\n- `allow-set-title`\n- `allow-set-visible`\n- `allow-set-temp-dir-path`\n- `allow-set-icon-as-template`\n- `allow-set-icon-with-as-template`\n- `allow-set-show-menu-on-left-click`"
- },
- {
- "description": "Enables the get_by_id command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:allow-get-by-id",
- "markdownDescription": "Enables the get_by_id command without any pre-configured scope."
- },
- {
- "description": "Enables the new command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:allow-new",
- "markdownDescription": "Enables the new command without any pre-configured scope."
- },
- {
- "description": "Enables the remove_by_id command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:allow-remove-by-id",
- "markdownDescription": "Enables the remove_by_id command without any pre-configured scope."
- },
- {
- "description": "Enables the set_icon command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:allow-set-icon",
- "markdownDescription": "Enables the set_icon command without any pre-configured scope."
- },
- {
- "description": "Enables the set_icon_as_template command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:allow-set-icon-as-template",
- "markdownDescription": "Enables the set_icon_as_template command without any pre-configured scope."
- },
- {
- "description": "Enables the set_icon_with_as_template command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:allow-set-icon-with-as-template",
- "markdownDescription": "Enables the set_icon_with_as_template command without any pre-configured scope."
- },
- {
- "description": "Enables the set_menu command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:allow-set-menu",
- "markdownDescription": "Enables the set_menu command without any pre-configured scope."
- },
- {
- "description": "Enables the set_show_menu_on_left_click command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:allow-set-show-menu-on-left-click",
- "markdownDescription": "Enables the set_show_menu_on_left_click command without any pre-configured scope."
- },
- {
- "description": "Enables the set_temp_dir_path command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:allow-set-temp-dir-path",
- "markdownDescription": "Enables the set_temp_dir_path command without any pre-configured scope."
- },
- {
- "description": "Enables the set_title command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:allow-set-title",
- "markdownDescription": "Enables the set_title command without any pre-configured scope."
- },
- {
- "description": "Enables the set_tooltip command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:allow-set-tooltip",
- "markdownDescription": "Enables the set_tooltip command without any pre-configured scope."
- },
- {
- "description": "Enables the set_visible command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:allow-set-visible",
- "markdownDescription": "Enables the set_visible command without any pre-configured scope."
- },
- {
- "description": "Denies the get_by_id command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:deny-get-by-id",
- "markdownDescription": "Denies the get_by_id command without any pre-configured scope."
- },
- {
- "description": "Denies the new command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:deny-new",
- "markdownDescription": "Denies the new command without any pre-configured scope."
- },
- {
- "description": "Denies the remove_by_id command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:deny-remove-by-id",
- "markdownDescription": "Denies the remove_by_id command without any pre-configured scope."
- },
- {
- "description": "Denies the set_icon command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:deny-set-icon",
- "markdownDescription": "Denies the set_icon command without any pre-configured scope."
- },
- {
- "description": "Denies the set_icon_as_template command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:deny-set-icon-as-template",
- "markdownDescription": "Denies the set_icon_as_template command without any pre-configured scope."
- },
- {
- "description": "Denies the set_icon_with_as_template command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:deny-set-icon-with-as-template",
- "markdownDescription": "Denies the set_icon_with_as_template command without any pre-configured scope."
- },
- {
- "description": "Denies the set_menu command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:deny-set-menu",
- "markdownDescription": "Denies the set_menu command without any pre-configured scope."
- },
- {
- "description": "Denies the set_show_menu_on_left_click command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:deny-set-show-menu-on-left-click",
- "markdownDescription": "Denies the set_show_menu_on_left_click command without any pre-configured scope."
- },
- {
- "description": "Denies the set_temp_dir_path command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:deny-set-temp-dir-path",
- "markdownDescription": "Denies the set_temp_dir_path command without any pre-configured scope."
- },
- {
- "description": "Denies the set_title command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:deny-set-title",
- "markdownDescription": "Denies the set_title command without any pre-configured scope."
- },
- {
- "description": "Denies the set_tooltip command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:deny-set-tooltip",
- "markdownDescription": "Denies the set_tooltip command without any pre-configured scope."
- },
- {
- "description": "Denies the set_visible command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:deny-set-visible",
- "markdownDescription": "Denies the set_visible command without any pre-configured scope."
- },
- {
- "description": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-get-all-webviews`\n- `allow-webview-position`\n- `allow-webview-size`\n- `allow-internal-toggle-devtools`",
- "type": "string",
- "const": "core:webview:default",
- "markdownDescription": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-get-all-webviews`\n- `allow-webview-position`\n- `allow-webview-size`\n- `allow-internal-toggle-devtools`"
- },
- {
- "description": "Enables the clear_all_browsing_data command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-clear-all-browsing-data",
- "markdownDescription": "Enables the clear_all_browsing_data command without any pre-configured scope."
- },
- {
- "description": "Enables the create_webview command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-create-webview",
- "markdownDescription": "Enables the create_webview command without any pre-configured scope."
- },
- {
- "description": "Enables the create_webview_window command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-create-webview-window",
- "markdownDescription": "Enables the create_webview_window command without any pre-configured scope."
- },
- {
- "description": "Enables the get_all_webviews command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-get-all-webviews",
- "markdownDescription": "Enables the get_all_webviews command without any pre-configured scope."
- },
- {
- "description": "Enables the internal_toggle_devtools command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-internal-toggle-devtools",
- "markdownDescription": "Enables the internal_toggle_devtools command without any pre-configured scope."
- },
- {
- "description": "Enables the print command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-print",
- "markdownDescription": "Enables the print command without any pre-configured scope."
- },
- {
- "description": "Enables the reparent command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-reparent",
- "markdownDescription": "Enables the reparent command without any pre-configured scope."
- },
- {
- "description": "Enables the set_webview_auto_resize command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-set-webview-auto-resize",
- "markdownDescription": "Enables the set_webview_auto_resize command without any pre-configured scope."
- },
- {
- "description": "Enables the set_webview_background_color command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-set-webview-background-color",
- "markdownDescription": "Enables the set_webview_background_color command without any pre-configured scope."
- },
- {
- "description": "Enables the set_webview_focus command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-set-webview-focus",
- "markdownDescription": "Enables the set_webview_focus command without any pre-configured scope."
- },
- {
- "description": "Enables the set_webview_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-set-webview-position",
- "markdownDescription": "Enables the set_webview_position command without any pre-configured scope."
- },
- {
- "description": "Enables the set_webview_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-set-webview-size",
- "markdownDescription": "Enables the set_webview_size command without any pre-configured scope."
- },
- {
- "description": "Enables the set_webview_zoom command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-set-webview-zoom",
- "markdownDescription": "Enables the set_webview_zoom command without any pre-configured scope."
- },
- {
- "description": "Enables the webview_close command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-webview-close",
- "markdownDescription": "Enables the webview_close command without any pre-configured scope."
- },
- {
- "description": "Enables the webview_hide command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-webview-hide",
- "markdownDescription": "Enables the webview_hide command without any pre-configured scope."
- },
- {
- "description": "Enables the webview_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-webview-position",
- "markdownDescription": "Enables the webview_position command without any pre-configured scope."
- },
- {
- "description": "Enables the webview_show command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-webview-show",
- "markdownDescription": "Enables the webview_show command without any pre-configured scope."
- },
- {
- "description": "Enables the webview_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-webview-size",
- "markdownDescription": "Enables the webview_size command without any pre-configured scope."
- },
- {
- "description": "Denies the clear_all_browsing_data command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-clear-all-browsing-data",
- "markdownDescription": "Denies the clear_all_browsing_data command without any pre-configured scope."
- },
- {
- "description": "Denies the create_webview command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-create-webview",
- "markdownDescription": "Denies the create_webview command without any pre-configured scope."
- },
- {
- "description": "Denies the create_webview_window command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-create-webview-window",
- "markdownDescription": "Denies the create_webview_window command without any pre-configured scope."
- },
- {
- "description": "Denies the get_all_webviews command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-get-all-webviews",
- "markdownDescription": "Denies the get_all_webviews command without any pre-configured scope."
- },
- {
- "description": "Denies the internal_toggle_devtools command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-internal-toggle-devtools",
- "markdownDescription": "Denies the internal_toggle_devtools command without any pre-configured scope."
- },
- {
- "description": "Denies the print command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-print",
- "markdownDescription": "Denies the print command without any pre-configured scope."
- },
- {
- "description": "Denies the reparent command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-reparent",
- "markdownDescription": "Denies the reparent command without any pre-configured scope."
- },
- {
- "description": "Denies the set_webview_auto_resize command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-set-webview-auto-resize",
- "markdownDescription": "Denies the set_webview_auto_resize command without any pre-configured scope."
- },
- {
- "description": "Denies the set_webview_background_color command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-set-webview-background-color",
- "markdownDescription": "Denies the set_webview_background_color command without any pre-configured scope."
- },
- {
- "description": "Denies the set_webview_focus command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-set-webview-focus",
- "markdownDescription": "Denies the set_webview_focus command without any pre-configured scope."
- },
- {
- "description": "Denies the set_webview_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-set-webview-position",
- "markdownDescription": "Denies the set_webview_position command without any pre-configured scope."
- },
- {
- "description": "Denies the set_webview_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-set-webview-size",
- "markdownDescription": "Denies the set_webview_size command without any pre-configured scope."
- },
- {
- "description": "Denies the set_webview_zoom command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-set-webview-zoom",
- "markdownDescription": "Denies the set_webview_zoom command without any pre-configured scope."
- },
- {
- "description": "Denies the webview_close command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-webview-close",
- "markdownDescription": "Denies the webview_close command without any pre-configured scope."
- },
- {
- "description": "Denies the webview_hide command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-webview-hide",
- "markdownDescription": "Denies the webview_hide command without any pre-configured scope."
- },
- {
- "description": "Denies the webview_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-webview-position",
- "markdownDescription": "Denies the webview_position command without any pre-configured scope."
- },
- {
- "description": "Denies the webview_show command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-webview-show",
- "markdownDescription": "Denies the webview_show command without any pre-configured scope."
- },
- {
- "description": "Denies the webview_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-webview-size",
- "markdownDescription": "Denies the webview_size command without any pre-configured scope."
- },
- {
- "description": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-get-all-windows`\n- `allow-scale-factor`\n- `allow-inner-position`\n- `allow-outer-position`\n- `allow-inner-size`\n- `allow-outer-size`\n- `allow-is-fullscreen`\n- `allow-is-minimized`\n- `allow-is-maximized`\n- `allow-is-focused`\n- `allow-is-decorated`\n- `allow-is-resizable`\n- `allow-is-maximizable`\n- `allow-is-minimizable`\n- `allow-is-closable`\n- `allow-is-visible`\n- `allow-is-enabled`\n- `allow-title`\n- `allow-current-monitor`\n- `allow-primary-monitor`\n- `allow-monitor-from-point`\n- `allow-available-monitors`\n- `allow-cursor-position`\n- `allow-theme`\n- `allow-is-always-on-top`\n- `allow-activity-name`\n- `allow-scene-identifier`\n- `allow-internal-toggle-maximize`",
- "type": "string",
- "const": "core:window:default",
- "markdownDescription": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-get-all-windows`\n- `allow-scale-factor`\n- `allow-inner-position`\n- `allow-outer-position`\n- `allow-inner-size`\n- `allow-outer-size`\n- `allow-is-fullscreen`\n- `allow-is-minimized`\n- `allow-is-maximized`\n- `allow-is-focused`\n- `allow-is-decorated`\n- `allow-is-resizable`\n- `allow-is-maximizable`\n- `allow-is-minimizable`\n- `allow-is-closable`\n- `allow-is-visible`\n- `allow-is-enabled`\n- `allow-title`\n- `allow-current-monitor`\n- `allow-primary-monitor`\n- `allow-monitor-from-point`\n- `allow-available-monitors`\n- `allow-cursor-position`\n- `allow-theme`\n- `allow-is-always-on-top`\n- `allow-activity-name`\n- `allow-scene-identifier`\n- `allow-internal-toggle-maximize`"
- },
- {
- "description": "Enables the activity_name command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-activity-name",
- "markdownDescription": "Enables the activity_name command without any pre-configured scope."
- },
- {
- "description": "Enables the available_monitors command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-available-monitors",
- "markdownDescription": "Enables the available_monitors command without any pre-configured scope."
- },
- {
- "description": "Enables the center command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-center",
- "markdownDescription": "Enables the center command without any pre-configured scope."
- },
- {
- "description": "Enables the close command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-close",
- "markdownDescription": "Enables the close command without any pre-configured scope."
- },
- {
- "description": "Enables the create command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-create",
- "markdownDescription": "Enables the create command without any pre-configured scope."
- },
- {
- "description": "Enables the current_monitor command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-current-monitor",
- "markdownDescription": "Enables the current_monitor command without any pre-configured scope."
- },
- {
- "description": "Enables the cursor_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-cursor-position",
- "markdownDescription": "Enables the cursor_position command without any pre-configured scope."
- },
- {
- "description": "Enables the destroy command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-destroy",
- "markdownDescription": "Enables the destroy command without any pre-configured scope."
- },
- {
- "description": "Enables the get_all_windows command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-get-all-windows",
- "markdownDescription": "Enables the get_all_windows command without any pre-configured scope."
- },
- {
- "description": "Enables the hide command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-hide",
- "markdownDescription": "Enables the hide command without any pre-configured scope."
- },
- {
- "description": "Enables the inner_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-inner-position",
- "markdownDescription": "Enables the inner_position command without any pre-configured scope."
- },
- {
- "description": "Enables the inner_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-inner-size",
- "markdownDescription": "Enables the inner_size command without any pre-configured scope."
- },
- {
- "description": "Enables the internal_toggle_maximize command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-internal-toggle-maximize",
- "markdownDescription": "Enables the internal_toggle_maximize command without any pre-configured scope."
- },
- {
- "description": "Enables the is_always_on_top command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-is-always-on-top",
- "markdownDescription": "Enables the is_always_on_top command without any pre-configured scope."
- },
- {
- "description": "Enables the is_closable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-is-closable",
- "markdownDescription": "Enables the is_closable command without any pre-configured scope."
- },
- {
- "description": "Enables the is_decorated command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-is-decorated",
- "markdownDescription": "Enables the is_decorated command without any pre-configured scope."
- },
- {
- "description": "Enables the is_enabled command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-is-enabled",
- "markdownDescription": "Enables the is_enabled command without any pre-configured scope."
- },
- {
- "description": "Enables the is_focused command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-is-focused",
- "markdownDescription": "Enables the is_focused command without any pre-configured scope."
- },
- {
- "description": "Enables the is_fullscreen command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-is-fullscreen",
- "markdownDescription": "Enables the is_fullscreen command without any pre-configured scope."
- },
- {
- "description": "Enables the is_maximizable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-is-maximizable",
- "markdownDescription": "Enables the is_maximizable command without any pre-configured scope."
- },
- {
- "description": "Enables the is_maximized command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-is-maximized",
- "markdownDescription": "Enables the is_maximized command without any pre-configured scope."
- },
- {
- "description": "Enables the is_minimizable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-is-minimizable",
- "markdownDescription": "Enables the is_minimizable command without any pre-configured scope."
- },
- {
- "description": "Enables the is_minimized command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-is-minimized",
- "markdownDescription": "Enables the is_minimized command without any pre-configured scope."
- },
- {
- "description": "Enables the is_resizable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-is-resizable",
- "markdownDescription": "Enables the is_resizable command without any pre-configured scope."
- },
- {
- "description": "Enables the is_visible command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-is-visible",
- "markdownDescription": "Enables the is_visible command without any pre-configured scope."
- },
- {
- "description": "Enables the maximize command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-maximize",
- "markdownDescription": "Enables the maximize command without any pre-configured scope."
- },
- {
- "description": "Enables the minimize command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-minimize",
- "markdownDescription": "Enables the minimize command without any pre-configured scope."
- },
- {
- "description": "Enables the monitor_from_point command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-monitor-from-point",
- "markdownDescription": "Enables the monitor_from_point command without any pre-configured scope."
- },
- {
- "description": "Enables the outer_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-outer-position",
- "markdownDescription": "Enables the outer_position command without any pre-configured scope."
- },
- {
- "description": "Enables the outer_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-outer-size",
- "markdownDescription": "Enables the outer_size command without any pre-configured scope."
- },
- {
- "description": "Enables the primary_monitor command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-primary-monitor",
- "markdownDescription": "Enables the primary_monitor command without any pre-configured scope."
- },
- {
- "description": "Enables the request_user_attention command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-request-user-attention",
- "markdownDescription": "Enables the request_user_attention command without any pre-configured scope."
- },
- {
- "description": "Enables the scale_factor command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-scale-factor",
- "markdownDescription": "Enables the scale_factor command without any pre-configured scope."
- },
- {
- "description": "Enables the scene_identifier command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-scene-identifier",
- "markdownDescription": "Enables the scene_identifier command without any pre-configured scope."
- },
- {
- "description": "Enables the set_always_on_bottom command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-always-on-bottom",
- "markdownDescription": "Enables the set_always_on_bottom command without any pre-configured scope."
- },
- {
- "description": "Enables the set_always_on_top command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-always-on-top",
- "markdownDescription": "Enables the set_always_on_top command without any pre-configured scope."
- },
- {
- "description": "Enables the set_background_color command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-background-color",
- "markdownDescription": "Enables the set_background_color command without any pre-configured scope."
- },
- {
- "description": "Enables the set_badge_count command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-badge-count",
- "markdownDescription": "Enables the set_badge_count command without any pre-configured scope."
- },
- {
- "description": "Enables the set_badge_label command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-badge-label",
- "markdownDescription": "Enables the set_badge_label command without any pre-configured scope."
- },
- {
- "description": "Enables the set_closable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-closable",
- "markdownDescription": "Enables the set_closable command without any pre-configured scope."
- },
- {
- "description": "Enables the set_content_protected command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-content-protected",
- "markdownDescription": "Enables the set_content_protected command without any pre-configured scope."
- },
- {
- "description": "Enables the set_cursor_grab command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-cursor-grab",
- "markdownDescription": "Enables the set_cursor_grab command without any pre-configured scope."
- },
- {
- "description": "Enables the set_cursor_icon command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-cursor-icon",
- "markdownDescription": "Enables the set_cursor_icon command without any pre-configured scope."
- },
- {
- "description": "Enables the set_cursor_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-cursor-position",
- "markdownDescription": "Enables the set_cursor_position command without any pre-configured scope."
- },
- {
- "description": "Enables the set_cursor_visible command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-cursor-visible",
- "markdownDescription": "Enables the set_cursor_visible command without any pre-configured scope."
- },
- {
- "description": "Enables the set_decorations command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-decorations",
- "markdownDescription": "Enables the set_decorations command without any pre-configured scope."
- },
- {
- "description": "Enables the set_effects command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-effects",
- "markdownDescription": "Enables the set_effects command without any pre-configured scope."
- },
- {
- "description": "Enables the set_enabled command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-enabled",
- "markdownDescription": "Enables the set_enabled command without any pre-configured scope."
- },
- {
- "description": "Enables the set_focus command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-focus",
- "markdownDescription": "Enables the set_focus command without any pre-configured scope."
- },
- {
- "description": "Enables the set_focusable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-focusable",
- "markdownDescription": "Enables the set_focusable command without any pre-configured scope."
- },
- {
- "description": "Enables the set_fullscreen command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-fullscreen",
- "markdownDescription": "Enables the set_fullscreen command without any pre-configured scope."
- },
- {
- "description": "Enables the set_icon command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-icon",
- "markdownDescription": "Enables the set_icon command without any pre-configured scope."
- },
- {
- "description": "Enables the set_ignore_cursor_events command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-ignore-cursor-events",
- "markdownDescription": "Enables the set_ignore_cursor_events command without any pre-configured scope."
- },
- {
- "description": "Enables the set_max_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-max-size",
- "markdownDescription": "Enables the set_max_size command without any pre-configured scope."
- },
- {
- "description": "Enables the set_maximizable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-maximizable",
- "markdownDescription": "Enables the set_maximizable command without any pre-configured scope."
- },
- {
- "description": "Enables the set_min_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-min-size",
- "markdownDescription": "Enables the set_min_size command without any pre-configured scope."
- },
- {
- "description": "Enables the set_minimizable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-minimizable",
- "markdownDescription": "Enables the set_minimizable command without any pre-configured scope."
- },
- {
- "description": "Enables the set_overlay_icon command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-overlay-icon",
- "markdownDescription": "Enables the set_overlay_icon command without any pre-configured scope."
- },
- {
- "description": "Enables the set_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-position",
- "markdownDescription": "Enables the set_position command without any pre-configured scope."
- },
- {
- "description": "Enables the set_progress_bar command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-progress-bar",
- "markdownDescription": "Enables the set_progress_bar command without any pre-configured scope."
- },
- {
- "description": "Enables the set_resizable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-resizable",
- "markdownDescription": "Enables the set_resizable command without any pre-configured scope."
- },
- {
- "description": "Enables the set_shadow command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-shadow",
- "markdownDescription": "Enables the set_shadow command without any pre-configured scope."
- },
- {
- "description": "Enables the set_simple_fullscreen command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-simple-fullscreen",
- "markdownDescription": "Enables the set_simple_fullscreen command without any pre-configured scope."
- },
- {
- "description": "Enables the set_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-size",
- "markdownDescription": "Enables the set_size command without any pre-configured scope."
- },
- {
- "description": "Enables the set_size_constraints command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-size-constraints",
- "markdownDescription": "Enables the set_size_constraints command without any pre-configured scope."
- },
- {
- "description": "Enables the set_skip_taskbar command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-skip-taskbar",
- "markdownDescription": "Enables the set_skip_taskbar command without any pre-configured scope."
- },
- {
- "description": "Enables the set_theme command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-theme",
- "markdownDescription": "Enables the set_theme command without any pre-configured scope."
- },
- {
- "description": "Enables the set_title command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-title",
- "markdownDescription": "Enables the set_title command without any pre-configured scope."
- },
- {
- "description": "Enables the set_title_bar_style command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-title-bar-style",
- "markdownDescription": "Enables the set_title_bar_style command without any pre-configured scope."
- },
- {
- "description": "Enables the set_visible_on_all_workspaces command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-visible-on-all-workspaces",
- "markdownDescription": "Enables the set_visible_on_all_workspaces command without any pre-configured scope."
- },
- {
- "description": "Enables the show command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-show",
- "markdownDescription": "Enables the show command without any pre-configured scope."
- },
- {
- "description": "Enables the start_dragging command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-start-dragging",
- "markdownDescription": "Enables the start_dragging command without any pre-configured scope."
- },
- {
- "description": "Enables the start_resize_dragging command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-start-resize-dragging",
- "markdownDescription": "Enables the start_resize_dragging command without any pre-configured scope."
- },
- {
- "description": "Enables the theme command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-theme",
- "markdownDescription": "Enables the theme command without any pre-configured scope."
- },
- {
- "description": "Enables the title command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-title",
- "markdownDescription": "Enables the title command without any pre-configured scope."
- },
- {
- "description": "Enables the toggle_maximize command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-toggle-maximize",
- "markdownDescription": "Enables the toggle_maximize command without any pre-configured scope."
- },
- {
- "description": "Enables the unmaximize command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-unmaximize",
- "markdownDescription": "Enables the unmaximize command without any pre-configured scope."
- },
- {
- "description": "Enables the unminimize command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-unminimize",
- "markdownDescription": "Enables the unminimize command without any pre-configured scope."
- },
- {
- "description": "Denies the activity_name command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-activity-name",
- "markdownDescription": "Denies the activity_name command without any pre-configured scope."
- },
- {
- "description": "Denies the available_monitors command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-available-monitors",
- "markdownDescription": "Denies the available_monitors command without any pre-configured scope."
- },
- {
- "description": "Denies the center command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-center",
- "markdownDescription": "Denies the center command without any pre-configured scope."
- },
- {
- "description": "Denies the close command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-close",
- "markdownDescription": "Denies the close command without any pre-configured scope."
- },
- {
- "description": "Denies the create command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-create",
- "markdownDescription": "Denies the create command without any pre-configured scope."
- },
- {
- "description": "Denies the current_monitor command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-current-monitor",
- "markdownDescription": "Denies the current_monitor command without any pre-configured scope."
- },
- {
- "description": "Denies the cursor_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-cursor-position",
- "markdownDescription": "Denies the cursor_position command without any pre-configured scope."
- },
- {
- "description": "Denies the destroy command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-destroy",
- "markdownDescription": "Denies the destroy command without any pre-configured scope."
- },
- {
- "description": "Denies the get_all_windows command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-get-all-windows",
- "markdownDescription": "Denies the get_all_windows command without any pre-configured scope."
- },
- {
- "description": "Denies the hide command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-hide",
- "markdownDescription": "Denies the hide command without any pre-configured scope."
- },
- {
- "description": "Denies the inner_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-inner-position",
- "markdownDescription": "Denies the inner_position command without any pre-configured scope."
- },
- {
- "description": "Denies the inner_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-inner-size",
- "markdownDescription": "Denies the inner_size command without any pre-configured scope."
- },
- {
- "description": "Denies the internal_toggle_maximize command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-internal-toggle-maximize",
- "markdownDescription": "Denies the internal_toggle_maximize command without any pre-configured scope."
- },
- {
- "description": "Denies the is_always_on_top command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-is-always-on-top",
- "markdownDescription": "Denies the is_always_on_top command without any pre-configured scope."
- },
- {
- "description": "Denies the is_closable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-is-closable",
- "markdownDescription": "Denies the is_closable command without any pre-configured scope."
- },
- {
- "description": "Denies the is_decorated command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-is-decorated",
- "markdownDescription": "Denies the is_decorated command without any pre-configured scope."
- },
- {
- "description": "Denies the is_enabled command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-is-enabled",
- "markdownDescription": "Denies the is_enabled command without any pre-configured scope."
- },
- {
- "description": "Denies the is_focused command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-is-focused",
- "markdownDescription": "Denies the is_focused command without any pre-configured scope."
- },
- {
- "description": "Denies the is_fullscreen command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-is-fullscreen",
- "markdownDescription": "Denies the is_fullscreen command without any pre-configured scope."
- },
- {
- "description": "Denies the is_maximizable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-is-maximizable",
- "markdownDescription": "Denies the is_maximizable command without any pre-configured scope."
- },
- {
- "description": "Denies the is_maximized command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-is-maximized",
- "markdownDescription": "Denies the is_maximized command without any pre-configured scope."
- },
- {
- "description": "Denies the is_minimizable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-is-minimizable",
- "markdownDescription": "Denies the is_minimizable command without any pre-configured scope."
- },
- {
- "description": "Denies the is_minimized command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-is-minimized",
- "markdownDescription": "Denies the is_minimized command without any pre-configured scope."
- },
- {
- "description": "Denies the is_resizable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-is-resizable",
- "markdownDescription": "Denies the is_resizable command without any pre-configured scope."
- },
- {
- "description": "Denies the is_visible command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-is-visible",
- "markdownDescription": "Denies the is_visible command without any pre-configured scope."
- },
- {
- "description": "Denies the maximize command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-maximize",
- "markdownDescription": "Denies the maximize command without any pre-configured scope."
- },
- {
- "description": "Denies the minimize command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-minimize",
- "markdownDescription": "Denies the minimize command without any pre-configured scope."
- },
- {
- "description": "Denies the monitor_from_point command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-monitor-from-point",
- "markdownDescription": "Denies the monitor_from_point command without any pre-configured scope."
- },
- {
- "description": "Denies the outer_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-outer-position",
- "markdownDescription": "Denies the outer_position command without any pre-configured scope."
- },
- {
- "description": "Denies the outer_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-outer-size",
- "markdownDescription": "Denies the outer_size command without any pre-configured scope."
- },
- {
- "description": "Denies the primary_monitor command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-primary-monitor",
- "markdownDescription": "Denies the primary_monitor command without any pre-configured scope."
- },
- {
- "description": "Denies the request_user_attention command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-request-user-attention",
- "markdownDescription": "Denies the request_user_attention command without any pre-configured scope."
- },
- {
- "description": "Denies the scale_factor command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-scale-factor",
- "markdownDescription": "Denies the scale_factor command without any pre-configured scope."
- },
- {
- "description": "Denies the scene_identifier command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-scene-identifier",
- "markdownDescription": "Denies the scene_identifier command without any pre-configured scope."
- },
- {
- "description": "Denies the set_always_on_bottom command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-always-on-bottom",
- "markdownDescription": "Denies the set_always_on_bottom command without any pre-configured scope."
- },
- {
- "description": "Denies the set_always_on_top command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-always-on-top",
- "markdownDescription": "Denies the set_always_on_top command without any pre-configured scope."
- },
- {
- "description": "Denies the set_background_color command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-background-color",
- "markdownDescription": "Denies the set_background_color command without any pre-configured scope."
- },
- {
- "description": "Denies the set_badge_count command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-badge-count",
- "markdownDescription": "Denies the set_badge_count command without any pre-configured scope."
- },
- {
- "description": "Denies the set_badge_label command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-badge-label",
- "markdownDescription": "Denies the set_badge_label command without any pre-configured scope."
- },
- {
- "description": "Denies the set_closable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-closable",
- "markdownDescription": "Denies the set_closable command without any pre-configured scope."
- },
- {
- "description": "Denies the set_content_protected command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-content-protected",
- "markdownDescription": "Denies the set_content_protected command without any pre-configured scope."
- },
- {
- "description": "Denies the set_cursor_grab command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-cursor-grab",
- "markdownDescription": "Denies the set_cursor_grab command without any pre-configured scope."
- },
- {
- "description": "Denies the set_cursor_icon command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-cursor-icon",
- "markdownDescription": "Denies the set_cursor_icon command without any pre-configured scope."
- },
- {
- "description": "Denies the set_cursor_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-cursor-position",
- "markdownDescription": "Denies the set_cursor_position command without any pre-configured scope."
- },
- {
- "description": "Denies the set_cursor_visible command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-cursor-visible",
- "markdownDescription": "Denies the set_cursor_visible command without any pre-configured scope."
- },
- {
- "description": "Denies the set_decorations command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-decorations",
- "markdownDescription": "Denies the set_decorations command without any pre-configured scope."
- },
- {
- "description": "Denies the set_effects command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-effects",
- "markdownDescription": "Denies the set_effects command without any pre-configured scope."
- },
- {
- "description": "Denies the set_enabled command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-enabled",
- "markdownDescription": "Denies the set_enabled command without any pre-configured scope."
- },
- {
- "description": "Denies the set_focus command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-focus",
- "markdownDescription": "Denies the set_focus command without any pre-configured scope."
- },
- {
- "description": "Denies the set_focusable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-focusable",
- "markdownDescription": "Denies the set_focusable command without any pre-configured scope."
- },
- {
- "description": "Denies the set_fullscreen command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-fullscreen",
- "markdownDescription": "Denies the set_fullscreen command without any pre-configured scope."
- },
- {
- "description": "Denies the set_icon command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-icon",
- "markdownDescription": "Denies the set_icon command without any pre-configured scope."
- },
- {
- "description": "Denies the set_ignore_cursor_events command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-ignore-cursor-events",
- "markdownDescription": "Denies the set_ignore_cursor_events command without any pre-configured scope."
- },
- {
- "description": "Denies the set_max_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-max-size",
- "markdownDescription": "Denies the set_max_size command without any pre-configured scope."
- },
- {
- "description": "Denies the set_maximizable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-maximizable",
- "markdownDescription": "Denies the set_maximizable command without any pre-configured scope."
- },
- {
- "description": "Denies the set_min_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-min-size",
- "markdownDescription": "Denies the set_min_size command without any pre-configured scope."
- },
- {
- "description": "Denies the set_minimizable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-minimizable",
- "markdownDescription": "Denies the set_minimizable command without any pre-configured scope."
- },
- {
- "description": "Denies the set_overlay_icon command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-overlay-icon",
- "markdownDescription": "Denies the set_overlay_icon command without any pre-configured scope."
- },
- {
- "description": "Denies the set_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-position",
- "markdownDescription": "Denies the set_position command without any pre-configured scope."
- },
- {
- "description": "Denies the set_progress_bar command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-progress-bar",
- "markdownDescription": "Denies the set_progress_bar command without any pre-configured scope."
- },
- {
- "description": "Denies the set_resizable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-resizable",
- "markdownDescription": "Denies the set_resizable command without any pre-configured scope."
- },
- {
- "description": "Denies the set_shadow command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-shadow",
- "markdownDescription": "Denies the set_shadow command without any pre-configured scope."
- },
- {
- "description": "Denies the set_simple_fullscreen command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-simple-fullscreen",
- "markdownDescription": "Denies the set_simple_fullscreen command without any pre-configured scope."
- },
- {
- "description": "Denies the set_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-size",
- "markdownDescription": "Denies the set_size command without any pre-configured scope."
- },
- {
- "description": "Denies the set_size_constraints command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-size-constraints",
- "markdownDescription": "Denies the set_size_constraints command without any pre-configured scope."
- },
- {
- "description": "Denies the set_skip_taskbar command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-skip-taskbar",
- "markdownDescription": "Denies the set_skip_taskbar command without any pre-configured scope."
- },
- {
- "description": "Denies the set_theme command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-theme",
- "markdownDescription": "Denies the set_theme command without any pre-configured scope."
- },
- {
- "description": "Denies the set_title command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-title",
- "markdownDescription": "Denies the set_title command without any pre-configured scope."
- },
- {
- "description": "Denies the set_title_bar_style command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-title-bar-style",
- "markdownDescription": "Denies the set_title_bar_style command without any pre-configured scope."
- },
- {
- "description": "Denies the set_visible_on_all_workspaces command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-visible-on-all-workspaces",
- "markdownDescription": "Denies the set_visible_on_all_workspaces command without any pre-configured scope."
- },
- {
- "description": "Denies the show command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-show",
- "markdownDescription": "Denies the show command without any pre-configured scope."
- },
- {
- "description": "Denies the start_dragging command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-start-dragging",
- "markdownDescription": "Denies the start_dragging command without any pre-configured scope."
- },
- {
- "description": "Denies the start_resize_dragging command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-start-resize-dragging",
- "markdownDescription": "Denies the start_resize_dragging command without any pre-configured scope."
- },
- {
- "description": "Denies the theme command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-theme",
- "markdownDescription": "Denies the theme command without any pre-configured scope."
- },
- {
- "description": "Denies the title command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-title",
- "markdownDescription": "Denies the title command without any pre-configured scope."
- },
- {
- "description": "Denies the toggle_maximize command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-toggle-maximize",
- "markdownDescription": "Denies the toggle_maximize command without any pre-configured scope."
- },
- {
- "description": "Denies the unmaximize command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-unmaximize",
- "markdownDescription": "Denies the unmaximize command without any pre-configured scope."
- },
- {
- "description": "Denies the unminimize command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-unminimize",
- "markdownDescription": "Denies the unminimize command without any pre-configured scope."
- },
- {
- "description": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n\n#### This default permission set includes:\n\n- `allow-message`\n- `allow-save`\n- `allow-open`",
- "type": "string",
- "const": "dialog:default",
- "markdownDescription": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n\n#### This default permission set includes:\n\n- `allow-message`\n- `allow-save`\n- `allow-open`"
- },
- {
- "description": "Enables the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)",
- "type": "string",
- "const": "dialog:allow-ask",
- "markdownDescription": "Enables the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)"
- },
- {
- "description": "Enables the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)",
- "type": "string",
- "const": "dialog:allow-confirm",
- "markdownDescription": "Enables the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)"
- },
- {
- "description": "Enables the message command without any pre-configured scope.",
- "type": "string",
- "const": "dialog:allow-message",
- "markdownDescription": "Enables the message command without any pre-configured scope."
- },
- {
- "description": "Enables the open command without any pre-configured scope.",
- "type": "string",
- "const": "dialog:allow-open",
- "markdownDescription": "Enables the open command without any pre-configured scope."
- },
- {
- "description": "Enables the save command without any pre-configured scope.",
- "type": "string",
- "const": "dialog:allow-save",
- "markdownDescription": "Enables the save command without any pre-configured scope."
- },
- {
- "description": "Denies the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)",
- "type": "string",
- "const": "dialog:deny-ask",
- "markdownDescription": "Denies the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)"
- },
- {
- "description": "Denies the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)",
- "type": "string",
- "const": "dialog:deny-confirm",
- "markdownDescription": "Denies the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)"
- },
- {
- "description": "Denies the message command without any pre-configured scope.",
- "type": "string",
- "const": "dialog:deny-message",
- "markdownDescription": "Denies the message command without any pre-configured scope."
- },
- {
- "description": "Denies the open command without any pre-configured scope.",
- "type": "string",
- "const": "dialog:deny-open",
- "markdownDescription": "Denies the open command without any pre-configured scope."
- },
- {
- "description": "Denies the save command without any pre-configured scope.",
- "type": "string",
- "const": "dialog:deny-save",
- "markdownDescription": "Denies the save command without any pre-configured scope."
- }
- ]
- },
- "Value": {
- "description": "All supported ACL values.",
- "anyOf": [
- {
- "description": "Represents a null JSON value.",
- "type": "null"
- },
- {
- "description": "Represents a [`bool`].",
- "type": "boolean"
- },
- {
- "description": "Represents a valid ACL [`Number`].",
- "allOf": [
- {
- "$ref": "#/definitions/Number"
- }
- ]
- },
- {
- "description": "Represents a [`String`].",
- "type": "string"
- },
- {
- "description": "Represents a list of other [`Value`]s.",
- "type": "array",
- "items": {
- "$ref": "#/definitions/Value"
- }
- },
- {
- "description": "Represents a map of [`String`] keys to [`Value`]s.",
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/Value"
- }
- }
- ]
- },
- "Number": {
- "description": "A valid ACL number.",
- "anyOf": [
- {
- "description": "Represents an [`i64`].",
- "type": "integer",
- "format": "int64"
- },
- {
- "description": "Represents a [`f64`].",
- "type": "number",
- "format": "double"
- }
- ]
- },
- "Target": {
- "description": "Platform target.",
- "oneOf": [
- {
- "description": "MacOS.",
- "type": "string",
- "enum": [
- "macOS"
- ]
- },
- {
- "description": "Windows.",
- "type": "string",
- "enum": [
- "windows"
- ]
- },
- {
- "description": "Linux.",
- "type": "string",
- "enum": [
- "linux"
- ]
- },
- {
- "description": "Android.",
- "type": "string",
- "enum": [
- "android"
- ]
- },
- {
- "description": "iOS.",
- "type": "string",
- "enum": [
- "iOS"
- ]
- }
- ]
- }
- }
-}
\ No newline at end of file
diff --git a/apps/windows-client/src-tauri/gen/schemas/windows-schema.json b/apps/windows-client/src-tauri/gen/schemas/windows-schema.json
deleted file mode 100644
index 24c9001..0000000
--- a/apps/windows-client/src-tauri/gen/schemas/windows-schema.json
+++ /dev/null
@@ -1,2358 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-07/schema#",
- "title": "CapabilityFile",
- "description": "Capability formats accepted in a capability file.",
- "anyOf": [
- {
- "description": "A single capability.",
- "allOf": [
- {
- "$ref": "#/definitions/Capability"
- }
- ]
- },
- {
- "description": "A list of capabilities.",
- "type": "array",
- "items": {
- "$ref": "#/definitions/Capability"
- }
- },
- {
- "description": "A list of capabilities.",
- "type": "object",
- "required": [
- "capabilities"
- ],
- "properties": {
- "capabilities": {
- "description": "The list of capabilities.",
- "type": "array",
- "items": {
- "$ref": "#/definitions/Capability"
- }
- }
- }
- }
- ],
- "definitions": {
- "Capability": {
- "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows' and webviews' fine grained access to the Tauri core, application, or plugin commands. If a webview or its window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programmatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, ], \"platforms\": [\"macOS\",\"windows\"] } ```",
- "type": "object",
- "required": [
- "identifier",
- "permissions"
- ],
- "properties": {
- "identifier": {
- "description": "Identifier of the capability.\n\n## Example\n\n`main-user-files-write`",
- "type": "string"
- },
- "description": {
- "description": "Description of what the capability is intended to allow on associated windows.\n\nIt should contain a description of what the grouped permissions should allow.\n\n## Example\n\nThis capability allows the `main` window access to `filesystem` write related commands and `dialog` commands to enable programmatic access to files selected by the user.",
- "default": "",
- "type": "string"
- },
- "remote": {
- "description": "Configure remote URLs that can use the capability permissions.\n\nThis setting is optional and defaults to not being set, as our default use case is that the content is served from our local application.\n\n:::caution Make sure you understand the security implications of providing remote sources with local system access. :::\n\n## Example\n\n```json { \"urls\": [\"https://*.mydomain.dev\"] } ```",
- "anyOf": [
- {
- "$ref": "#/definitions/CapabilityRemote"
- },
- {
- "type": "null"
- }
- ]
- },
- "local": {
- "description": "Whether this capability is enabled for local app URLs or not. Defaults to `true`.",
- "default": true,
- "type": "boolean"
- },
- "windows": {
- "description": "List of windows that are affected by this capability. Can be a glob pattern.\n\nIf a window label matches any of the patterns in this list, the capability will be enabled on all the webviews of that window, regardless of the value of [`Self::webviews`].\n\nOn multiwebview windows, prefer specifying [`Self::webviews`] and omitting [`Self::windows`] for a fine grained access control.\n\n## Example\n\n`[\"main\"]`",
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "webviews": {
- "description": "List of webviews that are affected by this capability. Can be a glob pattern.\n\nThe capability will be enabled on all the webviews whose label matches any of the patterns in this list, regardless of whether the webview's window label matches a pattern in [`Self::windows`].\n\n## Example\n\n`[\"sub-webview-one\", \"sub-webview-two\"]`",
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "permissions": {
- "description": "List of permissions attached to this capability.\n\nMust include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`. For commands directly implemented in the application itself only `${permission-name}` is required.\n\n## Example\n\n```json [ \"core:default\", \"shell:allow-open\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] } ] ```",
- "type": "array",
- "items": {
- "$ref": "#/definitions/PermissionEntry"
- },
- "uniqueItems": true
- },
- "platforms": {
- "description": "Limit which target platforms this capability applies to.\n\nBy default all platforms are targeted.\n\n## Example\n\n`[\"macOS\",\"windows\"]`",
- "type": [
- "array",
- "null"
- ],
- "items": {
- "$ref": "#/definitions/Target"
- }
- }
- }
- },
- "CapabilityRemote": {
- "description": "Configuration for remote URLs that are associated with the capability.",
- "type": "object",
- "required": [
- "urls"
- ],
- "properties": {
- "urls": {
- "description": "Remote domains this capability refers to using the [URLPattern standard](https://urlpattern.spec.whatwg.org/).\n\n## Examples\n\n- \"https://*.mydomain.dev\": allows subdomains of mydomain.dev - \"https://mydomain.dev/api/*\": allows any subpath of mydomain.dev/api",
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- }
- },
- "PermissionEntry": {
- "description": "An entry for a permission value in a [`Capability`] can be either a raw permission [`Identifier`] or an object that references a permission and extends its scope.",
- "anyOf": [
- {
- "description": "Reference a permission or permission set by identifier.",
- "allOf": [
- {
- "$ref": "#/definitions/Identifier"
- }
- ]
- },
- {
- "description": "Reference a permission or permission set by identifier and extends its scope.",
- "type": "object",
- "allOf": [
- {
- "properties": {
- "identifier": {
- "description": "Identifier of the permission or permission set.",
- "allOf": [
- {
- "$ref": "#/definitions/Identifier"
- }
- ]
- },
- "allow": {
- "description": "Data that defines what is allowed by the scope.",
- "type": [
- "array",
- "null"
- ],
- "items": {
- "$ref": "#/definitions/Value"
- }
- },
- "deny": {
- "description": "Data that defines what is denied by the scope. This should be prioritized by validation logic.",
- "type": [
- "array",
- "null"
- ],
- "items": {
- "$ref": "#/definitions/Value"
- }
- }
- }
- }
- ],
- "required": [
- "identifier"
- ]
- }
- ]
- },
- "Identifier": {
- "description": "Permission identifier",
- "oneOf": [
- {
- "description": "Default core plugins set.\n#### This default permission set includes:\n\n- `core:path:default`\n- `core:event:default`\n- `core:window:default`\n- `core:webview:default`\n- `core:app:default`\n- `core:image:default`\n- `core:resources:default`\n- `core:menu:default`\n- `core:tray:default`",
- "type": "string",
- "const": "core:default",
- "markdownDescription": "Default core plugins set.\n#### This default permission set includes:\n\n- `core:path:default`\n- `core:event:default`\n- `core:window:default`\n- `core:webview:default`\n- `core:app:default`\n- `core:image:default`\n- `core:resources:default`\n- `core:menu:default`\n- `core:tray:default`"
- },
- {
- "description": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-version`\n- `allow-name`\n- `allow-tauri-version`\n- `allow-identifier`\n- `allow-bundle-type`\n- `allow-register-listener`\n- `allow-remove-listener`\n- `allow-supports-multiple-windows`",
- "type": "string",
- "const": "core:app:default",
- "markdownDescription": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-version`\n- `allow-name`\n- `allow-tauri-version`\n- `allow-identifier`\n- `allow-bundle-type`\n- `allow-register-listener`\n- `allow-remove-listener`\n- `allow-supports-multiple-windows`"
- },
- {
- "description": "Enables the app_hide command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-app-hide",
- "markdownDescription": "Enables the app_hide command without any pre-configured scope."
- },
- {
- "description": "Enables the app_show command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-app-show",
- "markdownDescription": "Enables the app_show command without any pre-configured scope."
- },
- {
- "description": "Enables the bundle_type command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-bundle-type",
- "markdownDescription": "Enables the bundle_type command without any pre-configured scope."
- },
- {
- "description": "Enables the default_window_icon command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-default-window-icon",
- "markdownDescription": "Enables the default_window_icon command without any pre-configured scope."
- },
- {
- "description": "Enables the fetch_data_store_identifiers command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-fetch-data-store-identifiers",
- "markdownDescription": "Enables the fetch_data_store_identifiers command without any pre-configured scope."
- },
- {
- "description": "Enables the identifier command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-identifier",
- "markdownDescription": "Enables the identifier command without any pre-configured scope."
- },
- {
- "description": "Enables the name command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-name",
- "markdownDescription": "Enables the name command without any pre-configured scope."
- },
- {
- "description": "Enables the register_listener command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-register-listener",
- "markdownDescription": "Enables the register_listener command without any pre-configured scope."
- },
- {
- "description": "Enables the remove_data_store command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-remove-data-store",
- "markdownDescription": "Enables the remove_data_store command without any pre-configured scope."
- },
- {
- "description": "Enables the remove_listener command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-remove-listener",
- "markdownDescription": "Enables the remove_listener command without any pre-configured scope."
- },
- {
- "description": "Enables the set_app_theme command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-set-app-theme",
- "markdownDescription": "Enables the set_app_theme command without any pre-configured scope."
- },
- {
- "description": "Enables the set_dock_visibility command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-set-dock-visibility",
- "markdownDescription": "Enables the set_dock_visibility command without any pre-configured scope."
- },
- {
- "description": "Enables the supports_multiple_windows command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-supports-multiple-windows",
- "markdownDescription": "Enables the supports_multiple_windows command without any pre-configured scope."
- },
- {
- "description": "Enables the tauri_version command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-tauri-version",
- "markdownDescription": "Enables the tauri_version command without any pre-configured scope."
- },
- {
- "description": "Enables the version command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:allow-version",
- "markdownDescription": "Enables the version command without any pre-configured scope."
- },
- {
- "description": "Denies the app_hide command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-app-hide",
- "markdownDescription": "Denies the app_hide command without any pre-configured scope."
- },
- {
- "description": "Denies the app_show command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-app-show",
- "markdownDescription": "Denies the app_show command without any pre-configured scope."
- },
- {
- "description": "Denies the bundle_type command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-bundle-type",
- "markdownDescription": "Denies the bundle_type command without any pre-configured scope."
- },
- {
- "description": "Denies the default_window_icon command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-default-window-icon",
- "markdownDescription": "Denies the default_window_icon command without any pre-configured scope."
- },
- {
- "description": "Denies the fetch_data_store_identifiers command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-fetch-data-store-identifiers",
- "markdownDescription": "Denies the fetch_data_store_identifiers command without any pre-configured scope."
- },
- {
- "description": "Denies the identifier command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-identifier",
- "markdownDescription": "Denies the identifier command without any pre-configured scope."
- },
- {
- "description": "Denies the name command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-name",
- "markdownDescription": "Denies the name command without any pre-configured scope."
- },
- {
- "description": "Denies the register_listener command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-register-listener",
- "markdownDescription": "Denies the register_listener command without any pre-configured scope."
- },
- {
- "description": "Denies the remove_data_store command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-remove-data-store",
- "markdownDescription": "Denies the remove_data_store command without any pre-configured scope."
- },
- {
- "description": "Denies the remove_listener command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-remove-listener",
- "markdownDescription": "Denies the remove_listener command without any pre-configured scope."
- },
- {
- "description": "Denies the set_app_theme command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-set-app-theme",
- "markdownDescription": "Denies the set_app_theme command without any pre-configured scope."
- },
- {
- "description": "Denies the set_dock_visibility command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-set-dock-visibility",
- "markdownDescription": "Denies the set_dock_visibility command without any pre-configured scope."
- },
- {
- "description": "Denies the supports_multiple_windows command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-supports-multiple-windows",
- "markdownDescription": "Denies the supports_multiple_windows command without any pre-configured scope."
- },
- {
- "description": "Denies the tauri_version command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-tauri-version",
- "markdownDescription": "Denies the tauri_version command without any pre-configured scope."
- },
- {
- "description": "Denies the version command without any pre-configured scope.",
- "type": "string",
- "const": "core:app:deny-version",
- "markdownDescription": "Denies the version command without any pre-configured scope."
- },
- {
- "description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-listen`\n- `allow-unlisten`\n- `allow-emit`\n- `allow-emit-to`",
- "type": "string",
- "const": "core:event:default",
- "markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-listen`\n- `allow-unlisten`\n- `allow-emit`\n- `allow-emit-to`"
- },
- {
- "description": "Enables the emit command without any pre-configured scope.",
- "type": "string",
- "const": "core:event:allow-emit",
- "markdownDescription": "Enables the emit command without any pre-configured scope."
- },
- {
- "description": "Enables the emit_to command without any pre-configured scope.",
- "type": "string",
- "const": "core:event:allow-emit-to",
- "markdownDescription": "Enables the emit_to command without any pre-configured scope."
- },
- {
- "description": "Enables the listen command without any pre-configured scope.",
- "type": "string",
- "const": "core:event:allow-listen",
- "markdownDescription": "Enables the listen command without any pre-configured scope."
- },
- {
- "description": "Enables the unlisten command without any pre-configured scope.",
- "type": "string",
- "const": "core:event:allow-unlisten",
- "markdownDescription": "Enables the unlisten command without any pre-configured scope."
- },
- {
- "description": "Denies the emit command without any pre-configured scope.",
- "type": "string",
- "const": "core:event:deny-emit",
- "markdownDescription": "Denies the emit command without any pre-configured scope."
- },
- {
- "description": "Denies the emit_to command without any pre-configured scope.",
- "type": "string",
- "const": "core:event:deny-emit-to",
- "markdownDescription": "Denies the emit_to command without any pre-configured scope."
- },
- {
- "description": "Denies the listen command without any pre-configured scope.",
- "type": "string",
- "const": "core:event:deny-listen",
- "markdownDescription": "Denies the listen command without any pre-configured scope."
- },
- {
- "description": "Denies the unlisten command without any pre-configured scope.",
- "type": "string",
- "const": "core:event:deny-unlisten",
- "markdownDescription": "Denies the unlisten command without any pre-configured scope."
- },
- {
- "description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-from-bytes`\n- `allow-from-path`\n- `allow-rgba`\n- `allow-size`",
- "type": "string",
- "const": "core:image:default",
- "markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-from-bytes`\n- `allow-from-path`\n- `allow-rgba`\n- `allow-size`"
- },
- {
- "description": "Enables the from_bytes command without any pre-configured scope.",
- "type": "string",
- "const": "core:image:allow-from-bytes",
- "markdownDescription": "Enables the from_bytes command without any pre-configured scope."
- },
- {
- "description": "Enables the from_path command without any pre-configured scope.",
- "type": "string",
- "const": "core:image:allow-from-path",
- "markdownDescription": "Enables the from_path command without any pre-configured scope."
- },
- {
- "description": "Enables the new command without any pre-configured scope.",
- "type": "string",
- "const": "core:image:allow-new",
- "markdownDescription": "Enables the new command without any pre-configured scope."
- },
- {
- "description": "Enables the rgba command without any pre-configured scope.",
- "type": "string",
- "const": "core:image:allow-rgba",
- "markdownDescription": "Enables the rgba command without any pre-configured scope."
- },
- {
- "description": "Enables the size command without any pre-configured scope.",
- "type": "string",
- "const": "core:image:allow-size",
- "markdownDescription": "Enables the size command without any pre-configured scope."
- },
- {
- "description": "Denies the from_bytes command without any pre-configured scope.",
- "type": "string",
- "const": "core:image:deny-from-bytes",
- "markdownDescription": "Denies the from_bytes command without any pre-configured scope."
- },
- {
- "description": "Denies the from_path command without any pre-configured scope.",
- "type": "string",
- "const": "core:image:deny-from-path",
- "markdownDescription": "Denies the from_path command without any pre-configured scope."
- },
- {
- "description": "Denies the new command without any pre-configured scope.",
- "type": "string",
- "const": "core:image:deny-new",
- "markdownDescription": "Denies the new command without any pre-configured scope."
- },
- {
- "description": "Denies the rgba command without any pre-configured scope.",
- "type": "string",
- "const": "core:image:deny-rgba",
- "markdownDescription": "Denies the rgba command without any pre-configured scope."
- },
- {
- "description": "Denies the size command without any pre-configured scope.",
- "type": "string",
- "const": "core:image:deny-size",
- "markdownDescription": "Denies the size command without any pre-configured scope."
- },
- {
- "description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-append`\n- `allow-prepend`\n- `allow-insert`\n- `allow-remove`\n- `allow-remove-at`\n- `allow-items`\n- `allow-get`\n- `allow-popup`\n- `allow-create-default`\n- `allow-set-as-app-menu`\n- `allow-set-as-window-menu`\n- `allow-text`\n- `allow-set-text`\n- `allow-is-enabled`\n- `allow-set-enabled`\n- `allow-set-accelerator`\n- `allow-set-as-windows-menu-for-nsapp`\n- `allow-set-as-help-menu-for-nsapp`\n- `allow-is-checked`\n- `allow-set-checked`\n- `allow-set-icon`",
- "type": "string",
- "const": "core:menu:default",
- "markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-append`\n- `allow-prepend`\n- `allow-insert`\n- `allow-remove`\n- `allow-remove-at`\n- `allow-items`\n- `allow-get`\n- `allow-popup`\n- `allow-create-default`\n- `allow-set-as-app-menu`\n- `allow-set-as-window-menu`\n- `allow-text`\n- `allow-set-text`\n- `allow-is-enabled`\n- `allow-set-enabled`\n- `allow-set-accelerator`\n- `allow-set-as-windows-menu-for-nsapp`\n- `allow-set-as-help-menu-for-nsapp`\n- `allow-is-checked`\n- `allow-set-checked`\n- `allow-set-icon`"
- },
- {
- "description": "Enables the append command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-append",
- "markdownDescription": "Enables the append command without any pre-configured scope."
- },
- {
- "description": "Enables the create_default command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-create-default",
- "markdownDescription": "Enables the create_default command without any pre-configured scope."
- },
- {
- "description": "Enables the get command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-get",
- "markdownDescription": "Enables the get command without any pre-configured scope."
- },
- {
- "description": "Enables the insert command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-insert",
- "markdownDescription": "Enables the insert command without any pre-configured scope."
- },
- {
- "description": "Enables the is_checked command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-is-checked",
- "markdownDescription": "Enables the is_checked command without any pre-configured scope."
- },
- {
- "description": "Enables the is_enabled command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-is-enabled",
- "markdownDescription": "Enables the is_enabled command without any pre-configured scope."
- },
- {
- "description": "Enables the items command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-items",
- "markdownDescription": "Enables the items command without any pre-configured scope."
- },
- {
- "description": "Enables the new command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-new",
- "markdownDescription": "Enables the new command without any pre-configured scope."
- },
- {
- "description": "Enables the popup command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-popup",
- "markdownDescription": "Enables the popup command without any pre-configured scope."
- },
- {
- "description": "Enables the prepend command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-prepend",
- "markdownDescription": "Enables the prepend command without any pre-configured scope."
- },
- {
- "description": "Enables the remove command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-remove",
- "markdownDescription": "Enables the remove command without any pre-configured scope."
- },
- {
- "description": "Enables the remove_at command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-remove-at",
- "markdownDescription": "Enables the remove_at command without any pre-configured scope."
- },
- {
- "description": "Enables the set_accelerator command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-set-accelerator",
- "markdownDescription": "Enables the set_accelerator command without any pre-configured scope."
- },
- {
- "description": "Enables the set_as_app_menu command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-set-as-app-menu",
- "markdownDescription": "Enables the set_as_app_menu command without any pre-configured scope."
- },
- {
- "description": "Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-set-as-help-menu-for-nsapp",
- "markdownDescription": "Enables the set_as_help_menu_for_nsapp command without any pre-configured scope."
- },
- {
- "description": "Enables the set_as_window_menu command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-set-as-window-menu",
- "markdownDescription": "Enables the set_as_window_menu command without any pre-configured scope."
- },
- {
- "description": "Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-set-as-windows-menu-for-nsapp",
- "markdownDescription": "Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope."
- },
- {
- "description": "Enables the set_checked command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-set-checked",
- "markdownDescription": "Enables the set_checked command without any pre-configured scope."
- },
- {
- "description": "Enables the set_enabled command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-set-enabled",
- "markdownDescription": "Enables the set_enabled command without any pre-configured scope."
- },
- {
- "description": "Enables the set_icon command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-set-icon",
- "markdownDescription": "Enables the set_icon command without any pre-configured scope."
- },
- {
- "description": "Enables the set_text command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-set-text",
- "markdownDescription": "Enables the set_text command without any pre-configured scope."
- },
- {
- "description": "Enables the text command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:allow-text",
- "markdownDescription": "Enables the text command without any pre-configured scope."
- },
- {
- "description": "Denies the append command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-append",
- "markdownDescription": "Denies the append command without any pre-configured scope."
- },
- {
- "description": "Denies the create_default command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-create-default",
- "markdownDescription": "Denies the create_default command without any pre-configured scope."
- },
- {
- "description": "Denies the get command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-get",
- "markdownDescription": "Denies the get command without any pre-configured scope."
- },
- {
- "description": "Denies the insert command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-insert",
- "markdownDescription": "Denies the insert command without any pre-configured scope."
- },
- {
- "description": "Denies the is_checked command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-is-checked",
- "markdownDescription": "Denies the is_checked command without any pre-configured scope."
- },
- {
- "description": "Denies the is_enabled command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-is-enabled",
- "markdownDescription": "Denies the is_enabled command without any pre-configured scope."
- },
- {
- "description": "Denies the items command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-items",
- "markdownDescription": "Denies the items command without any pre-configured scope."
- },
- {
- "description": "Denies the new command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-new",
- "markdownDescription": "Denies the new command without any pre-configured scope."
- },
- {
- "description": "Denies the popup command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-popup",
- "markdownDescription": "Denies the popup command without any pre-configured scope."
- },
- {
- "description": "Denies the prepend command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-prepend",
- "markdownDescription": "Denies the prepend command without any pre-configured scope."
- },
- {
- "description": "Denies the remove command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-remove",
- "markdownDescription": "Denies the remove command without any pre-configured scope."
- },
- {
- "description": "Denies the remove_at command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-remove-at",
- "markdownDescription": "Denies the remove_at command without any pre-configured scope."
- },
- {
- "description": "Denies the set_accelerator command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-set-accelerator",
- "markdownDescription": "Denies the set_accelerator command without any pre-configured scope."
- },
- {
- "description": "Denies the set_as_app_menu command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-set-as-app-menu",
- "markdownDescription": "Denies the set_as_app_menu command without any pre-configured scope."
- },
- {
- "description": "Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-set-as-help-menu-for-nsapp",
- "markdownDescription": "Denies the set_as_help_menu_for_nsapp command without any pre-configured scope."
- },
- {
- "description": "Denies the set_as_window_menu command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-set-as-window-menu",
- "markdownDescription": "Denies the set_as_window_menu command without any pre-configured scope."
- },
- {
- "description": "Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-set-as-windows-menu-for-nsapp",
- "markdownDescription": "Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope."
- },
- {
- "description": "Denies the set_checked command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-set-checked",
- "markdownDescription": "Denies the set_checked command without any pre-configured scope."
- },
- {
- "description": "Denies the set_enabled command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-set-enabled",
- "markdownDescription": "Denies the set_enabled command without any pre-configured scope."
- },
- {
- "description": "Denies the set_icon command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-set-icon",
- "markdownDescription": "Denies the set_icon command without any pre-configured scope."
- },
- {
- "description": "Denies the set_text command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-set-text",
- "markdownDescription": "Denies the set_text command without any pre-configured scope."
- },
- {
- "description": "Denies the text command without any pre-configured scope.",
- "type": "string",
- "const": "core:menu:deny-text",
- "markdownDescription": "Denies the text command without any pre-configured scope."
- },
- {
- "description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-resolve-directory`\n- `allow-resolve`\n- `allow-normalize`\n- `allow-join`\n- `allow-dirname`\n- `allow-extname`\n- `allow-basename`\n- `allow-is-absolute`",
- "type": "string",
- "const": "core:path:default",
- "markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-resolve-directory`\n- `allow-resolve`\n- `allow-normalize`\n- `allow-join`\n- `allow-dirname`\n- `allow-extname`\n- `allow-basename`\n- `allow-is-absolute`"
- },
- {
- "description": "Enables the basename command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:allow-basename",
- "markdownDescription": "Enables the basename command without any pre-configured scope."
- },
- {
- "description": "Enables the dirname command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:allow-dirname",
- "markdownDescription": "Enables the dirname command without any pre-configured scope."
- },
- {
- "description": "Enables the extname command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:allow-extname",
- "markdownDescription": "Enables the extname command without any pre-configured scope."
- },
- {
- "description": "Enables the is_absolute command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:allow-is-absolute",
- "markdownDescription": "Enables the is_absolute command without any pre-configured scope."
- },
- {
- "description": "Enables the join command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:allow-join",
- "markdownDescription": "Enables the join command without any pre-configured scope."
- },
- {
- "description": "Enables the normalize command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:allow-normalize",
- "markdownDescription": "Enables the normalize command without any pre-configured scope."
- },
- {
- "description": "Enables the resolve command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:allow-resolve",
- "markdownDescription": "Enables the resolve command without any pre-configured scope."
- },
- {
- "description": "Enables the resolve_directory command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:allow-resolve-directory",
- "markdownDescription": "Enables the resolve_directory command without any pre-configured scope."
- },
- {
- "description": "Denies the basename command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:deny-basename",
- "markdownDescription": "Denies the basename command without any pre-configured scope."
- },
- {
- "description": "Denies the dirname command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:deny-dirname",
- "markdownDescription": "Denies the dirname command without any pre-configured scope."
- },
- {
- "description": "Denies the extname command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:deny-extname",
- "markdownDescription": "Denies the extname command without any pre-configured scope."
- },
- {
- "description": "Denies the is_absolute command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:deny-is-absolute",
- "markdownDescription": "Denies the is_absolute command without any pre-configured scope."
- },
- {
- "description": "Denies the join command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:deny-join",
- "markdownDescription": "Denies the join command without any pre-configured scope."
- },
- {
- "description": "Denies the normalize command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:deny-normalize",
- "markdownDescription": "Denies the normalize command without any pre-configured scope."
- },
- {
- "description": "Denies the resolve command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:deny-resolve",
- "markdownDescription": "Denies the resolve command without any pre-configured scope."
- },
- {
- "description": "Denies the resolve_directory command without any pre-configured scope.",
- "type": "string",
- "const": "core:path:deny-resolve-directory",
- "markdownDescription": "Denies the resolve_directory command without any pre-configured scope."
- },
- {
- "description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-close`",
- "type": "string",
- "const": "core:resources:default",
- "markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-close`"
- },
- {
- "description": "Enables the close command without any pre-configured scope.",
- "type": "string",
- "const": "core:resources:allow-close",
- "markdownDescription": "Enables the close command without any pre-configured scope."
- },
- {
- "description": "Denies the close command without any pre-configured scope.",
- "type": "string",
- "const": "core:resources:deny-close",
- "markdownDescription": "Denies the close command without any pre-configured scope."
- },
- {
- "description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-get-by-id`\n- `allow-remove-by-id`\n- `allow-set-icon`\n- `allow-set-menu`\n- `allow-set-tooltip`\n- `allow-set-title`\n- `allow-set-visible`\n- `allow-set-temp-dir-path`\n- `allow-set-icon-as-template`\n- `allow-set-icon-with-as-template`\n- `allow-set-show-menu-on-left-click`",
- "type": "string",
- "const": "core:tray:default",
- "markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-get-by-id`\n- `allow-remove-by-id`\n- `allow-set-icon`\n- `allow-set-menu`\n- `allow-set-tooltip`\n- `allow-set-title`\n- `allow-set-visible`\n- `allow-set-temp-dir-path`\n- `allow-set-icon-as-template`\n- `allow-set-icon-with-as-template`\n- `allow-set-show-menu-on-left-click`"
- },
- {
- "description": "Enables the get_by_id command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:allow-get-by-id",
- "markdownDescription": "Enables the get_by_id command without any pre-configured scope."
- },
- {
- "description": "Enables the new command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:allow-new",
- "markdownDescription": "Enables the new command without any pre-configured scope."
- },
- {
- "description": "Enables the remove_by_id command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:allow-remove-by-id",
- "markdownDescription": "Enables the remove_by_id command without any pre-configured scope."
- },
- {
- "description": "Enables the set_icon command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:allow-set-icon",
- "markdownDescription": "Enables the set_icon command without any pre-configured scope."
- },
- {
- "description": "Enables the set_icon_as_template command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:allow-set-icon-as-template",
- "markdownDescription": "Enables the set_icon_as_template command without any pre-configured scope."
- },
- {
- "description": "Enables the set_icon_with_as_template command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:allow-set-icon-with-as-template",
- "markdownDescription": "Enables the set_icon_with_as_template command without any pre-configured scope."
- },
- {
- "description": "Enables the set_menu command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:allow-set-menu",
- "markdownDescription": "Enables the set_menu command without any pre-configured scope."
- },
- {
- "description": "Enables the set_show_menu_on_left_click command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:allow-set-show-menu-on-left-click",
- "markdownDescription": "Enables the set_show_menu_on_left_click command without any pre-configured scope."
- },
- {
- "description": "Enables the set_temp_dir_path command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:allow-set-temp-dir-path",
- "markdownDescription": "Enables the set_temp_dir_path command without any pre-configured scope."
- },
- {
- "description": "Enables the set_title command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:allow-set-title",
- "markdownDescription": "Enables the set_title command without any pre-configured scope."
- },
- {
- "description": "Enables the set_tooltip command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:allow-set-tooltip",
- "markdownDescription": "Enables the set_tooltip command without any pre-configured scope."
- },
- {
- "description": "Enables the set_visible command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:allow-set-visible",
- "markdownDescription": "Enables the set_visible command without any pre-configured scope."
- },
- {
- "description": "Denies the get_by_id command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:deny-get-by-id",
- "markdownDescription": "Denies the get_by_id command without any pre-configured scope."
- },
- {
- "description": "Denies the new command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:deny-new",
- "markdownDescription": "Denies the new command without any pre-configured scope."
- },
- {
- "description": "Denies the remove_by_id command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:deny-remove-by-id",
- "markdownDescription": "Denies the remove_by_id command without any pre-configured scope."
- },
- {
- "description": "Denies the set_icon command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:deny-set-icon",
- "markdownDescription": "Denies the set_icon command without any pre-configured scope."
- },
- {
- "description": "Denies the set_icon_as_template command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:deny-set-icon-as-template",
- "markdownDescription": "Denies the set_icon_as_template command without any pre-configured scope."
- },
- {
- "description": "Denies the set_icon_with_as_template command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:deny-set-icon-with-as-template",
- "markdownDescription": "Denies the set_icon_with_as_template command without any pre-configured scope."
- },
- {
- "description": "Denies the set_menu command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:deny-set-menu",
- "markdownDescription": "Denies the set_menu command without any pre-configured scope."
- },
- {
- "description": "Denies the set_show_menu_on_left_click command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:deny-set-show-menu-on-left-click",
- "markdownDescription": "Denies the set_show_menu_on_left_click command without any pre-configured scope."
- },
- {
- "description": "Denies the set_temp_dir_path command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:deny-set-temp-dir-path",
- "markdownDescription": "Denies the set_temp_dir_path command without any pre-configured scope."
- },
- {
- "description": "Denies the set_title command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:deny-set-title",
- "markdownDescription": "Denies the set_title command without any pre-configured scope."
- },
- {
- "description": "Denies the set_tooltip command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:deny-set-tooltip",
- "markdownDescription": "Denies the set_tooltip command without any pre-configured scope."
- },
- {
- "description": "Denies the set_visible command without any pre-configured scope.",
- "type": "string",
- "const": "core:tray:deny-set-visible",
- "markdownDescription": "Denies the set_visible command without any pre-configured scope."
- },
- {
- "description": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-get-all-webviews`\n- `allow-webview-position`\n- `allow-webview-size`\n- `allow-internal-toggle-devtools`",
- "type": "string",
- "const": "core:webview:default",
- "markdownDescription": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-get-all-webviews`\n- `allow-webview-position`\n- `allow-webview-size`\n- `allow-internal-toggle-devtools`"
- },
- {
- "description": "Enables the clear_all_browsing_data command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-clear-all-browsing-data",
- "markdownDescription": "Enables the clear_all_browsing_data command without any pre-configured scope."
- },
- {
- "description": "Enables the create_webview command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-create-webview",
- "markdownDescription": "Enables the create_webview command without any pre-configured scope."
- },
- {
- "description": "Enables the create_webview_window command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-create-webview-window",
- "markdownDescription": "Enables the create_webview_window command without any pre-configured scope."
- },
- {
- "description": "Enables the get_all_webviews command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-get-all-webviews",
- "markdownDescription": "Enables the get_all_webviews command without any pre-configured scope."
- },
- {
- "description": "Enables the internal_toggle_devtools command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-internal-toggle-devtools",
- "markdownDescription": "Enables the internal_toggle_devtools command without any pre-configured scope."
- },
- {
- "description": "Enables the print command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-print",
- "markdownDescription": "Enables the print command without any pre-configured scope."
- },
- {
- "description": "Enables the reparent command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-reparent",
- "markdownDescription": "Enables the reparent command without any pre-configured scope."
- },
- {
- "description": "Enables the set_webview_auto_resize command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-set-webview-auto-resize",
- "markdownDescription": "Enables the set_webview_auto_resize command without any pre-configured scope."
- },
- {
- "description": "Enables the set_webview_background_color command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-set-webview-background-color",
- "markdownDescription": "Enables the set_webview_background_color command without any pre-configured scope."
- },
- {
- "description": "Enables the set_webview_focus command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-set-webview-focus",
- "markdownDescription": "Enables the set_webview_focus command without any pre-configured scope."
- },
- {
- "description": "Enables the set_webview_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-set-webview-position",
- "markdownDescription": "Enables the set_webview_position command without any pre-configured scope."
- },
- {
- "description": "Enables the set_webview_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-set-webview-size",
- "markdownDescription": "Enables the set_webview_size command without any pre-configured scope."
- },
- {
- "description": "Enables the set_webview_zoom command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-set-webview-zoom",
- "markdownDescription": "Enables the set_webview_zoom command without any pre-configured scope."
- },
- {
- "description": "Enables the webview_close command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-webview-close",
- "markdownDescription": "Enables the webview_close command without any pre-configured scope."
- },
- {
- "description": "Enables the webview_hide command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-webview-hide",
- "markdownDescription": "Enables the webview_hide command without any pre-configured scope."
- },
- {
- "description": "Enables the webview_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-webview-position",
- "markdownDescription": "Enables the webview_position command without any pre-configured scope."
- },
- {
- "description": "Enables the webview_show command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-webview-show",
- "markdownDescription": "Enables the webview_show command without any pre-configured scope."
- },
- {
- "description": "Enables the webview_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:allow-webview-size",
- "markdownDescription": "Enables the webview_size command without any pre-configured scope."
- },
- {
- "description": "Denies the clear_all_browsing_data command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-clear-all-browsing-data",
- "markdownDescription": "Denies the clear_all_browsing_data command without any pre-configured scope."
- },
- {
- "description": "Denies the create_webview command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-create-webview",
- "markdownDescription": "Denies the create_webview command without any pre-configured scope."
- },
- {
- "description": "Denies the create_webview_window command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-create-webview-window",
- "markdownDescription": "Denies the create_webview_window command without any pre-configured scope."
- },
- {
- "description": "Denies the get_all_webviews command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-get-all-webviews",
- "markdownDescription": "Denies the get_all_webviews command without any pre-configured scope."
- },
- {
- "description": "Denies the internal_toggle_devtools command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-internal-toggle-devtools",
- "markdownDescription": "Denies the internal_toggle_devtools command without any pre-configured scope."
- },
- {
- "description": "Denies the print command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-print",
- "markdownDescription": "Denies the print command without any pre-configured scope."
- },
- {
- "description": "Denies the reparent command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-reparent",
- "markdownDescription": "Denies the reparent command without any pre-configured scope."
- },
- {
- "description": "Denies the set_webview_auto_resize command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-set-webview-auto-resize",
- "markdownDescription": "Denies the set_webview_auto_resize command without any pre-configured scope."
- },
- {
- "description": "Denies the set_webview_background_color command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-set-webview-background-color",
- "markdownDescription": "Denies the set_webview_background_color command without any pre-configured scope."
- },
- {
- "description": "Denies the set_webview_focus command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-set-webview-focus",
- "markdownDescription": "Denies the set_webview_focus command without any pre-configured scope."
- },
- {
- "description": "Denies the set_webview_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-set-webview-position",
- "markdownDescription": "Denies the set_webview_position command without any pre-configured scope."
- },
- {
- "description": "Denies the set_webview_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-set-webview-size",
- "markdownDescription": "Denies the set_webview_size command without any pre-configured scope."
- },
- {
- "description": "Denies the set_webview_zoom command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-set-webview-zoom",
- "markdownDescription": "Denies the set_webview_zoom command without any pre-configured scope."
- },
- {
- "description": "Denies the webview_close command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-webview-close",
- "markdownDescription": "Denies the webview_close command without any pre-configured scope."
- },
- {
- "description": "Denies the webview_hide command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-webview-hide",
- "markdownDescription": "Denies the webview_hide command without any pre-configured scope."
- },
- {
- "description": "Denies the webview_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-webview-position",
- "markdownDescription": "Denies the webview_position command without any pre-configured scope."
- },
- {
- "description": "Denies the webview_show command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-webview-show",
- "markdownDescription": "Denies the webview_show command without any pre-configured scope."
- },
- {
- "description": "Denies the webview_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:webview:deny-webview-size",
- "markdownDescription": "Denies the webview_size command without any pre-configured scope."
- },
- {
- "description": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-get-all-windows`\n- `allow-scale-factor`\n- `allow-inner-position`\n- `allow-outer-position`\n- `allow-inner-size`\n- `allow-outer-size`\n- `allow-is-fullscreen`\n- `allow-is-minimized`\n- `allow-is-maximized`\n- `allow-is-focused`\n- `allow-is-decorated`\n- `allow-is-resizable`\n- `allow-is-maximizable`\n- `allow-is-minimizable`\n- `allow-is-closable`\n- `allow-is-visible`\n- `allow-is-enabled`\n- `allow-title`\n- `allow-current-monitor`\n- `allow-primary-monitor`\n- `allow-monitor-from-point`\n- `allow-available-monitors`\n- `allow-cursor-position`\n- `allow-theme`\n- `allow-is-always-on-top`\n- `allow-activity-name`\n- `allow-scene-identifier`\n- `allow-internal-toggle-maximize`",
- "type": "string",
- "const": "core:window:default",
- "markdownDescription": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-get-all-windows`\n- `allow-scale-factor`\n- `allow-inner-position`\n- `allow-outer-position`\n- `allow-inner-size`\n- `allow-outer-size`\n- `allow-is-fullscreen`\n- `allow-is-minimized`\n- `allow-is-maximized`\n- `allow-is-focused`\n- `allow-is-decorated`\n- `allow-is-resizable`\n- `allow-is-maximizable`\n- `allow-is-minimizable`\n- `allow-is-closable`\n- `allow-is-visible`\n- `allow-is-enabled`\n- `allow-title`\n- `allow-current-monitor`\n- `allow-primary-monitor`\n- `allow-monitor-from-point`\n- `allow-available-monitors`\n- `allow-cursor-position`\n- `allow-theme`\n- `allow-is-always-on-top`\n- `allow-activity-name`\n- `allow-scene-identifier`\n- `allow-internal-toggle-maximize`"
- },
- {
- "description": "Enables the activity_name command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-activity-name",
- "markdownDescription": "Enables the activity_name command without any pre-configured scope."
- },
- {
- "description": "Enables the available_monitors command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-available-monitors",
- "markdownDescription": "Enables the available_monitors command without any pre-configured scope."
- },
- {
- "description": "Enables the center command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-center",
- "markdownDescription": "Enables the center command without any pre-configured scope."
- },
- {
- "description": "Enables the close command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-close",
- "markdownDescription": "Enables the close command without any pre-configured scope."
- },
- {
- "description": "Enables the create command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-create",
- "markdownDescription": "Enables the create command without any pre-configured scope."
- },
- {
- "description": "Enables the current_monitor command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-current-monitor",
- "markdownDescription": "Enables the current_monitor command without any pre-configured scope."
- },
- {
- "description": "Enables the cursor_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-cursor-position",
- "markdownDescription": "Enables the cursor_position command without any pre-configured scope."
- },
- {
- "description": "Enables the destroy command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-destroy",
- "markdownDescription": "Enables the destroy command without any pre-configured scope."
- },
- {
- "description": "Enables the get_all_windows command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-get-all-windows",
- "markdownDescription": "Enables the get_all_windows command without any pre-configured scope."
- },
- {
- "description": "Enables the hide command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-hide",
- "markdownDescription": "Enables the hide command without any pre-configured scope."
- },
- {
- "description": "Enables the inner_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-inner-position",
- "markdownDescription": "Enables the inner_position command without any pre-configured scope."
- },
- {
- "description": "Enables the inner_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-inner-size",
- "markdownDescription": "Enables the inner_size command without any pre-configured scope."
- },
- {
- "description": "Enables the internal_toggle_maximize command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-internal-toggle-maximize",
- "markdownDescription": "Enables the internal_toggle_maximize command without any pre-configured scope."
- },
- {
- "description": "Enables the is_always_on_top command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-is-always-on-top",
- "markdownDescription": "Enables the is_always_on_top command without any pre-configured scope."
- },
- {
- "description": "Enables the is_closable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-is-closable",
- "markdownDescription": "Enables the is_closable command without any pre-configured scope."
- },
- {
- "description": "Enables the is_decorated command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-is-decorated",
- "markdownDescription": "Enables the is_decorated command without any pre-configured scope."
- },
- {
- "description": "Enables the is_enabled command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-is-enabled",
- "markdownDescription": "Enables the is_enabled command without any pre-configured scope."
- },
- {
- "description": "Enables the is_focused command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-is-focused",
- "markdownDescription": "Enables the is_focused command without any pre-configured scope."
- },
- {
- "description": "Enables the is_fullscreen command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-is-fullscreen",
- "markdownDescription": "Enables the is_fullscreen command without any pre-configured scope."
- },
- {
- "description": "Enables the is_maximizable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-is-maximizable",
- "markdownDescription": "Enables the is_maximizable command without any pre-configured scope."
- },
- {
- "description": "Enables the is_maximized command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-is-maximized",
- "markdownDescription": "Enables the is_maximized command without any pre-configured scope."
- },
- {
- "description": "Enables the is_minimizable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-is-minimizable",
- "markdownDescription": "Enables the is_minimizable command without any pre-configured scope."
- },
- {
- "description": "Enables the is_minimized command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-is-minimized",
- "markdownDescription": "Enables the is_minimized command without any pre-configured scope."
- },
- {
- "description": "Enables the is_resizable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-is-resizable",
- "markdownDescription": "Enables the is_resizable command without any pre-configured scope."
- },
- {
- "description": "Enables the is_visible command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-is-visible",
- "markdownDescription": "Enables the is_visible command without any pre-configured scope."
- },
- {
- "description": "Enables the maximize command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-maximize",
- "markdownDescription": "Enables the maximize command without any pre-configured scope."
- },
- {
- "description": "Enables the minimize command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-minimize",
- "markdownDescription": "Enables the minimize command without any pre-configured scope."
- },
- {
- "description": "Enables the monitor_from_point command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-monitor-from-point",
- "markdownDescription": "Enables the monitor_from_point command without any pre-configured scope."
- },
- {
- "description": "Enables the outer_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-outer-position",
- "markdownDescription": "Enables the outer_position command without any pre-configured scope."
- },
- {
- "description": "Enables the outer_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-outer-size",
- "markdownDescription": "Enables the outer_size command without any pre-configured scope."
- },
- {
- "description": "Enables the primary_monitor command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-primary-monitor",
- "markdownDescription": "Enables the primary_monitor command without any pre-configured scope."
- },
- {
- "description": "Enables the request_user_attention command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-request-user-attention",
- "markdownDescription": "Enables the request_user_attention command without any pre-configured scope."
- },
- {
- "description": "Enables the scale_factor command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-scale-factor",
- "markdownDescription": "Enables the scale_factor command without any pre-configured scope."
- },
- {
- "description": "Enables the scene_identifier command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-scene-identifier",
- "markdownDescription": "Enables the scene_identifier command without any pre-configured scope."
- },
- {
- "description": "Enables the set_always_on_bottom command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-always-on-bottom",
- "markdownDescription": "Enables the set_always_on_bottom command without any pre-configured scope."
- },
- {
- "description": "Enables the set_always_on_top command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-always-on-top",
- "markdownDescription": "Enables the set_always_on_top command without any pre-configured scope."
- },
- {
- "description": "Enables the set_background_color command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-background-color",
- "markdownDescription": "Enables the set_background_color command without any pre-configured scope."
- },
- {
- "description": "Enables the set_badge_count command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-badge-count",
- "markdownDescription": "Enables the set_badge_count command without any pre-configured scope."
- },
- {
- "description": "Enables the set_badge_label command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-badge-label",
- "markdownDescription": "Enables the set_badge_label command without any pre-configured scope."
- },
- {
- "description": "Enables the set_closable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-closable",
- "markdownDescription": "Enables the set_closable command without any pre-configured scope."
- },
- {
- "description": "Enables the set_content_protected command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-content-protected",
- "markdownDescription": "Enables the set_content_protected command without any pre-configured scope."
- },
- {
- "description": "Enables the set_cursor_grab command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-cursor-grab",
- "markdownDescription": "Enables the set_cursor_grab command without any pre-configured scope."
- },
- {
- "description": "Enables the set_cursor_icon command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-cursor-icon",
- "markdownDescription": "Enables the set_cursor_icon command without any pre-configured scope."
- },
- {
- "description": "Enables the set_cursor_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-cursor-position",
- "markdownDescription": "Enables the set_cursor_position command without any pre-configured scope."
- },
- {
- "description": "Enables the set_cursor_visible command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-cursor-visible",
- "markdownDescription": "Enables the set_cursor_visible command without any pre-configured scope."
- },
- {
- "description": "Enables the set_decorations command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-decorations",
- "markdownDescription": "Enables the set_decorations command without any pre-configured scope."
- },
- {
- "description": "Enables the set_effects command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-effects",
- "markdownDescription": "Enables the set_effects command without any pre-configured scope."
- },
- {
- "description": "Enables the set_enabled command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-enabled",
- "markdownDescription": "Enables the set_enabled command without any pre-configured scope."
- },
- {
- "description": "Enables the set_focus command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-focus",
- "markdownDescription": "Enables the set_focus command without any pre-configured scope."
- },
- {
- "description": "Enables the set_focusable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-focusable",
- "markdownDescription": "Enables the set_focusable command without any pre-configured scope."
- },
- {
- "description": "Enables the set_fullscreen command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-fullscreen",
- "markdownDescription": "Enables the set_fullscreen command without any pre-configured scope."
- },
- {
- "description": "Enables the set_icon command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-icon",
- "markdownDescription": "Enables the set_icon command without any pre-configured scope."
- },
- {
- "description": "Enables the set_ignore_cursor_events command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-ignore-cursor-events",
- "markdownDescription": "Enables the set_ignore_cursor_events command without any pre-configured scope."
- },
- {
- "description": "Enables the set_max_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-max-size",
- "markdownDescription": "Enables the set_max_size command without any pre-configured scope."
- },
- {
- "description": "Enables the set_maximizable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-maximizable",
- "markdownDescription": "Enables the set_maximizable command without any pre-configured scope."
- },
- {
- "description": "Enables the set_min_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-min-size",
- "markdownDescription": "Enables the set_min_size command without any pre-configured scope."
- },
- {
- "description": "Enables the set_minimizable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-minimizable",
- "markdownDescription": "Enables the set_minimizable command without any pre-configured scope."
- },
- {
- "description": "Enables the set_overlay_icon command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-overlay-icon",
- "markdownDescription": "Enables the set_overlay_icon command without any pre-configured scope."
- },
- {
- "description": "Enables the set_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-position",
- "markdownDescription": "Enables the set_position command without any pre-configured scope."
- },
- {
- "description": "Enables the set_progress_bar command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-progress-bar",
- "markdownDescription": "Enables the set_progress_bar command without any pre-configured scope."
- },
- {
- "description": "Enables the set_resizable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-resizable",
- "markdownDescription": "Enables the set_resizable command without any pre-configured scope."
- },
- {
- "description": "Enables the set_shadow command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-shadow",
- "markdownDescription": "Enables the set_shadow command without any pre-configured scope."
- },
- {
- "description": "Enables the set_simple_fullscreen command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-simple-fullscreen",
- "markdownDescription": "Enables the set_simple_fullscreen command without any pre-configured scope."
- },
- {
- "description": "Enables the set_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-size",
- "markdownDescription": "Enables the set_size command without any pre-configured scope."
- },
- {
- "description": "Enables the set_size_constraints command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-size-constraints",
- "markdownDescription": "Enables the set_size_constraints command without any pre-configured scope."
- },
- {
- "description": "Enables the set_skip_taskbar command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-skip-taskbar",
- "markdownDescription": "Enables the set_skip_taskbar command without any pre-configured scope."
- },
- {
- "description": "Enables the set_theme command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-theme",
- "markdownDescription": "Enables the set_theme command without any pre-configured scope."
- },
- {
- "description": "Enables the set_title command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-title",
- "markdownDescription": "Enables the set_title command without any pre-configured scope."
- },
- {
- "description": "Enables the set_title_bar_style command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-title-bar-style",
- "markdownDescription": "Enables the set_title_bar_style command without any pre-configured scope."
- },
- {
- "description": "Enables the set_visible_on_all_workspaces command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-set-visible-on-all-workspaces",
- "markdownDescription": "Enables the set_visible_on_all_workspaces command without any pre-configured scope."
- },
- {
- "description": "Enables the show command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-show",
- "markdownDescription": "Enables the show command without any pre-configured scope."
- },
- {
- "description": "Enables the start_dragging command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-start-dragging",
- "markdownDescription": "Enables the start_dragging command without any pre-configured scope."
- },
- {
- "description": "Enables the start_resize_dragging command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-start-resize-dragging",
- "markdownDescription": "Enables the start_resize_dragging command without any pre-configured scope."
- },
- {
- "description": "Enables the theme command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-theme",
- "markdownDescription": "Enables the theme command without any pre-configured scope."
- },
- {
- "description": "Enables the title command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-title",
- "markdownDescription": "Enables the title command without any pre-configured scope."
- },
- {
- "description": "Enables the toggle_maximize command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-toggle-maximize",
- "markdownDescription": "Enables the toggle_maximize command without any pre-configured scope."
- },
- {
- "description": "Enables the unmaximize command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-unmaximize",
- "markdownDescription": "Enables the unmaximize command without any pre-configured scope."
- },
- {
- "description": "Enables the unminimize command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:allow-unminimize",
- "markdownDescription": "Enables the unminimize command without any pre-configured scope."
- },
- {
- "description": "Denies the activity_name command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-activity-name",
- "markdownDescription": "Denies the activity_name command without any pre-configured scope."
- },
- {
- "description": "Denies the available_monitors command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-available-monitors",
- "markdownDescription": "Denies the available_monitors command without any pre-configured scope."
- },
- {
- "description": "Denies the center command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-center",
- "markdownDescription": "Denies the center command without any pre-configured scope."
- },
- {
- "description": "Denies the close command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-close",
- "markdownDescription": "Denies the close command without any pre-configured scope."
- },
- {
- "description": "Denies the create command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-create",
- "markdownDescription": "Denies the create command without any pre-configured scope."
- },
- {
- "description": "Denies the current_monitor command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-current-monitor",
- "markdownDescription": "Denies the current_monitor command without any pre-configured scope."
- },
- {
- "description": "Denies the cursor_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-cursor-position",
- "markdownDescription": "Denies the cursor_position command without any pre-configured scope."
- },
- {
- "description": "Denies the destroy command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-destroy",
- "markdownDescription": "Denies the destroy command without any pre-configured scope."
- },
- {
- "description": "Denies the get_all_windows command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-get-all-windows",
- "markdownDescription": "Denies the get_all_windows command without any pre-configured scope."
- },
- {
- "description": "Denies the hide command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-hide",
- "markdownDescription": "Denies the hide command without any pre-configured scope."
- },
- {
- "description": "Denies the inner_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-inner-position",
- "markdownDescription": "Denies the inner_position command without any pre-configured scope."
- },
- {
- "description": "Denies the inner_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-inner-size",
- "markdownDescription": "Denies the inner_size command without any pre-configured scope."
- },
- {
- "description": "Denies the internal_toggle_maximize command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-internal-toggle-maximize",
- "markdownDescription": "Denies the internal_toggle_maximize command without any pre-configured scope."
- },
- {
- "description": "Denies the is_always_on_top command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-is-always-on-top",
- "markdownDescription": "Denies the is_always_on_top command without any pre-configured scope."
- },
- {
- "description": "Denies the is_closable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-is-closable",
- "markdownDescription": "Denies the is_closable command without any pre-configured scope."
- },
- {
- "description": "Denies the is_decorated command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-is-decorated",
- "markdownDescription": "Denies the is_decorated command without any pre-configured scope."
- },
- {
- "description": "Denies the is_enabled command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-is-enabled",
- "markdownDescription": "Denies the is_enabled command without any pre-configured scope."
- },
- {
- "description": "Denies the is_focused command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-is-focused",
- "markdownDescription": "Denies the is_focused command without any pre-configured scope."
- },
- {
- "description": "Denies the is_fullscreen command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-is-fullscreen",
- "markdownDescription": "Denies the is_fullscreen command without any pre-configured scope."
- },
- {
- "description": "Denies the is_maximizable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-is-maximizable",
- "markdownDescription": "Denies the is_maximizable command without any pre-configured scope."
- },
- {
- "description": "Denies the is_maximized command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-is-maximized",
- "markdownDescription": "Denies the is_maximized command without any pre-configured scope."
- },
- {
- "description": "Denies the is_minimizable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-is-minimizable",
- "markdownDescription": "Denies the is_minimizable command without any pre-configured scope."
- },
- {
- "description": "Denies the is_minimized command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-is-minimized",
- "markdownDescription": "Denies the is_minimized command without any pre-configured scope."
- },
- {
- "description": "Denies the is_resizable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-is-resizable",
- "markdownDescription": "Denies the is_resizable command without any pre-configured scope."
- },
- {
- "description": "Denies the is_visible command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-is-visible",
- "markdownDescription": "Denies the is_visible command without any pre-configured scope."
- },
- {
- "description": "Denies the maximize command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-maximize",
- "markdownDescription": "Denies the maximize command without any pre-configured scope."
- },
- {
- "description": "Denies the minimize command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-minimize",
- "markdownDescription": "Denies the minimize command without any pre-configured scope."
- },
- {
- "description": "Denies the monitor_from_point command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-monitor-from-point",
- "markdownDescription": "Denies the monitor_from_point command without any pre-configured scope."
- },
- {
- "description": "Denies the outer_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-outer-position",
- "markdownDescription": "Denies the outer_position command without any pre-configured scope."
- },
- {
- "description": "Denies the outer_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-outer-size",
- "markdownDescription": "Denies the outer_size command without any pre-configured scope."
- },
- {
- "description": "Denies the primary_monitor command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-primary-monitor",
- "markdownDescription": "Denies the primary_monitor command without any pre-configured scope."
- },
- {
- "description": "Denies the request_user_attention command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-request-user-attention",
- "markdownDescription": "Denies the request_user_attention command without any pre-configured scope."
- },
- {
- "description": "Denies the scale_factor command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-scale-factor",
- "markdownDescription": "Denies the scale_factor command without any pre-configured scope."
- },
- {
- "description": "Denies the scene_identifier command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-scene-identifier",
- "markdownDescription": "Denies the scene_identifier command without any pre-configured scope."
- },
- {
- "description": "Denies the set_always_on_bottom command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-always-on-bottom",
- "markdownDescription": "Denies the set_always_on_bottom command without any pre-configured scope."
- },
- {
- "description": "Denies the set_always_on_top command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-always-on-top",
- "markdownDescription": "Denies the set_always_on_top command without any pre-configured scope."
- },
- {
- "description": "Denies the set_background_color command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-background-color",
- "markdownDescription": "Denies the set_background_color command without any pre-configured scope."
- },
- {
- "description": "Denies the set_badge_count command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-badge-count",
- "markdownDescription": "Denies the set_badge_count command without any pre-configured scope."
- },
- {
- "description": "Denies the set_badge_label command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-badge-label",
- "markdownDescription": "Denies the set_badge_label command without any pre-configured scope."
- },
- {
- "description": "Denies the set_closable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-closable",
- "markdownDescription": "Denies the set_closable command without any pre-configured scope."
- },
- {
- "description": "Denies the set_content_protected command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-content-protected",
- "markdownDescription": "Denies the set_content_protected command without any pre-configured scope."
- },
- {
- "description": "Denies the set_cursor_grab command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-cursor-grab",
- "markdownDescription": "Denies the set_cursor_grab command without any pre-configured scope."
- },
- {
- "description": "Denies the set_cursor_icon command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-cursor-icon",
- "markdownDescription": "Denies the set_cursor_icon command without any pre-configured scope."
- },
- {
- "description": "Denies the set_cursor_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-cursor-position",
- "markdownDescription": "Denies the set_cursor_position command without any pre-configured scope."
- },
- {
- "description": "Denies the set_cursor_visible command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-cursor-visible",
- "markdownDescription": "Denies the set_cursor_visible command without any pre-configured scope."
- },
- {
- "description": "Denies the set_decorations command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-decorations",
- "markdownDescription": "Denies the set_decorations command without any pre-configured scope."
- },
- {
- "description": "Denies the set_effects command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-effects",
- "markdownDescription": "Denies the set_effects command without any pre-configured scope."
- },
- {
- "description": "Denies the set_enabled command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-enabled",
- "markdownDescription": "Denies the set_enabled command without any pre-configured scope."
- },
- {
- "description": "Denies the set_focus command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-focus",
- "markdownDescription": "Denies the set_focus command without any pre-configured scope."
- },
- {
- "description": "Denies the set_focusable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-focusable",
- "markdownDescription": "Denies the set_focusable command without any pre-configured scope."
- },
- {
- "description": "Denies the set_fullscreen command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-fullscreen",
- "markdownDescription": "Denies the set_fullscreen command without any pre-configured scope."
- },
- {
- "description": "Denies the set_icon command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-icon",
- "markdownDescription": "Denies the set_icon command without any pre-configured scope."
- },
- {
- "description": "Denies the set_ignore_cursor_events command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-ignore-cursor-events",
- "markdownDescription": "Denies the set_ignore_cursor_events command without any pre-configured scope."
- },
- {
- "description": "Denies the set_max_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-max-size",
- "markdownDescription": "Denies the set_max_size command without any pre-configured scope."
- },
- {
- "description": "Denies the set_maximizable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-maximizable",
- "markdownDescription": "Denies the set_maximizable command without any pre-configured scope."
- },
- {
- "description": "Denies the set_min_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-min-size",
- "markdownDescription": "Denies the set_min_size command without any pre-configured scope."
- },
- {
- "description": "Denies the set_minimizable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-minimizable",
- "markdownDescription": "Denies the set_minimizable command without any pre-configured scope."
- },
- {
- "description": "Denies the set_overlay_icon command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-overlay-icon",
- "markdownDescription": "Denies the set_overlay_icon command without any pre-configured scope."
- },
- {
- "description": "Denies the set_position command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-position",
- "markdownDescription": "Denies the set_position command without any pre-configured scope."
- },
- {
- "description": "Denies the set_progress_bar command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-progress-bar",
- "markdownDescription": "Denies the set_progress_bar command without any pre-configured scope."
- },
- {
- "description": "Denies the set_resizable command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-resizable",
- "markdownDescription": "Denies the set_resizable command without any pre-configured scope."
- },
- {
- "description": "Denies the set_shadow command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-shadow",
- "markdownDescription": "Denies the set_shadow command without any pre-configured scope."
- },
- {
- "description": "Denies the set_simple_fullscreen command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-simple-fullscreen",
- "markdownDescription": "Denies the set_simple_fullscreen command without any pre-configured scope."
- },
- {
- "description": "Denies the set_size command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-size",
- "markdownDescription": "Denies the set_size command without any pre-configured scope."
- },
- {
- "description": "Denies the set_size_constraints command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-size-constraints",
- "markdownDescription": "Denies the set_size_constraints command without any pre-configured scope."
- },
- {
- "description": "Denies the set_skip_taskbar command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-skip-taskbar",
- "markdownDescription": "Denies the set_skip_taskbar command without any pre-configured scope."
- },
- {
- "description": "Denies the set_theme command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-theme",
- "markdownDescription": "Denies the set_theme command without any pre-configured scope."
- },
- {
- "description": "Denies the set_title command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-title",
- "markdownDescription": "Denies the set_title command without any pre-configured scope."
- },
- {
- "description": "Denies the set_title_bar_style command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-title-bar-style",
- "markdownDescription": "Denies the set_title_bar_style command without any pre-configured scope."
- },
- {
- "description": "Denies the set_visible_on_all_workspaces command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-set-visible-on-all-workspaces",
- "markdownDescription": "Denies the set_visible_on_all_workspaces command without any pre-configured scope."
- },
- {
- "description": "Denies the show command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-show",
- "markdownDescription": "Denies the show command without any pre-configured scope."
- },
- {
- "description": "Denies the start_dragging command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-start-dragging",
- "markdownDescription": "Denies the start_dragging command without any pre-configured scope."
- },
- {
- "description": "Denies the start_resize_dragging command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-start-resize-dragging",
- "markdownDescription": "Denies the start_resize_dragging command without any pre-configured scope."
- },
- {
- "description": "Denies the theme command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-theme",
- "markdownDescription": "Denies the theme command without any pre-configured scope."
- },
- {
- "description": "Denies the title command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-title",
- "markdownDescription": "Denies the title command without any pre-configured scope."
- },
- {
- "description": "Denies the toggle_maximize command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-toggle-maximize",
- "markdownDescription": "Denies the toggle_maximize command without any pre-configured scope."
- },
- {
- "description": "Denies the unmaximize command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-unmaximize",
- "markdownDescription": "Denies the unmaximize command without any pre-configured scope."
- },
- {
- "description": "Denies the unminimize command without any pre-configured scope.",
- "type": "string",
- "const": "core:window:deny-unminimize",
- "markdownDescription": "Denies the unminimize command without any pre-configured scope."
- },
- {
- "description": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n\n#### This default permission set includes:\n\n- `allow-message`\n- `allow-save`\n- `allow-open`",
- "type": "string",
- "const": "dialog:default",
- "markdownDescription": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n\n#### This default permission set includes:\n\n- `allow-message`\n- `allow-save`\n- `allow-open`"
- },
- {
- "description": "Enables the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)",
- "type": "string",
- "const": "dialog:allow-ask",
- "markdownDescription": "Enables the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)"
- },
- {
- "description": "Enables the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)",
- "type": "string",
- "const": "dialog:allow-confirm",
- "markdownDescription": "Enables the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)"
- },
- {
- "description": "Enables the message command without any pre-configured scope.",
- "type": "string",
- "const": "dialog:allow-message",
- "markdownDescription": "Enables the message command without any pre-configured scope."
- },
- {
- "description": "Enables the open command without any pre-configured scope.",
- "type": "string",
- "const": "dialog:allow-open",
- "markdownDescription": "Enables the open command without any pre-configured scope."
- },
- {
- "description": "Enables the save command without any pre-configured scope.",
- "type": "string",
- "const": "dialog:allow-save",
- "markdownDescription": "Enables the save command without any pre-configured scope."
- },
- {
- "description": "Denies the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)",
- "type": "string",
- "const": "dialog:deny-ask",
- "markdownDescription": "Denies the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)"
- },
- {
- "description": "Denies the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)",
- "type": "string",
- "const": "dialog:deny-confirm",
- "markdownDescription": "Denies the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)"
- },
- {
- "description": "Denies the message command without any pre-configured scope.",
- "type": "string",
- "const": "dialog:deny-message",
- "markdownDescription": "Denies the message command without any pre-configured scope."
- },
- {
- "description": "Denies the open command without any pre-configured scope.",
- "type": "string",
- "const": "dialog:deny-open",
- "markdownDescription": "Denies the open command without any pre-configured scope."
- },
- {
- "description": "Denies the save command without any pre-configured scope.",
- "type": "string",
- "const": "dialog:deny-save",
- "markdownDescription": "Denies the save command without any pre-configured scope."
- }
- ]
- },
- "Value": {
- "description": "All supported ACL values.",
- "anyOf": [
- {
- "description": "Represents a null JSON value.",
- "type": "null"
- },
- {
- "description": "Represents a [`bool`].",
- "type": "boolean"
- },
- {
- "description": "Represents a valid ACL [`Number`].",
- "allOf": [
- {
- "$ref": "#/definitions/Number"
- }
- ]
- },
- {
- "description": "Represents a [`String`].",
- "type": "string"
- },
- {
- "description": "Represents a list of other [`Value`]s.",
- "type": "array",
- "items": {
- "$ref": "#/definitions/Value"
- }
- },
- {
- "description": "Represents a map of [`String`] keys to [`Value`]s.",
- "type": "object",
- "additionalProperties": {
- "$ref": "#/definitions/Value"
- }
- }
- ]
- },
- "Number": {
- "description": "A valid ACL number.",
- "anyOf": [
- {
- "description": "Represents an [`i64`].",
- "type": "integer",
- "format": "int64"
- },
- {
- "description": "Represents a [`f64`].",
- "type": "number",
- "format": "double"
- }
- ]
- },
- "Target": {
- "description": "Platform target.",
- "oneOf": [
- {
- "description": "MacOS.",
- "type": "string",
- "enum": [
- "macOS"
- ]
- },
- {
- "description": "Windows.",
- "type": "string",
- "enum": [
- "windows"
- ]
- },
- {
- "description": "Linux.",
- "type": "string",
- "enum": [
- "linux"
- ]
- },
- {
- "description": "Android.",
- "type": "string",
- "enum": [
- "android"
- ]
- },
- {
- "description": "iOS.",
- "type": "string",
- "enum": [
- "iOS"
- ]
- }
- ]
- }
- }
-}
\ No newline at end of file
diff --git a/apps/windows-client/src-tauri/icons/128x128.png b/apps/windows-client/src-tauri/icons/128x128.png
deleted file mode 100644
index a565b11..0000000
Binary files a/apps/windows-client/src-tauri/icons/128x128.png and /dev/null differ
diff --git a/apps/windows-client/src-tauri/icons/128x128@2x.png b/apps/windows-client/src-tauri/icons/128x128@2x.png
deleted file mode 100644
index 678a804..0000000
Binary files a/apps/windows-client/src-tauri/icons/128x128@2x.png and /dev/null differ
diff --git a/apps/windows-client/src-tauri/icons/32x32.png b/apps/windows-client/src-tauri/icons/32x32.png
deleted file mode 100644
index 87ba0c5..0000000
Binary files a/apps/windows-client/src-tauri/icons/32x32.png and /dev/null differ
diff --git a/apps/windows-client/src-tauri/icons/icon.ico b/apps/windows-client/src-tauri/icons/icon.ico
deleted file mode 100644
index 6f1424f..0000000
Binary files a/apps/windows-client/src-tauri/icons/icon.ico and /dev/null differ
diff --git a/apps/windows-client/src-tauri/src/activity.rs b/apps/windows-client/src-tauri/src/activity.rs
deleted file mode 100644
index 6c8cc28..0000000
--- a/apps/windows-client/src-tauri/src/activity.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-use crate::models::ActivityEntry;
-
-pub const DEFAULT_ACTIVITY_LIMIT: usize = 200;
-
-pub fn sort_activity_desc(mut entries: Vec) -> Vec {
- entries.sort_by(|left, right| right.at.cmp(&left.at).then_with(|| right.id.cmp(&left.id)));
- entries
-}
-
-pub fn cap_activity(entries: Vec, limit: usize) -> Vec {
- let mut entries = sort_activity_desc(entries);
- entries.truncate(limit);
- entries
-}
-
-pub fn append_activity(
- mut entries: Vec,
- entry: ActivityEntry,
- limit: usize,
-) -> Vec {
- entries.push(entry);
- cap_activity(entries, limit)
-}
diff --git a/apps/windows-client/src-tauri/src/adapters/proxifyre.rs b/apps/windows-client/src-tauri/src/adapters/proxifyre.rs
deleted file mode 100644
index 2839bbc..0000000
--- a/apps/windows-client/src-tauri/src/adapters/proxifyre.rs
+++ /dev/null
@@ -1,245 +0,0 @@
-#[cfg(not(test))]
-use crate::adapters::proxy_router::{
- ProxyRouterAdapter, ProxyRouterError, ProxyRouterErrorKind, ProxyRouterGeneratedConfig,
- ProxyRouterRequest,
-};
-use crate::models::{
- ComponentId, ComponentState, ComponentStatus, Profile, ProfileItemType, Protocol,
- ProxyProtocol, Target,
-};
-#[cfg(test)]
-use crate::proxy_router::{
- ProxyRouterAdapter, ProxyRouterError, ProxyRouterErrorKind, ProxyRouterGeneratedConfig,
- ProxyRouterRequest,
-};
-use serde::{Deserialize, Serialize};
-
-pub const PROXIFYRE_ADAPTER_ID: &str = "proxifyre";
-pub const PROXIFYRE_OUTPUT_FILE: &str = "proxifyre-app-config.json";
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct ProxiFyreAdapter {
- log_level: String,
- bypass_lan: bool,
-}
-
-impl ProxiFyreAdapter {
- pub fn new(log_level: impl Into, bypass_lan: bool) -> Self {
- Self {
- log_level: log_level.into(),
- bypass_lan,
- }
- }
-
- pub fn generate_proxifyre_config(
- &self,
- request: ProxyRouterRequest<'_>,
- ) -> Result {
- let mut proxies = Vec::new();
-
- for profile in request.profiles.iter().filter(|profile| profile.enabled) {
- let target = find_target(profile, request.targets)?;
- ensure_target_supported(profile, target, request.components)?;
-
- let app_names = app_names_for_profile(profile);
- if app_names.is_empty() {
- return Err(ProxyRouterError::new(
- ProxyRouterErrorKind::EmptyProfileItems,
- format!(
- "В профиле '{}' нет приложений для маршрутизации",
- profile.id
- ),
- ));
- }
-
- proxies.push(ProxiFyreProxy {
- app_names,
- socks5_proxy_endpoint: format!("{}:{}", target.host, target.port),
- supported_protocols: protocols_for_profile(profile),
- });
- }
-
- Ok(ProxiFyreConfig {
- log_level: self.log_level.clone(),
- bypass_lan: self.bypass_lan,
- proxies,
- })
- }
-}
-
-impl Default for ProxiFyreAdapter {
- fn default() -> Self {
- Self::new("Info", true)
- }
-}
-
-impl ProxyRouterAdapter for ProxiFyreAdapter {
- fn id(&self) -> &'static str {
- PROXIFYRE_ADAPTER_ID
- }
-
- fn output_file_name(&self) -> &'static str {
- PROXIFYRE_OUTPUT_FILE
- }
-
- fn generate_config(
- &self,
- request: ProxyRouterRequest<'_>,
- ) -> Result {
- let config = self.generate_proxifyre_config(request)?;
- let enabled_profiles = config.proxies.len();
- let routed_apps = config
- .proxies
- .iter()
- .map(|proxy| proxy.app_names.len())
- .sum();
- let contents = serde_json::to_string_pretty(&config).map_err(|error| {
- ProxyRouterError::new(
- ProxyRouterErrorKind::Serialization,
- format!("Не удалось сериализовать конфиг ProxiFyre: {error}"),
- )
- })?;
-
- Ok(ProxyRouterGeneratedConfig {
- adapter_id: self.id().to_string(),
- output_file_name: self.output_file_name().to_string(),
- contents,
- enabled_profiles,
- routed_apps,
- })
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-pub struct ProxiFyreConfig {
- #[serde(rename = "logLevel")]
- pub log_level: String,
- #[serde(rename = "bypassLan")]
- pub bypass_lan: bool,
- pub proxies: Vec,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-pub struct ProxiFyreProxy {
- #[serde(rename = "appNames")]
- pub app_names: Vec,
- #[serde(rename = "socks5ProxyEndpoint")]
- pub socks5_proxy_endpoint: String,
- #[serde(rename = "supportedProtocols")]
- pub supported_protocols: Vec,
-}
-
-fn find_target<'a>(
- profile: &Profile,
- targets: &'a [Target],
-) -> Result<&'a Target, ProxyRouterError> {
- targets
- .iter()
- .find(|target| target.id == profile.target_id)
- .ok_or_else(|| {
- ProxyRouterError::new(
- ProxyRouterErrorKind::MissingTarget,
- format!(
- "Профиль '{}' ссылается на отсутствующую цель '{}'",
- profile.id, profile.target_id
- ),
- )
- })
-}
-
-fn ensure_target_supported(
- profile: &Profile,
- target: &Target,
- components: &[ComponentStatus],
-) -> Result<(), ProxyRouterError> {
- if target.protocol != ProxyProtocol::Socks5 {
- return Err(ProxyRouterError::new(
- ProxyRouterErrorKind::UnsupportedTargetProtocol,
- format!(
- "Цель '{}' использует HTTP, но ProxiFyre требует SOCKS5",
- target.id
- ),
- ));
- }
-
- if let Some(required_component) = &target.requires_component {
- let Some(status) = components
- .iter()
- .find(|component| &component.id == required_component)
- else {
- return Err(ProxyRouterError::new(
- ProxyRouterErrorKind::MissingRequiredComponent,
- format!(
- "Цель '{}' профиля '{}' требует отсутствующий компонент '{}'",
- target.id,
- profile.id,
- component_id_label(required_component)
- ),
- ));
- };
-
- if !component_is_running(status) {
- return Err(ProxyRouterError::new(
- ProxyRouterErrorKind::RequiredComponentNotRunning,
- format!(
- "Цель '{}' профиля '{}' требует запущенный компонент '{}'",
- target.id,
- profile.id,
- component_id_label(required_component)
- ),
- ));
- }
- }
-
- Ok(())
-}
-
-fn component_is_running(status: &ComponentStatus) -> bool {
- status.installed && status.running && status.state == ComponentState::Running
-}
-
-fn app_names_for_profile(profile: &Profile) -> Vec {
- let mut names = Vec::new();
-
- for item in &profile.items {
- let value = item.value.trim();
- if value.is_empty() {
- continue;
- }
-
- let app_name = match item.item_type {
- ProfileItemType::Process | ProfileItemType::Folder | ProfileItemType::Exe => value,
- };
-
- if !names.iter().any(|existing| existing == app_name) {
- names.push(app_name.to_string());
- }
- }
-
- names
-}
-
-fn protocols_for_profile(profile: &Profile) -> Vec {
- let mut protocols = Vec::new();
-
- for protocol in &profile.protocols {
- let value = match protocol {
- Protocol::Tcp => "TCP",
- Protocol::Udp => "UDP",
- };
-
- if !protocols.iter().any(|existing| existing == value) {
- protocols.push(value.to_string());
- }
- }
-
- protocols
-}
-
-fn component_id_label(component_id: &ComponentId) -> &'static str {
- match component_id {
- ComponentId::ControlApp => "control-app",
- ComponentId::Proxyfier => "proxyfier",
- ComponentId::Singbox => "singbox",
- }
-}
diff --git a/apps/windows-client/src-tauri/src/adapters/proxy_router.rs b/apps/windows-client/src-tauri/src/adapters/proxy_router.rs
deleted file mode 100644
index f9e0162..0000000
--- a/apps/windows-client/src-tauri/src/adapters/proxy_router.rs
+++ /dev/null
@@ -1,67 +0,0 @@
-use crate::models::{ComponentStatus, Profile, Target};
-
-#[derive(Debug, Clone, Copy)]
-pub struct ProxyRouterRequest<'a> {
- pub profiles: &'a [Profile],
- pub targets: &'a [Target],
- pub components: &'a [ComponentStatus],
-}
-
-impl<'a> ProxyRouterRequest<'a> {
- pub fn new(
- profiles: &'a [Profile],
- targets: &'a [Target],
- components: &'a [ComponentStatus],
- ) -> Self {
- Self {
- profiles,
- targets,
- components,
- }
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct ProxyRouterGeneratedConfig {
- pub adapter_id: String,
- pub output_file_name: String,
- pub contents: String,
- pub enabled_profiles: usize,
- pub routed_apps: usize,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct ProxyRouterError {
- pub kind: ProxyRouterErrorKind,
- pub message: String,
-}
-
-impl ProxyRouterError {
- pub fn new(kind: ProxyRouterErrorKind, message: impl Into) -> Self {
- Self {
- kind,
- message: message.into(),
- }
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub enum ProxyRouterErrorKind {
- EmptyProfileItems,
- MissingTarget,
- MissingRequiredComponent,
- RequiredComponentNotRunning,
- UnsupportedTargetProtocol,
- Serialization,
-}
-
-pub trait ProxyRouterAdapter {
- fn id(&self) -> &'static str;
-
- fn output_file_name(&self) -> &'static str;
-
- fn generate_config(
- &self,
- request: ProxyRouterRequest<'_>,
- ) -> Result;
-}
diff --git a/apps/windows-client/src-tauri/src/adapters/singbox.rs b/apps/windows-client/src-tauri/src/adapters/singbox.rs
deleted file mode 100644
index 117d3b0..0000000
--- a/apps/windows-client/src-tauri/src/adapters/singbox.rs
+++ /dev/null
@@ -1,338 +0,0 @@
-use crate::models::{LocalSingBoxConfig, SubscriptionCache};
-use serde::{Deserialize, Serialize};
-use serde_json::{json, Value};
-use std::{
- env, fs,
- path::Path,
- process::Command,
- time::{SystemTime, UNIX_EPOCH},
-};
-
-pub const SINGBOX_ADAPTER_ID: &str = "singbox";
-pub const SINGBOX_OUTPUT_FILE: &str = "sing-box-config.json";
-pub const DEFAULT_MIXED_INBOUND_TAG: &str = "vpn-proxy-mixed-in";
-pub const DEFAULT_VPN_OUTBOUND_TAG: &str = "vpn";
-pub const DEFAULT_DIRECT_OUTBOUND_TAG: &str = "direct";
-pub const DEFAULT_BLOCK_OUTBOUND_TAG: &str = "block";
-
-const SUPPORTED_PROXY_TYPES: &[&str] = &["vless", "vmess", "trojan", "shadowsocks", "hysteria2"];
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct SingBoxAdapter {
- log_level: String,
- inbound_tag: String,
- vpn_outbound_tag: String,
-}
-
-impl SingBoxAdapter {
- pub fn new(
- log_level: impl Into,
- inbound_tag: impl Into,
- vpn_outbound_tag: impl Into,
- ) -> Self {
- Self {
- log_level: log_level.into(),
- inbound_tag: inbound_tag.into(),
- vpn_outbound_tag: vpn_outbound_tag.into(),
- }
- }
-
- pub fn generate_config(
- &self,
- request: SingBoxGenerationRequest<'_>,
- checker: &C,
- ) -> Result
- where
- C: SingBoxConfigChecker,
- {
- let selected_server_tag = request
- .config
- .selected_server_tag
- .as_deref()
- .map(str::trim)
- .filter(|value| !value.is_empty())
- .ok_or_else(|| {
- SingBoxConfigError::new(
- SingBoxConfigErrorKind::MissingSelectedServer,
- "Сервер Local sing-box не выбран",
- )
- })?;
- let vpn_outbound = selected_outbound(
- &request.subscription_cache.config,
- selected_server_tag,
- &self.vpn_outbound_tag,
- )?;
- let generated_config = json!({
- "log": {
- "disabled": false,
- "level": self.log_level,
- "timestamp": true
- },
- "inbounds": [
- {
- "type": "mixed",
- "tag": self.inbound_tag,
- "listen": request.config.listen_host,
- "listen_port": request.config.listen_port,
- "users": [],
- "set_system_proxy": false
- }
- ],
- "outbounds": [
- vpn_outbound,
- { "type": "direct", "tag": DEFAULT_DIRECT_OUTBOUND_TAG },
- { "type": "block", "tag": DEFAULT_BLOCK_OUTBOUND_TAG }
- ],
- "route": {
- "rules": [
- { "ip_is_private": true, "outbound": DEFAULT_DIRECT_OUTBOUND_TAG }
- ],
- "final": self.vpn_outbound_tag
- }
- });
- let contents = serde_json::to_string_pretty(&generated_config).map_err(|error| {
- SingBoxConfigError::new(
- SingBoxConfigErrorKind::Serialization,
- format!("Не удалось сериализовать конфиг sing-box: {error}"),
- )
- })?;
- let check = match request.binary_path {
- Some(binary_path) => Some(checker.check_config(binary_path, &contents)?),
- None => None,
- };
-
- Ok(SingBoxGeneratedConfig {
- adapter_id: SINGBOX_ADAPTER_ID.to_string(),
- output_file_name: SINGBOX_OUTPUT_FILE.to_string(),
- contents,
- selected_server_tag: selected_server_tag.to_string(),
- listen: request.config.listen_host.clone(),
- listen_port: request.config.listen_port,
- check,
- })
- }
-}
-
-impl Default for SingBoxAdapter {
- fn default() -> Self {
- Self::new("info", DEFAULT_MIXED_INBOUND_TAG, DEFAULT_VPN_OUTBOUND_TAG)
- }
-}
-
-#[derive(Debug, Clone, Copy)]
-pub struct SingBoxGenerationRequest<'a> {
- pub config: &'a LocalSingBoxConfig,
- pub subscription_cache: &'a SubscriptionCache,
- pub binary_path: Option<&'a Path>,
-}
-
-impl<'a> SingBoxGenerationRequest<'a> {
- pub fn new(
- config: &'a LocalSingBoxConfig,
- subscription_cache: &'a SubscriptionCache,
- binary_path: Option<&'a Path>,
- ) -> Self {
- Self {
- config,
- subscription_cache,
- binary_path,
- }
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct SingBoxGeneratedConfig {
- pub adapter_id: String,
- pub output_file_name: String,
- pub contents: String,
- pub selected_server_tag: String,
- pub listen: String,
- pub listen_port: u16,
- pub check: Option,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-pub struct SingBoxCheckResult {
- pub checked: bool,
- pub success: bool,
- pub message: String,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct SingBoxConfigError {
- pub kind: SingBoxConfigErrorKind,
- pub message: String,
-}
-
-impl SingBoxConfigError {
- pub fn new(kind: SingBoxConfigErrorKind, message: impl Into) -> Self {
- Self {
- kind,
- message: message.into(),
- }
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub enum SingBoxConfigErrorKind {
- MissingSelectedServer,
- MissingSelectedOutbound,
- UnsupportedSelectedOutbound,
- Serialization,
- CheckFailed,
-}
-
-pub trait SingBoxConfigChecker {
- fn check_config(
- &self,
- binary_path: &Path,
- config_json: &str,
- ) -> Result;
-}
-
-#[derive(Debug, Clone, Copy, Default)]
-pub struct SingBoxCommandChecker;
-
-impl SingBoxConfigChecker for SingBoxCommandChecker {
- fn check_config(
- &self,
- binary_path: &Path,
- config_json: &str,
- ) -> Result {
- let config_path = env::temp_dir().join(format!(
- "vpn-proxy-sing-box-{}-{}.json",
- std::process::id(),
- now_millis()
- ));
-
- fs::write(&config_path, config_json).map_err(|error| {
- SingBoxConfigError::new(
- SingBoxConfigErrorKind::CheckFailed,
- format!(
- "Не удалось записать временный конфиг sing-box '{}': {error}",
- config_path.display()
- ),
- )
- })?;
-
- let output = Command::new(binary_path)
- .arg("check")
- .arg("-c")
- .arg(&config_path)
- .output()
- .map_err(|error| {
- let _ = fs::remove_file(&config_path);
- SingBoxConfigError::new(
- SingBoxConfigErrorKind::CheckFailed,
- format!(
- "Не удалось выполнить '{} check': {error}",
- binary_path.display()
- ),
- )
- })?;
- let _ = fs::remove_file(&config_path);
-
- let stdout = String::from_utf8_lossy(&output.stdout);
- let stderr = String::from_utf8_lossy(&output.stderr);
- let message = command_message(&stdout, &stderr);
-
- if !output.status.success() {
- return Err(SingBoxConfigError::new(
- SingBoxConfigErrorKind::CheckFailed,
- format!("Проверка sing-box не прошла: {message}"),
- ));
- }
-
- Ok(SingBoxCheckResult {
- checked: true,
- success: true,
- message: if message.is_empty() {
- "Проверка sing-box прошла успешно".to_string()
- } else {
- message
- },
- })
- }
-}
-
-fn selected_outbound(
- subscription_config: &Value,
- selected_server_tag: &str,
- vpn_outbound_tag: &str,
-) -> Result {
- let outbounds = subscription_config
- .get("outbounds")
- .and_then(Value::as_array)
- .ok_or_else(|| {
- SingBoxConfigError::new(
- SingBoxConfigErrorKind::MissingSelectedOutbound,
- "В cache подписки нет outbounds",
- )
- })?;
- let outbound = outbounds
- .iter()
- .find(|outbound| {
- outbound
- .get("tag")
- .and_then(Value::as_str)
- .is_some_and(|tag| tag.trim() == selected_server_tag)
- })
- .ok_or_else(|| {
- SingBoxConfigError::new(
- SingBoxConfigErrorKind::MissingSelectedOutbound,
- format!("Outbound не найден: {selected_server_tag}"),
- )
- })?;
- let outbound_type = outbound
- .get("type")
- .and_then(Value::as_str)
- .unwrap_or_default();
-
- if !SUPPORTED_PROXY_TYPES.contains(&outbound_type) {
- return Err(SingBoxConfigError::new(
- SingBoxConfigErrorKind::UnsupportedSelectedOutbound,
- format!(
- "Outbound '{selected_server_tag}' имеет неподдерживаемый тип '{outbound_type}'"
- ),
- ));
- }
-
- let mut outbound = outbound.clone();
- let object = outbound.as_object_mut().ok_or_else(|| {
- SingBoxConfigError::new(
- SingBoxConfigErrorKind::UnsupportedSelectedOutbound,
- format!("Outbound '{selected_server_tag}' должен быть JSON-объектом"),
- )
- })?;
- object.insert(
- "tag".to_string(),
- Value::String(vpn_outbound_tag.to_string()),
- );
- if outbound_type == "vless" && !object.contains_key("packet_encoding") {
- object.insert(
- "packet_encoding".to_string(),
- Value::String("xudp".to_string()),
- );
- }
-
- Ok(outbound)
-}
-
-fn now_millis() -> u128 {
- SystemTime::now()
- .duration_since(UNIX_EPOCH)
- .map(|duration| duration.as_millis())
- .unwrap_or_default()
-}
-
-fn command_message(stdout: &str, stderr: &str) -> String {
- let stdout = stdout.trim();
- let stderr = stderr.trim();
-
- match (stdout.is_empty(), stderr.is_empty()) {
- (true, true) => String::new(),
- (false, true) => stdout.to_string(),
- (true, false) => stderr.to_string(),
- (false, false) => format!("{stdout}\n{stderr}"),
- }
-}
diff --git a/apps/windows-client/src-tauri/src/commands.rs b/apps/windows-client/src-tauri/src/commands.rs
deleted file mode 100644
index cafabfd..0000000
--- a/apps/windows-client/src-tauri/src/commands.rs
+++ /dev/null
@@ -1,3530 +0,0 @@
-#[cfg(not(test))]
-use crate::adapters::proxifyre::ProxiFyreAdapter;
-#[cfg(not(test))]
-use crate::adapters::proxy_router::{
- ProxyRouterAdapter, ProxyRouterError, ProxyRouterErrorKind, ProxyRouterGeneratedConfig,
- ProxyRouterRequest,
-};
-#[cfg(not(test))]
-use crate::adapters::singbox::{
- SingBoxAdapter, SingBoxCheckResult, SingBoxCommandChecker, SingBoxConfigChecker,
- SingBoxConfigError, SingBoxConfigErrorKind, SingBoxGeneratedConfig, SingBoxGenerationRequest,
-};
-use crate::component_detection::{
- detect_proxyfier_install, detect_proxyfier_install_with_host, detect_singbox_install,
- proxyfier_component_from_detection, singbox_component_from_detection, DetectedProxyfier,
- DetectedSingBox, ProxyfierDetectionHost, SystemProxyfierDetectionHost,
-};
-use crate::models::{
- ActivityEntry, ActivityLevel, ComponentId, ComponentState, ComponentStatus, LocalSingBoxConfig,
- Profile, ProfileInput, ProfileItem, ProfileItemInput, ProfileItemType, Protocol, ProxyProtocol,
- SubscriptionCache, SubscriptionServer, Target, TargetInput, TargetKind,
-};
-#[cfg(test)]
-use crate::proxifyre::ProxiFyreAdapter;
-#[cfg(test)]
-use crate::proxy_router::{
- ProxyRouterAdapter, ProxyRouterError, ProxyRouterErrorKind, ProxyRouterGeneratedConfig,
- ProxyRouterRequest,
-};
-#[cfg(test)]
-use crate::singbox::{
- SingBoxAdapter, SingBoxCheckResult, SingBoxCommandChecker, SingBoxConfigChecker,
- SingBoxConfigError, SingBoxConfigErrorKind, SingBoxGeneratedConfig, SingBoxGenerationRequest,
-};
-use crate::singbox_service::{
- build_singbox_setup_status, ensure_safe_singbox_install_dir,
- parse_service_command_output as parse_singbox_service_command_output, service_control_script,
- ServiceCommandOutput as SingBoxServiceCommandOutput, SingBoxServiceAction, SingBoxSetupStatus,
-};
-use crate::storage::{default_config_root, JsonStorage};
-use crate::subscription;
-use crate::validation::{normalize_profile, normalize_target, ValidationError};
-use serde::{Deserialize, Serialize};
-use std::env;
-use std::fs;
-use std::net::{IpAddr, TcpStream, ToSocketAddrs, UdpSocket};
-use std::path::{Path, PathBuf};
-use std::process::{Command, Output};
-use std::time::{Duration, Instant};
-use std::time::{SystemTime, UNIX_EPOCH};
-
-const PROXIFYRE_INSTALL_DIR: &str = r"C:\Tools\ProxiFyre";
-const PROXIFYRE_RELEASE_API_URL: &str =
- "https://api.github.com/repos/wiresock/proxifyre/releases/latest";
-const NDISAPI_RELEASE_API_URL: &str =
- "https://api.github.com/repos/wiresock/ndisapi/releases/latest";
-const VC_REDIST_X64_URL: &str = "https://aka.ms/vc14/vc_redist.x64.exe";
-const VC_REDIST_X86_URL: &str = "https://aka.ms/vc14/vc_redist.x86.exe";
-
-#[derive(Debug, Clone)]
-pub struct CommandState {
- root: PathBuf,
-}
-
-impl CommandState {
- pub fn new(root: impl Into) -> Self {
- Self { root: root.into() }
- }
-
- pub fn storage(&self) -> JsonStorage {
- JsonStorage::new(self.root.clone())
- }
-}
-
-impl Default for CommandState {
- fn default() -> Self {
- Self::new(default_config_root())
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct CommandError {
- pub code: String,
- pub message: String,
- #[serde(default)]
- pub details: Vec,
-}
-
-impl CommandError {
- fn new(code: impl Into, message: impl Into) -> Self {
- Self {
- code: code.into(),
- message: message.into(),
- details: Vec::new(),
- }
- }
-
- fn with_details(
- code: impl Into,
- message: impl Into,
- details: Vec,
- ) -> Self {
- Self {
- code: code.into(),
- message: message.into(),
- details,
- }
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct ValidationIssue {
- pub field: String,
- pub message: String,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct StatusResponse {
- pub route_line: String,
- pub active_profile_count: usize,
- pub routed_app_count: usize,
- pub active_target: Option,
- pub components: Vec,
- pub recent_activity: Vec,
- pub generated_config_path: String,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct SavedStateResponse {
- pub profiles: Vec,
- pub targets: Vec,
- pub generated_config_path: String,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct ProxiFyreSetupStatusDto {
- pub ready: bool,
- pub missing_count: usize,
- pub items: Vec,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct ProxiFyreSetupItemDto {
- pub id: String,
- pub name: String,
- pub installed: bool,
- pub version: Option,
- pub details: String,
-}
-
-pub type SingBoxSetupStatusDto = SingBoxSetupStatus;
-
-#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct LocalSingBoxStatusResponse {
- pub config: LocalSingBoxConfigDto,
- pub cache: Option,
- pub component: ComponentStatusDto,
- pub generated_config_path: String,
- pub lan_listen_host: Option,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct LocalSingBoxConfigDto {
- pub subscription_display_url: Option,
- pub has_subscription: bool,
- pub selected_server_tag: Option,
- pub listen_host: String,
- pub listen_port: u16,
- pub service_name: String,
- pub install_root: String,
- pub updated_at: Option,
-}
-
-#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct SubscriptionCacheDto {
- pub servers: Vec,
- pub user_info: serde_json::Map,
- pub fetched_at: String,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct SubscriptionServerDto {
- pub tag: String,
- #[serde(rename = "type")]
- pub server_type: String,
- pub server: String,
- pub server_port: u16,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct SaveSingBoxSubscriptionInputDto {
- pub subscription_url: String,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct SelectSingBoxServerInputDto {
- pub tag: String,
- #[serde(default)]
- pub server: Option,
- #[serde(default)]
- pub server_port: Option,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct PingSingBoxServerInputDto {
- pub tag: String,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct PingProxyTargetInputDto {
- pub host: String,
- pub port: u16,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct PingServerResponse {
- pub tag: String,
- pub server: String,
- pub server_port: u16,
- pub ok: bool,
- pub latency: Option,
- pub error: Option,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct GenerateSingBoxConfigResponse {
- pub success: bool,
- pub message: String,
- pub adapter_id: String,
- pub generated_config_path: String,
- pub selected_server_tag: String,
- pub listen_host: String,
- pub listen_port: u16,
- pub check: Option,
- pub activity: ActivityEntryDto,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct ProfileInputDto {
- pub id: Option,
- pub name: String,
- #[serde(default)]
- pub enabled: Option,
- #[serde(default)]
- pub target_id: Option,
- #[serde(default)]
- pub protocols: Option>,
- #[serde(default)]
- pub items: Option>,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-pub struct ProfileItemInputDto {
- #[serde(rename = "type")]
- pub item_type: String,
- pub value: String,
- #[serde(default)]
- pub recursive: Option,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct TargetInputDto {
- pub id: Option,
- pub name: String,
- #[serde(default)]
- pub kind: Option,
- #[serde(default)]
- pub protocol: Option,
- pub host: String,
- pub port: u32,
- #[serde(default)]
- pub requires_component: Option,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct ProfileDto {
- pub id: String,
- pub name: String,
- pub enabled: bool,
- pub target_id: String,
- pub protocols: Vec,
- pub items: Vec,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-pub struct ProfileItemDto {
- #[serde(rename = "type")]
- pub item_type: ProfileItemType,
- pub value: String,
- pub recursive: bool,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct TargetDto {
- pub id: String,
- pub name: String,
- pub kind: TargetKind,
- pub protocol: ProxyProtocol,
- pub host: String,
- pub port: u16,
- #[serde(skip_serializing_if = "Option::is_none")]
- pub requires_component: Option,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct ComponentStatusDto {
- pub id: ComponentId,
- pub name: String,
- pub state: ComponentState,
- pub installed: bool,
- pub running: bool,
- #[serde(skip_serializing_if = "Option::is_none")]
- pub version: Option,
- #[serde(skip_serializing_if = "Option::is_none")]
- pub path: Option,
- pub problems: Vec,
- pub actions: Vec,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct ActivityEntryDto {
- pub id: String,
- pub at: String,
- pub level: ActivityLevel,
- pub title: String,
- pub message: String,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct ResolveProfilePreviewResponse {
- pub profile_id: String,
- pub apps: Vec,
- pub warnings: Vec,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct ResolvedAppDto {
- pub source_type: ProfileItemType,
- pub source_value: String,
- pub app_name: String,
- pub notes: Vec,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct ApplyProfilesResponse {
- pub success: bool,
- pub changed: bool,
- pub message: String,
- pub adapter_id: String,
- pub generated_config_path: String,
- pub enabled_profiles: usize,
- pub routed_apps: usize,
- pub helper: HelperApplyResult,
- pub activity: ActivityEntryDto,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct HelperApplyResult {
- pub success: bool,
- pub changed: bool,
- pub action: String,
- pub message: String,
-}
-
-pub struct HelperApplyRequest<'a> {
- pub adapter_id: &'a str,
- pub config_path: &'a Path,
- pub config_contents: &'a str,
-}
-
-pub trait ProxyApplyHelper {
- fn apply_proxy_config(
- &self,
- request: HelperApplyRequest<'_>,
- ) -> Result;
-}
-
-pub trait SubscriptionFetcher {
- fn fetch_subscription(
- &self,
- url: &str,
- ) -> Result;
-}
-
-pub struct SystemSubscriptionFetcher;
-
-impl SubscriptionFetcher for SystemSubscriptionFetcher {
- fn fetch_subscription(
- &self,
- url: &str,
- ) -> Result {
- subscription::fetch_subscription(url)
- }
-}
-
-pub trait Clock {
- fn now(&self) -> String;
-}
-
-pub struct SystemClock;
-
-impl Clock for SystemClock {
- fn now(&self) -> String {
- let seconds = SystemTime::now()
- .duration_since(UNIX_EPOCH)
- .map(|duration| duration.as_secs())
- .unwrap_or(0);
- format!("unix:{seconds}")
- }
-}
-
-pub struct StagedApplyHelper;
-
-impl ProxyApplyHelper for StagedApplyHelper {
- fn apply_proxy_config(
- &self,
- request: HelperApplyRequest<'_>,
- ) -> Result {
- Ok(HelperApplyResult {
- success: true,
- changed: true,
- action: format!("{}.stage-generated-config", request.adapter_id),
- message: format!(
- "Сгенерированный конфиг подготовлен в {}; интеграция привилегированного помощника еще не подключена",
- request.config_path.display()
- ),
- })
- }
-}
-
-pub struct DetectedProxyApplyHelper {
- host: H,
-}
-
-impl DetectedProxyApplyHelper {
- pub fn system() -> Self {
- Self {
- host: SystemProxyfierDetectionHost,
- }
- }
-}
-
-impl DetectedProxyApplyHelper {
- pub fn new(host: H) -> Self {
- Self { host }
- }
-}
-
-impl ProxyApplyHelper for DetectedProxyApplyHelper
-where
- H: ProxyfierDetectionHost,
-{
- fn apply_proxy_config(
- &self,
- request: HelperApplyRequest<'_>,
- ) -> Result {
- let Some(detected) = detect_proxyfier_install_with_host(&self.host) else {
- return staged_apply_result(request);
- };
-
- apply_to_detected_proxyfier(request, &detected)
- }
-}
-
-#[tauri::command]
-pub async fn get_status(
- state: tauri::State<'_, CommandState>,
-) -> Result {
- let storage = state.storage();
- tauri::async_runtime::spawn_blocking(move || build_status(&storage))
- .await
- .map_err(background_task_error)?
-}
-
-#[tauri::command]
-pub fn get_saved_state(
- state: tauri::State<'_, CommandState>,
-) -> Result {
- read_saved_state(&state.storage())
-}
-
-#[tauri::command]
-pub fn get_profiles(
- state: tauri::State<'_, CommandState>,
-) -> Result, CommandError> {
- read_profiles(&state.storage())
-}
-
-#[tauri::command]
-pub fn save_profile(
- state: tauri::State<'_, CommandState>,
- input: ProfileInputDto,
-) -> Result {
- save_profile_to_storage(&state.storage(), input)
-}
-
-#[tauri::command]
-pub fn get_targets(state: tauri::State<'_, CommandState>) -> Result, CommandError> {
- read_targets(&state.storage())
-}
-
-#[tauri::command]
-pub fn save_target(
- state: tauri::State<'_, CommandState>,
- input: TargetInputDto,
-) -> Result {
- save_target_to_storage(&state.storage(), input)
-}
-
-#[tauri::command]
-pub async fn get_components(
- state: tauri::State<'_, CommandState>,
-) -> Result, CommandError> {
- let storage = state.storage();
- tauri::async_runtime::spawn_blocking(move || read_components(&storage))
- .await
- .map_err(background_task_error)?
-}
-
-#[tauri::command]
-pub async fn get_proxifyre_setup_status() -> Result {
- tauri::async_runtime::spawn_blocking(build_proxifyre_setup_status)
- .await
- .map_err(background_task_error)
-}
-
-#[tauri::command]
-pub async fn get_singbox_status(
- state: tauri::State<'_, CommandState>,
-) -> Result {
- let storage = state.storage();
- tauri::async_runtime::spawn_blocking(move || read_singbox_status(&storage))
- .await
- .map_err(background_task_error)?
-}
-
-#[tauri::command]
-pub async fn get_singbox_setup_status() -> Result {
- tauri::async_runtime::spawn_blocking(|| {
- build_singbox_setup_status(detect_singbox_install().as_ref())
- })
- .await
- .map_err(background_task_error)
-}
-
-#[tauri::command]
-pub fn resolve_profile_preview(
- input: ProfileInputDto,
-) -> Result {
- resolve_preview(input)
-}
-
-#[tauri::command]
-pub fn save_singbox_subscription(
- state: tauri::State<'_, CommandState>,
- input: SaveSingBoxSubscriptionInputDto,
-) -> Result {
- save_singbox_subscription_to_storage(&state.storage(), input, &SystemClock)
-}
-
-#[tauri::command]
-pub async fn fetch_singbox_subscription(
- state: tauri::State<'_, CommandState>,
-) -> Result {
- let storage = state.storage();
- tauri::async_runtime::spawn_blocking(move || {
- fetch_singbox_subscription_with_fetcher(&storage, &SystemSubscriptionFetcher, &SystemClock)
- })
- .await
- .map_err(background_task_error)?
-}
-
-#[tauri::command]
-pub fn forget_singbox_subscription(
- state: tauri::State<'_, CommandState>,
-) -> Result {
- forget_singbox_subscription_in_storage(&state.storage(), &SystemClock)
-}
-
-#[tauri::command]
-pub fn select_singbox_server(
- state: tauri::State<'_, CommandState>,
- input: SelectSingBoxServerInputDto,
-) -> Result {
- select_singbox_server_in_storage(&state.storage(), input, &SystemClock)
-}
-
-#[tauri::command]
-pub fn ping_singbox_server(
- state: tauri::State<'_, CommandState>,
- input: PingSingBoxServerInputDto,
-) -> Result {
- ping_singbox_server_in_storage(&state.storage(), input)
-}
-
-#[tauri::command]
-pub fn ping_all_singbox_servers(
- state: tauri::State<'_, CommandState>,
-) -> Result, CommandError> {
- ping_all_singbox_servers_in_storage(&state.storage())
-}
-
-#[tauri::command]
-pub fn ping_proxy_target(input: PingProxyTargetInputDto) -> Result {
- ping_proxy_target_endpoint(input)
-}
-
-#[tauri::command]
-pub fn generate_singbox_config(
- state: tauri::State<'_, CommandState>,
-) -> Result {
- let detected = detect_singbox_install();
- let binary_path = detected
- .as_ref()
- .map(|detected| detected.executable_path.as_path());
- generate_singbox_config_with_services(
- &state.storage(),
- &SingBoxAdapter::default(),
- &SingBoxCommandChecker,
- &SystemClock,
- binary_path,
- )
-}
-
-#[tauri::command]
-pub fn apply_profiles(
- state: tauri::State<'_, CommandState>,
-) -> Result {
- let storage = state.storage();
- let adapter = ProxiFyreAdapter::default();
- let helper = DetectedProxyApplyHelper::system();
- let clock = SystemClock;
-
- apply_profiles_with_services(&storage, &adapter, &helper, &clock)
-}
-
-#[tauri::command]
-pub fn get_logs(
- state: tauri::State<'_, CommandState>,
-) -> Result, CommandError> {
- read_activity(&state.storage())
-}
-
-#[tauri::command]
-pub fn open_config_location(state: tauri::State<'_, CommandState>) -> Result {
- let storage = state.storage();
- let generated_path = storage
- .paths()
- .generated_dir
- .join("proxifyre-app-config.json");
- let config_path = detect_proxyfier_install()
- .and_then(|detected| detected.config_path)
- .filter(|path| path.exists())
- .or_else(|| generated_path.exists().then_some(generated_path.clone()));
-
- let Some(config_path) = config_path else {
- return open_folder(&storage.paths().generated_dir);
- };
-
- open_file_or_select(&config_path)?;
- Ok(config_path.display().to_string())
-}
-
-#[tauri::command]
-pub async fn start_proxifyre_service() -> Result {
- tauri::async_runtime::spawn_blocking(|| control_proxifyre_service(ServiceControlAction::Start))
- .await
- .map_err(background_task_error)?
-}
-
-#[tauri::command]
-pub async fn stop_proxifyre_service() -> Result {
- tauri::async_runtime::spawn_blocking(|| control_proxifyre_service(ServiceControlAction::Stop))
- .await
- .map_err(background_task_error)?
-}
-
-#[tauri::command]
-pub async fn install_proxifyre(
- state: tauri::State<'_, CommandState>,
-) -> Result {
- let storage = state.storage();
- tauri::async_runtime::spawn_blocking(move || install_proxifyre_component(&storage))
- .await
- .map_err(background_task_error)?
-}
-
-#[tauri::command]
-pub async fn uninstall_proxifyre() -> Result {
- tauri::async_runtime::spawn_blocking(uninstall_proxifyre_component)
- .await
- .map_err(background_task_error)?
-}
-
-#[tauri::command]
-pub async fn start_singbox_service(
- state: tauri::State<'_, CommandState>,
-) -> Result {
- let storage = state.storage();
- tauri::async_runtime::spawn_blocking(move || {
- let detected = detect_singbox_install();
- let binary_path = detected
- .as_ref()
- .map(|detected| detected.executable_path.as_path());
- let generated = generate_singbox_config_with_services(
- &storage,
- &SingBoxAdapter::default(),
- &SingBoxCommandChecker,
- &SystemClock,
- binary_path,
- )?;
- let generated_path = PathBuf::from(generated.generated_config_path);
- control_singbox_service(SingBoxServiceAction::Start, Some(generated_path.as_path()))
- })
- .await
- .map_err(background_task_error)?
-}
-
-#[tauri::command]
-pub async fn stop_singbox_service() -> Result {
- tauri::async_runtime::spawn_blocking(|| control_singbox_service(SingBoxServiceAction::Stop, None))
- .await
- .map_err(background_task_error)?
-}
-
-#[tauri::command]
-pub async fn install_singbox(
- state: tauri::State<'_, CommandState>,
-) -> Result {
- let storage = state.storage();
- tauri::async_runtime::spawn_blocking(move || install_singbox_component(&storage))
- .await
- .map_err(background_task_error)?
-}
-
-#[tauri::command]
-pub async fn uninstall_singbox() -> Result {
- tauri::async_runtime::spawn_blocking(uninstall_singbox_component)
- .await
- .map_err(background_task_error)?
-}
-
-pub fn build_status(storage: &JsonStorage) -> Result {
- let profiles = storage.read_profiles().map_err(storage_error)?;
- let targets = storage.read_targets().map_err(storage_error)?;
- let components = components_or_defaults(storage)?;
- let activity = storage.read_activity().map_err(storage_error)?;
- let active_profile_count = profiles.iter().filter(|profile| profile.enabled).count();
- let routed_app_count = profiles
- .iter()
- .filter(|profile| profile.enabled)
- .map(|profile| profile.items.len())
- .sum();
- let active_target = profiles
- .iter()
- .find(|profile| profile.enabled)
- .and_then(|profile| targets.iter().find(|target| target.id == profile.target_id));
- let route_line = route_line(active_target);
-
- Ok(StatusResponse {
- route_line,
- active_profile_count,
- routed_app_count,
- active_target: active_target.map(TargetDto::from),
- components: components.iter().map(ComponentStatusDto::from).collect(),
- recent_activity: activity
- .iter()
- .take(10)
- .map(ActivityEntryDto::from)
- .collect(),
- generated_config_path: storage
- .paths()
- .generated_dir
- .join("proxifyre-app-config.json")
- .display()
- .to_string(),
- })
-}
-
-pub fn read_profiles(storage: &JsonStorage) -> Result, CommandError> {
- storage
- .read_profiles()
- .map_err(storage_error)
- .map(|profiles| profiles.iter().map(ProfileDto::from).collect())
-}
-
-pub fn save_profile_to_storage(
- storage: &JsonStorage,
- input: ProfileInputDto,
-) -> Result {
- let profile = normalize_profile(input.into()).map_err(validation_error)?;
- let mut profiles = storage.read_profiles().map_err(storage_error)?;
-
- match profiles
- .iter()
- .position(|existing| existing.id == profile.id)
- {
- Some(index) => profiles[index] = profile.clone(),
- None => profiles.push(profile.clone()),
- }
-
- storage.write_profiles(&profiles).map_err(storage_error)?;
- Ok(ProfileDto::from(&profile))
-}
-
-pub fn read_targets(storage: &JsonStorage) -> Result, CommandError> {
- storage
- .read_targets()
- .map_err(storage_error)
- .map(|targets| targets.iter().map(TargetDto::from).collect())
-}
-
-pub fn save_target_to_storage(
- storage: &JsonStorage,
- input: TargetInputDto,
-) -> Result {
- let target = normalize_target(input.into()).map_err(validation_error)?;
- let mut targets = storage.read_targets().map_err(storage_error)?;
-
- match targets.iter().position(|existing| existing.id == target.id) {
- Some(index) => targets[index] = target.clone(),
- None => targets.push(target.clone()),
- }
-
- storage.write_targets(&targets).map_err(storage_error)?;
- Ok(TargetDto::from(&target))
-}
-
-pub fn read_components(storage: &JsonStorage) -> Result, CommandError> {
- components_or_defaults(storage).map(|components| {
- components
- .iter()
- .map(ComponentStatusDto::from)
- .collect::>()
- })
-}
-
-pub fn read_activity(storage: &JsonStorage) -> Result, CommandError> {
- storage
- .read_activity()
- .map_err(storage_error)
- .map(|entries| entries.iter().map(ActivityEntryDto::from).collect())
-}
-
-pub fn read_saved_state(storage: &JsonStorage) -> Result {
- Ok(SavedStateResponse {
- profiles: read_profiles(storage)?,
- targets: read_targets(storage)?,
- generated_config_path: storage
- .paths()
- .generated_dir
- .join("proxifyre-app-config.json")
- .display()
- .to_string(),
- })
-}
-
-pub fn resolve_preview(
- input: ProfileInputDto,
-) -> Result {
- let profile = normalize_profile(input.into()).map_err(validation_error)?;
- let mut warnings = Vec::new();
- let apps = profile
- .items
- .iter()
- .map(|item| resolved_app(item, &mut warnings))
- .collect();
-
- Ok(ResolveProfilePreviewResponse {
- profile_id: profile.id,
- apps,
- warnings,
- })
-}
-
-pub fn apply_profiles_with_services(
- storage: &JsonStorage,
- adapter: &impl ProxyRouterAdapter,
- helper: &impl ProxyApplyHelper,
- clock: &impl Clock,
-) -> Result {
- let profiles = storage.read_profiles().map_err(storage_error)?;
- let targets = storage.read_targets().map_err(storage_error)?;
- let components = components_or_defaults(storage)?;
- let generated =
- match adapter.generate_config(ProxyRouterRequest::new(&profiles, &targets, &components)) {
- Ok(generated) => generated,
- Err(error) => {
- let command_error = adapter_error(error);
- let activity = activity_for_apply_error(clock, &command_error);
- storage.append_activity(activity).map_err(storage_error)?;
- return Err(command_error);
- }
- };
-
- let generated_path = storage
- .paths()
- .generated_dir
- .join(generated.output_file_name.as_str());
- write_generated_config(&generated_path, &generated.contents)?;
-
- let helper_result = helper.apply_proxy_config(HelperApplyRequest {
- adapter_id: generated.adapter_id.as_str(),
- config_path: &generated_path,
- config_contents: generated.contents.as_str(),
- })?;
-
- let activity = activity_for_apply(clock, &generated, &generated_path, &helper_result);
- storage
- .append_activity(activity.clone())
- .map_err(storage_error)?;
-
- Ok(ApplyProfilesResponse {
- success: helper_result.success,
- changed: helper_result.changed,
- message: helper_result.message.clone(),
- adapter_id: generated.adapter_id,
- generated_config_path: generated_path.display().to_string(),
- enabled_profiles: generated.enabled_profiles,
- routed_apps: generated.routed_apps,
- helper: helper_result,
- activity: ActivityEntryDto::from(&activity),
- })
-}
-
-pub fn read_singbox_status(
- storage: &JsonStorage,
-) -> Result {
- let config = storage.read_local_singbox_config().map_err(storage_error)?;
- let cache = storage
- .read_singbox_subscription_cache()
- .map_err(storage_error)?;
- let detected = detect_singbox_install();
- let component = singbox_component_from_detection(detected.as_ref());
-
- Ok(LocalSingBoxStatusResponse {
- config: LocalSingBoxConfigDto::from(&config),
- cache: cache.as_ref().map(SubscriptionCacheDto::from),
- component: ComponentStatusDto::from(&component),
- generated_config_path: storage
- .paths()
- .generated_dir
- .join("sing-box-config.json")
- .display()
- .to_string(),
- lan_listen_host: local_lan_ipv4(),
- })
-}
-
-pub fn save_singbox_subscription_to_storage(
- storage: &JsonStorage,
- input: SaveSingBoxSubscriptionInputDto,
- clock: &impl Clock,
-) -> Result {
- let subscription_url = input.subscription_url.trim().to_string();
- validate_subscription_url(&subscription_url)?;
-
- let mut config = storage.read_local_singbox_config().map_err(storage_error)?;
- config.subscription_url = Some(subscription_url);
- config.updated_at = Some(clock.now());
- storage
- .write_local_singbox_config(&config)
- .map_err(storage_error)?;
-
- read_singbox_status(storage)
-}
-
-pub fn fetch_singbox_subscription_with_fetcher(
- storage: &JsonStorage,
- fetcher: &impl SubscriptionFetcher,
- clock: &impl Clock,
-) -> Result {
- let mut config = storage.read_local_singbox_config().map_err(storage_error)?;
- let subscription_url = config
- .subscription_url
- .as_deref()
- .map(str::trim)
- .filter(|value| !value.is_empty())
- .map(str::to_string)
- .ok_or_else(|| {
- CommandError::new(
- "singbox_subscription_missing",
- "Ссылка на подписку Local sing-box не сохранена.",
- )
- })?;
-
- let cache = fetcher
- .fetch_subscription(&subscription_url)
- .map_err(|error| CommandError::new("singbox_subscription_fetch_failed", error.message))?;
- let selected_tag = config
- .selected_server_tag
- .as_deref()
- .filter(|tag| cache.servers.iter().any(|server| server.tag == *tag))
- .map(str::to_string)
- .or_else(|| cache.servers.first().map(|server| server.tag.clone()));
-
- config.selected_server_tag = selected_tag;
- config.updated_at = Some(clock.now());
- storage
- .write_singbox_subscription_cache(&cache)
- .map_err(storage_error)?;
- storage
- .write_local_singbox_config(&config)
- .map_err(storage_error)?;
- storage
- .append_activity(ActivityEntry {
- id: "singbox-subscription-fetched".to_string(),
- at: clock.now(),
- level: ActivityLevel::Success,
- title: "Подписка Local sing-box обновлена".to_string(),
- message: format!("Серверов найдено: {}", cache.servers.len()),
- })
- .map_err(storage_error)?;
-
- read_singbox_status(storage)
-}
-
-pub fn forget_singbox_subscription_in_storage(
- storage: &JsonStorage,
- clock: &impl Clock,
-) -> Result {
- let mut config = storage.read_local_singbox_config().map_err(storage_error)?;
- config.subscription_url = None;
- config.selected_server_tag = None;
- config.updated_at = Some(clock.now());
- storage
- .write_local_singbox_config(&config)
- .map_err(storage_error)?;
- storage
- .remove_singbox_subscription_cache()
- .map_err(storage_error)?;
-
- read_singbox_status(storage)
-}
-
-pub fn select_singbox_server_in_storage(
- storage: &JsonStorage,
- input: SelectSingBoxServerInputDto,
- clock: &impl Clock,
-) -> Result {
- let requested_tag = input.tag.trim().to_string();
- if requested_tag.is_empty() {
- return Err(CommandError::new(
- "singbox_server_tag_missing",
- "Сервер Local sing-box не выбран.",
- ));
- }
-
- let cache = storage
- .read_singbox_subscription_cache()
- .map_err(storage_error)?
- .ok_or_else(|| {
- CommandError::new(
- "singbox_subscription_cache_missing",
- "Сначала нужно загрузить подписку Local sing-box.",
- )
- })?;
- let Some(server) = find_subscription_server(
- &cache,
- &requested_tag,
- input.server.as_deref(),
- input.server_port,
- ) else {
- return Err(CommandError::new(
- "singbox_server_not_found",
- format!("Сервер Local sing-box '{requested_tag}' не найден в текущей подписке."),
- ));
- };
- let selected_tag = server.tag.clone();
-
- let mut config = storage.read_local_singbox_config().map_err(storage_error)?;
- config.selected_server_tag = Some(selected_tag);
- config.updated_at = Some(clock.now());
- storage
- .write_local_singbox_config(&config)
- .map_err(storage_error)?;
-
- read_singbox_status(storage)
-}
-
-pub fn ping_singbox_server_in_storage(
- storage: &JsonStorage,
- input: PingSingBoxServerInputDto,
-) -> Result {
- let tag = input.tag.trim();
- let cache = read_required_singbox_cache(storage)?;
- let server = find_subscription_server(&cache, tag, None, None).ok_or_else(|| {
- CommandError::new(
- "singbox_server_not_found",
- format!("Сервер Local sing-box '{tag}' не найден в текущей подписке."),
- )
- })?;
-
- Ok(ping_subscription_server(server))
-}
-
-pub fn ping_all_singbox_servers_in_storage(
- storage: &JsonStorage,
-) -> Result, CommandError> {
- let cache = read_required_singbox_cache(storage)?;
- Ok(cache.servers.iter().map(ping_subscription_server).collect())
-}
-
-pub fn ping_proxy_target_endpoint(
- input: PingProxyTargetInputDto,
-) -> Result {
- let host = input.host.trim();
- if host.is_empty() {
- return Err(CommandError::new(
- "proxy_target_host_missing",
- "Хост внешнего прокси не указан.",
- ));
- }
-
- Ok(ping_endpoint("external-proxy", host, input.port))
-}
-
-pub fn generate_singbox_config_with_services(
- storage: &JsonStorage,
- adapter: &SingBoxAdapter,
- checker: &C,
- clock: &impl Clock,
- binary_path: Option<&Path>,
-) -> Result
-where
- C: SingBoxConfigChecker,
-{
- let config = storage.read_local_singbox_config().map_err(storage_error)?;
- let cache = read_required_singbox_cache(storage)?;
- let generated = adapter
- .generate_config(
- SingBoxGenerationRequest::new(&config, &cache, binary_path),
- checker,
- )
- .map_err(singbox_adapter_error)?;
- let generated_path = storage
- .paths()
- .generated_dir
- .join(generated.output_file_name.as_str());
-
- write_generated_config(&generated_path, &generated.contents)?;
- ensure_local_singbox_target(storage, &config)?;
-
- let activity = activity_for_singbox_generate(clock, &generated, &generated_path);
- storage
- .append_activity(activity.clone())
- .map_err(storage_error)?;
-
- Ok(GenerateSingBoxConfigResponse {
- success: true,
- message: "Конфиг Local sing-box создан".to_string(),
- adapter_id: generated.adapter_id,
- generated_config_path: generated_path.display().to_string(),
- selected_server_tag: generated.selected_server_tag,
- listen_host: generated.listen,
- listen_port: generated.listen_port,
- check: generated.check,
- activity: ActivityEntryDto::from(&activity),
- })
-}
-
-fn read_required_singbox_cache(storage: &JsonStorage) -> Result {
- storage
- .read_singbox_subscription_cache()
- .map_err(storage_error)?
- .ok_or_else(|| {
- CommandError::new(
- "singbox_subscription_cache_missing",
- "Сначала нужно загрузить подписку Local sing-box.",
- )
- })
-}
-
-fn validate_subscription_url(subscription_url: &str) -> Result<(), CommandError> {
- if subscription_url.is_empty() {
- return Err(CommandError::new(
- "singbox_subscription_url_missing",
- "Ссылка на подписку Local sing-box не указана.",
- ));
- }
-
- let parsed = url::Url::parse(subscription_url).map_err(|_| {
- CommandError::new(
- "singbox_subscription_url_invalid",
- "Ссылка на подписку Local sing-box должна быть корректным URL.",
- )
- })?;
- if !matches!(parsed.scheme(), "http" | "https") {
- return Err(CommandError::new(
- "singbox_subscription_url_invalid",
- "Ссылка на подписку Local sing-box должна начинаться с http:// или https://.",
- ));
- }
-
- Ok(())
-}
-
-fn ping_subscription_server(server: &SubscriptionServer) -> PingServerResponse {
- ping_endpoint(&server.tag, &server.server, server.server_port)
-}
-
-fn ping_endpoint(tag: &str, server: &str, server_port: u16) -> PingServerResponse {
- let started = Instant::now();
- let addresses = match (server, server_port).to_socket_addrs() {
- Ok(addresses) => addresses.collect::>(),
- Err(error) => {
- return PingServerResponse {
- tag: tag.to_string(),
- server: server.to_string(),
- server_port,
- ok: false,
- latency: None,
- error: Some(format!("DNS/адрес недоступен: {error}")),
- };
- }
- };
-
- if addresses.is_empty() {
- return PingServerResponse {
- tag: tag.to_string(),
- server: server.to_string(),
- server_port,
- ok: false,
- latency: None,
- error: Some("DNS не вернул адреса".to_string()),
- };
- }
-
- let timeout = Duration::from_secs(2);
- let mut last_error = None;
- for address in addresses {
- match TcpStream::connect_timeout(&address, timeout) {
- Ok(_) => {
- return PingServerResponse {
- tag: tag.to_string(),
- server: server.to_string(),
- server_port,
- ok: true,
- latency: Some(started.elapsed().as_millis()),
- error: None,
- };
- }
- Err(error) => last_error = Some(error.to_string()),
- }
- }
-
- PingServerResponse {
- tag: tag.to_string(),
- server: server.to_string(),
- server_port,
- ok: false,
- latency: None,
- error: last_error,
- }
-}
-
-fn local_lan_ipv4() -> Option {
- let socket = UdpSocket::bind("0.0.0.0:0").ok()?;
- socket.connect("8.8.8.8:80").ok()?;
- let IpAddr::V4(address) = socket.local_addr().ok()?.ip() else {
- return None;
- };
- if address.is_loopback() || address.is_link_local() || address.is_unspecified() {
- return None;
- }
- Some(address.to_string())
-}
-
-fn find_subscription_server<'a>(
- cache: &'a SubscriptionCache,
- requested_tag: &str,
- requested_server: Option<&str>,
- requested_port: Option,
-) -> Option<&'a SubscriptionServer> {
- cache
- .servers
- .iter()
- .find(|server| server.tag == requested_tag)
- .or_else(|| {
- let requested = comparable_server_tag(requested_tag);
- cache
- .servers
- .iter()
- .find(|server| comparable_server_tag(&server.tag) == requested)
- })
- .or_else(|| {
- let server_name = requested_server?.trim();
- let server_port = requested_port?;
- cache.servers.iter().find(|server| {
- server.server.eq_ignore_ascii_case(server_name) && server.server_port == server_port
- })
- })
-}
-
-fn comparable_server_tag(value: &str) -> String {
- value
- .chars()
- .filter(|ch| !matches!(ch, '\u{fe0e}' | '\u{fe0f}' | '\u{200d}'))
- .collect::()
- .split_whitespace()
- .collect::>()
- .join(" ")
-}
-
-fn ensure_local_singbox_target(
- storage: &JsonStorage,
- config: &LocalSingBoxConfig,
-) -> Result<(), CommandError> {
- let mut targets = storage.read_targets().map_err(storage_error)?;
- let target = Target {
- id: "local-singbox".to_string(),
- name: "Локальный sing-box".to_string(),
- kind: TargetKind::Local,
- protocol: ProxyProtocol::Socks5,
- host: config.listen_host.clone(),
- port: config.listen_port,
- requires_component: Some(ComponentId::Singbox),
- };
-
- match targets.iter().position(|existing| existing.id == target.id) {
- Some(index) => targets[index] = target,
- None => targets.push(target),
- }
-
- storage.write_targets(&targets).map_err(storage_error)
-}
-
-fn activity_for_singbox_generate(
- clock: &impl Clock,
- generated: &SingBoxGeneratedConfig,
- generated_path: &Path,
-) -> ActivityEntry {
- ActivityEntry {
- id: "singbox-config-generated".to_string(),
- at: clock.now(),
- level: ActivityLevel::Success,
- title: "Конфиг Local sing-box создан".to_string(),
- message: format!(
- "Сервер: {}, listen: {}:{}, конфиг: {}",
- generated.selected_server_tag,
- generated.listen,
- generated.listen_port,
- generated_path.display()
- ),
- }
-}
-
-fn singbox_adapter_error(error: SingBoxConfigError) -> CommandError {
- let code = match error.kind {
- SingBoxConfigErrorKind::MissingSelectedServer => "singbox_server_not_selected",
- SingBoxConfigErrorKind::MissingSelectedOutbound => "singbox_selected_server_missing",
- SingBoxConfigErrorKind::UnsupportedSelectedOutbound => {
- "singbox_selected_server_unsupported"
- }
- SingBoxConfigErrorKind::Serialization => "serialization_error",
- SingBoxConfigErrorKind::CheckFailed => "singbox_check_failed",
- };
-
- CommandError::new(code, error.message)
-}
-
-fn control_singbox_service(
- action: SingBoxServiceAction,
- config_source: Option<&Path>,
-) -> Result {
- let Some(detected) = detect_singbox_install() else {
- return Err(CommandError::new(
- "singbox_not_found",
- "Local sing-box не найден на компьютере.",
- ));
- };
-
- let config_target = config_source.map(|_| detected.install_dir.join("config.json"));
- let script = service_control_script(
- action,
- &detected.service_name,
- config_source,
- config_target.as_deref(),
- );
- let output = Command::new("powershell")
- .args([
- "-NoProfile",
- "-NonInteractive",
- "-ExecutionPolicy",
- "Bypass",
- "-Command",
- script.as_str(),
- ])
- .output()
- .map_err(|error| {
- CommandError::new(
- singbox_service_error_code(action),
- format!(
- "Не удалось {} службу Local sing-box: {error}",
- action.label()
- ),
- )
- })?;
- let result = parse_singbox_service_command_output(&output.stdout).ok_or_else(|| {
- CommandError::new(
- singbox_service_error_code(action),
- singbox_service_script_failed_message(action, output.status.code()),
- )
- })?;
-
- if result.success {
- let refreshed = detect_singbox_install();
- let component = singbox_component_from_detection(refreshed.as_ref());
- return Ok(ComponentStatusDto::from(&component));
- }
-
- if matches!(
- result.code.as_str(),
- "start_failed" | "stop_failed" | "config_sync_failed"
- ) {
- run_elevated_singbox_service_command(
- action,
- &detected.service_name,
- config_source,
- config_target.as_deref(),
- &result,
- )?;
- let refreshed = detect_singbox_install();
- let component = singbox_component_from_detection(refreshed.as_ref());
- return Ok(ComponentStatusDto::from(&component));
- }
-
- Err(CommandError::new(
- singbox_service_error_code(action),
- singbox_service_command_failed_message(action, &result),
- ))
-}
-
-fn run_elevated_singbox_service_command(
- action: SingBoxServiceAction,
- service_name: &str,
- config_source: Option<&Path>,
- config_target: Option<&Path>,
- direct_result: &SingBoxServiceCommandOutput,
-) -> Result<(), CommandError> {
- let script_path =
- write_elevated_singbox_service_script(action, service_name, config_source, config_target)?;
- let launch_script = format!(
- "$p = Start-Process -FilePath 'powershell.exe' -Verb RunAs -Wait -PassThru -WindowStyle Hidden -ArgumentList @('-NoProfile','-ExecutionPolicy','Bypass','-File','{}'); exit $p.ExitCode",
- escape_powershell_single(&script_path.display().to_string())
- );
- let output = Command::new("powershell")
- .args([
- "-NoProfile",
- "-NonInteractive",
- "-ExecutionPolicy",
- "Bypass",
- "-Command",
- launch_script.as_str(),
- ])
- .output();
-
- let _ = fs::remove_file(&script_path);
-
- match output {
- Ok(output) if output.status.success() => Ok(()),
- Ok(output) => Err(CommandError::new(
- singbox_service_error_code(action),
- elevated_singbox_service_failed_message(action, direct_result, output.status.code()),
- )),
- Err(error) => Err(CommandError::new(
- singbox_service_error_code(action),
- format!(
- "Не удалось запросить права администратора, чтобы {} службу Local sing-box: {error}",
- action.label()
- ),
- )),
- }
-}
-
-fn write_elevated_singbox_service_script(
- action: SingBoxServiceAction,
- service_name: &str,
- config_source: Option<&Path>,
- config_target: Option<&Path>,
-) -> Result {
- let nonce = SystemTime::now()
- .duration_since(UNIX_EPOCH)
- .map(|duration| duration.as_millis())
- .unwrap_or(0);
- let script_path = env::temp_dir().join(format!("vpn-proxy-singbox-service-{nonce}.ps1"));
- let script = elevated_singbox_service_script(action, service_name, config_source, config_target);
-
- write_powershell_script(&script_path, &script).map_err(|error| {
- CommandError::new(
- singbox_service_error_code(action),
- format!(
- "Не удалось подготовить временный скрипт для управления Local sing-box '{}': {error}",
- script_path.display()
- ),
- )
- })?;
-
- Ok(script_path)
-}
-
-fn elevated_singbox_service_script(
- action: SingBoxServiceAction,
- service_name: &str,
- config_source: Option<&Path>,
- config_target: Option<&Path>,
-) -> String {
- let action_name = action.action_name();
- let escaped_service_name = escape_powershell_single(service_name);
- let escaped_config_source = config_source
- .map(|path| escape_powershell_single(&path.display().to_string()))
- .unwrap_or_default();
- let escaped_config_target = config_target
- .map(|path| escape_powershell_single(&path.display().to_string()))
- .unwrap_or_default();
-
- format!(
- r#"
-$ErrorActionPreference = 'SilentlyContinue'
-$serviceName = '{escaped_service_name}'
-$action = '{action_name}'
-$configSource = '{escaped_config_source}'
-$configTarget = '{escaped_config_target}'
-
-if ($action -eq 'start') {{
- if (-not [string]::IsNullOrWhiteSpace($configSource)) {{
- if (-not (Test-Path -LiteralPath $configSource)) {{ exit 5 }}
- if (-not [string]::IsNullOrWhiteSpace($configTarget)) {{
- try {{
- Copy-Item -LiteralPath $configSource -Destination $configTarget -Force -ErrorAction Stop
- }} catch {{
- exit 6
- }}
- }}
- }}
-
- $service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
- if ($null -eq $service) {{ exit 2 }}
- if ($service.Status -eq 'Running') {{ exit 0 }}
-
- Start-Service -Name $serviceName -ErrorAction SilentlyContinue
- $service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
- if ($null -ne $service) {{
- try {{ $service.WaitForStatus('Running', [TimeSpan]::FromSeconds(15)) }} catch {{}}
- if ($service.Status -eq 'Running') {{ exit 0 }}
- }}
-
- exit 3
-}}
-
-$service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
-if ($null -eq $service) {{ exit 2 }}
-if ($service.Status -eq 'Stopped') {{ exit 0 }}
-
-Stop-Service -Name $serviceName -Force -ErrorAction SilentlyContinue
-$service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
-if ($null -ne $service) {{
- try {{ $service.WaitForStatus('Stopped', [TimeSpan]::FromSeconds(15)) }} catch {{}}
- if ($service.Status -eq 'Stopped') {{ exit 0 }}
-}}
-
-exit 4
-"#
- )
-}
-
-fn install_singbox_component(storage: &JsonStorage) -> Result {
- let generated_config_path = storage.paths().generated_dir.join("sing-box-config.json");
- run_elevated_singbox_package_script(
- SingBoxPackageAction::Install,
- include_str!("../../scripts/install-singbox.ps1"),
- vec![
- "-ConfigSource".to_string(),
- generated_config_path.display().to_string(),
- ],
- &storage.paths().state_dir,
- )?;
-
- let refreshed = detect_singbox_install();
- let Some(detected) = refreshed.as_ref() else {
- return Err(CommandError::new(
- SingBoxPackageAction::Install.error_code(),
- "Установка Local sing-box завершилась, но приложение не найдено после проверки.",
- ));
- };
-
- Ok(ComponentStatusDto::from(&singbox_component_from_detection(
- Some(detected),
- )))
-}
-
-fn uninstall_singbox_component() -> Result {
- let Some(detected) = detect_singbox_install() else {
- let component = singbox_component_from_detection(None);
- return Ok(ComponentStatusDto::from(&component));
- };
-
- ensure_safe_singbox_install_dir(&detected.install_dir).map_err(|message| {
- CommandError::new(SingBoxPackageAction::Uninstall.error_code(), message)
- })?;
- let artifact_dir = default_config_root().join("state");
- run_elevated_singbox_package_script(
- SingBoxPackageAction::Uninstall,
- include_str!("../../scripts/install-singbox.ps1"),
- vec![
- "-InstallRoot".to_string(),
- detected.install_dir.display().to_string(),
- "-ServiceName".to_string(),
- detected.service_name,
- "-Uninstall".to_string(),
- ],
- &artifact_dir,
- )?;
-
- let refreshed = detect_singbox_install();
- if refreshed.is_some() {
- return Err(CommandError::new(
- SingBoxPackageAction::Uninstall.error_code(),
- "Удаление Local sing-box завершилось, но приложение все еще найдено на компьютере.",
- ));
- }
-
- let component = singbox_component_from_detection(None);
- Ok(ComponentStatusDto::from(&component))
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-enum SingBoxPackageAction {
- Install,
- Uninstall,
-}
-
-impl SingBoxPackageAction {
- fn error_code(self) -> &'static str {
- match self {
- SingBoxPackageAction::Install => "singbox_install_failed",
- SingBoxPackageAction::Uninstall => "singbox_uninstall_failed",
- }
- }
-
- fn label(self) -> &'static str {
- match self {
- SingBoxPackageAction::Install => "установить",
- SingBoxPackageAction::Uninstall => "удалить",
- }
- }
-
- fn file_label(self) -> &'static str {
- match self {
- SingBoxPackageAction::Install => "install",
- SingBoxPackageAction::Uninstall => "uninstall",
- }
- }
-}
-
-fn run_elevated_singbox_package_script(
- action: SingBoxPackageAction,
- installer_body: &str,
- installer_args: Vec,
- artifact_dir: &Path,
-) -> Result<(), CommandError> {
- let nonce = SystemTime::now()
- .duration_since(UNIX_EPOCH)
- .map(|duration| duration.as_millis())
- .unwrap_or(0);
- fs::create_dir_all(artifact_dir).map_err(|error| {
- CommandError::new(
- action.error_code(),
- format!(
- "Не удалось создать папку для временных файлов Local sing-box '{}': {error}",
- artifact_dir.display()
- ),
- )
- })?;
-
- let installer_path = artifact_dir.join(format!(
- "vpn-proxy-singbox-{}-{nonce}.ps1",
- action.file_label()
- ));
- let runner_path = artifact_dir.join(format!(
- "vpn-proxy-singbox-{}-{nonce}.runner.ps1",
- action.file_label()
- ));
- let result_path = artifact_dir.join(format!(
- "vpn-proxy-singbox-{}-{nonce}.log",
- action.file_label()
- ));
-
- write_powershell_script(&installer_path, installer_body).map_err(|error| {
- CommandError::new(
- action.error_code(),
- format!(
- "Не удалось подготовить установщик Local sing-box '{}': {error}",
- installer_path.display()
- ),
- )
- })?;
- write_powershell_script(
- &runner_path,
- &singbox_installer_runner_script(&installer_path, &result_path, &installer_args),
- )
- .map_err(|error| {
- CommandError::new(
- action.error_code(),
- format!(
- "Не удалось подготовить runner Local sing-box '{}': {error}",
- runner_path.display()
- ),
- )
- })?;
-
- let launch_script = format!(
- r#"
-$ErrorActionPreference = 'Stop'
-$resultPath = '{}'
-try {{
- $p = Start-Process -FilePath 'powershell.exe' -Verb RunAs -Wait -PassThru -WindowStyle Hidden -ArgumentList @('-NoProfile','-ExecutionPolicy','Bypass','-File','{}')
- if ($null -eq $p) {{
- Set-Content -LiteralPath $resultPath -Value 'Elevated PowerShell не был запущен.' -Encoding UTF8
- exit 1
- }}
- exit $p.ExitCode
-}} catch {{
- Set-Content -LiteralPath $resultPath -Value ($_ | Out-String) -Encoding UTF8
- exit 1
-}}
-"#,
- escape_powershell_single(&result_path.display().to_string()),
- escape_powershell_single(&runner_path.display().to_string())
- );
- let output = Command::new("powershell")
- .args([
- "-NoProfile",
- "-NonInteractive",
- "-ExecutionPolicy",
- "Bypass",
- "-Command",
- launch_script.as_str(),
- ])
- .output();
-
- let _ = fs::remove_file(&installer_path);
- let _ = fs::remove_file(&runner_path);
-
- match output {
- Ok(output) if output.status.success() => {
- let _ = fs::remove_file(&result_path);
- Ok(())
- }
- Ok(output) => {
- let details = package_failure_details(&result_path, &output);
- let _ = fs::remove_file(&result_path);
- Err(CommandError::new(
- action.error_code(),
- format!(
- "Не удалось {} Local sing-box. Код elevated-команды: {}. {details}",
- action.label(),
- output.status.code().unwrap_or(-1),
- ),
- ))
- }
- Err(error) => Err(CommandError::new(
- action.error_code(),
- format!(
- "Не удалось запросить права администратора, чтобы {} Local sing-box: {error}",
- action.label()
- ),
- )),
- }
-}
-
-pub(crate) fn singbox_installer_runner_script(
- installer_path: &Path,
- result_path: &Path,
- installer_args: &[String],
-) -> String {
- let args = installer_args
- .iter()
- .map(|arg| format!("'{}'", escape_powershell_single(arg)))
- .collect::>()
- .join(", ");
-
- format!(
- r#"
-$ErrorActionPreference = 'Stop'
-$installerPath = '{}'
-$resultPath = '{}'
-$stdoutPath = "$resultPath.stdout.log"
-$stderrPath = "$resultPath.stderr.log"
-$installerArgs = @({args})
-try {{
- $output = & powershell.exe -NoProfile -ExecutionPolicy Bypass -File $installerPath @installerArgs 2>&1
- $exitCode = $LASTEXITCODE
- Set-Content -LiteralPath $stdoutPath -Value ($output | Out-String) -Encoding UTF8
- if ($exitCode -ne 0) {{
- $stdout = if (Test-Path -LiteralPath $stdoutPath) {{ Get-Content -LiteralPath $stdoutPath -Raw }} else {{ '' }}
- $stderr = if (Test-Path -LiteralPath $stderrPath) {{ Get-Content -LiteralPath $stderrPath -Raw }} else {{ '' }}
- throw "install-singbox.ps1 завершился с кодом $exitCode. stdout: $stdout stderr: $stderr"
- }}
- Set-Content -LiteralPath $resultPath -Value 'ok' -Encoding UTF8
- exit 0
-}} catch {{
- Set-Content -LiteralPath $resultPath -Value ($_ | Out-String) -Encoding UTF8
- exit 1
-}} finally {{
- Remove-Item -LiteralPath $stdoutPath, $stderrPath -Force -ErrorAction SilentlyContinue
-}}
-"#,
- escape_powershell_single(&installer_path.display().to_string()),
- escape_powershell_single(&result_path.display().to_string())
- )
-}
-
-fn singbox_service_error_code(action: SingBoxServiceAction) -> &'static str {
- match action {
- SingBoxServiceAction::Start => "singbox_service_start_failed",
- SingBoxServiceAction::Stop => "singbox_service_stop_failed",
- }
-}
-
-fn singbox_service_script_failed_message(
- action: SingBoxServiceAction,
- exit_code: Option,
-) -> String {
- let exit_code = exit_code
- .map(|code| format!(" Код выхода PowerShell: {code}."))
- .unwrap_or_default();
-
- format!(
- "Не удалось {} службу Local sing-box: команда управления службой не вернула корректный результат.{exit_code}",
- action.label()
- )
-}
-
-fn singbox_service_command_failed_message(
- action: SingBoxServiceAction,
- result: &SingBoxServiceCommandOutput,
-) -> String {
- let service_name = result
- .service_name
- .as_deref()
- .filter(|value| !value.trim().is_empty())
- .unwrap_or("VpnProxySingBox");
- let status = result
- .status
- .as_deref()
- .filter(|value| !value.trim().is_empty())
- .unwrap_or("неизвестен");
- let pid = result
- .process_id
- .filter(|value| *value > 0)
- .map(|value| format!(", PID: {value}"))
- .unwrap_or_default();
-
- match result.code.as_str() {
- "service_not_found" => "Служба Local sing-box не найдена.".to_string(),
- "config_source_missing" => {
- "Сгенерированный конфиг Local sing-box не найден перед запуском службы.".to_string()
- }
- "config_sync_failed" => {
- "Не удалось обновить config.json службы Local sing-box перед запуском. Попробуй запустить приложение от имени администратора.".to_string()
- }
- "start_failed" => format!(
- "Не удалось запустить службу {service_name}. Текущий статус: {status}{pid}. Попробуй запустить приложение от имени администратора."
- ),
- "stop_failed" => format!(
- "Не удалось остановить службу {service_name}. Текущий статус: {status}{pid}. Запусти приложение от имени администратора или останови службу вручную в services.msc."
- ),
- _ => format!(
- "Не удалось {} службу {service_name}. Текущий статус: {status}{pid}.",
- action.label()
- ),
- }
-}
-
-fn elevated_singbox_service_failed_message(
- action: SingBoxServiceAction,
- direct_result: &SingBoxServiceCommandOutput,
- exit_code: Option,
-) -> String {
- let exit_code = exit_code
- .map(|code| format!(" Код выхода elevated PowerShell: {code}."))
- .unwrap_or_default();
- format!(
- "{} Попытка с правами администратора тоже не сработала.{exit_code}",
- singbox_service_command_failed_message(action, direct_result)
- )
-}
-
-fn components_or_defaults(storage: &JsonStorage) -> Result, CommandError> {
- let components = storage.read_components().map_err(storage_error)?;
- Ok(resolve_component_statuses(
- components,
- detect_proxyfier_install(),
- detect_singbox_install(),
- ))
-}
-
-pub fn resolve_component_statuses(
- stored_components: Vec,
- detected_proxyfier: Option,
- detected_singbox: Option,
-) -> Vec {
- let mut components = default_components();
-
- for component in stored_components {
- upsert_component(&mut components, component);
- }
-
- if detected_proxyfier.is_some() {
- upsert_component(
- &mut components,
- proxyfier_component_from_detection(detected_proxyfier.as_ref()),
- );
- }
- if detected_singbox.is_some() {
- upsert_component(
- &mut components,
- singbox_component_from_detection(detected_singbox.as_ref()),
- );
- }
-
- components
-}
-
-fn default_components() -> Vec {
- vec![
- ComponentStatus {
- id: ComponentId::ControlApp,
- name: "Приложение управления".to_string(),
- state: ComponentState::Running,
- installed: true,
- running: true,
- version: None,
- path: None,
- problems: Vec::new(),
- actions: vec![
- "Открыть журнал".to_string(),
- "Скопировать диагностику".to_string(),
- ],
- },
- ComponentStatus {
- id: ComponentId::Proxyfier,
- name: "ProxiFyre".to_string(),
- state: ComponentState::Missing,
- installed: false,
- running: false,
- version: None,
- path: None,
- problems: vec!["ProxiFyre нужен для маршрутизации выбранных приложений".to_string()],
- actions: vec!["Установить ProxiFyre".to_string()],
- },
- ComponentStatus {
- id: ComponentId::Singbox,
- name: "Локальный sing-box".to_string(),
- state: ComponentState::Missing,
- installed: false,
- running: false,
- version: None,
- path: None,
- problems: Vec::new(),
- actions: vec!["Установить локальный sing-box".to_string()],
- },
- ]
-}
-
-fn upsert_component(components: &mut Vec, component: ComponentStatus) {
- match components
- .iter()
- .position(|existing| existing.id == component.id)
- {
- Some(index) => components[index] = component,
- None => components.push(component),
- }
-}
-
-fn route_line(active_target: Option<&Target>) -> String {
- match active_target {
- Some(target) if target.id == "local-singbox" => {
- format!(
- "Выбранные приложения -> ProxiFyre -> локальный sing-box {}:{} -> VPN",
- target.host, target.port
- )
- }
- Some(target) => format!(
- "Выбранные приложения -> ProxiFyre -> внешний прокси {}:{}",
- target.host, target.port
- ),
- None => "Выбранные приложения -> ProxiFyre -> внешний прокси".to_string(),
- }
-}
-
-fn resolved_app(item: &ProfileItem, warnings: &mut Vec) -> ResolvedAppDto {
- let mut notes = Vec::new();
- match item.item_type {
- ProfileItemType::Process => notes.push("Имя процесса используется напрямую".to_string()),
- ProfileItemType::Folder => {
- let note = "Сканирование папок отложено; ProxiFyre получает путь к папке";
- notes.push(note.to_string());
- warnings.push(note.to_string());
- }
- ProfileItemType::Exe => {
- notes.push("Путь к EXE сохраняется для сопоставления в ProxiFyre".to_string())
- }
- }
-
- ResolvedAppDto {
- source_type: item.item_type.clone(),
- source_value: item.value.clone(),
- app_name: item.value.clone(),
- notes,
- }
-}
-
-fn write_generated_config(path: &Path, contents: &str) -> Result<(), CommandError> {
- if let Some(parent) = path.parent() {
- fs::create_dir_all(parent).map_err(storage_error)?;
- }
- fs::write(path, contents).map_err(storage_error)
-}
-
-fn open_file_or_select(path: &Path) -> Result<(), CommandError> {
- let status = Command::new("notepad.exe")
- .arg(path)
- .spawn()
- .map_err(|error| {
- CommandError::new(
- "open_config_failed",
- format!("Не удалось открыть конфиг '{}': {error}", path.display()),
- )
- })?;
-
- drop(status);
- Ok(())
-}
-
-fn open_folder(path: &Path) -> Result {
- fs::create_dir_all(path).map_err(storage_error)?;
- Command::new("explorer.exe")
- .arg(path)
- .spawn()
- .map_err(|error| {
- CommandError::new(
- "open_config_failed",
- format!("Не удалось открыть папку '{}': {error}", path.display()),
- )
- })?;
-
- Ok(path.display().to_string())
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-enum ServiceControlAction {
- Start,
- Stop,
-}
-
-impl ServiceControlAction {
- fn error_code(self) -> &'static str {
- match self {
- ServiceControlAction::Start => "proxifyre_service_start_failed",
- ServiceControlAction::Stop => "proxifyre_service_stop_failed",
- }
- }
-
- fn label(self) -> &'static str {
- match self {
- ServiceControlAction::Start => "запустить",
- ServiceControlAction::Stop => "остановить",
- }
- }
-}
-
-fn control_proxifyre_service(
- action: ServiceControlAction,
-) -> Result {
- let Some(detected) = detect_proxyfier_install() else {
- return Err(CommandError::new(
- "proxifyre_not_found",
- "ProxiFyre не найден на компьютере.",
- ));
- };
-
- run_proxifyre_service_command(action, &service_name_candidates(&detected))?;
- let refreshed = detect_proxyfier_install();
- let component = proxyfier_component_from_detection(refreshed.as_ref());
-
- Ok(ComponentStatusDto::from(&component))
-}
-
-fn service_name_candidates(detected: &DetectedProxyfier) -> Vec {
- let mut names = Vec::new();
-
- if let Some(service_name) = &detected.service_name {
- names.push(service_name.clone());
- }
- for service_name in ["ProxiFyreService", "ProxiFyre"] {
- if !names
- .iter()
- .any(|existing| existing.eq_ignore_ascii_case(service_name))
- {
- names.push(service_name.to_string());
- }
- }
-
- names
-}
-
-#[derive(Debug, Deserialize)]
-#[serde(rename_all = "camelCase")]
-struct ServiceCommandOutput {
- success: bool,
- code: String,
- service_name: Option,
- status: Option,
- process_id: Option,
-}
-
-fn run_proxifyre_service_command(
- action: ServiceControlAction,
- service_names: &[String],
-) -> Result<(), CommandError> {
- let names = service_names
- .iter()
- .map(|name| format!("'{}'", escape_powershell_single(name)))
- .collect::>()
- .join(", ");
- let action_name = match action {
- ServiceControlAction::Start => "start",
- ServiceControlAction::Stop => "stop",
- };
- let script = format!(
- r#"
-$ErrorActionPreference = 'Stop'
-$names = @({names})
-$action = '{action_name}'
-$service = $null
-
-function Find-ProxiFyreService {{
- foreach ($name in $names) {{
- $candidate = Get-Service -Name $name -ErrorAction SilentlyContinue
- if ($null -ne $candidate) {{ return $candidate }}
- }}
-
- return Get-Service |
- Where-Object {{ $_.Name -match 'ProxiFyre|Proxifyre' -or $_.DisplayName -match 'ProxiFyre|Proxifyre' }} |
- Select-Object -First 1
-}}
-
-function Get-ServiceProcessId([string]$name) {{
- $escapedName = $name.Replace("'", "''")
- $record = Get-CimInstance Win32_Service -Filter "Name='$escapedName'" -ErrorAction SilentlyContinue
- if ($null -eq $record) {{ return 0 }}
- return [int]$record.ProcessId
-}}
-
-function Get-ServiceStatus([string]$name) {{
- $current = Get-Service -Name $name -ErrorAction SilentlyContinue
- if ($null -eq $current) {{ return $null }}
- return $current.Status.ToString()
-}}
-
-function Write-ServiceResult([bool]$success, [string]$code, [string]$status, [int]$processId) {{
- [PSCustomObject]@{{
- success = $success
- code = $code
- serviceName = if ($null -ne $service) {{ $service.Name }} else {{ $null }}
- status = $status
- processId = $processId
- }} | ConvertTo-Json -Compress
- exit 0
-}}
-
-$service = Find-ProxiFyreService
-if ($null -eq $service) {{
- Write-ServiceResult $false 'service_not_found' $null 0
-}}
-
-$status = $service.Status.ToString()
-$processId = Get-ServiceProcessId $service.Name
-
-if ($action -eq 'start') {{
- if ($status -eq 'Running') {{
- Write-ServiceResult $true 'already_running' $status $processId
- }}
-
- try {{
- Start-Service -Name $service.Name -ErrorAction Stop
- $service = Get-Service -Name $service.Name
- $service.WaitForStatus('Running', [TimeSpan]::FromSeconds(15))
- }} catch {{
- Write-ServiceResult $false 'start_failed' (Get-ServiceStatus $service.Name) (Get-ServiceProcessId $service.Name)
- }}
-
- Write-ServiceResult ($service.Status -eq 'Running') 'started' $service.Status.ToString() (Get-ServiceProcessId $service.Name)
-}}
-
-if ($status -eq 'Stopped') {{
- Write-ServiceResult $true 'already_stopped' $status $processId
-}}
-
-try {{
- if ($service.CanStop) {{
- Stop-Service -Name $service.Name -Force -ErrorAction Stop
- }}
-}} catch {{}}
-
-try {{
- $service = Get-Service -Name $service.Name -ErrorAction SilentlyContinue
- if ($null -ne $service -and $service.Status -ne 'Stopped') {{
- $null = & sc.exe stop $service.Name 2>$null
- }}
-}} catch {{}}
-
-try {{
- $service = Get-Service -Name $service.Name -ErrorAction SilentlyContinue
- if ($null -ne $service -and $service.Status -ne 'Stopped') {{
- $service.WaitForStatus('Stopped', [TimeSpan]::FromSeconds(8))
- }}
-}} catch {{}}
-
-$status = Get-ServiceStatus $service.Name
-$processId = Get-ServiceProcessId $service.Name
-if ($status -ne 'Stopped' -and $processId -gt 0) {{
- try {{
- $null = & taskkill.exe /PID $processId /F 2>$null
- Start-Sleep -Milliseconds 700
- $service = Get-Service -Name $service.Name -ErrorAction SilentlyContinue
- if ($null -ne $service) {{
- $service.WaitForStatus('Stopped', [TimeSpan]::FromSeconds(8))
- }}
- }} catch {{}}
-}}
-
-$status = Get-ServiceStatus $service.Name
-$processId = Get-ServiceProcessId $service.Name
-if ($status -eq 'Stopped') {{
- Write-ServiceResult $true 'stopped' $status $processId
-}}
-
-Write-ServiceResult $false 'stop_failed' $status $processId
-"#
- );
-
- let output = Command::new("powershell")
- .args([
- "-NoProfile",
- "-NonInteractive",
- "-ExecutionPolicy",
- "Bypass",
- "-Command",
- script.as_str(),
- ])
- .output()
- .map_err(|error| {
- CommandError::new(
- action.error_code(),
- format!("Не удалось {} службу ProxiFyre: {error}", action.label()),
- )
- })?;
-
- let result = parse_service_command_output(&output.stdout).ok_or_else(|| {
- CommandError::new(
- action.error_code(),
- service_script_failed_message(action, output.status.code()),
- )
- })?;
-
- if result.success {
- return Ok(());
- }
-
- if matches!(result.code.as_str(), "start_failed" | "stop_failed") {
- run_elevated_proxifyre_service_command(action, service_names, &result)?;
- return Ok(());
- }
-
- Err(CommandError::new(
- action.error_code(),
- service_command_failed_message(action, &result),
- ))
-}
-
-fn run_elevated_proxifyre_service_command(
- action: ServiceControlAction,
- service_names: &[String],
- direct_result: &ServiceCommandOutput,
-) -> Result<(), CommandError> {
- let script_path = write_elevated_service_script(action, service_names)?;
- let launch_script = format!(
- "$p = Start-Process -FilePath 'powershell.exe' -Verb RunAs -Wait -PassThru -WindowStyle Hidden -ArgumentList @('-NoProfile','-ExecutionPolicy','Bypass','-File','{}'); exit $p.ExitCode",
- escape_powershell_single(&script_path.display().to_string())
- );
- let output = Command::new("powershell")
- .args([
- "-NoProfile",
- "-NonInteractive",
- "-ExecutionPolicy",
- "Bypass",
- "-Command",
- launch_script.as_str(),
- ])
- .output();
-
- let _ = fs::remove_file(&script_path);
-
- match output {
- Ok(output) if output.status.success() => Ok(()),
- Ok(output) => Err(CommandError::new(
- action.error_code(),
- elevated_service_failed_message(action, direct_result, output.status.code()),
- )),
- Err(error) => Err(CommandError::new(
- action.error_code(),
- format!(
- "Не удалось запросить права администратора, чтобы {} службу ProxiFyre: {error}",
- action.label()
- ),
- )),
- }
-}
-
-fn write_elevated_service_script(
- action: ServiceControlAction,
- service_names: &[String],
-) -> Result {
- let nonce = SystemTime::now()
- .duration_since(UNIX_EPOCH)
- .map(|duration| duration.as_millis())
- .unwrap_or(0);
- let script_path = env::temp_dir().join(format!("vpn-proxy-proxifyre-service-{nonce}.ps1"));
- let script = elevated_service_script(action, service_names);
-
- write_powershell_script(&script_path, &script).map_err(|error| {
- CommandError::new(
- action.error_code(),
- format!(
- "Не удалось подготовить временный скрипт для управления ProxiFyre '{}': {error}",
- script_path.display()
- ),
- )
- })?;
-
- Ok(script_path)
-}
-
-fn elevated_service_script(action: ServiceControlAction, service_names: &[String]) -> String {
- let names = service_names
- .iter()
- .map(|name| format!("'{}'", escape_powershell_single(name)))
- .collect::>()
- .join(", ");
- let action_name = match action {
- ServiceControlAction::Start => "start",
- ServiceControlAction::Stop => "stop",
- };
-
- format!(
- r#"
-$ErrorActionPreference = 'SilentlyContinue'
-$names = @({names})
-$action = '{action_name}'
-$service = $null
-
-foreach ($name in $names) {{
- $service = Get-Service -Name $name -ErrorAction SilentlyContinue
- if ($null -ne $service) {{ break }}
-}}
-
-if ($null -eq $service) {{
- $service = Get-Service |
- Where-Object {{ $_.Name -match 'ProxiFyre|Proxifyre' -or $_.DisplayName -match 'ProxiFyre|Proxifyre' }} |
- Select-Object -First 1
-}}
-
-if ($null -eq $service) {{ exit 2 }}
-
-function Get-ServiceProcessId([string]$name) {{
- $escapedName = $name.Replace("'", "''")
- $record = Get-CimInstance Win32_Service -Filter "Name='$escapedName'" -ErrorAction SilentlyContinue
- if ($null -eq $record) {{ return 0 }}
- return [int]$record.ProcessId
-}}
-
-if ($action -eq 'start') {{
- if ($service.Status -eq 'Running') {{ exit 0 }}
- Start-Service -Name $service.Name -ErrorAction SilentlyContinue
- $service = Get-Service -Name $service.Name -ErrorAction SilentlyContinue
- if ($null -ne $service) {{
- try {{ $service.WaitForStatus('Running', [TimeSpan]::FromSeconds(15)) }} catch {{}}
- if ($service.Status -eq 'Running') {{ exit 0 }}
- }}
- exit 3
-}}
-
-if ($service.Status -eq 'Stopped') {{ exit 0 }}
-
-if ($service.CanStop) {{
- Stop-Service -Name $service.Name -Force -ErrorAction SilentlyContinue
-}}
-
-$service = Get-Service -Name $service.Name -ErrorAction SilentlyContinue
-if ($null -ne $service -and $service.Status -ne 'Stopped') {{
- $null = & sc.exe stop $service.Name 2>$null
-}}
-
-$service = Get-Service -Name $service.Name -ErrorAction SilentlyContinue
-if ($null -ne $service -and $service.Status -ne 'Stopped') {{
- try {{ $service.WaitForStatus('Stopped', [TimeSpan]::FromSeconds(8)) }} catch {{}}
-}}
-
-$service = Get-Service -Name $service.Name -ErrorAction SilentlyContinue
-if ($null -ne $service -and $service.Status -ne 'Stopped') {{
- $processId = Get-ServiceProcessId $service.Name
- if ($processId -gt 0) {{
- $null = & taskkill.exe /PID $processId /F 2>$null
- Start-Sleep -Milliseconds 700
- $service = Get-Service -Name $service.Name -ErrorAction SilentlyContinue
- if ($null -ne $service) {{
- try {{ $service.WaitForStatus('Stopped', [TimeSpan]::FromSeconds(8)) }} catch {{}}
- }}
- }}
-}}
-
-$service = Get-Service -Name $service.Name -ErrorAction SilentlyContinue
-if ($null -eq $service -or $service.Status -eq 'Stopped') {{ exit 0 }}
-exit 4
-"#
- )
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-enum ProxiFyrePackageAction {
- Install,
- Uninstall,
-}
-
-impl ProxiFyrePackageAction {
- fn error_code(self) -> &'static str {
- match self {
- ProxiFyrePackageAction::Install => "proxifyre_install_failed",
- ProxiFyrePackageAction::Uninstall => "proxifyre_uninstall_failed",
- }
- }
-
- fn label(self) -> &'static str {
- match self {
- ProxiFyrePackageAction::Install => "установить",
- ProxiFyrePackageAction::Uninstall => "удалить",
- }
- }
-
- fn file_label(self) -> &'static str {
- match self {
- ProxiFyrePackageAction::Install => "install",
- ProxiFyrePackageAction::Uninstall => "uninstall",
- }
- }
-}
-
-fn install_proxifyre_component(storage: &JsonStorage) -> Result {
- let generated_config_path = storage
- .paths()
- .generated_dir
- .join("proxifyre-app-config.json");
- let script = install_proxifyre_script(&generated_config_path);
-
- run_elevated_package_script(
- ProxiFyrePackageAction::Install,
- script,
- &storage.paths().state_dir,
- )?;
-
- let refreshed = detect_proxyfier_install();
- let Some(detected) = refreshed.as_ref() else {
- return Err(CommandError::new(
- ProxiFyrePackageAction::Install.error_code(),
- "Установка ProxiFyre завершилась, но приложение не найдено после проверки.",
- ));
- };
-
- Ok(ComponentStatusDto::from(
- &proxyfier_component_from_detection(Some(detected)),
- ))
-}
-
-fn uninstall_proxifyre_component() -> Result {
- let Some(detected) = detect_proxyfier_install() else {
- let component = proxyfier_component_from_detection(None);
- return Ok(ComponentStatusDto::from(&component));
- };
-
- ensure_safe_proxifyre_install_dir(&detected.install_dir)?;
- let script = uninstall_proxifyre_script(&detected.install_dir, &detected.executable_path);
-
- let artifact_dir = default_config_root().join("state");
- run_elevated_package_script(ProxiFyrePackageAction::Uninstall, script, &artifact_dir)?;
-
- let refreshed = detect_proxyfier_install();
- if refreshed.is_some() {
- return Err(CommandError::new(
- ProxiFyrePackageAction::Uninstall.error_code(),
- "Удаление ProxiFyre завершилось, но приложение все еще найдено на компьютере.",
- ));
- }
-
- let component = proxyfier_component_from_detection(None);
- Ok(ComponentStatusDto::from(&component))
-}
-
-fn build_proxifyre_setup_status() -> ProxiFyreSetupStatusDto {
- let vc_runtime = detect_vc_runtime();
- let packet_filter = detect_windows_packet_filter();
- let proxifyre = detect_proxyfier_install();
-
- let vc_runtime_item = setup_item_from_program(
- "vc-runtime",
- &format!("Microsoft Visual C++ Runtime ({})", runtime_arch_label()),
- vc_runtime,
- "Нужен для запуска ProxiFyre.exe. Установщик скачает официальный vc_redist от Microsoft.",
- );
- let packet_filter_item = setup_item_from_program(
- "packet-filter",
- "Windows Packet Filter",
- packet_filter,
- "Сетевой драйвер NT Kernel/WireSock, через который ProxiFyre перехватывает трафик приложений.",
- );
- let proxifyre_item = match proxifyre {
- Some(detected) => ProxiFyreSetupItemDto {
- id: "proxifyre".to_string(),
- name: "ProxiFyre".to_string(),
- installed: true,
- version: Some(if detected.running {
- "служба запущена".to_string()
- } else {
- "служба не запущена".to_string()
- }),
- details: detected.install_dir.display().to_string(),
- },
- None => ProxiFyreSetupItemDto {
- id: "proxifyre".to_string(),
- name: "ProxiFyre".to_string(),
- installed: false,
- version: None,
- details: format!(
- "Будет скачан с GitHub и распакован в {}.",
- PROXIFYRE_INSTALL_DIR
- ),
- },
- };
-
- let items = vec![vc_runtime_item, packet_filter_item, proxifyre_item];
- let missing_count = items.iter().filter(|item| !item.installed).count();
-
- ProxiFyreSetupStatusDto {
- ready: missing_count == 0,
- missing_count,
- items,
- }
-}
-
-fn setup_item_from_program(
- id: &str,
- name: &str,
- program: Option,
- missing_details: &str,
-) -> ProxiFyreSetupItemDto {
- match program {
- Some(program) => ProxiFyreSetupItemDto {
- id: id.to_string(),
- name: name.to_string(),
- installed: true,
- version: program.display_version,
- details: program.display_name,
- },
- None => ProxiFyreSetupItemDto {
- id: id.to_string(),
- name: name.to_string(),
- installed: false,
- version: None,
- details: missing_details.to_string(),
- },
- }
-}
-
-#[derive(Debug, Clone)]
-struct InstalledProgram {
- display_name: String,
- display_version: Option,
-}
-
-#[derive(Debug, Deserialize)]
-#[serde(rename_all = "PascalCase")]
-struct InstalledProgramJson {
- display_name: Option,
- display_version: Option,
-}
-
-fn detect_vc_runtime() -> Option {
- installed_program(&vc_runtime_registry_pattern())
-}
-
-fn detect_windows_packet_filter() -> Option {
- installed_program("Windows Packet Filter|WinpkFilter|NDISAPI")
-}
-
-fn installed_program(pattern: &str) -> Option {
- let script = format!(
- r#"
-$paths = @(
- 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*',
- 'HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*',
- 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
-)
-$program = Get-ItemProperty -Path $paths -ErrorAction SilentlyContinue |
- Where-Object {{ $_.DisplayName -match '{}' }} |
- Select-Object -First 1 DisplayName, DisplayVersion
-if ($null -ne $program) {{
- $program | ConvertTo-Json -Compress
-}}
-"#,
- escape_powershell_single(pattern)
- );
-
- let output = Command::new("powershell")
- .args([
- "-NoProfile",
- "-NonInteractive",
- "-ExecutionPolicy",
- "Bypass",
- "-Command",
- script.as_str(),
- ])
- .output()
- .ok()?;
- if !output.status.success() {
- return None;
- }
-
- let stdout = String::from_utf8_lossy(&output.stdout);
- let payload = stdout.trim();
- if payload.is_empty() || payload.eq_ignore_ascii_case("null") {
- return None;
- }
-
- let parsed: InstalledProgramJson = serde_json::from_str(payload).ok()?;
- let display_name = parsed.display_name?.trim().to_string();
- if display_name.is_empty() {
- return None;
- }
-
- Some(InstalledProgram {
- display_name,
- display_version: parsed
- .display_version
- .map(|version| version.trim().to_string())
- .filter(|version| !version.is_empty()),
- })
-}
-
-fn vc_runtime_registry_pattern() -> String {
- let arch = runtime_arch_label();
- if arch == "ARM64" {
- return r"Microsoft Visual C\+\+.*Redistributable.*\((ARM64|x64)\)".to_string();
- }
-
- format!(r"Microsoft Visual C\+\+.*Redistributable.*\({arch}\)")
-}
-
-fn runtime_arch_label() -> &'static str {
- if cfg!(target_arch = "aarch64") {
- "ARM64"
- } else if cfg!(target_arch = "x86") {
- "x86"
- } else {
- "x64"
- }
-}
-
-fn run_elevated_package_script(
- action: ProxiFyrePackageAction,
- body: String,
- artifact_dir: &Path,
-) -> Result<(), CommandError> {
- let nonce = SystemTime::now()
- .duration_since(UNIX_EPOCH)
- .map(|duration| duration.as_millis())
- .unwrap_or(0);
- fs::create_dir_all(artifact_dir).map_err(|error| {
- CommandError::new(
- action.error_code(),
- format!(
- "Не удалось создать папку для временных файлов ProxiFyre '{}': {error}",
- artifact_dir.display()
- ),
- )
- })?;
- let script_path = artifact_dir.join(format!(
- "vpn-proxy-proxifyre-{}-{nonce}.ps1",
- action.file_label()
- ));
- let result_path = artifact_dir.join(format!(
- "vpn-proxy-proxifyre-{}-{nonce}.log",
- action.file_label()
- ));
- let script = wrap_elevated_package_script(&body, &result_path);
-
- write_powershell_script(&script_path, &script).map_err(|error| {
- CommandError::new(
- action.error_code(),
- format!(
- "Не удалось подготовить временный скрипт, чтобы {} ProxiFyre '{}': {error}",
- action.label(),
- script_path.display()
- ),
- )
- })?;
-
- let launch_script = format!(
- r#"
-$ErrorActionPreference = 'Stop'
-$resultPath = '{}'
-try {{
- $p = Start-Process -FilePath 'powershell.exe' -Verb RunAs -Wait -PassThru -WindowStyle Hidden -ArgumentList @('-NoProfile','-ExecutionPolicy','Bypass','-File','{}')
- if ($null -eq $p) {{
- Set-Content -LiteralPath $resultPath -Value 'Elevated PowerShell не был запущен.' -Encoding UTF8
- exit 1
- }}
- exit $p.ExitCode
-}} catch {{
- Set-Content -LiteralPath $resultPath -Value ($_ | Out-String) -Encoding UTF8
- exit 1
-}}
-"#,
- escape_powershell_single(&result_path.display().to_string()),
- escape_powershell_single(&script_path.display().to_string())
- );
- let output = Command::new("powershell")
- .args([
- "-NoProfile",
- "-NonInteractive",
- "-ExecutionPolicy",
- "Bypass",
- "-Command",
- launch_script.as_str(),
- ])
- .output();
-
- let _ = fs::remove_file(&script_path);
-
- match output {
- Ok(output) if output.status.success() => {
- let _ = fs::remove_file(&result_path);
- Ok(())
- }
- Ok(output) => {
- let details = package_failure_details(&result_path, &output);
- let _ = fs::remove_file(&result_path);
- Err(CommandError::new(
- action.error_code(),
- format!(
- "Не удалось {} ProxiFyre. Код elevated-команды: {}. {details}",
- action.label(),
- output.status.code().unwrap_or(-1),
- ),
- ))
- }
- Err(error) => Err(CommandError::new(
- action.error_code(),
- format!(
- "Не удалось запросить права администратора, чтобы {} ProxiFyre: {error}",
- action.label()
- ),
- )),
- }
-}
-
-pub(crate) fn wrap_elevated_package_script(body: &str, result_path: &Path) -> String {
- let mut script = String::new();
- script.push_str("$ErrorActionPreference = 'Stop'\n");
- script.push_str(&format!(
- "$resultPath = '{}'\n",
- escape_powershell_single(&result_path.display().to_string())
- ));
- script.push_str("try {\n");
- script.push_str(body);
- script.push_str(
- r#"
- Set-Content -LiteralPath $resultPath -Value 'ok' -Encoding UTF8
- exit 0
-} catch {
- $message = ($_ | Out-String)
- Set-Content -LiteralPath $resultPath -Value $message -Encoding UTF8
- exit 1
-}
-"#,
- );
-
- script
-}
-
-fn write_powershell_script(path: &Path, script: &str) -> std::io::Result<()> {
- let mut bytes = Vec::with_capacity(script.len() + 3);
- bytes.extend_from_slice(&[0xEF, 0xBB, 0xBF]);
- bytes.extend_from_slice(script.as_bytes());
- fs::write(path, bytes)
-}
-
-pub(crate) fn install_proxifyre_script(generated_config_path: &Path) -> String {
- let mut script = String::new();
- script.push_str(&format!(
- "$targetDir = '{}'\n",
- escape_powershell_single(PROXIFYRE_INSTALL_DIR)
- ));
- script.push_str(&format!(
- "$generatedConfigPath = '{}'\n",
- escape_powershell_single(&generated_config_path.display().to_string())
- ));
- script.push_str(&format!(
- "$proxifyreReleaseApi = '{}'\n",
- escape_powershell_single(PROXIFYRE_RELEASE_API_URL)
- ));
- script.push_str(&format!(
- "$ndisapiReleaseApi = '{}'\n",
- escape_powershell_single(NDISAPI_RELEASE_API_URL)
- ));
- script.push_str(&format!(
- "$vcRedistX64Url = '{}'\n",
- escape_powershell_single(VC_REDIST_X64_URL)
- ));
- script.push_str(&format!(
- "$vcRedistX86Url = '{}'\n",
- escape_powershell_single(VC_REDIST_X86_URL)
- ));
- script.push_str(
- r#"
- [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
-
- function Get-NativeArchitecture {
- $processor = Get-CimInstance Win32_Processor | Select-Object -First 1
- if ($null -ne $processor -and $processor.Architecture -eq 12) { return 'ARM64' }
- if ([Environment]::Is64BitOperatingSystem) { return 'x64' }
- return 'x86'
- }
-
- function Invoke-Download([string]$uri, [string]$path) {
- Invoke-WebRequest -UseBasicParsing -Uri $uri -OutFile $path -Headers @{ 'User-Agent' = 'vpn-proxy-windows-client' }
- }
-
- function Select-Asset($assets, [string]$pattern, [string]$label) {
- $asset = $assets | Where-Object { $_.name -match $pattern } | Select-Object -First 1
- if ($null -eq $asset) { throw "Не найден подходящий asset для $label ($pattern)." }
- return $asset
- }
-
- function Verify-AssetHash([string]$path, $asset) {
- if ($asset.digest -match '^sha256:(.+)$') {
- $expected = $Matches[1].ToLowerInvariant()
- $actual = (Get-FileHash -LiteralPath $path -Algorithm SHA256).Hash.ToLowerInvariant()
- if ($actual -ne $expected) {
- throw "SHA256 не совпал для $($asset.name). Ожидалось $expected, получилось $actual."
- }
- }
- }
-
- function Assert-ExitCode($process, [string]$label) {
- if ($process.ExitCode -ne 0 -and $process.ExitCode -ne 3010) {
- throw "$label завершился с кодом $($process.ExitCode)."
- }
- }
-
- function Get-InstalledProgram([string]$pattern) {
- $paths = @(
- 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*',
- 'HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*',
- 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
- )
- return Get-ItemProperty -Path $paths -ErrorAction SilentlyContinue |
- Where-Object { $_.DisplayName -match $pattern } |
- Select-Object -First 1
- }
-
- function Test-VcRuntime([string]$arch) {
- $pattern = if ($arch -eq 'ARM64') {
- 'Microsoft Visual C\+\+.*Redistributable.*\((ARM64|x64)\)'
- } else {
- "Microsoft Visual C\+\+.*Redistributable.*\($arch\)"
- }
-
- return $null -ne (Get-InstalledProgram $pattern)
- }
-
- function Test-WindowsPacketFilter {
- return $null -ne (Get-InstalledProgram 'Windows Packet Filter|WinpkFilter|NDISAPI')
- }
-
- function Get-LogTail([string]$path) {
- if (-not (Test-Path -LiteralPath $path)) { return '' }
- return (Get-Content -LiteralPath $path -Tail 40 -ErrorAction SilentlyContinue) -join ' '
- }
-
- $arch = Get-NativeArchitecture
- $workDir = Join-Path ([IO.Path]::GetTempPath()) 'vpn-proxy-proxifyre-install'
- $extractDir = Join-Path $workDir 'proxifyre'
- Remove-Item -LiteralPath $workDir -Recurse -Force -ErrorAction SilentlyContinue
- New-Item -ItemType Directory -Force -Path $workDir, $extractDir, $targetDir | Out-Null
-
- if (-not (Test-VcRuntime $arch)) {
- $vcRedistPath = Join-Path $workDir 'vc_redist.exe'
- $vcRedistUrl = if ($arch -eq 'x86') { $vcRedistX86Url } else { $vcRedistX64Url }
- Invoke-Download $vcRedistUrl $vcRedistPath
- $vcProcess = Start-Process -FilePath $vcRedistPath -ArgumentList @('/install', '/quiet', '/norestart') -Wait -PassThru -WindowStyle Hidden
- if ($vcProcess.ExitCode -ne 0 -and $vcProcess.ExitCode -ne 3010 -and $vcProcess.ExitCode -ne 1638 -and -not (Test-VcRuntime $arch)) {
- throw "Visual C++ Runtime завершился с кодом $($vcProcess.ExitCode)."
- }
- }
-
- if (-not (Test-WindowsPacketFilter)) {
- $ndisRelease = Invoke-RestMethod -Uri $ndisapiReleaseApi -Headers @{ 'User-Agent' = 'vpn-proxy-windows-client' }
- $ndisPattern = if ($arch -eq 'ARM64') { 'ARM64\.msi$' } elseif ($arch -eq 'x86') { 'x86\.msi$' } else { 'x64\.msi$' }
- $ndisAsset = Select-Asset $ndisRelease.assets $ndisPattern 'Windows Packet Filter'
- $ndisPath = Join-Path $workDir $ndisAsset.name
- $ndisLogPath = Join-Path $workDir 'windows-packet-filter-install.log'
- Invoke-Download $ndisAsset.browser_download_url $ndisPath
- Verify-AssetHash $ndisPath $ndisAsset
- $ndisProcess = Start-Process -FilePath 'msiexec.exe' -ArgumentList @('/i', $ndisPath, '/qn', '/norestart', '/L*v', $ndisLogPath) -Wait -PassThru -WindowStyle Hidden
- if ($ndisProcess.ExitCode -ne 0 -and $ndisProcess.ExitCode -ne 3010 -and -not (Test-WindowsPacketFilter)) {
- $ndisLogTail = Get-LogTail $ndisLogPath
- throw "Windows Packet Filter завершился с кодом $($ndisProcess.ExitCode). MSI log: $ndisLogPath $ndisLogTail"
- }
- }
-
- $proxifyreRelease = Invoke-RestMethod -Uri $proxifyreReleaseApi -Headers @{ 'User-Agent' = 'vpn-proxy-windows-client' }
- $proxifyrePattern = if ($arch -eq 'ARM64') { 'ARM64-signed\.zip$' } elseif ($arch -eq 'x86') { 'x86-signed\.zip$' } else { 'x64-signed\.zip$' }
- $proxifyreAsset = Select-Asset $proxifyreRelease.assets $proxifyrePattern 'ProxiFyre'
- $proxifyreZipPath = Join-Path $workDir $proxifyreAsset.name
- Invoke-Download $proxifyreAsset.browser_download_url $proxifyreZipPath
- Verify-AssetHash $proxifyreZipPath $proxifyreAsset
-
- Expand-Archive -LiteralPath $proxifyreZipPath -DestinationPath $extractDir -Force
- $proxifyreExe = Get-ChildItem -LiteralPath $extractDir -Recurse -Filter 'ProxiFyre.exe' | Select-Object -First 1
- if ($null -eq $proxifyreExe) { throw 'В архиве ProxiFyre не найден ProxiFyre.exe.' }
-
- Copy-Item -Path (Join-Path $proxifyreExe.Directory.FullName '*') -Destination $targetDir -Recurse -Force
-
- $configTarget = Join-Path $targetDir 'app-config.json'
- if (Test-Path -LiteralPath $generatedConfigPath) {
- Copy-Item -LiteralPath $generatedConfigPath -Destination $configTarget -Force
- } elseif (-not (Test-Path -LiteralPath $configTarget)) {
- $emptyConfig = '{"logLevel":"Info","bypassLan":true,"proxies":[]}'
- Set-Content -LiteralPath $configTarget -Value $emptyConfig -Encoding UTF8
- }
-
- Push-Location $targetDir
- try {
- & .\ProxiFyre.exe stop | Out-Null
- & .\ProxiFyre.exe uninstall | Out-Null
- & .\ProxiFyre.exe install
- if ($LASTEXITCODE -ne 0) { throw "ProxiFyre.exe install завершился с кодом $LASTEXITCODE." }
- & .\ProxiFyre.exe start
- if ($LASTEXITCODE -ne 0) {
- Start-Service -Name 'ProxiFyreService' -ErrorAction Stop
- }
- } finally {
- Pop-Location
- }
-"#,
- );
-
- script
-}
-
-fn uninstall_proxifyre_script(install_dir: &Path, executable_path: &Path) -> String {
- let mut script = String::new();
- script.push_str(&format!(
- "$installDir = '{}'\n",
- escape_powershell_single(&install_dir.display().to_string())
- ));
- script.push_str(&format!(
- "$exePath = '{}'\n",
- escape_powershell_single(&executable_path.display().to_string())
- ));
- script.push_str(
- r#"
- function Find-ProxiFyreService {
- foreach ($name in @('ProxiFyreService', 'ProxiFyre')) {
- $candidate = Get-Service -Name $name -ErrorAction SilentlyContinue
- if ($null -ne $candidate) { return $candidate }
- }
-
- return Get-Service |
- Where-Object { $_.Name -match 'ProxiFyre|Proxifyre' -or $_.DisplayName -match 'ProxiFyre|Proxifyre' } |
- Select-Object -First 1
- }
-
- function Get-ServiceProcessId([string]$name) {
- $escapedName = $name.Replace("'", "''")
- $record = Get-CimInstance Win32_Service -Filter "Name='$escapedName'" -ErrorAction SilentlyContinue
- if ($null -eq $record) { return 0 }
- return [int]$record.ProcessId
- }
-
- $service = Find-ProxiFyreService
- if ($null -ne $service -and $service.Status -ne 'Stopped') {
- try {
- if ($service.CanStop) { Stop-Service -Name $service.Name -Force -ErrorAction SilentlyContinue }
- $service = Get-Service -Name $service.Name -ErrorAction SilentlyContinue
- if ($null -ne $service) { $service.WaitForStatus('Stopped', [TimeSpan]::FromSeconds(8)) }
- } catch {}
- }
-
- $service = Find-ProxiFyreService
- if ($null -ne $service -and $service.Status -ne 'Stopped') {
- $processId = Get-ServiceProcessId $service.Name
- if ($processId -gt 0) {
- taskkill.exe /PID $processId /F | Out-Null
- Start-Sleep -Milliseconds 700
- }
- }
-
- if (Test-Path -LiteralPath $exePath) {
- Push-Location (Split-Path -Parent $exePath)
- try {
- & $exePath uninstall | Out-Null
- } finally {
- Pop-Location
- }
- }
-
- $service = Find-ProxiFyreService
- if ($null -ne $service) {
- sc.exe delete $service.Name | Out-Null
- }
-
- Get-Process -Name 'ProxiFyre' -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
-
- if (Test-Path -LiteralPath $installDir) {
- Remove-Item -LiteralPath $installDir -Recurse -Force
- }
-"#,
- );
-
- script
-}
-
-fn ensure_safe_proxifyre_install_dir(path: &Path) -> Result<(), CommandError> {
- let name = path
- .file_name()
- .and_then(|value| value.to_str())
- .map(|value| value.to_ascii_lowercase())
- .unwrap_or_default();
-
- if path.parent().is_some() && name.contains("proxifyre") {
- return Ok(());
- }
-
- Err(CommandError::new(
- ProxiFyrePackageAction::Uninstall.error_code(),
- format!(
- "Отказываюсь рекурсивно удалять папку ProxiFyre с небезопасным путем: {}",
- path.display()
- ),
- ))
-}
-
-fn apply_to_detected_proxyfier(
- request: HelperApplyRequest<'_>,
- detected: &DetectedProxyfier,
-) -> Result {
- let Some(config_path) = &detected.config_path else {
- return staged_apply_result(request);
- };
-
- if let Some(parent) = config_path.parent() {
- fs::create_dir_all(parent).map_err(|error| {
- CommandError::new(
- "proxyfier_apply_failed",
- format!(
- "Не удалось создать папку конфига ProxiFyre '{}': {error}",
- parent.display()
- ),
- )
- })?;
- }
-
- if config_path.exists() {
- let backup_path = config_path.with_file_name(format!(
- "{}.bak",
- config_path
- .file_name()
- .and_then(|value| value.to_str())
- .unwrap_or("app-config.json")
- ));
- fs::copy(config_path, backup_path).map_err(|error| {
- CommandError::new(
- "proxyfier_apply_failed",
- format!(
- "Не удалось создать backup текущего конфига ProxiFyre '{}': {error}",
- config_path.display()
- ),
- )
- })?;
- }
-
- fs::write(config_path, request.config_contents).map_err(|error| {
- CommandError::new(
- "proxyfier_apply_failed",
- format!(
- "Не удалось записать конфиг ProxiFyre '{}': {error}",
- config_path.display()
- ),
- )
- })?;
-
- Ok(HelperApplyResult {
- success: true,
- changed: true,
- action: "proxifyre.apply-detected-config".to_string(),
- message: format!(
- "Сгенерированный конфиг записан в найденную установку ProxiFyre: {}",
- config_path.display()
- ),
- })
-}
-
-fn staged_apply_result(request: HelperApplyRequest<'_>) -> Result {
- Ok(HelperApplyResult {
- success: true,
- changed: true,
- action: format!("{}.stage-generated-config", request.adapter_id),
- message: format!(
- "Сгенерированный конфиг подготовлен в {}; совместимая установка ProxiFyre не найдена",
- request.config_path.display()
- ),
- })
-}
-
-fn activity_for_apply(
- clock: &impl Clock,
- generated: &ProxyRouterGeneratedConfig,
- generated_path: &Path,
- helper_result: &HelperApplyResult,
-) -> ActivityEntry {
- let level = if helper_result.success {
- ActivityLevel::Success
- } else {
- ActivityLevel::Error
- };
-
- ActivityEntry {
- id: format!("apply-{}", generated.adapter_id),
- at: clock.now(),
- level,
- title: "Конфиг ProxiFyre создан".to_string(),
- message: format!(
- "Профилей: {}, приложений: {}, конфиг: {}",
- generated.enabled_profiles,
- generated.routed_apps,
- generated_path.display()
- ),
- }
-}
-
-fn activity_for_apply_error(clock: &impl Clock, error: &CommandError) -> ActivityEntry {
- ActivityEntry {
- id: format!("apply-error-{}", error.code),
- at: clock.now(),
- level: ActivityLevel::Error,
- title: "Применение ProxiFyre заблокировано".to_string(),
- message: error.message.clone(),
- }
-}
-
-fn storage_error(error: std::io::Error) -> CommandError {
- CommandError::new("storage_error", error.to_string())
-}
-
-fn background_task_error(error: impl std::fmt::Display) -> CommandError {
- CommandError::new(
- "background_task_failed",
- format!("Фоновая проверка не завершилась: {error}"),
- )
-}
-
-fn package_failure_details(result_path: &Path, output: &Output) -> String {
- let mut parts = Vec::new();
-
- if let Ok(contents) = fs::read_to_string(result_path) {
- let details = compact_error_text(&contents);
- if !details.is_empty() && !details.eq_ignore_ascii_case("ok") {
- parts.push(details);
- }
- }
-
- let stdout = String::from_utf8_lossy(&output.stdout);
- let stdout = compact_error_text(&stdout);
- if !stdout.is_empty() {
- parts.push(format!("stdout: {stdout}"));
- }
-
- let stderr = String::from_utf8_lossy(&output.stderr);
- let stderr = compact_error_text(&stderr);
- if !stderr.is_empty() {
- parts.push(format!("stderr: {stderr}"));
- }
-
- if parts.is_empty() {
- parts.push(
- "Лог elevated-скрипта не создан. Обычно это значит, что окно UAC было отменено или Windows не дала запустить elevated PowerShell."
- .to_string(),
- );
- }
-
- parts.join(" ")
-}
-
-fn compact_error_text(value: &str) -> String {
- let text = value
- .lines()
- .map(str::trim)
- .filter(|line| !line.is_empty())
- .collect::>()
- .join(" ");
-
- let max_chars = 1400;
- if text.chars().count() <= max_chars {
- return text;
- }
-
- let truncated = text.chars().take(max_chars).collect::();
- format!("{truncated}...")
-}
-
-fn parse_service_command_output(stdout: &[u8]) -> Option {
- let stdout = String::from_utf8_lossy(stdout);
- let payload = stdout
- .lines()
- .rev()
- .map(str::trim)
- .find(|line| line.starts_with('{') && line.ends_with('}'))?;
-
- serde_json::from_str(payload).ok()
-}
-
-fn service_script_failed_message(action: ServiceControlAction, exit_code: Option) -> String {
- let exit_code = exit_code
- .map(|code| format!(" Код выхода PowerShell: {code}."))
- .unwrap_or_default();
-
- format!(
- "Не удалось {} службу ProxiFyre: команда управления службой не вернула корректный результат.{exit_code}",
- action.label()
- )
-}
-
-fn service_command_failed_message(
- action: ServiceControlAction,
- result: &ServiceCommandOutput,
-) -> String {
- let service_name = result
- .service_name
- .as_deref()
- .filter(|value| !value.trim().is_empty())
- .unwrap_or("ProxiFyre");
- let status = result
- .status
- .as_deref()
- .filter(|value| !value.trim().is_empty())
- .unwrap_or("неизвестен");
- let pid = result
- .process_id
- .filter(|value| *value > 0)
- .map(|value| format!(", PID: {value}"))
- .unwrap_or_default();
-
- match result.code.as_str() {
- "service_not_found" => "Служба ProxiFyre не найдена.".to_string(),
- "start_failed" => format!(
- "Не удалось запустить службу {service_name}. Текущий статус: {status}{pid}. Попробуй запустить приложение от имени администратора."
- ),
- "stop_failed" => format!(
- "Не удалось остановить службу {service_name} даже после принудительной попытки. Текущий статус: {status}{pid}. Запусти приложение от имени администратора или останови службу вручную в services.msc."
- ),
- _ => format!(
- "Не удалось {} службу {service_name}. Текущий статус: {status}{pid}.",
- action.label()
- ),
- }
-}
-
-fn elevated_service_failed_message(
- action: ServiceControlAction,
- direct_result: &ServiceCommandOutput,
- exit_code: Option,
-) -> String {
- let service_name = direct_result
- .service_name
- .as_deref()
- .filter(|value| !value.trim().is_empty())
- .unwrap_or("ProxiFyre");
- let status = direct_result
- .status
- .as_deref()
- .filter(|value| !value.trim().is_empty())
- .unwrap_or("неизвестен");
- let pid = direct_result
- .process_id
- .filter(|value| *value > 0)
- .map(|value| format!(", PID: {value}"))
- .unwrap_or_default();
- let exit_code = exit_code
- .map(|code| format!(" Код elevated-команды: {code}."))
- .unwrap_or_default();
-
- format!(
- "Не удалось {} службу {service_name} даже после запроса прав администратора. До запроса UAC статус был: {status}{pid}.{exit_code} Если появлялось окно UAC, проверь, что оно было подтверждено.",
- action.label()
- )
-}
-
-fn escape_powershell_single(value: &str) -> String {
- value.replace('\'', "''")
-}
-
-fn validation_error(errors: Vec) -> CommandError {
- CommandError::with_details(
- "validation_error",
- "Проверка введенных данных не прошла",
- errors
- .into_iter()
- .map(|error| ValidationIssue {
- field: error.field,
- message: error.message,
- })
- .collect(),
- )
-}
-
-fn adapter_error(error: ProxyRouterError) -> CommandError {
- let code = match error.kind {
- ProxyRouterErrorKind::EmptyProfileItems => "empty_profile_items",
- ProxyRouterErrorKind::MissingTarget => "missing_target",
- ProxyRouterErrorKind::MissingRequiredComponent => "missing_required_component",
- ProxyRouterErrorKind::RequiredComponentNotRunning => "required_component_not_running",
- ProxyRouterErrorKind::UnsupportedTargetProtocol => "unsupported_target_protocol",
- ProxyRouterErrorKind::Serialization => "serialization_error",
- };
-
- CommandError::new(code, error.message)
-}
-
-impl From for ProfileInput {
- fn from(input: ProfileInputDto) -> Self {
- Self {
- id: input.id,
- name: input.name,
- enabled: input.enabled.unwrap_or(true),
- target_id: input
- .target_id
- .unwrap_or_else(|| "local-singbox".to_string()),
- protocols: input
- .protocols
- .unwrap_or_else(|| vec!["TCP".to_string(), "UDP".to_string()]),
- items: input
- .items
- .unwrap_or_default()
- .into_iter()
- .map(ProfileItemInput::from)
- .collect(),
- }
- }
-}
-
-impl From for ProfileItemInput {
- fn from(input: ProfileItemInputDto) -> Self {
- Self {
- item_type: input.item_type,
- value: input.value,
- recursive: input.recursive,
- }
- }
-}
-
-impl From for TargetInput {
- fn from(input: TargetInputDto) -> Self {
- Self {
- id: input.id,
- name: input.name,
- kind: input.kind.unwrap_or_else(|| "external".to_string()),
- protocol: input.protocol.unwrap_or_else(|| "socks5".to_string()),
- host: input.host,
- port: input.port,
- requires_component: input.requires_component,
- }
- }
-}
-
-impl From<&Profile> for ProfileDto {
- fn from(profile: &Profile) -> Self {
- Self {
- id: profile.id.clone(),
- name: profile.name.clone(),
- enabled: profile.enabled,
- target_id: profile.target_id.clone(),
- protocols: profile.protocols.clone(),
- items: profile.items.iter().map(ProfileItemDto::from).collect(),
- }
- }
-}
-
-impl From<&ProfileItem> for ProfileItemDto {
- fn from(item: &ProfileItem) -> Self {
- Self {
- item_type: item.item_type.clone(),
- value: item.value.clone(),
- recursive: item.recursive,
- }
- }
-}
-
-impl From<&Target> for TargetDto {
- fn from(target: &Target) -> Self {
- Self {
- id: target.id.clone(),
- name: target.name.clone(),
- kind: target.kind.clone(),
- protocol: target.protocol.clone(),
- host: target.host.clone(),
- port: target.port,
- requires_component: target.requires_component.clone(),
- }
- }
-}
-
-impl From<&ComponentStatus> for ComponentStatusDto {
- fn from(component: &ComponentStatus) -> Self {
- Self {
- id: component.id.clone(),
- name: component.name.clone(),
- state: component.state.clone(),
- installed: component.installed,
- running: component.running,
- version: component.version.clone(),
- path: component.path.clone(),
- problems: component.problems.clone(),
- actions: component.actions.clone(),
- }
- }
-}
-
-impl From<&ActivityEntry> for ActivityEntryDto {
- fn from(entry: &ActivityEntry) -> Self {
- Self {
- id: entry.id.clone(),
- at: entry.at.clone(),
- level: entry.level.clone(),
- title: entry.title.clone(),
- message: entry.message.clone(),
- }
- }
-}
-
-impl From<&LocalSingBoxConfig> for LocalSingBoxConfigDto {
- fn from(config: &LocalSingBoxConfig) -> Self {
- Self {
- subscription_display_url: config.subscription_display_url(),
- has_subscription: config
- .subscription_url
- .as_deref()
- .is_some_and(|value| !value.trim().is_empty()),
- selected_server_tag: config.selected_server_tag.clone(),
- listen_host: config.listen_host.clone(),
- listen_port: config.listen_port,
- service_name: config.service_name.clone(),
- install_root: config.install_root.clone(),
- updated_at: config.updated_at.clone(),
- }
- }
-}
-
-impl From<&SubscriptionCache> for SubscriptionCacheDto {
- fn from(cache: &SubscriptionCache) -> Self {
- Self {
- servers: cache
- .servers
- .iter()
- .map(SubscriptionServerDto::from)
- .collect(),
- user_info: cache.user_info.clone(),
- fetched_at: cache.fetched_at.clone(),
- }
- }
-}
-
-impl From<&SubscriptionServer> for SubscriptionServerDto {
- fn from(server: &SubscriptionServer) -> Self {
- Self {
- tag: server.tag.clone(),
- server_type: server.server_type.clone(),
- server: server.server.clone(),
- server_port: server.server_port,
- }
- }
-}
diff --git a/apps/windows-client/src-tauri/src/component_detection.rs b/apps/windows-client/src-tauri/src/component_detection.rs
deleted file mode 100644
index 878dbe5..0000000
--- a/apps/windows-client/src-tauri/src/component_detection.rs
+++ /dev/null
@@ -1,564 +0,0 @@
-use crate::models::{
- ComponentId, ComponentState, ComponentStatus, DEFAULT_LOCAL_SINGBOX_INSTALL_ROOT,
- DEFAULT_LOCAL_SINGBOX_SERVICE_NAME,
-};
-use serde::Deserialize;
-use std::{
- env,
- path::{Path, PathBuf},
- process::Command,
-};
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub enum ProxyfierEngine {
- ProxiFyre,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct DetectedProxyfier {
- pub engine: ProxyfierEngine,
- pub name: String,
- pub install_dir: PathBuf,
- pub executable_path: PathBuf,
- pub config_path: Option,
- pub running: bool,
- pub service_name: Option,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct DetectedSingBox {
- pub install_dir: PathBuf,
- pub executable_path: PathBuf,
- pub wrapper_path: PathBuf,
- pub binary_exists: bool,
- pub wrapper_exists: bool,
- pub running: bool,
- pub service_name: String,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct RegistryInstallEntry {
- pub display_name: String,
- pub install_location: Option,
- pub display_icon: Option,
-}
-
-pub trait ProxyfierDetectionHost {
- fn env_var(&self, name: &str) -> Option;
-
- fn path_exists(&self, path: &Path) -> bool;
-
- fn process_running(&self, process_name: &str) -> bool;
-
- fn service_running(&self, service_name: &str) -> bool;
-
- fn registry_install_entries(&self) -> Vec;
-}
-
-#[derive(Debug, Clone, Copy, Default)]
-pub struct SystemProxyfierDetectionHost;
-
-impl ProxyfierDetectionHost for SystemProxyfierDetectionHost {
- fn env_var(&self, name: &str) -> Option {
- env::var(name).ok().filter(|value| !value.trim().is_empty())
- }
-
- fn path_exists(&self, path: &Path) -> bool {
- path.exists()
- }
-
- fn process_running(&self, process_name: &str) -> bool {
- let process_name = process_name.trim_end_matches(".exe");
- let script = format!(
- "if (Get-Process -Name '{}' -ErrorAction SilentlyContinue) {{ 'true' }} else {{ 'false' }}",
- escape_powershell_single(process_name)
- );
-
- powershell_bool(&script)
- }
-
- fn service_running(&self, service_name: &str) -> bool {
- let script = format!(
- "$s = Get-Service -Name '{}' -ErrorAction SilentlyContinue; if ($s -and $s.Status -eq 'Running') {{ 'true' }} else {{ 'false' }}",
- escape_powershell_single(service_name)
- );
-
- powershell_bool(&script)
- }
-
- fn registry_install_entries(&self) -> Vec {
- read_registry_install_entries()
- }
-}
-
-pub fn detect_proxyfier_install() -> Option {
- detect_proxyfier_install_with_host(&SystemProxyfierDetectionHost)
-}
-
-pub fn detect_proxyfier_install_with_host(
- host: &impl ProxyfierDetectionHost,
-) -> Option {
- let proxifyre_running = host.process_running("ProxiFyre.exe")
- || host.service_running("ProxiFyreService")
- || host.service_running("ProxiFyre");
-
- proxyfier_candidates(host)
- .into_iter()
- .filter_map(|candidate| candidate.into_detected(host, proxifyre_running))
- .next()
-}
-
-pub fn proxyfier_component_from_detection(detected: Option<&DetectedProxyfier>) -> ComponentStatus {
- match detected {
- Some(proxyfier) => detected_proxyfier_component(proxyfier),
- None => missing_proxyfier_component(),
- }
-}
-
-pub fn detect_singbox_install() -> Option {
- detect_singbox_install_with_host(&SystemProxyfierDetectionHost)
-}
-
-pub fn detect_singbox_install_with_host(
- host: &impl ProxyfierDetectionHost,
-) -> Option {
- let running = host.process_running("sing-box.exe")
- || host.service_running(DEFAULT_LOCAL_SINGBOX_SERVICE_NAME);
-
- singbox_candidates(host)
- .into_iter()
- .filter_map(|install_dir| detected_singbox_from_dir(host, install_dir, running))
- .next()
-}
-
-pub fn singbox_component_from_detection(detected: Option<&DetectedSingBox>) -> ComponentStatus {
- match detected {
- Some(singbox) => detected_singbox_component(singbox),
- None => missing_singbox_component(),
- }
-}
-
-fn detected_proxyfier_component(proxyfier: &DetectedProxyfier) -> ComponentStatus {
- let state = if proxyfier.running {
- ComponentState::Running
- } else {
- ComponentState::Installed
- };
- let actions = match proxyfier.engine {
- ProxyfierEngine::ProxiFyre => {
- if proxyfier.running {
- vec![
- "Применить сгенерированный конфиг".to_string(),
- "Открыть папку конфига".to_string(),
- "Остановить".to_string(),
- ]
- } else {
- vec![
- "Применить сгенерированный конфиг".to_string(),
- "Открыть папку конфига".to_string(),
- "Запустить".to_string(),
- ]
- }
- }
- };
-
- ComponentStatus {
- id: ComponentId::Proxyfier,
- name: "ProxiFyre".to_string(),
- state,
- installed: true,
- running: proxyfier.running,
- version: Some(match proxyfier.engine {
- ProxyfierEngine::ProxiFyre => "ProxiFyre найден".to_string(),
- }),
- path: Some(proxyfier.install_dir.display().to_string()),
- problems: Vec::new(),
- actions,
- }
-}
-
-fn missing_proxyfier_component() -> ComponentStatus {
- ComponentStatus {
- id: ComponentId::Proxyfier,
- name: "ProxiFyre".to_string(),
- state: ComponentState::Missing,
- installed: false,
- running: false,
- version: None,
- path: None,
- problems: vec!["ProxiFyre нужен для маршрутизации выбранных приложений".to_string()],
- actions: vec!["Установить ProxiFyre".to_string()],
- }
-}
-
-fn detected_singbox_component(singbox: &DetectedSingBox) -> ComponentStatus {
- let state = if singbox.running {
- ComponentState::Running
- } else {
- ComponentState::Stopped
- };
- let actions = if singbox.running {
- vec![
- "Сгенерировать конфиг".to_string(),
- "Остановить".to_string(),
- "Открыть папку".to_string(),
- ]
- } else {
- vec![
- "Сгенерировать конфиг".to_string(),
- "Запустить".to_string(),
- "Открыть папку".to_string(),
- ]
- };
- let problems = if singbox.running {
- Vec::new()
- } else {
- vec!["Служба Local sing-box остановлена".to_string()]
- };
-
- ComponentStatus {
- id: ComponentId::Singbox,
- name: "Local sing-box".to_string(),
- state,
- installed: true,
- running: singbox.running,
- version: Some("sing-box найден".to_string()),
- path: Some(singbox.executable_path.display().to_string()),
- problems,
- actions,
- }
-}
-
-fn missing_singbox_component() -> ComponentStatus {
- ComponentStatus {
- id: ComponentId::Singbox,
- name: "Local sing-box".to_string(),
- state: ComponentState::Missing,
- installed: false,
- running: false,
- version: None,
- path: None,
- problems: Vec::new(),
- actions: vec!["Установить Local sing-box".to_string()],
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-struct ProxyfierCandidate {
- engine: ProxyfierEngine,
- name: String,
- install_dir: PathBuf,
-}
-
-impl ProxyfierCandidate {
- fn into_detected(
- self,
- host: &impl ProxyfierDetectionHost,
- proxifyre_running: bool,
- ) -> Option {
- let executable_path = self.install_dir.join(executable_name(&self.engine));
- let config_path = config_path(&self.engine, &self.install_dir);
- let exists = host.path_exists(&self.install_dir)
- || host.path_exists(&executable_path)
- || config_path
- .as_ref()
- .is_some_and(|path| host.path_exists(path));
-
- if !exists {
- return None;
- }
-
- Some(DetectedProxyfier {
- service_name: service_name(&self.engine).map(str::to_string),
- engine: self.engine,
- name: self.name,
- install_dir: self.install_dir,
- executable_path,
- config_path,
- running: proxifyre_running,
- })
- }
-}
-
-fn proxyfier_candidates(host: &impl ProxyfierDetectionHost) -> Vec {
- let mut candidates = Vec::new();
-
- push_env_candidate(
- &mut candidates,
- host,
- ProxyfierEngine::ProxiFyre,
- "ProxiFyre",
- "VPN_PROXY_PROXIFYRE_ROOT",
- );
- for entry in host.registry_install_entries() {
- if let Some(engine) = engine_from_name(&entry.display_name) {
- let install_dir = entry
- .install_location
- .or_else(|| entry.display_icon.and_then(|path| executable_parent(&path)));
- if let Some(install_dir) = install_dir {
- push_candidate(
- &mut candidates,
- ProxyfierCandidate {
- name: entry.display_name,
- engine,
- install_dir,
- },
- );
- }
- }
- }
-
- for install_dir in common_install_dirs(host, "ProxiFyre") {
- push_candidate(
- &mut candidates,
- ProxyfierCandidate {
- engine: ProxyfierEngine::ProxiFyre,
- name: "ProxiFyre".to_string(),
- install_dir,
- },
- );
- }
- candidates
-}
-
-fn push_env_candidate(
- candidates: &mut Vec,
- host: &impl ProxyfierDetectionHost,
- engine: ProxyfierEngine,
- name: &str,
- env_name: &str,
-) {
- if let Some(path) = host.env_var(env_name) {
- push_candidate(
- candidates,
- ProxyfierCandidate {
- engine,
- name: name.to_string(),
- install_dir: PathBuf::from(path),
- },
- );
- }
-}
-
-fn push_candidate(candidates: &mut Vec, candidate: ProxyfierCandidate) {
- if !candidates.iter().any(|existing| {
- existing.engine == candidate.engine
- && same_path(&existing.install_dir, &candidate.install_dir)
- }) {
- candidates.push(candidate);
- }
-}
-
-fn common_install_dirs(host: &impl ProxyfierDetectionHost, folder_name: &str) -> Vec {
- let mut dirs = vec![PathBuf::from(format!(r"C:\Tools\{folder_name}"))];
-
- for env_name in ["ProgramFiles", "ProgramFiles(x86)", "LOCALAPPDATA"] {
- if let Some(root) = host.env_var(env_name) {
- dirs.push(PathBuf::from(root).join(folder_name));
- }
- }
-
- dirs
-}
-
-fn singbox_candidates(host: &impl ProxyfierDetectionHost) -> Vec {
- let mut candidates = Vec::new();
-
- if let Some(path) = host.env_var("VPN_PROXY_SINGBOX_ROOT") {
- push_path_candidate(&mut candidates, PathBuf::from(path));
- }
- push_path_candidate(
- &mut candidates,
- PathBuf::from(DEFAULT_LOCAL_SINGBOX_INSTALL_ROOT),
- );
- push_path_candidate(
- &mut candidates,
- PathBuf::from(r"C:\Tools\VpnProxy\sing-box"),
- );
- for env_name in ["ProgramFiles", "ProgramFiles(x86)", "LOCALAPPDATA"] {
- if let Some(root) = host.env_var(env_name) {
- push_path_candidate(
- &mut candidates,
- PathBuf::from(&root).join("VpnProxy").join("sing-box"),
- );
- push_path_candidate(&mut candidates, PathBuf::from(root).join("sing-box"));
- }
- }
-
- candidates
-}
-
-fn push_path_candidate(candidates: &mut Vec, candidate: PathBuf) {
- if !candidates
- .iter()
- .any(|existing| same_path(existing, &candidate))
- {
- candidates.push(candidate);
- }
-}
-
-fn detected_singbox_from_dir(
- host: &impl ProxyfierDetectionHost,
- install_dir: PathBuf,
- running: bool,
-) -> Option {
- let executable_path = install_dir.join("sing-box.exe");
- let wrapper_path = install_dir.join("VpnProxySingBox.exe");
- let binary_exists = host.path_exists(&executable_path);
- let wrapper_exists = host.path_exists(&wrapper_path);
- let exists = host.path_exists(&install_dir) || binary_exists || wrapper_exists;
-
- if !exists {
- return None;
- }
-
- Some(DetectedSingBox {
- install_dir,
- executable_path,
- wrapper_path,
- binary_exists,
- wrapper_exists,
- running,
- service_name: DEFAULT_LOCAL_SINGBOX_SERVICE_NAME.to_string(),
- })
-}
-
-fn executable_name(engine: &ProxyfierEngine) -> &'static str {
- match engine {
- ProxyfierEngine::ProxiFyre => "ProxiFyre.exe",
- }
-}
-
-fn config_path(engine: &ProxyfierEngine, install_dir: &Path) -> Option {
- match engine {
- ProxyfierEngine::ProxiFyre => Some(install_dir.join("app-config.json")),
- }
-}
-
-fn service_name(engine: &ProxyfierEngine) -> Option<&'static str> {
- match engine {
- ProxyfierEngine::ProxiFyre => Some("ProxiFyreService"),
- }
-}
-
-fn engine_from_name(name: &str) -> Option {
- let normalized = name.to_ascii_lowercase();
- if normalized.contains("proxifyre") {
- Some(ProxyfierEngine::ProxiFyre)
- } else {
- None
- }
-}
-
-fn executable_parent(path: &Path) -> Option {
- path.parent().map(Path::to_path_buf)
-}
-
-fn same_path(left: &Path, right: &Path) -> bool {
- left.to_string_lossy()
- .eq_ignore_ascii_case(&right.to_string_lossy())
-}
-
-fn powershell_bool(script: &str) -> bool {
- Command::new("powershell")
- .args(["-NoProfile", "-NonInteractive", "-Command", script])
- .output()
- .ok()
- .and_then(|output| String::from_utf8(output.stdout).ok())
- .is_some_and(|stdout| stdout.trim().eq_ignore_ascii_case("true"))
-}
-
-#[derive(Debug, Deserialize)]
-#[serde(rename_all = "PascalCase")]
-struct RegistryInstallJson {
- display_name: Option,
- install_location: Option,
- display_icon: Option,
-}
-
-fn read_registry_install_entries() -> Vec {
- let script = r#"
-$paths = @(
- 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*',
- 'HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*',
- 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
-)
-$items = foreach ($path in $paths) {
- Get-ItemProperty -Path $path -ErrorAction SilentlyContinue
-}
-$items |
- Where-Object { $_.DisplayName -match 'ProxiFyre' } |
- Select-Object DisplayName,InstallLocation,DisplayIcon |
- ConvertTo-Json -Compress
-"#;
-
- let Ok(output) = Command::new("powershell")
- .args(["-NoProfile", "-NonInteractive", "-Command", script])
- .output()
- else {
- return Vec::new();
- };
-
- if !output.status.success() {
- return Vec::new();
- }
-
- let Ok(stdout) = String::from_utf8(output.stdout) else {
- return Vec::new();
- };
- let stdout = stdout.trim();
- if stdout.is_empty() {
- return Vec::new();
- }
-
- parse_registry_json(stdout)
-}
-
-fn parse_registry_json(json: &str) -> Vec {
- let Ok(value) = serde_json::from_str::(json) else {
- return Vec::new();
- };
-
- match value {
- serde_json::Value::Array(entries) => entries
- .into_iter()
- .filter_map(registry_entry_from_value)
- .collect(),
- entry => registry_entry_from_value(entry).into_iter().collect(),
- }
-}
-
-fn registry_entry_from_value(value: serde_json::Value) -> Option {
- let parsed = serde_json::from_value::(value).ok()?;
- let display_name = parsed.display_name?;
- Some(RegistryInstallEntry {
- display_name,
- install_location: parsed
- .install_location
- .filter(|value| !value.trim().is_empty())
- .map(PathBuf::from),
- display_icon: parsed
- .display_icon
- .and_then(|value| display_icon_path(&value)),
- })
-}
-
-fn display_icon_path(value: &str) -> Option {
- let trimmed = value.trim().trim_matches('"');
- if trimmed.is_empty() {
- return None;
- }
-
- let without_icon_index = trimmed
- .split_once(',')
- .map(|(path, _)| path)
- .unwrap_or(trimmed)
- .trim()
- .trim_matches('"');
-
- Some(PathBuf::from(without_icon_index))
-}
-
-fn escape_powershell_single(value: &str) -> String {
- value.replace('\'', "''")
-}
diff --git a/apps/windows-client/src-tauri/src/helper.rs b/apps/windows-client/src-tauri/src/helper.rs
deleted file mode 100644
index 1334c29..0000000
--- a/apps/windows-client/src-tauri/src/helper.rs
+++ /dev/null
@@ -1,184 +0,0 @@
-use crate::models::ComponentId;
-use serde::{Deserialize, Serialize};
-use serde_json::{json, Value};
-use std::path::{Path, PathBuf};
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-pub enum HelperAction {
- #[serde(rename = "install-control-app")]
- InstallControlApp,
- #[serde(rename = "install-proxyfier")]
- InstallProxyfier,
- #[serde(rename = "install-singbox")]
- InstallSingbox,
- #[serde(rename = "proxyfier.apply")]
- ProxyfierApply,
- #[serde(rename = "service.status")]
- ServiceStatus,
- #[serde(rename = "service.start")]
- ServiceStart,
- #[serde(rename = "service.stop")]
- ServiceStop,
- #[serde(rename = "service.restart")]
- ServiceRestart,
-}
-
-#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct HelperRequest {
- pub action: HelperAction,
- #[serde(skip_serializing_if = "Option::is_none")]
- pub component: Option,
- #[serde(default)]
- pub payload: Value,
-}
-
-#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct HelperResponse {
- pub success: bool,
- pub action: HelperAction,
- pub changed: bool,
- pub message: String,
- #[serde(default)]
- pub details: Value,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct HelperCommandSpec {
- pub program: PathBuf,
- pub args: Vec,
- pub stdin: String,
- pub requires_elevation: bool,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct HelperCommandOutput {
- pub status_code: i32,
- pub stdout: String,
- pub stderr: String,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct HelperError {
- pub code: String,
- pub message: String,
-}
-
-impl HelperError {
- pub fn new(code: impl Into, message: impl Into) -> Self {
- Self {
- code: code.into(),
- message: message.into(),
- }
- }
-}
-
-pub trait HelperCommandRunner {
- fn run(&self, spec: &HelperCommandSpec) -> Result;
-}
-
-#[derive(Debug, Clone)]
-pub struct StructuredHelper {
- helper_program: PathBuf,
- runner: R,
-}
-
-impl StructuredHelper
-where
- R: HelperCommandRunner,
-{
- pub fn new(helper_program: impl Into, runner: R) -> Self {
- Self {
- helper_program: helper_program.into(),
- runner,
- }
- }
-
- pub fn runner(&self) -> &R {
- &self.runner
- }
-
- pub fn execute(&self, request: &HelperRequest) -> Result {
- let stdin = serde_json::to_string(request)
- .map_err(|error| HelperError::new("helper_request_encode", error.to_string()))?;
- let spec = HelperCommandSpec {
- program: self.helper_program.clone(),
- args: vec!["--json".to_string()],
- stdin,
- requires_elevation: helper_action_requires_elevation(&request.action),
- };
- let output = self.runner.run(&spec)?;
-
- if output.status_code != 0 {
- return Err(HelperError::new(
- "helper_exit",
- format!(
- "Помощник завершился с кодом {}: {}",
- output.status_code, output.stderr
- ),
- ));
- }
-
- parse_helper_response(&output.stdout)
- }
-}
-
-pub fn parse_helper_response(stdout: &str) -> Result {
- serde_json::from_str(stdout).map_err(|error| {
- HelperError::new(
- "helper_response_decode",
- format!("Помощник вернул не JSON или некорректный JSON: {error}"),
- )
- })
-}
-
-pub fn install_request(component: ComponentId) -> HelperRequest {
- let action = match component {
- ComponentId::ControlApp => HelperAction::InstallControlApp,
- ComponentId::Proxyfier => HelperAction::InstallProxyfier,
- ComponentId::Singbox => HelperAction::InstallSingbox,
- };
-
- HelperRequest {
- action,
- component: Some(component),
- payload: json!({}),
- }
-}
-
-pub fn service_request(component: ComponentId, action: HelperAction) -> HelperRequest {
- HelperRequest {
- action,
- component: Some(component),
- payload: json!({}),
- }
-}
-
-pub fn proxifyre_apply_request(
- config_path: impl AsRef,
- service_name: impl Into,
-) -> HelperRequest {
- HelperRequest {
- action: HelperAction::ProxyfierApply,
- component: Some(ComponentId::Proxyfier),
- payload: json!({
- "configPath": config_path.as_ref().display().to_string(),
- "serviceName": service_name.into(),
- }),
- }
-}
-
-pub fn helper_action_requires_elevation(action: &HelperAction) -> bool {
- matches!(
- action,
- HelperAction::InstallControlApp
- | HelperAction::InstallProxyfier
- | HelperAction::InstallSingbox
- | HelperAction::ProxyfierApply
- | HelperAction::ServiceStart
- | HelperAction::ServiceStop
- | HelperAction::ServiceRestart
- )
-}
diff --git a/apps/windows-client/src-tauri/src/lib.rs b/apps/windows-client/src-tauri/src/lib.rs
deleted file mode 100644
index 5504150..0000000
--- a/apps/windows-client/src-tauri/src/lib.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-pub fn run() {
- tauri::Builder::default()
- .run(tauri::generate_context!())
- .expect("не удалось запустить клиент VPN Proxy для Windows");
-}
diff --git a/apps/windows-client/src-tauri/src/main.rs b/apps/windows-client/src-tauri/src/main.rs
deleted file mode 100644
index ae5dec6..0000000
--- a/apps/windows-client/src-tauri/src/main.rs
+++ /dev/null
@@ -1,71 +0,0 @@
-#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
-
-mod activity;
-mod commands;
-mod component_detection;
-mod models;
-mod singbox_service;
-mod storage;
-mod subscription;
-mod validation;
-
-mod adapters {
- pub mod proxifyre;
- pub mod proxy_router;
- pub mod singbox;
-}
-
-#[cfg(test)]
-pub(crate) mod proxifyre {
- pub use crate::adapters::proxifyre::*;
-}
-
-#[cfg(test)]
-pub(crate) mod proxy_router {
- pub use crate::adapters::proxy_router::*;
-}
-
-#[cfg(test)]
-pub(crate) mod singbox {
- pub use crate::adapters::singbox::*;
-}
-
-fn main() {
- tauri::Builder::default()
- .plugin(tauri_plugin_dialog::init())
- .manage(commands::CommandState::default())
- .invoke_handler(tauri::generate_handler![
- commands::get_status,
- commands::get_profiles,
- commands::get_saved_state,
- commands::save_profile,
- commands::get_targets,
- commands::save_target,
- commands::get_components,
- commands::get_proxifyre_setup_status,
- commands::get_singbox_status,
- commands::get_singbox_setup_status,
- commands::resolve_profile_preview,
- commands::save_singbox_subscription,
- commands::fetch_singbox_subscription,
- commands::forget_singbox_subscription,
- commands::select_singbox_server,
- commands::ping_singbox_server,
- commands::ping_all_singbox_servers,
- commands::ping_proxy_target,
- commands::generate_singbox_config,
- commands::apply_profiles,
- commands::get_logs,
- commands::open_config_location,
- commands::start_proxifyre_service,
- commands::stop_proxifyre_service,
- commands::install_proxifyre,
- commands::uninstall_proxifyre,
- commands::start_singbox_service,
- commands::stop_singbox_service,
- commands::install_singbox,
- commands::uninstall_singbox
- ])
- .run(tauri::generate_context!())
- .expect("не удалось запустить клиент VPN Proxy для Windows");
-}
diff --git a/apps/windows-client/src-tauri/src/models.rs b/apps/windows-client/src-tauri/src/models.rs
deleted file mode 100644
index 2ff7211..0000000
--- a/apps/windows-client/src-tauri/src/models.rs
+++ /dev/null
@@ -1,273 +0,0 @@
-use serde::{Deserialize, Serialize};
-
-pub const DEFAULT_LOCAL_SINGBOX_LISTEN_HOST: &str = "127.0.0.1";
-pub const DEFAULT_LOCAL_SINGBOX_LISTEN_PORT: u16 = 1080;
-pub const DEFAULT_LOCAL_SINGBOX_SERVICE_NAME: &str = "VpnProxySingBox";
-pub const DEFAULT_LOCAL_SINGBOX_INSTALL_ROOT: &str = r"C:\Program Files\VpnProxy\sing-box";
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
-pub enum Protocol {
- Tcp,
- Udp,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub enum ProfileItemType {
- Process,
- Folder,
- Exe,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub enum TargetKind {
- Local,
- External,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "lowercase")]
-pub enum ProxyProtocol {
- Socks5,
- Http,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "kebab-case")]
-pub enum ComponentId {
- ControlApp,
- Proxyfier,
- Singbox,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub enum ComponentState {
- Installed,
- Missing,
- Stopped,
- Running,
- Error,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-pub struct ProfileItemInput {
- #[serde(rename = "type")]
- pub item_type: String,
- pub value: String,
- #[serde(default)]
- pub recursive: Option,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-pub struct ProfileInput {
- pub id: Option,
- pub name: String,
- #[serde(default = "default_enabled")]
- pub enabled: bool,
- #[serde(default = "default_target_id")]
- pub target_id: String,
- #[serde(default = "default_protocols")]
- pub protocols: Vec,
- #[serde(default)]
- pub items: Vec,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-pub struct ProfileItem {
- #[serde(rename = "type")]
- pub item_type: ProfileItemType,
- pub value: String,
- pub recursive: bool,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-pub struct Profile {
- pub id: String,
- pub name: String,
- pub enabled: bool,
- pub target_id: String,
- pub protocols: Vec,
- pub items: Vec,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-pub struct TargetInput {
- pub id: Option,
- pub name: String,
- #[serde(default = "default_target_kind")]
- pub kind: String,
- #[serde(default = "default_proxy_protocol")]
- pub protocol: String,
- pub host: String,
- pub port: u32,
- #[serde(default)]
- pub requires_component: Option,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-pub struct Target {
- pub id: String,
- pub name: String,
- pub kind: TargetKind,
- pub protocol: ProxyProtocol,
- pub host: String,
- pub port: u16,
- pub requires_component: Option,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-pub struct ComponentStatus {
- pub id: ComponentId,
- pub name: String,
- pub state: ComponentState,
- pub installed: bool,
- pub running: bool,
- pub version: Option,
- pub path: Option,
- #[serde(default)]
- pub problems: Vec,
- #[serde(default)]
- pub actions: Vec,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-pub struct LocalSingBoxConfig {
- #[serde(default)]
- pub subscription_url: Option,
- #[serde(default)]
- pub selected_server_tag: Option,
- #[serde(default = "default_local_singbox_listen_host")]
- pub listen_host: String,
- #[serde(default = "default_local_singbox_listen_port")]
- pub listen_port: u16,
- #[serde(default = "default_local_singbox_service_name")]
- pub service_name: String,
- #[serde(default = "default_local_singbox_install_root")]
- pub install_root: String,
- #[serde(default)]
- pub updated_at: Option,
-}
-
-impl LocalSingBoxConfig {
- pub fn subscription_display_url(&self) -> Option {
- self.subscription_url
- .as_deref()
- .map(redact_subscription_url)
- }
-}
-
-impl Default for LocalSingBoxConfig {
- fn default() -> Self {
- Self {
- subscription_url: None,
- selected_server_tag: None,
- listen_host: default_local_singbox_listen_host(),
- listen_port: default_local_singbox_listen_port(),
- service_name: default_local_singbox_service_name(),
- install_root: default_local_singbox_install_root(),
- updated_at: None,
- }
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
-pub struct SubscriptionCache {
- pub config: serde_json::Value,
- #[serde(default)]
- pub servers: Vec,
- #[serde(default)]
- pub user_info: serde_json::Map,
- pub fetched_at: String,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-pub struct SubscriptionServer {
- pub tag: String,
- #[serde(rename = "type")]
- pub server_type: String,
- pub server: String,
- pub server_port: u16,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-pub struct ActivityEntry {
- pub id: String,
- pub at: String,
- pub level: ActivityLevel,
- pub title: String,
- pub message: String,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "lowercase")]
-pub enum ActivityLevel {
- Info,
- Warning,
- Error,
- Success,
-}
-
-fn default_enabled() -> bool {
- true
-}
-
-fn default_target_id() -> String {
- "local-singbox".to_string()
-}
-
-fn default_protocols() -> Vec {
- vec!["TCP".to_string(), "UDP".to_string()]
-}
-
-fn default_target_kind() -> String {
- "external".to_string()
-}
-
-fn default_proxy_protocol() -> String {
- "socks5".to_string()
-}
-
-fn default_local_singbox_listen_host() -> String {
- DEFAULT_LOCAL_SINGBOX_LISTEN_HOST.to_string()
-}
-
-fn default_local_singbox_listen_port() -> u16 {
- DEFAULT_LOCAL_SINGBOX_LISTEN_PORT
-}
-
-fn default_local_singbox_service_name() -> String {
- DEFAULT_LOCAL_SINGBOX_SERVICE_NAME.to_string()
-}
-
-fn default_local_singbox_install_root() -> String {
- DEFAULT_LOCAL_SINGBOX_INSTALL_ROOT.to_string()
-}
-
-pub fn redact_subscription_url(raw_url: &str) -> String {
- let trimmed = raw_url.trim();
- if trimmed.is_empty() {
- return String::new();
- }
-
- match trimmed.split_once("://") {
- Some((scheme, rest)) => {
- let host = rest
- .split(['/', '?', '#'])
- .next()
- .filter(|value| !value.is_empty())
- .unwrap_or("subscription");
- format!("{scheme}://{host}/...")
- }
- None => {
- let visible = trimmed.chars().take(18).collect::();
- if trimmed.chars().count() <= 18 {
- "***".to_string()
- } else {
- format!("{visible}...")
- }
- }
- }
-}
diff --git a/apps/windows-client/src-tauri/src/singbox_service.rs b/apps/windows-client/src-tauri/src/singbox_service.rs
deleted file mode 100644
index d5a42c8..0000000
--- a/apps/windows-client/src-tauri/src/singbox_service.rs
+++ /dev/null
@@ -1,273 +0,0 @@
-use crate::component_detection::DetectedSingBox;
-use crate::models::{DEFAULT_LOCAL_SINGBOX_INSTALL_ROOT, DEFAULT_LOCAL_SINGBOX_SERVICE_NAME};
-use serde::{Deserialize, Serialize};
-use std::path::Path;
-
-pub const SINGBOX_RELEASE_API_URL: &str =
- "https://api.github.com/repos/SagerNet/sing-box/releases/latest";
-pub const WINSW_RELEASE_API_URL: &str = "https://api.github.com/repos/winsw/winsw/releases/latest";
-pub const WINSW_WRAPPER_FILE: &str = "VpnProxySingBox.exe";
-pub const SINGBOX_BINARY_FILE: &str = "sing-box.exe";
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub enum SingBoxServiceAction {
- Start,
- Stop,
-}
-
-impl SingBoxServiceAction {
- pub fn action_name(self) -> &'static str {
- match self {
- SingBoxServiceAction::Start => "start",
- SingBoxServiceAction::Stop => "stop",
- }
- }
-
- pub fn label(self) -> &'static str {
- match self {
- SingBoxServiceAction::Start => "запустить",
- SingBoxServiceAction::Stop => "остановить",
- }
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct SingBoxSetupStatus {
- pub ready: bool,
- pub missing_count: usize,
- pub items: Vec,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct SingBoxSetupItem {
- pub id: String,
- pub name: String,
- pub installed: bool,
- pub version: Option,
- pub details: String,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct ServiceCommandOutput {
- pub success: bool,
- pub code: String,
- pub service_name: Option