diff --git a/.claude/settings.local.json b/.claude/settings.local.json
new file mode 100644
index 0000000000..3e16c33d41
--- /dev/null
+++ b/.claude/settings.local.json
@@ -0,0 +1,9 @@
+{
+ "permissions": {
+ "allow": [
+ "Bash(rm:*)"
+ ],
+ "deny": [],
+ "ask": []
+ }
+}
diff --git a/.gitignore b/.gitignore
index b545240576..3318e3af3a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,6 @@ playground
tmp
dist
.turbo
+/packages/app/release
+/packages/app
+/packages/desktop/src-tauri/gen/apple/build
diff --git a/AGENTS.md b/AGENTS.md
index 36a37713bd..d0107960e4 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -1,47 +1,175 @@
-## IMPORTANT
+# AGENTS.md
-- Try to keep things in one function unless composable or reusable
-- DO NOT do unnecessary destructuring of variables
-- DO NOT use `else` statements unless necessary
-- DO NOT use `try`/`catch` if it can be avoided
-- AVOID `try`/`catch` where possible
-- AVOID `else` statements
-- AVOID using `any` type
-- AVOID `let` statements
-- PREFER single word variable names where possible
-- Use as many bun apis as possible like Bun.file()
+## Development Commands
-## Debugging
+### Build & Development
-- To test opencode in the `packages/opencode` directory you can run `bun dev`
+- `bun dev` - Start development server for opencode package
+- `bun run build` - Build the entire project
+- `bun run build:dev` - Build for development
+- `bun run test` - Run all tests
+- `bun run typecheck` - Type checking
+- `bun run lint` - Lint code
+- `bun run format` - Check formatting
+- `bun run format:fix` - Fix formatting issues
-## Tool Calling
+### Testing
-- ALWAYS USE PARALLEL TOOLS WHEN APPLICABLE. Here is an example illustrating how to execute 3 parallel file reads in this chat environnement:
+- `bun test` - Run all tests
+- `npx vitest run tests/file-name.test.ts` - Run specific test file
-json
+## Project Structure
+
+This is a monorepo with the following structure:
+
+### Core Packages
+
+- `packages/opencode/` - Main opencode CLI tool
+- `packages/console/` - Web console interface
+- `packages/core/` - Core functionality
+- `packages/function/` - Serverless functions
+- `packages/mail/` - Email templates and functionality
+- `packages/resource/` - Shared resources
+- `packages/scripts/` - Build and utility scripts
+
+### SDKs
+
+- `packages/sdk/go/` - Go SDK
+- `packages/sdk/js/` - JavaScript SDK
+
+### Applications
+
+- `packages/desktop/` - Desktop application (Tauri-based)
+- `packages/web/` - Web application (Astro-based)
+- `packages/tui/` - Terminal user interface (Go-based)
+
+### Extensions
+
+- `packages/plugin/` - Plugin system
+- `packages/vscode/` - VS Code extension
+
+## Code Style Guidelines
+
+### Core Principles
+
+- **Single Function**: Keep things in one function unless composable or reusable
+- **No Destructuring**: Avoid unnecessary destructuring of variables
+- **No Else**: Avoid `else` statements unless absolutely necessary
+- **No Try/Catch**: Avoid `try`/`catch` where possible
+- **No Any**: Avoid using `any` type
+- **No Let**: Prefer `const` over `let`
+- **Single Words**: Prefer single word variable names where possible
+- **Bun APIs**: Use as many bun apis as possible like Bun.file()
+
+### TypeScript Standards
+
+- **Strict typing**: Use explicit function return types
+- **Organized imports**: Group by type (external, internal, relative)
+- **Naming conventions**: PascalCase for types/components, camelCase for variables/functions
+- **Error handling**: Explicit error types, avoid `any` suppression
+
+## Development Guidelines
+
+### When Adding New Features
+
+1. Use existing patterns and conventions
+2. Follow the established file structure
+3. Add appropriate tests
+4. Run linting and type checking
+5. Update documentation if needed
+
+### File Organization
+
+- Keep related files together
+- Use index.ts for exports when appropriate
+- Follow existing directory naming conventions
+- Use descriptive file names that indicate purpose
+
+### Testing
+
+- Use vitest for testing
+- Mock external dependencies with vi.mock/vi.spyOn
+- Test both success and error cases
+- Keep tests focused and isolated
+
+## Environment Setup
+
+1. Install dependencies: `bun install`
+2. Copy environment variables if needed
+3. Run development server: `bun dev`
+4. Run tests: `bun test`
+
+## Common Tasks
+
+### Adding a New Package
+
+1. Create directory in appropriate location
+2. Add package.json with proper dependencies
+3. Add to workspace configuration
+4. Follow existing patterns for structure
+
+### Adding a New Component
+
+1. Check existing components for patterns
+2. Use TypeScript with proper typing
+3. Add to appropriate index file for exports
+4. Add tests if component has business logic
+
+### Debugging
+
+- Use console.log with component prefixes for debugging
+- Check browser console for errors
+- Use development mode for better error messages
+- Run tests to verify functionality
+
+## Tool Calling Best Practices
+
+### Parallel Tool Usage
+
+Always use parallel tools when applicable. Example:
+
+```json
{
- "recipient_name": "multi_tool_use.parallel",
- "parameters": {
- "tool_uses": [
- {
- "recipient_name": "functions.read",
- "parameters": {
- "filePath": "path/to/file.tsx"
- }
- },
- {
- "recipient_name": "functions.read",
- "parameters": {
- "filePath": "path/to/file.ts"
- }
- },
- {
- "recipient_name": "functions.read",
- "parameters": {
- "filePath": "path/to/file.md"
- }
- }
- ]
- }
+ "recipient_name": "multi_tool_use.parallel",
+ "parameters": {
+ "tool_uses": [
+ {
+ "recipient_name": "functions.read",
+ "parameters": {
+ "filePath": "path/to/file.tsx"
+ }
+ },
+ {
+ "recipient_name": "functions.read",
+ "parameters": {
+ "filePath": "path/to/file.ts"
+ }
+ },
+ {
+ "recipient_name": "functions.read",
+ "parameters": {
+ "filePath": "path/to/file.md"
+ }
+ }
+ ]
+ }
}
+```
+
+## Build System
+
+The project uses:
+
+- **Bun** as package manager and runtime
+- **Turbo** for monorepo builds
+- **Vite** for bundling
+- **TypeScript** for type checking
+- **ESLint** for linting
+- **Prettier** for formatting
+
+## Deployment
+
+- GitHub Actions for CI/CD
+- Automatic deployment on merge to main
+- Staging deployments for feature branches
+- Build artifacts are generated in dist/ directories
diff --git a/STATS.md b/STATS.md
index de0ca37f75..775c4200ad 100644
--- a/STATS.md
+++ b/STATS.md
@@ -103,10 +103,10 @@
| 2025-10-06 | 460,927 (+5,368) | 379,489 (+4,744) | 840,416 (+10,112) |
| 2025-10-07 | 467,336 (+6,409) | 385,438 (+5,949) | 852,774 (+12,358) |
| 2025-10-08 | 474,643 (+7,307) | 394,139 (+8,701) | 868,782 (+16,008) |
-| 2025-10-09 | 479,203 (+4,560) | 400,526 (+6,387) | 879,729 (+10,947) |
-| 2025-10-10 | 484,374 (+5,171) | 406,015 (+5,489) | 890,389 (+10,660) |
-| 2025-10-11 | 488,427 (+4,053) | 414,699 (+8,684) | 903,126 (+12,737) |
-| 2025-10-12 | 492,125 (+3,698) | 418,745 (+4,046) | 910,870 (+7,744) |
-| 2025-10-14 | 505,130 (+13,005) | 429,286 (+10,541) | 934,416 (+23,546) |
-| 2025-10-15 | 512,717 (+7,587) | 439,290 (+10,004) | 952,007 (+17,591) |
-| 2025-10-16 | 517,719 (+5,002) | 447,137 (+7,847) | 964,856 (+12,849) |
+| 2025-10-11 | 488,430 (+13,787) | 414,699 (+20,560) | 903,129 (+34,347) |
+| 2025-10-12 | 492,126 (+3,696) | 418,745 (+4,046) | 910,871 (+7,742) |
+| 2025-10-13 | 497,573 (+5,447) | 423,531 (+4,786) | 921,104 (+10,233) |
+| 2025-10-14 | 505,190 (+7,617) | 429,286 (+5,755) | 934,476 (+13,372) |
+| 2025-10-15 | 512,767 (+7,577) | 439,290 (+10,004) | 952,057 (+17,581) |
+| 2025-10-16 | 517,739 (+4,972) | 447,137 (+7,847) | 964,876 (+12,819) |
+| 2025-10-17 | 526,294 (+8,555) | 457,467 (+10,330) | 983,761 (+18,885) |
diff --git a/bun.lock b/bun.lock
index 8da8c5ce30..479a5f4e5f 100644
--- a/bun.lock
+++ b/bun.lock
@@ -122,18 +122,17 @@
},
"packages/desktop": {
"name": "@opencode-ai/desktop",
- "version": "0.15.4",
+ "version": "0.14.7",
"dependencies": {
"@kobalte/core": "catalog:",
"@opencode-ai/sdk": "workspace:*",
- "@opencode-ai/ui": "workspace:*",
"@shikijs/transformers": "3.9.2",
"@solid-primitives/event-bus": "1.1.2",
"@solid-primitives/resize-observer": "2.1.3",
"@solid-primitives/scroll": "2.1.3",
"@solidjs/router": "0.15.3",
"@thisbeyond/solid-dnd": "0.7.5",
- "diff": "catalog:",
+ "diff": "8.0.2",
"fuzzysort": "catalog:",
"luxon": "catalog:",
"marked": "16.2.0",
@@ -142,19 +141,21 @@
"shiki": "3.9.2",
"solid-js": "catalog:",
"solid-list": "0.3.0",
- "tailwindcss": "catalog:",
+ "tailwindcss": "4.1.11",
"virtua": "0.42.3",
},
"devDependencies": {
- "@tailwindcss/vite": "catalog:",
+ "@tailwindcss/vite": "4.1.11",
+ "@tauri-apps/api": "2.8.0",
+ "@tauri-apps/cli": "2.8.4",
"@tsconfig/bun": "1.0.9",
"@types/luxon": "3.7.1",
"@types/node": "catalog:",
- "@typescript/native-preview": "catalog:",
+ "concurrently": "^9.1.2",
"typescript": "catalog:",
- "vite": "catalog:",
+ "vite": "^6.0.0",
"vite-plugin-icons-spritesheet": "3.0.1",
- "vite-plugin-solid": "catalog:",
+ "vite-plugin-solid": "^2.11.6",
},
},
"packages/function": {
@@ -1080,13 +1081,13 @@
"@rollup/plugin-alias": ["@rollup/plugin-alias@5.1.1", "", { "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-PR9zDb+rOzkRb2VD+EuKB7UC41vU5DIwZ5qqCpk0KJudcWAyi8rvYOhS7+L5aZCspw1stTViLgN5v6FF1p5cgQ=="],
- "@rollup/plugin-commonjs": ["@rollup/plugin-commonjs@28.0.7", "", { "dependencies": { "@rollup/pluginutils": "^5.0.1", "commondir": "^1.0.1", "estree-walker": "^2.0.2", "fdir": "^6.2.0", "is-reference": "1.2.1", "magic-string": "^0.30.3", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^2.68.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-6cE2Wr/MkpdtTS8gXlCn9Zdmf7e9Xm96yFqOwFEXuvYLAHtjRf57/n6GEVF4K8NSesT1eKdBtcDA/SQdpW/8nA=="],
+ "@rollup/plugin-commonjs": ["@rollup/plugin-commonjs@28.0.6", "", { "dependencies": { "@rollup/pluginutils": "^5.0.1", "commondir": "^1.0.1", "estree-walker": "^2.0.2", "fdir": "^6.2.0", "is-reference": "1.2.1", "magic-string": "^0.30.3", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^2.68.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-XSQB1K7FUU5QP+3lOQmVCE3I0FcbbNvmNT4VJSj93iUjayaARrTQeoRdiYQoftAJBLrR9t2agwAd3ekaTgHNlw=="],
"@rollup/plugin-inject": ["@rollup/plugin-inject@5.0.5", "", { "dependencies": { "@rollup/pluginutils": "^5.0.1", "estree-walker": "^2.0.2", "magic-string": "^0.30.3" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg=="],
"@rollup/plugin-json": ["@rollup/plugin-json@6.1.0", "", { "dependencies": { "@rollup/pluginutils": "^5.1.0" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA=="],
- "@rollup/plugin-node-resolve": ["@rollup/plugin-node-resolve@16.0.3", "", { "dependencies": { "@rollup/pluginutils": "^5.0.1", "@types/resolve": "1.20.2", "deepmerge": "^4.2.2", "is-module": "^1.0.0", "resolve": "^1.22.1" }, "peerDependencies": { "rollup": "^2.78.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg=="],
+ "@rollup/plugin-node-resolve": ["@rollup/plugin-node-resolve@16.0.2", "", { "dependencies": { "@rollup/pluginutils": "^5.0.1", "@types/resolve": "1.20.2", "deepmerge": "^4.2.2", "is-module": "^1.0.0", "resolve": "^1.22.1" }, "peerDependencies": { "rollup": "^2.78.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-tCtHJ2BlhSoK4cCs25NMXfV7EALKr0jyasmqVCq3y9cBrKdmJhtsy1iTz36Xhk/O+pDJbzawxF4K6ZblqCnITQ=="],
"@rollup/plugin-replace": ["@rollup/plugin-replace@6.0.2", "", { "dependencies": { "@rollup/pluginutils": "^5.0.1", "magic-string": "^0.30.3" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-7QaYCf8bqF04dOy7w/eHmJeNExxTYwvKAmlSAH/EaWWUzbT0h5sbF6bktFoX/0F/0qwng5/dWFMyf3gzaM8DsQ=="],
@@ -1172,57 +1173,57 @@
"@slack/web-api": ["@slack/web-api@6.13.0", "", { "dependencies": { "@slack/logger": "^3.0.0", "@slack/types": "^2.11.0", "@types/is-stream": "^1.1.0", "@types/node": ">=12.0.0", "axios": "^1.7.4", "eventemitter3": "^3.1.0", "form-data": "^2.5.0", "is-electron": "2.2.2", "is-stream": "^1.1.0", "p-queue": "^6.6.1", "p-retry": "^4.0.0" } }, "sha512-dv65crIgdh9ZYHrevLU6XFHTQwTyDmNqEqzuIrV+Vqe/vgiG6w37oex5ePDU1RGm2IJ90H8iOvHFvzdEO/vB+g=="],
- "@smithy/abort-controller": ["@smithy/abort-controller@4.2.2", "", { "dependencies": { "@smithy/types": "^4.7.1", "tslib": "^2.6.2" } }, "sha512-fPbcmEI+A6QiGOuumTpKSo7z+9VYr5DLN8d5/8jDJOwmt4HAKy/UGuRstCMpKbtr+FMaHH4pvFinSAbIAYCHZQ=="],
+ "@smithy/abort-controller": ["@smithy/abort-controller@4.2.0", "", { "dependencies": { "@smithy/types": "^4.6.0", "tslib": "^2.6.2" } }, "sha512-PLUYa+SUKOEZtXFURBu/CNxlsxfaFGxSBPcStL13KpVeVWIfdezWyDqkz7iDLmwnxojXD0s5KzuB5HGHvt4Aeg=="],
- "@smithy/config-resolver": ["@smithy/config-resolver@4.3.2", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.2", "@smithy/types": "^4.7.1", "@smithy/util-config-provider": "^4.2.0", "@smithy/util-middleware": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-F/G+VaulIebINyfvcoXmODgIc7JU/lxWK9/iI0Divxyvd2QWB7/ZcF7JKwMssWI6/zZzlMkq/Pt6ow2AOEebPw=="],
+ "@smithy/config-resolver": ["@smithy/config-resolver@4.3.0", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.0", "@smithy/types": "^4.6.0", "@smithy/util-config-provider": "^4.2.0", "@smithy/util-middleware": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-9oH+n8AVNiLPK/iK/agOsoWfrKZ3FGP3502tkksd6SRsKMYiu7AFX0YXo6YBADdsAj7C+G/aLKdsafIJHxuCkQ=="],
- "@smithy/core": ["@smithy/core@3.16.1", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.2", "@smithy/protocol-http": "^5.3.2", "@smithy/types": "^4.7.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-middleware": "^4.2.2", "@smithy/util-stream": "^4.5.2", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-yRx5ag3xEQ/yGvyo80FVukS7ZkeUP49Vbzg0MjfHLkuCIgg5lFtaEJfZR178KJmjWPqLU4d0P4k7SKgF9UkOaQ=="],
+ "@smithy/core": ["@smithy/core@3.15.0", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.0", "@smithy/protocol-http": "^5.3.0", "@smithy/types": "^4.6.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-middleware": "^4.2.0", "@smithy/util-stream": "^4.5.0", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-VJWncXgt+ExNn0U2+Y7UywuATtRYaodGQKFo9mDyh70q+fJGedfrqi2XuKU1BhiLeXgg6RZrW7VEKfeqFhHAJA=="],
- "@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.2", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.2", "@smithy/property-provider": "^4.2.2", "@smithy/types": "^4.7.1", "@smithy/url-parser": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-hOjFTK+4mfehDnfjNkPqHUKBKR2qmlix5gy7YzruNbTdeoBE3QkfNCPvuCK2r05VUJ02QQ9bz2G41CxhSexsMw=="],
+ "@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.0", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.0", "@smithy/property-provider": "^4.2.0", "@smithy/types": "^4.6.0", "@smithy/url-parser": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-SOhFVvFH4D5HJZytb0bLKxCrSnwcqPiNlrw+S4ZXjMnsC+o9JcUQzbZOEQcA8yv9wJFNhfsUiIUKiEnYL68Big=="],
- "@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.2", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.7.1", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-TDJFBixL6p/CZ6VyTfU+9YrPtcriAouv2IECk5jM4Y3zRJYXyei8lvsCSMMgYW9mLMbtp3mvJbeI8SLOF2BunA=="],
+ "@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.0", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.6.0", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-XE7CtKfyxYiNZ5vz7OvyTf1osrdbJfmUy+rbh+NLQmZumMGvY0mT0Cq1qKSfhrvLtRYzMsOBuRpi10dyI0EBPg=="],
- "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.3", "", { "dependencies": { "@smithy/protocol-http": "^5.3.2", "@smithy/querystring-builder": "^4.2.2", "@smithy/types": "^4.7.1", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-cipIcM3xQ5NdIVwcRb37LaQwIxZNMEZb/ZOPmLFS9uGo9TGx2dGCyMBj9oT7ypH4TUD/kOTc/qHmwQzthrSk+g=="],
+ "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.1", "", { "dependencies": { "@smithy/protocol-http": "^5.3.0", "@smithy/querystring-builder": "^4.2.0", "@smithy/types": "^4.6.0", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-3AvYYbB+Dv5EPLqnJIAgYw/9+WzeBiUYS8B+rU0pHq5NMQMvrZmevUROS4V2GAt0jEOn9viBzPLrZE+riTNd5Q=="],
- "@smithy/hash-node": ["@smithy/hash-node@4.2.2", "", { "dependencies": { "@smithy/types": "^4.7.1", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-xuOPGrF2GUP+9og5NU02fplRVjJjMhAaY8ZconB3eLKjv/VSV9/s+sFf72MYO5Q2jcSRVk/ywZHpyGbE3FYnFQ=="],
+ "@smithy/hash-node": ["@smithy/hash-node@4.2.0", "", { "dependencies": { "@smithy/types": "^4.6.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ugv93gOhZGysTctZh9qdgng8B+xO0cj+zN0qAZ+Sgh7qTQGPOJbMdIuyP89KNfUyfAqFSNh5tMvC+h2uCpmTtA=="],
- "@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.2.2", "", { "dependencies": { "@smithy/types": "^4.7.1", "tslib": "^2.6.2" } }, "sha512-Z0844Zpoid5L1DmKX2+cn2Qu9i3XWjhzwYBRJEWrKJwjUuhEkzf37jKPj9dYFsZeKsAbS2qI0JyLsYafbXJvpA=="],
+ "@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.2.0", "", { "dependencies": { "@smithy/types": "^4.6.0", "tslib": "^2.6.2" } }, "sha512-ZmK5X5fUPAbtvRcUPtk28aqIClVhbfcmfoS4M7UQBTnDdrNxhsrxYVv0ZEl5NaPSyExsPWqL4GsPlRvtlwg+2A=="],
"@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.2", "", { "dependencies": { "@smithy/protocol-http": "^5.3.2", "@smithy/types": "^4.7.1", "tslib": "^2.6.2" } }, "sha512-aJ7LAuIXStF6EqzRVX9kAW+6/sYoJJv0QqoFrz2BhA9r/85kLYOJ6Ph47wYSGBxzSLxsYT5jqgMw/qpbv1+m+w=="],
+ "@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.0", "", { "dependencies": { "@smithy/protocol-http": "^5.3.0", "@smithy/types": "^4.6.0", "tslib": "^2.6.2" } }, "sha512-6ZAnwrXFecrA4kIDOcz6aLBhU5ih2is2NdcZtobBDSdSHtE9a+MThB5uqyK4XXesdOCvOcbCm2IGB95birTSOQ=="],
- "@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.3.3", "", { "dependencies": { "@smithy/core": "^3.16.1", "@smithy/middleware-serde": "^4.2.2", "@smithy/node-config-provider": "^4.3.2", "@smithy/shared-ini-file-loader": "^4.3.2", "@smithy/types": "^4.7.1", "@smithy/url-parser": "^4.2.2", "@smithy/util-middleware": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-CfxQ6X9L87/3C67Po6AGWXsx8iS4w2BO8vQEZJD6hwqg2vNRC/lMa2O5wXYCG9tKotdZ0R8KG33TS7kpUnYKiw=="],
+ "@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.3.1", "", { "dependencies": { "@smithy/core": "^3.15.0", "@smithy/middleware-serde": "^4.2.0", "@smithy/node-config-provider": "^4.3.0", "@smithy/shared-ini-file-loader": "^4.3.0", "@smithy/types": "^4.6.0", "@smithy/url-parser": "^4.2.0", "@smithy/util-middleware": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-JtM4SjEgImLEJVXdsbvWHYiJ9dtuKE8bqLlvkvGi96LbejDL6qnVpVxEFUximFodoQbg0Gnkyff9EKUhFhVJFw=="],
- "@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.3", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.2", "@smithy/protocol-http": "^5.3.2", "@smithy/service-error-classification": "^4.2.2", "@smithy/smithy-client": "^4.8.1", "@smithy/types": "^4.7.1", "@smithy/util-middleware": "^4.2.2", "@smithy/util-retry": "^4.2.2", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-EHnKGeFuzbmER4oSl/VJDxPLi+aiZUb3nk5KK8eNwHjMhI04jHlui2ZkaBzMfNmXOgymaS6zV//fyt6PSnI1ow=="],
+ "@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.1", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.0", "@smithy/protocol-http": "^5.3.0", "@smithy/service-error-classification": "^4.2.0", "@smithy/smithy-client": "^4.7.1", "@smithy/types": "^4.6.0", "@smithy/util-middleware": "^4.2.0", "@smithy/util-retry": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-wXxS4ex8cJJteL0PPQmWYkNi9QKDWZIpsndr0wZI2EL+pSSvA/qqxXU60gBOJoIc2YgtZSWY/PE86qhKCCKP1w=="],
- "@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.2", "", { "dependencies": { "@smithy/protocol-http": "^5.3.2", "@smithy/types": "^4.7.1", "tslib": "^2.6.2" } }, "sha512-tDMPMBCsA1GBxanShhPvQYwdiau3NmctUp+eELMhUTDua+EUrugXlaKCnTMMoEB5mbHFebdv81uJPkVP02oihA=="],
+ "@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.0", "", { "dependencies": { "@smithy/protocol-http": "^5.3.0", "@smithy/types": "^4.6.0", "tslib": "^2.6.2" } }, "sha512-rpTQ7D65/EAbC6VydXlxjvbifTf4IH+sADKg6JmAvhkflJO2NvDeyU9qsWUNBelJiQFcXKejUHWRSdmpJmEmiw=="],
- "@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.2", "", { "dependencies": { "@smithy/types": "^4.7.1", "tslib": "^2.6.2" } }, "sha512-7rgzDyLOQouh1bC6gOXnCGSX2dqvbOclgClsFkj735xQM2CHV63Ams8odNZGJgcqnBsEz44V/pDGHU6ALEUD+w=="],
+ "@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.0", "", { "dependencies": { "@smithy/types": "^4.6.0", "tslib": "^2.6.2" } }, "sha512-G5CJ//eqRd9OARrQu9MK1H8fNm2sMtqFh6j8/rPozhEL+Dokpvi1Og+aCixTuwDAGZUkJPk6hJT5jchbk/WCyg=="],
- "@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.2", "", { "dependencies": { "@smithy/property-provider": "^4.2.2", "@smithy/shared-ini-file-loader": "^4.3.2", "@smithy/types": "^4.7.1", "tslib": "^2.6.2" } }, "sha512-u38G0Audi2ORsL0QnzhopZ3yweMblQf8CZNbzUJ3wfTtZ7OiOwOzee0Nge/3dKeG/8lx0kt8K0kqDi6sYu0oKQ=="],
+ "@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.0", "", { "dependencies": { "@smithy/property-provider": "^4.2.0", "@smithy/shared-ini-file-loader": "^4.3.0", "@smithy/types": "^4.6.0", "tslib": "^2.6.2" } }, "sha512-5QgHNuWdT9j9GwMPPJCKxy2KDxZ3E5l4M3/5TatSZrqYVoEiqQrDfAq8I6KWZw7RZOHtVtCzEPdYz7rHZixwcA=="],
- "@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.1", "", { "dependencies": { "@smithy/abort-controller": "^4.2.2", "@smithy/protocol-http": "^5.3.2", "@smithy/querystring-builder": "^4.2.2", "@smithy/types": "^4.7.1", "tslib": "^2.6.2" } }, "sha512-9gKJoL45MNyOCGTG082nmx0A6KrbLVQ+5QSSKyzRi0AzL0R81u3wC1+nPvKXgTaBdAKM73fFPdCBHpmtipQwdQ=="],
+ "@smithy/node-http-handler": ["@smithy/node-http-handler@4.3.0", "", { "dependencies": { "@smithy/abort-controller": "^4.2.0", "@smithy/protocol-http": "^5.3.0", "@smithy/querystring-builder": "^4.2.0", "@smithy/types": "^4.6.0", "tslib": "^2.6.2" } }, "sha512-RHZ/uWCmSNZ8cneoWEVsVwMZBKy/8123hEpm57vgGXA3Irf/Ja4v9TVshHK2ML5/IqzAZn0WhINHOP9xl+Qy6Q=="],
- "@smithy/property-provider": ["@smithy/property-provider@4.2.2", "", { "dependencies": { "@smithy/types": "^4.7.1", "tslib": "^2.6.2" } }, "sha512-MW7MfI+qYe/Ue5RH0uEztEKB+vBlOMM+1Dz68qzTsY8fC9kanXMFPEVdiq35JTGKWt5wZAjU1R0uXYEjK2MM1g=="],
+ "@smithy/property-provider": ["@smithy/property-provider@4.2.0", "", { "dependencies": { "@smithy/types": "^4.6.0", "tslib": "^2.6.2" } }, "sha512-rV6wFre0BU6n/tx2Ztn5LdvEdNZ2FasQbPQmDOPfV9QQyDmsCkOAB0osQjotRCQg+nSKFmINhyda0D3AnjSBJw=="],
- "@smithy/protocol-http": ["@smithy/protocol-http@5.3.2", "", { "dependencies": { "@smithy/types": "^4.7.1", "tslib": "^2.6.2" } }, "sha512-nkKOI8xEkBXUmdxsFExomOb+wkU+Xgn0Fq2LMC7YIX5r4YPUg7PLayV/s/u3AtbyjWYlrvN7nAiDTLlqSdUjHw=="],
+ "@smithy/protocol-http": ["@smithy/protocol-http@5.3.0", "", { "dependencies": { "@smithy/types": "^4.6.0", "tslib": "^2.6.2" } }, "sha512-6POSYlmDnsLKb7r1D3SVm7RaYW6H1vcNcTWGWrF7s9+2noNYvUsm7E4tz5ZQ9HXPmKn6Hb67pBDRIjrT4w/d7Q=="],
- "@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.2", "", { "dependencies": { "@smithy/types": "^4.7.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-YgXvq89o+R/8zIoeuXYv8Ysrbwgjx+iVYu9QbseqZjMDAhIg/FRt7jis0KASYFtd/Cnsnz4/nYTJXkJDWe8wHg=="],
+ "@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.0", "", { "dependencies": { "@smithy/types": "^4.6.0", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Q4oFD0ZmI8yJkiPPeGUITZj++4HHYCW3pYBYfIobUCkYpI6mbkzmG1MAQQ3lJYYWj3iNqfzOenUZu+jqdPQ16A=="],
- "@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.2", "", { "dependencies": { "@smithy/types": "^4.7.1", "tslib": "^2.6.2" } }, "sha512-DczOD2yJy3NXcv1JvhjFC7bIb/tay6nnIRD/qrzBaju5lrkVBOwCT3Ps37tra20wy8PicZpworStK7ZcI9pCRQ=="],
+ "@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.0", "", { "dependencies": { "@smithy/types": "^4.6.0", "tslib": "^2.6.2" } }, "sha512-BjATSNNyvVbQxOOlKse0b0pSezTWGMvA87SvoFoFlkRsKXVsN3bEtjCxvsNXJXfnAzlWFPaT9DmhWy1vn0sNEA=="],
- "@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.2", "", { "dependencies": { "@smithy/types": "^4.7.1" } }, "sha512-1X17cMLwe/vb4RpZbQVpJ1xQQ7fhQKggMdt3qjdV3+6QNllzvUXyS3WFnyaFWLyaGqfYHKkNONbO1fBCMQyZtQ=="],
+ "@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.0", "", { "dependencies": { "@smithy/types": "^4.6.0" } }, "sha512-Ylv1ttUeKatpR0wEOMnHf1hXMktPUMObDClSWl2TpCVT4DwtJhCeighLzSLbgH3jr5pBNM0LDXT5yYxUvZ9WpA=="],
- "@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.3.2", "", { "dependencies": { "@smithy/types": "^4.7.1", "tslib": "^2.6.2" } }, "sha512-AWnLgSmOTdDXM8aZCN4Im0X07M3GGffeL9vGfea4mdKZD0cPT9yLF9SsRbEa00tHLI+KfubDrmjpaKT2pM4GdQ=="],
+ "@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.3.0", "", { "dependencies": { "@smithy/types": "^4.6.0", "tslib": "^2.6.2" } }, "sha512-VCUPPtNs+rKWlqqntX0CbVvWyjhmX30JCtzO+s5dlzzxrvSfRh5SY0yxnkirvc1c80vdKQttahL71a9EsdolSQ=="],
- "@smithy/signature-v4": ["@smithy/signature-v4@5.3.2", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.2", "@smithy/types": "^4.7.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.2", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-BRnQGGyaRSSL0KtjjFF9YoSSg8qzSqHMub4H2iKkd+LZNzZ1b7H5amslZBzi+AnvuwPMyeiNv0oqay/VmIuoRA=="],
+ "@smithy/signature-v4": ["@smithy/signature-v4@5.3.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.0", "@smithy/types": "^4.6.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.0", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-MKNyhXEs99xAZaFhm88h+3/V+tCRDQ+PrDzRqL0xdDpq4gjxcMmf5rBA3YXgqZqMZ/XwemZEurCBQMfxZOWq/g=="],
- "@smithy/smithy-client": ["@smithy/smithy-client@4.8.1", "", { "dependencies": { "@smithy/core": "^3.16.1", "@smithy/middleware-endpoint": "^4.3.3", "@smithy/middleware-stack": "^4.2.2", "@smithy/protocol-http": "^5.3.2", "@smithy/types": "^4.7.1", "@smithy/util-stream": "^4.5.2", "tslib": "^2.6.2" } }, "sha512-N5wK57pVThzLVK5NgmHxocTy5auqGDGQ+JsL5RjCTriPt8JLYgXT0Awa915zCpzc9hXHDOKqDX5g9BFdwkSfUA=="],
+ "@smithy/smithy-client": ["@smithy/smithy-client@4.7.1", "", { "dependencies": { "@smithy/core": "^3.15.0", "@smithy/middleware-endpoint": "^4.3.1", "@smithy/middleware-stack": "^4.2.0", "@smithy/protocol-http": "^5.3.0", "@smithy/types": "^4.6.0", "@smithy/util-stream": "^4.5.0", "tslib": "^2.6.2" } }, "sha512-WXVbiyNf/WOS/RHUoFMkJ6leEVpln5ojCjNBnzoZeMsnCg3A0BRhLK3WYc4V7PmYcYPZh9IYzzAg9XcNSzYxYQ=="],
- "@smithy/types": ["@smithy/types@4.7.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-WwP7vzoDyzvIFLzF5UhLQ6AsEx/PvSObzlNtJNW3lLy+BaSvTqCU628QKVvcJI/dydlAS1mSHQP7anKcxDcOxA=="],
+ "@smithy/types": ["@smithy/types@4.6.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4lI9C8NzRPOv66FaY1LL1O/0v0aLVrq/mXP/keUa9mJOApEeae43LsLd2kZRUJw91gxOQfLIrV3OvqPgWz1YsA=="],
- "@smithy/url-parser": ["@smithy/url-parser@4.2.2", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.2", "@smithy/types": "^4.7.1", "tslib": "^2.6.2" } }, "sha512-s2EYKukaswzjiHJCss6asB1F4zjRc0E/MFyceAKzb3+wqKA2Z/+Gfhb5FP8xVVRHBAvBkregaQAydifgbnUlCw=="],
+ "@smithy/url-parser": ["@smithy/url-parser@4.2.0", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.0", "@smithy/types": "^4.6.0", "tslib": "^2.6.2" } }, "sha512-AlBmD6Idav2ugmoAL6UtR6ItS7jU5h5RNqLMZC7QrLCoITA9NzIN3nx9GWi8g4z1pfWh2r9r96SX/jHiNwPJ9A=="],
"@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
@@ -1234,19 +1235,19 @@
"@smithy/util-config-provider": ["@smithy/util-config-provider@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q=="],
- "@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.2", "", { "dependencies": { "@smithy/property-provider": "^4.2.2", "@smithy/smithy-client": "^4.8.1", "@smithy/types": "^4.7.1", "tslib": "^2.6.2" } }, "sha512-6JvKHZ5GORYkEZ2+yJKEHp6dQQKng+P/Mu3g3CDy0fRLQgXEO8be+FLrBGGb4kB9lCW6wcQDkN7kRiGkkVAXgg=="],
+ "@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.0", "", { "dependencies": { "@smithy/property-provider": "^4.2.0", "@smithy/smithy-client": "^4.7.1", "@smithy/types": "^4.6.0", "tslib": "^2.6.2" } }, "sha512-H4MAj8j8Yp19Mr7vVtGgi7noJjvjJbsKQJkvNnLlrIFduRFT5jq5Eri1k838YW7rN2g5FTnXpz5ktKVr1KVgPQ=="],
- "@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.3", "", { "dependencies": { "@smithy/config-resolver": "^4.3.2", "@smithy/credential-provider-imds": "^4.2.2", "@smithy/node-config-provider": "^4.3.2", "@smithy/property-provider": "^4.2.2", "@smithy/smithy-client": "^4.8.1", "@smithy/types": "^4.7.1", "tslib": "^2.6.2" } }, "sha512-bkTGuMmKvghfCh9NayADrQcjngoF8P+XTgID5r3rm+8LphFiuM6ERqpBS95YyVaLjDetnKus9zK/bGlkQOOtNQ=="],
+ "@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.1", "", { "dependencies": { "@smithy/config-resolver": "^4.3.0", "@smithy/credential-provider-imds": "^4.2.0", "@smithy/node-config-provider": "^4.3.0", "@smithy/property-provider": "^4.2.0", "@smithy/smithy-client": "^4.7.1", "@smithy/types": "^4.6.0", "tslib": "^2.6.2" } }, "sha512-PuDcgx7/qKEMzV1QFHJ7E4/MMeEjaA7+zS5UNcHCLPvvn59AeZQ0DSDGMpqC2xecfa/1cNGm4l8Ec/VxCuY7Ug=="],
- "@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.2", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.2", "@smithy/types": "^4.7.1", "tslib": "^2.6.2" } }, "sha512-ZQi6fFTMBkfwwSPAlcGzArmNILz33QH99CL8jDfVWrzwVVcZc56Mge10jGk0zdRgWPXyL1/OXKjfw4vT5VtRQg=="],
+ "@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.0", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.0", "@smithy/types": "^4.6.0", "tslib": "^2.6.2" } }, "sha512-TXeCn22D56vvWr/5xPqALc9oO+LN+QpFjrSM7peG/ckqEPoI3zaKZFp+bFwfmiHhn5MGWPaLCqDOJPPIixk9Wg=="],
"@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
- "@smithy/util-middleware": ["@smithy/util-middleware@4.2.2", "", { "dependencies": { "@smithy/types": "^4.7.1", "tslib": "^2.6.2" } }, "sha512-wL9tZwWKy0x0qf6ffN7tX5CT03hb1e7XpjdepaKfKcPcyn5+jHAWPqivhF1Sw/T5DYi9wGcxsX8Lu07MOp2Puw=="],
+ "@smithy/util-middleware": ["@smithy/util-middleware@4.2.0", "", { "dependencies": { "@smithy/types": "^4.6.0", "tslib": "^2.6.2" } }, "sha512-u9OOfDa43MjagtJZ8AapJcmimP+K2Z7szXn8xbty4aza+7P1wjFmy2ewjSbhEiYQoW1unTlOAIV165weYAaowA=="],
- "@smithy/util-retry": ["@smithy/util-retry@4.2.2", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.2", "@smithy/types": "^4.7.1", "tslib": "^2.6.2" } }, "sha512-TlbnWAOoCuG2PgY0Hi3BGU1w2IXs3xDsD4E8WDfKRZUn2qx3wRA9mbYnmpWHPswTJCz2L+ebh+9OvD42sV4mNw=="],
+ "@smithy/util-retry": ["@smithy/util-retry@4.2.0", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.0", "@smithy/types": "^4.6.0", "tslib": "^2.6.2" } }, "sha512-BWSiuGbwRnEE2SFfaAZEX0TqaxtvtSYPM/J73PFVm+A29Fg1HTPiYFb8TmX1DXp4hgcdyJcNQmprfd5foeORsg=="],
- "@smithy/util-stream": ["@smithy/util-stream@4.5.2", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.3", "@smithy/node-http-handler": "^4.4.1", "@smithy/types": "^4.7.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-RWYVuQVKtNbr7E0IxV8XHDId714yHPTxU6dHScd6wSMWAXboErzTG7+xqcL+K3r0Xg0cZSlfuNhl1J0rzMLSSw=="],
+ "@smithy/util-stream": ["@smithy/util-stream@4.5.0", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.1", "@smithy/node-http-handler": "^4.3.0", "@smithy/types": "^4.6.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-0TD5M5HCGu5diEvZ/O/WquSjhJPasqv7trjoqHyWjNh/FBeBl7a0ztl9uFMOsauYtRfd8jvpzIAQhDHbx+nvZw=="],
"@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
@@ -1332,6 +1333,32 @@
"@tanstack/server-functions-plugin": ["@tanstack/server-functions-plugin@1.121.21", "", { "dependencies": { "@babel/code-frame": "7.26.2", "@babel/core": "^7.26.8", "@babel/plugin-syntax-jsx": "^7.25.9", "@babel/plugin-syntax-typescript": "^7.25.9", "@babel/template": "^7.26.8", "@babel/traverse": "^7.26.8", "@babel/types": "^7.26.8", "@tanstack/directive-functions-plugin": "1.121.21", "babel-dead-code-elimination": "^1.0.9", "tiny-invariant": "^1.3.3" } }, "sha512-a05fzK+jBGacsSAc1vE8an7lpBh4H0PyIEcivtEyHLomgSeElAJxm9E2It/0nYRZ5Lh23m0okbhzJNaYWZpAOg=="],
+ "@tauri-apps/api": ["@tauri-apps/api@2.8.0", "", {}, "sha512-ga7zdhbS2GXOMTIZRT0mYjKJtR9fivsXzsyq5U3vjDL0s6DTMwYRm0UHNjzTY5dh4+LSC68Sm/7WEiimbQNYlw=="],
+
+ "@tauri-apps/cli": ["@tauri-apps/cli@2.8.4", "", { "optionalDependencies": { "@tauri-apps/cli-darwin-arm64": "2.8.4", "@tauri-apps/cli-darwin-x64": "2.8.4", "@tauri-apps/cli-linux-arm-gnueabihf": "2.8.4", "@tauri-apps/cli-linux-arm64-gnu": "2.8.4", "@tauri-apps/cli-linux-arm64-musl": "2.8.4", "@tauri-apps/cli-linux-riscv64-gnu": "2.8.4", "@tauri-apps/cli-linux-x64-gnu": "2.8.4", "@tauri-apps/cli-linux-x64-musl": "2.8.4", "@tauri-apps/cli-win32-arm64-msvc": "2.8.4", "@tauri-apps/cli-win32-ia32-msvc": "2.8.4", "@tauri-apps/cli-win32-x64-msvc": "2.8.4" }, "bin": { "tauri": "tauri.js" } }, "sha512-ejUZBzuQRcjFV+v/gdj/DcbyX/6T4unZQjMSBZwLzP/CymEjKcc2+Fc8xTORThebHDUvqoXMdsCZt8r+hyN15g=="],
+
+ "@tauri-apps/cli-darwin-arm64": ["@tauri-apps/cli-darwin-arm64@2.8.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-BKu8HRkYV01SMTa7r4fLx+wjgtRK8Vep7lmBdHDioP6b8XH3q2KgsAyPWfEZaZIkZ2LY4SqqGARaE9oilNe0oA=="],
+
+ "@tauri-apps/cli-darwin-x64": ["@tauri-apps/cli-darwin-x64@2.8.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-imb9PfSd/7G6VAO7v1bQ2A3ZH4NOCbhGJFLchxzepGcXf9NKkfun157JH9mko29K6sqAwuJ88qtzbKCbWJTH9g=="],
+
+ "@tauri-apps/cli-linux-arm-gnueabihf": ["@tauri-apps/cli-linux-arm-gnueabihf@2.8.4", "", { "os": "linux", "cpu": "arm" }, "sha512-Ml215UnDdl7/fpOrF1CNovym/KjtUbCuPgrcZ4IhqUCnhZdXuphud/JT3E8X97Y03TZ40Sjz8raXYI2ET0exzw=="],
+
+ "@tauri-apps/cli-linux-arm64-gnu": ["@tauri-apps/cli-linux-arm64-gnu@2.8.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-pbcgBpMyI90C83CxE5REZ9ODyIlmmAPkkJXtV398X3SgZEIYy5TACYqlyyv2z5yKgD8F8WH4/2fek7+jH+ZXAw=="],
+
+ "@tauri-apps/cli-linux-arm64-musl": ["@tauri-apps/cli-linux-arm64-musl@2.8.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-zumFeaU1Ws5Ay872FTyIm7z8kfzEHu8NcIn8M6TxbJs0a7GRV21KBdpW1zNj2qy7HynnpQCqjAYXTUUmm9JAOw=="],
+
+ "@tauri-apps/cli-linux-riscv64-gnu": ["@tauri-apps/cli-linux-riscv64-gnu@2.8.4", "", { "os": "linux", "cpu": "none" }, "sha512-qiqbB3Zz6IyO201f+1ojxLj65WYj8mixL5cOMo63nlg8CIzsP23cPYUrx1YaDPsCLszKZo7tVs14pc7BWf+/aQ=="],
+
+ "@tauri-apps/cli-linux-x64-gnu": ["@tauri-apps/cli-linux-x64-gnu@2.8.4", "", { "os": "linux", "cpu": "x64" }, "sha512-TaqaDd9Oy6k45Hotx3pOf+pkbsxLaApv4rGd9mLuRM1k6YS/aw81YrsMryYPThrxrScEIUcmNIHaHsLiU4GMkw=="],
+
+ "@tauri-apps/cli-linux-x64-musl": ["@tauri-apps/cli-linux-x64-musl@2.8.4", "", { "os": "linux", "cpu": "x64" }, "sha512-ot9STAwyezN8w+bBHZ+bqSQIJ0qPZFlz/AyscpGqB/JnJQVDFQcRDmUPFEaAtt2UUHSWzN3GoTJ5ypqLBp2WQA=="],
+
+ "@tauri-apps/cli-win32-arm64-msvc": ["@tauri-apps/cli-win32-arm64-msvc@2.8.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-+2aJ/g90dhLiOLFSD1PbElXX3SoMdpO7HFPAZB+xot3CWlAZD1tReUFy7xe0L5GAR16ZmrxpIDM9v9gn5xRy/w=="],
+
+ "@tauri-apps/cli-win32-ia32-msvc": ["@tauri-apps/cli-win32-ia32-msvc@2.8.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-yj7WDxkL1t9Uzr2gufQ1Hl7hrHuFKTNEOyascbc109EoiAqCp0tgZ2IykQqOZmZOHU884UAWI1pVMqBhS/BfhA=="],
+
+ "@tauri-apps/cli-win32-x64-msvc": ["@tauri-apps/cli-win32-x64-msvc@2.8.4", "", { "os": "win32", "cpu": "x64" }, "sha512-XuvGB4ehBdd7QhMZ9qbj/8icGEatDuBNxyYHbLKsTYh90ggUlPa/AtaqcC1Fo69lGkTmq9BOKrs1aWSi7xDonA=="],
+
"@thisbeyond/solid-dnd": ["@thisbeyond/solid-dnd@0.7.5", "", { "peerDependencies": { "solid-js": "^1.5" } }, "sha512-DfI5ff+yYGpK9M21LhYwIPlbP2msKxN2ARwuu6GF8tT1GgNVDTI8VCQvH4TJFoVApP9d44izmAcTh/iTCH2UUw=="],
"@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
@@ -1584,7 +1611,7 @@
"bare-stream": ["bare-stream@2.7.0", "", { "dependencies": { "streamx": "^2.21.0" }, "peerDependencies": { "bare-buffer": "*", "bare-events": "*" }, "optionalPeers": ["bare-buffer", "bare-events"] }, "sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A=="],
- "bare-url": ["bare-url@2.3.0", "", { "dependencies": { "bare-path": "^3.0.0" } }, "sha512-c+RCqMSZbkz97Mw1LWR0gcOqwK82oyYKfLoHJ8k13ybi1+I80ffdDzUy0TdAburdrR/kI0/VuN8YgEnJqX+Nyw=="],
+ "bare-url": ["bare-url@2.2.2", "", { "dependencies": { "bare-path": "^3.0.0" } }, "sha512-g+ueNGKkrjMazDG3elZO1pNs3HY5+mMmOet1jtKyhOaCnkLzitxf26z7hoAEkDNgdNmnc1KIlt/dw6Po6xZMpA=="],
"base-64": ["base-64@1.0.0", "", {}, "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg=="],
@@ -1666,7 +1693,7 @@
"camelcase-css": ["camelcase-css@2.0.1", "", {}, "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA=="],
- "caniuse-lite": ["caniuse-lite@1.0.30001750", "", {}, "sha512-cuom0g5sdX6rw00qOoLNSFCJ9/mYIsuSOA+yzpDw8eopiFqcVwQvZHqov0vmEighRxX++cfC0Vg1G+1Iy/mSpQ=="],
+ "caniuse-lite": ["caniuse-lite@1.0.30001749", "", {}, "sha512-0rw2fJOmLfnzCRbkm8EyHL8SvI2Apu5UbnQuTsJ0ClgrH8hcwFooJ1s5R0EP8o8aVrFu8++ae29Kt9/gZAZp/Q=="],
"ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="],
@@ -1734,6 +1761,8 @@
"compress-commons": ["compress-commons@6.0.2", "", { "dependencies": { "crc-32": "^1.2.0", "crc32-stream": "^6.0.0", "is-stream": "^2.0.1", "normalize-path": "^3.0.0", "readable-stream": "^4.0.0" } }, "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg=="],
+ "concurrently": ["concurrently@9.2.1", "", { "dependencies": { "chalk": "4.1.2", "rxjs": "7.8.2", "shell-quote": "1.8.3", "supports-color": "8.1.1", "tree-kill": "1.2.2", "yargs": "17.7.2" }, "bin": { "conc": "dist/bin/concurrently.js", "concurrently": "dist/bin/concurrently.js" } }, "sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng=="],
+
"condense-newlines": ["condense-newlines@0.2.1", "", { "dependencies": { "extend-shallow": "^2.0.1", "is-whitespace": "^0.3.0", "kind-of": "^3.0.2" } }, "sha512-P7X+QL9Hb9B/c8HI5BFFKmjgBu2XpQuF98WZ9XkO+dBGgk5XgwiQz7o1SmpglNWId3581UcS0SFAWfoIhMHPfg=="],
"confbox": ["confbox@0.2.2", "", {}, "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ=="],
@@ -1882,9 +1911,9 @@
"ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="],
- "electron-to-chromium": ["electron-to-chromium@1.5.235", "", {}, "sha512-i/7ntLFwOdoHY7sgjlTIDo4Sl8EdoTjWIaKinYOVfC6bOp71bmwenyZthWHcasxgHDNWbWxvG9M3Ia116zIaYQ=="],
+ "electron-to-chromium": ["electron-to-chromium@1.5.234", "", {}, "sha512-RXfEp2x+VRYn8jbKfQlRImzoJU01kyDvVPBmG39eU2iuRVhuS6vQNocB8J0/8GrIMLnPzgz4eW6WiRnJkTuNWg=="],
- "emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="],
+ "emoji-regex": ["emoji-regex@10.5.0", "", {}, "sha512-lb49vf1Xzfx080OKA0o6l8DQQpV+6Vg95zyCJX9VB/BqKYlhG7N4wgROUUHRA+ZPUefLnteQOad7z1kT2bV7bg=="],
"emoji-regex-xs": ["emoji-regex-xs@1.0.0", "", {}, "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg=="],
@@ -3026,6 +3055,8 @@
"run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
+ "rxjs": ["rxjs@7.8.2", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA=="],
+
"s-js": ["s-js@0.4.9", "", {}, "sha512-RtpOm+cM6O0sHg6IA70wH+UC3FZcND+rccBZpBAHzlUgNO2Bm5BN+FnM8+OBxzXdwpKWFwX11JGF0MFRkhSoIQ=="],
"safe-array-concat": ["safe-array-concat@1.1.3", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", "get-intrinsic": "^1.2.6", "has-symbols": "^1.1.0", "isarray": "^2.0.5" } }, "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q=="],
@@ -3164,7 +3195,7 @@
"statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="],
- "std-env": ["std-env@3.10.0", "", {}, "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg=="],
+ "std-env": ["std-env@3.9.0", "", {}, "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw=="],
"stop-iteration-iterator": ["stop-iteration-iterator@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "internal-slot": "^1.1.0" } }, "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ=="],
@@ -3214,7 +3245,7 @@
"superstruct": ["superstruct@1.0.4", "", {}, "sha512-7JpaAoX2NGyoFlI9NBh66BQXGONc+uE+MRS5i2iOBKuS4e+ccgMDjATgZldkah+33DakBxDHiss9kvUcGAO8UQ=="],
- "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
+ "supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="],
"supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
@@ -3268,6 +3299,8 @@
"tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="],
+ "tree-kill": ["tree-kill@1.2.2", "", { "bin": { "tree-kill": "cli.js" } }, "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A=="],
+
"tree-sitter": ["tree-sitter@0.22.4", "", { "dependencies": { "node-addon-api": "^8.3.0", "node-gyp-build": "^4.8.4" } }, "sha512-usbHZP9/oxNsUY65MQUsduGRqDHQOou1cagUSwjhoSYAmSahjQDAVsh9s+SlZkn8X8+O1FULRGwHu7AFP3kjzg=="],
"tree-sitter-bash": ["tree-sitter-bash@0.23.3", "", { "dependencies": { "node-addon-api": "^8.2.1", "node-gyp-build": "^4.8.2" }, "peerDependencies": { "tree-sitter": "^0.21.1" }, "optionalPeers": ["tree-sitter"] }, "sha512-36cg/GQ2YmIbeiBeqeuh4fBJ6i4kgVouDaqTxqih5ysPag+zHufyIaxMOFeM8CeplwAK/Luj1o5XHqgdAfoCZg=="],
@@ -3432,13 +3465,13 @@
"virtua": ["virtua@0.42.3", "", { "peerDependencies": { "react": ">=16.14.0", "react-dom": ">=16.14.0", "solid-js": ">=1.0", "svelte": ">=5.0", "vue": ">=3.2" }, "optionalPeers": ["react", "react-dom", "solid-js", "svelte", "vue"] }, "sha512-5FoAKcEvh05qsUF97Yz42SWJ7bwnPExjUYHGuoxz1EUtfWtaOgXaRwnylJbDpA0QcH1rKvJ2qsGRi9MK1fpQbg=="],
- "vite": ["vite@7.1.4", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.14" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-X5QFK4SGynAeeIt+A7ZWnApdUyHYm+pzv/8/A57LqSGcI88U6R6ipOs3uCesdc6yl7nl+zNO0t8LmqAdXcQihw=="],
+ "vite": ["vite@6.3.6", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-0msEVHJEScQbhkbVTb/4iHZdJ6SXp/AvxL2sjwYQFfBqleHtnCqv1J3sa9zbWz/6kW1m9Tfzn92vW+kZ1WV6QA=="],
"vite-plugin-dynamic-import": ["vite-plugin-dynamic-import@1.6.0", "", { "dependencies": { "acorn": "^8.12.1", "es-module-lexer": "^1.5.4", "fast-glob": "^3.3.2", "magic-string": "^0.30.11" } }, "sha512-TM0sz70wfzTIo9YCxVFwS8OA9lNREsh+0vMHGSkWDTZ7bgd1Yjs5RV8EgB634l/91IsXJReg0xtmuQqP0mf+rg=="],
"vite-plugin-icons-spritesheet": ["vite-plugin-icons-spritesheet@3.0.1", "", { "dependencies": { "chalk": "^5.4.1", "glob": "^11.0.1", "node-html-parser": "^7.0.1", "tinyexec": "^0.3.2" }, "peerDependencies": { "vite": ">=5.2.0" } }, "sha512-Cr0+Z6wRMwSwKisWW9PHeTjqmQFv0jwRQQMc3YgAhAgZEe03j21el0P/CA31KN/L5eiL1LhR14VTXl96LetonA=="],
- "vite-plugin-solid": ["vite-plugin-solid@2.11.8", "", { "dependencies": { "@babel/core": "^7.23.3", "@types/babel__core": "^7.20.4", "babel-preset-solid": "^1.8.4", "merge-anything": "^5.1.7", "solid-refresh": "^0.6.3", "vitefu": "^1.0.4" }, "peerDependencies": { "@testing-library/jest-dom": "^5.16.6 || ^5.17.0 || ^6.*", "solid-js": "^1.7.2", "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" }, "optionalPeers": ["@testing-library/jest-dom"] }, "sha512-hFrCxBfv3B1BmFqnJF4JOCYpjrmi/zwyeKjcomQ0khh8HFyQ8SbuBWQ7zGojfrz6HUOBFrJBNySDi/JgAHytWg=="],
+ "vite-plugin-solid": ["vite-plugin-solid@2.11.9", "", { "dependencies": { "@babel/core": "^7.23.3", "@types/babel__core": "^7.20.4", "babel-preset-solid": "^1.8.4", "merge-anything": "^5.1.7", "solid-refresh": "^0.6.3", "vitefu": "^1.0.4" }, "peerDependencies": { "@testing-library/jest-dom": "^5.16.6 || ^5.17.0 || ^6.*", "solid-js": "^1.7.2", "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" }, "optionalPeers": ["@testing-library/jest-dom"] }, "sha512-bTA6p+bspXZsuulSd2y6aTzegF8xGaJYcq1Uyh/mv+W4DQtzCgL9nN6n2fsTaxp/dMk+ZHHKgGndlNeooqHLKw=="],
"vitefu": ["vitefu@1.1.1", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" }, "optionalPeers": ["vite"] }, "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ=="],
@@ -3484,7 +3517,7 @@
"wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
- "ws": ["ws@7.5.10", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ=="],
+ "ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="],
"xdg-basedir": ["xdg-basedir@5.1.0", "", {}, "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ=="],
@@ -3542,16 +3575,12 @@
"@ai-sdk/google-vertex/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.7", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.5" }, "peerDependencies": { "zod": "^3.25.76 || ^4" } }, "sha512-o3BS5/t8KnBL3ubP8k3w77AByOypLm+pkIL/DCw0qKkhDbvhCy+L3hRTGPikpdb8WHcylAeKsjgwOxhj4cqTUA=="],
- "@astrojs/cloudflare/vite": ["vite@6.3.7", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-mQYaKepA0NGMBsz8Xktt3tJUG5ELE2iT7IJ+ssXI6nxVdE2sFc/d/6w/JByqMLvWg8hNKHpPgzjgOkrhpKFnrA=="],
-
"@astrojs/markdown-remark/@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.6.1", "", {}, "sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A=="],
"@astrojs/mdx/@astrojs/markdown-remark": ["@astrojs/markdown-remark@6.3.8", "", { "dependencies": { "@astrojs/internal-helpers": "0.7.4", "@astrojs/prism": "3.3.0", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "import-meta-resolve": "^4.2.0", "js-yaml": "^4.1.0", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remark-smartypants": "^3.0.2", "shiki": "^3.13.0", "smol-toml": "^1.4.2", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.1", "vfile": "^6.0.3" } }, "sha512-uFNyFWadnULWK2cOw4n0hLKeu+xaVWeuECdP10cQ3K2fkybtTlhb7J7TcScdjmS8Yps7oje9S/ehYMfZrhrgCg=="],
"@astrojs/sitemap/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
- "@astrojs/solid-js/vite": ["vite@6.3.7", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-mQYaKepA0NGMBsz8Xktt3tJUG5ELE2iT7IJ+ssXI6nxVdE2sFc/d/6w/JByqMLvWg8hNKHpPgzjgOkrhpKFnrA=="],
-
"@aws-crypto/sha256-browser/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="],
"@aws-crypto/util/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="],
@@ -3658,6 +3687,10 @@
"@openauthjs/openauth/jose": ["jose@5.9.6", "", {}, "sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ=="],
+ "@opencode-ai/ui/vite": ["vite@7.1.4", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.14" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-X5QFK4SGynAeeIt+A7ZWnApdUyHYm+pzv/8/A57LqSGcI88U6R6ipOs3uCesdc6yl7nl+zNO0t8LmqAdXcQihw=="],
+
+ "@opencode-ai/ui/vite-plugin-solid": ["vite-plugin-solid@2.11.8", "", { "dependencies": { "@babel/core": "^7.23.3", "@types/babel__core": "^7.20.4", "babel-preset-solid": "^1.8.4", "merge-anything": "^5.1.7", "solid-refresh": "^0.6.3", "vitefu": "^1.0.4" }, "peerDependencies": { "@testing-library/jest-dom": "^5.16.6 || ^5.17.0 || ^6.*", "solid-js": "^1.7.2", "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" }, "optionalPeers": ["@testing-library/jest-dom"] }, "sha512-hFrCxBfv3B1BmFqnJF4JOCYpjrmi/zwyeKjcomQ0khh8HFyQ8SbuBWQ7zGojfrz6HUOBFrJBNySDi/JgAHytWg=="],
+
"@opencode-ai/web/@shikijs/transformers": ["@shikijs/transformers@3.4.2", "", { "dependencies": { "@shikijs/core": "3.4.2", "@shikijs/types": "3.4.2" } }, "sha512-I5baLVi/ynLEOZoWSAMlACHNnG+yw5HDmse0oe+GW6U1u+ULdEB3UHiVWaHoJSSONV7tlcVxuaMy74sREDkSvg=="],
"@opencode-ai/web/@types/luxon": ["@types/luxon@3.6.2", "", {}, "sha512-R/BdP7OxEMc44l2Ex5lSXHoIXTB2JLNa3y2QISIbr58U/YcsffyQrYW//hZSdrfxrjRZj3GcUoxMPGdO8gSYuw=="],
@@ -3692,6 +3725,8 @@
"@slack/socket-mode/eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="],
+ "@slack/socket-mode/ws": ["ws@7.5.10", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ=="],
+
"@slack/web-api/@slack/logger": ["@slack/logger@3.0.0", "", { "dependencies": { "@types/node": ">=12.0.0" } }, "sha512-DTuBFbqu4gGfajREEMrkq5jBhcnskinhr4+AnfJEk48zhVeEv3XnUKGIX98B74kxhYsIMfApGGySTn7V3b5yBA=="],
"@slack/web-api/eventemitter3": ["eventemitter3@3.1.2", "", {}, "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q=="],
@@ -3750,8 +3785,6 @@
"astro/sharp": ["sharp@0.33.5", "", { "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.3", "semver": "^7.6.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.33.5", "@img/sharp-darwin-x64": "0.33.5", "@img/sharp-libvips-darwin-arm64": "1.0.4", "@img/sharp-libvips-darwin-x64": "1.0.4", "@img/sharp-libvips-linux-arm": "1.0.5", "@img/sharp-libvips-linux-arm64": "1.0.4", "@img/sharp-libvips-linux-s390x": "1.0.4", "@img/sharp-libvips-linux-x64": "1.0.4", "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", "@img/sharp-libvips-linuxmusl-x64": "1.0.4", "@img/sharp-linux-arm": "0.33.5", "@img/sharp-linux-arm64": "0.33.5", "@img/sharp-linux-s390x": "0.33.5", "@img/sharp-linux-x64": "0.33.5", "@img/sharp-linuxmusl-arm64": "0.33.5", "@img/sharp-linuxmusl-x64": "0.33.5", "@img/sharp-wasm32": "0.33.5", "@img/sharp-win32-ia32": "0.33.5", "@img/sharp-win32-x64": "0.33.5" } }, "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw=="],
- "astro/vite": ["vite@6.3.7", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-mQYaKepA0NGMBsz8Xktt3tJUG5ELE2iT7IJ+ssXI6nxVdE2sFc/d/6w/JByqMLvWg8hNKHpPgzjgOkrhpKFnrA=="],
-
"astro/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
"axios/form-data": ["form-data@4.0.4", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow=="],
@@ -3782,10 +3815,14 @@
"c12/pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="],
+ "chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
+
"clean-css/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
"compress-commons/is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="],
+ "concurrently/yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="],
+
"condense-newlines/kind-of": ["kind-of@3.2.2", "", { "dependencies": { "is-buffer": "^1.1.5" } }, "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ=="],
"cross-spawn/which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
@@ -3794,7 +3831,7 @@
"dir-glob/path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="],
- "dot-prop/type-fest": ["type-fest@5.1.0", "", { "dependencies": { "tagged-tag": "^1.0.0" } }, "sha512-wQ531tuWvB6oK+pchHIu5lHe5f5wpSCqB8Kf4dWQRbOYc9HTge7JL0G4Qd44bh6QuJCccIzL3bugb8GI0MwHrg=="],
+ "dot-prop/type-fest": ["type-fest@5.0.1", "", { "dependencies": { "tagged-tag": "^1.0.0" } }, "sha512-9MpwAI52m8H6ssA542UxSLnSiSD2dsC3/L85g6hVubLSXd82wdI80eZwTWhdOfN67NlA+D+oipAs1MlcTcu3KA=="],
"drizzle-kit/esbuild": ["esbuild@0.19.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.19.12", "@esbuild/android-arm": "0.19.12", "@esbuild/android-arm64": "0.19.12", "@esbuild/android-x64": "0.19.12", "@esbuild/darwin-arm64": "0.19.12", "@esbuild/darwin-x64": "0.19.12", "@esbuild/freebsd-arm64": "0.19.12", "@esbuild/freebsd-x64": "0.19.12", "@esbuild/linux-arm": "0.19.12", "@esbuild/linux-arm64": "0.19.12", "@esbuild/linux-ia32": "0.19.12", "@esbuild/linux-loong64": "0.19.12", "@esbuild/linux-mips64el": "0.19.12", "@esbuild/linux-ppc64": "0.19.12", "@esbuild/linux-riscv64": "0.19.12", "@esbuild/linux-s390x": "0.19.12", "@esbuild/linux-x64": "0.19.12", "@esbuild/netbsd-x64": "0.19.12", "@esbuild/openbsd-x64": "0.19.12", "@esbuild/sunos-x64": "0.19.12", "@esbuild/win32-arm64": "0.19.12", "@esbuild/win32-ia32": "0.19.12", "@esbuild/win32-x64": "0.19.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg=="],
@@ -3864,8 +3901,6 @@
"miniflare/sharp": ["sharp@0.33.5", "", { "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.3", "semver": "^7.6.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.33.5", "@img/sharp-darwin-x64": "0.33.5", "@img/sharp-libvips-darwin-arm64": "1.0.4", "@img/sharp-libvips-darwin-x64": "1.0.4", "@img/sharp-libvips-linux-arm": "1.0.5", "@img/sharp-libvips-linux-arm64": "1.0.4", "@img/sharp-libvips-linux-s390x": "1.0.4", "@img/sharp-libvips-linux-x64": "1.0.4", "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", "@img/sharp-libvips-linuxmusl-x64": "1.0.4", "@img/sharp-linux-arm": "0.33.5", "@img/sharp-linux-arm64": "0.33.5", "@img/sharp-linux-s390x": "0.33.5", "@img/sharp-linux-x64": "0.33.5", "@img/sharp-linuxmusl-arm64": "0.33.5", "@img/sharp-linuxmusl-x64": "0.33.5", "@img/sharp-wasm32": "0.33.5", "@img/sharp-win32-ia32": "0.33.5", "@img/sharp-win32-x64": "0.33.5" } }, "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw=="],
- "miniflare/ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="],
-
"miniflare/youch": ["youch@4.1.0-beta.10", "", { "dependencies": { "@poppinss/colors": "^4.1.5", "@poppinss/dumper": "^0.6.4", "@speed-highlight/core": "^1.2.7", "cookie": "^1.0.2", "youch-core": "^0.3.3" } }, "sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ=="],
"miniflare/zod": ["zod@3.22.3", "", {}, "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug=="],
@@ -4018,8 +4053,6 @@
"utif2/pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="],
- "vinxi/vite": ["vite@6.3.7", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-mQYaKepA0NGMBsz8Xktt3tJUG5ELE2iT7IJ+ssXI6nxVdE2sFc/d/6w/JByqMLvWg8hNKHpPgzjgOkrhpKFnrA=="],
-
"vinxi/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
"vite-plugin-icons-spritesheet/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
@@ -4036,6 +4069,8 @@
"wrap-ansi-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
+ "xml2js/sax": ["sax@1.4.1", "", {}, "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="],
+
"yargs/yargs-parser": ["yargs-parser@22.0.0", "", {}, "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw=="],
"zod-to-json-schema/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
@@ -4194,6 +4229,8 @@
"@modelcontextprotocol/sdk/express/serve-static": ["serve-static@2.2.0", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ=="],
+ "@modelcontextprotocol/sdk/express/statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="],
+
"@modelcontextprotocol/sdk/express/type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="],
"@octokit/auth-oauth-app/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@26.0.0", "", {}, "sha512-7AtcfKtpo77j7Ts73b4OWhOZHTKo/gGY8bB3bNBQz4H+GRSWqx2yvj8TXRsbdTE0eRmYmXOEY66jM7mJ7LzfsA=="],
@@ -4282,12 +4319,14 @@
"babel-plugin-module-resolver/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
- "bl/buffer/ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
-
"body-parser/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
"c12/pkg-types/pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="],
+ "concurrently/yargs/cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="],
+
+ "concurrently/yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
+
"cross-spawn/which/isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
"drizzle-kit/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.19.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA=="],
@@ -4574,6 +4613,14 @@
"babel-plugin-module-resolver/glob/path-scurry/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
+ "concurrently/yargs/cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
+
+ "concurrently/yargs/cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
+
+ "concurrently/yargs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
+
+ "concurrently/yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
+
"esbuild-plugin-copy/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
"giget/tar/minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
@@ -4584,6 +4631,8 @@
"nitropack/serve-static/send/fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="],
+ "nitropack/serve-static/send/statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="],
+
"opencontrol/@modelcontextprotocol/sdk/express/accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="],
"opencontrol/@modelcontextprotocol/sdk/express/body-parser": ["body-parser@2.2.0", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.0", "http-errors": "^2.0.0", "iconv-lite": "^0.6.3", "on-finished": "^2.4.1", "qs": "^6.14.0", "raw-body": "^3.0.0", "type-is": "^2.0.0" } }, "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg=="],
@@ -4604,6 +4653,8 @@
"opencontrol/@modelcontextprotocol/sdk/express/serve-static": ["serve-static@2.2.0", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ=="],
+ "opencontrol/@modelcontextprotocol/sdk/express/statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="],
+
"opencontrol/@modelcontextprotocol/sdk/express/type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="],
"pkg-up/find-up/locate-path/p-locate": ["p-locate@3.0.0", "", { "dependencies": { "p-limit": "^2.0.0" } }, "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ=="],
@@ -4632,6 +4683,10 @@
"@solidjs/start/shiki/@shikijs/engine-javascript/oniguruma-to-es/regex-recursion": ["regex-recursion@5.1.1", "", { "dependencies": { "regex": "^5.1.1", "regex-utilities": "^2.3.0" } }, "sha512-ae7SBCbzVNrIjgSbh7wMznPcQel1DNlDtzensnFxpiNpXt1U2ju/bHugH422r+4LAVS1FpW1YCwilmnNsjum9w=="],
+ "concurrently/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
+
+ "concurrently/yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
+
"nitropack/c12/giget/nypm/tinyexec": ["tinyexec@1.0.1", "", {}, "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw=="],
"opencontrol/@modelcontextprotocol/sdk/express/accepts/negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="],
diff --git a/packages/desktop/.claude/settings.local.json b/packages/desktop/.claude/settings.local.json
new file mode 100644
index 0000000000..3d49709307
--- /dev/null
+++ b/packages/desktop/.claude/settings.local.json
@@ -0,0 +1,29 @@
+{
+ "permissions": {
+ "allow": [
+ "Bash(npm run build)",
+ "Bash(opencode serve --help)",
+ "Read(//Users/jkneen/Documents/GitHub/flows/opencode-stt/packages/opencode/src/cli/cmd/**)",
+ "Read(//Users/jkneen/Documents/GitHub/flows/opencode-stt/packages/sdk/js/src/**)",
+ "Read(//Users/jkneen/Documents/GitHub/flows/opencode-stt/**)",
+ "Bash(curl -s http://localhost:4096)",
+ "Bash(curl -s http://localhost:4096/api/health)",
+ "Bash(curl -s http://localhost:4096/health)",
+ "Bash(lsof -i :4096)",
+ "Bash(curl -s http://localhost:4096/api/v1/session)",
+ "Bash(curl -v http://localhost:4096/v1/session)",
+ "Bash(curl -s http://localhost:4096/session)",
+ "Bash(curl -s http://localhost:4096/config)",
+ "Bash(curl -s \"http://localhost:4096/session?directory=/Users/jkneen/Documents/GitHub/flows/opencode-stt/packages/desktop\")",
+ "Bash(curl -v http://localhost:4096/session)",
+ "mcp__playwright__browser_navigate",
+ "mcp__playwright__browser_console_messages",
+ "mcp__playwright__browser_snapshot",
+ "mcp__playwright__browser_wait_for",
+ "mcp__playwright__browser_take_screenshot",
+ "Bash(chmod +x /Users/jkneen/Documents/GitHub/flows/opencode-stt/packages/desktop/scripts/tauri-dev.sh)"
+ ],
+ "deny": [],
+ "ask": []
+ }
+}
diff --git a/packages/desktop/.env.example b/packages/desktop/.env.example
new file mode 100644
index 0000000000..51f351c901
--- /dev/null
+++ b/packages/desktop/.env.example
@@ -0,0 +1,7 @@
+# OpenCode Server Configuration (not used when proxy is enabled)
+VITE_OPENCODE_SERVER_HOST=127.0.0.1
+VITE_OPENCODE_SERVER_PORT=4096
+
+# Vite Dev Server
+PORT=5173
+HOST=127.0.0.1
diff --git a/packages/desktop/.playwright-mcp/desktop-ui-loaded.png b/packages/desktop/.playwright-mcp/desktop-ui-loaded.png
new file mode 100644
index 0000000000..47cfc0049f
Binary files /dev/null and b/packages/desktop/.playwright-mcp/desktop-ui-loaded.png differ
diff --git a/packages/desktop/AGENTS.md b/packages/desktop/AGENTS.md
index 3137bddc25..d20a72ffbd 100644
--- a/packages/desktop/AGENTS.md
+++ b/packages/desktop/AGENTS.md
@@ -2,10 +2,24 @@
## Build/Test Commands
-- **Development**: `bun run dev` (starts Vite dev server on port 3000)
-- **Build**: `bun run build` (production build)
-- **Preview**: `bun run serve` (preview production build)
+### Development
+
+- **Web Dev**: `bun run dev` (starts Vite dev server on port 3000, responsive mobile UI at < 768px)
+- **macOS Desktop**: `bun run tauri:dev` or `cargo tauri dev`
+- **iOS Simulator**: `bun run ios:dev` or `cargo tauri ios dev "iPhone 16 Pro"`
- **Validation**: Use `bun run typecheck` only - do not build or run project for validation
+
+### Production Builds
+
+- **Build All**: `./scripts/build-all.sh` (builds web, macOS desktop, and iOS)
+- **Web Only**: `bun run build` (production web build)
+- **macOS Desktop**: `bun run build:macos` (creates .app and .dmg)
+- **iOS for Mac**: `bun run build:ios` (creates IPA that runs on iPhone, iPad, and Apple Silicon Macs)
+- **iOS Simulator**: `bun run build:ios-sim` (for testing in simulator)
+
+### Testing
+
+- **Preview**: `bun run serve` (preview production build)
- **Testing**: Do not create or run automated tests
## Code Style
diff --git a/packages/desktop/BUILD.md b/packages/desktop/BUILD.md
new file mode 100644
index 0000000000..253aaf6b79
--- /dev/null
+++ b/packages/desktop/BUILD.md
@@ -0,0 +1,150 @@
+# OpenCode Desktop - Build Guide
+
+## Platform Overview
+
+OpenCode Desktop can be built for three platforms:
+
+1. **macOS Desktop** - Traditional macOS app with desktop UI
+2. **iOS** - iPhone and iPad app with mobile UI
+3. **iOS on Mac** - iOS app running natively on Apple Silicon Macs with mobile UI
+
+## Prerequisites
+
+- macOS with Xcode installed
+- Rust and Cargo
+- Bun package manager
+- Tauri CLI with iOS support
+- Apple Developer account (for iOS builds)
+
+## Development
+
+### macOS Desktop
+
+```bash
+bun run tauri:dev
+# or
+cargo tauri dev
+```
+
+### iOS Simulator
+
+```bash
+bun run ios:dev
+# or
+cargo tauri ios dev "iPhone 16 Pro"
+```
+
+### Web (responsive mobile)
+
+```bash
+bun dev
+# Open http://localhost:3000 and resize window < 768px
+```
+
+## Building
+
+### Build All Platforms
+
+```bash
+./scripts/build-all.sh
+```
+
+### Build Individual Platforms
+
+#### macOS Desktop
+
+```bash
+bun run build:macos
+# Creates: src-tauri/target/release/bundle/macos/OpenCode Desktop.app
+# Creates: src-tauri/target/release/bundle/dmg/OpenCode Desktop_*.dmg
+```
+
+#### iOS (for iPhone, iPad, and Apple Silicon Macs)
+
+```bash
+bun run build:ios
+# Creates: src-tauri/gen/apple/build/arm64/Release-iphoneos/app_iOS.ipa
+```
+
+#### iOS Simulator Build
+
+```bash
+bun run build:ios-sim
+# Creates: src-tauri/gen/apple/build/arm64/Release-iphonesimulator/
+```
+
+## Outputs
+
+### macOS Desktop
+
+- **Location**: `src-tauri/target/release/bundle/macos/`
+- **Format**: `.app` bundle and `.dmg` installer
+- **UI**: Desktop layout with resizable panes
+- **Runs on**: Intel and Apple Silicon Macs
+
+### iOS App
+
+- **Location**: `src-tauri/gen/apple/build/arm64/Release-iphoneos/`
+- **Format**: `.ipa` package
+- **UI**: Mobile layout with bottom navigation
+- **Runs on**:
+ - iPhone (iOS 14+)
+ - iPad (iOS 14+)
+ - Apple Silicon Macs (M1/M2/M3/M4) via "Designed for iPad"
+
+## Configuration
+
+### macOS Desktop
+
+- Config: `src-tauri/tauri.conf.json`
+- Bundle ID: `ai.opencode.desktop`
+
+### iOS
+
+- Config: `src-tauri/tauri.ios.conf.json` (overrides)
+- Xcode Project: `src-tauri/gen/apple/app.xcodeproj`
+- Bundle ID: `ai.opencode.desktop`
+- Development Team: `SW75ZJJ5R6`
+
+## Mac Catalyst / Designed for iPad
+
+The iOS build is configured to run on Apple Silicon Macs via "Designed for iPad" mode:
+
+- **SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD**: Enabled
+- **UIDeviceFamily**: `[1, 2, 6]` (iPhone, iPad, Mac)
+- **TARGETED_DEVICE_FAMILY**: `"1,2,6"`
+
+This allows the iOS app to be installed and run natively on M1+ Macs while showing the mobile UI.
+
+## Testing
+
+### Test iOS app on Mac
+
+1. Build iOS: `bun run build:ios`
+2. Install the IPA on your Apple Silicon Mac
+3. The app will run with the mobile UI (bottom navigation, drawer menu, etc.)
+
+### Test responsive web version
+
+1. Run: `bun dev`
+2. Open browser to `http://localhost:3000`
+3. Resize window to < 768px width
+4. Mobile UI should activate automatically
+
+## Distribution
+
+### macOS Desktop
+
+- Use the `.dmg` for distribution
+- Can be signed and notarized for distribution outside App Store
+
+### iOS
+
+- Use `--export-method app-store-connect` for App Store
+- Use `--export-method release-testing` for TestFlight
+- The same build works on iPhone, iPad, and Mac
+
+```bash
+# Build for App Store
+cargo tauri ios build --export-method app-store-connect
+```
diff --git a/packages/desktop/PLATFORMS.md b/packages/desktop/PLATFORMS.md
new file mode 100644
index 0000000000..9101cc3d32
--- /dev/null
+++ b/packages/desktop/PLATFORMS.md
@@ -0,0 +1,122 @@
+# Platform Support
+
+OpenCode Desktop is a multi-platform application with different UI modes:
+
+## 🖥️ macOS Desktop
+
+- **UI**: Traditional desktop layout with resizable panes
+- **Build**: `bun run build:macos`
+- **Dev**: `bun run tauri:dev`
+- **Output**: `.app` bundle and `.dmg` installer
+- **Runs on**: Intel and Apple Silicon Macs
+
+## 📱 iOS Mobile
+
+- **UI**: Mobile-first layout with bottom navigation
+- **Build**: `bun run build:ios`
+- **Dev**: `bun run ios:dev`
+- **Output**: `.ipa` package
+- **Runs on**:
+ - iPhone (iOS 14+)
+ - iPad (iOS 14+)
+ - **Apple Silicon Macs (M1/M2/M3/M4)** ✨
+
+## 🌐 Web (Responsive)
+
+- **UI**: Responsive - desktop layout on wide screens, mobile layout on narrow screens
+- **Build**: `bun run build`
+- **Dev**: `bun run dev`
+- **Breakpoint**: 768px (mobile UI activates at < 768px width)
+- **Runs on**: Any modern web browser
+
+## Key Features by Platform
+
+| Feature | macOS Desktop | iOS | Web |
+| ------------------ | ------------- | -------------- | ------------ |
+| Resizable panes | ✅ | ❌ | ✅ |
+| Bottom navigation | ❌ | ✅ | ✅ (< 768px) |
+| Swipe gestures | ❌ | ✅ | ✅ (< 768px) |
+| Drawer menu | ❌ | ✅ | ✅ (< 768px) |
+| Keyboard shortcuts | ✅ | ⚠️ (limited) | ✅ |
+| Haptic feedback | ❌ | ✅ | ❌ |
+| File system access | ✅ (native) | ⚠️ (sandboxed) | ⚠️ (limited) |
+
+## iOS on Apple Silicon Macs
+
+The iOS build runs natively on Apple Silicon Macs using "Designed for iPad" mode:
+
+- Shows mobile UI (bottom nav, drawer, suggestion chips)
+- Runs as native app (not browser-based)
+- Installed from `.ipa` file
+- Uses mobile-optimized layout and interactions
+- Same binary as iPhone/iPad version
+
+**To install on Mac:**
+
+1. Build: `bun run build:ios`
+2. Locate IPA: `src-tauri/gen/apple/build/arm64/Release-iphoneos/app_iOS.ipa`
+3. Install via Finder or Apple Configurator
+4. App appears in Launchpad/Applications
+
+## Development Workflow
+
+### Testing Mobile UI
+
+1. **iOS Simulator**: Most accurate for iOS-specific features
+
+ ```bash
+ bun run ios:dev
+ ```
+
+2. **Browser (Responsive)**: Fastest for iteration
+
+ ```bash
+ bun dev
+ # Resize window to < 768px
+ ```
+
+3. **Apple Silicon Mac**: Test final iOS build on Mac
+ ```bash
+ bun run build:ios
+ # Install IPA on Mac
+ ```
+
+### Testing Desktop UI
+
+1. **macOS Native**:
+
+ ```bash
+ bun run tauri:dev
+ ```
+
+2. **Browser (Wide)**:
+ ```bash
+ bun dev
+ # Keep window > 768px
+ ```
+
+## Build Automation
+
+Build all platforms at once:
+
+```bash
+./scripts/build-all.sh
+```
+
+Outputs:
+
+- `src-tauri/target/release/bundle/macos/` - macOS desktop
+- `src-tauri/target/release/bundle/dmg/` - macOS installer
+- `src-tauri/gen/apple/build/arm64/Release-iphoneos/` - iOS app
+
+## Mobile UI Components
+
+The mobile UI includes these custom components:
+
+- `MobileLayout` - Single-pane navigation with tabs
+- `MobileNavigation` - Bottom tab bar (Files/Editor/Chat)
+- `MobileHeader` - Top header with title and menu button
+- `Drawer` - Slide-out settings drawer
+- `SuggestionChips` - Context-aware prompt suggestions
+
+Mobile detection is reactive and responds to window resizing in real-time.
diff --git a/packages/desktop/README.md b/packages/desktop/README.md
index 6a17645366..08b49fdaf8 100644
--- a/packages/desktop/README.md
+++ b/packages/desktop/README.md
@@ -10,14 +10,46 @@ $ npm install # or pnpm install or yarn install
### Learn more on the [Solid Website](https://solidjs.com) and come chat with us on our [Discord](https://discord.com/invite/solidjs)
+## Development
+
+### Web Development (Browser)
+Run backend + Vite dev server:
+```bash
+npm run dev:web
+```
+Then open: `http://127.0.0.1:5173/?directory=/Users/jkneen/Documents/GitHub/flows/opencode-stt/packages/desktop`
+
+### Desktop Development (Tauri Native App)
+Run backend + Vite + Tauri:
+```bash
+npm start
+# or
+npm run dev:tauri
+```
+
+### Services Architecture
+
+The desktop app requires:
+1. **OpenCode Backend** (`127.0.0.1:4096`) - API server
+2. **Vite Dev Server** (`127.0.0.1:5173`) - UI with proxy to backend
+3. **Tauri** - Native app wrapper (optional for browser-only dev)
+
+**Important:** All services use `127.0.0.1` (not `localhost`) to avoid IPv4/IPv6 networking issues.
+
+The startup scripts handle this automatically:
+- `npm run dev:web` - Backend + Vite (browser testing)
+- `npm start` - Backend + Vite + Tauri (native app)
+
## Available Scripts
-In the project directory, you can run:
+### `npm start` or `npm run dev:tauri`
+
+Runs the Tauri native desktop app with backend and Vite dev server.
-### `npm run dev` or `npm start`
+### `npm run dev:web`
-Runs the app in the development mode.
-Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
+Runs backend + Vite for browser-based development.
+Open [http://127.0.0.1:5173/?directory=/path/to/project](http://127.0.0.1:5173/?directory=/path/to/project)
The page will reload if you make edits.
diff --git a/packages/desktop/index.html b/packages/desktop/index.html
index 1ee727ff41..b742f223d2 100644
--- a/packages/desktop/index.html
+++ b/packages/desktop/index.html
@@ -2,8 +2,13 @@
-
+
+
+
opencode
diff --git a/packages/desktop/package.json b/packages/desktop/package.json
index 45acb25382..4f5a40a44a 100644
--- a/packages/desktop/package.json
+++ b/packages/desktop/package.json
@@ -1,26 +1,41 @@
{
"name": "@opencode-ai/desktop",
- "version": "0.15.4",
+ "version": "0.14.7",
"description": "",
"type": "module",
"scripts": {
- "start": "vite",
+ "start": "tauri dev",
"dev": "vite",
+ "dev:web": "./scripts/dev.sh",
+ "dev:tauri": "tauri dev",
+ "serve": "./scripts/dev.sh",
+ "dev:backend": "opencode serve -p 4096 -h 127.0.0.1",
"build": "vite build",
- "serve": "vite preview",
- "typecheck": "tsgo --noEmit"
+ "build:all": "npm run build && npm run build:tauri",
+ "build:tauri": "tauri build",
+ "build:macos": "tauri build --bundles app,dmg",
+ "build:ios": "tauri ios build --target aarch64",
+ "build:ios-sim": "tauri ios build --target aarch64-sim",
+ "preview": "vite preview",
+ "typecheck": "tsc --noEmit",
+ "tauri": "tauri",
+ "tauri:dev": "tauri dev",
+ "tauri:build": "tauri build",
+ "ios:dev": "tauri ios dev"
},
"license": "MIT",
"devDependencies": {
- "@tailwindcss/vite": "catalog:",
+ "@tailwindcss/vite": "4.1.11",
+ "@tauri-apps/api": "2.8.0",
+ "@tauri-apps/cli": "2.8.4",
"@tsconfig/bun": "1.0.9",
"@types/luxon": "3.7.1",
"@types/node": "catalog:",
+ "concurrently": "^9.1.2",
"typescript": "catalog:",
- "@typescript/native-preview": "catalog:",
- "vite": "catalog:",
+ "vite": "^6.0.0",
"vite-plugin-icons-spritesheet": "3.0.1",
- "vite-plugin-solid": "catalog:"
+ "vite-plugin-solid": "^2.11.6"
},
"dependencies": {
"@kobalte/core": "catalog:",
@@ -31,8 +46,7 @@
"@solid-primitives/scroll": "2.1.3",
"@solidjs/router": "0.15.3",
"@thisbeyond/solid-dnd": "0.7.5",
- "diff": "catalog:",
- "@opencode-ai/ui": "workspace:*",
+ "diff": "8.0.2",
"fuzzysort": "catalog:",
"luxon": "catalog:",
"marked": "16.2.0",
@@ -41,7 +55,7 @@
"solid-js": "catalog:",
"shiki": "3.9.2",
"solid-list": "0.3.0",
- "tailwindcss": "catalog:",
+ "tailwindcss": "4.1.11",
"virtua": "0.42.3"
},
"prettier": {
diff --git a/packages/desktop/scripts/build-all.sh b/packages/desktop/scripts/build-all.sh
new file mode 100755
index 0000000000..5e214e7121
--- /dev/null
+++ b/packages/desktop/scripts/build-all.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+set -e
+
+echo "🔨 Building OpenCode for all platforms..."
+
+# Build web assets
+echo "📦 Building web assets..."
+bun run build
+
+# Build macOS desktop app
+echo "🍎 Building macOS desktop app..."
+cargo tauri build --bundles app,dmg
+
+# Build iOS app (runs on iPhone, iPad, and Apple Silicon Macs)
+echo "📱 Building iOS app for Apple Silicon Macs..."
+cargo tauri ios build --target aarch64
+
+echo "✅ All builds complete!"
+echo ""
+echo "Outputs:"
+echo " macOS Desktop: src-tauri/target/release/bundle/macos/"
+echo " iOS (Mac): src-tauri/gen/apple/build/arm64/Release-iphoneos/"
diff --git a/packages/desktop/scripts/dev.sh b/packages/desktop/scripts/dev.sh
new file mode 100755
index 0000000000..721e425a54
--- /dev/null
+++ b/packages/desktop/scripts/dev.sh
@@ -0,0 +1,95 @@
+#!/bin/bash
+
+# OpenCode Desktop Development Launcher
+# Starts API, Web, and Desktop app
+
+set -e
+
+# Colors
+BLUE='\033[0;34m'
+GREEN='\033[0;32m'
+YELLOW='\033[0;33m'
+RED='\033[0;31m'
+NC='\033[0m' # No Color
+
+# Check if Backend is running
+check_backend() {
+ curl -s http://127.0.0.1:4096 > /dev/null 2>&1
+ return $?
+}
+
+# Start OpenCode Backend Server
+start_backend() {
+ export OPENCODE_PORT=4096
+ echo -e "${BLUE}[BACKEND]${NC} Starting OpenCode backend server on 127.0.0.1:4096..."
+ if command -v opencode &> /dev/null; then
+ opencode serve -p 4096 -h 127.0.0.1 &
+ BACKEND_PID=$!
+ echo -e "${BLUE}[BACKEND]${NC} Started (PID: $BACKEND_PID)"
+ sleep 2
+ else
+ echo -e "${RED}[BACKEND]${NC} opencode CLI not found. Install with: npm install -g @opencode-ai/cli"
+ exit 1
+ fi
+}
+
+# Start Web Frontend
+start_web() {
+ echo -e "${GREEN}[WEB]${NC} Starting web frontend..."
+ # Web frontend is served by the desktop app's Vite dev server
+ # This will be available at the desktop app's URL
+ echo -e "${GREEN}[WEB]${NC} Web frontend will be served by desktop app"
+}
+
+# Start Desktop
+start_desktop() {
+ echo -e "${YELLOW}[DESKTOP]${NC} Starting desktop app..."
+ npm run dev &
+ DESKTOP_PID=$!
+ echo -e "${YELLOW}[DESKTOP]${NC} Started (PID: $DESKTOP_PID)"
+}
+
+# Cleanup on exit
+cleanup() {
+ echo ""
+ echo -e "${RED}Shutting down...${NC}"
+ [ ! -z "$BACKEND_PID" ] && kill $BACKEND_PID 2>/dev/null && echo -e "${BLUE}[BACKEND]${NC} Stopped"
+ [ ! -z "$DESKTOP_PID" ] && kill $DESKTOP_PID 2>/dev/null && echo -e "${YELLOW}[DESKTOP]${NC} Stopped"
+ exit 0
+}
+
+trap cleanup INT TERM
+
+echo -e "${GREEN}========================================${NC}"
+echo -e "${GREEN} OpenCode Development Environment${NC}"
+echo -e "${GREEN}========================================${NC}"
+echo ""
+
+# Start backend server FIRST
+if check_backend; then
+ echo -e "${BLUE}[BACKEND]${NC} Already running ✓"
+else
+ start_backend
+ sleep 3
+fi
+
+# Then start desktop and web
+start_desktop
+sleep 2
+
+# Web frontend is served by desktop app
+start_web
+
+echo ""
+echo -e "${GREEN}========================================${NC}"
+echo -e "${GREEN} All services started!${NC}"
+echo -e "${GREEN}========================================${NC}"
+echo ""
+echo -e "Desktop App: ${YELLOW}http://127.0.0.1:5173${NC}"
+echo -e "Backend API: ${BLUE}http://127.0.0.1:4096${NC}"
+echo ""
+echo -e "Press ${RED}Ctrl+C${NC} to stop all services"
+echo ""
+
+# Wait for all background processes
+wait
diff --git a/packages/desktop/scripts/tauri-dev.sh b/packages/desktop/scripts/tauri-dev.sh
new file mode 100755
index 0000000000..355ad25a7b
--- /dev/null
+++ b/packages/desktop/scripts/tauri-dev.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+
+# Tauri Development Launcher
+# Starts Backend then Vite for Tauri
+
+set -e
+
+# Colors
+BLUE='\033[0;34m'
+GREEN='\033[0;32m'
+NC='\033[0m' # No Color
+
+# Check if Backend is running
+check_backend() {
+ curl -s http://127.0.0.1:4096 > /dev/null 2>&1
+ return $?
+}
+
+# Start OpenCode Backend Server
+start_backend() {
+ export OPENCODE_PORT=4096
+ echo -e "${BLUE}[BACKEND]${NC} Starting OpenCode backend server on 127.0.0.1:4096..."
+ if command -v opencode &> /dev/null; then
+ opencode serve -p 4096 -h 127.0.0.1 &
+ BACKEND_PID=$!
+ echo -e "${BLUE}[BACKEND]${NC} Started (PID: $BACKEND_PID)"
+ sleep 3
+ else
+ echo -e "${GREEN}[BACKEND]${NC} opencode CLI not found - Tauri will run without backend"
+ fi
+}
+
+# Cleanup on exit
+cleanup() {
+ [ ! -z "$BACKEND_PID" ] && kill $BACKEND_PID 2>/dev/null && echo -e "${BLUE}[BACKEND]${NC} Stopped"
+ exit 0
+}
+
+trap cleanup INT TERM
+
+echo -e "${GREEN}========================================${NC}"
+echo -e "${GREEN} OpenCode Tauri Development${NC}"
+echo -e "${GREEN}========================================${NC}"
+echo ""
+
+# Start backend server if not already running
+if check_backend; then
+ echo -e "${BLUE}[BACKEND]${NC} Already running ✓"
+else
+ start_backend
+fi
+
+echo -e "${GREEN}[VITE]${NC} Starting Vite dev server..."
+echo ""
+
+# Start Vite (Tauri will handle this)
+exec bun dev
diff --git a/packages/desktop/src-tauri/.gitignore b/packages/desktop/src-tauri/.gitignore
new file mode 100644
index 0000000000..502406b4ed
--- /dev/null
+++ b/packages/desktop/src-tauri/.gitignore
@@ -0,0 +1,4 @@
+# Generated by Cargo
+# will have compiled files and executables
+/target/
+/gen/schemas
diff --git a/packages/desktop/src-tauri/AGENTS.md b/packages/desktop/src-tauri/AGENTS.md
new file mode 100644
index 0000000000..2dadcb50db
--- /dev/null
+++ b/packages/desktop/src-tauri/AGENTS.md
@@ -0,0 +1,42 @@
+# Agent Guidelines for @opencode/desktop
+
+## Build/Test Commands
+
+### Development
+
+- **Web Dev**: `bun run dev` (starts Vite dev server on port 3000, responsive mobile UI at < 768px)
+- **macOS Desktop**: `bun run tauri:dev` or `cargo tauri dev`
+- **iOS Simulator**: `bun run ios:dev` or `cargo tauri ios dev "iPhone 16 Pro"`
+- **Validation**: Use `bun run typecheck` only - do not build or run project for validation
+
+### Production Builds
+
+- **Build All**: `./scripts/build-all.sh` (builds web, macOS desktop, and iOS)
+- **Web Only**: `bun run build` (production web build)
+- **macOS Desktop**: `bun run build:macos` (creates .app and .dmg)
+- **iOS for Mac**: `bun run build:ios` (creates IPA that runs on iPhone, iPad, and Apple Silicon Macs)
+- **iOS Simulator**: `bun run build:ios-sim` (for testing in simulator)
+
+### Testing
+
+- **Preview**: `bun run serve` (preview production build)
+- **Testing**: Do not create or run automated tests
+
+## Code Style
+
+- **Framework**: SolidJS with TypeScript
+- **Imports**: Use `@/` alias for src/ directory (e.g., `import Button from "@/ui/button"`)
+- **Formatting**: Prettier configured with semicolons disabled, 120 character line width
+- **Components**: Use function declarations, splitProps for component props
+- **Types**: Define interfaces for component props, avoid `any` type
+- **CSS**: TailwindCSS with custom CSS variables theme system
+- **Naming**: PascalCase for components, camelCase for variables/functions, snake_case for file names
+- **File Structure**: UI primitives in `/ui/`, higher-level components in `/components/`, pages in `/pages/`, providers in `/providers/`
+
+## Key Dependencies
+
+- SolidJS, @solidjs/router, @kobalte/core (UI primitives)
+- TailwindCSS 4.x with @tailwindcss/vite
+- Custom theme system with CSS variables
+- Tauri for desktop app framework
+- Rust backend with Cargo.toml configuration
diff --git a/packages/desktop/src-tauri/Cargo.lock b/packages/desktop/src-tauri/Cargo.lock
new file mode 100644
index 0000000000..7ceb8514a6
--- /dev/null
+++ b/packages/desktop/src-tauri/Cargo.lock
@@ -0,0 +1,5763 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "addr2line"
+version = "0.25.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b"
+dependencies = [
+ "gimli",
+]
+
+[[package]]
+name = "adler2"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
+
+[[package]]
+name = "ahash"
+version = "0.7.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9"
+dependencies = [
+ "getrandom 0.2.16",
+ "once_cell",
+ "version_check",
+]
+
+[[package]]
+name = "aho-corasick"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "alloc-no-stdlib"
+version = "2.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3"
+
+[[package]]
+name = "alloc-stdlib"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece"
+dependencies = [
+ "alloc-no-stdlib",
+]
+
+[[package]]
+name = "android_log-sys"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "84521a3cf562bc62942e294181d9eef17eb38ceb8c68677bc49f144e4c3d4f8d"
+
+[[package]]
+name = "android_logger"
+version = "0.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbb4e440d04be07da1f1bf44fb4495ebd58669372fe0cffa6e48595ac5bd88a3"
+dependencies = [
+ "android_log-sys",
+ "env_filter",
+ "log",
+]
+
+[[package]]
+name = "android_system_properties"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.100"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
+
+[[package]]
+name = "app"
+version = "0.1.0"
+dependencies = [
+ "log",
+ "rfd",
+ "serde",
+ "serde_json",
+ "tauri",
+ "tauri-build",
+ "tauri-plugin-log",
+]
+
+[[package]]
+name = "arrayvec"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
+
+[[package]]
+name = "ashpd"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6cbdf310d77fd3aaee6ea2093db7011dc2d35d2eb3481e5607f1f8d942ed99df"
+dependencies = [
+ "async-fs",
+ "async-net",
+ "enumflags2",
+ "futures-channel",
+ "futures-util",
+ "rand 0.9.2",
+ "raw-window-handle",
+ "serde",
+ "serde_repr",
+ "url",
+ "wayland-backend",
+ "wayland-client",
+ "wayland-protocols",
+ "zbus",
+]
+
+[[package]]
+name = "async-broadcast"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532"
+dependencies = [
+ "event-listener",
+ "event-listener-strategy",
+ "futures-core",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "async-channel"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2"
+dependencies = [
+ "concurrent-queue",
+ "event-listener-strategy",
+ "futures-core",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "async-executor"
+version = "1.13.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8"
+dependencies = [
+ "async-task",
+ "concurrent-queue",
+ "fastrand",
+ "futures-lite",
+ "pin-project-lite",
+ "slab",
+]
+
+[[package]]
+name = "async-fs"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8034a681df4aed8b8edbd7fbe472401ecf009251c8b40556b304567052e294c5"
+dependencies = [
+ "async-lock",
+ "blocking",
+ "futures-lite",
+]
+
+[[package]]
+name = "async-io"
+version = "2.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc"
+dependencies = [
+ "autocfg",
+ "cfg-if",
+ "concurrent-queue",
+ "futures-io",
+ "futures-lite",
+ "parking",
+ "polling",
+ "rustix",
+ "slab",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "async-lock"
+version = "3.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc"
+dependencies = [
+ "event-listener",
+ "event-listener-strategy",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "async-net"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7"
+dependencies = [
+ "async-io",
+ "blocking",
+ "futures-lite",
+]
+
+[[package]]
+name = "async-process"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75"
+dependencies = [
+ "async-channel",
+ "async-io",
+ "async-lock",
+ "async-signal",
+ "async-task",
+ "blocking",
+ "cfg-if",
+ "event-listener",
+ "futures-lite",
+ "rustix",
+]
+
+[[package]]
+name = "async-recursion"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
+[[package]]
+name = "async-signal"
+version = "0.2.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c"
+dependencies = [
+ "async-io",
+ "async-lock",
+ "atomic-waker",
+ "cfg-if",
+ "futures-core",
+ "futures-io",
+ "rustix",
+ "signal-hook-registry",
+ "slab",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "async-task"
+version = "4.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de"
+
+[[package]]
+name = "async-trait"
+version = "0.1.89"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
+[[package]]
+name = "atk"
+version = "0.18.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "241b621213072e993be4f6f3a9e4b45f65b7e6faad43001be957184b7bb1824b"
+dependencies = [
+ "atk-sys",
+ "glib",
+ "libc",
+]
+
+[[package]]
+name = "atk-sys"
+version = "0.18.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c5e48b684b0ca77d2bbadeef17424c2ea3c897d44d566a1617e7e8f30614d086"
+dependencies = [
+ "glib-sys",
+ "gobject-sys",
+ "libc",
+ "system-deps",
+]
+
+[[package]]
+name = "atomic-waker"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
+
+[[package]]
+name = "autocfg"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
+
+[[package]]
+name = "backtrace"
+version = "0.3.76"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6"
+dependencies = [
+ "addr2line",
+ "cfg-if",
+ "libc",
+ "miniz_oxide",
+ "object",
+ "rustc-demangle",
+ "windows-link 0.2.1",
+]
+
+[[package]]
+name = "base64"
+version = "0.21.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
+
+[[package]]
+name = "base64"
+version = "0.22.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bitflags"
+version = "2.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "bitvec"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
+dependencies = [
+ "funty",
+ "radium",
+ "tap",
+ "wyz",
+]
+
+[[package]]
+name = "block-buffer"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "block2"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f"
+dependencies = [
+ "objc2 0.5.2",
+]
+
+[[package]]
+name = "block2"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5"
+dependencies = [
+ "objc2 0.6.3",
+]
+
+[[package]]
+name = "blocking"
+version = "1.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21"
+dependencies = [
+ "async-channel",
+ "async-task",
+ "futures-io",
+ "futures-lite",
+ "piper",
+]
+
+[[package]]
+name = "borsh"
+version = "1.5.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce"
+dependencies = [
+ "borsh-derive",
+ "cfg_aliases",
+]
+
+[[package]]
+name = "borsh-derive"
+version = "1.5.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fdd1d3c0c2f5833f22386f252fe8ed005c7f59fdcddeef025c01b4c3b9fd9ac3"
+dependencies = [
+ "once_cell",
+ "proc-macro-crate 3.4.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
+[[package]]
+name = "brotli"
+version = "8.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560"
+dependencies = [
+ "alloc-no-stdlib",
+ "alloc-stdlib",
+ "brotli-decompressor",
+]
+
+[[package]]
+name = "brotli-decompressor"
+version = "5.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03"
+dependencies = [
+ "alloc-no-stdlib",
+ "alloc-stdlib",
+]
+
+[[package]]
+name = "bumpalo"
+version = "3.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
+
+[[package]]
+name = "byte-unit"
+version = "5.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1cd29c3c585209b0cbc7309bfe3ed7efd8c84c21b7af29c8bfae908f8777174"
+dependencies = [
+ "rust_decimal",
+ "serde",
+ "utf8-width",
+]
+
+[[package]]
+name = "bytecheck"
+version = "0.6.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2"
+dependencies = [
+ "bytecheck_derive",
+ "ptr_meta",
+ "simdutf8",
+]
+
+[[package]]
+name = "bytecheck_derive"
+version = "0.6.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "bytemuck"
+version = "1.24.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4"
+
+[[package]]
+name = "byteorder"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
+[[package]]
+name = "bytes"
+version = "1.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
+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.9.4",
+ "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.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "276a59bf2b2c967788139340c9f0c5b12d7fd6630315c15c217e559de85d2609"
+dependencies = [
+ "serde_core",
+]
+
+[[package]]
+name = "cargo-platform"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "cargo_metadata"
+version = "0.19.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba"
+dependencies = [
+ "camino",
+ "cargo-platform",
+ "semver",
+ "serde",
+ "serde_json",
+ "thiserror 2.0.17",
+]
+
+[[package]]
+name = "cargo_toml"
+version = "0.22.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77"
+dependencies = [
+ "serde",
+ "toml 0.9.7",
+]
+
+[[package]]
+name = "cc"
+version = "1.2.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1d05d92f4b1fd76aad469d46cdd858ca761576082cd37df81416691e50199fb"
+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.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
+
+[[package]]
+name = "cfg_aliases"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
+
+[[package]]
+name = "chrono"
+version = "0.4.42"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
+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 = "concurrent-queue"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
+dependencies = [
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "convert_case"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
+
+[[package]]
+name = "cookie"
+version = "0.18.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747"
+dependencies = [
+ "time",
+ "version_check",
+]
+
+[[package]]
+name = "core-foundation"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.8.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
+
+[[package]]
+name = "core-graphics"
+version = "0.24.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1"
+dependencies = [
+ "bitflags 2.9.4",
+ "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.9.4",
+ "core-foundation",
+ "libc",
+]
+
+[[package]]
+name = "cpufeatures"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "crc32fast"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "crossbeam-channel"
+version = "0.5.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
+dependencies = [
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
+
+[[package]]
+name = "crypto-common"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
+dependencies = [
+ "generic-array",
+ "typenum",
+]
+
+[[package]]
+name = "cssparser"
+version = "0.29.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f93d03419cb5950ccfd3daf3ff1c7a36ace64609a1a8746d493df1ca0afde0fa"
+dependencies = [
+ "cssparser-macros",
+ "dtoa-short",
+ "itoa",
+ "matches",
+ "phf 0.10.1",
+ "proc-macro2",
+ "quote",
+ "smallvec",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "cssparser-macros"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
+dependencies = [
+ "quote",
+ "syn 2.0.106",
+]
+
+[[package]]
+name = "ctor"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501"
+dependencies = [
+ "quote",
+ "syn 2.0.106",
+]
+
+[[package]]
+name = "darling"
+version = "0.21.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0"
+dependencies = [
+ "darling_core",
+ "darling_macro",
+]
+
+[[package]]
+name = "darling_core"
+version = "0.21.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4"
+dependencies = [
+ "fnv",
+ "ident_case",
+ "proc-macro2",
+ "quote",
+ "strsim",
+ "syn 2.0.106",
+]
+
+[[package]]
+name = "darling_macro"
+version = "0.21.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81"
+dependencies = [
+ "darling_core",
+ "quote",
+ "syn 2.0.106",
+]
+
+[[package]]
+name = "deranged"
+version = "0.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a41953f86f8a05768a6cda24def994fd2f424b04ec5c719cf89989779f199071"
+dependencies = [
+ "powerfmt",
+ "serde_core",
+]
+
+[[package]]
+name = "derive_more"
+version = "0.99.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f"
+dependencies = [
+ "convert_case",
+ "proc-macro2",
+ "quote",
+ "rustc_version",
+ "syn 2.0.106",
+]
+
+[[package]]
+name = "digest"
+version = "0.10.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
+dependencies = [
+ "block-buffer",
+ "crypto-common",
+]
+
+[[package]]
+name = "dirs"
+version = "6.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
+dependencies = [
+ "dirs-sys",
+]
+
+[[package]]
+name = "dirs-sys"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
+dependencies = [
+ "libc",
+ "option-ext",
+ "redox_users",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "dispatch"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b"
+
+[[package]]
+name = "dispatch2"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec"
+dependencies = [
+ "bitflags 2.9.4",
+ "block2 0.6.2",
+ "libc",
+ "objc2 0.6.3",
+]
+
+[[package]]
+name = "displaydoc"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
+[[package]]
+name = "dlib"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
+dependencies = [
+ "libloading",
+]
+
+[[package]]
+name = "dlopen2"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b54f373ccf864bf587a89e880fb7610f8d73f3045f13580948ccbcaff26febff"
+dependencies = [
+ "dlopen2_derive",
+ "libc",
+ "once_cell",
+ "winapi",
+]
+
+[[package]]
+name = "dlopen2_derive"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "788160fb30de9cdd857af31c6a2675904b16ece8fc2737b2c7127ba368c9d0f4"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
+[[package]]
+name = "downcast-rs"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
+
+[[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.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04"
+
+[[package]]
+name = "dtoa-short"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87"
+dependencies = [
+ "dtoa",
+]
+
+[[package]]
+name = "dunce"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
+
+[[package]]
+name = "dyn-clone"
+version = "1.0.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555"
+
+[[package]]
+name = "embed-resource"
+version = "3.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55a075fc573c64510038d7ee9abc7990635863992f83ebc52c8b433b8411a02e"
+dependencies = [
+ "cc",
+ "memchr",
+ "rustc_version",
+ "toml 0.9.7",
+ "vswhom",
+ "winreg",
+]
+
+[[package]]
+name = "embed_plist"
+version = "1.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7"
+
+[[package]]
+name = "endi"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf"
+
+[[package]]
+name = "enumflags2"
+version = "0.7.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef"
+dependencies = [
+ "enumflags2_derive",
+ "serde",
+]
+
+[[package]]
+name = "enumflags2_derive"
+version = "0.7.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
+[[package]]
+name = "env_filter"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0"
+dependencies = [
+ "log",
+ "regex",
+]
+
+[[package]]
+name = "equivalent"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
+
+[[package]]
+name = "erased-serde"
+version = "0.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "259d404d09818dec19332e31d94558aeb442fea04c817006456c24b5460bbd4b"
+dependencies = [
+ "serde",
+ "serde_core",
+ "typeid",
+]
+
+[[package]]
+name = "errno"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
+dependencies = [
+ "libc",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "event-listener"
+version = "5.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab"
+dependencies = [
+ "concurrent-queue",
+ "parking",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "event-listener-strategy"
+version = "0.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93"
+dependencies = [
+ "event-listener",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "fastrand"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
+
+[[package]]
+name = "fdeflate"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c"
+dependencies = [
+ "simd-adler32",
+]
+
+[[package]]
+name = "fern"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4316185f709b23713e41e3195f90edef7fb00c3ed4adc79769cf09cc762a3b29"
+dependencies = [
+ "log",
+]
+
+[[package]]
+name = "field-offset"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f"
+dependencies = [
+ "memoffset",
+ "rustc_version",
+]
+
+[[package]]
+name = "find-msvc-tools"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0399f9d26e5191ce32c498bebd31e7a3ceabc2745f0ac54af3f335126c3f24b3"
+
+[[package]]
+name = "flate2"
+version = "1.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9"
+dependencies = [
+ "crc32fast",
+ "miniz_oxide",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "foreign-types"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965"
+dependencies = [
+ "foreign-types-macros",
+ "foreign-types-shared",
+]
+
+[[package]]
+name = "foreign-types-macros"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
+[[package]]
+name = "foreign-types-shared"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b"
+
+[[package]]
+name = "form_urlencoded"
+version = "1.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf"
+dependencies = [
+ "percent-encoding",
+]
+
+[[package]]
+name = "funty"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
+
+[[package]]
+name = "futf"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843"
+dependencies = [
+ "mac",
+ "new_debug_unreachable",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
+dependencies = [
+ "futures-core",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
+
+[[package]]
+name = "futures-executor"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-io"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
+
+[[package]]
+name = "futures-lite"
+version = "2.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad"
+dependencies = [
+ "fastrand",
+ "futures-core",
+ "futures-io",
+ "parking",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "futures-macro"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
+[[package]]
+name = "futures-sink"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
+
+[[package]]
+name = "futures-task"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
+
+[[package]]
+name = "futures-util"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
+dependencies = [
+ "futures-core",
+ "futures-io",
+ "futures-macro",
+ "futures-sink",
+ "futures-task",
+ "memchr",
+ "pin-project-lite",
+ "pin-utils",
+ "slab",
+]
+
+[[package]]
+name = "fxhash"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
+dependencies = [
+ "byteorder",
+]
+
+[[package]]
+name = "gdk"
+version = "0.18.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9f245958c627ac99d8e529166f9823fb3b838d1d41fd2b297af3075093c2691"
+dependencies = [
+ "cairo-rs",
+ "gdk-pixbuf",
+ "gdk-sys",
+ "gio",
+ "glib",
+ "libc",
+ "pango",
+]
+
+[[package]]
+name = "gdk-pixbuf"
+version = "0.18.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50e1f5f1b0bfb830d6ccc8066d18db35c487b1b2b1e8589b5dfe9f07e8defaec"
+dependencies = [
+ "gdk-pixbuf-sys",
+ "gio",
+ "glib",
+ "libc",
+ "once_cell",
+]
+
+[[package]]
+name = "gdk-pixbuf-sys"
+version = "0.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9839ea644ed9c97a34d129ad56d38a25e6756f99f3a88e15cd39c20629caf7"
+dependencies = [
+ "gio-sys",
+ "glib-sys",
+ "gobject-sys",
+ "libc",
+ "system-deps",
+]
+
+[[package]]
+name = "gdk-sys"
+version = "0.18.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c2d13f38594ac1e66619e188c6d5a1adb98d11b2fcf7894fc416ad76aa2f3f7"
+dependencies = [
+ "cairo-sys-rs",
+ "gdk-pixbuf-sys",
+ "gio-sys",
+ "glib-sys",
+ "gobject-sys",
+ "libc",
+ "pango-sys",
+ "pkg-config",
+ "system-deps",
+]
+
+[[package]]
+name = "gdkwayland-sys"
+version = "0.18.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "140071d506d223f7572b9f09b5e155afbd77428cd5cc7af8f2694c41d98dfe69"
+dependencies = [
+ "gdk-sys",
+ "glib-sys",
+ "gobject-sys",
+ "libc",
+ "pkg-config",
+ "system-deps",
+]
+
+[[package]]
+name = "gdkx11"
+version = "0.18.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3caa00e14351bebbc8183b3c36690327eb77c49abc2268dd4bd36b856db3fbfe"
+dependencies = [
+ "gdk",
+ "gdkx11-sys",
+ "gio",
+ "glib",
+ "libc",
+ "x11",
+]
+
+[[package]]
+name = "gdkx11-sys"
+version = "0.18.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e2e7445fe01ac26f11601db260dd8608fe172514eb63b3b5e261ea6b0f4428d"
+dependencies = [
+ "gdk-sys",
+ "glib-sys",
+ "libc",
+ "system-deps",
+ "x11",
+]
+
+[[package]]
+name = "generic-array"
+version = "0.14.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.1.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi 0.9.0+wasi-snapshot-preview1",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi 0.11.1+wasi-snapshot-preview1",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "r-efi",
+ "wasi 0.14.7+wasi-0.2.4",
+]
+
+[[package]]
+name = "gimli"
+version = "0.32.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7"
+
+[[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.9.4",
+ "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.106",
+]
+
+[[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.106",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+dependencies = [
+ "ahash",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
+
+[[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 = "hermit-abi"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
+
+[[package]]
+name = "hex"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
+
+[[package]]
+name = "html5ever"
+version = "0.29.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b7410cae13cbc75623c98ac4cbfd1f0bedddf3227afc24f370cf0f50a44a11c"
+dependencies = [
+ "log",
+ "mac",
+ "markup5ever",
+ "match_token",
+]
+
+[[package]]
+name = "http"
+version = "1.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565"
+dependencies = [
+ "bytes",
+ "fnv",
+ "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 = "http-range"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573"
+
+[[package]]
+name = "httparse"
+version = "1.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
+
+[[package]]
+name = "hyper"
+version = "1.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e"
+dependencies = [
+ "atomic-waker",
+ "bytes",
+ "futures-channel",
+ "futures-core",
+ "http",
+ "http-body",
+ "httparse",
+ "itoa",
+ "pin-project-lite",
+ "pin-utils",
+ "smallvec",
+ "tokio",
+ "want",
+]
+
+[[package]]
+name = "hyper-util"
+version = "0.1.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8"
+dependencies = [
+ "base64 0.22.1",
+ "bytes",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "http",
+ "http-body",
+ "hyper",
+ "ipnet",
+ "libc",
+ "percent-encoding",
+ "pin-project-lite",
+ "socket2",
+ "tokio",
+ "tower-service",
+ "tracing",
+]
+
+[[package]]
+name = "iana-time-zone"
+version = "0.1.64"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb"
+dependencies = [
+ "android_system_properties",
+ "core-foundation-sys",
+ "iana-time-zone-haiku",
+ "js-sys",
+ "log",
+ "wasm-bindgen",
+ "windows-core 0.62.2",
+]
+
+[[package]]
+name = "iana-time-zone-haiku"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "ico"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc50b891e4acf8fe0e71ef88ec43ad82ee07b3810ad09de10f1d01f072ed4b98"
+dependencies = [
+ "byteorder",
+ "png",
+]
+
+[[package]]
+name = "icu_collections"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47"
+dependencies = [
+ "displaydoc",
+ "potential_utf",
+ "yoke",
+ "zerofrom",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_locale_core"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a"
+dependencies = [
+ "displaydoc",
+ "litemap",
+ "tinystr",
+ "writeable",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_normalizer"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979"
+dependencies = [
+ "displaydoc",
+ "icu_collections",
+ "icu_normalizer_data",
+ "icu_properties",
+ "icu_provider",
+ "smallvec",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_normalizer_data"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3"
+
+[[package]]
+name = "icu_properties"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b"
+dependencies = [
+ "displaydoc",
+ "icu_collections",
+ "icu_locale_core",
+ "icu_properties_data",
+ "icu_provider",
+ "potential_utf",
+ "zerotrie",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_properties_data"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632"
+
+[[package]]
+name = "icu_provider"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af"
+dependencies = [
+ "displaydoc",
+ "icu_locale_core",
+ "stable_deref_trait",
+ "tinystr",
+ "writeable",
+ "yoke",
+ "zerofrom",
+ "zerotrie",
+ "zerovec",
+]
+
+[[package]]
+name = "ident_case"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
+
+[[package]]
+name = "idna"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de"
+dependencies = [
+ "idna_adapter",
+ "smallvec",
+ "utf8_iter",
+]
+
+[[package]]
+name = "idna_adapter"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
+dependencies = [
+ "icu_normalizer",
+ "icu_properties",
+]
+
+[[package]]
+name = "indexmap"
+version = "1.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
+dependencies = [
+ "autocfg",
+ "hashbrown 0.12.3",
+ "serde",
+]
+
+[[package]]
+name = "indexmap"
+version = "2.11.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5"
+dependencies = [
+ "equivalent",
+ "hashbrown 0.16.0",
+ "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 = "io-uring"
+version = "0.7.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b"
+dependencies = [
+ "bitflags 2.9.4",
+ "cfg-if",
+ "libc",
+]
+
+[[package]]
+name = "ipnet"
+version = "2.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
+
+[[package]]
+name = "iri-string"
+version = "0.7.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2"
+dependencies = [
+ "memchr",
+ "serde",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
+
+[[package]]
+name = "javascriptcore-rs"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca5671e9ffce8ffba57afc24070e906da7fc4b1ba66f2cabebf61bf2ea257fcc"
+dependencies = [
+ "bitflags 1.3.2",
+ "glib",
+ "javascriptcore-rs-sys",
+]
+
+[[package]]
+name = "javascriptcore-rs-sys"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af1be78d14ffa4b75b66df31840478fef72b51f8c2465d4ca7c194da9f7a5124"
+dependencies = [
+ "glib-sys",
+ "gobject-sys",
+ "libc",
+ "system-deps",
+]
+
+[[package]]
+name = "jni"
+version = "0.21.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97"
+dependencies = [
+ "cesu8",
+ "cfg-if",
+ "combine",
+ "jni-sys",
+ "log",
+ "thiserror 1.0.69",
+ "walkdir",
+ "windows-sys 0.45.0",
+]
+
+[[package]]
+name = "jni-sys"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
+
+[[package]]
+name = "js-sys"
+version = "0.3.81"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305"
+dependencies = [
+ "once_cell",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "json-patch"
+version = "3.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "863726d7afb6bc2590eeff7135d923545e5e964f004c2ccf8716c25e70a86f08"
+dependencies = [
+ "jsonptr",
+ "serde",
+ "serde_json",
+ "thiserror 1.0.69",
+]
+
+[[package]]
+name = "jsonptr"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5dea2b27dd239b2556ed7a25ba842fe47fd602e7fc7433c2a8d6106d4d9edd70"
+dependencies = [
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "keyboard-types"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a"
+dependencies = [
+ "bitflags 2.9.4",
+ "serde",
+ "unicode-segmentation",
+]
+
+[[package]]
+name = "kuchikiki"
+version = "0.8.8-speedreader"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02cb977175687f33fa4afa0c95c112b987ea1443e5a51c8f8ff27dc618270cc2"
+dependencies = [
+ "cssparser",
+ "html5ever",
+ "indexmap 2.11.4",
+ "selectors",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
+
+[[package]]
+name = "libappindicator"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "03589b9607c868cc7ae54c0b2a22c8dc03dd41692d48f2d7df73615c6a95dc0a"
+dependencies = [
+ "glib",
+ "gtk",
+ "gtk-sys",
+ "libappindicator-sys",
+ "log",
+]
+
+[[package]]
+name = "libappindicator-sys"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e9ec52138abedcc58dc17a7c6c0c00a2bdb4f3427c7f63fa97fd0d859155caf"
+dependencies = [
+ "gtk-sys",
+ "libloading",
+ "once_cell",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.176"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174"
+
+[[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.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb"
+dependencies = [
+ "bitflags 2.9.4",
+ "libc",
+]
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
+
+[[package]]
+name = "litemap"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
+
+[[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.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
+dependencies = [
+ "value-bag",
+]
+
+[[package]]
+name = "mac"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
+
+[[package]]
+name = "markup5ever"
+version = "0.14.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7a7213d12e1864c0f002f52c2923d4556935a43dec5e71355c2760e0f6e7a18"
+dependencies = [
+ "log",
+ "phf 0.11.3",
+ "phf_codegen 0.11.3",
+ "string_cache",
+ "string_cache_codegen",
+ "tendril",
+]
+
+[[package]]
+name = "match_token"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
+[[package]]
+name = "matches"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
+
+[[package]]
+name = "memchr"
+version = "2.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
+
+[[package]]
+name = "memoffset"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "mime"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
+
+[[package]]
+name = "miniz_oxide"
+version = "0.8.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
+dependencies = [
+ "adler2",
+ "simd-adler32",
+]
+
+[[package]]
+name = "mio"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c"
+dependencies = [
+ "libc",
+ "wasi 0.11.1+wasi-snapshot-preview1",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "muda"
+version = "0.17.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01c1738382f66ed56b3b9c8119e794a2e23148ac8ea214eda86622d4cb9d415a"
+dependencies = [
+ "crossbeam-channel",
+ "dpi",
+ "gtk",
+ "keyboard-types",
+ "objc2 0.6.3",
+ "objc2-app-kit",
+ "objc2-core-foundation",
+ "objc2-foundation 0.3.2",
+ "once_cell",
+ "png",
+ "serde",
+ "thiserror 2.0.17",
+ "windows-sys 0.60.2",
+]
+
+[[package]]
+name = "ndk"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4"
+dependencies = [
+ "bitflags 2.9.4",
+ "jni-sys",
+ "log",
+ "ndk-sys",
+ "num_enum",
+ "raw-window-handle",
+ "thiserror 1.0.69",
+]
+
+[[package]]
+name = "ndk-context"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b"
+
+[[package]]
+name = "ndk-sys"
+version = "0.6.0+11769913"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873"
+dependencies = [
+ "jni-sys",
+]
+
+[[package]]
+name = "new_debug_unreachable"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
+
+[[package]]
+name = "nix"
+version = "0.30.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
+dependencies = [
+ "bitflags 2.9.4",
+ "cfg-if",
+ "cfg_aliases",
+ "libc",
+ "memoffset",
+]
+
+[[package]]
+name = "nodrop"
+version = "0.1.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
+
+[[package]]
+name = "num-conv"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
+
+[[package]]
+name = "num-traits"
+version = "0.2.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "num_enum"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a"
+dependencies = [
+ "num_enum_derive",
+ "rustversion",
+]
+
+[[package]]
+name = "num_enum_derive"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d"
+dependencies = [
+ "proc-macro-crate 3.4.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
+[[package]]
+name = "num_threads"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "objc-sys"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310"
+
+[[package]]
+name = "objc2"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804"
+dependencies = [
+ "objc-sys",
+ "objc2-encode",
+]
+
+[[package]]
+name = "objc2"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05"
+dependencies = [
+ "objc2-encode",
+ "objc2-exception-helper",
+]
+
+[[package]]
+name = "objc2-app-kit"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c"
+dependencies = [
+ "bitflags 2.9.4",
+ "block2 0.6.2",
+ "libc",
+ "objc2 0.6.3",
+ "objc2-cloud-kit",
+ "objc2-core-data",
+ "objc2-core-foundation",
+ "objc2-core-graphics",
+ "objc2-core-image",
+ "objc2-core-text",
+ "objc2-core-video",
+ "objc2-foundation 0.3.2",
+ "objc2-quartz-core 0.3.2",
+]
+
+[[package]]
+name = "objc2-cloud-kit"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c"
+dependencies = [
+ "bitflags 2.9.4",
+ "objc2 0.6.3",
+ "objc2-foundation 0.3.2",
+]
+
+[[package]]
+name = "objc2-core-data"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa"
+dependencies = [
+ "bitflags 2.9.4",
+ "objc2 0.6.3",
+ "objc2-foundation 0.3.2",
+]
+
+[[package]]
+name = "objc2-core-foundation"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536"
+dependencies = [
+ "bitflags 2.9.4",
+ "dispatch2",
+ "objc2 0.6.3",
+]
+
+[[package]]
+name = "objc2-core-graphics"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807"
+dependencies = [
+ "bitflags 2.9.4",
+ "dispatch2",
+ "objc2 0.6.3",
+ "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 0.6.3",
+ "objc2-foundation 0.3.2",
+]
+
+[[package]]
+name = "objc2-core-text"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d"
+dependencies = [
+ "bitflags 2.9.4",
+ "objc2 0.6.3",
+ "objc2-core-foundation",
+ "objc2-core-graphics",
+]
+
+[[package]]
+name = "objc2-core-video"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d425caf1df73233f29fd8a5c3e5edbc30d2d4307870f802d18f00d83dc5141a6"
+dependencies = [
+ "bitflags 2.9.4",
+ "objc2 0.6.3",
+ "objc2-core-foundation",
+ "objc2-core-graphics",
+ "objc2-io-surface",
+]
+
+[[package]]
+name = "objc2-encode"
+version = "4.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33"
+
+[[package]]
+name = "objc2-exception-helper"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7a1c5fbb72d7735b076bb47b578523aedc40f3c439bea6dfd595c089d79d98a"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "objc2-foundation"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
+dependencies = [
+ "bitflags 2.9.4",
+ "block2 0.5.1",
+ "libc",
+ "objc2 0.5.2",
+]
+
+[[package]]
+name = "objc2-foundation"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272"
+dependencies = [
+ "bitflags 2.9.4",
+ "block2 0.6.2",
+ "libc",
+ "objc2 0.6.3",
+ "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.9.4",
+ "objc2 0.6.3",
+ "objc2-core-foundation",
+]
+
+[[package]]
+name = "objc2-javascript-core"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a1e6550c4caed348956ce3370c9ffeca70bb1dbed4fa96112e7c6170e074586"
+dependencies = [
+ "objc2 0.6.3",
+ "objc2-core-foundation",
+]
+
+[[package]]
+name = "objc2-metal"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6"
+dependencies = [
+ "bitflags 2.9.4",
+ "block2 0.5.1",
+ "objc2 0.5.2",
+ "objc2-foundation 0.2.2",
+]
+
+[[package]]
+name = "objc2-quartz-core"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a"
+dependencies = [
+ "bitflags 2.9.4",
+ "block2 0.5.1",
+ "objc2 0.5.2",
+ "objc2-foundation 0.2.2",
+ "objc2-metal",
+]
+
+[[package]]
+name = "objc2-quartz-core"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f"
+dependencies = [
+ "bitflags 2.9.4",
+ "objc2 0.6.3",
+ "objc2-foundation 0.3.2",
+]
+
+[[package]]
+name = "objc2-security"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "709fe137109bd1e8b5a99390f77a7d8b2961dafc1a1c5db8f2e60329ad6d895a"
+dependencies = [
+ "bitflags 2.9.4",
+ "objc2 0.6.3",
+ "objc2-core-foundation",
+]
+
+[[package]]
+name = "objc2-ui-kit"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22"
+dependencies = [
+ "bitflags 2.9.4",
+ "objc2 0.6.3",
+ "objc2-core-foundation",
+ "objc2-foundation 0.3.2",
+]
+
+[[package]]
+name = "objc2-web-kit"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2e5aaab980c433cf470df9d7af96a7b46a9d892d521a2cbbb2f8a4c16751e7f"
+dependencies = [
+ "bitflags 2.9.4",
+ "block2 0.6.2",
+ "objc2 0.6.3",
+ "objc2-app-kit",
+ "objc2-core-foundation",
+ "objc2-foundation 0.3.2",
+ "objc2-javascript-core",
+ "objc2-security",
+]
+
+[[package]]
+name = "object"
+version = "0.37.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.21.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
+
+[[package]]
+name = "option-ext"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
+
+[[package]]
+name = "ordered-stream"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50"
+dependencies = [
+ "futures-core",
+ "pin-project-lite",
+]
+
+[[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"
+version = "2.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
+
+[[package]]
+name = "parking_lot"
+version = "0.12.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
+dependencies = [
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.9.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "windows-link 0.2.1",
+]
+
+[[package]]
+name = "percent-encoding"
+version = "2.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
+
+[[package]]
+name = "phf"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
+dependencies = [
+ "phf_shared 0.8.0",
+]
+
+[[package]]
+name = "phf"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259"
+dependencies = [
+ "phf_macros 0.10.0",
+ "phf_shared 0.10.0",
+ "proc-macro-hack",
+]
+
+[[package]]
+name = "phf"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
+dependencies = [
+ "phf_macros 0.11.3",
+ "phf_shared 0.11.3",
+]
+
+[[package]]
+name = "phf_codegen"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815"
+dependencies = [
+ "phf_generator 0.8.0",
+ "phf_shared 0.8.0",
+]
+
+[[package]]
+name = "phf_codegen"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a"
+dependencies = [
+ "phf_generator 0.11.3",
+ "phf_shared 0.11.3",
+]
+
+[[package]]
+name = "phf_generator"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526"
+dependencies = [
+ "phf_shared 0.8.0",
+ "rand 0.7.3",
+]
+
+[[package]]
+name = "phf_generator"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6"
+dependencies = [
+ "phf_shared 0.10.0",
+ "rand 0.8.5",
+]
+
+[[package]]
+name = "phf_generator"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
+dependencies = [
+ "phf_shared 0.11.3",
+ "rand 0.8.5",
+]
+
+[[package]]
+name = "phf_macros"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0"
+dependencies = [
+ "phf_generator 0.10.0",
+ "phf_shared 0.10.0",
+ "proc-macro-hack",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "phf_macros"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216"
+dependencies = [
+ "phf_generator 0.11.3",
+ "phf_shared 0.11.3",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
+[[package]]
+name = "phf_shared"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7"
+dependencies = [
+ "siphasher 0.3.11",
+]
+
+[[package]]
+name = "phf_shared"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096"
+dependencies = [
+ "siphasher 0.3.11",
+]
+
+[[package]]
+name = "phf_shared"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
+dependencies = [
+ "siphasher 1.0.1",
+]
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "piper"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066"
+dependencies = [
+ "atomic-waker",
+ "fastrand",
+ "futures-io",
+]
+
+[[package]]
+name = "pkg-config"
+version = "0.3.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
+
+[[package]]
+name = "plist"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "740ebea15c5d1428f910cd1a5f52cebf8d25006245ed8ade92702f4943d91e07"
+dependencies = [
+ "base64 0.22.1",
+ "indexmap 2.11.4",
+ "quick-xml 0.38.3",
+ "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 = "polling"
+version = "3.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218"
+dependencies = [
+ "cfg-if",
+ "concurrent-queue",
+ "hermit-abi",
+ "pin-project-lite",
+ "rustix",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "pollster"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3"
+
+[[package]]
+name = "potential_utf"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a"
+dependencies = [
+ "zerovec",
+]
+
+[[package]]
+name = "powerfmt"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
+dependencies = [
+ "zerocopy",
+]
+
+[[package]]
+name = "precomputed-hash"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
+
+[[package]]
+name = "proc-macro-crate"
+version = "1.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919"
+dependencies = [
+ "once_cell",
+ "toml_edit 0.19.15",
+]
+
+[[package]]
+name = "proc-macro-crate"
+version = "2.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24"
+dependencies = [
+ "toml_datetime 0.6.3",
+ "toml_edit 0.20.2",
+]
+
+[[package]]
+name = "proc-macro-crate"
+version = "3.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983"
+dependencies = [
+ "toml_edit 0.23.6",
+]
+
+[[package]]
+name = "proc-macro-error"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-hack"
+version = "0.5.20+deprecated"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.101"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "ptr_meta"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1"
+dependencies = [
+ "ptr_meta_derive",
+]
+
+[[package]]
+name = "ptr_meta_derive"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "quick-xml"
+version = "0.37.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "quick-xml"
+version = "0.38.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42a232e7487fc2ef313d96dde7948e7a3c05101870d8985e4fd8d26aedd27b89"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.41"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "r-efi"
+version = "5.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
+
+[[package]]
+name = "radium"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
+
+[[package]]
+name = "rand"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
+dependencies = [
+ "getrandom 0.1.16",
+ "libc",
+ "rand_chacha 0.2.2",
+ "rand_core 0.5.1",
+ "rand_hc",
+ "rand_pcg",
+]
+
+[[package]]
+name = "rand"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+dependencies = [
+ "libc",
+ "rand_chacha 0.3.1",
+ "rand_core 0.6.4",
+]
+
+[[package]]
+name = "rand"
+version = "0.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
+dependencies = [
+ "rand_chacha 0.9.0",
+ "rand_core 0.9.3",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
+dependencies = [
+ "ppv-lite86",
+ "rand_core 0.5.1",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+dependencies = [
+ "ppv-lite86",
+ "rand_core 0.6.4",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
+dependencies = [
+ "ppv-lite86",
+ "rand_core 0.9.3",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
+dependencies = [
+ "getrandom 0.1.16",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+dependencies = [
+ "getrandom 0.2.16",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
+dependencies = [
+ "getrandom 0.3.3",
+]
+
+[[package]]
+name = "rand_hc"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
+dependencies = [
+ "rand_core 0.5.1",
+]
+
+[[package]]
+name = "rand_pcg"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
+dependencies = [
+ "rand_core 0.5.1",
+]
+
+[[package]]
+name = "raw-window-handle"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539"
+
+[[package]]
+name = "redox_syscall"
+version = "0.5.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
+dependencies = [
+ "bitflags 2.9.4",
+]
+
+[[package]]
+name = "redox_users"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
+dependencies = [
+ "getrandom 0.2.16",
+ "libredox",
+ "thiserror 2.0.17",
+]
+
+[[package]]
+name = "ref-cast"
+version = "1.0.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d"
+dependencies = [
+ "ref-cast-impl",
+]
+
+[[package]]
+name = "ref-cast-impl"
+version = "1.0.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
+[[package]]
+name = "regex"
+version = "1.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001"
+
+[[package]]
+name = "rend"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c"
+dependencies = [
+ "bytecheck",
+]
+
+[[package]]
+name = "reqwest"
+version = "0.12.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb"
+dependencies = [
+ "base64 0.22.1",
+ "bytes",
+ "futures-core",
+ "futures-util",
+ "http",
+ "http-body",
+ "http-body-util",
+ "hyper",
+ "hyper-util",
+ "js-sys",
+ "log",
+ "percent-encoding",
+ "pin-project-lite",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "sync_wrapper",
+ "tokio",
+ "tokio-util",
+ "tower",
+ "tower-http",
+ "tower-service",
+ "url",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "wasm-streams",
+ "web-sys",
+]
+
+[[package]]
+name = "rfd"
+version = "0.15.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef2bee61e6cffa4635c72d7d81a84294e28f0930db0ddcb0f66d10244674ebed"
+dependencies = [
+ "ashpd",
+ "block2 0.6.2",
+ "dispatch2",
+ "js-sys",
+ "log",
+ "objc2 0.6.3",
+ "objc2-app-kit",
+ "objc2-core-foundation",
+ "objc2-foundation 0.3.2",
+ "pollster",
+ "raw-window-handle",
+ "urlencoding",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "rkyv"
+version = "0.7.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b"
+dependencies = [
+ "bitvec",
+ "bytecheck",
+ "bytes",
+ "hashbrown 0.12.3",
+ "ptr_meta",
+ "rend",
+ "rkyv_derive",
+ "seahash",
+ "tinyvec",
+ "uuid",
+]
+
+[[package]]
+name = "rkyv_derive"
+version = "0.7.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "rust_decimal"
+version = "1.38.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8975fc98059f365204d635119cf9c5a60ae67b841ed49b5422a9a7e56cdfac0"
+dependencies = [
+ "arrayvec",
+ "borsh",
+ "bytes",
+ "num-traits",
+ "rand 0.8.5",
+ "rkyv",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "rustc-demangle"
+version = "0.1.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
+
+[[package]]
+name = "rustc_version"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
+dependencies = [
+ "semver",
+]
+
+[[package]]
+name = "rustix"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
+dependencies = [
+ "bitflags 2.9.4",
+ "errno",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys 0.61.2",
+]
+
+[[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.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
+
+[[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.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0"
+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.106",
+]
+
+[[package]]
+name = "scoped-tls"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
+
+[[package]]
+name = "scopeguard"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+
+[[package]]
+name = "seahash"
+version = "4.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
+
+[[package]]
+name = "selectors"
+version = "0.24.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c37578180969d00692904465fb7f6b3d50b9a2b952b87c23d0e2e5cb5013416"
+dependencies = [
+ "bitflags 1.3.2",
+ "cssparser",
+ "derive_more",
+ "fxhash",
+ "log",
+ "phf 0.8.0",
+ "phf_codegen 0.8.0",
+ "precomputed-hash",
+ "servo_arc",
+ "smallvec",
+]
+
+[[package]]
+name = "semver"
+version = "1.0.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
+dependencies = [
+ "serde",
+ "serde_core",
+]
+
+[[package]]
+name = "serde"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
+dependencies = [
+ "serde_core",
+ "serde_derive",
+]
+
+[[package]]
+name = "serde-untagged"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f9faf48a4a2d2693be24c6289dbe26552776eb7737074e6722891fadbe6c5058"
+dependencies = [
+ "erased-serde",
+ "serde",
+ "serde_core",
+ "typeid",
+]
+
+[[package]]
+name = "serde_core"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
+[[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.106",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.145"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
+dependencies = [
+ "itoa",
+ "memchr",
+ "ryu",
+ "serde",
+ "serde_core",
+]
+
+[[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.106",
+]
+
+[[package]]
+name = "serde_spanned"
+version = "0.6.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "serde_spanned"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5417783452c2be558477e104686f7de5dae53dba813c28435e0e70f82d9b04ee"
+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.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6093cd8c01b25262b84927e0f7151692158fab02d961e04c979d3903eba7ecc5"
+dependencies = [
+ "base64 0.22.1",
+ "chrono",
+ "hex",
+ "indexmap 1.9.3",
+ "indexmap 2.11.4",
+ "schemars 0.9.0",
+ "schemars 1.0.4",
+ "serde_core",
+ "serde_json",
+ "serde_with_macros",
+ "time",
+]
+
+[[package]]
+name = "serde_with_macros"
+version = "3.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7e6c180db0816026a61afa1cff5344fb7ebded7e4d3062772179f2501481c27"
+dependencies = [
+ "darling",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
+[[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.106",
+]
+
+[[package]]
+name = "servo_arc"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d52aa42f8fdf0fed91e5ce7f23d8138441002fa31dca008acf47e6fd4721f741"
+dependencies = [
+ "nodrop",
+ "stable_deref_trait",
+]
+
+[[package]]
+name = "sha2"
+version = "0.10.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest",
+]
+
+[[package]]
+name = "shlex"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+
+[[package]]
+name = "signal-hook-registry"
+version = "1.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "simd-adler32"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
+
+[[package]]
+name = "simdutf8"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
+
+[[package]]
+name = "siphasher"
+version = "0.3.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
+
+[[package]]
+name = "siphasher"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
+
+[[package]]
+name = "slab"
+version = "0.4.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589"
+
+[[package]]
+name = "smallvec"
+version = "1.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
+
+[[package]]
+name = "socket2"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807"
+dependencies = [
+ "libc",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "softbuffer"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "18051cdd562e792cad055119e0cdb2cfc137e44e3987532e0f9659a77931bb08"
+dependencies = [
+ "bytemuck",
+ "cfg_aliases",
+ "core-graphics",
+ "foreign-types",
+ "js-sys",
+ "log",
+ "objc2 0.5.2",
+ "objc2-foundation 0.2.2",
+ "objc2-quartz-core 0.2.2",
+ "raw-window-handle",
+ "redox_syscall",
+ "wasm-bindgen",
+ "web-sys",
+ "windows-sys 0.59.0",
+]
+
+[[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 = "static_assertions"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
+
+[[package]]
+name = "string_cache"
+version = "0.8.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f"
+dependencies = [
+ "new_debug_unreachable",
+ "parking_lot",
+ "phf_shared 0.11.3",
+ "precomputed-hash",
+ "serde",
+]
+
+[[package]]
+name = "string_cache_codegen"
+version = "0.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0"
+dependencies = [
+ "phf_generator 0.11.3",
+ "phf_shared 0.11.3",
+ "proc-macro2",
+ "quote",
+]
+
+[[package]]
+name = "strsim"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
+
+[[package]]
+name = "swift-rs"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4057c98e2e852d51fdcfca832aac7b571f6b351ad159f9eda5db1655f8d0c4d7"
+dependencies = [
+ "base64 0.21.7",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.109"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.106"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
+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.106",
+]
+
+[[package]]
+name = "system-deps"
+version = "6.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349"
+dependencies = [
+ "cfg-expr",
+ "heck 0.5.0",
+ "pkg-config",
+ "toml 0.8.2",
+ "version-compare",
+]
+
+[[package]]
+name = "tao"
+version = "0.34.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "959469667dbcea91e5485fc48ba7dd6023face91bb0f1a14681a70f99847c3f7"
+dependencies = [
+ "bitflags 2.9.4",
+ "block2 0.6.2",
+ "core-foundation",
+ "core-graphics",
+ "crossbeam-channel",
+ "dispatch",
+ "dlopen2",
+ "dpi",
+ "gdkwayland-sys",
+ "gdkx11-sys",
+ "gtk",
+ "jni",
+ "lazy_static",
+ "libc",
+ "log",
+ "ndk",
+ "ndk-context",
+ "ndk-sys",
+ "objc2 0.6.3",
+ "objc2-app-kit",
+ "objc2-foundation 0.3.2",
+ "once_cell",
+ "parking_lot",
+ "raw-window-handle",
+ "scopeguard",
+ "tao-macros",
+ "unicode-segmentation",
+ "url",
+ "windows",
+ "windows-core 0.61.2",
+ "windows-version",
+ "x11-dl",
+]
+
+[[package]]
+name = "tao-macros"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
+[[package]]
+name = "tap"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
+
+[[package]]
+name = "target-lexicon"
+version = "0.12.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
+
+[[package]]
+name = "tauri"
+version = "2.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4d1d3b3dc4c101ac989fd7db77e045cc6d91a25349cd410455cb5c57d510c1c"
+dependencies = [
+ "anyhow",
+ "bytes",
+ "cookie",
+ "dirs",
+ "dunce",
+ "embed_plist",
+ "getrandom 0.3.3",
+ "glob",
+ "gtk",
+ "heck 0.5.0",
+ "http",
+ "http-range",
+ "jni",
+ "libc",
+ "log",
+ "mime",
+ "muda",
+ "objc2 0.6.3",
+ "objc2-app-kit",
+ "objc2-foundation 0.3.2",
+ "objc2-ui-kit",
+ "objc2-web-kit",
+ "percent-encoding",
+ "plist",
+ "raw-window-handle",
+ "reqwest",
+ "serde",
+ "serde_json",
+ "serde_repr",
+ "serialize-to-javascript",
+ "swift-rs",
+ "tauri-build",
+ "tauri-macros",
+ "tauri-runtime",
+ "tauri-runtime-wry",
+ "tauri-utils",
+ "thiserror 2.0.17",
+ "tokio",
+ "tray-icon",
+ "url",
+ "urlpattern",
+ "webkit2gtk",
+ "webview2-com",
+ "window-vibrancy",
+ "windows",
+]
+
+[[package]]
+name = "tauri-build"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c432ccc9ff661803dab74c6cd78de11026a578a9307610bbc39d3c55be7943f"
+dependencies = [
+ "anyhow",
+ "cargo_toml",
+ "dirs",
+ "glob",
+ "heck 0.5.0",
+ "json-patch",
+ "schemars 0.8.22",
+ "semver",
+ "serde",
+ "serde_json",
+ "tauri-utils",
+ "tauri-winres",
+ "toml 0.9.7",
+ "walkdir",
+]
+
+[[package]]
+name = "tauri-codegen"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ab3a62cf2e6253936a8b267c2e95839674e7439f104fa96ad0025e149d54d8a"
+dependencies = [
+ "base64 0.22.1",
+ "brotli",
+ "ico",
+ "json-patch",
+ "plist",
+ "png",
+ "proc-macro2",
+ "quote",
+ "semver",
+ "serde",
+ "serde_json",
+ "sha2",
+ "syn 2.0.106",
+ "tauri-utils",
+ "thiserror 2.0.17",
+ "time",
+ "url",
+ "uuid",
+ "walkdir",
+]
+
+[[package]]
+name = "tauri-macros"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4368ea8094e7045217edb690f493b55b30caf9f3e61f79b4c24b6db91f07995e"
+dependencies = [
+ "heck 0.5.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+ "tauri-codegen",
+ "tauri-utils",
+]
+
+[[package]]
+name = "tauri-plugin"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9946a3cede302eac0c6eb6c6070ac47b1768e326092d32efbb91f21ed58d978f"
+dependencies = [
+ "anyhow",
+ "glob",
+ "plist",
+ "schemars 0.8.22",
+ "serde",
+ "serde_json",
+ "tauri-utils",
+ "toml 0.9.7",
+ "walkdir",
+]
+
+[[package]]
+name = "tauri-plugin-log"
+version = "2.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61c1438bc7662acd16d508c919b3c087efd63669a4c75625dff829b1c75975ec"
+dependencies = [
+ "android_logger",
+ "byte-unit",
+ "fern",
+ "log",
+ "objc2 0.6.3",
+ "objc2-foundation 0.3.2",
+ "serde",
+ "serde_json",
+ "serde_repr",
+ "swift-rs",
+ "tauri",
+ "tauri-plugin",
+ "thiserror 2.0.17",
+ "time",
+]
+
+[[package]]
+name = "tauri-runtime"
+version = "2.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4cfc9ad45b487d3fded5a4731a567872a4812e9552e3964161b08edabf93846"
+dependencies = [
+ "cookie",
+ "dpi",
+ "gtk",
+ "http",
+ "jni",
+ "objc2 0.6.3",
+ "objc2-ui-kit",
+ "objc2-web-kit",
+ "raw-window-handle",
+ "serde",
+ "serde_json",
+ "tauri-utils",
+ "thiserror 2.0.17",
+ "url",
+ "webkit2gtk",
+ "webview2-com",
+ "windows",
+]
+
+[[package]]
+name = "tauri-runtime-wry"
+version = "2.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1fe9d48bd122ff002064e88cfcd7027090d789c4302714e68fcccba0f4b7807"
+dependencies = [
+ "gtk",
+ "http",
+ "jni",
+ "log",
+ "objc2 0.6.3",
+ "objc2-app-kit",
+ "objc2-foundation 0.3.2",
+ "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.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41a3852fdf9a4f8fbeaa63dc3e9a85284dd6ef7200751f0bd66ceee30c93f212"
+dependencies = [
+ "anyhow",
+ "brotli",
+ "cargo_metadata",
+ "ctor",
+ "dunce",
+ "glob",
+ "html5ever",
+ "http",
+ "infer",
+ "json-patch",
+ "kuchikiki",
+ "log",
+ "memchr",
+ "phf 0.11.3",
+ "proc-macro2",
+ "quote",
+ "regex",
+ "schemars 0.8.22",
+ "semver",
+ "serde",
+ "serde-untagged",
+ "serde_json",
+ "serde_with",
+ "swift-rs",
+ "thiserror 2.0.17",
+ "toml 0.9.7",
+ "url",
+ "urlpattern",
+ "uuid",
+ "walkdir",
+]
+
+[[package]]
+name = "tauri-winres"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd21509dd1fa9bd355dc29894a6ff10635880732396aa38c0066c1e6c1ab8074"
+dependencies = [
+ "embed-resource",
+ "toml 0.9.7",
+]
+
+[[package]]
+name = "tempfile"
+version = "3.23.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16"
+dependencies = [
+ "fastrand",
+ "getrandom 0.3.3",
+ "once_cell",
+ "rustix",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "tendril"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0"
+dependencies = [
+ "futf",
+ "mac",
+ "utf-8",
+]
+
+[[package]]
+name = "thiserror"
+version = "1.0.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
+dependencies = [
+ "thiserror-impl 1.0.69",
+]
+
+[[package]]
+name = "thiserror"
+version = "2.0.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
+dependencies = [
+ "thiserror-impl 2.0.17",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "2.0.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
+[[package]]
+name = "time"
+version = "0.3.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d"
+dependencies = [
+ "deranged",
+ "itoa",
+ "libc",
+ "num-conv",
+ "num_threads",
+ "powerfmt",
+ "serde",
+ "time-core",
+ "time-macros",
+]
+
+[[package]]
+name = "time-core"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b"
+
+[[package]]
+name = "time-macros"
+version = "0.2.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3"
+dependencies = [
+ "num-conv",
+ "time-core",
+]
+
+[[package]]
+name = "tinystr"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b"
+dependencies = [
+ "displaydoc",
+ "zerovec",
+]
+
+[[package]]
+name = "tinyvec"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa"
+dependencies = [
+ "tinyvec_macros",
+]
+
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
+
+[[package]]
+name = "tokio"
+version = "1.47.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038"
+dependencies = [
+ "backtrace",
+ "bytes",
+ "io-uring",
+ "libc",
+ "mio",
+ "pin-project-lite",
+ "slab",
+ "socket2",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "tokio-util"
+version = "0.7.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5"
+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.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00e5e5d9bf2475ac9d4f0d9edab68cc573dc2fd644b0dba36b0c30a92dd9eaa0"
+dependencies = [
+ "indexmap 2.11.4",
+ "serde_core",
+ "serde_spanned 1.0.2",
+ "toml_datetime 0.7.2",
+ "toml_parser",
+ "toml_writer",
+ "winnow 0.7.13",
+]
+
+[[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.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1"
+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.11.4",
+ "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.11.4",
+ "serde",
+ "serde_spanned 0.6.9",
+ "toml_datetime 0.6.3",
+ "winnow 0.5.40",
+]
+
+[[package]]
+name = "toml_edit"
+version = "0.23.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3effe7c0e86fdff4f69cdd2ccc1b96f933e24811c5441d44904e8683e27184b"
+dependencies = [
+ "indexmap 2.11.4",
+ "toml_datetime 0.7.2",
+ "toml_parser",
+ "winnow 0.7.13",
+]
+
+[[package]]
+name = "toml_parser"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627"
+dependencies = [
+ "winnow 0.7.13",
+]
+
+[[package]]
+name = "toml_writer"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d163a63c116ce562a22cda521fcc4d79152e7aba014456fb5eb442f6d6a10109"
+
+[[package]]
+name = "tower"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
+dependencies = [
+ "futures-core",
+ "futures-util",
+ "pin-project-lite",
+ "sync_wrapper",
+ "tokio",
+ "tower-layer",
+ "tower-service",
+]
+
+[[package]]
+name = "tower-http"
+version = "0.6.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2"
+dependencies = [
+ "bitflags 2.9.4",
+ "bytes",
+ "futures-util",
+ "http",
+ "http-body",
+ "iri-string",
+ "pin-project-lite",
+ "tower",
+ "tower-layer",
+ "tower-service",
+]
+
+[[package]]
+name = "tower-layer"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
+
+[[package]]
+name = "tower-service"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
+
+[[package]]
+name = "tracing"
+version = "0.1.41"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
+dependencies = [
+ "pin-project-lite",
+ "tracing-attributes",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-attributes"
+version = "0.1.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.34"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678"
+dependencies = [
+ "once_cell",
+]
+
+[[package]]
+name = "tray-icon"
+version = "0.21.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0d92153331e7d02ec09137538996a7786fe679c629c279e82a6be762b7e6fe2"
+dependencies = [
+ "crossbeam-channel",
+ "dirs",
+ "libappindicator",
+ "muda",
+ "objc2 0.6.3",
+ "objc2-app-kit",
+ "objc2-core-foundation",
+ "objc2-core-graphics",
+ "objc2-foundation 0.3.2",
+ "once_cell",
+ "png",
+ "serde",
+ "thiserror 2.0.17",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "try-lock"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
+
+[[package]]
+name = "typeid"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c"
+
+[[package]]
+name = "typenum"
+version = "1.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
+
+[[package]]
+name = "uds_windows"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9"
+dependencies = [
+ "memoffset",
+ "tempfile",
+ "winapi",
+]
+
+[[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.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d"
+
+[[package]]
+name = "unicode-segmentation"
+version = "1.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
+
+[[package]]
+name = "url"
+version = "2.5.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b"
+dependencies = [
+ "form_urlencoded",
+ "idna",
+ "percent-encoding",
+ "serde",
+]
+
+[[package]]
+name = "urlencoding"
+version = "2.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
+
+[[package]]
+name = "urlpattern"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70acd30e3aa1450bc2eece896ce2ad0d178e9c079493819301573dae3c37ba6d"
+dependencies = [
+ "regex",
+ "serde",
+ "unic-ucd-ident",
+ "url",
+]
+
+[[package]]
+name = "utf-8"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
+
+[[package]]
+name = "utf8-width"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3"
+
+[[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.18.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2"
+dependencies = [
+ "getrandom 0.3.3",
+ "js-sys",
+ "serde",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "value-bag"
+version = "1.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "943ce29a8a743eb10d6082545d861b24f9d1b160b7d741e0f2cdf726bec909c5"
+
+[[package]]
+name = "version-compare"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b"
+
+[[package]]
+name = "version_check"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
+
+[[package]]
+name = "vswhom"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b"
+dependencies = [
+ "libc",
+ "vswhom-sys",
+]
+
+[[package]]
+name = "vswhom-sys"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fb067e4cbd1ff067d1df46c9194b5de0e98efd2810bbc95c5d5e5f25a3231150"
+dependencies = [
+ "cc",
+ "libc",
+]
+
+[[package]]
+name = "walkdir"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
+dependencies = [
+ "same-file",
+ "winapi-util",
+]
+
+[[package]]
+name = "want"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
+dependencies = [
+ "try-lock",
+]
+
+[[package]]
+name = "wasi"
+version = "0.9.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
+
+[[package]]
+name = "wasi"
+version = "0.11.1+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
+
+[[package]]
+name = "wasi"
+version = "0.14.7+wasi-0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c"
+dependencies = [
+ "wasip2",
+]
+
+[[package]]
+name = "wasip2"
+version = "1.0.1+wasi-0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
+dependencies = [
+ "wit-bindgen",
+]
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.104"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+ "rustversion",
+ "wasm-bindgen-macro",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.104"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19"
+dependencies = [
+ "bumpalo",
+ "log",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-futures"
+version = "0.4.54"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c"
+dependencies = [
+ "cfg-if",
+ "js-sys",
+ "once_cell",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.104"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.104"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.104"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "wasm-streams"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65"
+dependencies = [
+ "futures-util",
+ "js-sys",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+]
+
+[[package]]
+name = "wayland-backend"
+version = "0.3.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "673a33c33048a5ade91a6b139580fa174e19fb0d23f396dca9fa15f2e1e49b35"
+dependencies = [
+ "cc",
+ "downcast-rs",
+ "rustix",
+ "scoped-tls",
+ "smallvec",
+ "wayland-sys",
+]
+
+[[package]]
+name = "wayland-client"
+version = "0.31.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d"
+dependencies = [
+ "bitflags 2.9.4",
+ "rustix",
+ "wayland-backend",
+ "wayland-scanner",
+]
+
+[[package]]
+name = "wayland-protocols"
+version = "0.32.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "efa790ed75fbfd71283bd2521a1cfdc022aabcc28bdcff00851f9e4ae88d9901"
+dependencies = [
+ "bitflags 2.9.4",
+ "wayland-backend",
+ "wayland-client",
+ "wayland-scanner",
+]
+
+[[package]]
+name = "wayland-scanner"
+version = "0.31.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "54cb1e9dc49da91950bdfd8b848c49330536d9d1fb03d4bfec8cae50caa50ae3"
+dependencies = [
+ "proc-macro2",
+ "quick-xml 0.37.5",
+ "quote",
+]
+
+[[package]]
+name = "wayland-sys"
+version = "0.31.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34949b42822155826b41db8e5d0c1be3a2bd296c747577a43a3e6daefc296142"
+dependencies = [
+ "dlib",
+ "log",
+ "pkg-config",
+]
+
+[[package]]
+name = "web-sys"
+version = "0.3.81"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "webkit2gtk"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76b1bc1e54c581da1e9f179d0b38512ba358fb1af2d634a1affe42e37172361a"
+dependencies = [
+ "bitflags 1.3.2",
+ "cairo-rs",
+ "gdk",
+ "gdk-sys",
+ "gio",
+ "gio-sys",
+ "glib",
+ "glib-sys",
+ "gobject-sys",
+ "gtk",
+ "gtk-sys",
+ "javascriptcore-rs",
+ "libc",
+ "once_cell",
+ "soup3",
+ "webkit2gtk-sys",
+]
+
+[[package]]
+name = "webkit2gtk-sys"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62daa38afc514d1f8f12b8693d30d5993ff77ced33ce30cd04deebc267a6d57c"
+dependencies = [
+ "bitflags 1.3.2",
+ "cairo-sys-rs",
+ "gdk-sys",
+ "gio-sys",
+ "glib-sys",
+ "gobject-sys",
+ "gtk-sys",
+ "javascriptcore-rs-sys",
+ "libc",
+ "pkg-config",
+ "soup3-sys",
+ "system-deps",
+]
+
+[[package]]
+name = "webview2-com"
+version = "0.38.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4ba622a989277ef3886dd5afb3e280e3dd6d974b766118950a08f8f678ad6a4"
+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.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d228f15bba3b9d56dde8bddbee66fa24545bd17b48d5128ccf4a8742b18e431"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
+[[package]]
+name = "webview2-com-sys"
+version = "0.38.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "36695906a1b53a3bf5c4289621efedac12b73eeb0b89e7e1a89b517302d5d75c"
+dependencies = [
+ "thiserror 2.0.17",
+ "windows",
+ "windows-core 0.61.2",
+]
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
+dependencies = [
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "window-vibrancy"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9bec5a31f3f9362f2258fd0e9c9dd61a9ca432e7306cc78c444258f0dce9a9c"
+dependencies = [
+ "objc2 0.6.3",
+ "objc2-app-kit",
+ "objc2-core-foundation",
+ "objc2-foundation 0.3.2",
+ "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.106",
+]
+
+[[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.106",
+]
+
+[[package]]
+name = "windows-link"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
+
+[[package]]
+name = "windows-link"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
+
+[[package]]
+name = "windows-numerics"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
+dependencies = [
+ "windows-core 0.61.2",
+ "windows-link 0.1.3",
+]
+
+[[package]]
+name = "windows-result"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
+dependencies = [
+ "windows-link 0.1.3",
+]
+
+[[package]]
+name = "windows-result"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
+dependencies = [
+ "windows-link 0.2.1",
+]
+
+[[package]]
+name = "windows-strings"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
+dependencies = [
+ "windows-link 0.1.3",
+]
+
+[[package]]
+name = "windows-strings"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
+dependencies = [
+ "windows-link 0.2.1",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
+dependencies = [
+ "windows-targets 0.42.2",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.59.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
+dependencies = [
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.60.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
+dependencies = [
+ "windows-targets 0.53.5",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.61.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
+dependencies = [
+ "windows-link 0.2.1",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
+dependencies = [
+ "windows_aarch64_gnullvm 0.42.2",
+ "windows_aarch64_msvc 0.42.2",
+ "windows_i686_gnu 0.42.2",
+ "windows_i686_msvc 0.42.2",
+ "windows_x86_64_gnu 0.42.2",
+ "windows_x86_64_gnullvm 0.42.2",
+ "windows_x86_64_msvc 0.42.2",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
+dependencies = [
+ "windows_aarch64_gnullvm 0.52.6",
+ "windows_aarch64_msvc 0.52.6",
+ "windows_i686_gnu 0.52.6",
+ "windows_i686_gnullvm 0.52.6",
+ "windows_i686_msvc 0.52.6",
+ "windows_x86_64_gnu 0.52.6",
+ "windows_x86_64_gnullvm 0.52.6",
+ "windows_x86_64_msvc 0.52.6",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.53.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
+dependencies = [
+ "windows-link 0.2.1",
+ "windows_aarch64_gnullvm 0.53.1",
+ "windows_aarch64_msvc 0.53.1",
+ "windows_i686_gnu 0.53.1",
+ "windows_i686_gnullvm 0.53.1",
+ "windows_i686_msvc 0.53.1",
+ "windows_x86_64_gnu 0.53.1",
+ "windows_x86_64_gnullvm 0.53.1",
+ "windows_x86_64_msvc 0.53.1",
+]
+
+[[package]]
+name = "windows-threading"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6"
+dependencies = [
+ "windows-link 0.1.3",
+]
+
+[[package]]
+name = "windows-version"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e4060a1da109b9d0326b7262c8e12c84df67cc0dbc9e33cf49e01ccc2eb63631"
+dependencies = [
+ "windows-link 0.2.1",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
+
+[[package]]
+name = "winnow"
+version = "0.5.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "winnow"
+version = "0.7.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf"
+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.46.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
+
+[[package]]
+name = "writeable"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
+
+[[package]]
+name = "wry"
+version = "0.53.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d78ec082b80fa088569a970d043bb3050abaabf4454101d44514ee8d9a8c9f6"
+dependencies = [
+ "base64 0.22.1",
+ "block2 0.6.2",
+ "cookie",
+ "crossbeam-channel",
+ "dirs",
+ "dpi",
+ "dunce",
+ "gdkx11",
+ "gtk",
+ "html5ever",
+ "http",
+ "javascriptcore-rs",
+ "jni",
+ "kuchikiki",
+ "libc",
+ "ndk",
+ "objc2 0.6.3",
+ "objc2-app-kit",
+ "objc2-core-foundation",
+ "objc2-foundation 0.3.2",
+ "objc2-ui-kit",
+ "objc2-web-kit",
+ "once_cell",
+ "percent-encoding",
+ "raw-window-handle",
+ "sha2",
+ "soup3",
+ "tao-macros",
+ "thiserror 2.0.17",
+ "url",
+ "webkit2gtk",
+ "webkit2gtk-sys",
+ "webview2-com",
+ "windows",
+ "windows-core 0.61.2",
+ "windows-version",
+ "x11-dl",
+]
+
+[[package]]
+name = "wyz"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
+dependencies = [
+ "tap",
+]
+
+[[package]]
+name = "x11"
+version = "2.21.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e"
+dependencies = [
+ "libc",
+ "pkg-config",
+]
+
+[[package]]
+name = "x11-dl"
+version = "2.21.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f"
+dependencies = [
+ "libc",
+ "once_cell",
+ "pkg-config",
+]
+
+[[package]]
+name = "yoke"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc"
+dependencies = [
+ "serde",
+ "stable_deref_trait",
+ "yoke-derive",
+ "zerofrom",
+]
+
+[[package]]
+name = "yoke-derive"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+ "synstructure",
+]
+
+[[package]]
+name = "zbus"
+version = "5.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d07e46d035fb8e375b2ce63ba4e4ff90a7f73cf2ffb0138b29e1158d2eaadf7"
+dependencies = [
+ "async-broadcast",
+ "async-executor",
+ "async-io",
+ "async-lock",
+ "async-process",
+ "async-recursion",
+ "async-task",
+ "async-trait",
+ "blocking",
+ "enumflags2",
+ "event-listener",
+ "futures-core",
+ "futures-lite",
+ "hex",
+ "nix",
+ "ordered-stream",
+ "serde",
+ "serde_repr",
+ "tracing",
+ "uds_windows",
+ "windows-sys 0.60.2",
+ "winnow 0.7.13",
+ "zbus_macros",
+ "zbus_names",
+ "zvariant",
+]
+
+[[package]]
+name = "zbus_macros"
+version = "5.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57e797a9c847ed3ccc5b6254e8bcce056494b375b511b3d6edcec0aeb4defaca"
+dependencies = [
+ "proc-macro-crate 3.4.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+ "zbus_names",
+ "zvariant",
+ "zvariant_utils",
+]
+
+[[package]]
+name = "zbus_names"
+version = "4.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7be68e64bf6ce8db94f63e72f0c7eb9a60d733f7e0499e628dfab0f84d6bcb97"
+dependencies = [
+ "serde",
+ "static_assertions",
+ "winnow 0.7.13",
+ "zvariant",
+]
+
+[[package]]
+name = "zerocopy"
+version = "0.8.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c"
+dependencies = [
+ "zerocopy-derive",
+]
+
+[[package]]
+name = "zerocopy-derive"
+version = "0.8.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
+[[package]]
+name = "zerofrom"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
+dependencies = [
+ "zerofrom-derive",
+]
+
+[[package]]
+name = "zerofrom-derive"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+ "synstructure",
+]
+
+[[package]]
+name = "zerotrie"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595"
+dependencies = [
+ "displaydoc",
+ "yoke",
+ "zerofrom",
+]
+
+[[package]]
+name = "zerovec"
+version = "0.11.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b"
+dependencies = [
+ "yoke",
+ "zerofrom",
+ "zerovec-derive",
+]
+
+[[package]]
+name = "zerovec-derive"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
+[[package]]
+name = "zvariant"
+version = "5.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "999dd3be73c52b1fccd109a4a81e4fcd20fab1d3599c8121b38d04e1419498db"
+dependencies = [
+ "endi",
+ "enumflags2",
+ "serde",
+ "url",
+ "winnow 0.7.13",
+ "zvariant_derive",
+ "zvariant_utils",
+]
+
+[[package]]
+name = "zvariant_derive"
+version = "5.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6643fd0b26a46d226bd90d3f07c1b5321fe9bb7f04673cb37ac6d6883885b68e"
+dependencies = [
+ "proc-macro-crate 3.4.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+ "zvariant_utils",
+]
+
+[[package]]
+name = "zvariant_utils"
+version = "3.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c6949d142f89f6916deca2232cf26a8afacf2b9fdc35ce766105e104478be599"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "serde",
+ "syn 2.0.106",
+ "winnow 0.7.13",
+]
diff --git a/packages/desktop/src-tauri/Cargo.toml b/packages/desktop/src-tauri/Cargo.toml
new file mode 100644
index 0000000000..cecc9d753a
--- /dev/null
+++ b/packages/desktop/src-tauri/Cargo.toml
@@ -0,0 +1,29 @@
+[package]
+name = "app"
+version = "0.1.0"
+description = "A Tauri App"
+authors = ["you"]
+license = ""
+repository = ""
+edition = "2021"
+rust-version = "1.77.2"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[lib]
+name = "app_lib"
+crate-type = ["staticlib", "cdylib", "rlib"]
+
+[build-dependencies]
+tauri-build = { version = "2.4.1", features = [] }
+
+[dependencies]
+serde_json = "1.0"
+serde = { version = "1.0", features = ["derive"] }
+log = "0.4"
+tauri = { version = "2.8.5", features = ["protocol-asset"] }
+tauri-plugin-log = "2"
+rfd = "0.15"
+
+[package.metadata.bundle]
+osx_info_plist_path = "Info.plist"
diff --git a/packages/desktop/src-tauri/Info.plist b/packages/desktop/src-tauri/Info.plist
new file mode 100644
index 0000000000..f4f4c073dd
--- /dev/null
+++ b/packages/desktop/src-tauri/Info.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ NSMicrophoneUsageDescription
+ OpenCode needs microphone access for voice dictation
+
+
diff --git a/packages/desktop/src-tauri/build.rs b/packages/desktop/src-tauri/build.rs
new file mode 100644
index 0000000000..795b9b7c83
--- /dev/null
+++ b/packages/desktop/src-tauri/build.rs
@@ -0,0 +1,3 @@
+fn main() {
+ tauri_build::build()
+}
diff --git a/packages/desktop/src-tauri/capabilities/default.json b/packages/desktop/src-tauri/capabilities/default.json
new file mode 100644
index 0000000000..c135d7f15d
--- /dev/null
+++ b/packages/desktop/src-tauri/capabilities/default.json
@@ -0,0 +1,11 @@
+{
+ "$schema": "../gen/schemas/desktop-schema.json",
+ "identifier": "default",
+ "description": "enables the default permissions",
+ "windows": [
+ "main"
+ ],
+ "permissions": [
+ "core:default"
+ ]
+}
diff --git a/packages/desktop/src-tauri/gen/apple/.gitignore b/packages/desktop/src-tauri/gen/apple/.gitignore
new file mode 100644
index 0000000000..6726e2f89b
--- /dev/null
+++ b/packages/desktop/src-tauri/gen/apple/.gitignore
@@ -0,0 +1,3 @@
+xcuserdata/
+build/
+Externals/
diff --git a/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@1x.png b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@1x.png
new file mode 100644
index 0000000000..a6ac2a8ccf
Binary files /dev/null and b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@1x.png differ
diff --git a/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x-1.png b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x-1.png
new file mode 100644
index 0000000000..2869541f73
Binary files /dev/null and b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x-1.png differ
diff --git a/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x.png b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x.png
new file mode 100644
index 0000000000..2869541f73
Binary files /dev/null and b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x.png differ
diff --git a/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@3x.png b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@3x.png
new file mode 100644
index 0000000000..cf265a45d3
Binary files /dev/null and b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@3x.png differ
diff --git a/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@1x.png b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@1x.png
new file mode 100644
index 0000000000..29c9746c05
Binary files /dev/null and b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@1x.png differ
diff --git a/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x-1.png b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x-1.png
new file mode 100644
index 0000000000..a4e68c8d6d
Binary files /dev/null and b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x-1.png differ
diff --git a/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x.png b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x.png
new file mode 100644
index 0000000000..a4e68c8d6d
Binary files /dev/null and b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x.png differ
diff --git a/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@3x.png b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@3x.png
new file mode 100644
index 0000000000..e4adcbcedc
Binary files /dev/null and b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@3x.png differ
diff --git a/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@1x.png b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@1x.png
new file mode 100644
index 0000000000..2869541f73
Binary files /dev/null and b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@1x.png differ
diff --git a/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x-1.png b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x-1.png
new file mode 100644
index 0000000000..a414e65bb0
Binary files /dev/null and b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x-1.png differ
diff --git a/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x.png b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x.png
new file mode 100644
index 0000000000..a414e65bb0
Binary files /dev/null and b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x.png differ
diff --git a/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@3x.png b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@3x.png
new file mode 100644
index 0000000000..a0807e5dfd
Binary files /dev/null and b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@3x.png differ
diff --git a/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png
new file mode 100644
index 0000000000..704c929133
Binary files /dev/null and b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png differ
diff --git a/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@2x.png b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@2x.png
new file mode 100644
index 0000000000..a0807e5dfd
Binary files /dev/null and b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@2x.png differ
diff --git a/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@3x.png b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@3x.png
new file mode 100644
index 0000000000..2a9fbc26ef
Binary files /dev/null and b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@3x.png differ
diff --git a/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@1x.png b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@1x.png
new file mode 100644
index 0000000000..2cdf18485f
Binary files /dev/null and b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@1x.png differ
diff --git a/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@2x.png b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@2x.png
new file mode 100644
index 0000000000..4723e4b45e
Binary files /dev/null and b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@2x.png differ
diff --git a/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5x83.5@2x.png b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5x83.5@2x.png
new file mode 100644
index 0000000000..f26fee45c0
Binary files /dev/null and b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5x83.5@2x.png differ
diff --git a/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000000..90eea7ec7e
--- /dev/null
+++ b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,116 @@
+{
+ "images" : [
+ {
+ "size" : "20x20",
+ "idiom" : "iphone",
+ "filename" : "AppIcon-20x20@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "iphone",
+ "filename" : "AppIcon-20x20@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "AppIcon-29x29@2x-1.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "AppIcon-29x29@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "AppIcon-40x40@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "AppIcon-40x40@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "AppIcon-60x60@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "AppIcon-60x60@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "ipad",
+ "filename" : "AppIcon-20x20@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "ipad",
+ "filename" : "AppIcon-20x20@2x-1.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "AppIcon-29x29@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "AppIcon-29x29@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "AppIcon-40x40@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "AppIcon-40x40@2x-1.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "AppIcon-76x76@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "AppIcon-76x76@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "83.5x83.5",
+ "idiom" : "ipad",
+ "filename" : "AppIcon-83.5x83.5@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "1024x1024",
+ "idiom" : "ios-marketing",
+ "filename" : "AppIcon-512@2x.png",
+ "scale" : "1x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/packages/desktop/src-tauri/gen/apple/Assets.xcassets/Contents.json b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/Contents.json
new file mode 100644
index 0000000000..da4a164c91
--- /dev/null
+++ b/packages/desktop/src-tauri/gen/apple/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/packages/desktop/src-tauri/gen/apple/ExportOptions.plist b/packages/desktop/src-tauri/gen/apple/ExportOptions.plist
new file mode 100644
index 0000000000..0428a171b3
--- /dev/null
+++ b/packages/desktop/src-tauri/gen/apple/ExportOptions.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ method
+ debugging
+
+
diff --git a/packages/desktop/src-tauri/gen/apple/LaunchScreen.storyboard b/packages/desktop/src-tauri/gen/apple/LaunchScreen.storyboard
new file mode 100644
index 0000000000..81b5f90e2f
--- /dev/null
+++ b/packages/desktop/src-tauri/gen/apple/LaunchScreen.storyboard
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/desktop/src-tauri/gen/apple/Podfile b/packages/desktop/src-tauri/gen/apple/Podfile
new file mode 100644
index 0000000000..0fb99f08d7
--- /dev/null
+++ b/packages/desktop/src-tauri/gen/apple/Podfile
@@ -0,0 +1,21 @@
+# Uncomment the next line to define a global platform for your project
+
+target 'app_iOS' do
+platform :ios, '14.0'
+ # Pods for app_iOS
+end
+
+target 'app_macOS' do
+platform :osx, '11.0'
+ # Pods for app_macOS
+end
+
+# Delete the deployment target for iOS and macOS, causing it to be inherited from the Podfile
+post_install do |installer|
+ installer.pods_project.targets.each do |target|
+ target.build_configurations.each do |config|
+ config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
+ config.build_settings.delete 'MACOSX_DEPLOYMENT_TARGET'
+ end
+ end
+end
diff --git a/packages/desktop/src-tauri/gen/apple/Sources/app/bindings/bindings.h b/packages/desktop/src-tauri/gen/apple/Sources/app/bindings/bindings.h
new file mode 100644
index 0000000000..51522007b6
--- /dev/null
+++ b/packages/desktop/src-tauri/gen/apple/Sources/app/bindings/bindings.h
@@ -0,0 +1,8 @@
+#pragma once
+
+namespace ffi {
+ extern "C" {
+ void start_app();
+ }
+}
+
diff --git a/packages/desktop/src-tauri/gen/apple/Sources/app/main.mm b/packages/desktop/src-tauri/gen/apple/Sources/app/main.mm
new file mode 100644
index 0000000000..7793a9d5cf
--- /dev/null
+++ b/packages/desktop/src-tauri/gen/apple/Sources/app/main.mm
@@ -0,0 +1,6 @@
+#include "bindings/bindings.h"
+
+int main(int argc, char * argv[]) {
+ ffi::start_app();
+ return 0;
+}
diff --git a/packages/desktop/src-tauri/gen/apple/app.xcodeproj/project.pbxproj b/packages/desktop/src-tauri/gen/apple/app.xcodeproj/project.pbxproj
new file mode 100644
index 0000000000..ff0d564ee7
--- /dev/null
+++ b/packages/desktop/src-tauri/gen/apple/app.xcodeproj/project.pbxproj
@@ -0,0 +1,505 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 63;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 299814393FFBF154FAD94CA8 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3673D372C5ABDD1AD6E7067 /* QuartzCore.framework */; };
+ 3036F7131E55779ABF15BD58 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 02B7F8347F94B067E6B27396 /* LaunchScreen.storyboard */; };
+ 31585529C029A01BE249A285 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E81BD6B453D87B7F7B1597B /* CoreGraphics.framework */; };
+ 324A1E9A4258E7911D4DAC39 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9FACFFCB6E3743955F72464C /* Security.framework */; };
+ 36C1893A7382FCD5A6A74845 /* libapp.a in Resources */ = {isa = PBXBuildFile; fileRef = CF674524E34966183631754E /* libapp.a */; };
+ 53CDD0ACFBE8BDF1550B2E53 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 682535EEFE1DA20BE07B123C /* main.mm */; };
+ 5C516481BCA83A182C2BCC94 /* assets in Resources */ = {isa = PBXBuildFile; fileRef = 3842AE2A64FB9933D0400EA4 /* assets */; };
+ 618672DC8A5E0605441C9935 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E2B15F176E4B041AE33EEEA /* UIKit.framework */; };
+ 836D84C5F07860664DAF79C8 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D8F57162F5CC7AEDD55F173D /* WebKit.framework */; };
+ 9D59FB167BB4E699DA17D1E9 /* MetalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04B56F58E2E44DDE1D67E7B7 /* MetalKit.framework */; };
+ C6BD59C055C986EA4A77FDA2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = AF1DE57E7D9CF13BB2E0E038 /* Assets.xcassets */; };
+ C869023DDFE275D42F3FBF29 /* libapp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 39EEC6A55698228E08917A52 /* libapp.a */; };
+ E68F6CFDAED6503ABB4044A5 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE1209BFDECB28E00189B168 /* Metal.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 007E478DB8BC37A788C4730F /* app_iOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = app_iOS.entitlements; sourceTree = ""; };
+ 02B7F8347F94B067E6B27396 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; };
+ 04B56F58E2E44DDE1D67E7B7 /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = System/Library/Frameworks/MetalKit.framework; sourceTree = SDKROOT; };
+ 0E2B15F176E4B041AE33EEEA /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
+ 1631E4CFBB715FFDBF919C8C /* main.rs */ = {isa = PBXFileReference; lastKnownFileType = text; path = main.rs; sourceTree = ""; };
+ 17B52554D60D361AFE791C3E /* lib.rs */ = {isa = PBXFileReference; lastKnownFileType = text; path = lib.rs; sourceTree = ""; };
+ 1E81BD6B453D87B7F7B1597B /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+ 306B9C1792E7B1C53FA262A6 /* bindings.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = bindings.h; sourceTree = ""; };
+ 3842AE2A64FB9933D0400EA4 /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; path = assets; sourceTree = SOURCE_ROOT; };
+ 39EEC6A55698228E08917A52 /* libapp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libapp.a; sourceTree = ""; };
+ 682535EEFE1DA20BE07B123C /* main.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = ""; };
+ 81E326B61ED92E1D1EECF952 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; };
+ 9FACFFCB6E3743955F72464C /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
+ AF1DE57E7D9CF13BB2E0E038 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ CE1209BFDECB28E00189B168 /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; };
+ CF674524E34966183631754E /* libapp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libapp.a; sourceTree = ""; };
+ D8F57162F5CC7AEDD55F173D /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
+ F3673D372C5ABDD1AD6E7067 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
+ FBC720DFA1D01F55B0A32344 /* OpenCode Desktop.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "OpenCode Desktop.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 4825CF6C55516D374210C8E1 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C869023DDFE275D42F3FBF29 /* libapp.a in Frameworks */,
+ 31585529C029A01BE249A285 /* CoreGraphics.framework in Frameworks */,
+ E68F6CFDAED6503ABB4044A5 /* Metal.framework in Frameworks */,
+ 9D59FB167BB4E699DA17D1E9 /* MetalKit.framework in Frameworks */,
+ 299814393FFBF154FAD94CA8 /* QuartzCore.framework in Frameworks */,
+ 324A1E9A4258E7911D4DAC39 /* Security.framework in Frameworks */,
+ 618672DC8A5E0605441C9935 /* UIKit.framework in Frameworks */,
+ 836D84C5F07860664DAF79C8 /* WebKit.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 1BBF8C620E54F8C028CA130C /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 1E81BD6B453D87B7F7B1597B /* CoreGraphics.framework */,
+ 39EEC6A55698228E08917A52 /* libapp.a */,
+ CE1209BFDECB28E00189B168 /* Metal.framework */,
+ 04B56F58E2E44DDE1D67E7B7 /* MetalKit.framework */,
+ F3673D372C5ABDD1AD6E7067 /* QuartzCore.framework */,
+ 9FACFFCB6E3743955F72464C /* Security.framework */,
+ 0E2B15F176E4B041AE33EEEA /* UIKit.framework */,
+ D8F57162F5CC7AEDD55F173D /* WebKit.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+ 2867E55E70187711EE923EBD /* app_iOS */ = {
+ isa = PBXGroup;
+ children = (
+ 007E478DB8BC37A788C4730F /* app_iOS.entitlements */,
+ 81E326B61ED92E1D1EECF952 /* Info.plist */,
+ );
+ path = app_iOS;
+ sourceTree = "";
+ };
+ 329C38BE5E8B40354375D0D0 /* bindings */ = {
+ isa = PBXGroup;
+ children = (
+ 306B9C1792E7B1C53FA262A6 /* bindings.h */,
+ );
+ path = bindings;
+ sourceTree = "";
+ };
+ 5F72359403FB561BE1489F63 /* debug */ = {
+ isa = PBXGroup;
+ children = (
+ CF674524E34966183631754E /* libapp.a */,
+ );
+ path = debug;
+ sourceTree = "";
+ };
+ 70DD658F1D4B0FED51A79854 /* arm64 */ = {
+ isa = PBXGroup;
+ children = (
+ 5F72359403FB561BE1489F63 /* debug */,
+ );
+ path = arm64;
+ sourceTree = "";
+ };
+ 78CBE3E5873199C0066F12DF /* Sources */ = {
+ isa = PBXGroup;
+ children = (
+ FB1C68C0357A1866B3D27465 /* app */,
+ );
+ path = Sources;
+ sourceTree = "";
+ };
+ 855775165ACE55D883F89EB3 /* src */ = {
+ isa = PBXGroup;
+ children = (
+ 17B52554D60D361AFE791C3E /* lib.rs */,
+ 1631E4CFBB715FFDBF919C8C /* main.rs */,
+ );
+ name = src;
+ path = ../../src;
+ sourceTree = "";
+ };
+ 87648061424F20D5D4871E9E = {
+ isa = PBXGroup;
+ children = (
+ 3842AE2A64FB9933D0400EA4 /* assets */,
+ AF1DE57E7D9CF13BB2E0E038 /* Assets.xcassets */,
+ 02B7F8347F94B067E6B27396 /* LaunchScreen.storyboard */,
+ 2867E55E70187711EE923EBD /* app_iOS */,
+ BAFB695BB8415511FEC74542 /* Externals */,
+ 78CBE3E5873199C0066F12DF /* Sources */,
+ 855775165ACE55D883F89EB3 /* src */,
+ 1BBF8C620E54F8C028CA130C /* Frameworks */,
+ EE72B6AC647386A11F795E44 /* Products */,
+ );
+ sourceTree = "";
+ };
+ BAFB695BB8415511FEC74542 /* Externals */ = {
+ isa = PBXGroup;
+ children = (
+ 70DD658F1D4B0FED51A79854 /* arm64 */,
+ );
+ path = Externals;
+ sourceTree = "";
+ };
+ EE72B6AC647386A11F795E44 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ FBC720DFA1D01F55B0A32344 /* OpenCode Desktop.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ FB1C68C0357A1866B3D27465 /* app */ = {
+ isa = PBXGroup;
+ children = (
+ 682535EEFE1DA20BE07B123C /* main.mm */,
+ 329C38BE5E8B40354375D0D0 /* bindings */,
+ );
+ path = app;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ E86255CB8A1836C0BF0C0E14 /* app_iOS */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = CDCB6DFA1AEBFEE3F608BA27 /* Build configuration list for PBXNativeTarget "app_iOS" */;
+ buildPhases = (
+ E028F843270D8815FCE2B491 /* Build Rust Code */,
+ 81BE6BC5B603407AF570E994 /* Sources */,
+ 2FBCB8C3ED193E9C4A9FDB59 /* Resources */,
+ 4825CF6C55516D374210C8E1 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = app_iOS;
+ packageProductDependencies = (
+ );
+ productName = app_iOS;
+ productReference = FBC720DFA1D01F55B0A32344 /* OpenCode Desktop.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ A9B1B09F1872768368ACECE2 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ BuildIndependentTargetsInParallel = YES;
+ LastUpgradeCheck = 2600;
+ };
+ buildConfigurationList = B302E784349268C93E6F0A36 /* Build configuration list for PBXProject "app" */;
+ compatibilityVersion = "Xcode 14.0";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ Base,
+ en,
+ );
+ mainGroup = 87648061424F20D5D4871E9E;
+ minimizedProjectReferenceProxies = 1;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ E86255CB8A1836C0BF0C0E14 /* app_iOS */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 2FBCB8C3ED193E9C4A9FDB59 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C6BD59C055C986EA4A77FDA2 /* Assets.xcassets in Resources */,
+ 3036F7131E55779ABF15BD58 /* LaunchScreen.storyboard in Resources */,
+ 5C516481BCA83A182C2BCC94 /* assets in Resources */,
+ 36C1893A7382FCD5A6A74845 /* libapp.a in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ E028F843270D8815FCE2B491 /* Build Rust Code */ = {
+ isa = PBXShellScriptBuildPhase;
+ alwaysOutOfDate = 1;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ );
+ name = "Build Rust Code";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ "$(SRCROOT)/Externals/x86_64/${CONFIGURATION}/libapp.a",
+ "$(SRCROOT)/Externals/arm64/${CONFIGURATION}/libapp.a",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "export PATH=\"/Users/jkneen/.cargo/bin:$PATH\"\ncargo tauri ios xcode-script -v --platform ${PLATFORM_DISPLAY_NAME:?} --sdk-root ${SDKROOT:?} --framework-search-paths \"${FRAMEWORK_SEARCH_PATHS:?}\" --header-search-paths \"${HEADER_SEARCH_PATHS:?}\" --gcc-preprocessor-definitions \"${GCC_PREPROCESSOR_DEFINITIONS:-}\" --configuration ${CONFIGURATION:?} ${FORCE_COLOR} ${ARCHS:?}\n";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 81BE6BC5B603407AF570E994 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 53CDD0ACFBE8BDF1550B2E53 /* main.mm in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 1B9D5B8D34E6E0C88D0207F2 /* release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_ENTITLEMENTS = app_iOS/app_iOS.entitlements;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ ENABLE_BITCODE = NO;
+ "EXCLUDED_ARCHS[sdk=iphoneos*]" = x86_64;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "\".\"",
+ );
+ INFOPLIST_FILE = app_iOS/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ "LIBRARY_SEARCH_PATHS[arch=arm64]" = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION)",
+ "$(SDKROOT)/usr/lib/swift",
+ "$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)",
+ "$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)",
+ );
+ "LIBRARY_SEARCH_PATHS[arch=x86_64]" = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Externals/x86_64/$(CONFIGURATION)",
+ "$(SDKROOT)/usr/lib/swift",
+ "$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)",
+ "$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = ai.opencode.desktop;
+ PRODUCT_NAME = "OpenCode Desktop";
+ SDKROOT = iphoneos;
+ SUPPORTS_MACCATALYST = YES;
+ SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
+ TARGETED_DEVICE_FAMILY = "1,2,6";
+ VALID_ARCHS = arm64;
+ DEVELOPMENT_TEAM = "SW75ZJJ5R6";
+ };
+ name = release;
+ };
+ 3C6497CF9EADFA373F12EF5C /* release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DEVELOPMENT_TEAM = SW75ZJJ5R6;
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 14.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = iphoneos;
+ STRING_CATALOG_GENERATE_SYMBOLS = YES;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ SWIFT_VERSION = 5.0;
+ };
+ name = release;
+ };
+ 4AC19FD47C6011940ACEB467 /* debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_ENTITLEMENTS = app_iOS/app_iOS.entitlements;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ ENABLE_BITCODE = NO;
+ "EXCLUDED_ARCHS[sdk=iphoneos*]" = x86_64;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "\".\"",
+ );
+ INFOPLIST_FILE = app_iOS/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ "LIBRARY_SEARCH_PATHS[arch=arm64]" = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION)",
+ "$(SDKROOT)/usr/lib/swift",
+ "$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)",
+ "$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)",
+ );
+ "LIBRARY_SEARCH_PATHS[arch=x86_64]" = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Externals/x86_64/$(CONFIGURATION)",
+ "$(SDKROOT)/usr/lib/swift",
+ "$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)",
+ "$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = ai.opencode.desktop;
+ PRODUCT_NAME = "OpenCode Desktop";
+ SDKROOT = iphoneos;
+ SUPPORTS_MACCATALYST = YES;
+ SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
+ TARGETED_DEVICE_FAMILY = "1,2,6";
+ VALID_ARCHS = arm64;
+ DEVELOPMENT_TEAM = "SW75ZJJ5R6";
+ };
+ name = debug;
+ };
+ CAA806262C53A2E15E5DB0CA /* debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ DEVELOPMENT_TEAM = SW75ZJJ5R6;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "$(inherited)",
+ "DEBUG=1",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 14.0;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = iphoneos;
+ STRING_CATALOG_GENERATE_SYMBOLS = YES;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ };
+ name = debug;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ B302E784349268C93E6F0A36 /* Build configuration list for PBXProject "app" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ CAA806262C53A2E15E5DB0CA /* debug */,
+ 3C6497CF9EADFA373F12EF5C /* release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = debug;
+ };
+ CDCB6DFA1AEBFEE3F608BA27 /* Build configuration list for PBXNativeTarget "app_iOS" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 4AC19FD47C6011940ACEB467 /* debug */,
+ 1B9D5B8D34E6E0C88D0207F2 /* release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = debug;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = A9B1B09F1872768368ACECE2 /* Project object */;
+}
diff --git a/packages/desktop/src-tauri/gen/apple/app.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/desktop/src-tauri/gen/apple/app.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000000..919434a625
--- /dev/null
+++ b/packages/desktop/src-tauri/gen/apple/app.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/packages/desktop/src-tauri/gen/apple/app.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/packages/desktop/src-tauri/gen/apple/app.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
new file mode 100644
index 0000000000..7f25aeeacd
--- /dev/null
+++ b/packages/desktop/src-tauri/gen/apple/app.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
@@ -0,0 +1,10 @@
+
+
+
+
+ BuildSystemType
+ Latest
+ DisableBuildSystemDeprecationDiagnostic
+
+
+
diff --git a/packages/desktop/src-tauri/gen/apple/app.xcodeproj/xcshareddata/xcschemes/app_iOS.xcscheme b/packages/desktop/src-tauri/gen/apple/app.xcodeproj/xcshareddata/xcschemes/app_iOS.xcscheme
new file mode 100644
index 0000000000..eea080c37e
--- /dev/null
+++ b/packages/desktop/src-tauri/gen/apple/app.xcodeproj/xcshareddata/xcschemes/app_iOS.xcscheme
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/desktop/src-tauri/gen/apple/app_iOS/Info.plist b/packages/desktop/src-tauri/gen/apple/app_iOS/Info.plist
new file mode 100644
index 0000000000..163ac82f79
--- /dev/null
+++ b/packages/desktop/src-tauri/gen/apple/app_iOS/Info.plist
@@ -0,0 +1,52 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 0.1.0
+ CFBundleVersion
+ 0.1.0
+ LSRequiresIPhoneOS
+
+ UIDeviceFamily
+
+ 1
+ 2
+ 6
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIRequiredDeviceCapabilities
+
+ arm64
+ metal
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ NSMicrophoneUsageDescription
+ OpenCode needs microphone access for voice dictation
+
+
\ No newline at end of file
diff --git a/packages/desktop/src-tauri/gen/apple/app_iOS/app_iOS.entitlements b/packages/desktop/src-tauri/gen/apple/app_iOS/app_iOS.entitlements
new file mode 100644
index 0000000000..e89b7f323c
--- /dev/null
+++ b/packages/desktop/src-tauri/gen/apple/app_iOS/app_iOS.entitlements
@@ -0,0 +1,8 @@
+
+
+
+
+ com.apple.security.app-sandbox
+
+
+
diff --git a/packages/desktop/src-tauri/gen/apple/project.yml b/packages/desktop/src-tauri/gen/apple/project.yml
new file mode 100644
index 0000000000..ae1859bd21
--- /dev/null
+++ b/packages/desktop/src-tauri/gen/apple/project.yml
@@ -0,0 +1,94 @@
+name: app
+options:
+ bundleIdPrefix: ai.opencode.desktop
+ deploymentTarget:
+ iOS: 14.0
+fileGroups: [../../src]
+configs:
+ debug: debug
+ release: release
+settingGroups:
+ app:
+ base:
+ PRODUCT_NAME: OpenCode Desktop
+ PRODUCT_BUNDLE_IDENTIFIER: ai.opencode.desktop
+targetTemplates:
+ app:
+ type: application
+ sources:
+ - path: Sources
+ scheme:
+ environmentVariables:
+ RUST_BACKTRACE: full
+ RUST_LOG: info
+ settings:
+ groups: [app]
+targets:
+ app_iOS:
+ type: application
+ platform: iOS
+ sources:
+ - path: Sources
+ - path: Assets.xcassets
+ - path: Externals
+ - path: app_iOS
+ - path: assets
+ buildPhase: resources
+ type: folder
+ - path: LaunchScreen.storyboard
+ info:
+ path: app_iOS/Info.plist
+ properties:
+ LSRequiresIPhoneOS: true
+ UILaunchStoryboardName: LaunchScreen
+ UIRequiredDeviceCapabilities: [arm64, metal]
+ UISupportedInterfaceOrientations:
+ - UIInterfaceOrientationPortrait
+ - UIInterfaceOrientationLandscapeLeft
+ - UIInterfaceOrientationLandscapeRight
+ UISupportedInterfaceOrientations~ipad:
+ - UIInterfaceOrientationPortrait
+ - UIInterfaceOrientationPortraitUpsideDown
+ - UIInterfaceOrientationLandscapeLeft
+ - UIInterfaceOrientationLandscapeRight
+ CFBundleShortVersionString: 0.1.0
+ CFBundleVersion: "0.1.0"
+ UIDeviceFamily: [1, 2, 6]
+ entitlements:
+ path: app_iOS/app_iOS.entitlements
+ scheme:
+ environmentVariables:
+ RUST_BACKTRACE: full
+ RUST_LOG: info
+ settings:
+ base:
+ ENABLE_BITCODE: false
+ ARCHS: [arm64]
+ VALID_ARCHS: arm64
+ LIBRARY_SEARCH_PATHS[arch=x86_64]: $(inherited) $(PROJECT_DIR)/Externals/x86_64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)
+ LIBRARY_SEARCH_PATHS[arch=arm64]: $(inherited) $(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES: true
+ EXCLUDED_ARCHS[sdk=iphoneos*]: x86_64
+ SUPPORTS_MACCATALYST: true
+ SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD: true
+ TARGETED_DEVICE_FAMILY: "1,2,6"
+ groups: [app]
+ dependencies:
+ - framework: libapp.a
+ embed: false
+ - sdk: CoreGraphics.framework
+ - sdk: Metal.framework
+ - sdk: MetalKit.framework
+ - sdk: QuartzCore.framework
+ - sdk: Security.framework
+ - sdk: UIKit.framework
+ - sdk: WebKit.framework
+ preBuildScripts:
+ - script: |
+ export PATH="/Users/jkneen/.cargo/bin:$PATH"
+ cargo tauri ios xcode-script -v --platform ${PLATFORM_DISPLAY_NAME:?} --sdk-root ${SDKROOT:?} --framework-search-paths "${FRAMEWORK_SEARCH_PATHS:?}" --header-search-paths "${HEADER_SEARCH_PATHS:?}" --gcc-preprocessor-definitions "${GCC_PREPROCESSOR_DEFINITIONS:-}" --configuration ${CONFIGURATION:?} ${FORCE_COLOR} ${ARCHS:?}
+ name: Build Rust Code
+ basedOnDependencyAnalysis: false
+ outputFiles:
+ - $(SRCROOT)/Externals/x86_64/${CONFIGURATION}/libapp.a
+ - $(SRCROOT)/Externals/arm64/${CONFIGURATION}/libapp.a
diff --git a/packages/desktop/src-tauri/icons/128x128.png b/packages/desktop/src-tauri/icons/128x128.png
new file mode 100644
index 0000000000..1f469abba7
Binary files /dev/null and b/packages/desktop/src-tauri/icons/128x128.png differ
diff --git a/packages/desktop/src-tauri/icons/128x128@2x.png b/packages/desktop/src-tauri/icons/128x128@2x.png
new file mode 100644
index 0000000000..785b9b9ac1
Binary files /dev/null and b/packages/desktop/src-tauri/icons/128x128@2x.png differ
diff --git a/packages/desktop/src-tauri/icons/32x32.png b/packages/desktop/src-tauri/icons/32x32.png
new file mode 100644
index 0000000000..15512351e3
Binary files /dev/null and b/packages/desktop/src-tauri/icons/32x32.png differ
diff --git a/packages/desktop/src-tauri/icons/Square107x107Logo.png b/packages/desktop/src-tauri/icons/Square107x107Logo.png
new file mode 100644
index 0000000000..f35d84ff13
Binary files /dev/null and b/packages/desktop/src-tauri/icons/Square107x107Logo.png differ
diff --git a/packages/desktop/src-tauri/icons/Square142x142Logo.png b/packages/desktop/src-tauri/icons/Square142x142Logo.png
new file mode 100644
index 0000000000..1823bb2696
Binary files /dev/null and b/packages/desktop/src-tauri/icons/Square142x142Logo.png differ
diff --git a/packages/desktop/src-tauri/icons/Square150x150Logo.png b/packages/desktop/src-tauri/icons/Square150x150Logo.png
new file mode 100644
index 0000000000..dc2b22cea5
Binary files /dev/null and b/packages/desktop/src-tauri/icons/Square150x150Logo.png differ
diff --git a/packages/desktop/src-tauri/icons/Square284x284Logo.png b/packages/desktop/src-tauri/icons/Square284x284Logo.png
new file mode 100644
index 0000000000..0ed3984c5f
Binary files /dev/null and b/packages/desktop/src-tauri/icons/Square284x284Logo.png differ
diff --git a/packages/desktop/src-tauri/icons/Square30x30Logo.png b/packages/desktop/src-tauri/icons/Square30x30Logo.png
new file mode 100644
index 0000000000..60bf0eadf7
Binary files /dev/null and b/packages/desktop/src-tauri/icons/Square30x30Logo.png differ
diff --git a/packages/desktop/src-tauri/icons/Square310x310Logo.png b/packages/desktop/src-tauri/icons/Square310x310Logo.png
new file mode 100644
index 0000000000..c8ca0ad132
Binary files /dev/null and b/packages/desktop/src-tauri/icons/Square310x310Logo.png differ
diff --git a/packages/desktop/src-tauri/icons/Square44x44Logo.png b/packages/desktop/src-tauri/icons/Square44x44Logo.png
new file mode 100644
index 0000000000..8756459b63
Binary files /dev/null and b/packages/desktop/src-tauri/icons/Square44x44Logo.png differ
diff --git a/packages/desktop/src-tauri/icons/Square71x71Logo.png b/packages/desktop/src-tauri/icons/Square71x71Logo.png
new file mode 100644
index 0000000000..2c8023cc82
Binary files /dev/null and b/packages/desktop/src-tauri/icons/Square71x71Logo.png differ
diff --git a/packages/desktop/src-tauri/icons/Square89x89Logo.png b/packages/desktop/src-tauri/icons/Square89x89Logo.png
new file mode 100644
index 0000000000..2c5e6034ff
Binary files /dev/null and b/packages/desktop/src-tauri/icons/Square89x89Logo.png differ
diff --git a/packages/desktop/src-tauri/icons/StoreLogo.png b/packages/desktop/src-tauri/icons/StoreLogo.png
new file mode 100644
index 0000000000..17d142c0a4
Binary files /dev/null and b/packages/desktop/src-tauri/icons/StoreLogo.png differ
diff --git a/packages/desktop/src-tauri/icons/icon.icns b/packages/desktop/src-tauri/icons/icon.icns
new file mode 100644
index 0000000000..53aa497cb8
Binary files /dev/null and b/packages/desktop/src-tauri/icons/icon.icns differ
diff --git a/packages/desktop/src-tauri/icons/icon.ico b/packages/desktop/src-tauri/icons/icon.ico
new file mode 100644
index 0000000000..06c23c82fe
Binary files /dev/null and b/packages/desktop/src-tauri/icons/icon.ico differ
diff --git a/packages/desktop/src-tauri/icons/icon.png b/packages/desktop/src-tauri/icons/icon.png
new file mode 100644
index 0000000000..7e935121c6
Binary files /dev/null and b/packages/desktop/src-tauri/icons/icon.png differ
diff --git a/packages/desktop/src-tauri/src/lib.rs b/packages/desktop/src-tauri/src/lib.rs
new file mode 100644
index 0000000000..a8658967ee
--- /dev/null
+++ b/packages/desktop/src-tauri/src/lib.rs
@@ -0,0 +1,173 @@
+use std::process::{Command, Stdio};
+use std::sync::Mutex;
+use tauri::Manager;
+
+struct ServerState {
+ child: Option,
+ port: Option,
+}
+
+
+
+fn get_opencode_path() -> Option {
+ let shell = std::env::var("SHELL").unwrap_or_else(|_| "/bin/zsh".to_string());
+
+ let output = Command::new(&shell)
+ .arg("-l")
+ .arg("-c")
+ .arg("which opencode")
+ .output()
+ .ok()?;
+
+ if output.status.success() {
+ String::from_utf8(output.stdout)
+ .ok()
+ .map(|s| s.trim().to_string())
+ .filter(|s| !s.is_empty())
+ } else {
+ None
+ }
+}
+
+#[tauri::command]
+fn check_opencode_installed() -> bool {
+ get_opencode_path().is_some()
+}
+
+#[tauri::command]
+fn start_opencode_server(state: tauri::State>) -> Result {
+ let mut server_state = state.lock().unwrap();
+
+ if let Some(port) = server_state.port {
+ return Ok(port);
+ }
+
+ let opencode_path = get_opencode_path()
+ .ok_or_else(|| "OpenCode CLI not found in PATH".to_string())?;
+
+ eprintln!("Found opencode at: {}", opencode_path);
+
+ let port: u16 = 56849;
+
+ eprintln!("Starting server on port: {}", port);
+
+ let home_dir = std::env::var("HOME")
+ .map_err(|e| format!("Failed to get HOME: {}", e))?;
+
+ let child = Command::new(&opencode_path)
+ .arg("serve")
+ .arg("--port")
+ .arg(port.to_string())
+ .current_dir(&home_dir)
+ .stdout(Stdio::piped())
+ .stderr(Stdio::piped())
+ .spawn()
+ .map_err(|e| {
+ eprintln!("Failed to spawn: {}", e);
+ format!("Failed to start server: {}", e)
+ })?;
+
+ eprintln!("Server process started with PID: {:?}", child.id());
+
+ server_state.child = Some(child);
+ server_state.port = Some(port);
+
+ Ok(port)
+}
+
+#[tauri::command]
+fn get_git_branch(path: String) -> Result {
+ let output = Command::new("git")
+ .arg("-C")
+ .arg(&path)
+ .arg("rev-parse")
+ .arg("--abbrev-ref")
+ .arg("HEAD")
+ .output()
+ .map_err(|e| format!("Failed to get git branch: {}", e))?;
+
+ if output.status.success() {
+ String::from_utf8(output.stdout)
+ .ok()
+ .map(|s| s.trim().to_string())
+ .filter(|s| !s.is_empty())
+ .ok_or_else(|| "No branch found".to_string())
+ } else {
+ Err("Not a git repository".to_string())
+ }
+}
+
+#[tauri::command]
+fn select_folder(state: tauri::State>) -> Result {
+ use rfd::FileDialog;
+
+ let folder_path = FileDialog::new()
+ .set_title("Select Project Folder")
+ .pick_folder()
+ .ok_or_else(|| "No folder selected".to_string())?
+ .to_string_lossy()
+ .to_string();
+
+ eprintln!("Folder selected: {}", folder_path);
+
+ let mut server_state = state.lock().unwrap();
+
+ if let Some(mut child) = server_state.child.take() {
+ eprintln!("Killing existing server process");
+ let _ = child.kill();
+ }
+
+ let opencode_path = get_opencode_path()
+ .ok_or_else(|| "OpenCode CLI not found in PATH".to_string())?;
+
+ let port: u16 = 56849;
+
+ eprintln!("Starting server with path: {}", folder_path);
+
+ let child = Command::new(&opencode_path)
+ .arg("serve")
+ .arg("--port")
+ .arg(port.to_string())
+ .current_dir(&folder_path)
+ .stdout(Stdio::piped())
+ .stderr(Stdio::piped())
+ .spawn()
+ .map_err(|e| format!("Failed to start server: {}", e))?;
+
+ eprintln!("Server restarted with PID: {:?}", child.id());
+
+ server_state.child = Some(child);
+ server_state.port = Some(port);
+
+ Ok(folder_path)
+}
+
+#[cfg_attr(mobile, tauri::mobile_entry_point)]
+pub fn run() {
+ tauri::Builder::default()
+ .manage(Mutex::new(ServerState { child: None, port: None }))
+ .invoke_handler(tauri::generate_handler![
+ check_opencode_installed,
+ start_opencode_server,
+ select_folder,
+ get_git_branch
+ ])
+ .setup(|app| {
+ if cfg!(debug_assertions) {
+ app.handle().plugin(
+ tauri_plugin_log::Builder::default()
+ .level(log::LevelFilter::Info)
+ .build(),
+ )?;
+ }
+
+ let state = app.state::>();
+ if let Err(e) = start_opencode_server(state) {
+ eprintln!("Warning: Failed to auto-start server: {}", e);
+ }
+
+ Ok(())
+ })
+ .run(tauri::generate_context!())
+ .expect("error while running tauri application");
+}
diff --git a/packages/desktop/src-tauri/src/main.rs b/packages/desktop/src-tauri/src/main.rs
new file mode 100644
index 0000000000..ad5fe83991
--- /dev/null
+++ b/packages/desktop/src-tauri/src/main.rs
@@ -0,0 +1,6 @@
+// Prevents additional console window on Windows in release, DO NOT REMOVE!!
+#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
+
+fn main() {
+ app_lib::run();
+}
diff --git a/packages/desktop/src-tauri/tauri.conf.json b/packages/desktop/src-tauri/tauri.conf.json
new file mode 100644
index 0000000000..ed2b7d1bfb
--- /dev/null
+++ b/packages/desktop/src-tauri/tauri.conf.json
@@ -0,0 +1,53 @@
+{
+ "$schema": "../../../node_modules/@tauri-apps/cli/config.schema.json",
+ "productName": "OpenCode Desktop",
+ "version": "0.1.0",
+ "identifier": "ai.opencode.desktop",
+ "build": {
+ "frontendDist": "../dist",
+ "beforeDevCommand": "../scripts/tauri-dev.sh",
+ "beforeBuildCommand": "bun run build"
+ },
+ "app": {
+ "windows": [
+ {
+ "title": "@opencode-ai/desktop",
+ "width": 800,
+ "height": 600,
+ "resizable": true,
+ "fullscreen": false,
+ "devtools": true
+ }
+ ],
+ "security": {
+ "csp": null,
+ "assetProtocol": {
+ "enable": true,
+ "scope": ["**"]
+ }
+ },
+ "withGlobalTauri": true
+ },
+ "plugins": {
+ "fs": {
+ "scope": [
+ "$RESOURCE/**",
+ "$APP/**",
+ "$APPDATA/**",
+ "$APPLOCALDATA/**",
+ "$APPLOG/**",
+ "$APPCONFIG/**",
+ "$APPCACHE/**",
+ "../gen/apple/**"
+ ]
+ }
+ },
+ "bundle": {
+ "active": true,
+ "targets": "all",
+ "icon": ["icons/32x32.png", "icons/128x128.png", "icons/128x128@2x.png", "icons/icon.icns", "icons/icon.ico"],
+ "iOS": {
+ "developmentTeam": "SW75ZJJ5R6"
+ }
+ }
+}
diff --git a/packages/desktop/src-tauri/tauri.ios.conf.json b/packages/desktop/src-tauri/tauri.ios.conf.json
new file mode 100644
index 0000000000..9fc29131c4
--- /dev/null
+++ b/packages/desktop/src-tauri/tauri.ios.conf.json
@@ -0,0 +1,5 @@
+{
+ "build": {
+ "beforeBuildCommand": "bun run build"
+ }
+}
diff --git a/packages/desktop/src/assets/theme.css b/packages/desktop/src/assets/theme.css
new file mode 100644
index 0000000000..78673ecc09
--- /dev/null
+++ b/packages/desktop/src/assets/theme.css
@@ -0,0 +1,2386 @@
+/* Auto-generated theme CSS - Do not edit manually */
+:root {
+ --theme-primary: #3b7dd8;
+ --theme-secondary: #7b5bb6;
+ --theme-accent: #d68c27;
+ --theme-error: #d1383d;
+ --theme-warning: #d68c27;
+ --theme-success: #3d9a57;
+ --theme-info: #318795;
+ --theme-text: #1a1a1a;
+ --theme-text-muted: #8a8a8a;
+ --theme-background: #ffffff;
+ --theme-background-panel: #fafafa;
+ --theme-background-element: #f5f5f5;
+ --theme-border: #b8b8b8;
+ --theme-border-active: #a0a0a0;
+ --theme-border-subtle: #d4d4d4;
+ --theme-diff-added: #1e725c;
+ --theme-diff-removed: #c53b53;
+ --theme-diff-context: #7086b5;
+ --theme-diff-hunk-header: #7086b5;
+ --theme-diff-highlight-added: #4db380;
+ --theme-diff-highlight-removed: #f52a65;
+ --theme-diff-added-bg: #d5e5d5;
+ --theme-diff-removed-bg: #f7d8db;
+ --theme-diff-context-bg: #fafafa;
+ --theme-diff-line-number: #f5f5f5;
+ --theme-diff-added-line-number-bg: #c5d5c5;
+ --theme-diff-removed-line-number-bg: #e7c8cb;
+ --theme-markdown-text: #1a1a1a;
+ --theme-markdown-heading: #d68c27;
+ --theme-markdown-link: #3b7dd8;
+ --theme-markdown-link-text: #318795;
+ --theme-markdown-code: #3d9a57;
+ --theme-markdown-block-quote: #b0851f;
+ --theme-markdown-emph: #b0851f;
+ --theme-markdown-strong: #d68c27;
+ --theme-markdown-horizontal-rule: #8a8a8a;
+ --theme-markdown-list-item: #3b7dd8;
+ --theme-markdown-list-enumeration: #318795;
+ --theme-markdown-image: #3b7dd8;
+ --theme-markdown-image-text: #318795;
+ --theme-markdown-code-block: #1a1a1a;
+ --theme-syntax-comment: #8a8a8a;
+ --theme-syntax-keyword: #d68c27;
+ --theme-syntax-function: #3b7dd8;
+ --theme-syntax-variable: #d1383d;
+ --theme-syntax-string: #3d9a57;
+ --theme-syntax-number: #d68c27;
+ --theme-syntax-type: #b0851f;
+ --theme-syntax-operator: #318795;
+ --theme-syntax-punctuation: #1a1a1a;
+}
+
+[data-theme="aura"][data-dark="false"] {
+ --theme-primary: #a277ff;
+ --theme-secondary: #f694ff;
+ --theme-accent: #a277ff;
+ --theme-error: #ff6767;
+ --theme-warning: #ffca85;
+ --theme-success: #61ffca;
+ --theme-info: #a277ff;
+ --theme-text: #edecee;
+ --theme-text-muted: #6d6d6d;
+ --theme-background: #0f0f0f;
+ --theme-background-panel: #15141b;
+ --theme-background-element: #15141b;
+ --theme-border: #2d2d2d;
+ --theme-border-active: #6d6d6d;
+ --theme-border-subtle: #2d2d2d;
+ --theme-diff-added: #61ffca;
+ --theme-diff-removed: #ff6767;
+ --theme-diff-context: #6d6d6d;
+ --theme-diff-hunk-header: #6d6d6d;
+ --theme-diff-highlight-added: #61ffca;
+ --theme-diff-highlight-removed: #ff6767;
+ --theme-diff-added-bg: #354933;
+ --theme-diff-removed-bg: #3f191a;
+ --theme-diff-context-bg: #15141b;
+ --theme-diff-line-number: #2d2d2d;
+ --theme-diff-added-line-number-bg: #162620;
+ --theme-diff-removed-line-number-bg: #26161a;
+ --theme-markdown-text: #edecee;
+ --theme-markdown-heading: #a277ff;
+ --theme-markdown-link: #f694ff;
+ --theme-markdown-link-text: #a277ff;
+ --theme-markdown-code: #61ffca;
+ --theme-markdown-block-quote: #6d6d6d;
+ --theme-markdown-emph: #ffca85;
+ --theme-markdown-strong: #a277ff;
+ --theme-markdown-horizontal-rule: #6d6d6d;
+ --theme-markdown-list-item: #a277ff;
+ --theme-markdown-list-enumeration: #a277ff;
+ --theme-markdown-image: #f694ff;
+ --theme-markdown-image-text: #a277ff;
+ --theme-markdown-code-block: #edecee;
+ --theme-syntax-comment: #6d6d6d;
+ --theme-syntax-keyword: #f694ff;
+ --theme-syntax-function: #a277ff;
+ --theme-syntax-variable: #a277ff;
+ --theme-syntax-string: #61ffca;
+ --theme-syntax-number: #9dff65;
+ --theme-syntax-type: #a277ff;
+ --theme-syntax-operator: #f694ff;
+ --theme-syntax-punctuation: #edecee;
+}
+
+[data-theme="aura"][data-dark="true"] {
+ --theme-primary: #a277ff;
+ --theme-secondary: #f694ff;
+ --theme-accent: #a277ff;
+ --theme-error: #ff6767;
+ --theme-warning: #ffca85;
+ --theme-success: #61ffca;
+ --theme-info: #a277ff;
+ --theme-text: #edecee;
+ --theme-text-muted: #6d6d6d;
+ --theme-background: #0f0f0f;
+ --theme-background-panel: #15141b;
+ --theme-background-element: #15141b;
+ --theme-border: #2d2d2d;
+ --theme-border-active: #6d6d6d;
+ --theme-border-subtle: #2d2d2d;
+ --theme-diff-added: #61ffca;
+ --theme-diff-removed: #ff6767;
+ --theme-diff-context: #6d6d6d;
+ --theme-diff-hunk-header: #6d6d6d;
+ --theme-diff-highlight-added: #61ffca;
+ --theme-diff-highlight-removed: #ff6767;
+ --theme-diff-added-bg: #354933;
+ --theme-diff-removed-bg: #3f191a;
+ --theme-diff-context-bg: #15141b;
+ --theme-diff-line-number: #2d2d2d;
+ --theme-diff-added-line-number-bg: #162620;
+ --theme-diff-removed-line-number-bg: #26161a;
+ --theme-markdown-text: #edecee;
+ --theme-markdown-heading: #a277ff;
+ --theme-markdown-link: #f694ff;
+ --theme-markdown-link-text: #a277ff;
+ --theme-markdown-code: #61ffca;
+ --theme-markdown-block-quote: #6d6d6d;
+ --theme-markdown-emph: #ffca85;
+ --theme-markdown-strong: #a277ff;
+ --theme-markdown-horizontal-rule: #6d6d6d;
+ --theme-markdown-list-item: #a277ff;
+ --theme-markdown-list-enumeration: #a277ff;
+ --theme-markdown-image: #f694ff;
+ --theme-markdown-image-text: #a277ff;
+ --theme-markdown-code-block: #edecee;
+ --theme-syntax-comment: #6d6d6d;
+ --theme-syntax-keyword: #f694ff;
+ --theme-syntax-function: #a277ff;
+ --theme-syntax-variable: #a277ff;
+ --theme-syntax-string: #61ffca;
+ --theme-syntax-number: #9dff65;
+ --theme-syntax-type: #a277ff;
+ --theme-syntax-operator: #f694ff;
+ --theme-syntax-punctuation: #edecee;
+}
+
+[data-theme="ayu"][data-dark="false"] {
+ --theme-primary: #59c2ff;
+ --theme-secondary: #d2a6ff;
+ --theme-accent: #e6b450;
+ --theme-error: #d95757;
+ --theme-warning: #e6b673;
+ --theme-success: #7fd962;
+ --theme-info: #39bae6;
+ --theme-text: #bfbdb6;
+ --theme-text-muted: #565b66;
+ --theme-background: #0b0e14;
+ --theme-background-panel: #0f131a;
+ --theme-background-element: #0d1017;
+ --theme-border: #6c7380;
+ --theme-border-active: #6c7380;
+ --theme-border-subtle: #11151c;
+ --theme-diff-added: #7fd962;
+ --theme-diff-removed: #f26d78;
+ --theme-diff-context: #acb6bf;
+ --theme-diff-hunk-header: #acb6bf;
+ --theme-diff-highlight-added: #aad94c;
+ --theme-diff-highlight-removed: #f07178;
+ --theme-diff-added-bg: #20303b;
+ --theme-diff-removed-bg: #37222c;
+ --theme-diff-context-bg: #0f131a;
+ --theme-diff-line-number: #6c7380;
+ --theme-diff-added-line-number-bg: #1b2b34;
+ --theme-diff-removed-line-number-bg: #2d1f26;
+ --theme-markdown-text: #bfbdb6;
+ --theme-markdown-heading: #d2a6ff;
+ --theme-markdown-link: #59c2ff;
+ --theme-markdown-link-text: #39bae6;
+ --theme-markdown-code: #aad94c;
+ --theme-markdown-block-quote: #e6b673;
+ --theme-markdown-emph: #e6b673;
+ --theme-markdown-strong: #ffb454;
+ --theme-markdown-horizontal-rule: #565b66;
+ --theme-markdown-list-item: #59c2ff;
+ --theme-markdown-list-enumeration: #39bae6;
+ --theme-markdown-image: #59c2ff;
+ --theme-markdown-image-text: #39bae6;
+ --theme-markdown-code-block: #bfbdb6;
+ --theme-syntax-comment: #acb6bf;
+ --theme-syntax-keyword: #ff8f40;
+ --theme-syntax-function: #ffb454;
+ --theme-syntax-variable: #59c2ff;
+ --theme-syntax-string: #aad94c;
+ --theme-syntax-number: #d2a6ff;
+ --theme-syntax-type: #e6b673;
+ --theme-syntax-operator: #f29668;
+ --theme-syntax-punctuation: #bfbdb6;
+}
+
+[data-theme="ayu"][data-dark="true"] {
+ --theme-primary: #59c2ff;
+ --theme-secondary: #d2a6ff;
+ --theme-accent: #e6b450;
+ --theme-error: #d95757;
+ --theme-warning: #e6b673;
+ --theme-success: #7fd962;
+ --theme-info: #39bae6;
+ --theme-text: #bfbdb6;
+ --theme-text-muted: #565b66;
+ --theme-background: #0b0e14;
+ --theme-background-panel: #0f131a;
+ --theme-background-element: #0d1017;
+ --theme-border: #6c7380;
+ --theme-border-active: #6c7380;
+ --theme-border-subtle: #11151c;
+ --theme-diff-added: #7fd962;
+ --theme-diff-removed: #f26d78;
+ --theme-diff-context: #acb6bf;
+ --theme-diff-hunk-header: #acb6bf;
+ --theme-diff-highlight-added: #aad94c;
+ --theme-diff-highlight-removed: #f07178;
+ --theme-diff-added-bg: #20303b;
+ --theme-diff-removed-bg: #37222c;
+ --theme-diff-context-bg: #0f131a;
+ --theme-diff-line-number: #6c7380;
+ --theme-diff-added-line-number-bg: #1b2b34;
+ --theme-diff-removed-line-number-bg: #2d1f26;
+ --theme-markdown-text: #bfbdb6;
+ --theme-markdown-heading: #d2a6ff;
+ --theme-markdown-link: #59c2ff;
+ --theme-markdown-link-text: #39bae6;
+ --theme-markdown-code: #aad94c;
+ --theme-markdown-block-quote: #e6b673;
+ --theme-markdown-emph: #e6b673;
+ --theme-markdown-strong: #ffb454;
+ --theme-markdown-horizontal-rule: #565b66;
+ --theme-markdown-list-item: #59c2ff;
+ --theme-markdown-list-enumeration: #39bae6;
+ --theme-markdown-image: #59c2ff;
+ --theme-markdown-image-text: #39bae6;
+ --theme-markdown-code-block: #bfbdb6;
+ --theme-syntax-comment: #acb6bf;
+ --theme-syntax-keyword: #ff8f40;
+ --theme-syntax-function: #ffb454;
+ --theme-syntax-variable: #59c2ff;
+ --theme-syntax-string: #aad94c;
+ --theme-syntax-number: #d2a6ff;
+ --theme-syntax-type: #e6b673;
+ --theme-syntax-operator: #f29668;
+ --theme-syntax-punctuation: #bfbdb6;
+}
+
+[data-theme="catppuccin"][data-dark="false"] {
+ --theme-primary: #1e66f5;
+ --theme-secondary: #8839ef;
+ --theme-accent: #ea76cb;
+ --theme-error: #d20f39;
+ --theme-warning: #df8e1d;
+ --theme-success: #40a02b;
+ --theme-info: #179299;
+ --theme-text: #4c4f69;
+ --theme-text-muted: #5c5f77;
+ --theme-background: #eff1f5;
+ --theme-background-panel: #e6e9ef;
+ --theme-background-element: #dce0e8;
+ --theme-border: #ccd0da;
+ --theme-border-active: #bcc0cc;
+ --theme-border-subtle: #acb0be;
+ --theme-diff-added: #40a02b;
+ --theme-diff-removed: #d20f39;
+ --theme-diff-context: #7c7f93;
+ --theme-diff-hunk-header: #fe640b;
+ --theme-diff-highlight-added: #40a02b;
+ --theme-diff-highlight-removed: #d20f39;
+ --theme-diff-added-bg: #d6f0d9;
+ --theme-diff-removed-bg: #f6dfe2;
+ --theme-diff-context-bg: #e6e9ef;
+ --theme-diff-line-number: #bcc0cc;
+ --theme-diff-added-line-number-bg: #c9e3cb;
+ --theme-diff-removed-line-number-bg: #e9d3d6;
+ --theme-markdown-text: #4c4f69;
+ --theme-markdown-heading: #8839ef;
+ --theme-markdown-link: #1e66f5;
+ --theme-markdown-link-text: #04a5e5;
+ --theme-markdown-code: #40a02b;
+ --theme-markdown-block-quote: #df8e1d;
+ --theme-markdown-emph: #df8e1d;
+ --theme-markdown-strong: #fe640b;
+ --theme-markdown-horizontal-rule: #6c6f85;
+ --theme-markdown-list-item: #1e66f5;
+ --theme-markdown-list-enumeration: #04a5e5;
+ --theme-markdown-image: #1e66f5;
+ --theme-markdown-image-text: #04a5e5;
+ --theme-markdown-code-block: #4c4f69;
+ --theme-syntax-comment: #7c7f93;
+ --theme-syntax-keyword: #8839ef;
+ --theme-syntax-function: #1e66f5;
+ --theme-syntax-variable: #d20f39;
+ --theme-syntax-string: #40a02b;
+ --theme-syntax-number: #fe640b;
+ --theme-syntax-type: #df8e1d;
+ --theme-syntax-operator: #04a5e5;
+ --theme-syntax-punctuation: #4c4f69;
+}
+
+[data-theme="catppuccin"][data-dark="true"] {
+ --theme-primary: #89b4fa;
+ --theme-secondary: #cba6f7;
+ --theme-accent: #f5c2e7;
+ --theme-error: #f38ba8;
+ --theme-warning: #f9e2af;
+ --theme-success: #a6e3a1;
+ --theme-info: #94e2d5;
+ --theme-text: #cdd6f4;
+ --theme-text-muted: #bac2de;
+ --theme-background: #1e1e2e;
+ --theme-background-panel: #181825;
+ --theme-background-element: #11111b;
+ --theme-border: #313244;
+ --theme-border-active: #45475a;
+ --theme-border-subtle: #585b70;
+ --theme-diff-added: #a6e3a1;
+ --theme-diff-removed: #f38ba8;
+ --theme-diff-context: #9399b2;
+ --theme-diff-hunk-header: #fab387;
+ --theme-diff-highlight-added: #a6e3a1;
+ --theme-diff-highlight-removed: #f38ba8;
+ --theme-diff-added-bg: #24312b;
+ --theme-diff-removed-bg: #3c2a32;
+ --theme-diff-context-bg: #181825;
+ --theme-diff-line-number: #45475a;
+ --theme-diff-added-line-number-bg: #1e2a25;
+ --theme-diff-removed-line-number-bg: #32232a;
+ --theme-markdown-text: #cdd6f4;
+ --theme-markdown-heading: #cba6f7;
+ --theme-markdown-link: #89b4fa;
+ --theme-markdown-link-text: #89dceb;
+ --theme-markdown-code: #a6e3a1;
+ --theme-markdown-block-quote: #f9e2af;
+ --theme-markdown-emph: #f9e2af;
+ --theme-markdown-strong: #fab387;
+ --theme-markdown-horizontal-rule: #a6adc8;
+ --theme-markdown-list-item: #89b4fa;
+ --theme-markdown-list-enumeration: #89dceb;
+ --theme-markdown-image: #89b4fa;
+ --theme-markdown-image-text: #89dceb;
+ --theme-markdown-code-block: #cdd6f4;
+ --theme-syntax-comment: #9399b2;
+ --theme-syntax-keyword: #cba6f7;
+ --theme-syntax-function: #89b4fa;
+ --theme-syntax-variable: #f38ba8;
+ --theme-syntax-string: #a6e3a1;
+ --theme-syntax-number: #fab387;
+ --theme-syntax-type: #f9e2af;
+ --theme-syntax-operator: #89dceb;
+ --theme-syntax-punctuation: #cdd6f4;
+}
+
+[data-theme="cobalt2"][data-dark="false"] {
+ --theme-primary: #0066cc;
+ --theme-secondary: #7c4dff;
+ --theme-accent: #00acc1;
+ --theme-error: #e91e63;
+ --theme-warning: #ff9800;
+ --theme-success: #4caf50;
+ --theme-info: #ff5722;
+ --theme-text: #193549;
+ --theme-text-muted: #5c6b7d;
+ --theme-background: #ffffff;
+ --theme-background-panel: #f5f7fa;
+ --theme-background-element: #e8ecf1;
+ --theme-border: #d3dae3;
+ --theme-border-active: #0066cc;
+ --theme-border-subtle: #e8ecf1;
+ --theme-diff-added: #4caf50;
+ --theme-diff-removed: #e91e63;
+ --theme-diff-context: #5c6b7d;
+ --theme-diff-hunk-header: #00acc1;
+ --theme-diff-highlight-added: #4caf50;
+ --theme-diff-highlight-removed: #e91e63;
+ --theme-diff-added-bg: #e8f5e9;
+ --theme-diff-removed-bg: #ffebee;
+ --theme-diff-context-bg: #f5f7fa;
+ --theme-diff-line-number: #b0bec5;
+ --theme-diff-added-line-number-bg: #e8f5e9;
+ --theme-diff-removed-line-number-bg: #ffebee;
+ --theme-markdown-text: #193549;
+ --theme-markdown-heading: #ff9800;
+ --theme-markdown-link: #0066cc;
+ --theme-markdown-link-text: #00acc1;
+ --theme-markdown-code: #4caf50;
+ --theme-markdown-block-quote: #5c6b7d;
+ --theme-markdown-emph: #ff5722;
+ --theme-markdown-strong: #e91e63;
+ --theme-markdown-horizontal-rule: #d3dae3;
+ --theme-markdown-list-item: #0066cc;
+ --theme-markdown-list-enumeration: #00acc1;
+ --theme-markdown-image: #0066cc;
+ --theme-markdown-image-text: #00acc1;
+ --theme-markdown-code-block: #193549;
+ --theme-syntax-comment: #5c6b7d;
+ --theme-syntax-keyword: #ff5722;
+ --theme-syntax-function: #ff9800;
+ --theme-syntax-variable: #193549;
+ --theme-syntax-string: #4caf50;
+ --theme-syntax-number: #e91e63;
+ --theme-syntax-type: #00acc1;
+ --theme-syntax-operator: #ff5722;
+ --theme-syntax-punctuation: #193549;
+}
+
+[data-theme="cobalt2"][data-dark="true"] {
+ --theme-primary: #0088ff;
+ --theme-secondary: #9a5feb;
+ --theme-accent: #2affdf;
+ --theme-error: #ff0088;
+ --theme-warning: #ffc600;
+ --theme-success: #9eff80;
+ --theme-info: #ff9d00;
+ --theme-text: #ffffff;
+ --theme-text-muted: #adb7c9;
+ --theme-background: #193549;
+ --theme-background-panel: #122738;
+ --theme-background-element: #1f4662;
+ --theme-border: #1f4662;
+ --theme-border-active: #0088ff;
+ --theme-border-subtle: #0e1e2e;
+ --theme-diff-added: #9eff80;
+ --theme-diff-removed: #ff0088;
+ --theme-diff-context: #adb7c9;
+ --theme-diff-hunk-header: #2affdf;
+ --theme-diff-highlight-added: #b9ff9f;
+ --theme-diff-highlight-removed: #ff5fb3;
+ --theme-diff-added-bg: #1a3a2a;
+ --theme-diff-removed-bg: #3a1a2a;
+ --theme-diff-context-bg: #122738;
+ --theme-diff-line-number: #2d5a7b;
+ --theme-diff-added-line-number-bg: #1a3a2a;
+ --theme-diff-removed-line-number-bg: #3a1a2a;
+ --theme-markdown-text: #ffffff;
+ --theme-markdown-heading: #ffc600;
+ --theme-markdown-link: #0088ff;
+ --theme-markdown-link-text: #2affdf;
+ --theme-markdown-code: #9eff80;
+ --theme-markdown-block-quote: #adb7c9;
+ --theme-markdown-emph: #ff9d00;
+ --theme-markdown-strong: #ff628c;
+ --theme-markdown-horizontal-rule: #2d5a7b;
+ --theme-markdown-list-item: #0088ff;
+ --theme-markdown-list-enumeration: #2affdf;
+ --theme-markdown-image: #0088ff;
+ --theme-markdown-image-text: #2affdf;
+ --theme-markdown-code-block: #ffffff;
+ --theme-syntax-comment: #0088ff;
+ --theme-syntax-keyword: #ff9d00;
+ --theme-syntax-function: #ffc600;
+ --theme-syntax-variable: #ffffff;
+ --theme-syntax-string: #9eff80;
+ --theme-syntax-number: #ff628c;
+ --theme-syntax-type: #2affdf;
+ --theme-syntax-operator: #ff9d00;
+ --theme-syntax-punctuation: #ffffff;
+}
+
+[data-theme="dracula"][data-dark="false"] {
+ --theme-primary: #bd93f9;
+ --theme-secondary: #ff79c6;
+ --theme-accent: #8be9fd;
+ --theme-error: #ff5555;
+ --theme-warning: #f1fa8c;
+ --theme-success: #50fa7b;
+ --theme-info: #ffb86c;
+ --theme-text: #282a36;
+ --theme-text-muted: #6272a4;
+ --theme-background: #f8f8f2;
+ --theme-background-panel: #e8e8e2;
+ --theme-background-element: #d8d8d2;
+ --theme-border: #c8c8c2;
+ --theme-border-active: #bd93f9;
+ --theme-border-subtle: #e0e0e0;
+ --theme-diff-added: #50fa7b;
+ --theme-diff-removed: #ff5555;
+ --theme-diff-context: #6272a4;
+ --theme-diff-hunk-header: #6272a4;
+ --theme-diff-highlight-added: #50fa7b;
+ --theme-diff-highlight-removed: #ff5555;
+ --theme-diff-added-bg: #e0ffe0;
+ --theme-diff-removed-bg: #ffe0e0;
+ --theme-diff-context-bg: #e8e8e2;
+ --theme-diff-line-number: #c8c8c2;
+ --theme-diff-added-line-number-bg: #e0ffe0;
+ --theme-diff-removed-line-number-bg: #ffe0e0;
+ --theme-markdown-text: #282a36;
+ --theme-markdown-heading: #bd93f9;
+ --theme-markdown-link: #8be9fd;
+ --theme-markdown-link-text: #ff79c6;
+ --theme-markdown-code: #50fa7b;
+ --theme-markdown-block-quote: #6272a4;
+ --theme-markdown-emph: #f1fa8c;
+ --theme-markdown-strong: #ffb86c;
+ --theme-markdown-horizontal-rule: #6272a4;
+ --theme-markdown-list-item: #bd93f9;
+ --theme-markdown-list-enumeration: #8be9fd;
+ --theme-markdown-image: #8be9fd;
+ --theme-markdown-image-text: #ff79c6;
+ --theme-markdown-code-block: #282a36;
+ --theme-syntax-comment: #6272a4;
+ --theme-syntax-keyword: #ff79c6;
+ --theme-syntax-function: #50fa7b;
+ --theme-syntax-variable: #282a36;
+ --theme-syntax-string: #f1fa8c;
+ --theme-syntax-number: #bd93f9;
+ --theme-syntax-type: #8be9fd;
+ --theme-syntax-operator: #ff79c6;
+ --theme-syntax-punctuation: #282a36;
+}
+
+[data-theme="dracula"][data-dark="true"] {
+ --theme-primary: #bd93f9;
+ --theme-secondary: #ff79c6;
+ --theme-accent: #8be9fd;
+ --theme-error: #ff5555;
+ --theme-warning: #f1fa8c;
+ --theme-success: #50fa7b;
+ --theme-info: #ffb86c;
+ --theme-text: #f8f8f2;
+ --theme-text-muted: #6272a4;
+ --theme-background: #282a36;
+ --theme-background-panel: #21222c;
+ --theme-background-element: #44475a;
+ --theme-border: #44475a;
+ --theme-border-active: #bd93f9;
+ --theme-border-subtle: #191a21;
+ --theme-diff-added: #50fa7b;
+ --theme-diff-removed: #ff5555;
+ --theme-diff-context: #6272a4;
+ --theme-diff-hunk-header: #6272a4;
+ --theme-diff-highlight-added: #50fa7b;
+ --theme-diff-highlight-removed: #ff5555;
+ --theme-diff-added-bg: #1a3a1a;
+ --theme-diff-removed-bg: #3a1a1a;
+ --theme-diff-context-bg: #21222c;
+ --theme-diff-line-number: #44475a;
+ --theme-diff-added-line-number-bg: #1a3a1a;
+ --theme-diff-removed-line-number-bg: #3a1a1a;
+ --theme-markdown-text: #f8f8f2;
+ --theme-markdown-heading: #bd93f9;
+ --theme-markdown-link: #8be9fd;
+ --theme-markdown-link-text: #ff79c6;
+ --theme-markdown-code: #50fa7b;
+ --theme-markdown-block-quote: #6272a4;
+ --theme-markdown-emph: #f1fa8c;
+ --theme-markdown-strong: #ffb86c;
+ --theme-markdown-horizontal-rule: #6272a4;
+ --theme-markdown-list-item: #bd93f9;
+ --theme-markdown-list-enumeration: #8be9fd;
+ --theme-markdown-image: #8be9fd;
+ --theme-markdown-image-text: #ff79c6;
+ --theme-markdown-code-block: #f8f8f2;
+ --theme-syntax-comment: #6272a4;
+ --theme-syntax-keyword: #ff79c6;
+ --theme-syntax-function: #50fa7b;
+ --theme-syntax-variable: #f8f8f2;
+ --theme-syntax-string: #f1fa8c;
+ --theme-syntax-number: #bd93f9;
+ --theme-syntax-type: #8be9fd;
+ --theme-syntax-operator: #ff79c6;
+ --theme-syntax-punctuation: #f8f8f2;
+}
+
+[data-theme="everforest"][data-dark="false"] {
+ --theme-primary: #8da101;
+ --theme-secondary: #3a94c5;
+ --theme-accent: #df69ba;
+ --theme-error: #f85552;
+ --theme-warning: #f57d26;
+ --theme-success: #8da101;
+ --theme-info: #35a77c;
+ --theme-text: #5c6a72;
+ --theme-text-muted: #a6b0a0;
+ --theme-background: #fdf6e3;
+ --theme-background-panel: #efebd4;
+ --theme-background-element: #f4f0d9;
+ --theme-border: #939f91;
+ --theme-border-active: #829181;
+ --theme-border-subtle: #a6b0a0;
+ --theme-diff-added: #1e725c;
+ --theme-diff-removed: #c53b53;
+ --theme-diff-context: #7086b5;
+ --theme-diff-hunk-header: #7086b5;
+ --theme-diff-highlight-added: #4db380;
+ --theme-diff-highlight-removed: #f52a65;
+ --theme-diff-added-bg: #d5e5d5;
+ --theme-diff-removed-bg: #f7d8db;
+ --theme-diff-context-bg: #efebd4;
+ --theme-diff-line-number: #f4f0d9;
+ --theme-diff-added-line-number-bg: #c5d5c5;
+ --theme-diff-removed-line-number-bg: #e7c8cb;
+ --theme-markdown-text: #5c6a72;
+ --theme-markdown-heading: #df69ba;
+ --theme-markdown-link: #8da101;
+ --theme-markdown-link-text: #35a77c;
+ --theme-markdown-code: #8da101;
+ --theme-markdown-block-quote: #dfa000;
+ --theme-markdown-emph: #dfa000;
+ --theme-markdown-strong: #f57d26;
+ --theme-markdown-horizontal-rule: #a6b0a0;
+ --theme-markdown-list-item: #8da101;
+ --theme-markdown-list-enumeration: #35a77c;
+ --theme-markdown-image: #8da101;
+ --theme-markdown-image-text: #35a77c;
+ --theme-markdown-code-block: #5c6a72;
+ --theme-syntax-comment: #a6b0a0;
+ --theme-syntax-keyword: #df69ba;
+ --theme-syntax-function: #8da101;
+ --theme-syntax-variable: #f85552;
+ --theme-syntax-string: #8da101;
+ --theme-syntax-number: #f57d26;
+ --theme-syntax-type: #dfa000;
+ --theme-syntax-operator: #35a77c;
+ --theme-syntax-punctuation: #5c6a72;
+}
+
+[data-theme="everforest"][data-dark="true"] {
+ --theme-primary: #a7c080;
+ --theme-secondary: #7fbbb3;
+ --theme-accent: #d699b6;
+ --theme-error: #e67e80;
+ --theme-warning: #e69875;
+ --theme-success: #a7c080;
+ --theme-info: #83c092;
+ --theme-text: #d3c6aa;
+ --theme-text-muted: #7a8478;
+ --theme-background: #2d353b;
+ --theme-background-panel: #333c43;
+ --theme-background-element: #343f44;
+ --theme-border: #859289;
+ --theme-border-active: #9da9a0;
+ --theme-border-subtle: #7a8478;
+ --theme-diff-added: #4fd6be;
+ --theme-diff-removed: #c53b53;
+ --theme-diff-context: #828bb8;
+ --theme-diff-hunk-header: #828bb8;
+ --theme-diff-highlight-added: #b8db87;
+ --theme-diff-highlight-removed: #e26a75;
+ --theme-diff-added-bg: #20303b;
+ --theme-diff-removed-bg: #37222c;
+ --theme-diff-context-bg: #333c43;
+ --theme-diff-line-number: #343f44;
+ --theme-diff-added-line-number-bg: #1b2b34;
+ --theme-diff-removed-line-number-bg: #2d1f26;
+ --theme-markdown-text: #d3c6aa;
+ --theme-markdown-heading: #d699b6;
+ --theme-markdown-link: #a7c080;
+ --theme-markdown-link-text: #83c092;
+ --theme-markdown-code: #a7c080;
+ --theme-markdown-block-quote: #dbbc7f;
+ --theme-markdown-emph: #dbbc7f;
+ --theme-markdown-strong: #e69875;
+ --theme-markdown-horizontal-rule: #7a8478;
+ --theme-markdown-list-item: #a7c080;
+ --theme-markdown-list-enumeration: #83c092;
+ --theme-markdown-image: #a7c080;
+ --theme-markdown-image-text: #83c092;
+ --theme-markdown-code-block: #d3c6aa;
+ --theme-syntax-comment: #7a8478;
+ --theme-syntax-keyword: #d699b6;
+ --theme-syntax-function: #a7c080;
+ --theme-syntax-variable: #e67e80;
+ --theme-syntax-string: #a7c080;
+ --theme-syntax-number: #e69875;
+ --theme-syntax-type: #dbbc7f;
+ --theme-syntax-operator: #83c092;
+ --theme-syntax-punctuation: #d3c6aa;
+}
+
+[data-theme="github"][data-dark="false"] {
+ --theme-primary: #0969da;
+ --theme-secondary: #8250df;
+ --theme-accent: #1b7c83;
+ --theme-error: #cf222e;
+ --theme-warning: #9a6700;
+ --theme-success: #1a7f37;
+ --theme-info: #bc4c00;
+ --theme-text: #24292f;
+ --theme-text-muted: #57606a;
+ --theme-background: #ffffff;
+ --theme-background-panel: #f6f8fa;
+ --theme-background-element: #f0f3f6;
+ --theme-border: #d0d7de;
+ --theme-border-active: #0969da;
+ --theme-border-subtle: #d8dee4;
+ --theme-diff-added: #1a7f37;
+ --theme-diff-removed: #cf222e;
+ --theme-diff-context: #57606a;
+ --theme-diff-hunk-header: #0969da;
+ --theme-diff-highlight-added: #1a7f37;
+ --theme-diff-highlight-removed: #cf222e;
+ --theme-diff-added-bg: #dafbe1;
+ --theme-diff-removed-bg: #ffebe9;
+ --theme-diff-context-bg: #f6f8fa;
+ --theme-diff-line-number: #afb8c1;
+ --theme-diff-added-line-number-bg: #dafbe1;
+ --theme-diff-removed-line-number-bg: #ffebe9;
+ --theme-markdown-text: #24292f;
+ --theme-markdown-heading: #0969da;
+ --theme-markdown-link: #0969da;
+ --theme-markdown-link-text: #1b7c83;
+ --theme-markdown-code: #bf3989;
+ --theme-markdown-block-quote: #57606a;
+ --theme-markdown-emph: #9a6700;
+ --theme-markdown-strong: #bc4c00;
+ --theme-markdown-horizontal-rule: #d0d7de;
+ --theme-markdown-list-item: #0969da;
+ --theme-markdown-list-enumeration: #1b7c83;
+ --theme-markdown-image: #0969da;
+ --theme-markdown-image-text: #1b7c83;
+ --theme-markdown-code-block: #24292f;
+ --theme-syntax-comment: #57606a;
+ --theme-syntax-keyword: #cf222e;
+ --theme-syntax-function: #8250df;
+ --theme-syntax-variable: #bc4c00;
+ --theme-syntax-string: #0969da;
+ --theme-syntax-number: #1b7c83;
+ --theme-syntax-type: #bc4c00;
+ --theme-syntax-operator: #cf222e;
+ --theme-syntax-punctuation: #24292f;
+}
+
+[data-theme="github"][data-dark="true"] {
+ --theme-primary: #58a6ff;
+ --theme-secondary: #bc8cff;
+ --theme-accent: #39c5cf;
+ --theme-error: #f85149;
+ --theme-warning: #e3b341;
+ --theme-success: #3fb950;
+ --theme-info: #d29922;
+ --theme-text: #c9d1d9;
+ --theme-text-muted: #8b949e;
+ --theme-background: #0d1117;
+ --theme-background-panel: #010409;
+ --theme-background-element: #161b22;
+ --theme-border: #30363d;
+ --theme-border-active: #58a6ff;
+ --theme-border-subtle: #21262d;
+ --theme-diff-added: #3fb950;
+ --theme-diff-removed: #f85149;
+ --theme-diff-context: #8b949e;
+ --theme-diff-hunk-header: #58a6ff;
+ --theme-diff-highlight-added: #3fb950;
+ --theme-diff-highlight-removed: #f85149;
+ --theme-diff-added-bg: #033a16;
+ --theme-diff-removed-bg: #67060c;
+ --theme-diff-context-bg: #010409;
+ --theme-diff-line-number: #484f58;
+ --theme-diff-added-line-number-bg: #033a16;
+ --theme-diff-removed-line-number-bg: #67060c;
+ --theme-markdown-text: #c9d1d9;
+ --theme-markdown-heading: #58a6ff;
+ --theme-markdown-link: #58a6ff;
+ --theme-markdown-link-text: #39c5cf;
+ --theme-markdown-code: #ff7b72;
+ --theme-markdown-block-quote: #8b949e;
+ --theme-markdown-emph: #e3b341;
+ --theme-markdown-strong: #d29922;
+ --theme-markdown-horizontal-rule: #30363d;
+ --theme-markdown-list-item: #58a6ff;
+ --theme-markdown-list-enumeration: #39c5cf;
+ --theme-markdown-image: #58a6ff;
+ --theme-markdown-image-text: #39c5cf;
+ --theme-markdown-code-block: #c9d1d9;
+ --theme-syntax-comment: #8b949e;
+ --theme-syntax-keyword: #ff7b72;
+ --theme-syntax-function: #bc8cff;
+ --theme-syntax-variable: #d29922;
+ --theme-syntax-string: #39c5cf;
+ --theme-syntax-number: #58a6ff;
+ --theme-syntax-type: #d29922;
+ --theme-syntax-operator: #ff7b72;
+ --theme-syntax-punctuation: #c9d1d9;
+}
+
+[data-theme="gruvbox"][data-dark="false"] {
+ --theme-primary: #076678;
+ --theme-secondary: #8f3f71;
+ --theme-accent: #427b58;
+ --theme-error: #9d0006;
+ --theme-warning: #af3a03;
+ --theme-success: #79740e;
+ --theme-info: #b57614;
+ --theme-text: #3c3836;
+ --theme-text-muted: #7c6f64;
+ --theme-background: #fbf1c7;
+ --theme-background-panel: #ebdbb2;
+ --theme-background-element: #d5c4a1;
+ --theme-border: #bdae93;
+ --theme-border-active: #3c3836;
+ --theme-border-subtle: #d5c4a1;
+ --theme-diff-added: #79740e;
+ --theme-diff-removed: #9d0006;
+ --theme-diff-context: #7c6f64;
+ --theme-diff-hunk-header: #427b58;
+ --theme-diff-highlight-added: #79740e;
+ --theme-diff-highlight-removed: #9d0006;
+ --theme-diff-added-bg: #e2e0b5;
+ --theme-diff-removed-bg: #e9d8d5;
+ --theme-diff-context-bg: #ebdbb2;
+ --theme-diff-line-number: #bdae93;
+ --theme-diff-added-line-number-bg: #d4d2a9;
+ --theme-diff-removed-line-number-bg: #d8cbc8;
+ --theme-markdown-text: #3c3836;
+ --theme-markdown-heading: #076678;
+ --theme-markdown-link: #427b58;
+ --theme-markdown-link-text: #79740e;
+ --theme-markdown-code: #b57614;
+ --theme-markdown-block-quote: #7c6f64;
+ --theme-markdown-emph: #8f3f71;
+ --theme-markdown-strong: #af3a03;
+ --theme-markdown-horizontal-rule: #7c6f64;
+ --theme-markdown-list-item: #076678;
+ --theme-markdown-list-enumeration: #427b58;
+ --theme-markdown-image: #427b58;
+ --theme-markdown-image-text: #79740e;
+ --theme-markdown-code-block: #3c3836;
+ --theme-syntax-comment: #7c6f64;
+ --theme-syntax-keyword: #9d0006;
+ --theme-syntax-function: #79740e;
+ --theme-syntax-variable: #076678;
+ --theme-syntax-string: #b57614;
+ --theme-syntax-number: #8f3f71;
+ --theme-syntax-type: #427b58;
+ --theme-syntax-operator: #af3a03;
+ --theme-syntax-punctuation: #3c3836;
+}
+
+[data-theme="gruvbox"][data-dark="true"] {
+ --theme-primary: #83a598;
+ --theme-secondary: #d3869b;
+ --theme-accent: #8ec07c;
+ --theme-error: #fb4934;
+ --theme-warning: #fe8019;
+ --theme-success: #b8bb26;
+ --theme-info: #fabd2f;
+ --theme-text: #ebdbb2;
+ --theme-text-muted: #928374;
+ --theme-background: #282828;
+ --theme-background-panel: #3c3836;
+ --theme-background-element: #504945;
+ --theme-border: #665c54;
+ --theme-border-active: #ebdbb2;
+ --theme-border-subtle: #504945;
+ --theme-diff-added: #98971a;
+ --theme-diff-removed: #cc241d;
+ --theme-diff-context: #928374;
+ --theme-diff-hunk-header: #689d6a;
+ --theme-diff-highlight-added: #b8bb26;
+ --theme-diff-highlight-removed: #fb4934;
+ --theme-diff-added-bg: #32302f;
+ --theme-diff-removed-bg: #322929;
+ --theme-diff-context-bg: #3c3836;
+ --theme-diff-line-number: #665c54;
+ --theme-diff-added-line-number-bg: #2a2827;
+ --theme-diff-removed-line-number-bg: #2a2222;
+ --theme-markdown-text: #ebdbb2;
+ --theme-markdown-heading: #83a598;
+ --theme-markdown-link: #8ec07c;
+ --theme-markdown-link-text: #b8bb26;
+ --theme-markdown-code: #fabd2f;
+ --theme-markdown-block-quote: #928374;
+ --theme-markdown-emph: #d3869b;
+ --theme-markdown-strong: #fe8019;
+ --theme-markdown-horizontal-rule: #928374;
+ --theme-markdown-list-item: #83a598;
+ --theme-markdown-list-enumeration: #8ec07c;
+ --theme-markdown-image: #8ec07c;
+ --theme-markdown-image-text: #b8bb26;
+ --theme-markdown-code-block: #ebdbb2;
+ --theme-syntax-comment: #928374;
+ --theme-syntax-keyword: #fb4934;
+ --theme-syntax-function: #b8bb26;
+ --theme-syntax-variable: #83a598;
+ --theme-syntax-string: #fabd2f;
+ --theme-syntax-number: #d3869b;
+ --theme-syntax-type: #8ec07c;
+ --theme-syntax-operator: #fe8019;
+ --theme-syntax-punctuation: #ebdbb2;
+}
+
+[data-theme="kanagawa"][data-dark="false"] {
+ --theme-primary: #2d4f67;
+ --theme-secondary: #957fb8;
+ --theme-accent: #d27e99;
+ --theme-error: #e82424;
+ --theme-warning: #d7a657;
+ --theme-success: #98bb6c;
+ --theme-info: #76946a;
+ --theme-text: #54433a;
+ --theme-text-muted: #9e9389;
+ --theme-background: #f2e9de;
+ --theme-background-panel: #eae4d7;
+ --theme-background-element: #e3dcd2;
+ --theme-border: #d4cbbf;
+ --theme-border-active: #c38d9d;
+ --theme-border-subtle: #dcd4c9;
+ --theme-diff-added: #98bb6c;
+ --theme-diff-removed: #e82424;
+ --theme-diff-context: #9e9389;
+ --theme-diff-hunk-header: #2d4f67;
+ --theme-diff-highlight-added: #89af5b;
+ --theme-diff-highlight-removed: #d61f1f;
+ --theme-diff-added-bg: #eaf3e4;
+ --theme-diff-removed-bg: #fbe6e6;
+ --theme-diff-context-bg: #eae4d7;
+ --theme-diff-line-number: #c7beb4;
+ --theme-diff-added-line-number-bg: #dde8d6;
+ --theme-diff-removed-line-number-bg: #f2dada;
+ --theme-markdown-text: #54433a;
+ --theme-markdown-heading: #957fb8;
+ --theme-markdown-link: #2d4f67;
+ --theme-markdown-link-text: #76946a;
+ --theme-markdown-code: #98bb6c;
+ --theme-markdown-block-quote: #9e9389;
+ --theme-markdown-emph: #c38d9d;
+ --theme-markdown-strong: #d7a657;
+ --theme-markdown-horizontal-rule: #9e9389;
+ --theme-markdown-list-item: #2d4f67;
+ --theme-markdown-list-enumeration: #76946a;
+ --theme-markdown-image: #2d4f67;
+ --theme-markdown-image-text: #76946a;
+ --theme-markdown-code-block: #54433a;
+ --theme-syntax-comment: #9e9389;
+ --theme-syntax-keyword: #957fb8;
+ --theme-syntax-function: #2d4f67;
+ --theme-syntax-variable: #54433a;
+ --theme-syntax-string: #98bb6c;
+ --theme-syntax-number: #d7a657;
+ --theme-syntax-type: #c38d9d;
+ --theme-syntax-operator: #d27e99;
+ --theme-syntax-punctuation: #54433a;
+}
+
+[data-theme="kanagawa"][data-dark="true"] {
+ --theme-primary: #7e9cd8;
+ --theme-secondary: #957fb8;
+ --theme-accent: #d27e99;
+ --theme-error: #e82424;
+ --theme-warning: #d7a657;
+ --theme-success: #98bb6c;
+ --theme-info: #76946a;
+ --theme-text: #dcd7ba;
+ --theme-text-muted: #727169;
+ --theme-background: #1f1f28;
+ --theme-background-panel: #2a2a37;
+ --theme-background-element: #363646;
+ --theme-border: #54546d;
+ --theme-border-active: #c38d9d;
+ --theme-border-subtle: #363646;
+ --theme-diff-added: #98bb6c;
+ --theme-diff-removed: #e82424;
+ --theme-diff-context: #727169;
+ --theme-diff-hunk-header: #2d4f67;
+ --theme-diff-highlight-added: #a9d977;
+ --theme-diff-highlight-removed: #f24a4a;
+ --theme-diff-added-bg: #252e25;
+ --theme-diff-removed-bg: #362020;
+ --theme-diff-context-bg: #2a2a37;
+ --theme-diff-line-number: #54546d;
+ --theme-diff-added-line-number-bg: #202820;
+ --theme-diff-removed-line-number-bg: #2d1c1c;
+ --theme-markdown-text: #dcd7ba;
+ --theme-markdown-heading: #957fb8;
+ --theme-markdown-link: #7e9cd8;
+ --theme-markdown-link-text: #76946a;
+ --theme-markdown-code: #98bb6c;
+ --theme-markdown-block-quote: #727169;
+ --theme-markdown-emph: #c38d9d;
+ --theme-markdown-strong: #d7a657;
+ --theme-markdown-horizontal-rule: #727169;
+ --theme-markdown-list-item: #7e9cd8;
+ --theme-markdown-list-enumeration: #76946a;
+ --theme-markdown-image: #7e9cd8;
+ --theme-markdown-image-text: #76946a;
+ --theme-markdown-code-block: #dcd7ba;
+ --theme-syntax-comment: #727169;
+ --theme-syntax-keyword: #957fb8;
+ --theme-syntax-function: #7e9cd8;
+ --theme-syntax-variable: #dcd7ba;
+ --theme-syntax-string: #98bb6c;
+ --theme-syntax-number: #d7a657;
+ --theme-syntax-type: #c38d9d;
+ --theme-syntax-operator: #d27e99;
+ --theme-syntax-punctuation: #dcd7ba;
+}
+
+[data-theme="material"][data-dark="false"] {
+ --theme-primary: #6182b8;
+ --theme-secondary: #7c4dff;
+ --theme-accent: #39adb5;
+ --theme-error: #e53935;
+ --theme-warning: #ffb300;
+ --theme-success: #91b859;
+ --theme-info: #f4511e;
+ --theme-text: #263238;
+ --theme-text-muted: #90a4ae;
+ --theme-background: #fafafa;
+ --theme-background-panel: #f5f5f5;
+ --theme-background-element: #e7e7e8;
+ --theme-border: #e0e0e0;
+ --theme-border-active: #6182b8;
+ --theme-border-subtle: #eeeeee;
+ --theme-diff-added: #91b859;
+ --theme-diff-removed: #e53935;
+ --theme-diff-context: #90a4ae;
+ --theme-diff-hunk-header: #39adb5;
+ --theme-diff-highlight-added: #91b859;
+ --theme-diff-highlight-removed: #e53935;
+ --theme-diff-added-bg: #e8f5e9;
+ --theme-diff-removed-bg: #ffebee;
+ --theme-diff-context-bg: #f5f5f5;
+ --theme-diff-line-number: #cfd8dc;
+ --theme-diff-added-line-number-bg: #e8f5e9;
+ --theme-diff-removed-line-number-bg: #ffebee;
+ --theme-markdown-text: #263238;
+ --theme-markdown-heading: #6182b8;
+ --theme-markdown-link: #39adb5;
+ --theme-markdown-link-text: #7c4dff;
+ --theme-markdown-code: #91b859;
+ --theme-markdown-block-quote: #90a4ae;
+ --theme-markdown-emph: #ffb300;
+ --theme-markdown-strong: #f4511e;
+ --theme-markdown-horizontal-rule: #e0e0e0;
+ --theme-markdown-list-item: #6182b8;
+ --theme-markdown-list-enumeration: #39adb5;
+ --theme-markdown-image: #39adb5;
+ --theme-markdown-image-text: #7c4dff;
+ --theme-markdown-code-block: #263238;
+ --theme-syntax-comment: #90a4ae;
+ --theme-syntax-keyword: #7c4dff;
+ --theme-syntax-function: #6182b8;
+ --theme-syntax-variable: #263238;
+ --theme-syntax-string: #91b859;
+ --theme-syntax-number: #f4511e;
+ --theme-syntax-type: #ffb300;
+ --theme-syntax-operator: #39adb5;
+ --theme-syntax-punctuation: #263238;
+}
+
+[data-theme="material"][data-dark="true"] {
+ --theme-primary: #82aaff;
+ --theme-secondary: #c792ea;
+ --theme-accent: #89ddff;
+ --theme-error: #f07178;
+ --theme-warning: #ffcb6b;
+ --theme-success: #c3e88d;
+ --theme-info: #ffcb6b;
+ --theme-text: #eeffff;
+ --theme-text-muted: #546e7a;
+ --theme-background: #263238;
+ --theme-background-panel: #1e272c;
+ --theme-background-element: #37474f;
+ --theme-border: #37474f;
+ --theme-border-active: #82aaff;
+ --theme-border-subtle: #1e272c;
+ --theme-diff-added: #c3e88d;
+ --theme-diff-removed: #f07178;
+ --theme-diff-context: #546e7a;
+ --theme-diff-hunk-header: #89ddff;
+ --theme-diff-highlight-added: #c3e88d;
+ --theme-diff-highlight-removed: #f07178;
+ --theme-diff-added-bg: #2e3c2b;
+ --theme-diff-removed-bg: #3c2b2b;
+ --theme-diff-context-bg: #1e272c;
+ --theme-diff-line-number: #37474f;
+ --theme-diff-added-line-number-bg: #2e3c2b;
+ --theme-diff-removed-line-number-bg: #3c2b2b;
+ --theme-markdown-text: #eeffff;
+ --theme-markdown-heading: #82aaff;
+ --theme-markdown-link: #89ddff;
+ --theme-markdown-link-text: #c792ea;
+ --theme-markdown-code: #c3e88d;
+ --theme-markdown-block-quote: #546e7a;
+ --theme-markdown-emph: #ffcb6b;
+ --theme-markdown-strong: #ffcb6b;
+ --theme-markdown-horizontal-rule: #37474f;
+ --theme-markdown-list-item: #82aaff;
+ --theme-markdown-list-enumeration: #89ddff;
+ --theme-markdown-image: #89ddff;
+ --theme-markdown-image-text: #c792ea;
+ --theme-markdown-code-block: #eeffff;
+ --theme-syntax-comment: #546e7a;
+ --theme-syntax-keyword: #c792ea;
+ --theme-syntax-function: #82aaff;
+ --theme-syntax-variable: #eeffff;
+ --theme-syntax-string: #c3e88d;
+ --theme-syntax-number: #ffcb6b;
+ --theme-syntax-type: #ffcb6b;
+ --theme-syntax-operator: #89ddff;
+ --theme-syntax-punctuation: #eeffff;
+}
+
+[data-theme="matrix"][data-dark="false"] {
+ --theme-primary: #1cc24b;
+ --theme-secondary: #24f6d9;
+ --theme-accent: #c770ff;
+ --theme-error: #ff4b4b;
+ --theme-warning: #e6ff57;
+ --theme-success: #1cc24b;
+ --theme-info: #30b3ff;
+ --theme-text: #203022;
+ --theme-text-muted: #748476;
+ --theme-background: #eef3ea;
+ --theme-background-panel: #e4ebe1;
+ --theme-background-element: #dae1d7;
+ --theme-border: #748476;
+ --theme-border-active: #1cc24b;
+ --theme-border-subtle: #dae1d7;
+ --theme-diff-added: #1cc24b;
+ --theme-diff-removed: #ff4b4b;
+ --theme-diff-context: #748476;
+ --theme-diff-hunk-header: #30b3ff;
+ --theme-diff-highlight-added: #5dac7e;
+ --theme-diff-highlight-removed: #d53a3a;
+ --theme-diff-added-bg: #e0efde;
+ --theme-diff-removed-bg: #f9e5e5;
+ --theme-diff-context-bg: #e4ebe1;
+ --theme-diff-line-number: #748476;
+ --theme-diff-added-line-number-bg: #d6e7d2;
+ --theme-diff-removed-line-number-bg: #f2d2d2;
+ --theme-markdown-text: #203022;
+ --theme-markdown-heading: #24f6d9;
+ --theme-markdown-link: #30b3ff;
+ --theme-markdown-link-text: #24f6d9;
+ --theme-markdown-code: #1cc24b;
+ --theme-markdown-block-quote: #748476;
+ --theme-markdown-emph: #ffa83d;
+ --theme-markdown-strong: #e6ff57;
+ --theme-markdown-horizontal-rule: #748476;
+ --theme-markdown-list-item: #30b3ff;
+ --theme-markdown-list-enumeration: #24f6d9;
+ --theme-markdown-image: #30b3ff;
+ --theme-markdown-image-text: #24f6d9;
+ --theme-markdown-code-block: #203022;
+ --theme-syntax-comment: #748476;
+ --theme-syntax-keyword: #c770ff;
+ --theme-syntax-function: #30b3ff;
+ --theme-syntax-variable: #203022;
+ --theme-syntax-string: #1cc24b;
+ --theme-syntax-number: #ffa83d;
+ --theme-syntax-type: #e6ff57;
+ --theme-syntax-operator: #24f6d9;
+ --theme-syntax-punctuation: #203022;
+}
+
+[data-theme="matrix"][data-dark="true"] {
+ --theme-primary: #2eff6a;
+ --theme-secondary: #00efff;
+ --theme-accent: #c770ff;
+ --theme-error: #ff4b4b;
+ --theme-warning: #e6ff57;
+ --theme-success: #62ff94;
+ --theme-info: #30b3ff;
+ --theme-text: #62ff94;
+ --theme-text-muted: #8ca391;
+ --theme-background: #0a0e0a;
+ --theme-background-panel: #0e130d;
+ --theme-background-element: #141c12;
+ --theme-border: #1e2a1b;
+ --theme-border-active: #2eff6a;
+ --theme-border-subtle: #141c12;
+ --theme-diff-added: #1cc24b;
+ --theme-diff-removed: #ff4b4b;
+ --theme-diff-context: #8ca391;
+ --theme-diff-hunk-header: #30b3ff;
+ --theme-diff-highlight-added: #77ffaf;
+ --theme-diff-highlight-removed: #ff7171;
+ --theme-diff-added-bg: #132616;
+ --theme-diff-removed-bg: #261212;
+ --theme-diff-context-bg: #0e130d;
+ --theme-diff-line-number: #1e2a1b;
+ --theme-diff-added-line-number-bg: #0f1b11;
+ --theme-diff-removed-line-number-bg: #1b1414;
+ --theme-markdown-text: #62ff94;
+ --theme-markdown-heading: #00efff;
+ --theme-markdown-link: #30b3ff;
+ --theme-markdown-link-text: #24f6d9;
+ --theme-markdown-code: #1cc24b;
+ --theme-markdown-block-quote: #8ca391;
+ --theme-markdown-emph: #ffa83d;
+ --theme-markdown-strong: #e6ff57;
+ --theme-markdown-horizontal-rule: #8ca391;
+ --theme-markdown-list-item: #30b3ff;
+ --theme-markdown-list-enumeration: #24f6d9;
+ --theme-markdown-image: #30b3ff;
+ --theme-markdown-image-text: #24f6d9;
+ --theme-markdown-code-block: #62ff94;
+ --theme-syntax-comment: #8ca391;
+ --theme-syntax-keyword: #c770ff;
+ --theme-syntax-function: #30b3ff;
+ --theme-syntax-variable: #62ff94;
+ --theme-syntax-string: #1cc24b;
+ --theme-syntax-number: #ffa83d;
+ --theme-syntax-type: #e6ff57;
+ --theme-syntax-operator: #24f6d9;
+ --theme-syntax-punctuation: #62ff94;
+}
+
+[data-theme="monokai"][data-dark="false"] {
+ --theme-primary: #66d9ef;
+ --theme-secondary: #ae81ff;
+ --theme-accent: #a6e22e;
+ --theme-error: #f92672;
+ --theme-warning: #fd971f;
+ --theme-success: #a6e22e;
+ --theme-info: #fd971f;
+ --theme-text: #272822;
+ --theme-text-muted: #75715e;
+ --theme-background: #fafafa;
+ --theme-background-panel: #f0f0f0;
+ --theme-background-element: #e0e0e0;
+ --theme-border: #d0d0d0;
+ --theme-border-active: #66d9ef;
+ --theme-border-subtle: #e8e8e8;
+ --theme-diff-added: #a6e22e;
+ --theme-diff-removed: #f92672;
+ --theme-diff-context: #75715e;
+ --theme-diff-hunk-header: #75715e;
+ --theme-diff-highlight-added: #a6e22e;
+ --theme-diff-highlight-removed: #f92672;
+ --theme-diff-added-bg: #e0ffe0;
+ --theme-diff-removed-bg: #ffe0e0;
+ --theme-diff-context-bg: #f0f0f0;
+ --theme-diff-line-number: #d0d0d0;
+ --theme-diff-added-line-number-bg: #e0ffe0;
+ --theme-diff-removed-line-number-bg: #ffe0e0;
+ --theme-markdown-text: #272822;
+ --theme-markdown-heading: #f92672;
+ --theme-markdown-link: #66d9ef;
+ --theme-markdown-link-text: #ae81ff;
+ --theme-markdown-code: #a6e22e;
+ --theme-markdown-block-quote: #75715e;
+ --theme-markdown-emph: #fd971f;
+ --theme-markdown-strong: #fd971f;
+ --theme-markdown-horizontal-rule: #75715e;
+ --theme-markdown-list-item: #66d9ef;
+ --theme-markdown-list-enumeration: #ae81ff;
+ --theme-markdown-image: #66d9ef;
+ --theme-markdown-image-text: #ae81ff;
+ --theme-markdown-code-block: #272822;
+ --theme-syntax-comment: #75715e;
+ --theme-syntax-keyword: #f92672;
+ --theme-syntax-function: #a6e22e;
+ --theme-syntax-variable: #272822;
+ --theme-syntax-string: #fd971f;
+ --theme-syntax-number: #ae81ff;
+ --theme-syntax-type: #66d9ef;
+ --theme-syntax-operator: #f92672;
+ --theme-syntax-punctuation: #272822;
+}
+
+[data-theme="monokai"][data-dark="true"] {
+ --theme-primary: #66d9ef;
+ --theme-secondary: #ae81ff;
+ --theme-accent: #a6e22e;
+ --theme-error: #f92672;
+ --theme-warning: #e6db74;
+ --theme-success: #a6e22e;
+ --theme-info: #fd971f;
+ --theme-text: #f8f8f2;
+ --theme-text-muted: #75715e;
+ --theme-background: #272822;
+ --theme-background-panel: #1e1f1c;
+ --theme-background-element: #3e3d32;
+ --theme-border: #3e3d32;
+ --theme-border-active: #66d9ef;
+ --theme-border-subtle: #1e1f1c;
+ --theme-diff-added: #a6e22e;
+ --theme-diff-removed: #f92672;
+ --theme-diff-context: #75715e;
+ --theme-diff-hunk-header: #75715e;
+ --theme-diff-highlight-added: #a6e22e;
+ --theme-diff-highlight-removed: #f92672;
+ --theme-diff-added-bg: #1a3a1a;
+ --theme-diff-removed-bg: #3a1a1a;
+ --theme-diff-context-bg: #1e1f1c;
+ --theme-diff-line-number: #3e3d32;
+ --theme-diff-added-line-number-bg: #1a3a1a;
+ --theme-diff-removed-line-number-bg: #3a1a1a;
+ --theme-markdown-text: #f8f8f2;
+ --theme-markdown-heading: #f92672;
+ --theme-markdown-link: #66d9ef;
+ --theme-markdown-link-text: #ae81ff;
+ --theme-markdown-code: #a6e22e;
+ --theme-markdown-block-quote: #75715e;
+ --theme-markdown-emph: #e6db74;
+ --theme-markdown-strong: #fd971f;
+ --theme-markdown-horizontal-rule: #75715e;
+ --theme-markdown-list-item: #66d9ef;
+ --theme-markdown-list-enumeration: #ae81ff;
+ --theme-markdown-image: #66d9ef;
+ --theme-markdown-image-text: #ae81ff;
+ --theme-markdown-code-block: #f8f8f2;
+ --theme-syntax-comment: #75715e;
+ --theme-syntax-keyword: #f92672;
+ --theme-syntax-function: #a6e22e;
+ --theme-syntax-variable: #f8f8f2;
+ --theme-syntax-string: #e6db74;
+ --theme-syntax-number: #ae81ff;
+ --theme-syntax-type: #66d9ef;
+ --theme-syntax-operator: #f92672;
+ --theme-syntax-punctuation: #f8f8f2;
+}
+
+[data-theme="nord"][data-dark="false"] {
+ --theme-primary: #5e81ac;
+ --theme-secondary: #81a1c1;
+ --theme-accent: #8fbcbb;
+ --theme-error: #bf616a;
+ --theme-warning: #d08770;
+ --theme-success: #a3be8c;
+ --theme-info: #5e81ac;
+ --theme-text: #2e3440;
+ --theme-text-muted: #3b4252;
+ --theme-background: #eceff4;
+ --theme-background-panel: #e5e9f0;
+ --theme-background-element: #d8dee9;
+ --theme-border: #4c566a;
+ --theme-border-active: #434c5e;
+ --theme-border-subtle: #4c566a;
+ --theme-diff-added: #a3be8c;
+ --theme-diff-removed: #bf616a;
+ --theme-diff-context: #4c566a;
+ --theme-diff-hunk-header: #4c566a;
+ --theme-diff-highlight-added: #a3be8c;
+ --theme-diff-highlight-removed: #bf616a;
+ --theme-diff-added-bg: #e5e9f0;
+ --theme-diff-removed-bg: #e5e9f0;
+ --theme-diff-context-bg: #e5e9f0;
+ --theme-diff-line-number: #d8dee9;
+ --theme-diff-added-line-number-bg: #e5e9f0;
+ --theme-diff-removed-line-number-bg: #e5e9f0;
+ --theme-markdown-text: #2e3440;
+ --theme-markdown-heading: #5e81ac;
+ --theme-markdown-link: #81a1c1;
+ --theme-markdown-link-text: #8fbcbb;
+ --theme-markdown-code: #a3be8c;
+ --theme-markdown-block-quote: #4c566a;
+ --theme-markdown-emph: #d08770;
+ --theme-markdown-strong: #ebcb8b;
+ --theme-markdown-horizontal-rule: #4c566a;
+ --theme-markdown-list-item: #5e81ac;
+ --theme-markdown-list-enumeration: #8fbcbb;
+ --theme-markdown-image: #81a1c1;
+ --theme-markdown-image-text: #8fbcbb;
+ --theme-markdown-code-block: #2e3440;
+ --theme-syntax-comment: #4c566a;
+ --theme-syntax-keyword: #81a1c1;
+ --theme-syntax-function: #88c0d0;
+ --theme-syntax-variable: #8fbcbb;
+ --theme-syntax-string: #a3be8c;
+ --theme-syntax-number: #b48ead;
+ --theme-syntax-type: #8fbcbb;
+ --theme-syntax-operator: #81a1c1;
+ --theme-syntax-punctuation: #2e3440;
+}
+
+[data-theme="nord"][data-dark="true"] {
+ --theme-primary: #88c0d0;
+ --theme-secondary: #81a1c1;
+ --theme-accent: #8fbcbb;
+ --theme-error: #bf616a;
+ --theme-warning: #d08770;
+ --theme-success: #a3be8c;
+ --theme-info: #88c0d0;
+ --theme-text: #eceff4;
+ --theme-text-muted: #8b95a7;
+ --theme-background: #2e3440;
+ --theme-background-panel: #3b4252;
+ --theme-background-element: #434c5e;
+ --theme-border: #434c5e;
+ --theme-border-active: #4c566a;
+ --theme-border-subtle: #434c5e;
+ --theme-diff-added: #a3be8c;
+ --theme-diff-removed: #bf616a;
+ --theme-diff-context: #8b95a7;
+ --theme-diff-hunk-header: #8b95a7;
+ --theme-diff-highlight-added: #a3be8c;
+ --theme-diff-highlight-removed: #bf616a;
+ --theme-diff-added-bg: #3b4252;
+ --theme-diff-removed-bg: #3b4252;
+ --theme-diff-context-bg: #3b4252;
+ --theme-diff-line-number: #434c5e;
+ --theme-diff-added-line-number-bg: #3b4252;
+ --theme-diff-removed-line-number-bg: #3b4252;
+ --theme-markdown-text: #d8dee9;
+ --theme-markdown-heading: #88c0d0;
+ --theme-markdown-link: #81a1c1;
+ --theme-markdown-link-text: #8fbcbb;
+ --theme-markdown-code: #a3be8c;
+ --theme-markdown-block-quote: #8b95a7;
+ --theme-markdown-emph: #d08770;
+ --theme-markdown-strong: #ebcb8b;
+ --theme-markdown-horizontal-rule: #8b95a7;
+ --theme-markdown-list-item: #88c0d0;
+ --theme-markdown-list-enumeration: #8fbcbb;
+ --theme-markdown-image: #81a1c1;
+ --theme-markdown-image-text: #8fbcbb;
+ --theme-markdown-code-block: #d8dee9;
+ --theme-syntax-comment: #8b95a7;
+ --theme-syntax-keyword: #81a1c1;
+ --theme-syntax-function: #88c0d0;
+ --theme-syntax-variable: #8fbcbb;
+ --theme-syntax-string: #a3be8c;
+ --theme-syntax-number: #b48ead;
+ --theme-syntax-type: #8fbcbb;
+ --theme-syntax-operator: #81a1c1;
+ --theme-syntax-punctuation: #d8dee9;
+}
+
+[data-theme="one-dark"][data-dark="false"] {
+ --theme-primary: #4078f2;
+ --theme-secondary: #a626a4;
+ --theme-accent: #0184bc;
+ --theme-error: #e45649;
+ --theme-warning: #c18401;
+ --theme-success: #50a14f;
+ --theme-info: #986801;
+ --theme-text: #383a42;
+ --theme-text-muted: #a0a1a7;
+ --theme-background: #fafafa;
+ --theme-background-panel: #f0f0f1;
+ --theme-background-element: #eaeaeb;
+ --theme-border: #d1d1d2;
+ --theme-border-active: #4078f2;
+ --theme-border-subtle: #e0e0e1;
+ --theme-diff-added: #50a14f;
+ --theme-diff-removed: #e45649;
+ --theme-diff-context: #a0a1a7;
+ --theme-diff-hunk-header: #0184bc;
+ --theme-diff-highlight-added: #489447;
+ --theme-diff-highlight-removed: #d65145;
+ --theme-diff-added-bg: #eafbe9;
+ --theme-diff-removed-bg: #fce9e8;
+ --theme-diff-context-bg: #f0f0f1;
+ --theme-diff-line-number: #c9c9ca;
+ --theme-diff-added-line-number-bg: #e1f3df;
+ --theme-diff-removed-line-number-bg: #f5e2e1;
+ --theme-markdown-text: #383a42;
+ --theme-markdown-heading: #a626a4;
+ --theme-markdown-link: #4078f2;
+ --theme-markdown-link-text: #0184bc;
+ --theme-markdown-code: #50a14f;
+ --theme-markdown-block-quote: #a0a1a7;
+ --theme-markdown-emph: #c18401;
+ --theme-markdown-strong: #986801;
+ --theme-markdown-horizontal-rule: #a0a1a7;
+ --theme-markdown-list-item: #4078f2;
+ --theme-markdown-list-enumeration: #0184bc;
+ --theme-markdown-image: #4078f2;
+ --theme-markdown-image-text: #0184bc;
+ --theme-markdown-code-block: #383a42;
+ --theme-syntax-comment: #a0a1a7;
+ --theme-syntax-keyword: #a626a4;
+ --theme-syntax-function: #4078f2;
+ --theme-syntax-variable: #e45649;
+ --theme-syntax-string: #50a14f;
+ --theme-syntax-number: #986801;
+ --theme-syntax-type: #c18401;
+ --theme-syntax-operator: #0184bc;
+ --theme-syntax-punctuation: #383a42;
+}
+
+[data-theme="one-dark"][data-dark="true"] {
+ --theme-primary: #61afef;
+ --theme-secondary: #c678dd;
+ --theme-accent: #56b6c2;
+ --theme-error: #e06c75;
+ --theme-warning: #e5c07b;
+ --theme-success: #98c379;
+ --theme-info: #d19a66;
+ --theme-text: #abb2bf;
+ --theme-text-muted: #5c6370;
+ --theme-background: #282c34;
+ --theme-background-panel: #21252b;
+ --theme-background-element: #353b45;
+ --theme-border: #393f4a;
+ --theme-border-active: #61afef;
+ --theme-border-subtle: #2c313a;
+ --theme-diff-added: #98c379;
+ --theme-diff-removed: #e06c75;
+ --theme-diff-context: #5c6370;
+ --theme-diff-hunk-header: #56b6c2;
+ --theme-diff-highlight-added: #aad482;
+ --theme-diff-highlight-removed: #e8828b;
+ --theme-diff-added-bg: #2c382b;
+ --theme-diff-removed-bg: #3a2d2f;
+ --theme-diff-context-bg: #21252b;
+ --theme-diff-line-number: #495162;
+ --theme-diff-added-line-number-bg: #283427;
+ --theme-diff-removed-line-number-bg: #36292b;
+ --theme-markdown-text: #abb2bf;
+ --theme-markdown-heading: #c678dd;
+ --theme-markdown-link: #61afef;
+ --theme-markdown-link-text: #56b6c2;
+ --theme-markdown-code: #98c379;
+ --theme-markdown-block-quote: #5c6370;
+ --theme-markdown-emph: #e5c07b;
+ --theme-markdown-strong: #d19a66;
+ --theme-markdown-horizontal-rule: #5c6370;
+ --theme-markdown-list-item: #61afef;
+ --theme-markdown-list-enumeration: #56b6c2;
+ --theme-markdown-image: #61afef;
+ --theme-markdown-image-text: #56b6c2;
+ --theme-markdown-code-block: #abb2bf;
+ --theme-syntax-comment: #5c6370;
+ --theme-syntax-keyword: #c678dd;
+ --theme-syntax-function: #61afef;
+ --theme-syntax-variable: #e06c75;
+ --theme-syntax-string: #98c379;
+ --theme-syntax-number: #d19a66;
+ --theme-syntax-type: #e5c07b;
+ --theme-syntax-operator: #56b6c2;
+ --theme-syntax-punctuation: #abb2bf;
+}
+
+[data-theme="opencode"][data-dark="false"] {
+ --theme-primary: #3b7dd8;
+ --theme-secondary: #7b5bb6;
+ --theme-accent: #d68c27;
+ --theme-error: #d1383d;
+ --theme-warning: #d68c27;
+ --theme-success: #3d9a57;
+ --theme-info: #318795;
+ --theme-text: #1a1a1a;
+ --theme-text-muted: #8a8a8a;
+ --theme-background: #ffffff;
+ --theme-background-panel: #fafafa;
+ --theme-background-element: #f5f5f5;
+ --theme-border: #b8b8b8;
+ --theme-border-active: #a0a0a0;
+ --theme-border-subtle: #d4d4d4;
+ --theme-diff-added: #1e725c;
+ --theme-diff-removed: #c53b53;
+ --theme-diff-context: #7086b5;
+ --theme-diff-hunk-header: #7086b5;
+ --theme-diff-highlight-added: #4db380;
+ --theme-diff-highlight-removed: #f52a65;
+ --theme-diff-added-bg: #d5e5d5;
+ --theme-diff-removed-bg: #f7d8db;
+ --theme-diff-context-bg: #fafafa;
+ --theme-diff-line-number: #f5f5f5;
+ --theme-diff-added-line-number-bg: #c5d5c5;
+ --theme-diff-removed-line-number-bg: #e7c8cb;
+ --theme-markdown-text: #1a1a1a;
+ --theme-markdown-heading: #d68c27;
+ --theme-markdown-link: #3b7dd8;
+ --theme-markdown-link-text: #318795;
+ --theme-markdown-code: #3d9a57;
+ --theme-markdown-block-quote: #b0851f;
+ --theme-markdown-emph: #b0851f;
+ --theme-markdown-strong: #d68c27;
+ --theme-markdown-horizontal-rule: #8a8a8a;
+ --theme-markdown-list-item: #3b7dd8;
+ --theme-markdown-list-enumeration: #318795;
+ --theme-markdown-image: #3b7dd8;
+ --theme-markdown-image-text: #318795;
+ --theme-markdown-code-block: #1a1a1a;
+ --theme-syntax-comment: #8a8a8a;
+ --theme-syntax-keyword: #d68c27;
+ --theme-syntax-function: #3b7dd8;
+ --theme-syntax-variable: #d1383d;
+ --theme-syntax-string: #3d9a57;
+ --theme-syntax-number: #d68c27;
+ --theme-syntax-type: #b0851f;
+ --theme-syntax-operator: #318795;
+ --theme-syntax-punctuation: #1a1a1a;
+}
+
+[data-theme="opencode"][data-dark="true"] {
+ --theme-primary: #fab283;
+ --theme-secondary: #5c9cf5;
+ --theme-accent: #9d7cd8;
+ --theme-error: #e06c75;
+ --theme-warning: #f5a742;
+ --theme-success: #7fd88f;
+ --theme-info: #56b6c2;
+ --theme-text: #eeeeee;
+ --theme-text-muted: #808080;
+ --theme-background: #0a0a0a;
+ --theme-background-panel: #141414;
+ --theme-background-element: #1e1e1e;
+ --theme-border: #484848;
+ --theme-border-active: #606060;
+ --theme-border-subtle: #3c3c3c;
+ --theme-diff-added: #4fd6be;
+ --theme-diff-removed: #c53b53;
+ --theme-diff-context: #828bb8;
+ --theme-diff-hunk-header: #828bb8;
+ --theme-diff-highlight-added: #b8db87;
+ --theme-diff-highlight-removed: #e26a75;
+ --theme-diff-added-bg: #20303b;
+ --theme-diff-removed-bg: #37222c;
+ --theme-diff-context-bg: #141414;
+ --theme-diff-line-number: #1e1e1e;
+ --theme-diff-added-line-number-bg: #1b2b34;
+ --theme-diff-removed-line-number-bg: #2d1f26;
+ --theme-markdown-text: #eeeeee;
+ --theme-markdown-heading: #9d7cd8;
+ --theme-markdown-link: #fab283;
+ --theme-markdown-link-text: #56b6c2;
+ --theme-markdown-code: #7fd88f;
+ --theme-markdown-block-quote: #e5c07b;
+ --theme-markdown-emph: #e5c07b;
+ --theme-markdown-strong: #f5a742;
+ --theme-markdown-horizontal-rule: #808080;
+ --theme-markdown-list-item: #fab283;
+ --theme-markdown-list-enumeration: #56b6c2;
+ --theme-markdown-image: #fab283;
+ --theme-markdown-image-text: #56b6c2;
+ --theme-markdown-code-block: #eeeeee;
+ --theme-syntax-comment: #808080;
+ --theme-syntax-keyword: #9d7cd8;
+ --theme-syntax-function: #fab283;
+ --theme-syntax-variable: #e06c75;
+ --theme-syntax-string: #7fd88f;
+ --theme-syntax-number: #f5a742;
+ --theme-syntax-type: #e5c07b;
+ --theme-syntax-operator: #56b6c2;
+ --theme-syntax-punctuation: #eeeeee;
+}
+
+[data-theme="palenight"][data-dark="false"] {
+ --theme-primary: #4976eb;
+ --theme-secondary: #a854f2;
+ --theme-accent: #00acc1;
+ --theme-error: #e53935;
+ --theme-warning: #ffb300;
+ --theme-success: #91b859;
+ --theme-info: #f4511e;
+ --theme-text: #292d3e;
+ --theme-text-muted: #8796b0;
+ --theme-background: #fafafa;
+ --theme-background-panel: #f5f5f5;
+ --theme-background-element: #e7e7e8;
+ --theme-border: #e0e0e0;
+ --theme-border-active: #4976eb;
+ --theme-border-subtle: #eeeeee;
+ --theme-diff-added: #91b859;
+ --theme-diff-removed: #e53935;
+ --theme-diff-context: #8796b0;
+ --theme-diff-hunk-header: #00acc1;
+ --theme-diff-highlight-added: #91b859;
+ --theme-diff-highlight-removed: #e53935;
+ --theme-diff-added-bg: #e8f5e9;
+ --theme-diff-removed-bg: #ffebee;
+ --theme-diff-context-bg: #f5f5f5;
+ --theme-diff-line-number: #cfd8dc;
+ --theme-diff-added-line-number-bg: #e8f5e9;
+ --theme-diff-removed-line-number-bg: #ffebee;
+ --theme-markdown-text: #292d3e;
+ --theme-markdown-heading: #a854f2;
+ --theme-markdown-link: #4976eb;
+ --theme-markdown-link-text: #00acc1;
+ --theme-markdown-code: #91b859;
+ --theme-markdown-block-quote: #8796b0;
+ --theme-markdown-emph: #ffb300;
+ --theme-markdown-strong: #f4511e;
+ --theme-markdown-horizontal-rule: #8796b0;
+ --theme-markdown-list-item: #4976eb;
+ --theme-markdown-list-enumeration: #00acc1;
+ --theme-markdown-image: #4976eb;
+ --theme-markdown-image-text: #00acc1;
+ --theme-markdown-code-block: #292d3e;
+ --theme-syntax-comment: #8796b0;
+ --theme-syntax-keyword: #a854f2;
+ --theme-syntax-function: #4976eb;
+ --theme-syntax-variable: #292d3e;
+ --theme-syntax-string: #91b859;
+ --theme-syntax-number: #f4511e;
+ --theme-syntax-type: #ffb300;
+ --theme-syntax-operator: #00acc1;
+ --theme-syntax-punctuation: #292d3e;
+}
+
+[data-theme="palenight"][data-dark="true"] {
+ --theme-primary: #82aaff;
+ --theme-secondary: #c792ea;
+ --theme-accent: #89ddff;
+ --theme-error: #f07178;
+ --theme-warning: #ffcb6b;
+ --theme-success: #c3e88d;
+ --theme-info: #f78c6c;
+ --theme-text: #a6accd;
+ --theme-text-muted: #676e95;
+ --theme-background: #292d3e;
+ --theme-background-panel: #1e2132;
+ --theme-background-element: #32364a;
+ --theme-border: #32364a;
+ --theme-border-active: #82aaff;
+ --theme-border-subtle: #1e2132;
+ --theme-diff-added: #c3e88d;
+ --theme-diff-removed: #f07178;
+ --theme-diff-context: #676e95;
+ --theme-diff-hunk-header: #89ddff;
+ --theme-diff-highlight-added: #c3e88d;
+ --theme-diff-highlight-removed: #f07178;
+ --theme-diff-added-bg: #2e3c2b;
+ --theme-diff-removed-bg: #3c2b2b;
+ --theme-diff-context-bg: #1e2132;
+ --theme-diff-line-number: #444760;
+ --theme-diff-added-line-number-bg: #2e3c2b;
+ --theme-diff-removed-line-number-bg: #3c2b2b;
+ --theme-markdown-text: #a6accd;
+ --theme-markdown-heading: #c792ea;
+ --theme-markdown-link: #82aaff;
+ --theme-markdown-link-text: #89ddff;
+ --theme-markdown-code: #c3e88d;
+ --theme-markdown-block-quote: #676e95;
+ --theme-markdown-emph: #ffcb6b;
+ --theme-markdown-strong: #f78c6c;
+ --theme-markdown-horizontal-rule: #676e95;
+ --theme-markdown-list-item: #82aaff;
+ --theme-markdown-list-enumeration: #89ddff;
+ --theme-markdown-image: #82aaff;
+ --theme-markdown-image-text: #89ddff;
+ --theme-markdown-code-block: #a6accd;
+ --theme-syntax-comment: #676e95;
+ --theme-syntax-keyword: #c792ea;
+ --theme-syntax-function: #82aaff;
+ --theme-syntax-variable: #a6accd;
+ --theme-syntax-string: #c3e88d;
+ --theme-syntax-number: #f78c6c;
+ --theme-syntax-type: #ffcb6b;
+ --theme-syntax-operator: #89ddff;
+ --theme-syntax-punctuation: #a6accd;
+}
+
+[data-theme="rosepine"][data-dark="false"] {
+ --theme-primary: #31748f;
+ --theme-secondary: #907aa9;
+ --theme-accent: #d7827e;
+ --theme-error: #b4637a;
+ --theme-warning: #ea9d34;
+ --theme-success: #286983;
+ --theme-info: #56949f;
+ --theme-text: #575279;
+ --theme-text-muted: #9893a5;
+ --theme-background: #faf4ed;
+ --theme-background-panel: #fffaf3;
+ --theme-background-element: #f2e9e1;
+ --theme-border: #dfdad9;
+ --theme-border-active: #31748f;
+ --theme-border-subtle: #f4ede8;
+ --theme-diff-added: #286983;
+ --theme-diff-removed: #b4637a;
+ --theme-diff-context: #9893a5;
+ --theme-diff-hunk-header: #907aa9;
+ --theme-diff-highlight-added: #286983;
+ --theme-diff-highlight-removed: #b4637a;
+ --theme-diff-added-bg: #e5f2f3;
+ --theme-diff-removed-bg: #fce5e8;
+ --theme-diff-context-bg: #fffaf3;
+ --theme-diff-line-number: #9893a5;
+ --theme-diff-added-line-number-bg: #e5f2f3;
+ --theme-diff-removed-line-number-bg: #fce5e8;
+ --theme-markdown-text: #575279;
+ --theme-markdown-heading: #907aa9;
+ --theme-markdown-link: #31748f;
+ --theme-markdown-link-text: #d7827e;
+ --theme-markdown-code: #286983;
+ --theme-markdown-block-quote: #9893a5;
+ --theme-markdown-emph: #ea9d34;
+ --theme-markdown-strong: #b4637a;
+ --theme-markdown-horizontal-rule: #dfdad9;
+ --theme-markdown-list-item: #31748f;
+ --theme-markdown-list-enumeration: #d7827e;
+ --theme-markdown-image: #31748f;
+ --theme-markdown-image-text: #d7827e;
+ --theme-markdown-code-block: #575279;
+ --theme-syntax-comment: #9893a5;
+ --theme-syntax-keyword: #286983;
+ --theme-syntax-function: #d7827e;
+ --theme-syntax-variable: #575279;
+ --theme-syntax-string: #ea9d34;
+ --theme-syntax-number: #907aa9;
+ --theme-syntax-type: #56949f;
+ --theme-syntax-operator: #797593;
+ --theme-syntax-punctuation: #797593;
+}
+
+[data-theme="rosepine"][data-dark="true"] {
+ --theme-primary: #9ccfd8;
+ --theme-secondary: #c4a7e7;
+ --theme-accent: #ebbcba;
+ --theme-error: #eb6f92;
+ --theme-warning: #f6c177;
+ --theme-success: #31748f;
+ --theme-info: #9ccfd8;
+ --theme-text: #e0def4;
+ --theme-text-muted: #6e6a86;
+ --theme-background: #191724;
+ --theme-background-panel: #1f1d2e;
+ --theme-background-element: #26233a;
+ --theme-border: #403d52;
+ --theme-border-active: #9ccfd8;
+ --theme-border-subtle: #21202e;
+ --theme-diff-added: #31748f;
+ --theme-diff-removed: #eb6f92;
+ --theme-diff-context: #6e6a86;
+ --theme-diff-hunk-header: #c4a7e7;
+ --theme-diff-highlight-added: #31748f;
+ --theme-diff-highlight-removed: #eb6f92;
+ --theme-diff-added-bg: #1f2d3a;
+ --theme-diff-removed-bg: #3a1f2d;
+ --theme-diff-context-bg: #1f1d2e;
+ --theme-diff-line-number: #6e6a86;
+ --theme-diff-added-line-number-bg: #1f2d3a;
+ --theme-diff-removed-line-number-bg: #3a1f2d;
+ --theme-markdown-text: #e0def4;
+ --theme-markdown-heading: #c4a7e7;
+ --theme-markdown-link: #9ccfd8;
+ --theme-markdown-link-text: #ebbcba;
+ --theme-markdown-code: #31748f;
+ --theme-markdown-block-quote: #6e6a86;
+ --theme-markdown-emph: #f6c177;
+ --theme-markdown-strong: #eb6f92;
+ --theme-markdown-horizontal-rule: #403d52;
+ --theme-markdown-list-item: #9ccfd8;
+ --theme-markdown-list-enumeration: #ebbcba;
+ --theme-markdown-image: #9ccfd8;
+ --theme-markdown-image-text: #ebbcba;
+ --theme-markdown-code-block: #e0def4;
+ --theme-syntax-comment: #6e6a86;
+ --theme-syntax-keyword: #31748f;
+ --theme-syntax-function: #ebbcba;
+ --theme-syntax-variable: #e0def4;
+ --theme-syntax-string: #f6c177;
+ --theme-syntax-number: #c4a7e7;
+ --theme-syntax-type: #9ccfd8;
+ --theme-syntax-operator: #908caa;
+ --theme-syntax-punctuation: #908caa;
+}
+
+[data-theme="solarized"][data-dark="false"] {
+ --theme-primary: #268bd2;
+ --theme-secondary: #6c71c4;
+ --theme-accent: #2aa198;
+ --theme-error: #dc322f;
+ --theme-warning: #b58900;
+ --theme-success: #859900;
+ --theme-info: #cb4b16;
+ --theme-text: #657b83;
+ --theme-text-muted: #93a1a1;
+ --theme-background: #fdf6e3;
+ --theme-background-panel: #eee8d5;
+ --theme-background-element: #eee8d5;
+ --theme-border: #eee8d5;
+ --theme-border-active: #93a1a1;
+ --theme-border-subtle: #eee8d5;
+ --theme-diff-added: #859900;
+ --theme-diff-removed: #dc322f;
+ --theme-diff-context: #93a1a1;
+ --theme-diff-hunk-header: #93a1a1;
+ --theme-diff-highlight-added: #859900;
+ --theme-diff-highlight-removed: #dc322f;
+ --theme-diff-added-bg: #eee8d5;
+ --theme-diff-removed-bg: #eee8d5;
+ --theme-diff-context-bg: #eee8d5;
+ --theme-diff-line-number: #93a1a1;
+ --theme-diff-added-line-number-bg: #eee8d5;
+ --theme-diff-removed-line-number-bg: #eee8d5;
+ --theme-markdown-text: #657b83;
+ --theme-markdown-heading: #268bd2;
+ --theme-markdown-link: #2aa198;
+ --theme-markdown-link-text: #6c71c4;
+ --theme-markdown-code: #859900;
+ --theme-markdown-block-quote: #93a1a1;
+ --theme-markdown-emph: #b58900;
+ --theme-markdown-strong: #cb4b16;
+ --theme-markdown-horizontal-rule: #93a1a1;
+ --theme-markdown-list-item: #268bd2;
+ --theme-markdown-list-enumeration: #2aa198;
+ --theme-markdown-image: #2aa198;
+ --theme-markdown-image-text: #6c71c4;
+ --theme-markdown-code-block: #657b83;
+ --theme-syntax-comment: #93a1a1;
+ --theme-syntax-keyword: #859900;
+ --theme-syntax-function: #268bd2;
+ --theme-syntax-variable: #2aa198;
+ --theme-syntax-string: #2aa198;
+ --theme-syntax-number: #d33682;
+ --theme-syntax-type: #b58900;
+ --theme-syntax-operator: #859900;
+ --theme-syntax-punctuation: #657b83;
+}
+
+[data-theme="solarized"][data-dark="true"] {
+ --theme-primary: #268bd2;
+ --theme-secondary: #6c71c4;
+ --theme-accent: #2aa198;
+ --theme-error: #dc322f;
+ --theme-warning: #b58900;
+ --theme-success: #859900;
+ --theme-info: #cb4b16;
+ --theme-text: #839496;
+ --theme-text-muted: #586e75;
+ --theme-background: #002b36;
+ --theme-background-panel: #073642;
+ --theme-background-element: #073642;
+ --theme-border: #073642;
+ --theme-border-active: #586e75;
+ --theme-border-subtle: #073642;
+ --theme-diff-added: #859900;
+ --theme-diff-removed: #dc322f;
+ --theme-diff-context: #586e75;
+ --theme-diff-hunk-header: #586e75;
+ --theme-diff-highlight-added: #859900;
+ --theme-diff-highlight-removed: #dc322f;
+ --theme-diff-added-bg: #073642;
+ --theme-diff-removed-bg: #073642;
+ --theme-diff-context-bg: #073642;
+ --theme-diff-line-number: #586e75;
+ --theme-diff-added-line-number-bg: #073642;
+ --theme-diff-removed-line-number-bg: #073642;
+ --theme-markdown-text: #839496;
+ --theme-markdown-heading: #268bd2;
+ --theme-markdown-link: #2aa198;
+ --theme-markdown-link-text: #6c71c4;
+ --theme-markdown-code: #859900;
+ --theme-markdown-block-quote: #586e75;
+ --theme-markdown-emph: #b58900;
+ --theme-markdown-strong: #cb4b16;
+ --theme-markdown-horizontal-rule: #586e75;
+ --theme-markdown-list-item: #268bd2;
+ --theme-markdown-list-enumeration: #2aa198;
+ --theme-markdown-image: #2aa198;
+ --theme-markdown-image-text: #6c71c4;
+ --theme-markdown-code-block: #839496;
+ --theme-syntax-comment: #586e75;
+ --theme-syntax-keyword: #859900;
+ --theme-syntax-function: #268bd2;
+ --theme-syntax-variable: #2aa198;
+ --theme-syntax-string: #2aa198;
+ --theme-syntax-number: #d33682;
+ --theme-syntax-type: #b58900;
+ --theme-syntax-operator: #859900;
+ --theme-syntax-punctuation: #839496;
+}
+
+[data-theme="synthwave84"][data-dark="false"] {
+ --theme-primary: #00bcd4;
+ --theme-secondary: #e91e63;
+ --theme-accent: #9c27b0;
+ --theme-error: #f44336;
+ --theme-warning: #ff9800;
+ --theme-success: #4caf50;
+ --theme-info: #ff5722;
+ --theme-text: #262335;
+ --theme-text-muted: #5c5c8a;
+ --theme-background: #fafafa;
+ --theme-background-panel: #f5f5f5;
+ --theme-background-element: #eeeeee;
+ --theme-border: #e0e0e0;
+ --theme-border-active: #00bcd4;
+ --theme-border-subtle: #f0f0f0;
+ --theme-diff-added: #4caf50;
+ --theme-diff-removed: #f44336;
+ --theme-diff-context: #5c5c8a;
+ --theme-diff-hunk-header: #9c27b0;
+ --theme-diff-highlight-added: #4caf50;
+ --theme-diff-highlight-removed: #f44336;
+ --theme-diff-added-bg: #e8f5e9;
+ --theme-diff-removed-bg: #ffebee;
+ --theme-diff-context-bg: #f5f5f5;
+ --theme-diff-line-number: #b0b0b0;
+ --theme-diff-added-line-number-bg: #e8f5e9;
+ --theme-diff-removed-line-number-bg: #ffebee;
+ --theme-markdown-text: #262335;
+ --theme-markdown-heading: #e91e63;
+ --theme-markdown-link: #00bcd4;
+ --theme-markdown-link-text: #9c27b0;
+ --theme-markdown-code: #4caf50;
+ --theme-markdown-block-quote: #5c5c8a;
+ --theme-markdown-emph: #ff9800;
+ --theme-markdown-strong: #ff5722;
+ --theme-markdown-horizontal-rule: #e0e0e0;
+ --theme-markdown-list-item: #00bcd4;
+ --theme-markdown-list-enumeration: #9c27b0;
+ --theme-markdown-image: #00bcd4;
+ --theme-markdown-image-text: #9c27b0;
+ --theme-markdown-code-block: #262335;
+ --theme-syntax-comment: #5c5c8a;
+ --theme-syntax-keyword: #e91e63;
+ --theme-syntax-function: #ff5722;
+ --theme-syntax-variable: #262335;
+ --theme-syntax-string: #ff9800;
+ --theme-syntax-number: #9c27b0;
+ --theme-syntax-type: #00bcd4;
+ --theme-syntax-operator: #e91e63;
+ --theme-syntax-punctuation: #262335;
+}
+
+[data-theme="synthwave84"][data-dark="true"] {
+ --theme-primary: #36f9f6;
+ --theme-secondary: #ff7edb;
+ --theme-accent: #b084eb;
+ --theme-error: #fe4450;
+ --theme-warning: #fede5d;
+ --theme-success: #72f1b8;
+ --theme-info: #ff8b39;
+ --theme-text: #ffffff;
+ --theme-text-muted: #848bbd;
+ --theme-background: #262335;
+ --theme-background-panel: #1e1a29;
+ --theme-background-element: #2a2139;
+ --theme-border: #495495;
+ --theme-border-active: #36f9f6;
+ --theme-border-subtle: #241b2f;
+ --theme-diff-added: #72f1b8;
+ --theme-diff-removed: #fe4450;
+ --theme-diff-context: #848bbd;
+ --theme-diff-hunk-header: #b084eb;
+ --theme-diff-highlight-added: #97f1d8;
+ --theme-diff-highlight-removed: #ff5e5b;
+ --theme-diff-added-bg: #1a3a2a;
+ --theme-diff-removed-bg: #3a1a2a;
+ --theme-diff-context-bg: #1e1a29;
+ --theme-diff-line-number: #495495;
+ --theme-diff-added-line-number-bg: #1a3a2a;
+ --theme-diff-removed-line-number-bg: #3a1a2a;
+ --theme-markdown-text: #ffffff;
+ --theme-markdown-heading: #ff7edb;
+ --theme-markdown-link: #36f9f6;
+ --theme-markdown-link-text: #b084eb;
+ --theme-markdown-code: #72f1b8;
+ --theme-markdown-block-quote: #848bbd;
+ --theme-markdown-emph: #fede5d;
+ --theme-markdown-strong: #ff8b39;
+ --theme-markdown-horizontal-rule: #495495;
+ --theme-markdown-list-item: #36f9f6;
+ --theme-markdown-list-enumeration: #b084eb;
+ --theme-markdown-image: #36f9f6;
+ --theme-markdown-image-text: #b084eb;
+ --theme-markdown-code-block: #ffffff;
+ --theme-syntax-comment: #848bbd;
+ --theme-syntax-keyword: #ff7edb;
+ --theme-syntax-function: #ff8b39;
+ --theme-syntax-variable: #ffffff;
+ --theme-syntax-string: #fede5d;
+ --theme-syntax-number: #b084eb;
+ --theme-syntax-type: #36f9f6;
+ --theme-syntax-operator: #ff7edb;
+ --theme-syntax-punctuation: #ffffff;
+}
+
+[data-theme="tokyonight"][data-dark="false"] {
+ --theme-primary: #2e7de9;
+ --theme-secondary: #9854f1;
+ --theme-accent: #b15c00;
+ --theme-error: #f52a65;
+ --theme-warning: #b15c00;
+ --theme-success: #587539;
+ --theme-info: #2e7de9;
+ --theme-text: #3760bf;
+ --theme-text-muted: #8990a3;
+ --theme-background: #e1e2e7;
+ --theme-background-panel: #d5d6db;
+ --theme-background-element: #c8c9ce;
+ --theme-border: #737a8c;
+ --theme-border-active: #5a607d;
+ --theme-border-subtle: #9699a8;
+ --theme-diff-added: #1e725c;
+ --theme-diff-removed: #c53b53;
+ --theme-diff-context: #7086b5;
+ --theme-diff-hunk-header: #7086b5;
+ --theme-diff-highlight-added: #4db380;
+ --theme-diff-highlight-removed: #f52a65;
+ --theme-diff-added-bg: #d5e5d5;
+ --theme-diff-removed-bg: #f7d8db;
+ --theme-diff-context-bg: #d5d6db;
+ --theme-diff-line-number: #c8c9ce;
+ --theme-diff-added-line-number-bg: #c5d5c5;
+ --theme-diff-removed-line-number-bg: #e7c8cb;
+ --theme-markdown-text: #3760bf;
+ --theme-markdown-heading: #9854f1;
+ --theme-markdown-link: #2e7de9;
+ --theme-markdown-link-text: #007197;
+ --theme-markdown-code: #587539;
+ --theme-markdown-block-quote: #8c6c3e;
+ --theme-markdown-emph: #8c6c3e;
+ --theme-markdown-strong: #b15c00;
+ --theme-markdown-horizontal-rule: #8990a3;
+ --theme-markdown-list-item: #2e7de9;
+ --theme-markdown-list-enumeration: #007197;
+ --theme-markdown-image: #2e7de9;
+ --theme-markdown-image-text: #007197;
+ --theme-markdown-code-block: #3760bf;
+ --theme-syntax-comment: #8990a3;
+ --theme-syntax-keyword: #9854f1;
+ --theme-syntax-function: #2e7de9;
+ --theme-syntax-variable: #f52a65;
+ --theme-syntax-string: #587539;
+ --theme-syntax-number: #b15c00;
+ --theme-syntax-type: #8c6c3e;
+ --theme-syntax-operator: #007197;
+ --theme-syntax-punctuation: #3760bf;
+}
+
+[data-theme="tokyonight"][data-dark="true"] {
+ --theme-primary: #82aaff;
+ --theme-secondary: #c099ff;
+ --theme-accent: #ff966c;
+ --theme-error: #ff757f;
+ --theme-warning: #ff966c;
+ --theme-success: #c3e88d;
+ --theme-info: #82aaff;
+ --theme-text: #c8d3f5;
+ --theme-text-muted: #828bb8;
+ --theme-background: #1a1b26;
+ --theme-background-panel: #1e2030;
+ --theme-background-element: #222436;
+ --theme-border: #737aa2;
+ --theme-border-active: #9099b2;
+ --theme-border-subtle: #545c7e;
+ --theme-diff-added: #4fd6be;
+ --theme-diff-removed: #c53b53;
+ --theme-diff-context: #828bb8;
+ --theme-diff-hunk-header: #828bb8;
+ --theme-diff-highlight-added: #b8db87;
+ --theme-diff-highlight-removed: #e26a75;
+ --theme-diff-added-bg: #20303b;
+ --theme-diff-removed-bg: #37222c;
+ --theme-diff-context-bg: #1e2030;
+ --theme-diff-line-number: #222436;
+ --theme-diff-added-line-number-bg: #1b2b34;
+ --theme-diff-removed-line-number-bg: #2d1f26;
+ --theme-markdown-text: #c8d3f5;
+ --theme-markdown-heading: #c099ff;
+ --theme-markdown-link: #82aaff;
+ --theme-markdown-link-text: #86e1fc;
+ --theme-markdown-code: #c3e88d;
+ --theme-markdown-block-quote: #ffc777;
+ --theme-markdown-emph: #ffc777;
+ --theme-markdown-strong: #ff966c;
+ --theme-markdown-horizontal-rule: #828bb8;
+ --theme-markdown-list-item: #82aaff;
+ --theme-markdown-list-enumeration: #86e1fc;
+ --theme-markdown-image: #82aaff;
+ --theme-markdown-image-text: #86e1fc;
+ --theme-markdown-code-block: #c8d3f5;
+ --theme-syntax-comment: #828bb8;
+ --theme-syntax-keyword: #c099ff;
+ --theme-syntax-function: #82aaff;
+ --theme-syntax-variable: #ff757f;
+ --theme-syntax-string: #c3e88d;
+ --theme-syntax-number: #ff966c;
+ --theme-syntax-type: #ffc777;
+ --theme-syntax-operator: #86e1fc;
+ --theme-syntax-punctuation: #c8d3f5;
+}
+
+[data-theme="vesper"][data-dark="false"] {
+ --theme-primary: #ffc799;
+ --theme-secondary: #99ffe4;
+ --theme-accent: #ffc799;
+ --theme-error: #ff8080;
+ --theme-warning: #ffc799;
+ --theme-success: #99ffe4;
+ --theme-info: #ffc799;
+ --theme-text: #101010;
+ --theme-text-muted: #a0a0a0;
+ --theme-background: #fff;
+ --theme-background-panel: #f0f0f0;
+ --theme-background-element: #e0e0e0;
+ --theme-border: #d0d0d0;
+ --theme-border-active: #ffc799;
+ --theme-border-subtle: #e8e8e8;
+ --theme-diff-added: #99ffe4;
+ --theme-diff-removed: #ff8080;
+ --theme-diff-context: #a0a0a0;
+ --theme-diff-hunk-header: #a0a0a0;
+ --theme-diff-highlight-added: #99ffe4;
+ --theme-diff-highlight-removed: #ff8080;
+ --theme-diff-added-bg: #e8f5e8;
+ --theme-diff-removed-bg: #f5e8e8;
+ --theme-diff-context-bg: #f8f8f8;
+ --theme-diff-line-number: #808080;
+ --theme-diff-added-line-number-bg: #e8f5e8;
+ --theme-diff-removed-line-number-bg: #f5e8e8;
+ --theme-markdown-text: #101010;
+ --theme-markdown-heading: #ffc799;
+ --theme-markdown-link: #ffc799;
+ --theme-markdown-link-text: #a0a0a0;
+ --theme-markdown-code: #a0a0a0;
+ --theme-markdown-block-quote: #101010;
+ --theme-markdown-emph: #101010;
+ --theme-markdown-strong: #101010;
+ --theme-markdown-horizontal-rule: #65737e;
+ --theme-markdown-list-item: #101010;
+ --theme-markdown-list-enumeration: #101010;
+ --theme-markdown-image: #ffc799;
+ --theme-markdown-image-text: #a0a0a0;
+ --theme-markdown-code-block: #101010;
+ --theme-syntax-comment: #8b8b8b94;
+ --theme-syntax-keyword: #a0a0a0;
+ --theme-syntax-function: #ffc799;
+ --theme-syntax-variable: #101010;
+ --theme-syntax-string: #99ffe4;
+ --theme-syntax-number: #ffc799;
+ --theme-syntax-type: #ffc799;
+ --theme-syntax-operator: #a0a0a0;
+ --theme-syntax-punctuation: #101010;
+}
+
+[data-theme="vesper"][data-dark="true"] {
+ --theme-primary: #ffc799;
+ --theme-secondary: #99ffe4;
+ --theme-accent: #ffc799;
+ --theme-error: #ff8080;
+ --theme-warning: #ffc799;
+ --theme-success: #99ffe4;
+ --theme-info: #ffc799;
+ --theme-text: #fff;
+ --theme-text-muted: #a0a0a0;
+ --theme-background: #101010;
+ --theme-background-panel: #101010;
+ --theme-background-element: #101010;
+ --theme-border: #282828;
+ --theme-border-active: #ffc799;
+ --theme-border-subtle: #1c1c1c;
+ --theme-diff-added: #99ffe4;
+ --theme-diff-removed: #ff8080;
+ --theme-diff-context: #a0a0a0;
+ --theme-diff-hunk-header: #a0a0a0;
+ --theme-diff-highlight-added: #99ffe4;
+ --theme-diff-highlight-removed: #ff8080;
+ --theme-diff-added-bg: #0d2818;
+ --theme-diff-removed-bg: #281a1a;
+ --theme-diff-context-bg: #101010;
+ --theme-diff-line-number: #505050;
+ --theme-diff-added-line-number-bg: #0d2818;
+ --theme-diff-removed-line-number-bg: #281a1a;
+ --theme-markdown-text: #fff;
+ --theme-markdown-heading: #ffc799;
+ --theme-markdown-link: #ffc799;
+ --theme-markdown-link-text: #a0a0a0;
+ --theme-markdown-code: #a0a0a0;
+ --theme-markdown-block-quote: #fff;
+ --theme-markdown-emph: #fff;
+ --theme-markdown-strong: #fff;
+ --theme-markdown-horizontal-rule: #65737e;
+ --theme-markdown-list-item: #fff;
+ --theme-markdown-list-enumeration: #fff;
+ --theme-markdown-image: #ffc799;
+ --theme-markdown-image-text: #a0a0a0;
+ --theme-markdown-code-block: #fff;
+ --theme-syntax-comment: #8b8b8b94;
+ --theme-syntax-keyword: #a0a0a0;
+ --theme-syntax-function: #ffc799;
+ --theme-syntax-variable: #fff;
+ --theme-syntax-string: #99ffe4;
+ --theme-syntax-number: #ffc799;
+ --theme-syntax-type: #ffc799;
+ --theme-syntax-operator: #a0a0a0;
+ --theme-syntax-punctuation: #fff;
+}
+
+[data-theme="zenburn"][data-dark="false"] {
+ --theme-primary: #5f7f8f;
+ --theme-secondary: #8f5f8f;
+ --theme-accent: #5f8f8f;
+ --theme-error: #8f5f5f;
+ --theme-warning: #8f8f5f;
+ --theme-success: #5f8f5f;
+ --theme-info: #8f7f5f;
+ --theme-text: #3f3f3f;
+ --theme-text-muted: #6f6f6f;
+ --theme-background: #ffffef;
+ --theme-background-panel: #f5f5e5;
+ --theme-background-element: #ebebdb;
+ --theme-border: #d0d0c0;
+ --theme-border-active: #5f7f8f;
+ --theme-border-subtle: #e0e0d0;
+ --theme-diff-added: #5f8f5f;
+ --theme-diff-removed: #8f5f5f;
+ --theme-diff-context: #6f6f6f;
+ --theme-diff-hunk-header: #5f8f8f;
+ --theme-diff-highlight-added: #5f8f5f;
+ --theme-diff-highlight-removed: #8f5f5f;
+ --theme-diff-added-bg: #efffef;
+ --theme-diff-removed-bg: #ffefef;
+ --theme-diff-context-bg: #f5f5e5;
+ --theme-diff-line-number: #b0b0a0;
+ --theme-diff-added-line-number-bg: #efffef;
+ --theme-diff-removed-line-number-bg: #ffefef;
+ --theme-markdown-text: #3f3f3f;
+ --theme-markdown-heading: #8f8f5f;
+ --theme-markdown-link: #5f7f8f;
+ --theme-markdown-link-text: #5f8f8f;
+ --theme-markdown-code: #5f8f5f;
+ --theme-markdown-block-quote: #6f6f6f;
+ --theme-markdown-emph: #8f8f5f;
+ --theme-markdown-strong: #8f7f5f;
+ --theme-markdown-horizontal-rule: #6f6f6f;
+ --theme-markdown-list-item: #5f7f8f;
+ --theme-markdown-list-enumeration: #5f8f8f;
+ --theme-markdown-image: #5f7f8f;
+ --theme-markdown-image-text: #5f8f8f;
+ --theme-markdown-code-block: #3f3f3f;
+ --theme-syntax-comment: #5f7f5f;
+ --theme-syntax-keyword: #8f8f5f;
+ --theme-syntax-function: #5f7f8f;
+ --theme-syntax-variable: #3f3f3f;
+ --theme-syntax-string: #8f5f5f;
+ --theme-syntax-number: #5f8f5f;
+ --theme-syntax-type: #5f8f8f;
+ --theme-syntax-operator: #8f8f5f;
+ --theme-syntax-punctuation: #3f3f3f;
+}
+
+[data-theme="zenburn"][data-dark="true"] {
+ --theme-primary: #8cd0d3;
+ --theme-secondary: #dc8cc3;
+ --theme-accent: #93e0e3;
+ --theme-error: #cc9393;
+ --theme-warning: #f0dfaf;
+ --theme-success: #7f9f7f;
+ --theme-info: #dfaf8f;
+ --theme-text: #dcdccc;
+ --theme-text-muted: #9f9f9f;
+ --theme-background: #3f3f3f;
+ --theme-background-panel: #4f4f4f;
+ --theme-background-element: #5f5f5f;
+ --theme-border: #5f5f5f;
+ --theme-border-active: #8cd0d3;
+ --theme-border-subtle: #4f4f4f;
+ --theme-diff-added: #7f9f7f;
+ --theme-diff-removed: #cc9393;
+ --theme-diff-context: #9f9f9f;
+ --theme-diff-hunk-header: #93e0e3;
+ --theme-diff-highlight-added: #8fb28f;
+ --theme-diff-highlight-removed: #dca3a3;
+ --theme-diff-added-bg: #4f5f4f;
+ --theme-diff-removed-bg: #5f4f4f;
+ --theme-diff-context-bg: #4f4f4f;
+ --theme-diff-line-number: #6f6f6f;
+ --theme-diff-added-line-number-bg: #4f5f4f;
+ --theme-diff-removed-line-number-bg: #5f4f4f;
+ --theme-markdown-text: #dcdccc;
+ --theme-markdown-heading: #f0dfaf;
+ --theme-markdown-link: #8cd0d3;
+ --theme-markdown-link-text: #93e0e3;
+ --theme-markdown-code: #7f9f7f;
+ --theme-markdown-block-quote: #9f9f9f;
+ --theme-markdown-emph: #e0cf9f;
+ --theme-markdown-strong: #dfaf8f;
+ --theme-markdown-horizontal-rule: #9f9f9f;
+ --theme-markdown-list-item: #8cd0d3;
+ --theme-markdown-list-enumeration: #93e0e3;
+ --theme-markdown-image: #8cd0d3;
+ --theme-markdown-image-text: #93e0e3;
+ --theme-markdown-code-block: #dcdccc;
+ --theme-syntax-comment: #7f9f7f;
+ --theme-syntax-keyword: #f0dfaf;
+ --theme-syntax-function: #8cd0d3;
+ --theme-syntax-variable: #dcdccc;
+ --theme-syntax-string: #cc9393;
+ --theme-syntax-number: #8fb28f;
+ --theme-syntax-type: #93e0e3;
+ --theme-syntax-operator: #f0dfaf;
+ --theme-syntax-punctuation: #dcdccc;
+}
+
diff --git a/packages/desktop/src/components/autocomplete-dropdown.tsx b/packages/desktop/src/components/autocomplete-dropdown.tsx
new file mode 100644
index 0000000000..726125adf3
--- /dev/null
+++ b/packages/desktop/src/components/autocomplete-dropdown.tsx
@@ -0,0 +1,99 @@
+import { createEffect, Show, For, onMount, onCleanup } from "solid-js"
+import { FileIcon, Icon } from "@/ui"
+import { createList } from "solid-list"
+
+export interface AutocompleteItem {
+ type: "file" | "command"
+ label: string
+ value: string
+ description?: string
+}
+
+interface AutocompleteDropdownProps {
+ items: AutocompleteItem[]
+ position: { top: number; left: number }
+ onSelect: (item: AutocompleteItem) => void
+ onClose: () => void
+}
+
+export function AutocompleteDropdown(props: AutocompleteDropdownProps) {
+ let containerRef: HTMLDivElement | undefined
+
+ const list = createList({
+ items: () => props.items.map((item) => item.value),
+ initialActive: props.items[0]?.value,
+ loop: true,
+ })
+
+ const handleKeyDown = (e: KeyboardEvent) => {
+ if (e.key === "Escape") {
+ e.preventDefault()
+ e.stopPropagation()
+ props.onClose()
+ } else if (e.key === "Enter" || e.key === "Tab") {
+ e.preventDefault()
+ e.stopPropagation()
+ const selected = props.items.find((x) => x.value === list.active())
+ if (selected) props.onSelect(selected)
+ } else if (e.key === "ArrowUp" || e.key === "ArrowDown") {
+ e.preventDefault()
+ e.stopPropagation()
+ list.onKeyDown(e)
+ }
+ }
+
+ onMount(() => {
+ document.addEventListener("keydown", handleKeyDown, { capture: true })
+ })
+
+ onCleanup(() => {
+ document.removeEventListener("keydown", handleKeyDown, { capture: true })
+ })
+
+ createEffect(() => {
+ if (props.items.length > 0 && !props.items.find((x) => x.value === list.active())) {
+ list.setActive(props.items[0].value)
+ }
+ })
+
+ return (
+ 0}>
+
+
+ {(item) => (
+
+ )}
+
+
+
+ )
+}
diff --git a/packages/desktop/src/components/code.tsx b/packages/desktop/src/components/code.tsx
index 40a40aa9a6..ea7ca1a988 100644
--- a/packages/desktop/src/components/code.tsx
+++ b/packages/desktop/src/components/code.tsx
@@ -330,9 +330,13 @@ export function Code(props: Props) {
container = el
}}
innerHTML={html()}
+ style={{
+ transform: "translateZ(0)",
+ "will-change": "contents",
+ }}
class="
font-mono text-xs tracking-wide overflow-y-auto h-full
- [&]:[counter-reset:line]
+ [&_code]:[counter-reset:line]
[&_pre]:focus-visible:outline-none
[&_pre]:overflow-x-auto [&_pre]:no-scrollbar
[&_code]:min-w-full [&_code]:inline-block
@@ -347,7 +351,7 @@ export function Code(props: Props) {
[&_.line]:inline-block [&_.line]:w-full
[&_.line]:hover:bg-background-element
[&_.line::before]:sticky [&_.line::before]:left-0
- [&_.line::before]:w-12 [&_.line::before]:pr-4
+ [&_.line::before]:w-10 [&_.line::before]:pr-4
[&_.line::before]:z-10
[&_.line::before]:bg-background-panel
[&_.line::before]:text-text-muted/60
@@ -355,12 +359,11 @@ export function Code(props: Props) {
[&_.line::before]:select-none
[&_.line::before]:[counter-increment:line]
[&_.line::before]:content-[counter(line)]
+ [&_.line::before]:min-w-[2ch]
[&_.line-number-highlight]:bg-accent/20
[&_.line-number-highlight::before]:bg-accent/40!
[&_.line-number-highlight::before]:text-background-panel!
- [&_code.code-diff_.line::before]:content-['']
- [&_code.code-diff_.line::before]:w-0
- [&_code.code-diff_.line::before]:pr-0
+ [&_code.code-diff_.line::before]:hidden
[&_.diff-split_code.code-diff::before]:w-10
[&_.diff-split_.diff-newln]:left-0
[&_.diff-oldln]:sticky [&_.diff-oldln]:left-0
diff --git a/packages/desktop/src/components/drawer.tsx b/packages/desktop/src/components/drawer.tsx
new file mode 100644
index 0000000000..5b26aef709
--- /dev/null
+++ b/packages/desktop/src/components/drawer.tsx
@@ -0,0 +1,63 @@
+import { Show, type ParentProps, onMount, onCleanup } from "solid-js"
+import { Icon, IconButton } from "@/ui"
+
+interface DrawerProps extends ParentProps {
+ open: boolean
+ onClose: () => void
+ title: string
+ side?: "left" | "right"
+}
+
+export default function Drawer(props: DrawerProps) {
+ let drawerRef: HTMLDivElement | undefined
+
+ const handleBackdropClick = (e: MouseEvent) => {
+ if (e.target === e.currentTarget) {
+ props.onClose()
+ }
+ }
+
+ onMount(() => {
+ const handleEscape = (e: KeyboardEvent) => {
+ if (e.key === "Escape" && props.open) {
+ props.onClose()
+ }
+ }
+ document.addEventListener("keydown", handleEscape)
+ onCleanup(() => document.removeEventListener("keydown", handleEscape))
+ })
+
+ return (
+
+
+
+ )
+}
diff --git a/packages/desktop/src/components/editor-pane.tsx b/packages/desktop/src/components/editor-pane.tsx
index 2f4c87e25f..4f59ecf8b4 100644
--- a/packages/desktop/src/components/editor-pane.tsx
+++ b/packages/desktop/src/components/editor-pane.tsx
@@ -1,4 +1,4 @@
-import { For, Match, Show, Switch, createSignal, splitProps } from "solid-js"
+import { For, Match, Show, Switch, createSignal, splitProps, createMemo } from "solid-js"
import { Tabs } from "@/ui/tabs"
import { FileIcon, Icon, IconButton, Logo, Tooltip } from "@/ui"
import {
@@ -13,16 +13,40 @@ import {
import type { DragEvent, Transformer } from "@thisbeyond/solid-dnd"
import type { LocalFile } from "@/context/local"
import { Code } from "@/components/code"
-import { useLocal } from "@/context"
+import PromptForm from "@/components/prompt-form"
+import SuggestionChips from "@/components/suggestion-chips"
+import { useLocal, useSDK, useSync } from "@/context"
+import { getFilename } from "@/utils"
import type { JSX } from "solid-js"
interface EditorPaneProps {
+ layoutKey: string
+ timelinePane: string
onFileClick: (file: LocalFile) => void
+ onOpenModelSelect: () => void
+ onOpenAgentSelect: () => void
+ onInputRefChange: (element: HTMLTextAreaElement | null) => void
+ onPromptSubmit: (prompt: string) => void
+ onDragProximity?: (proximity: { isDragging: boolean; nearDockZone: boolean; x: number; y: number }) => void
+ onDrop?: () => void
+ hideFloatingChat?: boolean
}
export default function EditorPane(props: EditorPaneProps): JSX.Element {
- const [localProps] = splitProps(props, ["onFileClick"])
+ const [localProps] = splitProps(props, [
+ "layoutKey",
+ "timelinePane",
+ "onFileClick",
+ "onOpenModelSelect",
+ "onOpenAgentSelect",
+ "onInputRefChange",
+ "onPromptSubmit",
+ "onDragProximity",
+ "onDrop",
+ "hideFloatingChat",
+ ])
const local = useLocal()
+ const sync = useSync()
const [activeItem, setActiveItem] = createSignal(undefined)
const navigateChange = (dir: 1 | -1) => {
@@ -63,8 +87,133 @@ export default function EditorPane(props: EditorPaneProps): JSX.Element {
setActiveItem(undefined)
}
+ const handleOpenFolder = () => {
+ const input = document.createElement("input")
+ input.type = "file"
+ input.webkitdirectory = true
+ input.onchange = (e) => {
+ const files = (e.target as HTMLInputElement).files
+ if (files && files.length > 0) {
+ const path = files[0].webkitRelativePath.split("/")[0]
+ window.location.href = `/?path=${encodeURIComponent(path)}`
+ }
+ }
+ input.click()
+ }
+
+ const suggestions = createMemo(() => {
+ if (local.file.opened().length > 0) return []
+
+ const hasFiles = Object.keys(sync.data.node).length > 0
+ if (!hasFiles) {
+ return ["Open a folder to get started"]
+ }
+
+ const activeSession = local.session.active()
+ const hasConversation = activeSession && sync.data.message[activeSession.id]?.length > 0
+
+ if (hasConversation) {
+ const messages = sync.data.message[activeSession.id] || []
+
+ const conversationText = messages
+ .map((m) =>
+ sync.data.part[m.id]
+ ?.filter((p) => p.type === "text")
+ .map((p) => p.text)
+ .join(" "),
+ )
+ .join(" ")
+ .toLowerCase()
+
+ const result = []
+
+ if (conversationText.includes("agent") || conversationText.includes("guideline")) {
+ result.push("Review the AGENTS.md file")
+ result.push("What build commands are configured?")
+ }
+
+ if (conversationText.includes("component") || conversationText.includes("ui")) {
+ result.push("Show me all components")
+ result.push("Create a new component")
+ }
+
+ if (conversationText.includes("test") || conversationText.includes("spec")) {
+ result.push("Write tests for this feature")
+ result.push("Run the test suite")
+ }
+
+ if (
+ conversationText.includes("style") ||
+ conversationText.includes("css") ||
+ conversationText.includes("theme")
+ ) {
+ result.push("Update the theme system")
+ result.push("Review styling patterns")
+ }
+
+ if (conversationText.includes("error") || conversationText.includes("bug") || conversationText.includes("fix")) {
+ result.push("Debug this issue")
+ result.push("Check error logs")
+ }
+
+ if (result.length === 0) {
+ result.push("Continue working on this feature")
+ result.push("What should we do next?")
+ result.push("Review recent changes")
+ }
+
+ return result.slice(0, 6)
+ }
+
+ const files = Object.keys(sync.data.node)
+ const agentsMdFile = files.find((f) => f.endsWith("AGENTS.md") || f.endsWith("agents.md"))
+ const hasAgentsMd = !!agentsMdFile
+ const hasPackageJson = files.some((f) => f.endsWith("package.json"))
+ const hasReadme = files.some((f) => f.toLowerCase().includes("readme"))
+ const hasSrc = files.some((f) => f.startsWith("src/"))
+ const hasTests = files.some((f) => f.includes("test") || f.includes("spec"))
+ const hasTsConfig = files.some((f) => f.includes("tsconfig"))
+ const hasComponents = files.some((f) => f.includes("component"))
+
+ const result = []
+
+ if (!hasAgentsMd) {
+ result.push("Create an AGENTS.md file for this project")
+ } else {
+ result.push("Review the AGENTS.md file")
+ }
+ if (hasReadme) result.push("Explain what this project does")
+ if (hasPackageJson) result.push("Show me the dependencies")
+ if (hasSrc) result.push("Give me an overview of the codebase")
+ if (hasComponents) result.push("Review component architecture")
+ if (hasTsConfig) result.push("Check TypeScript configuration")
+ if (hasTests) result.push("Review test coverage")
+
+ if (result.length === 0) {
+ result.push("Explain the project structure")
+ }
+
+ return result.slice(0, 6)
+ })
+
+ const handleSuggestion = async (suggestion: string) => {
+ if (suggestion === "Open a folder to get started") {
+ handleOpenFolder()
+ } else {
+ await handlePromptSubmit(suggestion)
+ }
+ }
+
return (
+
+
+
navigateChange(-1)}>
-
+
navigateChange(1)}>
-
+
@@ -120,7 +269,7 @@ export default function EditorPane(props: EditorPaneProps): JSX.Element {
}}
onClick={() => local.file.setView(activeFile.path, "raw")}
>
-
+
@@ -134,7 +283,7 @@ export default function EditorPane(props: EditorPaneProps): JSX.Element {
}}
onClick={() => local.file.setView(activeFile.path, "diff-unified")}
>
-
+
@@ -148,19 +297,66 @@ export default function EditorPane(props: EditorPaneProps): JSX.Element {
}}
onClick={() => local.file.setView(activeFile.path, "diff-split")}
>
-
+
)
})()}
+
+ local.layout.toggle(localProps.layoutKey, localProps.timelinePane)}
+ >
+
+
+
{(file) => (
{(() => {
+ const ext = file.path.split(".").pop()?.toLowerCase()
+ const imageExts = ["png", "jpg", "jpeg", "gif", "svg", "webp", "bmp", "ico"]
+ const isImage = ext && imageExts.includes(ext)
+
+ if (isImage) {
+ const absolutePath = sync.absolute(file.path)
+
+ return (
+
+
+

{
+ const target = e.currentTarget
+ target.style.display = "none"
+ const sibling = target.nextElementSibling as HTMLElement
+ if (sibling) sibling.style.display = "block"
+ }}
+ />
+
+
Unable to display image
+
{absolutePath}
+
+
+
+ )
+ }
+
const view = local.file.view(file.path)
const showRaw = view === "raw" || !file.content?.diff
const code = showRaw ? (file.content?.content ?? "") : (file.content?.diff ?? "")
@@ -184,6 +380,21 @@ export default function EditorPane(props: EditorPaneProps): JSX.Element {
})()}
+
+ localProps.onInputRefChange(element ?? null)}
+ onDragProximity={localProps.onDragProximity}
+ onDrop={localProps.onDrop}
+ />
+
)
}
@@ -233,7 +444,7 @@ function SortableTab(props: {
variant="ghost"
onClick={() => props.onTabClose(props.file)}
>
-
+
diff --git a/packages/desktop/src/components/file-tree.tsx b/packages/desktop/src/components/file-tree.tsx
index d31255ced5..0eee63c73c 100644
--- a/packages/desktop/src/components/file-tree.tsx
+++ b/packages/desktop/src/components/file-tree.tsx
@@ -1,6 +1,6 @@
import { useLocal } from "@/context"
import type { LocalFile } from "@/context/local"
-import { Collapsible, FileIcon, Tooltip } from "@/ui"
+import { Collapsible, FileIcon } from "@/ui"
import { For, Match, Switch, Show, type ComponentProps, type ParentProps } from "solid-js"
import { Dynamic } from "solid-js/web"
@@ -19,6 +19,7 @@ export default function FileTree(props: {
component={p.as ?? "div"}
classList={{
"p-0.5 w-full flex items-center gap-x-2 hover:bg-background-element cursor-pointer": true,
+ "!py-0": p.node.type === "directory",
"bg-background-element": local.file.active()?.path === p.node.path,
[props.nodeClass ?? ""]: !!props.nodeClass,
}}
@@ -71,38 +72,36 @@ export default function FileTree(props: {
{(node) => (
-
-
-
- (open ? local.file.expand(node.path) : local.file.collapse(node.path))}
- >
-
-
-
-
-
-
-
-
-
-
-
-
- props.onFileClick?.(node)}>
-
-
-
-
-
-
+
+
+ (open ? local.file.expand(node.path) : local.file.collapse(node.path))}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+ props.onFileClick?.(node)} title={node.path}>
+
+
+
+
+
)}
diff --git a/packages/desktop/src/components/markdown.tsx b/packages/desktop/src/components/markdown.tsx
index a60fad1492..9a0cfa97b2 100644
--- a/packages/desktop/src/components/markdown.tsx
+++ b/packages/desktop/src/components/markdown.tsx
@@ -18,6 +18,11 @@ export function Markdown(props: { text: string; class?: string }) {
)
}
diff --git a/packages/desktop/src/components/mobile-header.tsx b/packages/desktop/src/components/mobile-header.tsx
new file mode 100644
index 0000000000..bdc5ba749d
--- /dev/null
+++ b/packages/desktop/src/components/mobile-header.tsx
@@ -0,0 +1,54 @@
+import { Icon, IconButton } from "@/ui"
+import { Show } from "solid-js"
+
+interface MobileHeaderProps {
+ title: string
+ showBack?: boolean
+ onBack?: () => void
+ onMenuClick?: () => void
+ actions?: Array<{
+ icon: string
+ label: string
+ onClick: () => void
+ }>
+}
+
+export default function MobileHeader(props: MobileHeaderProps) {
+ return (
+
+ )
+}
diff --git a/packages/desktop/src/components/mobile-layout.tsx b/packages/desktop/src/components/mobile-layout.tsx
new file mode 100644
index 0000000000..9f937f9571
--- /dev/null
+++ b/packages/desktop/src/components/mobile-layout.tsx
@@ -0,0 +1,308 @@
+import { createSignal, For, Match, Show, Switch, onMount, onCleanup, createMemo } from "solid-js"
+import { FileIcon, Logo } from "@/ui"
+import { Tabs } from "@/ui/tabs"
+import FileTree from "@/components/file-tree"
+import SessionList from "@/components/session-list"
+import SessionTimeline from "@/components/session-timeline"
+import PromptForm from "@/components/prompt-form"
+import SuggestionChips from "@/components/suggestion-chips"
+import MobileNavigation, { type MobileTab } from "@/components/mobile-navigation"
+import MobileHeader from "@/components/mobile-header"
+import Drawer from "@/components/drawer"
+import EditorPane from "@/components/editor-pane"
+import { useLocal, useSync } from "@/context"
+import type { LocalFile } from "@/context/local"
+import { getDirectory, getFilename, createSwipeGesture, vibrate } from "@/utils"
+
+interface MobileLayoutProps {
+ layoutKey: string
+ timelinePane: string
+ onFileClick: (file: LocalFile) => void
+ onPromptSubmit: (prompt: string) => Promise
+ onOpenModelSelect: () => void
+ onOpenAgentSelect: () => void
+}
+
+export default function MobileLayout(props: MobileLayoutProps) {
+ const local = useLocal()
+ const sync = useSync()
+ const [activeTab, setActiveTab] = createSignal("editor")
+ const [drawerOpen, setDrawerOpen] = createSignal(false)
+ const [keyboardHeight, setKeyboardHeight] = createSignal(0)
+ const [viewportHeight, setViewportHeight] = createSignal(typeof window !== "undefined" ? window.innerHeight : 0)
+
+ const suggestions = createMemo(() => {
+ const hasFiles = Object.keys(sync.data.node).length > 0
+ if (!hasFiles) {
+ return ["Open a folder to get started"]
+ }
+
+ const files = Object.keys(sync.data.node)
+ const agentsMdFile = files.find((f) => f.endsWith("AGENTS.md") || f.endsWith("agents.md"))
+ const hasAgentsMd = !!agentsMdFile
+ const hasPackageJson = files.some((f) => f.endsWith("package.json"))
+ const hasReadme = files.some((f) => f.toLowerCase().includes("readme"))
+
+ const result = []
+
+ if (!hasAgentsMd) {
+ result.push("Create an AGENTS.md file")
+ } else {
+ result.push("Review AGENTS.md")
+ }
+
+ if (hasPackageJson) {
+ result.push("What build commands are configured?")
+ }
+
+ if (hasReadme) {
+ result.push("Summarize this project")
+ }
+
+ result.push("Show me all components")
+ result.push("Create a new feature")
+ result.push("Write tests")
+
+ return result.slice(0, 6)
+ })
+
+ const handleSuggestion = async (suggestion: string) => {
+ await props.onPromptSubmit(suggestion)
+ setActiveTab("chat")
+ }
+
+ const handleSwipeLeft = () => {
+ const tabs: MobileTab[] = ["files", "editor", "chat"]
+ const currentIndex = tabs.indexOf(activeTab())
+ if (currentIndex < tabs.length - 1) {
+ vibrate(10)
+ setActiveTab(tabs[currentIndex + 1])
+ }
+ }
+
+ const handleSwipeRight = () => {
+ const tabs: MobileTab[] = ["files", "editor", "chat"]
+ const currentIndex = tabs.indexOf(activeTab())
+ if (currentIndex > 0) {
+ vibrate(10)
+ setActiveTab(tabs[currentIndex - 1])
+ }
+ }
+
+ let containerRef: HTMLDivElement | undefined
+
+ onMount(() => {
+ const handleResize = () => {
+ const newHeight = window.innerHeight
+ const heightDiff = viewportHeight() - newHeight
+ if (heightDiff > 100) {
+ setKeyboardHeight(heightDiff)
+ } else {
+ setKeyboardHeight(0)
+ }
+ setViewportHeight(newHeight)
+ }
+
+ const handleVisualViewportResize = () => {
+ if (window.visualViewport) {
+ const keyboardOffset = window.innerHeight - window.visualViewport.height
+ setKeyboardHeight(keyboardOffset > 100 ? keyboardOffset : 0)
+ }
+ }
+
+ window.addEventListener("resize", handleResize)
+ window.visualViewport?.addEventListener("resize", handleVisualViewportResize)
+
+ if (containerRef) {
+ const cleanupSwipe = createSwipeGesture(containerRef, {
+ onSwipeLeft: handleSwipeLeft,
+ onSwipeRight: handleSwipeRight,
+ })
+
+ onCleanup(() => {
+ cleanupSwipe()
+ })
+ }
+
+ onCleanup(() => {
+ window.removeEventListener("resize", handleResize)
+ window.visualViewport?.removeEventListener("resize", handleVisualViewportResize)
+ })
+ })
+
+ return (
+ 0 ? `calc(100vh - ${keyboardHeight()}px)` : "100vh",
+ "padding-bottom": keyboardHeight() > 0 ? "0" : "calc(4rem + var(--safe-area-inset-bottom))",
+ "touch-action": "pan-y",
+ }}
+ >
+
+
+ setDrawerOpen(true)} />
+
+
+
+
+ Files
+
+
+ Changes
+
+
+
+
+
+
+ No changes
}
+ >
+
+
+ {(path) => (
+ -
+
+
+ )}
+
+
+
+
+
+
+
+
+
+ setDrawerOpen(true)}
+ />
+
+
+
+
+
+
+
Start a conversation or open a file to begin
+
+
+
+
+
+
+
+
+ {}}
+ hideFloatingChat={true}
+ />
+
+
+
+
+
+
+
+ setDrawerOpen(true)} />
+
+
+
+ >
+ }
+ >
+ {(activeSession) => (
+ <>
+ local.session.clearActive()}
+ />
+
+
+
+ 0 ? `${keyboardHeight()}px` : "calc(4rem + var(--safe-area-inset-bottom))",
+ }}
+ >
+
+
+ >
+ )}
+
+
+
+
+
+
+ setDrawerOpen(false)} title="Settings" side="left">
+
+
+
Agent
+
+
+
+
Model
+
+
+
+
+
+ )
+}
diff --git a/packages/desktop/src/components/mobile-navigation.tsx b/packages/desktop/src/components/mobile-navigation.tsx
new file mode 100644
index 0000000000..434d4f5303
--- /dev/null
+++ b/packages/desktop/src/components/mobile-navigation.tsx
@@ -0,0 +1,65 @@
+import { Icon } from "@/ui"
+import { Show } from "solid-js"
+
+export type MobileTab = "files" | "editor" | "chat"
+
+interface MobileNavigationProps {
+ activeTab: MobileTab
+ onTabChange: (tab: MobileTab) => void
+ hasActiveSession: boolean
+}
+
+export default function MobileNavigation(props: MobileNavigationProps) {
+ return (
+
+ )
+}
diff --git a/packages/desktop/src/components/prompt-form.tsx b/packages/desktop/src/components/prompt-form.tsx
index 5e6441596c..3083c89549 100644
--- a/packages/desktop/src/components/prompt-form.tsx
+++ b/packages/desktop/src/components/prompt-form.tsx
@@ -1,31 +1,31 @@
-import { For, Show, createMemo, onCleanup, type JSX } from "solid-js"
+import { For, Show, createEffect, createMemo, createSignal, onCleanup, onMount, createResource } from "solid-js"
import { createStore } from "solid-js/store"
-import { Popover } from "@kobalte/core/popover"
import { Button, FileIcon, Icon, IconButton, Tooltip } from "@/ui"
import { Select } from "@/components/select"
-import { useLocal } from "@/context"
+import { useLocal, useMobile } from "@/context"
import type { FileContext, LocalFile } from "@/context/local"
-import { getDirectory, getFilename } from "@/utils"
-import { composeDisplaySegments, createAttachmentDisplay, parsePrompt, registerCandidate } from "./prompt-form-helpers"
-import type {
- AttachmentCandidate,
- PromptAttachmentPart,
- PromptAttachmentSegment,
- PromptDisplaySegment,
- PromptSubmitValue,
-} from "./prompt-form-helpers"
-import { useMentionController, usePromptScrollSync, usePromptSpeech, type PromptFormState } from "./prompt-form-hooks"
+import { getFilename, getDirectory } from "@/utils"
+import { createSpeechRecognition } from "@/utils/speech"
+import { getCurrentWindow } from "@tauri-apps/api/window"
+import { AutocompleteDropdown, type AutocompleteItem } from "@/components/autocomplete-dropdown"
+import { usePromptSpeech, useMentionController, usePromptScrollSync, type PromptFormState } from "./prompt-form-hooks"
+import { parsePrompt, createAttachmentDisplay, type PromptAttachmentSegment } from "./prompt-form-helpers"
interface PromptFormProps {
class?: string
classList?: Record
onSubmit: (prompt: PromptSubmitValue) => Promise | void
onOpenModelSelect: () => void
+ onOpenAgentSelect: () => void
onInputRefChange?: (element: HTMLTextAreaElement | undefined) => void
+ onDragProximity?: (proximity: { isDragging: boolean; nearDockZone: boolean; x: number; y: number }) => void
+ onDrop?: () => void
+ docked?: boolean
}
export default function PromptForm(props: PromptFormProps) {
const local = useLocal()
+ const mobile = useMobile()
const [state, setState] = createStore({
promptInput: "",
@@ -35,9 +35,57 @@ export default function PromptForm(props: PromptFormProps) {
mentionRange: undefined,
mentionIndex: 0,
mentionAnchorOffset: { x: 0, y: 0 },
- inlineAliases: new Map(),
+ inlineAliases: new Map(),
})
+ const [prompt, setPrompt] = createSignal("")
+ const [isDragOver, setIsDragOver] = createSignal(false)
+ const [uploadedFiles, setUploadedFiles] = createSignal([])
+ const [autocomplete, setAutocomplete] = createSignal<{
+ type: "file" | "command"
+ query: string
+ position: { top: number; left: number }
+ startPos: number
+ } | null>(null)
+
+ const [autocompleteItems] = createResource(autocomplete, async (ac) => {
+ if (!ac) return []
+
+ if (ac.type === "file") {
+ const files = await local.file.search(ac.query)
+
+ const sorted = files.sort((a: string, b: string) => {
+ const aFilename = getFilename(a)
+ const bFilename = getFilename(b)
+ const aIsHidden = aFilename.startsWith(".")
+ const bIsHidden = bFilename.startsWith(".")
+
+ if (aIsHidden && !bIsHidden) return 1
+ if (!aIsHidden && bIsHidden) return -1
+ return 0
+ })
+
+ return sorted.slice(0, 10).map((path: string) => ({
+ type: "file" as const,
+ label: getFilename(path),
+ value: path,
+ description: getDirectory(path),
+ }))
+ }
+
+ if (ac.type === "command") {
+ const commands = [
+ { label: "model", value: "model", description: "Change model" },
+ { label: "agent", value: "agent", description: "Change agent" },
+ ]
+ return commands.filter((c) => c.label.startsWith(ac.query)).map((c) => ({ type: "command" as const, ...c }))
+ }
+
+ return []
+ })
+
+ let dragCounter = 0
+
const placeholderText = "Start typing or speaking..."
const {
@@ -50,7 +98,51 @@ export default function PromptForm(props: PromptFormProps) {
let inputRef: HTMLTextAreaElement | undefined = undefined
let overlayContainerRef: HTMLDivElement | undefined = undefined
- let mentionMeasureRef: HTMLDivElement | undefined = undefined
+ let containerRef!: HTMLDivElement
+ let shouldAutoScroll = true
+ let isDraggingForm = false
+ let dragStartPos = { x: 0, y: 0 }
+ let currentTranslate = { x: 0, y: 0 }
+ let animationFrameId: number | undefined
+ let wasNearDockZone = false
+
+ const modeColors = createMemo(() => {
+ const agentName = local.agent.current().name.toLowerCase()
+
+ if (agentName === "build") {
+ return {
+ ring: "ring-primary/50",
+ focusRing: "focus-within:ring-primary/40",
+ focusBorder: "focus-within:border-primary",
+ button: "bg-primary",
+ buttonHover: "hover:bg-primary/90",
+ }
+ } else if (agentName === "plan") {
+ return {
+ ring: "ring-secondary/50",
+ focusRing: "focus-within:ring-secondary/40",
+ focusBorder: "focus-within:border-secondary",
+ button: "bg-secondary",
+ buttonHover: "hover:bg-secondary/90",
+ }
+ } else if (agentName === "docs") {
+ return {
+ ring: "ring-accent/50",
+ focusRing: "focus-within:ring-accent/40",
+ focusBorder: "focus-within:border-accent",
+ button: "bg-accent",
+ buttonHover: "hover:bg-accent/90",
+ }
+ }
+
+ return {
+ ring: "ring-border-active/50",
+ focusRing: "focus-within:ring-primary/40",
+ focusBorder: "focus-within:border-primary",
+ button: "bg-primary",
+ buttonHover: "hover:bg-primary/90",
+ }
+ })
const attachmentLookup = createMemo(() => {
const map = new Map()
@@ -127,74 +219,77 @@ export default function PromptForm(props: PromptFormProps) {
getActiveContext: () => local.context.active() ?? undefined,
})
- const { handlePromptScroll, resetScrollPosition } = usePromptScrollSync({
+ const { handlePromptScroll, resetScrollPosition, setAutoScroll } = usePromptScrollSync({
state,
getInputRef: () => inputRef,
getOverlayRef: () => overlayContainerRef,
- interim: () => (isRecording() ? interimTranscript() : ""),
+ interim: interimTranscript,
updateMentionPosition,
})
- const displaySegments = createMemo(() => {
- const value = state.promptInput
- const segments = parsedPrompt().segments
- const interim = isRecording() ? interimTranscript() : ""
- return composeDisplaySegments(segments, value, interim)
- })
+ let mentionMeasureRef: HTMLDivElement | undefined = undefined
+ function renderAttachmentChip(part: PromptAttachmentPart, _placeholder: string) {
+ const display = part.display ?? createAttachmentDisplay(part.path, part.selection)
+ return @{display}
+ }
+
+ function renderTextSegment(text: string) {
+ return {text}
+ }
+
+ const displaySegments = createMemo(() => parsedPrompt().segments)
const hasDisplaySegments = createMemo(() => displaySegments().length > 0)
- function handleAttachmentNavigation(
- event: KeyboardEvent & { currentTarget: HTMLTextAreaElement },
- direction: "left" | "right",
- ) {
- const element = event.currentTarget
- const caret = element.selectionStart ?? 0
- const segments = attachmentSegments()
- if (direction === "left") {
- let match = segments.find((segment) => caret > segment.start && caret <= segment.end)
- if (!match && element.selectionStart !== element.selectionEnd) {
- match = segments.find(
- (segment) => element.selectionStart === segment.start && element.selectionEnd === segment.end,
- )
- }
- if (!match) return false
- event.preventDefault()
- if (element.selectionStart === match.start && element.selectionEnd === match.end) {
- const next = Math.max(0, match.start)
- element.setSelectionRange(next, next)
- syncMentionFromCaret(element)
- return true
- }
- element.setSelectionRange(match.start, match.end)
- syncMentionFromCaret(element)
- return true
- }
- if (direction === "right") {
- let match = segments.find((segment) => caret >= segment.start && caret < segment.end)
- if (!match && element.selectionStart !== element.selectionEnd) {
- match = segments.find(
- (segment) => element.selectionStart === segment.start && element.selectionEnd === segment.end,
- )
- }
- if (!match) return false
- event.preventDefault()
- if (element.selectionStart === match.start && element.selectionEnd === match.end) {
- const next = match.end
- element.setSelectionRange(next, next)
- syncMentionFromCaret(element)
- return true
- }
- element.setSelectionRange(match.start, match.end)
- syncMentionFromCaret(element)
- return true
- }
- return false
+ function PromptDisplayOverlay(props: any) {
+ return (
+
+ {props.placeholder}}>
+
+ {(segment: any) => (
+ {segment.text}}
+ >
+ {props.renderAttachmentChip ? props.renderAttachmentChip(segment, props.placeholder) : @{segment.token}}
+
+ )}
+
+
+
+ )
}
- function renderAttachmentChip(part: PromptAttachmentPart, _placeholder: string) {
- const display = part.display ?? createAttachmentDisplay(part.path, part.selection)
- return @{display}
+ function MentionSuggestions(props: any) {
+ return (
+
+
+
+ {(item: string, index) => (
+
+ )}
+
+ }>
+ Loading...
+
+
+
+ )
}
function renderTextSegment(value: string) {
@@ -235,6 +330,98 @@ export default function PromptForm(props: PromptFormProps) {
}
}
+ const getCaretCoordinates = (element: HTMLTextAreaElement): { top: number; left: number } => {
+ const rect = element.getBoundingClientRect()
+ const style = window.getComputedStyle(element)
+ const lineHeight = parseInt(style.lineHeight || "20")
+
+ return {
+ top: rect.top + lineHeight + 5,
+ left: rect.left + 10,
+ }
+ }
+
+ const detectAutocomplete = (value: string, cursorPos: number) => {
+ const beforeCursor = value.slice(0, cursorPos)
+
+ const atMatch = beforeCursor.match(/@(\S*)$/)
+ if (atMatch) {
+ const query = atMatch[1]
+ const startPos = cursorPos - atMatch[0].length
+ const position = getCaretCoordinates(inputRef!)
+
+ setAutocomplete({
+ type: "file",
+ query,
+ position,
+ startPos,
+ })
+ return
+ }
+
+ const slashMatch = value.match(/^\/(\w*)$/)
+ if (slashMatch && cursorPos <= slashMatch[0].length) {
+ const query = slashMatch[1]
+ const position = getCaretCoordinates(inputRef!)
+
+ setAutocomplete({
+ type: "command",
+ query,
+ position,
+ startPos: 0,
+ })
+ return
+ }
+
+ setAutocomplete(null)
+ }
+
+ const handleAutocompleteSelect = (item: AutocompleteItem) => {
+ if (!autocomplete() || !inputRef) return
+
+ const ac = autocomplete()!
+ const currentPrompt = prompt()
+ const before = currentPrompt.slice(0, ac.startPos)
+ const after = currentPrompt.slice(inputRef.selectionStart)
+
+ if (ac.type === "file") {
+ const newPrompt = before + "@" + item.label + " " + after
+ setPrompt(newPrompt)
+
+ local.context.add({
+ type: "file",
+ path: item.value,
+ })
+
+ const newCursorPos = before.length + item.label.length + 2
+ queueMicrotask(() => {
+ if (inputRef) {
+ inputRef.selectionStart = newCursorPos
+ inputRef.selectionEnd = newCursorPos
+ }
+ })
+ } else if (ac.type === "command") {
+ const newPrompt = before + after
+ setPrompt(newPrompt)
+
+ if (item.value === "model") {
+ props.onOpenModelSelect()
+ } else if (item.value === "agent") {
+ props.onOpenAgentSelect()
+ }
+
+ queueMicrotask(() => {
+ if (inputRef) {
+ inputRef.selectionStart = before.length
+ inputRef.selectionEnd = before.length
+ }
+ })
+ }
+
+ setAutocomplete(null)
+ inputRef?.focus()
+ }
+
const handleSubmit = async (event: SubmitEvent) => {
event.preventDefault()
const parts = baseParts()
@@ -258,37 +445,194 @@ export default function PromptForm(props: PromptFormProps) {
await props.onSubmit(currentPrompt)
}
+ const handleDragStart = (event: MouseEvent) => {
+ if (props.docked) return
+ const target = event.target as HTMLElement
+ if (
+ target.closest("textarea") ||
+ target.closest("button") ||
+ target.closest("input") ||
+ target.closest("[role='combobox']") ||
+ target.closest("[role='listbox']")
+ )
+ return
+
+ isDraggingForm = true
+ dragStartPos = { x: event.clientX - currentTranslate.x, y: event.clientY - currentTranslate.y }
+ containerRef.style.cursor = "grabbing"
+ event.preventDefault()
+ }
+
+ const handleDragMove = (event: MouseEvent) => {
+ if (!isDraggingForm) return
+ event.preventDefault()
+
+ if (animationFrameId) return
+
+ animationFrameId = requestAnimationFrame(() => {
+ currentTranslate = {
+ x: event.clientX - dragStartPos.x,
+ y: event.clientY - dragStartPos.y,
+ }
+ containerRef.style.transform = `translate3d(${currentTranslate.x}px, ${currentTranslate.y}px, 0)`
+
+ const windowWidth = window.innerWidth
+ const windowHeight = window.innerHeight
+ const isNearRight = event.clientX > windowWidth * 0.75
+ const isNearBottom = event.clientY > windowHeight * 0.6
+ const nearDockZone = isNearRight && isNearBottom
+
+ wasNearDockZone = nearDockZone
+
+ props.onDragProximity?.({
+ isDragging: true,
+ nearDockZone,
+ x: event.clientX,
+ y: event.clientY,
+ })
+
+ props.onDragProximity?.({
+ isDragging: true,
+ nearDockZone,
+ x: event.clientX,
+ y: event.clientY,
+ })
+
+ animationFrameId = undefined
+ })
+ }
+
+ const handleDragEnd = (event: MouseEvent) => {
+ if (!isDraggingForm) return
+
+ console.log("[PromptForm handleDragEnd]", {
+ clientX: event.clientX,
+ clientY: event.clientY,
+ windowWidth: window.innerWidth,
+ windowHeight: window.innerHeight,
+ wasNearDockZone,
+ })
+
+ isDraggingForm = false
+ containerRef.style.cursor = ""
+
+ if (wasNearDockZone) {
+ console.log("[PromptForm] Was near dock zone, calling onDrop")
+ props.onDrop?.()
+ }
+
+ currentTranslate = { x: 0, y: 0 }
+ containerRef.style.transform = `translate3d(0px, 0px, 0)`
+
+ wasNearDockZone = false
+
+ props.onDragProximity?.({
+ isDragging: false,
+ nearDockZone: false,
+ x: 0,
+ y: 0,
+ })
+ }
+
+ onMount(async () => {
+ document.addEventListener("mousemove", handleDragMove)
+ document.addEventListener("mouseup", handleDragEnd)
+
+ // Only set up Tauri drag/drop in desktop environment
+ if (typeof window !== "undefined" && "__TAURI__" in window) {
+ try {
+ const tauriWindow = getCurrentWindow()
+ if (tauriWindow) {
+ const unlisten = await tauriWindow.onDragDropEvent((e) => {
+ switch (e.payload.type) {
+ case "enter":
+ dragCounter++
+ setIsDragOver(true)
+ break
+ case "over":
+ break
+ case "drop":
+ dragCounter = 0
+ setIsDragOver(false)
+ if (e.payload.paths && e.payload.paths.length > 0) {
+ const current = uploadedFiles()
+ const available = 5 - current.length
+ if (available <= 0) return
+ Promise.all(
+ e.payload.paths.slice(0, available).map(async (path) => {
+ const response = await fetch(`asset://localhost${path}`)
+ const blob = await response.blob()
+ const fileName = path.split("/").pop() || "file"
+ return new File([blob], fileName, { type: blob.type })
+ }),
+ ).then((files) => {
+ setUploadedFiles([...current, ...files])
+ })
+ }
+ break
+ case "leave":
+ dragCounter--
+ if (dragCounter === 0) {
+ setIsDragOver(false)
+ }
+ break
+ }
+ })
+
+ onCleanup(() => {
+ unlisten()
+ })
+ }
+ } catch (error) {
+ console.warn("[PromptForm] Tauri drag/drop not available:", error)
+ }
+ }
+ })
+
onCleanup(() => {
+ document.removeEventListener("mousemove", handleDragMove)
+ document.removeEventListener("mouseup", handleDragEnd)
+ if (animationFrameId) cancelAnimationFrame(animationFrameId)
props.onInputRefChange?.(undefined)
})
return (
)
}
@@ -446,7 +855,7 @@ const ActiveTabContextTag = (props: { file: LocalFile; onClose: () => void }) =>
@@ -462,7 +871,7 @@ const FileTag = (props: { file: FileContext; onClose: () => void }) => (
@@ -479,103 +888,19 @@ const FileTag = (props: { file: FileContext; onClose: () => void }) => (
)
-function PromptDisplayOverlay(props: {
- hasDisplaySegments: boolean
- displaySegments: PromptDisplaySegment[]
- placeholder: string
- renderAttachmentChip: (part: PromptAttachmentPart, placeholder: string) => JSX.Element
- renderTextSegment: (value: string) => JSX.Element | undefined
-}) {
- return (
-
-
{props.placeholder}}>
-
- {(segment) => {
- if (segment.kind === "text") {
- return props.renderTextSegment(segment.value)
- }
- if (segment.kind === "attachment") {
- return props.renderAttachmentChip(segment.part, segment.source)
- }
- return (
-
- {segment.leadingSpace ? ` ${segment.value}` : segment.value}
-
- )
- }}
-
-
+const UploadedFileTag = (props: { file: File; onClose: () => void }) => (
+
+
+
+
+
+
+ {props.file.name}
+ ({(props.file.size / 1024).toFixed(1)}KB)
- )
-}
-
-function MentionSuggestions(props: {
- open: boolean
- anchor: { x: number; y: number }
- loading: boolean
- items: string[]
- activeIndex: number
- onHover: (index: number) => void
- onSelect: (path: string) => void
-}) {
- return (
-
-
-
-
-
-
-
-
-
- Searching…
-
-
-
- No matching files
-
-
- {(path, indexAccessor) => {
- const index = indexAccessor()
- const dir = getDirectory(path)
- return (
-
- )
- }}
-
-
-
-
-
- )
-}
-
-export type {
- PromptAttachmentPart,
- PromptAttachmentSegment,
- PromptContentPart,
- PromptDisplaySegment,
- PromptSubmitValue,
-} from "./prompt-form-helpers"
+
+)
diff --git a/packages/desktop/src/components/resizeable-pane.tsx b/packages/desktop/src/components/resizeable-pane.tsx
index 49ccc4e701..e349a83719 100644
--- a/packages/desktop/src/components/resizeable-pane.tsx
+++ b/packages/desktop/src/components/resizeable-pane.tsx
@@ -195,6 +195,8 @@ export function ResizeablePane(props: ResizeablePaneProps) {
style={{
width: `${width()}%`,
flex: `0 0 ${width()}%`,
+ transform: "translateZ(0)",
+ "will-change": "width",
}}
>
{props.children}
diff --git a/packages/desktop/src/components/select-dialog.tsx b/packages/desktop/src/components/select-dialog.tsx
index 315fe14e5f..7df4cdf5be 100644
--- a/packages/desktop/src/components/select-dialog.tsx
+++ b/packages/desktop/src/components/select-dialog.tsx
@@ -1,4 +1,4 @@
-import { createEffect, Show, For, createMemo, type JSX, createResource } from "solid-js"
+import { createEffect, Show, For, createMemo, type JSX, createResource, onMount } from "solid-js"
import { Dialog } from "@kobalte/core/dialog"
import { Icon, IconButton } from "@/ui"
import { createStore } from "solid-js/store"
@@ -16,6 +16,9 @@ interface SelectDialogProps
{
groupBy?: (x: T) => string
onSelect?: (value: T | undefined) => void
onClose?: () => void
+ onBack?: () => void
+ reduceBlur?: boolean
+ keepOpen?: boolean
}
export function SelectDialog(props: SelectDialogProps) {
@@ -29,7 +32,7 @@ export function SelectDialog(props: SelectDialogProps) {
() => store.filter,
async (filter) => {
const needle = filter.toLowerCase()
- const all = (typeof props.items === "function" ? await props.items(needle) : props.items) || []
+ const all = (typeof props.items === "function" ? await props.items(needle).catch(() => []) : props.items) || []
const result = pipe(
all,
(x) => {
@@ -64,6 +67,10 @@ export function SelectDialog(props: SelectDialogProps) {
list.setActive(props.key(all[0]))
}
+ onMount(() => {
+ resetSelection()
+ })
+
createEffect(() => {
store.filter
scrollRef?.scrollTo(0, 0)
@@ -88,7 +95,9 @@ export function SelectDialog(props: SelectDialogProps) {
const handleSelect = (item: T) => {
props.onSelect?.(item)
- props.onClose?.()
+ if (!props.keepOpen) {
+ props.onClose?.()
+ }
}
const handleKey = (e: KeyboardEvent) => {
@@ -100,7 +109,11 @@ export function SelectDialog(props: SelectDialogProps) {
if (selected) handleSelect(selected)
} else if (e.key === "Escape") {
e.preventDefault()
- props.onClose?.()
+ if (props.onBack) {
+ props.onBack()
+ } else {
+ props.onClose?.()
+ }
} else {
list.onKeyDown(e)
}
@@ -109,25 +122,47 @@ export function SelectDialog(props: SelectDialogProps) {
return (