From eb740b637c2914a6a40f10867a7a67427ba9f17c Mon Sep 17 00:00:00 2001 From: Indosaram Date: Mon, 19 Oct 2026 22:43:27 +0900 Subject: [PATCH 1/2] feat(mobile): add isolated Tauri remote companion for Android and iOS --- .gitignore | 6 + .../coverage-summary.json | 4 + .../mobile-tauri-20261019/phone-390.png | Bin 0 -> 24089 bytes .../mobile-tauri-20261019/phone-landscape.png | Bin 0 -> 25589 bytes mobile/README.md | 61 + mobile/package.json | 14 + mobile/scripts/init-android.mjs | 28 + mobile/scripts/tauri.mjs | 10 + mobile/src-tauri/Cargo.lock | 4314 +++++++++++++++++ mobile/src-tauri/Cargo.toml | 16 + mobile/src-tauri/build.rs | 3 + mobile/src-tauri/icons/icon.png | Bin 0 -> 15265 bytes mobile/src-tauri/src/lib.rs | 8 + mobile/src-tauri/tauri.conf.json | 25 + ui/package.json | 4 +- ui/src/lib/clientRuntime.test.ts | 23 + ui/src/lib/clientRuntime.ts | 8 + ui/src/lib/settingsRuntimeBridge.ts | 3 +- ui/src/lib/tauri.ts | 7 +- ui/src/main.tsx | 5 +- ui/vite.mobile.config.ts | 13 + 21 files changed, 4547 insertions(+), 5 deletions(-) create mode 100644 docs/evidence/mobile-tauri-20261019/coverage-summary.json create mode 100644 docs/evidence/mobile-tauri-20261019/phone-390.png create mode 100644 docs/evidence/mobile-tauri-20261019/phone-landscape.png create mode 100644 mobile/README.md create mode 100644 mobile/package.json create mode 100644 mobile/scripts/init-android.mjs create mode 100644 mobile/scripts/tauri.mjs create mode 100644 mobile/src-tauri/Cargo.lock create mode 100644 mobile/src-tauri/Cargo.toml create mode 100644 mobile/src-tauri/build.rs create mode 100644 mobile/src-tauri/icons/icon.png create mode 100644 mobile/src-tauri/src/lib.rs create mode 100644 mobile/src-tauri/tauri.conf.json create mode 100644 ui/src/lib/clientRuntime.test.ts create mode 100644 ui/src/lib/clientRuntime.ts create mode 100644 ui/vite.mobile.config.ts diff --git a/.gitignore b/.gitignore index 7473fa88a..c24ac6074 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,9 @@ Thumbs.db # Video production belongs in the separate private repository. /videos/ + +# Mobile generated SDK projects and build outputs +ui/dist-mobile/ +mobile/src-tauri/gen/ +!/mobile/src-tauri/Cargo.lock +mobile/src-tauri/.tauri/ diff --git a/docs/evidence/mobile-tauri-20261019/coverage-summary.json b/docs/evidence/mobile-tauri-20261019/coverage-summary.json new file mode 100644 index 000000000..3065ce6ab --- /dev/null +++ b/docs/evidence/mobile-tauri-20261019/coverage-summary.json @@ -0,0 +1,4 @@ +{"total": {"lines":{"total":69,"covered":69,"skipped":0,"pct":100},"statements":{"total":69,"covered":69,"skipped":0,"pct":100},"functions":{"total":11,"covered":11,"skipped":0,"pct":100},"branches":{"total":27,"covered":23,"skipped":0,"pct":85.18},"branchesTrue":{"total":0,"covered":0,"skipped":0,"pct":"Unknown"}} +,"/home/sandbox/code/ferryx-wt/mobile-companion-20261019/ui/src/lib/clientRuntime.ts": {"lines":{"total":6,"covered":6,"skipped":0,"pct":100},"functions":{"total":2,"covered":2,"skipped":0,"pct":100},"statements":{"total":6,"covered":6,"skipped":0,"pct":100},"branches":{"total":3,"covered":3,"skipped":0,"pct":100}} +,"/home/sandbox/code/ferryx-wt/mobile-companion-20261019/ui/src/lib/settingsRuntimeBridge.ts": {"lines":{"total":63,"covered":63,"skipped":0,"pct":100},"functions":{"total":9,"covered":9,"skipped":0,"pct":100},"statements":{"total":63,"covered":63,"skipped":0,"pct":100},"branches":{"total":24,"covered":20,"skipped":0,"pct":83.33}} +} diff --git a/docs/evidence/mobile-tauri-20261019/phone-390.png b/docs/evidence/mobile-tauri-20261019/phone-390.png new file mode 100644 index 0000000000000000000000000000000000000000..09069893fd7ba372c65a5f8e1f59583a257b3798 GIT binary patch literal 24089 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 literal 0 HcmV?d00001 diff --git a/docs/evidence/mobile-tauri-20261019/phone-landscape.png b/docs/evidence/mobile-tauri-20261019/phone-landscape.png new file mode 100644 index 0000000000000000000000000000000000000000..ab0f57b1f29ede642de417545ad3727796effa70 GIT binary patch literal 25589 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 literal 0 HcmV?d00001 diff --git a/mobile/README.md b/mobile/README.md new file mode 100644 index 000000000..17f5612f3 --- /dev/null +++ b/mobile/README.md @@ -0,0 +1,61 @@ +# Ferryx mobile companion (Android + iOS) + +A separate Tauri v2 shell embeds the existing RemoteApp bundle. It does not run +PTYs, the desktop daemon, native GPU terminals, or desktop filesystem commands. +Use an existing Ferryx desktop/relay to sign in and control remote sessions. +No native IPC capabilities or plugins are granted. Production network access is +HTTPS/WSS only; insecure LAN HTTP hosts are intentionally not supported yet. + +## Build + +Install Node, Rust, and the [Tauri prerequisites](https://v2.tauri.app/start/prerequisites/). +From the repository root install dependencies (`npm install`, then +`npm --prefix ui install`). Mobile uses the root Tauri CLI. + +Android requires JDK 17, SDK platforms 35 and 36 (the Tauri runtime uses 36), +Build Tools 34/35, NDK 27.2.12479018, and JAVA_HOME/ANDROID_HOME/NDK_HOME. + +```sh +cd mobile +npm run android:init +npm run android:build -- --debug --target aarch64 --apk +``` + +The init wrapper pins Gradle 8.9 and AGP 8.7.3 instead of unavailable preview +SDK defaults, and fixes the generated Node callback path. The Tauri runtime's +compileSdk 36 emits an AGP compatibility warning. Generated SDK projects are +ignored and recreated locally. Do not rerun raw `tauri android init` afterward. + +On macOS with Xcode and iOS Rust targets: + +```sh +cd mobile +npm run ios:init +npm run ios:dev +# Distribution also needs the owner's Apple team/signing setup. +npm run ios:build +``` + +iOS is configured, NOT compiled or run in this change. No Apple team or signing +identity is guessed, and no App Store/TestFlight deployment is performed. + +Frontend-only validation: `npm --prefix ui run build:mobile`. +`npm --prefix ui run build` continues to build the desktop/web UI separately. + +## QA status (2026-10-19) + +- Mobile frontend and existing desktop frontend builds pass. +- ARM64 Android Rust native library cross-compiles successfully. +- APK packaging not yet verified: Gradle compilation exceeds this environment's + bounded build attempts. No APK/device-run claim is made. +- 47 targeted tests pass (account sign-in/session, remote preferences, runtime + routing, settings). Runtime routing: 100% statements/branches/functions/lines. + Settings bridge: 100% statements/functions/lines, 83.33% branches. These are + focused-module numbers, not whole-project coverage. +- Production mobile bundle, with native internals present: login screen renders + without desktop IPC or JS errors at 360x800, 390x844 and 844x390, no horizontal + overflow. Landscape requires normal vertical scrolling. +- Broader remote test sweep was interrupted by the execution budget; not green. +- No real phone/emulator, keyboard/IME, safe-area hardware, background/resume, + authenticated live relay, push notifications or iOS/Xcode QA has been done. +- Bundle-size warnings remain. This is a draft companion, not store-ready. diff --git a/mobile/package.json b/mobile/package.json new file mode 100644 index 000000000..01e7b9782 --- /dev/null +++ b/mobile/package.json @@ -0,0 +1,14 @@ +{ + "name": "ferryx-mobile", + "version": "0.1.0", + "private": true, + "scripts": { + "tauri": "node scripts/tauri.mjs", + "android:init": "node scripts/init-android.mjs", + "android:dev": "node scripts/tauri.mjs android dev", + "android:build": "node scripts/tauri.mjs android build", + "ios:init": "node scripts/tauri.mjs ios init", + "ios:dev": "node scripts/tauri.mjs ios dev", + "ios:build": "node scripts/tauri.mjs ios build" + } +} diff --git a/mobile/scripts/init-android.mjs b/mobile/scripts/init-android.mjs new file mode 100644 index 000000000..1b74d3373 --- /dev/null +++ b/mobile/scripts/init-android.mjs @@ -0,0 +1,28 @@ +import { execFileSync } from "node:child_process"; +import { readFileSync, writeFileSync } from "node:fs"; +import { fileURLToPath } from "node:url"; +import path from "node:path"; + +const mobile = fileURLToPath(new URL("..", import.meta.url)); +const cli = path.join(mobile, "../node_modules/@tauri-apps/cli/tauri.js"); +execFileSync(process.execPath, [cli, "android", "init", "--ci"], { cwd: mobile, stdio: "inherit" }); +// The CLI's generated templates can drift independently of this source tree. +// Pin to the available Android 35 toolchain instead of silently requiring preview SDKs. +const gen = path.join(mobile, "src-tauri/gen/android"); +function patch(file, transform) { + const target = path.join(gen, file); + writeFileSync(target, transform(readFileSync(target, "utf8"))); +} +patch("build.gradle.kts", s => s.replace(/com.android.tools.build:gradle:[^"\s]+/, "com.android.tools.build:gradle:8.7.3")); +patch("buildSrc/build.gradle.kts", s => s.replace(/com.android.tools.build:gradle:[^"\s]+/, "com.android.tools.build:gradle:8.7.3")); +patch("gradle/wrapper/gradle-wrapper.properties", s => s.replace(/gradle-[\d.]+-bin.zip/, "gradle-8.9-bin.zip")); +patch("app/build.gradle.kts", s => s + .replace(/compileSdk = \d+/, "compileSdk = 35") + .replace(/targetSdk = \d+/, "targetSdk = 35") + .replace(/optimization\s*\{\s*enable = true\s*\}/, "isMinifyEnabled = true") + .replace(/lifecycle-process:[\d.]+/, "lifecycle-process:2.8.7")); +patch("gradle.properties", s => s + .replace(/^org.gradle.jvmargs=.*$/m, "org.gradle.jvmargs=-Xmx768m -XX:MaxMetaspaceSize=384m") + + "\norg.gradle.workers.max=1\nkotlin.compiler.execution.strategy=in-process\norg.gradle.daemon=false\n"); + +patch("buildSrc/src/main/java/com/ferryx/mobile/kotlin/BuildTask.kt", s => s.replace('listOf("tauri", "android", "android-studio-script")', `listOf("${cli.replaceAll("\\", "/")}", "android", "android-studio-script")`)); diff --git a/mobile/scripts/tauri.mjs b/mobile/scripts/tauri.mjs new file mode 100644 index 000000000..976b25cdf --- /dev/null +++ b/mobile/scripts/tauri.mjs @@ -0,0 +1,10 @@ +import { spawnSync } from "node:child_process"; +import { fileURLToPath } from "node:url"; +// Use an absolute CLI path so the generated Gradle callback works from src-tauri. +const cli = fileURLToPath(new URL("../../node_modules/@tauri-apps/cli/tauri.js", import.meta.url)); +const result = spawnSync(process.execPath, [cli, ...process.argv.slice(2)], { + cwd: fileURLToPath(new URL("..", import.meta.url)), + stdio: "inherit", +}); +if (result.error) throw result.error; +process.exit(result.status ?? 1); diff --git a/mobile/src-tauri/Cargo.lock b/mobile/src-tauri/Cargo.lock new file mode 100644 index 000000000..e94fe4c88 --- /dev/null +++ b/mobile/src-tauri/Cargo.lock @@ -0,0 +1,4314 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "aho-corasick" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2fb6cfd47bf496ff64095c20eaba0c201404ee38714d4142fcfa1dc334fcc7a" + +[[package]] +name = "alloc-stdlib" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5c1865780388bfa186411ab5f247819487fc4864c6e9c3106611fa347586e1" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "android_system_properties" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" + +[[package]] +name = "atk" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241b621213072e993be4f6f3a9e4b45f65b7e6faad43001be957184b7bb1824b" +dependencies = [ + "atk-sys", + "glib", + "libc", +] + +[[package]] +name = "atk-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e48b684b0ca77d2bbadeef17424c2ea3c897d44d566a1617e7e8f30614d086" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" + +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" +dependencies = [ + "serde_core", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" +dependencies = [ + "objc2", +] + +[[package]] +name = "brotli" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8b851b75c23ca7873623d612fe49bd1989aeb03d08fb9432187eb253d3d4c6b" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "6.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "941cd9bd4ddab83cb46fa5a2d428f1c857b24ac78cb876cf7beb710840934bd7" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "bytemuck" +version = "1.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" +dependencies = [ + "serde", +] + +[[package]] +name = "cairo-rs" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" +dependencies = [ + "bitflags 2.13.2", + "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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbad30e4b4c14a39e3cc8aed085a12a327257c316619c93581e017bc52be591" +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.21", +] + +[[package]] +name = "cargo_toml" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82f4b26e751e711a5302649417f2da046dce6391b2ea30a4820f37462314f0b9" +dependencies = [ + "semver", + "serde", + "toml 1.1.8+spec-1.1.0", +] + +[[package]] +name = "cc" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877bf67ac8e52449eb2f9e98a344ea163beb70dd1f9eebe3cc5357dcfeaee4df" +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.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a347dcabdae9c31b0825fd6a8bed285ec9c2acb89c47827126d52fa4f59cece3" +dependencies = [ + "fnv", + "uuid", + "web-time", +] + +[[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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" + +[[package]] +name = "chrono" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" +dependencies = [ + "iana-time-zone", + "num-traits", + "serde", + "windows-link", +] + +[[package]] +name = "combine" +version = "4.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4356eba6976435498d05a311ee9fc486da3bc81c200d3f0d7dd9703b41913f92" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "cookie" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a373e3602691c3cdea496d2f0ee5935151e6168fe87739483c463db1b2f2f87" +dependencies = [ + "time", + "version_check", +] + +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core-graphics" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "064badf302c3194842cf2c5d61f56cc88e54a759313879cdf03abdd27d0c3b97" +dependencies = [ + "bitflags 2.13.2", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" +dependencies = [ + "bitflags 2.13.2", + "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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01a7799fd6b852db0e61728dde9a204c423b44d689dbd432522543614b490e78" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98b0cc327b5bc766e7fda9c9260cc0fa81b43a8e240440422dff70788e3f9ef1" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31eee39dddec8330830986fcd7625edb5a24ec90ea038215273bbc3adb08ac6" + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "cssparser" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c9cdaae01d5ed7882b04d795e7f752f46ff52d2fa3b50a20d28c464510bba98" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa", + "phf", + "smallvec", +] + +[[package]] +name = "cssparser-macros" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d045de693cb712d0b22c6a64be5b953f67b3ce00ab5ad3dd5d8b441886ab8e1a" +dependencies = [ + "quote", + "syn 3.0.9", +] + +[[package]] +name = "ctor" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914a755b7c2d4af2bdcff7ce1739e2db9a1b81a9b07123d8015786ae03c0980d" + +[[package]] +name = "darling" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed17f5901b6630b993ca003def43f2f8ef4014fc13b047b57aad617ff32bc2ec" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6837e2cf7485aaae18f86181d2f0e9a7ed297a025e220aeabf63fdebd3a2ddff" +dependencies = [ + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 3.0.9", +] + +[[package]] +name = "darling_macro" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ac7135c3ef02b2f7833bbeb1be5ba7f966dcde8a87c6b87f65a778d71a02785" +dependencies = [ + "darling_core", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "dbus" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab69f03cc8c4340c9c8e315114e1658e6775a9b16a04357973aa21cec22b32e" +dependencies = [ + "libc", + "libdbus-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "defmt" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a0795ac740cb54d7b3775c9c17345f6aaecf884c01733b39d6017738e0e3e1" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "840bb056bd99c495c9188198a258ab787c79f306d864db3e6e8451442d6d8366" +dependencies = [ + "defmt-parser", + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "defmt-parser" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71958f69fb2de856c5dd51ac9377e986ca1aa5919f931bf5395a807277f889a0" +dependencies = [ + "thiserror 2.0.21", +] + +[[package]] +name = "deranged" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e9de72ce2ad1f90dc62fa25f0f430ef85eb4b0d8fa0be4f30373bc40a21d28e" +dependencies = [ + "serde_core", +] + +[[package]] +name = "derive_more" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.119", +] + +[[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 = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d57d423b3c82e89b9a24ca3091fee61f456a26edbd28d26c65906f4bc1dcd8f" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.61.2", +] + +[[package]] +name = "dispatch2" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" +dependencies = [ + "bitflags 2.13.2", + "block2", + "libc", + "objc2", +] + +[[package]] +name = "displaydoc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "dlopen2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e2c5bd4158e66d1e215c49b837e11d62f3267b30c92f1d171c4d3105e3dc4d4" +dependencies = [ + "dlopen2_derive", + "libc", + "once_cell", + "winapi", +] + +[[package]] +name = "dlopen2_derive" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fbbb781877580993a8707ec48672673ec7b81eeba04cfd2310bd28c08e47c8f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "dom_query" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fac5fca71e65e94cc718a6e2af65d6e0f9c6027751c2aa562fbb5087fda639bc" +dependencies = [ + "bit-set", + "cssparser", + "foldhash", + "html5ever", + "precomputed-hash", + "selectors", + "tendril", +] + +[[package]] +name = "dpi" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" +dependencies = [ + "serde", +] + +[[package]] +name = "dtoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c3cf4824e2d5f025c7b531afcb2325364084a16806f6d47fbc1f5fbd9960590" + +[[package]] +name = "dtoa-short" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" +dependencies = [ + "dtoa", +] + +[[package]] +name = "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.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6168487b5e7eb2673e6efe1200b1848016e436a6ca0b8031bf04bd9d493a249f" +dependencies = [ + "cc", + "memchr", + "rustc_version", + "toml 1.1.8+spec-1.1.0", + "vswhom", + "winreg", +] + +[[package]] +name = "embed_plist" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" + +[[package]] +name = "equivalent" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00d174d5400e5e8fd687ad1049e2f578285fa914201b1af7e8b112a4546bd826" + +[[package]] +name = "erased-serde" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2add8a07dd6a8d93ff627029c51de145e12686fbc36ecb298ac22e74cf02dec" +dependencies = [ + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "fastrand" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" + +[[package]] +name = "fdeflate" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "ferryx-mobile" +version = "0.1.0" +dependencies = [ + "tauri", + "tauri-build", +] + +[[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.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c66915cc5391097de7a2b0b972e8505aa33c0df401fd3a6811dbdb32881ba48" + +[[package]] +name = "flate2" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e634e2e0ebac1ee034020da1ca582e17ffe4e0f5e985823721e168928136dcb" +dependencies = [ + "crc32fast", + "miniz_oxide 0.9.1", + "zlib-rs", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea5190182e6915eb873ddbc16e23b711b6eb1f9c00a0d0a3a91b5f6228475225" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" + +[[package]] +name = "futures-executor" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" + +[[package]] +name = "futures-macro" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "futures-sink" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" + +[[package]] +name = "futures-task" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" + +[[package]] +name = "futures-util" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +dependencies = [ + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", +] + +[[package]] +name = "gdk" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9f245958c627ac99d8e529166f9823fb3b838d1d41fd2b297af3075093c2691" +dependencies = [ + "cairo-rs", + "gdk-pixbuf", + "gdk-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50e1f5f1b0bfb830d6ccc8066d18db35c487b1b2b1e8589b5dfe9f07e8defaec" +dependencies = [ + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", + "once_cell", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9839ea644ed9c97a34d129ad56d38a25e6756f99f3a88e15cd39c20629caf7" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gdk-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c2d13f38594ac1e66619e188c6d5a1adb98d11b2fcf7894fc416ad76aa2f3f7" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gdkwayland-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "140071d506d223f7572b9f09b5e155afbd77428cd5cc7af8f2694c41d98dfe69" +dependencies = [ + "gdk-sys", + "glib-sys", + "gobject-sys", + "libc", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gdkx11" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3caa00e14351bebbc8183b3c36690327eb77c49abc2268dd4bd36b856db3fbfe" +dependencies = [ + "gdk", + "gdkx11-sys", + "gio", + "glib", + "libc", + "x11", +] + +[[package]] +name = "gdkx11-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e7445fe01ac26f11601db260dd8608fe172514eb63b3b5e261ea6b0f4428d" +dependencies = [ + "gdk-sys", + "glib-sys", + "libc", + "system-deps", + "x11", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi 5.3.0", + "wasip2", +] + +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", +] + +[[package]] +name = "gio" +version = "0.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fc8f532f87b79cbc51a79748f16a6828fb784be93145a322fa14d06d354c73" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys", + "glib", + "libc", + "once_cell", + "pin-project-lite", + "smallvec", + "thiserror 1.0.69", +] + +[[package]] +name = "gio-sys" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37566df850baf5e4cb0dfb78af2e4b9898d817ed9263d1090a2df958c64737d2" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "winapi", +] + +[[package]] +name = "glib" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5" +dependencies = [ + "bitflags 2.13.2", + "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.119", +] + +[[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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" + +[[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.119", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "html5ever" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46a1761807faccc9a19e86944bbf40610014066306f96edcdedc2fb714bcb7b8" +dependencies = [ + "log", + "markup5ever", +] + +[[package]] +name = "http" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23169fe34a5fbcdd3f3862e78fb9b6fccd5f02a6dc6f732547005d45631ce71c" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "hyper" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c3e324da4c95177d6291d4c8730197c0d1822f8a9766814a4a44fa5ab797c9c" +dependencies = [ + "atomic-waker", + "bytes", + "futures-core", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-util" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddc03d96684f9226b8a787cdb71488417b53ab5ea8fdb1dac946cb9431cc8bff" +dependencies = [ + "base64 0.23.1", + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "httparse", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ico" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e795dff5605e0f04bff85ca41b51a96b83e80b281e96231bcaaf1ac35103371" +dependencies = [ + "byteorder", + "png 0.17.16", +] + +[[package]] +name = "icu_collections" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513" +dependencies = [ + "displaydoc", + "potential_utf", + "utf8_iter", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" + +[[package]] +name = "icu_properties" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" + +[[package]] +name = "icu_provider" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", + "serde", + "serde_core", +] + +[[package]] +name = "infer" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4200d433cbd5178df7797c9c2e75b348b728e39631cf14520d1e2fc424201f4" +dependencies = [ + "cfb", +] + +[[package]] +name = "ipnet" +version = "2.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791930b43c0d5973160d90a8f3894509f2b273430f5c5c73b668636d0287c5c0" + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "javascriptcore-rs" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca5671e9ffce8ffba57afc24070e906da7fc4b1ba66f2cabebf61bf2ea257fcc" +dependencies = [ + "bitflags 1.3.2", + "glib", + "javascriptcore-rs-sys", +] + +[[package]] +name = "javascriptcore-rs-sys" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1be78d14ffa4b75b66df31840478fef72b51f8c2465d4ca7c194da9f7a5124" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "jiff" +version = "0.2.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b005715dcbeb0089a3c0dab99f2ff1cc3b2525323552703d648585d342a383" +dependencies = [ + "defmt", + "jiff-core", + "jiff-static", + "jiff-tzdb-platform", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", + "windows-link", +] + +[[package]] +name = "jiff-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e52fe76043ccecc9005d2305ebaadf7d7fc0cc89ca6baa10a94d6bc68c7128c" +dependencies = [ + "defmt", + "log", +] + +[[package]] +name = "jiff-static" +version = "0.2.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cc9817253cf7c7ee4684451bd327e88d6f3658014e54a29198625590650695c" +dependencies = [ + "jiff-core", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "jiff-tzdb" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa8377070c6bae868759445e5a77f66d84f0b72f3a054bfb00e6d038b8282da7" + +[[package]] +name = "jiff-tzdb-platform" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" +dependencies = [ + "jiff-tzdb", +] + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys 0.3.1", + "log", + "thiserror 1.0.69", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" +dependencies = [ + "jni-sys 0.4.1", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn 2.0.119", +] + +[[package]] +name = "js-sys" +version = "0.3.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7883d941dae510fb2d978fc3fe018c71c9e2892fd38854de3e8b92c2e5ad9cc5" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "json-patch" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7421438de105a0827e44fadd05377727847d717c80ce29a229f85fd04c427b72" +dependencies = [ + "jsonptr", + "serde", + "serde_json", + "thiserror 2.0.21", +] + +[[package]] +name = "jsonptr" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5a3cc660ba5d72bce0b3bb295bf20847ccbb40fd423f3f05b61273672e561fe" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "keyboard-types" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fbe853b403ae61a04233030ae8a79d94975281ed9770a1f9e246732b534b28d" +dependencies = [ + "bitflags 2.13.2", + "serde", +] + +[[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.191" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a" + +[[package]] +name = "libdbus-sys" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "328c4789d42200f1eeec05bd86c9c13c7f091d2ba9a6ea35acdf51f31bc0f043" +dependencies = [ + "pkg-config", +] + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libredox" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61ff90caf6077a803a240f62fdbe88645a890bbca49ef8174c3cb0404362171d" +dependencies = [ + "libc", +] + +[[package]] +name = "litemap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" + +[[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.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" + +[[package]] +name = "markup5ever" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7122d987ec5f704ee56f6e5b41a7d93722e9aae27ae07cafa4036c4d3f9757de" +dependencies = [ + "log", + "tendril", + "web_atoms", +] + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[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 = "miniz_oxide" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63fbc4a50860e98e7b2aa7804ded1db5cbc3aff9193adaff57a6931bf7c4b4c" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "1.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1788edb87fdc09c7e26304471e2f5be8cdefb1b6930d6e3985fc02ff53bf86ee" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + +[[package]] +name = "muda" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cca139e57da4383727f189e43e66e84fa372347027fc996f9f1a007ec0a37996" +dependencies = [ + "crossbeam-channel", + "dpi", + "gtk", + "keyboard-types", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", + "once_cell", + "png 0.18.1", + "serde", + "thiserror 2.0.21", + "windows-sys 0.61.2", +] + +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.13.2", + "jni-sys 0.3.1", + "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 0.3.1", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "num-conv" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" +dependencies = [ + "proc-macro-crate 3.5.0", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "objc2" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08849bbd4767dfae9457696856ae1c84fe4e0281bbe4a7abff2d0e06fb7981f8" +dependencies = [ + "objc2-encode", + "objc2-exception-helper", +] + +[[package]] +name = "objc2-app-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" +dependencies = [ + "bitflags 2.13.2", + "block2", + "objc2", + "objc2-core-foundation", + "objc2-foundation", + "objc2-quartz-core", +] + +[[package]] +name = "objc2-cloud-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" +dependencies = [ + "bitflags 2.13.2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-data" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" +dependencies = [ + "bitflags 2.13.2", + "dispatch2", + "objc2", +] + +[[package]] +name = "objc2-core-graphics" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" +dependencies = [ + "bitflags 2.13.2", + "dispatch2", + "objc2", + "objc2-core-foundation", + "objc2-io-surface", +] + +[[package]] +name = "objc2-core-image" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-location" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca347214e24bc973fc025fd0d36ebb179ff30536ed1f80252706db19ee452009" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-text" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" +dependencies = [ + "bitflags 2.13.2", + "objc2", + "objc2-core-foundation", + "objc2-core-graphics", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "objc2-exception-helper" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7a1c5fbb72d7735b076bb47b578523aedc40f3c439bea6dfd595c089d79d98a" +dependencies = [ + "cc", +] + +[[package]] +name = "objc2-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" +dependencies = [ + "bitflags 2.13.2", + "block2", + "objc2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-io-surface" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" +dependencies = [ + "bitflags 2.13.2", + "objc2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" +dependencies = [ + "bitflags 2.13.2", + "objc2", + "objc2-core-foundation", + "objc2-foundation", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" +dependencies = [ + "bitflags 2.13.2", + "block2", + "objc2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-core-image", + "objc2-core-location", + "objc2-core-text", + "objc2-foundation", + "objc2-quartz-core", + "objc2-user-notifications", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9df9128cbbfef73cda168416ccf7f837b62737d748333bfe9ab71c245d76613e" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-web-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2e5aaab980c433cf470df9d7af96a7b46a9d892d521a2cbbb2f8a4c16751e7f" +dependencies = [ + "bitflags 2.13.2", + "block2", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "pango" +version = "0.18.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ca27ec1eb0457ab26f3036ea52229edbdb74dee1edd29063f5b9b010e7ebee4" +dependencies = [ + "gio", + "glib", + "libc", + "once_cell", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436737e391a843e5933d6d9aa102cb126d501e815b83601365a948a518555dc5" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "phf" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" +dependencies = [ + "phf_macros", + "phf_shared", + "serde", +] + +[[package]] +name = "phf_codegen" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49aa7f9d80421bca176ca8dbfebe668cc7a2684708594ec9f3c0db0805d5d6e1" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" +dependencies = [ + "fastrand", + "phf_shared", +] + +[[package]] +name = "phf_macros" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "phf_shared" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pkg-config" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" + +[[package]] +name = "plist" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896bade328c13f7042a297ea5ac5b0951f6cf989dea5f32c2fd98da398195cb" +dependencies = [ + "base64 0.23.1", + "indexmap 2.14.2", + "quick-xml", + "serde", + "time", +] + +[[package]] +name = "png" +version = "0.17.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide 0.8.9", +] + +[[package]] +name = "png" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" +dependencies = [ + "bitflags 2.13.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide 0.8.9", +] + +[[package]] +name = "portable-atomic" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" + +[[package]] +name = "portable-atomic-util" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "potential_utf" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661" +dependencies = [ + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a6394b9e965e73d0a289ee54f589087e2c676aedf60885baf52c76b771e4958" + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" +dependencies = [ + "toml_datetime 0.6.3", + "toml_edit 0.20.2", +] + +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit 0.25.17+spec-1.1.0", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quick-xml" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41b1177fdf999d2321d3fb46ff47159d9c1fb9ad66a4879f8c50a0b504615e9b" +dependencies = [ + "memchr", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.13.2", +] + +[[package]] +name = "redox_users" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60dc65c0ff1a7ae1294b0c67b9f14baf70b644404010370171787bfac1038fc0" +dependencies = [ + "libredox", + "thiserror 2.0.21", +] + +[[package]] +name = "ref-cast" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e440fb4e4b4147295338efb76001ab9e4efc0e5839df2c47fc5ac2381d365c3" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecd8964f8453721699a1ed72037b0db49ce2f5a5138486ee89bed6f67cdf3a" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "regex" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + +[[package]] +name = "reqwest" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16a1cfa75cc186dd73d5818e510e042e40927bccc9c236b061cea97e1eb08029" +dependencies = [ + "base64 0.23.1", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "sync_wrapper", + "tokio", + "tokio-util", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", +] + +[[package]] +name = "rustc-hash" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schemars" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" +dependencies = [ + "dyn-clone", + "indexmap 1.9.3", + "schemars_derive", + "serde", + "serde_json", + "url", + "uuid", +] + +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab508826f74a77ca9d5aba6ff19b522583ee3eaf28a19384ff3d0e5835fadf6e" +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.119", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "selectors" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8adfa1c298912827b8a28b223b3b874357397ae706e6190acd9bf28cee99114d" +dependencies = [ + "bitflags 2.13.2", + "cssparser", + "derive_more", + "log", + "new_debug_unreachable", + "phf", + "phf_codegen", + "precomputed-hash", + "rustc-hash", + "servo_arc", + "smallvec", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +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.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[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.119", +] + +[[package]] +name = "serde_json" +version = "1.0.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e9cc8b1b85264074fbcc02a88680c4096b1e47df8f739dceb03bf482f04bd6" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_repr" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d3b1629de253c70a0508c3899572da79ca359fdab27c7920ff00406df418906" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_spanned" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7523beb55eece201a2356bee0bbca0d1ab466c14c07703b2e0ee6d42cb0c2c" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_with" +version = "3.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df9adc193c780ef8f159aee8b61e2d5801aaa555e6eb0947fe45530ec506296f" +dependencies = [ + "base64 0.23.1", + "bs58", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.14.2", + "jiff", + "schemars 0.9.0", + "schemars 1.2.3", + "serde_core", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e17bbc68e28663bbbb90df47e058aa7eda4fb445b89fe70457bb94fbccf6e49" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[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.119", +] + +[[package]] +name = "servo_arc" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "170fb83ab34de17dc69aa7c67482b22218ddb85da56546f9bd6b929e32a05930" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "simd-adler32" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" + +[[package]] +name = "siphasher" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33f4fe9184a62d842c9ef383018f3306d8ba224fd9d836f56d7288308847c256" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b3dc8af474f516a851ff4bd12db780f948b9250ad37211e4eec0bccea54e01b" + +[[package]] +name = "socket2" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "softbuffer" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aac18da81ebbf05109ab275b157c22a653bb3c12cf884450179942f81bcbf6c3" +dependencies = [ + "bytemuck", + "js-sys", + "ndk", + "objc2", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation", + "objc2-quartz-core", + "raw-window-handle", + "redox_syscall", + "tracing", + "wasm-bindgen", + "web-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "soup3" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "471f924a40f31251afc77450e781cb26d55c0b650842efafc9c6cbd2f7cc4f9f" +dependencies = [ + "futures-channel", + "gio", + "glib", + "libc", + "soup3-sys", +] + +[[package]] +name = "soup3-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebe8950a680a12f24f15ebe1bf70db7af98ad242d9db43596ad3108aab86c27" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "static_vcruntime" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff7589a1859b09232522bb9edf076ca7fcf14ded96685d3fa629db73023ffbb7" + +[[package]] +name = "string_cache" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18596f8c785a729f2819c0f6a7eae6ebeebdfffbfe4214ae6b087f690e31901" +dependencies = [ + "new_debug_unreachable", + "parking_lot", + "phf_shared", + "precomputed-hash", +] + +[[package]] +name = "string_cache_codegen" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "585635e46db231059f76c5849798146164652513eb9e8ab2685939dd90f29b69" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "swift-rs" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cefd87076fd385308ee4aff597256c902f1fbb4d031de1558efc12f8ffefadd9" +dependencies = [ + "base64 0.21.7", + "serde", + "serde_json", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b" +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.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "901704edd0dfe137f1987838ee4f259e4e063c31371bdb423f7ae38ec6f77f02" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[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.37.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f37f381f4e048e6cdf038b5705f8cf14ad108279d46eb968140a7b291aba9400" +dependencies = [ + "bitflags 2.13.2", + "block2", + "core-foundation", + "core-graphics", + "crossbeam-channel", + "dbus", + "dispatch2", + "dlopen2", + "dpi", + "gdkwayland-sys", + "gdkx11-sys", + "gtk", + "jni", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "objc2-ui-kit", + "parking_lot", + "percent-encoding", + "raw-window-handle", + "tao-macros", + "unicode-segmentation", + "url", + "windows", + "windows-core", + "windows-version", + "x11-dl", +] + +[[package]] +name = "tao-macros" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f7eeb6d99155545da6150a1795945f16ac9c178deb2a5f2e74d776107bd5849" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[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.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f316751027fc2644221d1a448564d519efb07067fda584879d9cda966391d212" +dependencies = [ + "anyhow", + "bytes", + "cookie", + "dirs", + "dunce", + "embed_plist", + "getrandom 0.3.4", + "glob", + "gtk", + "heck 0.5.0", + "http", + "jni", + "libc", + "log", + "mime", + "muda", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "objc2-ui-kit", + "objc2-web-kit", + "percent-encoding", + "plist", + "raw-window-handle", + "reqwest", + "serde", + "serde_json", + "serde_repr", + "serialize-to-javascript", + "swift-rs", + "tauri-build", + "tauri-macros", + "tauri-runtime", + "tauri-runtime-wry", + "tauri-utils", + "thiserror 2.0.21", + "tokio", + "tray-icon", + "url", + "webkit2gtk", + "webview2-com", + "window-vibrancy", + "windows", +] + +[[package]] +name = "tauri-build" +version = "2.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "641dd5fd297c99ab92717b0428cca5b9c6f960b2ac96ca131b3eebc9d70b8ddc" +dependencies = [ + "anyhow", + "cargo_toml", + "dirs", + "glob", + "heck 0.5.0", + "json-patch", + "schemars 0.8.22", + "semver", + "serde", + "serde_json", + "static_vcruntime", + "strsim", + "tauri-utils", + "tauri-winres", + "walkdir", +] + +[[package]] +name = "tauri-codegen" +version = "2.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6585c5b536c00f039d12ce70a9755172d5423bbcfd3969863baa70314c3e02f" +dependencies = [ + "base64 0.23.1", + "brotli", + "ico", + "json-patch", + "plist", + "png 0.18.1", + "proc-macro2", + "quote", + "semver", + "serde", + "serde_json", + "sha2", + "syn 2.0.119", + "tauri-utils", + "thiserror 2.0.21", + "time", + "url", + "uuid", + "walkdir", +] + +[[package]] +name = "tauri-macros" +version = "2.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e83a0cfa1bae376e8fbbdc0b1692707aed50cd6072ce85cae4789af5d6c19f" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.119", + "tauri-codegen", + "tauri-utils", +] + +[[package]] +name = "tauri-runtime" +version = "2.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c55766d99cea69055904d1735b93c2049302b2e09effd462120deb5581d78e9" +dependencies = [ + "cookie", + "dpi", + "gtk", + "http", + "jni", + "objc2", + "objc2-ui-kit", + "objc2-web-kit", + "raw-window-handle", + "serde", + "serde_json", + "tauri-utils", + "thiserror 2.0.21", + "url", + "webkit2gtk", + "webview2-com", + "windows", +] + +[[package]] +name = "tauri-runtime-wry" +version = "2.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d61892587aea2a85245bcaec98c6fe46268874c0a0deae5535fb71ca7b93eae" +dependencies = [ + "gtk", + "http", + "jni", + "log", + "objc2", + "objc2-app-kit", + "once_cell", + "percent-encoding", + "raw-window-handle", + "softbuffer", + "tao", + "tauri-runtime", + "tauri-utils", + "url", + "webkit2gtk", + "webview2-com", + "windows", + "wry", +] + +[[package]] +name = "tauri-utils" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "362ab21cd4cc713f2a02b1a9b5688198b1541cfb6907c4281e9190e0f0ef4aa3" +dependencies = [ + "anyhow", + "brotli", + "cargo_metadata", + "ctor", + "dom_query", + "dunce", + "glob", + "http", + "infer", + "json-patch", + "log", + "memchr", + "phf", + "plist", + "proc-macro2", + "quote", + "regex", + "schemars 0.8.22", + "semver", + "serde", + "serde-untagged", + "serde_json", + "serde_with", + "swift-rs", + "thiserror 2.0.21", + "toml 1.1.8+spec-1.1.0", + "url", + "urlpattern", + "uuid", + "walkdir", +] + +[[package]] +name = "tauri-winres" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc65d45c68858bfe420dd29e834b5d15dbecf8a07a8a16cf4d532c7b1f69d4b6" +dependencies = [ + "dunce", + "embed-resource", + "toml 1.1.8+spec-1.1.0", +] + +[[package]] +name = "tendril" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fed54709c5b3a53d09bb1c113ea4f5ceafd1e772ddcb0030a82e1d56c087b08" +dependencies = [ + "new_debug_unreachable", +] + +[[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.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09e52cb86a36cede5cb101bf8908837b3e4c6e5e59fe7fd85c23fb56200d189e" +dependencies = [ + "thiserror-impl 2.0.21", +] + +[[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.119", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe5197923287db20a58125f0bc85c062f7f2c892de97b18c356f9efb14b28524" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "time" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde_core", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" + +[[package]] +name = "time-macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinystr" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e27c91459209c2986af3dcf603a5a74a4368754ce37414f59acc971167f643" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3ca314f692efd6c868f8408f53fe444634a845f96c028b97d35f6a1f79f0ee" + +[[package]] +name = "tokio" +version = "1.53.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce3335fa71841cda333a58d7615b03901380ecf09d59b3296d21f8bbac0dde4e" +dependencies = [ + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-util" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e464cf451ba96ebfc6f9b6542f17ee8b8956e33f1e40d9690624e59d7a7f8a4b" +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 = "1.1.8+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20489e00e4d8741d6be680764cc12e270655e375a20d1011e844a9c3379e678d" +dependencies = [ + "indexmap 2.14.2", + "serde_core", + "serde_spanned 1.1.2", + "toml_datetime 1.1.2+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 1.0.4", +] + +[[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 = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b86d767906c6c42421dcba507eb9d203e779497710a47782a224bb871653053" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.14.2", + "toml_datetime 0.6.3", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +dependencies = [ + "indexmap 2.14.2", + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.3", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.25.17+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3641d5bbb5349a79e1020a242d251efbc546ad8048d133958323ce9c40a9c9c" +dependencies = [ + "indexmap 2.14.2", + "toml_datetime 1.1.2+spec-1.1.0", + "toml_parser", + "winnow 1.0.4", +] + +[[package]] +name = "toml_parser" +version = "1.1.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa693a8032d7e1cada7d0041e96126df243179ff061456783ac7f12bda4744c" +dependencies = [ + "winnow 1.0.4", +] + +[[package]] +name = "toml_writer" +version = "1.1.3+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06bdbd8cfc056b8d2e2e85f29b56a3bdbecb527cef81eb39e3e7b98af4652770" + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" +dependencies = [ + "bitflags 2.13.2", + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", + "url", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "tray-icon" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b9c52859a94554803ccd4a24b98f74148ebc73b90676d783f3490b1bff9d72" +dependencies = [ + "crossbeam-channel", + "dirs", + "libappindicator", + "muda", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation", + "once_cell", + "png 0.18.1", + "serde", + "thiserror 2.0.21", + "windows-sys 0.61.2", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + +[[package]] +name = "unicode-ident" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c754d6c33795a1c324727428e5a7dedb5b06195f9890bdbcba760d3e246563" + +[[package]] +name = "unicode-segmentation" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" + +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", + "serde_derive", +] + +[[package]] +name = "urlpattern" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df16f50ef4cc145211879a3867ba757076b25dfee812040dcb0658bd9ae7904b" +dependencies = [ + "icu_properties", + "regex", + "serde", + "url", +] + +[[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.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cc1186384beb7dd8eedea376413fd654937285ea6c9cfbb928dc3043ea4b606" +dependencies = [ + "getrandom 0.4.3", + "js-sys", + "serde_core", + "wasm-bindgen", +] + +[[package]] +name = "version-compare" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c2856837ef78f57382f06b2b8563a2f512f7185d732608fd9176cb3b8edf0e" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec4cdd0dd910afe868b7ef477227d8d538b46b3075031afee8a9f2acb0a2ed0b" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.4+wasi-0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.129" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb54f33acc68fd454578d9820b0bde1a1a3d17aa17bb7b6595806d02886d409" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cbab34de2d982e9b48e18d216d04c4a6f641066ff19ffb699980f591ee3610e" +dependencies = [ + "js-sys", + "tokio", + "wasm-bindgen", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.129" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e29d0c35b16e224a7eeb5cd2d25e3e1968fbd65604117b44d3b789d00ee8535" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.129" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f501a8bc3719dba86ef8ae4728879c08001bea749eb1333ac5b91e040e2a6b7" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 3.0.9", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.129" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23f0c9c52aa7cd7d77769a4cfe2a9adb1b331f489a41d912ce14513d5ab995c6" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-streams" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88261b9deccee56594c11a3460c462c41f58d148598fe70ad77070126a68aba4" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web_atoms" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba8b815c1b593dc0baf78dd0f4fc8fdb2de53198fb1163738093e9a311c33fb3" +dependencies = [ + "phf", + "phf_codegen", + "string_cache", + "string_cache_codegen", +] + +[[package]] +name = "webkit2gtk" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1027150013530fb2eaf806408df88461ae4815a45c541c8975e61d6f2fc4793" +dependencies = [ + "bitflags 1.3.2", + "cairo-rs", + "gdk", + "gdk-sys", + "gio", + "gio-sys", + "glib", + "glib-sys", + "gobject-sys", + "gtk", + "gtk-sys", + "javascriptcore-rs", + "libc", + "once_cell", + "soup3", + "webkit2gtk-sys", +] + +[[package]] +name = "webkit2gtk-sys" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "916a5f65c2ef0dfe12fff695960a2ec3d4565359fdbb2e9943c974e06c734ea5" +dependencies = [ + "bitflags 1.3.2", + "cairo-sys-rs", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "gtk-sys", + "javascriptcore-rs-sys", + "libc", + "pkg-config", + "soup3-sys", + "system-deps", +] + +[[package]] +name = "webview2-com" +version = "0.39.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f89fca7a704cee10dcb3654c1dbb8941d1783132f1917358af75bec37a7d7e6" +dependencies = [ + "webview2-com-macros", + "webview2-com-sys", + "windows", + "windows-core", +] + +[[package]] +name = "webview2-com-macros" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a921c1b6914c367b2b823cd4cde6f96beec77d30a939c8199bb377cf9b9b54" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "webview2-com-sys" +version = "0.39.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a07132775117d6065853d9d1178157b8c90e228de47129d6bce2c7edebedfb" +dependencies = [ + "thiserror 2.0.21", + "windows", + "windows-core", +] + +[[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.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "111e51caca442cafd9bab396628ac4d814880eaea4e63dfd76a12e9f342b5580" +dependencies = [ + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", + "objc2-quartz-core", + "raw-window-handle", + "windows-sys 0.61.2", + "windows-version", +] + +[[package]] +name = "windows" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" +dependencies = [ + "windows-collections", + "windows-core", + "windows-future", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" +dependencies = [ + "windows-core", +] + +[[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", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-future" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" +dependencies = [ + "windows-core", + "windows-link", + "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.119", +] + +[[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.119", +] + +[[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.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" +dependencies = [ + "windows-core", + "windows-link", +] + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows-threading" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-version" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4060a1da109b9d0326b7262c8e12c84df67cc0dbc9e33cf49e01ccc2eb63631" +dependencies = [ + "windows-link", +] + +[[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_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[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_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[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_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[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 = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d6f32a0ff4a9f6f01231eb2059cc85479330739333e0e58cadf03b6af2cca10" +dependencies = [ + "cfg-if", + "windows-sys 0.61.2", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "writeable" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" + +[[package]] +name = "wry" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a819957a01b3119af85e638a38d242af76dbc87d130dca67bfd0441072e21ff0" +dependencies = [ + "base64 0.22.1", + "block2", + "cookie", + "crossbeam-channel", + "dirs", + "dom_query", + "dpi", + "dunce", + "gdkx11", + "gtk", + "http", + "javascriptcore-rs", + "jni", + "libc", + "ndk", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", + "objc2-ui-kit", + "objc2-web-kit", + "once_cell", + "percent-encoding", + "raw-window-handle", + "sha2", + "soup3", + "tao-macros", + "thiserror 2.0.21", + "url", + "webkit2gtk", + "webkit2gtk-sys", + "webview2-com", + "windows", + "windows-core", + "windows-version", + "x11-dl", +] + +[[package]] +name = "x11" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "yoke" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec8ebde2db3681e8c9980cc27822030e68752690ddfa9473e739aeb4dbde6d71" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", + "synstructure", +] + +[[package]] +name = "zerofrom" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f75b4683f6c7f45248d4d64056a24298c6281e0993356d7d1b4a1a962ef10d4a" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", + "synstructure", +] + +[[package]] +name = "zerotrie" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "zlib-rs" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b268e58e7c693d7c271f93ffc4ba3b380412554231c85bf61ca7af91042a4112" + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/mobile/src-tauri/Cargo.toml b/mobile/src-tauri/Cargo.toml new file mode 100644 index 000000000..44d11fdb4 --- /dev/null +++ b/mobile/src-tauri/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "ferryx-mobile" +version = "0.1.0" +edition = "2021" +rust-version = "1.89" +license = "SUL-1.0" + +[lib] +name = "ferryx_mobile_lib" +crate-type = ["staticlib", "cdylib", "rlib"] + +[build-dependencies] +tauri-build = { version = "=2.7.3", features = [] } + +[dependencies] +tauri = { version = "=2.12.4", features = [] } diff --git a/mobile/src-tauri/build.rs b/mobile/src-tauri/build.rs new file mode 100644 index 000000000..d860e1e6a --- /dev/null +++ b/mobile/src-tauri/build.rs @@ -0,0 +1,3 @@ +fn main() { + tauri_build::build() +} diff --git a/mobile/src-tauri/icons/icon.png b/mobile/src-tauri/icons/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3d6fa79b010b3dd4aa8b41a78b53c208a40bdee1 GIT binary patch literal 15265 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 literal 0 HcmV?d00001 diff --git a/mobile/src-tauri/src/lib.rs b/mobile/src-tauri/src/lib.rs new file mode 100644 index 000000000..6d2dbb7f0 --- /dev/null +++ b/mobile/src-tauri/src/lib.rs @@ -0,0 +1,8 @@ +/// Mobile is a remote companion. It never starts the desktop PTY daemon, +/// binds a server, or exposes desktop filesystem/terminal commands to web content. +#[cfg_attr(mobile, tauri::mobile_entry_point)] +pub fn run() { + tauri::Builder::default() + .run(tauri::generate_context!()) + .expect("failed to run Ferryx mobile"); +} diff --git a/mobile/src-tauri/tauri.conf.json b/mobile/src-tauri/tauri.conf.json new file mode 100644 index 000000000..978754568 --- /dev/null +++ b/mobile/src-tauri/tauri.conf.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://schema.tauri.app/config/2", + "productName": "Ferryx Mobile", + "version": "0.1.0", + "identifier": "com.ferryx.mobile", + "build": { + "beforeDevCommand": "npm --prefix ../ui run dev:mobile", + "devUrl": "http://localhost:5173", + "beforeBuildCommand": "npm --prefix ../ui run build:mobile", + "frontendDist": "../../ui/dist-mobile" + }, + "app": { + "windows": [{ "label": "main", "title": "Ferryx", "width": 390, "height": 844 }], + "security": { + "capabilities": [], + "csp": "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https:; font-src 'self' data:; connect-src 'self' https: wss:; object-src 'none'; base-uri 'self'; frame-src 'none'; form-action 'none'" + } + }, + "bundle": { + "active": true, + "icon": ["icons/icon.png"], + "android": { "minSdkVersion": 24 }, + "iOS": { "minimumSystemVersion": "14.0" } + } +} diff --git a/ui/package.json b/ui/package.json index f2da6bf7b..cfdf9d04d 100644 --- a/ui/package.json +++ b/ui/package.json @@ -14,7 +14,9 @@ "doctor": "react-doctor", "lint": "eslint src", "typecheck:test": "tsc --noEmit -p tsconfig.test.json", - "preview": "vite preview" + "preview": "vite preview", + "build:mobile": "tsc && vite build --config vite.mobile.config.ts", + "dev:mobile": "vite --config vite.mobile.config.ts" }, "dependencies": { "@dnd-kit/core": "^6.3.1", diff --git a/ui/src/lib/clientRuntime.test.ts b/ui/src/lib/clientRuntime.test.ts new file mode 100644 index 000000000..63b11ac27 --- /dev/null +++ b/ui/src/lib/clientRuntime.test.ts @@ -0,0 +1,23 @@ +import { afterEach, describe, expect, it, vi } from "vitest"; +import { isDesktopShell, isMobileCompanion } from "./clientRuntime"; + +afterEach(() => vi.unstubAllEnvs()); + +describe("client runtime routing", () => { + it("routes the native phone shell to remote, even with native internals", () => { + vi.stubEnv("VITE_FERRYX_MOBILE", "1"); + expect(isMobileCompanion()).toBe(true); + expect(isDesktopShell(true)).toBe(false); + expect(isDesktopShell(false)).toBe(false); + }); + it("keeps desktop native and browser remote", () => { + vi.stubEnv("VITE_FERRYX_MOBILE", undefined); + expect(isMobileCompanion()).toBe(false); + expect(isDesktopShell(true)).toBe(true); + expect(isDesktopShell(false)).toBe(false); + }); + it("does not enable mobile for an arbitrary truthy value", () => { + vi.stubEnv("VITE_FERRYX_MOBILE", "false"); + expect(isDesktopShell(true)).toBe(true); + }); +}); diff --git a/ui/src/lib/clientRuntime.ts b/ui/src/lib/clientRuntime.ts new file mode 100644 index 000000000..15ec6b9f9 --- /dev/null +++ b/ui/src/lib/clientRuntime.ts @@ -0,0 +1,8 @@ +/** A native mobile shell still uses remote HTTP/WebSocket transport, never desktop IPC. */ +export function isMobileCompanion(): boolean { + return import.meta.env.VITE_FERRYX_MOBILE === "1"; +} + +export function isDesktopShell(hasTauri: boolean): boolean { + return hasTauri && !isMobileCompanion(); +} diff --git a/ui/src/lib/settingsRuntimeBridge.ts b/ui/src/lib/settingsRuntimeBridge.ts index d863c4215..fd419124d 100644 --- a/ui/src/lib/settingsRuntimeBridge.ts +++ b/ui/src/lib/settingsRuntimeBridge.ts @@ -1,3 +1,4 @@ +import { isDesktopShell as selectDesktopShell } from "./clientRuntime"; import { APPEARANCE_SETTINGS_EVENT, applyAppearanceSettings, @@ -22,7 +23,7 @@ export function _resetSettingsRuntimeBridgeForTest() { } function isDesktopShell() { - return Boolean((window as { __TAURI_INTERNALS__?: unknown }).__TAURI_INTERNALS__); + return selectDesktopShell(Boolean((window as { __TAURI_INTERNALS__?: unknown }).__TAURI_INTERNALS__)); } function prefersLightScheme() { diff --git a/ui/src/lib/tauri.ts b/ui/src/lib/tauri.ts index 600e8f91e..a9cf7f2cd 100644 --- a/ui/src/lib/tauri.ts +++ b/ui/src/lib/tauri.ts @@ -1,8 +1,9 @@ +import { isDesktopShell } from "./clientRuntime"; import type { DagRunSnapshot } from "./dagTypes"; import type { RunTarget } from "./scopedContracts"; export const DEFAULT_TERMINAL_FONT_STACK = 'MesloLGS NF, "Noto Sans KR", monospace'; import { defaultRemoteClient, getRemoteAuthToken, RemoteClient, type RemotePreferenceTarget } from "./remoteClient"; -import { invoke, isTauri } from "@tauri-apps/api/core"; +import { invoke, isTauri as isTauriShell } from "@tauri-apps/api/core"; import { listen, type UnlistenFn } from "@tauri-apps/api/event"; import { switchDebug } from "./switchDebug"; import { shortcutContext, traceShortcutAction } from "./shortcutDiagnostics"; @@ -201,6 +202,10 @@ export type TerminalDescribeResult = { suspensionSource?: string | null; }; +function isTauri() { + return isDesktopShell(isTauriShell()); +} + export function isTauriRuntime() { return isTauri(); } diff --git a/ui/src/main.tsx b/ui/src/main.tsx index cdedad546..dda8de4e4 100644 --- a/ui/src/main.tsx +++ b/ui/src/main.tsx @@ -1,3 +1,4 @@ +import { isDesktopShell, isMobileCompanion } from "./lib/clientRuntime"; import "./lib/uuid"; import React from "react"; import ReactDOM from "react-dom/client"; @@ -21,7 +22,7 @@ if (import.meta.env.DEV && import.meta.env.VITE_DISABLE_REACT_DEVTOOLS !== "1") void import("react-scan"); } -const isTauriApp = typeof window !== "undefined" && Boolean((window as any).__TAURI_INTERNALS__); +const isTauriApp = isDesktopShell(typeof window !== "undefined" && Boolean((window as any).__TAURI_INTERNALS__)); // Build identity is exposed for support: a stale phone bundle is then visible on the device itself. document.documentElement.dataset.ferryxBuild = BUILD_STAMP; console.info(`Ferryx ${isTauriApp ? "desktop" : "remote client"} build ${BUILD_STAMP}`); @@ -97,7 +98,7 @@ boot().catch((error: unknown) => { el.replaceChildren(message); }); -if (typeof window !== "undefined" && "serviceWorker" in navigator && !isTauriApp) { +if (typeof window !== "undefined" && "serviceWorker" in navigator && !isTauriApp && !isMobileCompanion()) { const registerServiceWorker = () => { navigator.serviceWorker.register(SERVICE_WORKER_PATH).catch(() => {}); }; diff --git a/ui/vite.mobile.config.ts b/ui/vite.mobile.config.ts new file mode 100644 index 000000000..f069343db --- /dev/null +++ b/ui/vite.mobile.config.ts @@ -0,0 +1,13 @@ +import { mergeConfig } from "vite"; +import base from "./vite.config"; + +// Bundle the existing remote UI locally, not a mutable remote webpage. +// The explicit build flag keeps Tauri's native shell from selecting Desktop App. +export default mergeConfig(base, { + define: { "import.meta.env.VITE_FERRYX_MOBILE": JSON.stringify("1") }, + build: { outDir: "dist-mobile" }, + server: { + host: "0.0.0.0", + hmr: { host: process.env.TAURI_DEV_HOST ?? "localhost", clientPort: 5173 }, + }, +}); From 2b1e8e17bfee50e130eac06ebad6809ece2761ac Mon Sep 17 00:00:00 2001 From: Indosaram Date: Mon, 19 Oct 2026 22:51:22 +0900 Subject: [PATCH 2/2] test(mobile): verify Android APK packaging and complete remote suite --- .../mobile-tauri-20261019/android-build.log | 93 +++++++++++++++++++ .../apk-verification.txt | 15 +++ .../remote-test-summary.json | 7 ++ mobile/README.md | 8 +- mobile/scripts/init-android.mjs | 2 +- 5 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 docs/evidence/mobile-tauri-20261019/android-build.log create mode 100644 docs/evidence/mobile-tauri-20261019/apk-verification.txt create mode 100644 docs/evidence/mobile-tauri-20261019/remote-test-summary.json diff --git a/docs/evidence/mobile-tauri-20261019/android-build.log b/docs/evidence/mobile-tauri-20261019/android-build.log new file mode 100644 index 000000000..a97188bc4 --- /dev/null +++ b/docs/evidence/mobile-tauri-20261019/android-build.log @@ -0,0 +1,93 @@ + +> ferryx-mobile@0.1.0 android:build +> node scripts/tauri.mjs android build --debug --target aarch64 --apk + + Info Using installed NDK: /android-sdk/ndk/27.2.12479018 + Info Looking up installed tauri packages to check mismatched versions... + Running beforeBuildCommand `npm --prefix ../ui run build:mobile` + +> ui@0.1.0 build:mobile +> tsc && vite build --config vite.mobile.config.ts + +vite v6.4.4 building for production... +transforming... +✓ 2258 modules transformed. +rendering chunks... +computing gzip size... +dist-mobile/index.html 3.39 kB │ gzip: 1.22 kB +dist-mobile/assets/crush-DHElXcRZ.png 5.46 kB +dist-mobile/assets/droid-BhrKLgQ8.svg 6.30 kB │ gzip: 2.88 kB +dist-mobile/assets/antigravity-DgAQAdn3.svg 7.63 kB │ gzip: 1.72 kB +dist-mobile/assets/gjc-CmlXGg4z.png 22.73 kB +dist-mobile/assets/geist-variable-CrgPqtmy.woff2 69.44 kB +dist-mobile/assets/ferryx-icon-OXRkkUvz.png 805.82 kB +dist-mobile/assets/App-V8Wj_Bb0.css 0.59 kB │ gzip: 0.31 kB +dist-mobile/assets/index-ckLza-72.css 113.95 kB │ gzip: 20.02 kB +dist-mobile/assets/arrow-down-Ev2p6eA6.js 0.34 kB │ gzip: 0.27 kB +dist-mobile/assets/nativeShortcutTable-ChDHIVvA.js 0.57 kB │ gzip: 0.35 kB +dist-mobile/assets/arrow-right-CACxJEnM.js 0.62 kB │ gzip: 0.32 kB +dist-mobile/assets/clipboard-CCgcnRg2.js 1.69 kB │ gzip: 0.83 kB +dist-mobile/assets/shortcutOverrides-CEXeEYvN.js 1.81 kB │ gzip: 0.85 kB +dist-mobile/assets/tailscaleDiscovery-BtfcwLaD.js 2.56 kB │ gzip: 1.11 kB +dist-mobile/assets/WhatsNewDialog-BTJXmGhU.js 2.85 kB │ gzip: 1.16 kB +dist-mobile/assets/sshHosts-CWzxb_af.js 3.22 kB │ gzip: 1.29 kB +dist-mobile/assets/SystemResourcesDialog-Dx4piHvl.js 7.05 kB │ gzip: 2.62 kB +dist-mobile/assets/AccountSignIn-CbolCq8y.js 7.16 kB │ gzip: 2.70 kB +dist-mobile/assets/pairedHostInventory-DJG7kEq_.js 14.65 kB │ gzip: 5.03 kB +dist-mobile/assets/browserProtocol-Ck8ZGqNi.js 16.42 kB │ gzip: 4.13 kB +dist-mobile/assets/MobileChatWorkspace-B3QtzgTW.js 27.90 kB │ gzip: 8.11 kB +dist-mobile/assets/RemoteTerminal-C8t4Pa3B.js 31.15 kB │ gzip: 10.90 kB +dist-mobile/assets/WelcomeWizard-EPL6nB2W.js 32.23 kB │ gzip: 9.52 kB +dist-mobile/assets/RemoteBrowserWorkspace-DC34mb7J.js 47.34 kB │ gzip: 13.44 kB +dist-mobile/assets/index-8l85aDrS.js 208.76 kB │ gzip: 66.27 kB +dist-mobile/assets/SettingsDialog-FwtXOrXs.js 288.21 kB │ gzip: 81.41 kB +dist-mobile/assets/RemoteApp-D_N4FfT1.js 543.75 kB │ gzip: 164.32 kB +dist-mobile/assets/App-BYycgCGu.js 950.58 kB │ gzip: 276.85 kB + +(!) Some chunks are larger than 500 kB after minification. Consider: +- Using dynamic import() to code-split the application +- Use build.rollupOptions.output.manualChunks to improve chunking: https://rollupjs.org/configuration-options/#output-manualchunks +- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit. +✓ built in 11.01s + Compiling ferryx-mobile v0.1.0 (/mobile/src-tauri) + Finished `dev` profile [unoptimized] target(s) in 5.47s + Info symlinking lib "/mobile/src-tauri/target/aarch64-linux-android/debug/libferryx_mobile_lib.so" in jniLibs dir "/mobile/src-tauri/gen/android/app/src/main/jniLibs/arm64-v8a" + Info "/mobile/src-tauri/target/aarch64-linux-android/debug/libferryx_mobile_lib.so" requires shared lib "libandroid.so" + Info "/mobile/src-tauri/target/aarch64-linux-android/debug/libferryx_mobile_lib.so" requires shared lib "libdl.so" + Info "/mobile/src-tauri/target/aarch64-linux-android/debug/libferryx_mobile_lib.so" requires shared lib "liblog.so" + Info "/mobile/src-tauri/target/aarch64-linux-android/debug/libferryx_mobile_lib.so" requires shared lib "libm.so" + Info "/mobile/src-tauri/target/aarch64-linux-android/debug/libferryx_mobile_lib.so" requires shared lib "libc.so" + Info symlink at "/mobile/src-tauri/gen/android/app/src/main/jniLibs/arm64-v8a/libferryx_mobile_lib.so" points to "/mobile/src-tauri/target/aarch64-linux-android/debug/libferryx_mobile_lib.so" +WARNING: We recommend using a newer Android Gradle plugin to use compileSdk = 36 + +This Android Gradle plugin (8.7.3) was tested up to compileSdk = 35. + +You are strongly encouraged to update your project to use a newer +Android Gradle plugin that has been tested with compileSdk = 36. + +If you are already using the latest version of the Android Gradle plugin, +you may need to wait until a newer version with support for compileSdk = 36 is available. + +For more information refer to the compatibility table: +https://d.android.com/r/tools/api-level-support + +To suppress this warning, add/update + android.suppressUnsupportedCompileSdk=36 +to this project's gradle.properties. + +> ferryx-mobile@0.1.0 tauri +> node scripts/tauri.mjs android android-studio-script --target aarch64 + + Info connection; remote_addr=127.0.0.1:39994 conn_id=0 + Info Using installed NDK: /android-sdk/ndk/27.2.12479018 + Compiling ferryx-mobile v0.1.0 (/mobile/src-tauri) + Finished `dev` profile [unoptimized] target(s) in 5.26s + Info symlinking lib "/mobile/src-tauri/target/aarch64-linux-android/debug/libferryx_mobile_lib.so" in jniLibs dir "/mobile/src-tauri/gen/android/app/src/main/jniLibs/arm64-v8a" + Info "/mobile/src-tauri/target/aarch64-linux-android/debug/libferryx_mobile_lib.so" requires shared lib "libandroid.so" + Info "/mobile/src-tauri/target/aarch64-linux-android/debug/libferryx_mobile_lib.so" requires shared lib "libdl.so" + Info "/mobile/src-tauri/target/aarch64-linux-android/debug/libferryx_mobile_lib.so" requires shared lib "liblog.so" + Info "/mobile/src-tauri/target/aarch64-linux-android/debug/libferryx_mobile_lib.so" requires shared lib "libm.so" + Info "/mobile/src-tauri/target/aarch64-linux-android/debug/libferryx_mobile_lib.so" requires shared lib "libc.so" + Finished 1 APK at: + /mobile/src-tauri/gen/android/app/build/outputs/apk/universal/debug/app-universal-debug.apk + diff --git a/docs/evidence/mobile-tauri-20261019/apk-verification.txt b/docs/evidence/mobile-tauri-20261019/apk-verification.txt new file mode 100644 index 000000000..e7a562852 --- /dev/null +++ b/docs/evidence/mobile-tauri-20261019/apk-verification.txt @@ -0,0 +1,15 @@ +Verifies +Verified using v1 scheme (JAR signing): false +Verified using v2 scheme (APK Signature Scheme v2): true +Verified using v3 scheme (APK Signature Scheme v3): false +Verified using v3.1 scheme (APK Signature Scheme v3.1): false +Verified using v4 scheme (APK Signature Scheme v4): false +Verified for SourceStamp: false +Number of signers: 1 +package: name='com.ferryx.mobile' versionCode='1000' versionName='0.1.0' platformBuildVersionName='15' platformBuildVersionCode='35' compileSdkVersion='35' compileSdkVersionCodename='15' +sdkVersion:'24' +targetSdkVersion:'35' +uses-permission: name='android.permission.INTERNET' +uses-permission: name='com.ferryx.mobile.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION' +native-code: 'arm64-v8a' +05c132f2fc4f48e4765865d9aa865cecfb00cb59abecdcd89fe685e4e5920664 diff --git a/docs/evidence/mobile-tauri-20261019/remote-test-summary.json b/docs/evidence/mobile-tauri-20261019/remote-test-summary.json new file mode 100644 index 000000000..855e36bc7 --- /dev/null +++ b/docs/evidence/mobile-tauri-20261019/remote-test-summary.json @@ -0,0 +1,7 @@ +{ + "numTotalTests": 1221, + "numPassedTests": 1221, + "numFailedTests": 0, + "numPendingTests": 0, + "success": true +} diff --git a/mobile/README.md b/mobile/README.md index 17f5612f3..abb59338e 100644 --- a/mobile/README.md +++ b/mobile/README.md @@ -46,8 +46,10 @@ Frontend-only validation: `npm --prefix ui run build:mobile`. - Mobile frontend and existing desktop frontend builds pass. - ARM64 Android Rust native library cross-compiles successfully. -- APK packaging not yet verified: Gradle compilation exceeds this environment's - bounded build attempts. No APK/device-run claim is made. +- Android ARM64 debug APK builds with the normal `android:build` command. + APK signature v2 verifies, package `com.ferryx.mobile` / version 0.1.0, + min SDK 24 / target SDK 35; ARM64 native library is present. + This is a debug-signed package, not a store/distribution release. - 47 targeted tests pass (account sign-in/session, remote preferences, runtime routing, settings). Runtime routing: 100% statements/branches/functions/lines. Settings bridge: 100% statements/functions/lines, 83.33% branches. These are @@ -55,7 +57,7 @@ Frontend-only validation: `npm --prefix ui run build:mobile`. - Production mobile bundle, with native internals present: login screen renders without desktop IPC or JS errors at 360x800, 390x844 and 844x390, no horizontal overflow. Landscape requires normal vertical scrolling. -- Broader remote test sweep was interrupted by the execution budget; not green. +- Complete remote UI suite: 1,221 tests pass, 0 fail, 0 skip (JSON reporter). - No real phone/emulator, keyboard/IME, safe-area hardware, background/resume, authenticated live relay, push notifications or iOS/Xcode QA has been done. - Bundle-size warnings remain. This is a draft companion, not store-ready. diff --git a/mobile/scripts/init-android.mjs b/mobile/scripts/init-android.mjs index 1b74d3373..204da43e3 100644 --- a/mobile/scripts/init-android.mjs +++ b/mobile/scripts/init-android.mjs @@ -7,7 +7,7 @@ const mobile = fileURLToPath(new URL("..", import.meta.url)); const cli = path.join(mobile, "../node_modules/@tauri-apps/cli/tauri.js"); execFileSync(process.execPath, [cli, "android", "init", "--ci"], { cwd: mobile, stdio: "inherit" }); // The CLI's generated templates can drift independently of this source tree. -// Pin to the available Android 35 toolchain instead of silently requiring preview SDKs. +// Pin to the available Android 35/36 toolchain instead of silently requiring preview SDKs. const gen = path.join(mobile, "src-tauri/gen/android"); function patch(file, transform) { const target = path.join(gen, file);