From 2c9b591c52e1f30cddfc3f9610ca8a21d34d9076 Mon Sep 17 00:00:00 2001 From: Bailey Taylor Date: Wed, 27 May 2026 09:01:09 +0800 Subject: [PATCH] feat: initial PSG Launcher scaffold --- .gitea/workflows/release.yml | 167 + .gitignore | 43 + .vs/PSG-Conduit.slnx/v18/Browse.VC.db | Bin 0 -> 8192 bytes .vs/PSG-Conduit.slnx/v18/Browse.VC.db-shm | Bin 0 -> 32768 bytes .vs/PSG-Conduit.slnx/v18/Browse.VC.db-wal | Bin 0 -> 2045816 bytes .vs/PSG-Conduit.slnx/v18/Browse.VC.opendb | Bin 0 -> 36 bytes PSG-Conduit.slnx | 7 + PSG-Conduit/PSG-Conduit.vcxproj | 150 + PSG-Conduit/PSG-Conduit.vcxproj.filters | 17 + PSG-Conduit/PSG-Conduit.vcxproj.user | 4 + README.md | 198 + index.html | 12 + manifests/apps.json | 27 + manifests/apps.json.sig | 1 + manifests/latest.json | 11 + package-lock.json | 1931 +++++ package.json | 29 + scripts/_openssl.ps1 | 54 + scripts/keygen.ps1 | 66 + scripts/sign-manifest.ps1 | 122 + scripts/sign-package.ps1 | 75 + src-tauri/Cargo.lock | 6236 +++++++++++++++++ src-tauri/Cargo.toml | 60 + src-tauri/build.rs | 3 + src-tauri/capabilities/default.json | 23 + src-tauri/icons/128x128.png | Bin 0 -> 1370 bytes src-tauri/icons/128x128@2x.png | Bin 0 -> 2576 bytes src-tauri/icons/32x32.png | Bin 0 -> 441 bytes src-tauri/icons/64x64.png | Bin 0 -> 727 bytes src-tauri/icons/Square107x107Logo.png | Bin 0 -> 1226 bytes src-tauri/icons/Square142x142Logo.png | Bin 0 -> 1528 bytes src-tauri/icons/Square150x150Logo.png | Bin 0 -> 1596 bytes src-tauri/icons/Square284x284Logo.png | Bin 0 -> 2681 bytes src-tauri/icons/Square30x30Logo.png | Bin 0 -> 421 bytes src-tauri/icons/Square310x310Logo.png | Bin 0 -> 3004 bytes src-tauri/icons/Square44x44Logo.png | Bin 0 -> 588 bytes src-tauri/icons/Square71x71Logo.png | Bin 0 -> 859 bytes src-tauri/icons/Square89x89Logo.png | Bin 0 -> 1057 bytes src-tauri/icons/StoreLogo.png | Bin 0 -> 610 bytes .../android/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../icons/android/mipmap-hdpi/ic_launcher.png | Bin 0 -> 647 bytes .../mipmap-hdpi/ic_launcher_foreground.png | Bin 0 -> 1659 bytes .../android/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 818 bytes .../icons/android/mipmap-mdpi/ic_launcher.png | Bin 0 -> 608 bytes .../mipmap-mdpi/ic_launcher_foreground.png | Bin 0 -> 1165 bytes .../android/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 771 bytes .../android/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 1125 bytes .../mipmap-xhdpi/ic_launcher_foreground.png | Bin 0 -> 2148 bytes .../mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 1428 bytes .../android/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 1571 bytes .../mipmap-xxhdpi/ic_launcher_foreground.png | Bin 0 -> 3114 bytes .../mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 2048 bytes .../android/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 2089 bytes .../mipmap-xxxhdpi/ic_launcher_foreground.png | Bin 0 -> 4293 bytes .../mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 2589 bytes .../android/values/ic_launcher_background.xml | 4 + src-tauri/icons/icon.icns | Bin 0 -> 26657 bytes src-tauri/icons/icon.ico | Bin 0 -> 5433 bytes src-tauri/icons/icon.png | Bin 0 -> 2037 bytes src-tauri/icons/ios/AppIcon-20x20@1x.png | Bin 0 -> 338 bytes src-tauri/icons/ios/AppIcon-20x20@2x-1.png | Bin 0 -> 511 bytes src-tauri/icons/ios/AppIcon-20x20@2x.png | Bin 0 -> 511 bytes src-tauri/icons/ios/AppIcon-20x20@3x.png | Bin 0 -> 737 bytes src-tauri/icons/ios/AppIcon-29x29@1x.png | Bin 0 -> 404 bytes src-tauri/icons/ios/AppIcon-29x29@2x-1.png | Bin 0 -> 699 bytes src-tauri/icons/ios/AppIcon-29x29@2x.png | Bin 0 -> 699 bytes src-tauri/icons/ios/AppIcon-29x29@3x.png | Bin 0 -> 1011 bytes src-tauri/icons/ios/AppIcon-40x40@1x.png | Bin 0 -> 511 bytes src-tauri/icons/ios/AppIcon-40x40@2x-1.png | Bin 0 -> 918 bytes src-tauri/icons/ios/AppIcon-40x40@2x.png | Bin 0 -> 918 bytes src-tauri/icons/ios/AppIcon-40x40@3x.png | Bin 0 -> 1297 bytes src-tauri/icons/ios/AppIcon-512@2x.png | Bin 0 -> 12837 bytes src-tauri/icons/ios/AppIcon-60x60@2x.png | Bin 0 -> 1297 bytes src-tauri/icons/ios/AppIcon-60x60@3x.png | Bin 0 -> 1839 bytes src-tauri/icons/ios/AppIcon-76x76@1x.png | Bin 0 -> 906 bytes src-tauri/icons/ios/AppIcon-76x76@2x.png | Bin 0 -> 1605 bytes src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png | Bin 0 -> 1735 bytes src-tauri/src/commands/apps.rs | 259 + src-tauri/src/commands/manifest.rs | 115 + src-tauri/src/commands/mod.rs | 3 + src-tauri/src/commands/updater.rs | 75 + src-tauri/src/config.rs | 31 + src-tauri/src/error.rs | 62 + src-tauri/src/lib.rs | 52 + src-tauri/src/main.rs | 6 + src-tauri/src/models/installed.rs | 21 + src-tauri/src/models/manifest.rs | 65 + src-tauri/src/models/mod.rs | 2 + src-tauri/tauri.conf.json | 53 + src/App.css | 85 + src/App.tsx | 75 + src/components/AppCard.css | 191 + src/components/AppCard.tsx | 153 + src/components/AppGrid.css | 16 + src/components/AppGrid.tsx | 32 + src/components/Sidebar.css | 75 + src/components/Sidebar.tsx | 48 + src/components/TitleBar.css | 66 + src/components/TitleBar.tsx | 39 + src/components/UpdateBanner.css | 51 + src/components/UpdateBanner.tsx | 27 + src/hooks/useAppManifest.ts | 55 + src/hooks/useLauncherUpdate.ts | 33 + src/index.css | 51 + src/lib/commands.ts | 34 + src/main.tsx | 10 + src/types/manifest.ts | 61 + tsconfig.json | 21 + tsconfig.node.json | 13 + vite.config.ts | 25 + 110 files changed, 11150 insertions(+) create mode 100644 .gitea/workflows/release.yml create mode 100644 .gitignore create mode 100644 .vs/PSG-Conduit.slnx/v18/Browse.VC.db create mode 100644 .vs/PSG-Conduit.slnx/v18/Browse.VC.db-shm create mode 100644 .vs/PSG-Conduit.slnx/v18/Browse.VC.db-wal create mode 100644 .vs/PSG-Conduit.slnx/v18/Browse.VC.opendb create mode 100644 PSG-Conduit.slnx create mode 100644 PSG-Conduit/PSG-Conduit.vcxproj create mode 100644 PSG-Conduit/PSG-Conduit.vcxproj.filters create mode 100644 PSG-Conduit/PSG-Conduit.vcxproj.user create mode 100644 README.md create mode 100644 index.html create mode 100644 manifests/apps.json create mode 100644 manifests/apps.json.sig create mode 100644 manifests/latest.json create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 scripts/_openssl.ps1 create mode 100644 scripts/keygen.ps1 create mode 100644 scripts/sign-manifest.ps1 create mode 100644 scripts/sign-package.ps1 create mode 100644 src-tauri/Cargo.lock create mode 100644 src-tauri/Cargo.toml create mode 100644 src-tauri/build.rs create mode 100644 src-tauri/capabilities/default.json create mode 100644 src-tauri/icons/128x128.png create mode 100644 src-tauri/icons/128x128@2x.png create mode 100644 src-tauri/icons/32x32.png create mode 100644 src-tauri/icons/64x64.png create mode 100644 src-tauri/icons/Square107x107Logo.png create mode 100644 src-tauri/icons/Square142x142Logo.png create mode 100644 src-tauri/icons/Square150x150Logo.png create mode 100644 src-tauri/icons/Square284x284Logo.png create mode 100644 src-tauri/icons/Square30x30Logo.png create mode 100644 src-tauri/icons/Square310x310Logo.png create mode 100644 src-tauri/icons/Square44x44Logo.png create mode 100644 src-tauri/icons/Square71x71Logo.png create mode 100644 src-tauri/icons/Square89x89Logo.png create mode 100644 src-tauri/icons/StoreLogo.png create mode 100644 src-tauri/icons/android/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 src-tauri/icons/android/mipmap-hdpi/ic_launcher.png create mode 100644 src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png create mode 100644 src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png create mode 100644 src-tauri/icons/android/mipmap-mdpi/ic_launcher.png create mode 100644 src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png create mode 100644 src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png create mode 100644 src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png create mode 100644 src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png create mode 100644 src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png create mode 100644 src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png create mode 100644 src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png create mode 100644 src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png create mode 100644 src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png create mode 100644 src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 src-tauri/icons/android/values/ic_launcher_background.xml create mode 100644 src-tauri/icons/icon.icns create mode 100644 src-tauri/icons/icon.ico create mode 100644 src-tauri/icons/icon.png create mode 100644 src-tauri/icons/ios/AppIcon-20x20@1x.png create mode 100644 src-tauri/icons/ios/AppIcon-20x20@2x-1.png create mode 100644 src-tauri/icons/ios/AppIcon-20x20@2x.png create mode 100644 src-tauri/icons/ios/AppIcon-20x20@3x.png create mode 100644 src-tauri/icons/ios/AppIcon-29x29@1x.png create mode 100644 src-tauri/icons/ios/AppIcon-29x29@2x-1.png create mode 100644 src-tauri/icons/ios/AppIcon-29x29@2x.png create mode 100644 src-tauri/icons/ios/AppIcon-29x29@3x.png create mode 100644 src-tauri/icons/ios/AppIcon-40x40@1x.png create mode 100644 src-tauri/icons/ios/AppIcon-40x40@2x-1.png create mode 100644 src-tauri/icons/ios/AppIcon-40x40@2x.png create mode 100644 src-tauri/icons/ios/AppIcon-40x40@3x.png create mode 100644 src-tauri/icons/ios/AppIcon-512@2x.png create mode 100644 src-tauri/icons/ios/AppIcon-60x60@2x.png create mode 100644 src-tauri/icons/ios/AppIcon-60x60@3x.png create mode 100644 src-tauri/icons/ios/AppIcon-76x76@1x.png create mode 100644 src-tauri/icons/ios/AppIcon-76x76@2x.png create mode 100644 src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png create mode 100644 src-tauri/src/commands/apps.rs create mode 100644 src-tauri/src/commands/manifest.rs create mode 100644 src-tauri/src/commands/mod.rs create mode 100644 src-tauri/src/commands/updater.rs create mode 100644 src-tauri/src/config.rs create mode 100644 src-tauri/src/error.rs create mode 100644 src-tauri/src/lib.rs create mode 100644 src-tauri/src/main.rs create mode 100644 src-tauri/src/models/installed.rs create mode 100644 src-tauri/src/models/manifest.rs create mode 100644 src-tauri/src/models/mod.rs create mode 100644 src-tauri/tauri.conf.json create mode 100644 src/App.css create mode 100644 src/App.tsx create mode 100644 src/components/AppCard.css create mode 100644 src/components/AppCard.tsx create mode 100644 src/components/AppGrid.css create mode 100644 src/components/AppGrid.tsx create mode 100644 src/components/Sidebar.css create mode 100644 src/components/Sidebar.tsx create mode 100644 src/components/TitleBar.css create mode 100644 src/components/TitleBar.tsx create mode 100644 src/components/UpdateBanner.css create mode 100644 src/components/UpdateBanner.tsx create mode 100644 src/hooks/useAppManifest.ts create mode 100644 src/hooks/useLauncherUpdate.ts create mode 100644 src/index.css create mode 100644 src/lib/commands.ts create mode 100644 src/main.tsx create mode 100644 src/types/manifest.ts create mode 100644 tsconfig.json create mode 100644 tsconfig.node.json create mode 100644 vite.config.ts diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml new file mode 100644 index 0000000..c2ec747 --- /dev/null +++ b/.gitea/workflows/release.yml @@ -0,0 +1,167 @@ +# PSG Launcher — Release workflow +# +# Triggers on version tags: git tag v1.2.3 && git push --tags +# +# Required Gitea repository secrets: +# TAURI_SIGNING_PRIVATE_KEY — from: npm run tauri signer generate +# TAURI_SIGNING_PRIVATE_KEY_PASSWORD — (empty string is fine if no passphrase) +# MANIFEST_SIGNING_KEY — PEM content of manifest-private.pem +# GITEA_TOKEN — a personal access token with repo write scope +# +# The workflow: +# 1. Builds the Tauri Windows installer (signed with Tauri's ed25519 key) +# 2. Signs apps.json with the manifest key +# 3. Creates a Gitea release with the installer attached +# 4. Pushes updated latest.json and apps.json.sig to the `releases` branch + +name: Release + +on: + push: + tags: + - "v*" + +jobs: + build-windows: + runs-on: windows-latest + permissions: + contents: write + + steps: + # ── Checkout ─────────────────────────────────────────────────────────── + - name: Checkout + uses: actions/checkout@v4 + + # ── Toolchains ───────────────────────────────────────────────────────── + - name: Set up Node.js 20 + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "npm" + + - name: Set up Rust (stable) + uses: dtolnay/rust-toolchain@stable + with: + targets: x86_64-pc-windows-msvc + + - name: Cache Rust build + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + src-tauri/target + key: ${{ runner.os }}-cargo-${{ hashFiles('src-tauri/Cargo.lock') }} + restore-keys: ${{ runner.os }}-cargo- + + # ── Install dependencies ─────────────────────────────────────────────── + - name: Install npm dependencies + run: npm ci + + # ── Build Tauri release ──────────────────────────────────────────────── + - name: Build Tauri app (Windows) + run: npm run tauri build -- --target x86_64-pc-windows-msvc + env: + TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} + TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} + + # ── Collect artefacts ────────────────────────────────────────────────── + - name: Locate installer and signature + id: artefacts + shell: pwsh + run: | + $installer = Get-ChildItem src-tauri/target/x86_64-pc-windows-msvc/release/bundle/nsis ` + -Filter "*-setup.exe" -Recurse | Select-Object -First 1 + $sig = Get-Item "$($installer.FullName).sig" + + echo "installer=$($installer.FullName)" >> $env:GITHUB_OUTPUT + echo "sig=$($sig.FullName)" >> $env:GITHUB_OUTPUT + echo "version=${GITHUB_REF_NAME#v}" >> $env:GITHUB_OUTPUT + + $sigContent = Get-Content $sig.FullName -Raw + echo "tauri_sig=$sigContent" >> $env:GITHUB_OUTPUT + + # ── Update latest.json ───────────────────────────────────────────────── + - name: Write latest.json + shell: pwsh + run: | + $version = "${{ steps.artefacts.outputs.version }}" + $tauriSig = "${{ steps.artefacts.outputs.tauri_sig }}" + $baseUrl = "${{ gitea.server_url }}/${{ gitea.repository }}/releases/download/v$version" + $filename = Split-Path "${{ steps.artefacts.outputs.installer }}" -Leaf + + $latest = @{ + version = $version + notes = "Release $version" + pub_date = (Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ") + platforms = @{ + "windows-x86_64" = @{ + signature = $tauriSig.Trim() + url = "$baseUrl/$filename" + } + } + } + $latest | ConvertTo-Json -Depth 5 | Set-Content manifests/latest.json + Write-Host "latest.json written" + + # ── Sign apps.json ───────────────────────────────────────────────────── + - name: Sign apps manifest + shell: pwsh + env: + MANIFEST_SIGNING_KEY: ${{ secrets.MANIFEST_SIGNING_KEY }} + run: .\scripts\sign-manifest.ps1 + + # ── Create Gitea release ─────────────────────────────────────────────── + - name: Create release and upload installer + shell: pwsh + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + run: | + $tag = "${{ github.ref_name }}" + $version = "${{ steps.artefacts.outputs.version }}" + $installer= "${{ steps.artefacts.outputs.installer }}" + $sig = "${{ steps.artefacts.outputs.sig }}" + $apiBase = "${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}" + $headers = @{ Authorization = "token $env:GITEA_TOKEN"; "Content-Type" = "application/json" } + + # Create release + $body = @{ tag_name = $tag; name = "PSG Launcher $tag"; draft = $false; prerelease = $false } | ConvertTo-Json + $release = Invoke-RestMethod -Uri "$apiBase/releases" -Method Post -Headers $headers -Body $body + $uploadUrl = "$apiBase/releases/$($release.id)/assets" + + # Upload installer + $uploadHeaders = @{ Authorization = "token $env:GITEA_TOKEN" } + Invoke-RestMethod -Uri "$uploadUrl`?name=$(Split-Path $installer -Leaf)" ` + -Method Post -Headers $uploadHeaders ` + -InFile $installer -ContentType "application/octet-stream" + + # Upload .sig file + Invoke-RestMethod -Uri "$uploadUrl`?name=$(Split-Path $sig -Leaf)" ` + -Method Post -Headers $uploadHeaders ` + -InFile $sig -ContentType "text/plain" + + Write-Host "Release $tag created ✓" + + # ── Push manifests to releases branch ───────────────────────────────── + - name: Push manifests to releases branch + shell: pwsh + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + run: | + git config user.name "Gitea Actions" + git config user.email "actions@gitea" + + $remote = "${{ gitea.server_url }}/${{ gitea.repository }}.git" + $authedRemote = $remote -replace "://", "://actions:$env:GITEA_TOKEN@" + + # Fetch or create the releases branch + git fetch origin releases 2>$null + git checkout -B releases origin/releases 2>$null || git checkout --orphan releases + + # Copy only the manifest files + git checkout ${{ github.sha }} -- manifests/ + + git add manifests/apps.json manifests/apps.json.sig manifests/latest.json + git commit -m "chore: update manifests for ${{ github.ref_name }}" --allow-empty + git push $authedRemote releases + Write-Host "Manifests pushed to releases branch ✓" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..81d6307 --- /dev/null +++ b/.gitignore @@ -0,0 +1,43 @@ +# Dependencies +node_modules/ + +# Build output +dist/ +dist-ssr/ + +# Tauri build artifacts +src-tauri/target/ +src-tauri/gen/ + +# Logs +*.log +npm-debug.log* + +# Editor +.vscode/* +!.vscode/extensions.json +.idea/ +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +# OS +.DS_Store +Thumbs.db + +# Keys — NEVER commit private keys +keys/ +*.key +*.pem +!manifests/*.json + +# Env +.env +.env.local +.env.*.local + +# Tauri signing env vars (set in CI secrets, not files) +# TAURI_SIGNING_PRIVATE_KEY +# TAURI_SIGNING_PRIVATE_KEY_PASSWORD diff --git a/.vs/PSG-Conduit.slnx/v18/Browse.VC.db b/.vs/PSG-Conduit.slnx/v18/Browse.VC.db new file mode 100644 index 0000000000000000000000000000000000000000..15211d04233b40f98a785ee2415aecde3ee3d5c1 GIT binary patch literal 8192 zcmeIuu?d7w5CqWG+#a?96C1b!OvDNdPB4%I`EA&+kqYJq#&2QRXeM~$&@bhi^KV8_@ zRumOM?A<5b+m$ox+zWF(^S~sTyR+86c9OFv`SVR?-jb9qS`RHJiE2UF-x4<$OvcqRUA>-* z^<8Y>VnY`jxwwjpja_Ww;;Jq-b+MU?&0TEaVoMiWx!BspHZHbxvDC%YTwLA7b}p_V zaZOQsQ3uyoCUGrMM^PtHXVKasU2A1g^YXu?`;vMWH%?_SotH5FznJh>_QkA(Lw?k~ zsQXZ*`%m|t?kC+F30vJ)x+jvK)!((|>i*O{srx6rSIVTF?2)cgUq{qUw63VTsE0`Z zT6>CgtYn__@3)uquP@p_)LYa?)K}C`)L%3}w4tb6w2^3_Xpm@Q(O}UK(NNJQqD@7^ zM8id!iAIR@e}k?$8C&bRb{#iaXW}bAN{SUDU<8bS5ikNqzz7%tBVYuKfDtePM!*Od z0V7}pjDQg^0!F|H7y%<-1dMir zTRE5CPVR5$AZPJA$^8pmDjK%d@8yPd{hH-PXGtfgU`%Twjub#aWp8nm!pY3Y}f!;h>Q4hQFt!H}; zIFRui#K9cGp&Z8H9Kn$s#nBwYu^h+oOyC4glsh3$<`holG$wL7XK*HGaW?00F6VJR z7chwnxrmFogvm_dQZD0iuHZ_pVk%d24cBrV*E5Y9xRIN`=NVaAq zyD>KaHz8XnWqQc=Qrb zc_#o@AzIM)#o{OnT< S$Y#2PY%a&!S2?ZfZ~O}>E4Xa{ literal 0 HcmV?d00001 diff --git a/.vs/PSG-Conduit.slnx/v18/Browse.VC.db-wal b/.vs/PSG-Conduit.slnx/v18/Browse.VC.db-wal new file mode 100644 index 0000000000000000000000000000000000000000..a27b5704dcf217d8ba1d6c6e43d9ca4e6331282c GIT binary patch literal 2045816 zcmeFa4|E*Kecy>8K@9(agwuGS5;Sc*Z2Fo@PU!dp>zM~ z_|T9w#6A~(_15aAp1u0ni{JOD@A$pn{7?Us7UksSk6vxO?e@t({OzUZ=No}*)xA#3 z39R$9^^P4w@3bsRyMzAU$+i(6w*7GQgZ}dTq~E5mJBHr!k-r=r|MJj|@$*CD=f{7| zlnBc}00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1VG?*AkZ7l zGX(k6z_*1RlLQF6SX- zkFOvA0w4eaAOHd&00JNY0w4eaAOHd&00JNY0w4eaAOHd&00JNY0w4eaZ%6{Ysh#=4 z*jR3JGIZN_I=ji15PI_~ zKK{jX!y|>6u}mX=v9D=S_FZqbI0F2Ad^9iM4?bA??C*W?(H`Omydhf^3Izfn00JNY z0w4eaAOHd&00JNY0w4eaAOHd&00JNY0w4eaAOHd&00JNY0{2RQY5#Xc^8!9F^T={* z`saTgaRlxaBhrHa2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?x zfWRA)fD%Vw{Ad2bcYO9YyIb4D5g3tV*v2{r1hq+JBHr!k-r=r|MJkTQ;TsN z0s4v$2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xJOBhXhj--* zXV2#DJk1UCt6t5u8-d%h*Bb4bul*cR4E42@WUNnq`i*wruDBg*;Y!6?Se~D^X0I$P zRTgLF7An^InyqbP(-zx0>dW@~ilx4scRiiAyxn5?+45p}VYa*^-2eS4X?3xPI0BWj zRhfBazHF^`ymhw|G+dv~Xgb1y44qDBk~)lepq$N{PP6N(Ar^|~cZ?J+Ph^Hch<9#J zCt0(1`MX79V(<7zBENuN`uul&{?qgOUO^mz2cWA#5kUY1KmY_l00ck)1V8`;KmY_l z00ck)1V8`;KmY_l00ck)1V8`;KmY_lV0!|JU%=DjKY03m_T%r^#xEc*Wy`z*?%OY5 z%a*aLdnyogs6;*w-bRao>lz1Q=eXY@<-Flr3Rgqn?R=Om^SCsW7 z%U^XmE-h`eH%QVS%lV7&3m{nV3nk#c z{-?8-pWenVAc{f2SnZg+x5l@MMvj&Z?8K3 zs&%cgA}g;;EHF3IjkDC+Iyojc4}{Lk#bR?u8_4m`h5USqbj&3~fbWv!1VN{9ts77T za9#ghBAvJ&*!7Ona&LK^H9r;bol3H^38=Q{scI>nZf}A&RR!VuO{wCYW?Tat=r=->J3wUt+0@yqL z-H~6w@Bh%&XaCL@FMl8W0=|wHTkHx1KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l z00ck)1V8`;KmY_l00h2v1Qfr3GtEEw#hp*=`kih30`^G78KLj@?H927#F*w6Knw5z z0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X0D-SBf!>R|^Mx~Ka(6DsLC={U zItqNwzwc4R^O0hmr6Rp=Bmmz|@Gfsg5@4o&XUbnmlp8MendaTPvS3{*&zC8H_3X^j z?98QdBCV(WhB{zPV6Ud&BH}Pb$?CYi*SzW0Y-wo`egQ(B4ZncI;sAaDv1*_E9#)-> zTTA&%6gP)=!#D}y4-~%DgOB#BZbQo znZ-}Cn@$R{lP;xEECBY7e^2BW@Wq+8oxL#ed!K|~z}I)MfxUqM2!H?xfB*=900@8p z2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfWX&?fZ`W$>8t<#gYRwpqxWs&7qC|< zOP;>pw_m`X!jGl=0%#FFAOHd&00JNY0w4eaAOHd&00JNY0w4eaAOHd&00JQJjYnYf zr9JsVp^&?~%$14tM$`5AKYJBDB40F+xRj?%g`f@^EefITwAS?~?jjO3TTiNTrx|M$ zDI$BVW?Ecp)a$0@X_aKjYPwF{Am3!+*aM2wPVv!2cy=lJyB=(N@L1X5p-UmKWih^x zf@%@6;TJHL`_MU|dS(^|zA!D=tyDj;aG(k((x$55s^dqpbg7a>E(+wFpxGbD8e1L+ zofprRHju0q#8U3HV3ra~H7sbfH>j3Lr3k2T*!7Ona&LK^H9r;bog4)`uj#vi-SDa2 zQiS-L+YTD_1_gy@!emyVtIaOS#@C%7I!e-;d)-b|TNdK68*M{+u`Vu1-&EduK<&pD z*r=5>ouKY@TIP-7wcBJKr_-|+zirwD^U!cRZoBHnJC_f~n55X78_5?=oyu*-671`4 zHHd6E{Jc`%qSHB0g^LoWYMiM@sx>;aTd%XBDzZz~N|&mjA~J_xK>6A7VtHYbUx+oS-~y0clZS;Xo|1aFMz${-y8V_yz|`o zk9_#hN4^NZfN#9vCXN^cKmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`; zKmY_l;7v(D@eBCib0?pA_W%3R-`~bBV4p;S#Ur?Hzkt2Ro;COd&_aAb00ck)1V8`; zKmY_l00ck)1V8`;KmY_l00ck)1m3^|HYeg*Ev$|Av_R7Li zWpQS1p<VN2A6`Xo^*9Dn8)&0EWCL{1RC*SzW0Lhpuf zX>n^U&*i@G3m~01`~p^};YqFodM60KfY@K6xH-HlUpRX*mvZr(Jz1&;{yU9 z00JNY0w4eaAOHd&00JNY0w4eaAOHdn9)Y{p_vH%{6S)tMtFo~~G3M_#i^Z6#h{Vyl zG**)p#X2!RB@xS%SCih0A|D%-*G$Zo+NC1M*2`m-q6Hi4p`M8X@CHsNAklQQ+iDxK z4p)=J+cm6o+qLX1*~*OVm>SF8X2(*Re!2850?(sQIf%5=vTJVL={5s9QF-xr==vIC zf%~PDi)~JqE_`-6Q*P~U>l%f}jzstr4Bop%N{10X~r5_b63%Hoq8yVRN^JGaO?raX{Y$;yq0a#3CS8(B_FxJB<(9VuedkG>x;X& z3C5iZVT9~Nksk#cO7IJatyI>VPEhwcEgOCTG`v}*(NxXS z>kIq>m|aP+*n?ld1L7CJ-tq5``~p7pEkE^hPyem={;g4V$7Qj9@Bsl3009sH0T2KI z5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T6hA2`GL62R}10divQEZ)@9^6}AXU#UQ)}^wuR~D8k zi!<;GfM0-!C4Jqk2HZ&iegUempRTZxu%8A3()F}ttvY_x0_6rQEE={QHbmLNFCZk5 z67&Fmb35r!+x0pd`U)n2*O$RBpuAXKm@O|^p=FCdC0Vz? zFQ7bAc|iOE*gO8w$S>fR@_+S*KmE^sugG5Z!!O`!3m00ck)1V8`;KmY_l z00ck)1V8`;KmY_l00ck)1V8`;KmY_l00cnb)e}(s0%jII`l+A#7(MjSOuqnHg%1dT00@8p2!H?xfB*=900@8p2!Oyh41qgGNArc#r*n62NV;@? z-D&%wl$(D&ps0tW755`e=Q+Oi+Vs~$E3GP5B`(V0-Iw?segTTU5q<$&9Bh)@1sm(3 z437fv22LlSy4UQs+9b^m+!cygpM-6OUjY09>W!5!@OwXLHT(kZF7wMFvrX{%KYNu+ zAYU|)dX}e5NoV^wDsTxXTW@t-rzy2wr&cp9t~Kg)({fW+(R7`4ct(8vROo-~)X_AU4B=J)eyW6_5U|lNDmr0O1JF_%9bE#aiqzuBN zyVh7CSkf7jQ*i2GiV~e!-)r7PG zstUp{fKFD)3h|hYO2oQtB>f_lF6fVy{<3yI7WBt!x5+$Cr)LkpfViO*H-~rS3un*f z?mR78PUI}bT&4WPXo~+F(OQy{cEA>;Y?EqPrVdu_1-Xk>G%C}2C9Sac)_YFvT7 zWY~N1j+gGXSpVw}D~Bx>(%}wNFtQyHTPOum{6|bj?XP+?9!;+)o*N!1%#7uR==`|1 z{Tt0j;Mz_%@c8d|U(;fzyLzKJZl2bQ%`Mj5PS9|fy@mL;Lp{EDIUQnp|1xxTY;o$a ztjclSbedhw=Aw9h$4KGwL}u}m?52~fchVz;-QuwVd&hqu@(bAaul{0o@?ZXqGW-I* zVII2RKtTWmKmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY{Z+yoTA zfbae7bN_qwhi9MJ#xLNYgk(Q`zi+>Q1BZ6?@e81p_<#TifB*=900@8p2!H?xfB*=9 z00?|-3G_w|@bI2Jn`=9ms?csZ>(SqXiuxg1O4^4+Pm+!Rn~0xk>A=oBkMuT0_yx?D zEVo_DR#~%^%|_cb2(aN7AheTAiDdT9#zt$I-$n`OY-V17Vci($5lli z9#>^!iDJy(ue7VUF|lCl)HZZ!tX9?}c}gOd(Yi=f>QLa{fTd5VNjWopm)l5n)6%Ds z1-}4pr9h;emR)n}PB(G|5aMUU8r$Toz|WSRhe#=R0OoY*J|sJxDYtgFb&cE|{Fc+C z)ud!?dbdbt&Ca;J%9@qZj*6R=yzE7+0Nh*FZ;Xh54GqXZV zO7f_vv2c?gu^7QNT`H^gy7JK`x^FI4*P1Ew91#Z`8zK~o)(dl$cU@Vo zSc_L)n7g$3(w=;wP{_eApwqb44O~CfDTa?KXMP8=GXVSo zXvih?Bc^eKAJ}oPV5)d+;HIhbjx2w%A$-38_U^N!$ z`(C$G)s{tFLfeo&>RRZ+;@^j<1f`Ww5vcx`-?=FH=CdiL-Oh%YV+m22JhudlYh9C6hk;RF#H<9DzWp7E_8pXicRK+IVQXE)jkKa!t!TWu~~k z8QOG{0yvfwMWNSap{}$tt@YJbW^AX{r%?M&0X^HkQeSLdVx`i^6}Dut^?C)_d~!b* zzi*x8df-G?pL`ot8g;UqD}e`Y$H{g|q18aka?`zsbHdf6ilh{N0aq&40vEW$FFY~0Db}R3(&e<_yrikJu`WAK)UOO*A`7iQgf#rO{k?&#A=&~R8MzPOv4VBERDFM5*Ro<)+5wD1TqWl}_G_ zu6&VmhE&9GAs?=qu6a@hA&ZnFjGTfyy@V;?7XZJ2*arZ90pzIRbvD$Vq-3Rg7aGH_ z(*14PmkNFX@C)#F=+}fdvR?pu$A2jD3kd$yy8gBU-}C;x?3t6r{=o+XKmY_l00ck) z1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00cnb0VbgM1-x%h{@?Mv28r`dHar@axY zDvQ=qWpQq{0>6OB7{RFKR}^2e&{@|i!!KZdzIf;8D6jl?Z%Ddyu6YlIcnHHeyR`8498A#Smuh7 zc3%lyA`Jb0U#TuvooWUQ!N$5PWWKLQ8{j(rZFVfB$x!?A6z~h^SbocC5+e$c-Slpe zDw~5@r3I>>vbb5<%ca#@YrNl%LSZwBw)}mc(sRpe`bn!xR%V5ks%KQxcz_~8&)Y$x ze3<~Q=82I zgY*SU8#aW^j_e?Wj{|KW4ZOutVGYLmFtz(CSyDd|G};@igIkELbOP!=?6_C(4Ohv) z^P0X(7gnEqE?m04(p9!mZ@3+CC3J5a`WfHrcB(GjGz6=nXDZQ1DLnJ0ektl&I#m8! zUT4iV_Ff{D-b=-f0LG2tweeA!Gmq2h*^A$H-RsyLx9-v~qw2;-CGXRiq}ZDq$rnzY z%5A!`HAiI2;pdg>Mszv{8YV@FQ-dT^HK;W@@C%^Z`kA?fibbRGc#O$S#_rK=Wol=> zFgBLkoD5GXw{@YrE#~gx5346MTuA3r@@r9>sNCM^35Li<{0$9Kq-$%*GM!z2)$0TX zgPP*G;gQ13SZ;`n(%jqrjbEsrS*eJ~z`Zjv__}<6?F4yVVym4@KW6N2O{vK2s zMzoa9QhY=PT#5LpmKJJ8`bq7i!Y^Q+g5CBNDzlXtDrdDmNj?fnwdT?vOQ|&SX$+O) zdIi~hazF1qx6bkklBoKVZ=*^jNtSO@O|({(Y^M}DyXl%@Ew7Q#$1>^uZfiPc-LoTO z@Arl5?)7~f*@wqDvY0Ums3Y5u{R*;V`9K$(BzfwBlhL~3t{^SHgkJz@I}?Q{yDZy% zn_-+Hqb*WL?X>KgTX(w6zz*GZm@1l|1AUEcGC1g$Qr@XKUApku=}ft`yRB=4Bog7n zFCZ4b>QY&?*NsHIJeYl?{;k0;AU)8fDh0oQSeYwi%}i|V)0Gc?0q_f;QG&@!U>iw4 z`~uVt8GZovn00JNY0w4eaAOHd&00JNY0w4eaAOHd&00JNY0w4eaAOHd&00JNY0&fHY zieEtG@BClS{V)Id&dzQ80**)pKSbZ}+b`ho{=)A+~dm}zY zMT-Iv&dpZt%pA-Yrl)f+pX1dfEqhNdIiysg^m?jKDc!rSIoFg8=}d%$KqSs(2iixw zZxZ5bV)pI#Xv(C|K2>4MAV&bdfOV(sA5f}KsPU%2m2KuTktkf!qG;^|N*liR+H{iw zIBq&6D_kuLb)}VQt*^E+V>`7zWgXsqiQnNDP`g))1^5NL9&Lc@__x`ylqRDk#clvq zui0(24cEgsMMe(r3uvr_eoV50exK5F%WHVo9jTGu0D8x}P7&g@!G5F}pK8>K=FsC(KVtG3^2u9{{9oK#UT4iWTnz$`?vP#Dt?#yd zm-bEuU5$D}+|`l;)a`1stLy)LuiL4bJpqjUQq)~W1+n|3(tD}(rW4e?PRqPeyf!|{ zZPMx4i{Ccwf>~a;gH#fo!%QoYX?d&xA(TU3|*NtfDK#v`w#Hkxy zQ;$?@bZEC;XG8C*R=QLL6=gk*;rU&3%9pCRIlL=hID0mC=V{d_D%9L3Hz>^2${$gV zOj|k70czU}be#Oc2)}?U6>EVmX2o;EBZZl<+z_1*_qKnd*$7{JE&F;C$T;WaZ z7r@@}ABp?|K6Uq3R=@m~AN>#T3-~%da>cGd00ck)1V8`;KmY_l00ck)1V8`;KmY_l z00ck)1V8`;KmY_l00ck)1VG?xM?mol`09JS!_R;Ir~dUeegO|l#d(On-?v}Dk-eWA z$S;7B;R6C700JNY0w4eaAOHfdn!x7dk$mCw>D<;)Nd?ctIfg=Z{`FyH_O`TwW^RjL zY3V{AIg^;;Z`!8jR+}vTY@6>mo?74aofTJIq{=|0LPb$alX#SNQb;9$w9s2gA-`$5 zJNE&g>E(JXY4`=qJTqUmR>^W8RJ;u|Z9hq#nz7$Uu$C4r6np0m@rt@R5mwYh+b_xd zA5tr7l4hW?N*SdJ3%>xHS<`_mi@KghB&~&-K{mhWx@slH&pV0^k?W zuGtwHW%WVWhhmFvAU(U*xCOQJO5`?6SoU%)o9{jZ5<2G{X#vtubuMoZ!; z`r3BHDKc`POM%m3<2$F@4D8Ttht;c+WmsdI3fwQHyi;?!bm6npnR07)Th~bL8j0{J z7`%6jA`oXKsi35_I|{MmzeFmspENLh6#o?nv^$7?&nm8E0&YbH1F1x1?y6IzFa9=volMxGndNLxP?-l zN)*No&lKOY6s#S`_naNq_nJ4!KulU%+*-?X*SHUbHelg#h{o*iRt{OL8>j+`w5ck{ zZ#y!JyzO8-$~K}v8%Rc7Vku__zW{@E0sI1(ZoFi{FF+a(*Vm*$FgG_4()qA|k=s|O zsGs5&i_nIkSnN&h3~eVT`L!!tN49QUd_SyoAYvhPAW{zM2t)2J$?;HZp%h4Z;$?2+ z{;Jmr!cI=P3;0I&3t;c~ACCM2-v0l7_22yG<{$mQUiQS*V*lU+0w4eaAOHd&00JNY z0w4eaAOHd&00JNY0w4eaAOHd&00JNY0w4eaAOHd&@BkA~`~uwn`AfD+;Z0w4eaAOHd&00M7n0-M!`^M!Nga$6grKseNKcU+1H z*YMgRusi7w#P6fZRNGiSF4oeVTM@S|)`RQ1*OC=DofV3P*C$0d|K1>)6+zz9LHMMJ z#w>!lb`Z8+C|fT>B9btu^YpFLhoDH|+2rPw^ag$bH3d?9_H|P53xHohJ8)M>F1R2f z@Rh7k@#wTS;$=l^sj@gXTe&lHFkhIS&b=H8i_)_9^pZnL7nWX6omfgLulHiIfPj<@ z=}g2TNo_Anh~lV>LPSIYgp|}@lP_(*M^h$}tU}+X+GP%M1n>)hUjY09q9&cGon+Vl zRNPk@Gmu_eRUzq~9ihhp`~s4GUkbcTDskYGf^p|UsCZ2j`BC6=_ysU$wXmAACQLGY{RGLQW_mCn(!wu*E{|TfQ*~)b zAFRfGPt;?y4WfRrZkz5&q|$q-*b%_k<;82a$vjS{XD@!+b+5zPgiAM5)x?lO-ls81 zu{Sr8FPu7++jQlo7Bw?JuiP+3_74M9xF~U|#+e2$@C%TxX7CH3+X(k|>`gE&E)u(X zqq%%xVj|azE9<)32^ub|uHxGcy~2v+RAtlkPU|9*TtaUHY0MBkhf%JV#q&Ex3YRBx zL%g{DjVAdW+D$D`>_i|CJ7TM_Q?FEDX`Krjk-y7rqwZ7to~1-0%w^rA5i= z`p$|Q2B!?GkS=MAofztVRM{kSu?c{xOcFI#s)Zz12rV5bTxHREVXpG7E6WvY@yZKx zm*5uwzkrl96n+8o^0a=lLjeg2QlO49 z>FWXI+AOW0Yje!lATQNUptK?NpfwVt25yUOmU+rdaeXti>92=YTGINEGB4}!40b&7 z(T9dW`ZZzm$^Bd+vvpQFFHE%(?uC6DHJlZ$Yq^h;!nS+u&j~LL|0mJIo0z5ceqYG$ zUf;)&eR!NBiy2dlW>MGt{R*;V`9MOrBzZ~-m(jYofSPqsrm-up$GX^a8>wzu`UJlK zD~wc3mjb6{*W9|(ja&hQ_}Q=qegW_c;D!jPZug}<`9h(PySp6Us`{*P`+Jq1gD)DW z)8Hvn{Y4)~1+I}~>#dIKG$k(vr&cp9t~Kg)({fW+0l$FC;>_Ga#iG%qkTvr=zvO;S z9g4K;jg?G~94Uh^{&(sLgq(t(j_3xn@v22merL115C-;?HiS z`iX@DRX~w8RRvcaKT^$0l`JZ9`hum6<)Un*4Wv<=SSqZ+OjS{Gq)1yK2Cg62v69|T zSt8Iy&-0o-IWRVS^0{EnCUli;)Enfu#>NsQ%e`&T|HCgJwiJM0K!rbZh{tq%#5t$~ zM|A7LhH!qWWtplw@6|hDKcNhWQ_V`vTi#A?Urxt&JG$G-)K1=kY)6_{OE6O;}=knj`v~ue&2op$MT=N z2fqMHj1LHa00@8p2!H@5usM4yUznWCZI$^HOp>>;fL|0$sI%fLKMKlpOl1{K%8Zr5 zx^!LA6Q@^Yijcf|o#sj#W>K?ZrSnl0T1wfXu=I+0TPNc90>ER8OnOy5my)q&ShjEhfjuyR`K(Bq9le zI#1u4X6S2&pi}@>ME$I9P9EV()UBhu?ZgGF`_k8km3AYo=-+BGn?@guHMiPida|}^ z4gkLZA-GFV>kgHyhJMC(TMp?ns&?S5x$Us}=*q`p@9~GYd~>tF&;KeV2t$r0-wrEh zKUqGI5GF~Unz7$Uj+H*jV(;7`UQstE!iu^|BJ`SFBXbi!`TCGjRB6RPWtGyW3d@B% zI=v{aozvck)jUOOsj@gXTe&lHFkhIS&b=H8i>^5&n5i~NN6aSklWxXOFFB-?KE0j} zB3u|LYYiQdrff)OVyCl^Bo47MLx_mNvZ@+ot?S!{IPB2RQ=m*vM1iygx2K8fce??;k((Z--z%M}S+cK}Ml8`ceQAl6C;1>YD z0J?yPo}cydWRJmg&f!>VpK>9Q*YJx8PiVU5$hcf6b{2liX;Q~1H+U}av-=Fcob!*X2$41u(gF-%g01s= zyfP{RQ)y@xW}+)zU)-H9oH>)bbAgYFA}u<_Pmcnh^Lw{FN~M-l^{dp{Xj0xRsWyzU_{Cy|A zP}nVAtFU+cg~%_!`-zJmYM*>$b}w6Lv48LZ0T2KI5C8!X009sH0T2KI5C8!X009sH z0T2KI5C8!X009sH0T2KI5C8!Xcz_8gegVgS{oybC`tf6L-^MTCxOBWn>HB^A1r+k{ zyC=T@N{$Z*fB*=900=yg1QrS-g~>v$Me=3$cK1f8ncxAA_~iBDVxsx-!rb%AWovHX zQu)1>l8gnkWQG^Yr^fIy9#9?Q=axwsH#z%SsM*EA??(_;I3l6t}~Af>ev74Due z!Y|;e_3rZ3lGXCsjWrR8Q4)8Ww1~XwrDcoo3rLIvXwE$e?sP`7x`t-k!!ICFy2CHv zg}F=c3y_^DB&Atwh`_4}8;)Hn&zCD@Yj$R7cIHx9=&aK*X?-%Z39?oH;pzN!1GXq- zn^enUBNe^qaxbVHRjOI3dCS|$?aS%-Zb$Dur*`rVWOFifTM5&Mj&@i%Y_Sl20TqjR zA;hBo@ZzZSlgUUjepdFX{Q}rK{^OBfz^%(4oBfr2KX4j;0T1LWClne4KmY_l00ck) z1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00eXbieEru>DvGOGgm+U(l&kp zC!|b{(f9lI3phUVrF--XpbhW=0T2KI5CDPKltAtHNa4an?gL!O-?*JA-G`i)koaTgQ7={!W| z!}jWR--Ta*e^i-jD~NSmf=B`j7Ng7ex}7SCrXrTS@)BW$T5aK-Ov*q%+Q?Ytk%PYf9fbZF!&=Mz9Q0p*kmz@UZP$NBQ*SxPWzE`ueb$ zZJlGy<_W)mK}71DpP!n~4!;0p#(uGP?hvo2n-gJ0O}qdkng2s-MNQHSBr%XON}Uca z+|m68N>(^e-Dz(m)6}h{%HrH?<<88(d|`Sz_i`vK3Ip6XDY`j}mM`H;dfk=~~6Uf-85OibiHJkF8D8zhP`f4_n(Nik3-o+MB8 z;hEzR(LtqqQ!%Vd_xpXNx+WY=sOtGKvvVlB|89;{t&tWfie zZenGPH2eaZF8l&!<`yaz3Em^2I|XN#>WylX!zxpzZ;_ON&DG7R8+SPc@43SiC9C85 zUh}3~3+1WdQuqZVolHR8haL9{e$+ur9ZleQO?o(GH+=HBaH+x5y+otl5H5Jk0HfOM zlJt7r306ffM0)e^IgPR`>M`1e^ikJBmk;-r*IBcTy_ZO(_foMVfN`UEZG4pG%;R)= z_Tsl)_c}IJVV7?Fs*&|XiGU@CV@y))&5h&>r%vTIT|QV6Rn?FF=9Pg`v~-|hQj|C~ zNHPsxYK;#30_e6r>XqU#CLaOwJ9;t(2>TalM9#0X@C#tob=~a*4cFhHS6H!}s%*O6 zX*VHBE?+0V0QQdmMC2Fn1C?+81M9ng`q$wX@S47GLS`TU0w4eaAOHd&00JNY0w4ea zAOHd&00JNY0w4eaAOHd&00JNY0w4eaAn&6k$Ldb8>8j%G+ zIv-VE0l$FaX7%BG;oQ00)2?F~3*fpWQCUb3sHliV z+f^XNNp+!PZ|QIt81DU2eH5+={t;y&beIQoQ=mQS9e_3sTBJ?Q+lOC(B4LGJK)~u# zO82f`NaWf@daFUy_Nw|yj0?B`%P6Y9_dNv-ILHyeFJRqi`v;UhDAaiS zYz5UDg}o-3)2fWLp)wN9K4tI=fL}ly8(g}tuuKL;@CzW3c86K8$SQbAWErlOgWF3h z-F7W|OSUp&JEq1GqWa7oOKJM$(zggak3QuvxB|d0z~86z+>rp5Y3q5{E!6e;g|`&m z&zoE>;1}@Be3|1JY!J?F1k#pWeH<0I6qKzeRk_oY8mLpNnHJX?^}1R+-O4RkZfXkAgA_Rar%IP-CTVT9^U9 z06XZ~WL9xZA;`{%SV8>wuk;jlnpobA14(L9MMMHXh`6`Kup_$f|CSDTf+`NEkqxve#!k>t{Uej_Wp z0>Cd|aqhX9#kda<1_`ktf^OZl`O=VQ*EAmkMM zz9URgA}0vnYun^U&t2m_bWUo~z9__Q<&ed~fhwR#o2r7Vj=!ou8KE94 zk^gIlqv4CPl{SE1fJY8m(K(Kl{*89E*(DYDx)VgeiF4!wP^W8?d&}#r+5OYOF93c4 zwr_*3Cu-u)Ddy{Vm{?c^lyKtvkxXISY##6s#oq#V={hTPuQ*MxBa z`GZIX29iUjd1&gddgNbac;s?!c%(2hmK);F>HQncM&Q~`H}LrHcwf_^m~T420QQc5 zEb{WnSo&z+{fk7CG*gv= zyjRMX%ZqAB{1>ff=C3?cvb+w9Llh+{_C`;U9(_933+2t)z8kgM=_RN7mV`E$obufj z9$?z-v}mH^O4}>RrIAkmLi+WwWe2H<7kS# zBV+kOvADZeHSAm6t=Qpr&Mj7!XXdTS42vMACb5>6<`ynnRIA>~h2%b$BL}20yEr)+ zf2T-tKIsygZs1;=CLxEn=C-K{Tzo8`(?s(^A1lHyfX@hQ+@{8vv{j}JZ`6_{C&U?< zTewtyuVqZkCU7SkOtD${ltpo&FjAN-8-y1CKX330n3rg#=kPN*VJfJa zep9{lzy+QNVZC&wiQ|#FlH!z-Yz6WXcFP&$v+o@9A*p1dTZY}`70QdzYvPIu* zIqjfPwfQA3)Wedb4SoS}ud8*sVPr&`jb6;c9i1MHHo4-_X>Y`N7Okbq;@oWI&dfnR z%6mB!7F~0E*RD26t;{CcGueB3$suJ>m0nN6fpB4TRc58^FBnQ^l2+TR>Z|C2&jeUp zOG#x-#sT-W$MAsFOeEQoG(zC}RQ2719DzWp?m_7(Q{0S)mbxU49LN_=oyzs7TaGS? zWSYaThxGTLa=xOaTn#5E8gTW!h=>uAeo~8fj*jwc^W7V~Ad==?`g%YqjpuE{8h-9|I3OJ&twH+;$`JQu|e zGDC}6q;jo}SH}maUzgz*KwYtNmeZXOwWm1db-!5I>=dX1Q|US%W}+)zU);@2Fz#I7 zJ$R%=XSZJRclZT(%=dyd;X$riJZ>Di0lcHQeR4-J=Y{Hm_#u1hqmNIVLRNs7I>5q<-*8Ha4YPIeqoGxPJxKuI*d z!75yoI921)y77`#YjkM0US~rUtCy^mE>&%%cY$93`~u?2y6$#@hRdp}__jl@uwps& zk?DG;4eXO#LT>|U%n&_?QEFoG{Em^r<%vwYgSb%kbdvQ>dXc(Yyi9$B{f+zr{>9sV z`1_kb^rL4+Y1xkPSBA#FLjT|c0w4eaAOHd&00JNY0w4eaAOHd&00JNY0w4eaAOHd& z00JNY0w4eaAOHd&@J1(aVDHYM$5r}mCFU0}WU+tn0Ra#I0T2KI5C8!X009sH0T2KI5C8!X009sH z0T2KI5C8!X009sH0T2KI5O{zIj8oaiqj>?JntSr+{?{*l_6M0?KyLgmhUh=!WGE&a}a`0+1XUV47M5x7>}>$IG}I#1RCJ9Z4c)3PY(4*LHL{U3c; zYyy@~^x^qMKQjLA7<$V`{&E+s%#DAAB{?(xmGR+Ii;ui~^7x6d!jBz$_Q=)4k01Kz zpt-aQ=L*cR6sbHQh$dZ3m5dg8IUz3v-vgcOqYS z>sxcZF=L5pPT=S}WXr7nWnxJtry4bDZlO}XTwat5Q?jl#z3Q6v%>0#SikqWWzHs*J z?mJ7S-D`Um`~1$i#me%`yx^gwv6h$S7A{*v^R2Z17;nj{dhLLIUYwkazc*dqw`*?G z4cv><1kYP@+l?39i;s2NjjC63zjfN`xGnFdYu6f1wbKY1Ro{BjGJdK~;I4R`hU;6C zvrky_Pgu`AVJ$piz2^yQ=?Uw*o|rUlW%=&9({Tc?L!0F$A1l5zo-bUukn0`gI9MTU zYFn+ade9-%8!N_zVRB@3qn!SXUOTWTPpT zN3nPKM85F+sa$V1+6&u(-E!9L_^7Dwq#vw((6?yy$&7tQ>oYcIWr&hkQ}QlK@h*zB z<0FL&6S)uYA~kL&Sy5YMrEApU4gC|M9N|G56SI9L8%&8TiVKC2!ek-Wk`Fv2%ToBq z`y61HEIJlHM7cS8EMJ(M%x#4Yin^BdCiPsl(^>JA9|e(fc+pW-SyPt3(Yod}=@_kR zti1--!j+1(uslD{t5J9o(yPQlrB`_My6*-SW#q279Vs(btaS3(D+^1N#TmM`SnF%H zQZ_p-SyCIK^I?nKNEb$HDo!tzycC{&c0mm{(XW}k(WCjo>C?F$HE+6%^WzG-tU^j( zk0}JD6~r%-1m%*sF0Okzk>Y0c;e6rTx!l$UFON8;j!UPO25!Fo`>0YfeJwk^Ubj7 z`dQzcJi^cVR(Nra3s_G8*ZqghZ0mmiR&(zsy=2wgYLkX9^|sw{DgUq~maMMtthnl; z46^mOtCG-(!=k3G@Dl}8AjL^_QoW_a`NG&(Zu9+8eH4`ZBL+f@4((Cz04!6%*)Uly zTghs9?Zz7Q8-aUU?upp7Ltn-#hQ6B;4Z~Uvjl`=q9|PLPRK?!o59JFJ6S>U-KdR&^ zm3%v_99yz{puTI=bSm_Ev4@7y6?Q8y<-{HspKt=Vj(;U`}oQi>|A z7^tjL`cz?8X*a1;S+Z_A&8}-X?Txs9FIv=%&&^iu%pBySyqC}M@?LX%*RD1l8l2PM zn8xgWddVTB^y&3<5aGgT1Z}uh$+fG#W~Va|i{va8%g>e<%L}vRCHZRIs1@n1iAyEk}2s1|uu+h2FuzV!8gQXFZ;HYL)kjI^N&H1m|P z;n=0}e3@?NXJ?jXXD*d9FNf6LI{{_e?6%s5<`k}OHrlRXrQ2qs;fyWW%8c#Q`jmBe zVgIO98u>JaN2FJf%_sNs-gE1$bY57G9qxsF8#SC2-lzAkCdQM(wtMZ*2`>%*CmHaX zn5Fi9U&!uW-^Y=Cc$_1P8T-k%{R*;V`9Pg`l04OiXSA-kD=>}xjaSW*W zGiP#JYofCAdwEt5sk$fM_h}VAS;M<-{?k-BGb^-IJ)@$=0~CJ1G#KeK{A#qT%`QEq zTX%xhcnDsnGw0s&I%~FZwYSc1%i`o}4&!`_i6#p-{-( zUFKLhPyWwd1tecIP^ZCDruvIMgs2|V%{>iZ>0zqVl-N48nrU&ZQLmepv-YCa8LCpQ zQ|C2GUqS7}ZL_x)e8o1M5HDfJUg=WBQ95_+$`T&BoLaihhl~9wX?3yKdvQ0f)ORj$ z`s*FLHT^2JRyujJq~2Ik5yQ&l({u5nX&fSD5VA-;+mTc7(-GZs zc3j_U-lUrhX=!n5Ezj=)KNJq@#oooA-O3@0g#%SUkv3HY`E5sLk<)#GhA+xCI!4++ zLMN7Tb|uSH6{UV8{b++Oe)Lo{>J>~E!oc&I)J*J#PxY2PJ&aymhzji9HuN*%k%-dw zgvVj-c*MH6AbnHmy%c*;$lmdpH;UJ8lX;v@&tCktX&0=0xOC%Jb>l8l?njMDioLlJ zegm@U%1zCWPF!B8Z_(0$DqNH}RpU(6pw{S63->x3YEM$K(!C1}Z}{za>QPv6b9fhf zE0(+Sw73?E*Fby}nT-CzpCihV#bdf~??g;F5t+G=j({;Eg!Wa;x>JU2X2 zm>J6r@#pmZjV8Ucvz>0>@!#>jro~Qo^+t1iWZ#P`>$=+s=;a~RHSukSdVKM6I>hw; zW$5hK;?!YTmE%fAlJT{;cz(x7;qpXg@ssSPldN}!uggy#q`wyX9{C0Q`R9M)@JD~- z#h+tw1a^$SGDPp|Ut#O<0Ra#I0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X z009sH0T2KI5O_lqIIwr;5YzS#{dMROurs%FXg~d&V9TO;0na~E`oZ4!{mh@UI0E5} z0rmwS5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sHfd`ZT zpDPf}3n=tn`P7qt@9{rlegT*l@PM9C6dMFU00ck)1V8`;KmY_l00ck)1V8`;KmY_l z00ck)1V8`;KmY_l00ck)1QG(L+1F@Zz(3A^=FrDye*fy|_?L$c9+(*#KR^C!k6s-g zKDGGB%O{VY7%TkPv1gB5J^c8gj~?1}U}p4V`#-n;@ZQhu+1&kw{3rA88~M_Rv+Jw7 z>cg)LfA`K$@0{Q9j@&Qj&JKN?GJ8!vy~C&Tg}1*w*Lyn;PLTv`31hX3kmnhTA5(%m zOlG9Ik9g^a9t#7MUp5wsqMz%#qD2$^3-c;Nrho55zVOz!=6Yks60xA9dXd;NtACjW zj+(wXYOzQvyYDQScCYPO>{E@KuBDL!r%S7Ns7eYs6$}(Uz1wcEm@D5pO(C&b-c8r8 zHJoavK>=ue>q*P_sZx~g6|X}fLafQzC#?A=tmmGv7M`%)^MtkZg!NrdOd7YMz_t`} z#G!aJv{`QQvEobP`ND+@xn3B;I1c<0*4Z#Tka6L-dOnP4Ca2caxV$%u)(dl$cU@Vo zSc_L)n7h2VK{Vc-&FI{OHTDI z$*XKE8;^v|_kRFrPWJ|n9LQtgh2ia!n8{l9nf5Pp;uE1g`8$EcJoiFlvXhA1?nEp{VCTe7C&Bawm` z$H5v)R=9~Cw6QmOl*cgcQS*+1DF=M;uefrBh2G7DZrpirOZAA5}`Gr)HvpOXWObu;&13S+Bnu2cY)fqvFECy(&6z7<}a;{w(b zz;*v&Guyh~zt!CPNiSJ7x7uX!XWKkpr8q|=tLr-}uDU3LY(4I(By`CsRrrYlDv;u& zI;q~$;V>}V`=$CQDEUVWgcu#FW_tW#Eo@r2KR*@!uI05GYZS^>2`6U`5SI}H*>_t` zn}&CG;H|msFc`F6m}2kohj>u9%>qBF2l~|Mm8>wXozvb(!rEC&mBqQ)%AJ{m ze3bWc7>G0saNnf3<18>AjoJP5l0!=A)9dLV!i6-9w<*{kMa4|@Vsh=Oui5EL#3DHh zDI}tFwWbR-4@FF6O~wKDwa4&))lB;AQ*GFT9DzWp?m=nkDQ?C?OEvkC13bKEkGkdP zk{DeN>F+`1eDThNmeN^@DH?D|olW`*l+j}r?;IWFmH+MyUXU<)y}$0Xed+4~r8v@x zZAzq78EHcmXyz$n!?8={`EsRf&CV>%&Ri;IUJkbjaUQOg1AE8qs$`{OgKH}@wo~g< z*5QTyqf%+)(-CP$;}{l1Xhy}pkl`|vnN7BfyF%=-HkWJ!vFI`JfVst?a-U2#{C z?oCBKPWSs#;N|qn^wo<7W*h5aAaM%7OM^6a8k^l#J2g6pR%g`Z`)vcPNcJ{6meOSG zou}wqgg8Y;4(!2Di;eG`ZZoixsIdGT=xdAx?w3;DsX1M`@Y(51xwX5kYcweHTTYW! z2NVq6yG4nn6yFwV-L6<2-?FB<-Iw;{ z3xz`N?lQ;98S;PjDj@lyfjSMIGSy%7A;b}~_4F{+X-aIJTFtb$)~MG_%UQ)y>kL&X z*Qp!AJ<|p7Ha+b1>E@SjQL?17obH5p2}R6nrE{12b{Zjuhc2gXB-V z4(-cBCv1gSneiGNpk_TbrX`_o-4j=<4}J~K4_o<~1%>bD;G#MsQqpFgp7V(j=Y9=8g=R5)|& zXOEpc`oW|7j(p|F`w#!g;blsS4+ww&2!H?xfB*=900@8p2!H?xfB*=9!0S!m`@Si( zjtjj}68W0!TxVYTO^VPZ<+T`U*0%SqgWcoYb2E!qt#_BNPWkQ%d6kjctkcrdApT>*s#m8Xx$Shl86=2w8VfQ$933iWR1A*Nm>>e|W03*41%3UjVq)1yg z!R|5g4uaj|%-ll7BFS>>rYJlrVfWZrQ9UGJ_s9pgB@1?sis8ZoXZJ|AsyTMM8qEth z8vNn+?f5@Fdw1#id9qEgn8%0{Sm%eVp&dJh-f3BsbO-&<<`P677Keb%FNi)ozvxHC z-yK75`N&`HqLsPvudpO%#=r9FVimkrkqR=(+i!6XaRjcGtZPlLx@J8yf907X;s}tn z2;vC%FY@X@zTIR{-)NJ|e5HK3yjbiZjzH8>5Jv!U1a1f`J7y%rP3;gzV9iDx0mKpD z4>=O^M1yOu9)$pL1jwupaRh`HG~x&(u?7aR9z-00!~tKJi_$0e(Db=A=taRkzSz_&I3bHovd11e<1=#dPT(-z)oOH{-W5MvVd zU$%FV0FmrZ`{oR^~mVjw{Z^ zbYx{lj|l}mP-_CS|9&lC{3l_Db>yRbCAvI(o6-wFA=j z&{SmKuDLLxt5}OyUYNVoJNRg59{Cinor%)Lt_K9ltNLWqXI}cKT1U-^CP^`4zJbDx zrJ0N5tbrR#+*snq5;vA?BKtMflMFYOxUo#`B5`9W1a~GaVuq#>H@m;&xB(*Y|XiwvGKfUCTGTuzDC)0y)p%=*&(%q&e7)obir?bcug410W z`~ps$f?q&OQ<^2WLhuVHOibjq&hkbcdJ!-K&E(st(x{W=)R<$6hT)Iaj+5<311Por z%%)3oIjl=GgRxS!W@naWXD*dXR)&WIH~dswKlRrf8GAQ47|DeTcc?#_xqE$Io+112 zxOP7tZ|d(?kR{6pGJQ#sGpdphxsPYG=;hMAsbH421V|=%(oB@VU2!|sLhLbMx<&^Z z>n_DixE;Jco*Ar2wjVg1fa*`P+iGVNTcl|=+HO_~w_V#N50)Y$2R7pXegW_cAc;3M zPwo_`HBCuMFl+n)QtMe}bp>mv9C1o6d38#aW*;1|H(j<7x_nl~Fh zY@+)ciU`0w!4)k;{O&qlYo64bPN!#Yo+={3c3!y|>6 zvD^?HqkG%G(If+X+vx@#{~hmZTI_UJZ#2h8_Pw~WuDhL};rdk9#J3&l@x{yO5YzjY zp|fL)Q-@_$jw=*MDd((se#c1R@!A&K&#MV<(S(@aVoHUpeyr!+&yk`JvD3 z`3xn;2LwO>1VG?TN#Jk4cOMtw@wI9n4J ztta{Ly6Ob>Eq`kAdua!$RF7NJBIRVmr`&_aO_$QOyUiw*#E|@(qvWK!wp(7UOY@rg zZtyM91|rxOAEY$eEA*_Ywa#Wk)%tG!wyez?Z5mrNNYt8Sz}U6DwmVs5I@jb;pa$%o zq~Dq*R?A9~voZyFbR#Tj;Is`y3iEx7l!drK(YB87d*nM5wpF|$BV)NkzeV~<(hI^bpzAU|ay3g( z$MSvoyd*00Z7X9x?SGt&yt{aZgVeGxcTuh4>>^cmRP*HQ<4SBk9^-1IhQ=w(<%FI9K2(;%NXb^FvA=#vzF0rxRY9ex4u3t;zz(FcA3?=HhH zAXDxFSqIIrDfSMZ$QPccDTA~80Yo=cH`py_U75H=KSWRj79x?YJ}I6JEicSHzg#Be z%%$>st?f6btDqHS!KO|`FQ&+}F5X44c6_98VIuc|@R`W%q$F`{wRl7SgeXT?fQBhC z+h?-D6yJTLR$M5I6ebI~mVDssSr5WME=Gaq;THf|2V@@Wgs*999HQR-`x*8_BhSLe0_C`Fhs%R}$7UyOw^!iHi3wY`8{n^z2nSV$5 z9{d7W90K?Sz%RgyqNZ<-TKU4+v%Bvs@hL%?TY~m8eucPLS)Q4b(`&((aPGX}*y+IR^_-i`m5pZ#m-i6Wd5PktA>t@kR;0O&B$o)6DH;5NKqV(XCh7{QksBmM68%x|+s_J-Mp@kbu+*snq5;vB( zu@oxIV(;9ceBt!z+~x!yrbst|($_c8jV1g7n4*9gBZ$ArQ)+hCF3BpA!6Or&>sP`- z91o0pkVe1ORLUg5Xoa9_n|mV%xLl`a^EwwjmyiA)R0hG(QhJ6F9}zoJ%?F3ysD*OL z^eXY_U0+eWb99tf{<}ALK|=kuzwWes>FWWdIMRx3N+jztNTMfgIN&K`?+*slrf(xz z4p(Prjr$6f`)HI^$I`6ByD#zk=9BxmLH5Pr*P(rPk)XnMCuDai4z(gO88KykCOH(xk&CbzXF zo~`hg#H^S1#oJu|eV@{E%WHVoE#55aSA{+X7|9&=xTx`yZ+<9bUKBK1E>*?WdOBZu z=9O4WJ0qtD_m z>CvS&mJ6F5`~u=Zx86&cCmKh6SiE+dzAsLvXD@zh6J4Y1#*d0itFUjr}GX6B&3gNpQP*3c1c>I0kh_pabwnejhZ!Q(l={` z6ML>17Fk_<(Nca>Vc{3xwc!__NN?{kR6NPpt8yQxbHa6FoIGg0mvM#rO^_A0#l%iV2*+n@-HBa6ouEcUZOSUww zR*oo6aZksz%~s|;q>d}j#dKt1nc8NOBQvg6_A3*~$|XBZ0vUb*REMKJRt5&YfY`Hh zFuizO-xZ2i7LvNgNSjl^FCgY3nm+T#i7w${(O{>+*mcnOSUnBqR2R)gC4=o)KJ99c zl-hfrr0@&Ko{pUv)((CF@C#srvFHQ80Qdzs+5HG)9rPFuegW_cpjkjk>=<<#3}hXU zbwJhuSqEet52~z#USKMI0ga=#2p3JUX$!cq#Em6xEaQ3H>6!1ivBZrfZY*(Q`Jmod!Y=@R0Ti|regVoT z=k?G^tB>sA7tr2d!sg_a29L_Agyz&eJ3?kGi6oVx@Zj75Rq^FWlvHGJ4Zi>h^2WN$ z#pEUH^=Jd^mJ@yf@C#U;pNC%nL6CLT6uX$aHl!q_eH<0I6qKze>4?*mI#Z`sGcB$) z>UGm{E^5*GUibx6;1|ICcS`UJSmCZL22DcjW71b!pr?xF%|?>_c=oJ3*)-lLUTYQx zq|@oyn{JEE%xEt(_*K)dZRgRp4M}@ITC3=*WFIg zaQ)=l1LGHPg5K$$X5!`xzj|x+Q_o)g?Eh5%=Fcl_Y!_?L%Hj5tH%=f{8T(W~Rb zrxqW1`Q-5vV}&0(_Uw_XhaW%m(L=iq%#40)|L67}-ut;do4db||78AsBVQVEc71hM zefX8(@80?8o%1{1k^AM`*`be9X0OSocldO^@b8;(WG;v!z+XZ34YUz-8Y`r`eymtMnJ-LFcQfY6yfz2^8(zKj{tQG{IQJFS&3eFN)Hs&r`MQpj(Gu?7Z5d* zlGXK{6_+{NB#YDr<8QRC5ioB0Biy(pzf!T5-qJ~91uN>1q}eI-)IQ9J9L@EBL`#SB zg|V^R=KJ|DCQRpxKSz|IidZ<1-rS^B*gWv7aUuhMt(}q5Aq8ypFa-aj$wi)O+<=5%TQOWQSN8n99FJQNLRey&5 zo{8oKjKAX-FFWu1FE>YzTSEsaEI{Fx3TKY}?6H$aKX`QCk*^$i|KUG5y!_B-_IzgK z*v|hr_5ZP-8I=q@gfbw&FTC}wx!xFmf}9M5LeW6Y2^`ZhOL>-@*1gbX z*`gQ89UZa`$T}#pM5YXC^c2YkrgOcr`hFvM;_>Dxoz#r*gg7NIb%4 zBe$G&b?Q`f*HnvEpA>aLmy$&5Gd5?IlTi|DDy~6vmspB-QLG&wDO{MyeSjCKaXZP1 zYGR|wZYkpp{S%@ba|@Ts@3oAH**=pEqFL0%g~CW-vH-hB#dJrVNC#QRYbWdYpg)yA zdiwP4k4>|vzpNg!_J6IrB7GHgnMeDT7SmJiWHc^9{xTnif+4%iX!x7ci@WjF$<*i_WIPdkm%)Bd~d#%*`qtFE%b_}y#1TTPWj zDnhbp!jlytaz`1g03!9h?>^d4-FfW6GT7duyT`3>j*_;VHmPN5eUg4ll$2&e zyRB=@jXr7L7Nuo1?{>py7v4U}r@u8y-|}i*c5$Igb*JuB-98(gkITN|w%v}?q$_v7 z@_%c508}W>rC;jlZ;p>4%sxmmCy-KoPSA^HA-om%^DN$h(2GJPj==AJ&wu;rKmQ-z z|MES=5tyVr5Jv!U1Q16+T>lV90C5Bcdj!)vGL|nCi@SSO!##F#OTvsL;-TMSWqD@a z(hP?9Ex5J3G`DcsqQnotjb-ofi9BvB-P_$8Qosd%Nj@%4wdu||iOax~h9Ma?XOHCz zlaslv@JWqwQ>OeVh@8X9qpYGisG)L~O)L#vyyB_0{Fy|(v0_}s%3)mL)$8<@H#Kj! zWWg_B5VEh`jU^4%*&J%|GQ7`O4(QC#d-*;o;zuy)D#AtE`Xp)HkXK~gap^4>E0(Pn z%GS$3&vx2j)ib#E>RZ!Is&)uc)ivAtZcZM_7fzqfZG~n&aRKW>3C|Vy4=e3PO4Gm9 zWHycXn9>+)Zneo&V{O$O0Db{hC{#2}=Z9Ya`~pm}5K=Z=b7+Q9wMmZ!V)cHwD3)i? z!yf5|K9xzIeX5UG4f&;xKpdM|OvM=_wTbc2 zQWha22l7m=)1z+rTGQqI89n)r{vK4i#b_z@i7`b3E~!UO_kI~YX7SF^QQk}6y}=72 zY2Kx;2bAJSE4C?-b^@ghRiK%tjJ-d&RGu$a%GT`6((KHoa(JytX@*`O4|TOZWgVX3 z@+zOkjH~C9`?+=I)>-MiFr`tr7xrz`a8|e$sed&wo)os-Yky97Y4|@;C!!BqlA}@f zeqYG$Uf;)&eRy2E<%?mKq-8$W*Xj$4$8DDc+kAfUHgg;=n$qZw(DNw(VSii69Lz6ZbE`&jr(n0k3vYH|8NF>oh zye#Sx+SO*4bmi+#5K)PT)BitvZvr02b=~TZ&dw+Bj=?TJURCytZYiQ_Mm=gDFx^L<&Icrr>fVaD-f zUgG%0ll4pHjU8Eu^Aaa^oO!nM<(+eDySJ9Ef+$g>^zTm;s&CzUtNK^BwtN2PoS4g# z-Gl!s4h+^SvL@o61<^3lXoB--Z;iaDGgBC*qnR zuS32Dc8&1&7O4yS1;y9eeV>uvP`H)5BBEmzfLq(y3iS~BM&#SPyjAtR$m?JBNY3fk zSwEfk)}B0ldgg5A4QEcCcA}ruMI;pA=`bd}4U_*Qxn};rJNmnNcJA!{iIXfnx7gLG zS8vIFE*HXcuQW_|o~Qm86~DO)WcKukRVq#*Z$EjMc;^yVU(%qFJCa9_=iDuqDwL%W z<<*u7mCE*Ll8=kmC}d?=a8|pUv&`A!G*OMIv`M{~|14p1m)x$J7?Oid{erP}5d0$uW!Gmp!y<$qv?{jXQ#^I&+ zDHC=9Uv#T!d`>&W3qZU8l1P<`CEZ-2J2ZLt@l^MLNeW_Dsb1A{g_4#xON~;#o|$kR z5|ssVP}AqDCS`cd3>+WIoEpl^4rNXcW!^ZHIX9H~o}mGyw)+Kc9dPS_TZiPWKzE>w zml@LXMW8v&|M_Zm>v(rpwyS4&xchz5tFn!R9?I?4HsQOiUk|=CyEQ}KoQv+n2ERcU z$82?oSXSPWi(|sj~N=+Jph!;>CblmtYzjg1F;_E_4xCEy<;su08j#mUyv@d9g&ifQlS}&k6(}bo+=G za3!b2GVnaugRT}iJ1l{u3e5~Ung@RE4me+oWUMBBCyd3_J;En(k>ag7&XJ8~&hd}5 z7B?#M#`}IC3Z>JiO>)ieGH$%LDYMDgN(h(P~YwB^XHqE^54G+W%AZwHx zGgCt6o)EGFVaAD!shlNl)xi02Zk;9ceup?eta^4-h5CBsys+0L(zV-l1A6vK)hJz| z{D6u)JY4V{;nPTw<215CXD!VGJNVKm~{lLx&#~nYtk&HDZ zs2K}x2$XE*-1)O7kDq_?=o%4j_~}uxzd^V6V98o#?}O{^VrGruRn9)eCF(# z$4)+scmXuWZ*tg&aSSMS4Ons8)`0Q!&04Ay|ml~(MOB@ zpo=cz1&Fs?*|v&!0cTyk5aI>6(W(8<{%)*l+uho;p@&>4EZ0%X2}pT|@I4`l!KgTx zO80rI6Tipn6Wv|C{rzoEPKzg7M}5z)Uh*>H1t4Ak;ssb?Ar+yl8wEiYcc>axyGnNP zWTyyNc0-p>HRm*|cPTH7_Q{tlK!sB|@S+=h^&ZI-N~WG~RLuqd6=}Xn?*+=$g+hXf zH}gQOujljwIQy=MCRmfOW%JrOU! z2?If6(00?OBN`lc@{NjPA-J_IXHID*)R~7-Mq+lVy|ed`ooy*$W~jflTx#e!&f_7z z%iT?ST|4mtc9KnhH~mXZKX>i&%@Y@&|EZg8fBWF3e}2pAzW<%t+4gLzZ>sONc3kXB zZ$G>3=`EW!Z|(i@jVIP$T(@WKGi#UKb9D6wSG}-m-HI2M-{}6wu1|Jd>ilM>w(L90 zis`SW-`w%Jj#KRqwmsW6ocb_z_L6)SAvkv*Amx-?{s|oDX!Yf6mEJT93%*oT|XC5JsUga7trE)|b0VJqH9svx|e z&;``pS7_uBKpp|;0-y^ZOMX45Y~X2azl~ph=FAKR^c2V=;3`?<`4>t(VVSfkvL&Ut zabJ0OT1}eqa?7C$Kpp|rrsoMs!c#9m7Z78fhc2Mp$O*k&sE|Qixc%A!yQVB>2(K3u zHAL47>&<9Z=18pR1m~v|!_{lLDJH6OEP+&wB-tD1R|pg8Q&((Th?gM%x&RVAJ92Sp zeh9h%=mO54JxVi&8G0D8&6gsnoTu|vA4T|_ihK@{I%?m zM?k@I*ME8D{7_fVYQT1 z4VpULc=GyS&5rSHHq27R`{r9aaEan@4-8~E3id!&iald{^Jg*xnb8c@$&2o?BC?U? zRq8w<@#B%wP!9G~9P=JrDRz>0w0BGF0OUm}YO)pPg&kMvx8$zX2M69x8|Oec)T<a8kh>u(Ti16ZkaNUw3W4PhIPUA-jjQ5Rx5J#b-pJ$u`}dNJ zz}iagvaS{A-H~(|F+XU^{Y7ruTK;nD?HzD`m3}=5w8_2h@3Mq_t-Ig5-~B!Fx}lqL znDy|3xPQ|973I>LshJDOxJ~SJe~FOa<%(LV+%)}B=zRxi@5Da$_bAOM30@#BeE1IU zn>gtHMyrb&%^q-MdU`QvmK$zZ`$S>o?Qv~&((X$^XKhW_T7%&M=4r#R6F}F(lVky!W34`D@vkH`X~?V?h_l?lJ&}5 zc|m=cRO-5qX$VtDVG5s`9uQ%A-<##vO6R>xL_4A9cqwBqWx0`GD1EE=j(%?D)Xeeo zoCV9hJCm);>q1P2d(US6H6!-Zqg>AKf8i~}o1xu8nK$>UE5%;#ZdM=qkw|4m$4%kH z&sX$8Dl>v$%}dxXYw`>MQkl7FaBIlYSnJ|0}>>3g8 zd|ns!Yf@2OHmQ}nBBEpE(ax*wY=wHT7geK-Z}ak2)rwyK(nB^U9TW3q-dgD; z%f5uReDOglv!>1jtr5O|ZddX~k;=?|K#7deFJJ!X&MU)HuZ=X#A=g!AJR*CS zhPIeCk+VZmhtld~{e_JBz)pwNaT9tegHN99iTnw6cj1FBYU2^L-Q5UZza$3sITp1C z&T4m)&bgZCN4w{m%qy^|@LEV^=5p~4g1;!)p|;zrcjLfe2(RVNgQ~5QZCF0+YWu*} zTU1q(dZ_)-ejt_EnPU{O)-27J499IWySR2&SMSsv6>**n*Ge9NU-)0&u6*k6>+guk zBd|v@cxP$(MduM{@B1cqwWsgfec!y5m;^6XL;~q|C0)D&k1FB?AYOnSw{UUI4lAkT zK{b30;srR79T&D)7v;^NfGAL}E4{OsQPDO<&ld=#KsBP{C?H+{O}l21M*w*Q8m`aY zi0rgSL6Z?YT8;N`$A%8365y((ZFT@LQ zAK}>}&F6pS8#0I&aQ31#Xk=*N&hIxSRv}&h;sxmQ|U zKodDL=BJ>)`NETx!<$13_cf`kM@UQc0Pw6erjvtm#Ai{0Q;zUn*`q~@N0F5vVz5c&G!nbGM$q`*5#zM>-{M zQ*|u2d(JMN?Ck2@zP;^+E`0W!fHcnEF6F-AlqO1C;ZzP}t_Zs#6-uU_Z&b|%|D|f4 zOx^x6E5IpTJdFiTtmDWfv(N=V7trn>ur=LmlyvrZ2#!1Xy_8(#XvEsJEzz80-5SYQ zVTTnRU3RLyv-gpmZ7E^JslT;cYUnu*wk*EO-A#I3caRjo$q2xC1YBLfvmeUbw{zL= zWH^t&nywS6l~1ksyA}22Ut0cX_aAoM>^h<56-cF!M}XKB zr9siO>$!p+JV9=+J_~sSoY_w)fGI!OcvGJtNpPeTIF$CL$hmgh`jowfawc8ZYgLg1 zX`tSmtLyndN-KYgn~+fc&LnHH9k6RJee+I3FPkdRp!=CaUSdPO zkGeSx?JxEWoRrScUP0Ww3!R;Wf^$M~)Oa>S@LvZKm3nnEv@bLR{vs0^Dx2jw1!o&f zO4&-@PM0WNuaQSUx=%{i75T6rj{x!r_|957heOUQY5Y(HpT95n5b5BnoS;f*bvF^9 zT&h%;1E;&Sr9!2$6H7pfSl|ZBcSYpV%CN@aRy?;G`P4xk0l!Vt#pGoQIZP z*EV#u(m}LQ)axa>j&}^@EFb(xk@r?bJ}}5bH4r0QS&2LXA+~mZ=7rXlc{iwk#A%r* z#=p<3AF&7asN*D;Rz?xKfSzs=j0*QmkcVAhc!bwN9s!q&cM$wV$qqy4r6X_{!fPRq zz~B{G+e`-YZ050(=U;!u2@buuZg*Gjp+jwphlJ9kRG^u-Qn93)O8o4I;$4bae;}e( zbfoCJ$g`Y`znl|bj}tH8uX3Mi`{1X3^RHPK(6RQx)b^_z`{)loAOHd&00JNY0w4ea zAOHd&00JNY0wACe`2O!37N*-D?qJhxeW5Z}E!##}<%?{(RaPiARNHjRhTBTjC|%J_ zD^j`T!A=Q?j-H#zJofsT)0w(XQjSI`pKDaF=!WIZeK<3jInOIC^WusY75CZ|D_Y*H z4z#K{W!Kb=W<@tO@+4|meV<)@zFeKt$`n1^EOFF>mTmUiZOYYr(k2J&CL~ZIQ*%Ra zy;IY6Z4U6>a!>BJE3$SWw(>!{vao-}SD&1)>ld3wo=S?P*(KHoNnflHF6KD z-KeCO3#~Wf9A5I3<K%?q)RJuDHYVB{`*1qnTr;`S$;s2FXU=BcaOUJ`5pYHTEZQxd2sE@e zQEe>t7IwRpeK<&AONxxBcD4@GlKF~;lKhk!)~MmTyRuz9!^7S0JL!pD?LfUG*Rix7 zLRX#Bugh;wzExrGPlUzYO_IPB$LyafmKDKVaZI>4c!_qD5z6;HCDBf}j49YA{J49q z!`BD&5G8@Oro2a`v-X*_%kDY4`h%-pSha4&3(IeG|6|uDyDoKp zvr}94on^)JSJQ9q_*}=S_6OUZZ5yVv2d~s;aqTWELHQ%05|mQmx?fmAMLSzdPpHO# z>{~~E7xPASMApK{tFt~;4E$7sZg}Lw#eoqIOp@%sQoX9@3MHBVD$$#NJu@M$c7gxp zwT3=lH9647!11BXsiDm5Q0DYd=8Z#{b3>W$85#(*5CwIer)Frjh?=zx?8?5aud8=@ zx^1y1EP=gsv35f?TCydpuumN$p>+mg1yXBvboCxQ*tU2uZ0m(;zD_~peO=q7J6dkv zuJj_*QLDF8ochVO#hI`@qLJ_08!Fk}a!+pYWI-MQADv+luk=4W}!DWH``;vGH77^6(n@{M?jn1-x3hPk7kLDvC|fkWf5wfU zM?sT_7prY4@R2!R&smdEbb#o9*g++oyr-xxE4Zhd;_bsD%)Cr2_?6aPJP zadl5u@9y1gi<-DBiG$T><|g_Q{^r;@UffXDdXiu z1;xKHv8t71_shRUL zEF3w0^x+vxM-qtdO5w6;Fa5z_!Ncw=M7L?d@%Q_XYR9T<15;`U>S@D~jkkOHWA@(ORF^O*g8we0inUZBdhN*3yn3 zj{wE<(abuzl3KCDte{7fA^VB$uHOFswkM|reJAb<>E`P4@^a-^$ZN!{FCsaHd|>Fl zCpV*ekJCuG?Qvm!kRDgV?s-xNRxBak^D;dLN&$peo@GCLji`}&?9%L0SGu}-w{C5F z->CTU)-KseLF(PgPqx=38i01)zz{?p0pt-t9s%!t>I%(F^LudoCEeF1aAt{9T|D|a znGVD&AzkjQ>x8n(cUAKDZCxg{2CS>6b%nL7rj-kbT}VGy-azDz zajbo-H~X)(L&_~J>{r(>SIveMn_uZWJDTq7J-RhA5Wl^xNqeKq7FV~4m!U;B>4hEl zpRTa>(w&}1fK2H9gY>`Mo9TZ_ynr8g^Y{Pkw#SRV!tnyqs}}5d0knV*2!H?xfB*=9 z00@8p2!H?xywn8V^Uz3FPd3~A%n{GonB#2MNg{9See7@cJEVvdt*%k@@*GAkqhGIS zMnMddSn~JL*S&6nCF=YZKa!D3C%M#; zCADn5m+O^vW4=LQt)=!;T<(ecy&od^@(Ea6uWowlg?EIN`7l=?;S;ZCj69V{zp0?- z%j9KPG_1xPy}MXf93PIKJ#+4yOsSF(hE~7VTvbKv-TlTQRYkA@HN!qESr%p*_I8N4aYSt;U!7Fx*92Iod zJy`Z}8M1=kJ0}_91*j1V9PeVp3kbw=aQwv`H}jT0&WIP_#=vk~$`LOh%*UO)@Ae{I zK+AJ!FX9C_w=?JOKxQ;Ud2#Y01A%y;u^;su%PAWbl*cyN>k{cjGe|EQonLkTB;o}G z9FeUE3hvXSeIiOZ+A5>{I^qRXjk?DOzR+RsvYszA;sxl}>1Es-F!nnd;sqe421jJ$ zDIafeh!pA0$s>o?plLlNUO?kVe(nRmaL-?TX$kQHhN%z43z%wKM7)5^u~TP`WpAv` zboEj+lqb&#NsupEg72$4yL)eq=73J9+w%OtDelPr68V zm2f@bRK14>_<6ocn%EX;dl4^ygIBszFD0K!cq!rqQ1nxpMEBF7qHT(>Z6KsZbR2~_ ziVb?jI#U+cZ|&+OBgkUjR^K|l_2$`N-H zh!-GywEgaSVi;Kw6@sg56IyVE?a1%%UDcZhqHRj+RUS+Cp=?ZQO5 zcDrss&u+&I_d9Zi3BK9<9`J~wUlI~l+ zex6r7@CzFyxh_jL{zA!Eytpu+k3ENt+MyQ_4FeGe(!#E zKF@|=Cx{oISNNfaeK6>CNqN``obrelU_X%a`5<}1xQ~yKetP1X)F>GXbk4Zv23?aH z8u_N=tL0|J2)ks7)#Y%%f8F4CNf9l1Wkfsm$qMlT{KrH%2`QdJ{+nw=v;xEnpcL&P zqd0i?BHv@mL?G_vugp2XyF?NHTb_JUorp6@)M$Acx-}wtpo^|nVFjMnEH@~l2;V(< z=!wg*e@*BPx2h>`G`wDL=cDU|^=2hm$kZ!ZnO4(om#f#v!%+Nee$-JP*RnUxuMn=) zPhGL+H-y78KcCtz#@4geO6A6HzmAJqbjx?&&i%J~*PTAN!jn$AyDD9Tg@d0LCOOz# ziK*>8Z->V@wi{Crx|%iX?o?N=y7F(5p39w=XUV6L=O%2oaQ6rL@5_i6AWj+SC=dDfHeIWlSHf|RLf)ux&El{uFLBc#4_X>oQ$NmAhUYS;2#r8p=j#{>^= z;xjd@ED$Vk4PC$)wFz%?1C8`6j&=_#Pdtx9C7zs_c#QGPa7fJ$b~w7do#N zA_jo_Mj;+5>z&Fk^Q}zuGVg1X=yxW)X8QY<+r?fz5ielIwsLxL1n7tc$DKTt!LbnB zr~_7P1L>K;nTJtEVs@&%v-gpmk>L)!?k3%?$&w!tFJRq!cXoW~2Y&oG-v+7hXm)mbz0rzsbPMFa8 zMLLtqZr+~rxUAF_?h%qRxa>?Wx0ap9TeV-JGdVe;Cvp4^Q|B+q(|n1ZP~0phSBUcexEEDHmoq{tD-y|)zW zOhmkZx|em`wyb-M5HBF?UDgpKknCJ>DJ<$7ATMvXa%39?YL|~{M-O&F)W8jEqT!fb#5ViGnHn{GcUQKnhdgTE zcamqg9K{FA=qOsE@2fnY{CQzey4P+;lSV( z*$0r6L)i>R&OLMCeCF(#$4)-HxMoLJ@4Kezca&xQlo2*0LIJ%E1Uix2D*W42Jq<(p3j|GIcelV6B!7a;V4z9pPxJdF zE+SrlV#EtTynulJH%;pxUVwOzpmWWMI^e$u z+TTNi0gOWEn+QF*=mxi_>1Ly(b9f7Tsa=_X_sZ}5cmc25 zwPw%#Z}^Ek#|!9eAC}?;&=-6_AV}Z?#j&oQ@$v4Dzboj*H`koE%}wlMMgi2Qz&xiP!}?g*?6B7`WNk<%UcyKHE74~E%9my@bV6rlT9^qBpt<%|_jH>~r zn0h6W47aH2N`Ku*L{Xi(n%`#Kr(gCq>?xN?=S-<8=zz4?_TGtoZl_{5wQ}i+mM!j| zJm~&5y6`uuJR?HkmuSk5Qe%jw98xLjCmh(nf6CP&6Kx7rC87=HTKuHF69=a!_q$uI zXnC`mqiF49jlABhMQv%{P%!m+Jy(s~wY`)3ruW@HbwDPf7@&Ea+zI?Rul9V(Hd%c?!YUx{WtPOHLzY{IqWE$?NHXg{=jp zdX7#AEv-e|u)& zfdT&07_(&qUJ+;PuyoQiis(PjD>1_oTW9BaU_0s7{8_b0RLfP}#M+X|*9liH?m(gv z&*syJ^wbcCGg3-zsi~Mb;3h&;Oidgqgd!@I8qn{itP7r^n3`BcmM~aS6ibb4?XYMS zB`3D;4X0*KoVWDO3KT&pu3i*EY+)Rdol0^EX+s^&s z!E{B7icUsy@pRbI*>(!?0wMwc9JI+;?=1Z4(-I`&1z5QV5HEn{YwIEhU>2^Bzh>ZeI5-C1zrfCp^ey z(|c96=gO>iWMx84ttL%)II{uj`@6roJJS&{UFNUv&Tly0_^rElCp4Vuh!=o(0p6sa zH^7y5ReSgg6Pl#RLA-#*WrdS%NJqQ?H@|{6aYR>XZ|2K4=i~?y=rxJ1Z_YQw3m|6p zyE9>NCm|_uWYL>nQ*H=imG3lFMyR+~%8CwetjeXqHsQKDuXXtPU_Vi(NXEM}Bc?{{ zm>M1_@eC7ox{#T-jZMAN&t1EG^TfsHcf8^2UwZq2-?+4dcmbo-9Pt7WF97iZtoI9= zGNB7A;sw;7$Q(O$<`|`3Gg((inc&aQJTh}OySRG0$UM7fxi`CFI4e{_sXzg99H*^Z zu~8>u+V$;<&dMJ-fhr6P*7bSLn%dCK3JDnJjp~RTM?qfg_ljEB*3~;jr|;&_fC^-- z^z9GZy|%U7A+9k%4rk6!miJ^NGgo%cl*RR1yLz+P?!|n_w$;tLYMQg>FC0B(XQ)xD zWGz;~qI6+}{*z%5 zLXICg?o|(iw<3{?fi%|=I2W_rdk_BdkK_mdbnSi)|x25QKa02fL6Q#H715;srd6cmeWAiyS71 z7x2`uILWP81boHzmR2h#wO39jvwO0|pT}N1?=hQOy%fhp++lpT8TIBGvGtHA68R@t zHzxmW^xcoI6kbK&-zSi{4JhHd^ZKw#LFSbwx`=z#1K04#=Mn3Q9C8#Q@2#HsC*-CO zc8^B90K^MmnK{3V@i?U6?k%tM4R~*jxJrnx!CSriM(2M9K)e9U%~WtsbkPts1J{cd z5fy~xC@cT~xtD|$BVK?NMVwuNS_Z-JJ-^!C0-~AsKBwOH`1GiAc&o7I5UGQl$cFBF zUZ%NHZ_g~JS?2|l+=Qy-tMq0euIE;1_Ngmf;w|uf)?>YO7TYIty*uPQPWBdP_Y)X` z;?A3mpB=QpZP40fqt7w$?d-R2slV4NXx+H$R#^^hB3qgpM~

@4P@D^n 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

lCHROLC3k9^VSbb2z>Q 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%0DMLbKNT>{H0k#Lx3A7yyg2*HDkuU&) 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 C9=!Dc literal 0 HcmV?d00001 diff --git a/.vs/PSG-Conduit.slnx/v18/Browse.VC.opendb b/.vs/PSG-Conduit.slnx/v18/Browse.VC.opendb new file mode 100644 index 0000000000000000000000000000000000000000..5e58888ac9259e78fd89e255ce202c9648a3f754 GIT binary patch literal 36 ocmYddC}BussAR}t$Y&^GU| + + + + + + diff --git a/PSG-Conduit/PSG-Conduit.vcxproj b/PSG-Conduit/PSG-Conduit.vcxproj new file mode 100644 index 0000000..4728a1a --- /dev/null +++ b/PSG-Conduit/PSG-Conduit.vcxproj @@ -0,0 +1,150 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + 18.0 + Win32Proj + {83b5cd7b-0f43-4e26-b53c-67789bed170b} + PSGConduit + 10.0 + + + + Application + true + v145 + Unicode + + + Application + false + v145 + true + Unicode + + + Application + true + v145 + Unicode + + + Application + false + v145 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp20 + + + Console + true + + + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp20 + + + Console + true + + + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp20 + + + Console + true + + + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp20 + + + Console + true + + + true + + + + + + + + diff --git a/PSG-Conduit/PSG-Conduit.vcxproj.filters b/PSG-Conduit/PSG-Conduit.vcxproj.filters new file mode 100644 index 0000000..a8a6563 --- /dev/null +++ b/PSG-Conduit/PSG-Conduit.vcxproj.filters @@ -0,0 +1,17 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + \ No newline at end of file diff --git a/PSG-Conduit/PSG-Conduit.vcxproj.user b/PSG-Conduit/PSG-Conduit.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/PSG-Conduit/PSG-Conduit.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..3c66002 --- /dev/null +++ b/README.md @@ -0,0 +1,198 @@ +# PSG Launcher + +An all-in-one launcher for PSG tools. Fetches a signed manifest from your Gitea instance, displays available apps, and handles install/update/launch — with OTA updates for both the launcher itself and every app it manages. + +--- + +## Security model + +| Threat | Mitigation | +|---|---| +| MITM on the wire | All fetches use `https_only(true)` — plain HTTP is rejected at the Rust layer | +| Tampered manifest | `apps.json` has a detached ed25519 signature (`apps.json.sig`); the launcher verifies it before parsing | +| Tampered package | Each app package has an inline SHA-256 hash **and** a separate ed25519 signature; both are verified before writing a single byte to disk | +| Rollback / replay | Tauri's self-updater rejects packages whose version ≤ the running version | +| Compromised CDN / server | The private key never touches the server; only signed content is accepted | +| Supply chain (npm) | Frontend is a thin React shell; all crypto lives in Rust with audited crates | + +**Two separate keys are used:** +- `manifest-private.pem` — signs `apps.json` and each app package (your custom key) +- Tauri signer key — signs the launcher installer for self-updates (generated by Tauri CLI) + +--- + +## Prerequisites + +| Tool | Version | +|---|---| +| Rust | 1.77+ | +| Node.js | 20+ | +| OpenSSL | 3.x (`winget install ShiningLight.OpenSSL.Light`) | +| WebView2 | Bundled with Windows 11 | + +--- + +## First-time setup + +### 1 — Generate the manifest signing keypair + +```powershell +.\scripts\keygen.ps1 +``` + +This writes `keys\manifest-private.pem` and `keys\manifest-public.pem`. +Copy the printed base64 value into `src-tauri\src\config.rs` as `MANIFEST_PUBLIC_KEY_B64`. + +> ⚠ `keys\` is in `.gitignore`. Never commit the private key. + +### 2 — Generate the Tauri self-updater keypair + +```powershell +npm run tauri signer generate -- -w keys\tauri.key +``` + +Copy the printed public key into `src-tauri\tauri.conf.json` under `plugins.updater.pubkey`. + +### 3 — Update config.rs + +Open `src-tauri\src\config.rs` and replace the three `YOURDOMAIN / OWNER` placeholders with your actual Gitea instance URL and repository owner name. + +### 4 — Update tauri.conf.json + +Replace the `YOURDOMAIN / OWNER` placeholders in `src-tauri\tauri.conf.json`. + +### 5 — Install npm dependencies + +```powershell +npm install +``` + +--- + +## Development + +```powershell +npm run tauri dev +``` + +The Tauri dev server starts Vite at `http://localhost:1420` and hot-reloads the UI. + +--- + +## Building a release locally + +```powershell +npm run tauri build +``` + +Installer goes to `src-tauri\target\release\bundle\nsis\`. + +--- + +## Adding an app to the manifest + +1. Build your app and note its `.exe` / `.zip` path. +2. Sign the package and get its hash + signature: + ```powershell + .\scripts\sign-package.ps1 -PackagePath .\path\to\your-app.exe + ``` +3. Copy the printed values into `manifests\apps.json` (add a new entry or update `current_version`). +4. Re-sign the manifest: + ```powershell + .\scripts\sign-manifest.ps1 + ``` +5. Commit, push, and tag: + ```powershell + git add manifests\ + git commit -m "feat: add your-app v1.0.0" + git tag v0.2.0 + git push && git push --tags + ``` + +The release workflow triggers automatically, builds the launcher, and pushes the updated manifests to the `releases` branch where the launcher can reach them. + +--- + +## CI secrets (Gitea repository settings → Secrets) + +| Secret | Value | +|---|---| +| `TAURI_SIGNING_PRIVATE_KEY` | Content of `keys\tauri.key` | +| `TAURI_SIGNING_PRIVATE_KEY_PASSWORD` | Passphrase (or empty string) | +| `MANIFEST_SIGNING_KEY` | Content of `keys\manifest-private.pem` | +| `GITEA_TOKEN` | Personal access token with `repo` write scope | + +--- + +## Manifest structure + +### `manifests/apps.json` + +```jsonc +{ + "schema_version": 1, + "generated_at": "ISO 8601 timestamp", + "minimum_launcher_version": "0.1.0", + "apps": [ + { + "id": "my-app", // stable, URL-safe ID + "name": "My App", + "description": "...", + "category": "tools", // tools | utilities | games | media | development | network | other + "current_version": "1.0.0", + "icon_url": null, // optional HTTPS URL + "changelog": "...", + "tags": [], + "platforms": { + "windows-x86_64": { + "download_url": "https://...", + "hash_sha256": "lowercase hex", + "size_bytes": 1234567, + "install_type": "portable", // portable | zip | installer + "install_path": null, // null = default (%APPDATA%\PSG\) + "signature": "base64 ed25519 sig of download bytes" + } + } + } + ] +} +``` + +### `manifests/apps.json.sig` + +Plain text file containing the base64-encoded ed25519 signature of the raw `apps.json` bytes. + +### `manifests/latest.json` + +Tauri's self-update format — updated automatically by the release workflow. + +--- + +## Project layout + +``` +PSG-Conduit/ +├── src/ React + TypeScript frontend +│ ├── components/ UI components (AppCard, Sidebar, TitleBar, …) +│ ├── hooks/ useAppManifest, useLauncherUpdate +│ ├── lib/commands.ts Type-safe Tauri invoke wrappers +│ └── types/manifest.ts Shared TypeScript types +├── src-tauri/ Rust backend +│ ├── src/ +│ │ ├── commands/ Tauri commands (manifest, apps, updater) +│ │ ├── models/ Serde types (manifest, installed) +│ │ ├── config.rs Public key + manifest URLs +│ │ └── error.rs Serialisable error enum +│ ├── tauri.conf.json +│ └── capabilities/ +├── manifests/ Cloud manifests (committed to `releases` branch via CI) +│ ├── apps.json +│ ├── apps.json.sig ← generated by sign-manifest.ps1 +│ └── latest.json ← generated by release workflow +├── scripts/ +│ ├── keygen.ps1 Generate ed25519 keypair +│ ├── sign-manifest.ps1 Sign apps.json → apps.json.sig +│ └── sign-package.ps1 Get hash + sig for a single app package +└── .gitea/workflows/ + └── release.yml Build + sign + publish on tag push +``` diff --git a/index.html b/index.html new file mode 100644 index 0000000..f2ffa3c --- /dev/null +++ b/index.html @@ -0,0 +1,12 @@ + + + + + + PSG Launcher + + +

+ + + diff --git a/manifests/apps.json b/manifests/apps.json new file mode 100644 index 0000000..c6bca23 --- /dev/null +++ b/manifests/apps.json @@ -0,0 +1,27 @@ +{ + "schema_version": 1, + "generated_at": "2026-05-27T00:00:00Z", + "minimum_launcher_version": "0.1.0", + "apps": [ + { + "id": "psg-conduit", + "name": "PSG Conduit", + "description": "High-performance network conduit and relay tool.", + "category": "network", + "current_version": "0.1.0", + "icon_url": null, + "changelog": "Initial release.", + "tags": ["network", "conduit", "relay"], + "platforms": { + "windows-x86_64": { + "download_url": "https://gitea.YOURDOMAIN.com/OWNER/psg-conduit/releases/download/v0.1.0/psg-conduit.exe", + "hash_sha256": "REPLACE_WITH_SHA256_OF_EXE", + "size_bytes": 0, + "install_type": "portable", + "install_path": null, + "signature": "REPLACE_WITH_BASE64_ED25519_SIG_OF_EXE_BYTES" + } + } + } + ] +} diff --git a/manifests/apps.json.sig b/manifests/apps.json.sig new file mode 100644 index 0000000..046b895 --- /dev/null +++ b/manifests/apps.json.sig @@ -0,0 +1 @@ +hYpFWHlcLsJK/3npBxmBU2Ao7HBOO09hXzan27Vw2dZuivUCII7R4uBgA1no2rUKKqHaLWTDBldNXTOuiYX9CA== \ No newline at end of file diff --git a/manifests/latest.json b/manifests/latest.json new file mode 100644 index 0000000..a50f2fb --- /dev/null +++ b/manifests/latest.json @@ -0,0 +1,11 @@ +{ + "version": "0.1.0", + "notes": "Initial release of PSG Launcher.", + "pub_date": "2026-05-27T00:00:00Z", + "platforms": { + "windows-x86_64": { + "signature": "REPLACE_WITH_TAURI_SIGNER_SIG", + "url": "https://gitea.YOURDOMAIN.com/OWNER/psg-launcher/releases/download/v0.1.0/PSG-Launcher_0.1.0_x64-setup.exe" + } + } +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..2849c8c --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1931 @@ +{ + "name": "psg-launcher", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "psg-launcher", + "version": "0.1.0", + "dependencies": { + "@tauri-apps/api": "^2", + "@tauri-apps/plugin-dialog": "^2", + "@tauri-apps/plugin-process": "^2", + "@tauri-apps/plugin-shell": "^2", + "@tauri-apps/plugin-updater": "^2", + "react": "^18.3.1", + "react-dom": "^18.3.1" + }, + "devDependencies": { + "@tauri-apps/cli": "^2", + "@types/react": "^18.3.1", + "@types/react-dom": "^18.3.1", + "@vitejs/plugin-react": "^4.3.1", + "typescript": "^5.5.3", + "vite": "^8.0.14" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", + "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz", + "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz", + "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", + "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.132.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.132.0.tgz", + "integrity": "sha512-FESMOxil5Se014ui/Eq8fT5uHJo6nIRwH0PfJrZJXs6Gek3ZVFOrpUv3YIZT20m+extU98Hg1Ym72U58rlsxUQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.2.tgz", + "integrity": "sha512-ZS4D1JPGn/MYQN/SYDWftIE/nVsM8j/AFOYEzAoOE2O3NktQOZru+/vYXGbR/qtdLdIfGCP0lcoJiYVzsEz+iQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.2.tgz", + "integrity": "sha512-vdFA9+C/rekyGce7WqHs/xoT0ioZEWaOFyZLIV1mEeNFaFDUQrPIo8Vs2GvJ6eetb3rzDUtUBgzto3ExpXJB3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.2.tgz", + "integrity": "sha512-BewSOwTHazv77DTYiAZXSqqKZ4KP/KonFisDMVU7PImxoWfB2aepnPhd2E4SWz3zDzYgDNbs6jBmTdgNnF02GA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.2.tgz", + "integrity": "sha512-m41o7M0YWtUdqk61Tb+jnKb2rN++iRdIASlExkUoKfIAH30DOHCB8fVLzSUpbWHHU8esmEioY62PxzexE8MBuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.2.tgz", + "integrity": "sha512-jcojB9H7W/jS29pMKWAK1N+fU99vXodHDTatS3b3y/XSOCiHo0kkA74pL3jJmkoQtYpOCxDvaKs1fo2Ij/1X5w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.2.tgz", + "integrity": "sha512-1jn6qDU5iiOgFgygDzKUuKP0maTi0/f1+sBLgvij/76C77Nm3ts6ufz9Bjg5q5dduxiUIxtq86JIoBvo1xQ4Ig==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.2.tgz", + "integrity": "sha512-QVLO/czFMdoMFSqlX3bcswcJNm/23r+qoa/jgtmFc/qEp6/jXmIkDjF/XIo8dPfGaiwy1xfQn8o77L79GeXFgw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.2.tgz", + "integrity": "sha512-hgO5Abm0w5UL6FEa2iFnZqo2KlK7TQ5QhV5x09hujBf7t5KzHQ1VmfPuTpqRy/rNlSxua3eWH374xxiVrP+lcA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.2.tgz", + "integrity": "sha512-fy8rXxuYEu602abC8MUNaPjYLIFzReOaEIEMKMUa0rFEUxNpVXhs15KSSQ4qlqSaM7B6rcj9rDZgADh/IGDzLQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.2.tgz", + "integrity": "sha512-0+bOkiQ779+r1WpoHOWHqncvyySci0vKph+myNDYb+im6meJAzHQXay6oEgnkHuUGouM1LKTZwqKpBow6Kj7CQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.2.tgz", + "integrity": "sha512-mjSkrzZK5Qsl0a9d1JgILOiuZOSDTVdKENcSXBoqbzSrspLR/4/IRVDo5wd2GgZjNss/viBFJdeq+j7qH2nypw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.2.tgz", + "integrity": "sha512-1v5vHasdfQAZoEHakBV72LIFAC9JjnymsiKxp+GEr/ma3+NJCPSaYK+qavInOovJkgwFrs7GccX2d6IgDA3Z5w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.2.tgz", + "integrity": "sha512-mb1VobWn6NheziTk5/WEaR6AKVbrwT5sOi6C7zk3gy/pD1qtJfU1j4PgTo2NJnOtbL9Dl3Aeei8w9jJ7qC2jZQ==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.2.tgz", + "integrity": "sha512-SqKonF56vA/L2yHwHYcEp2P34URpOZ7d1fS635cTkpDnUtEGdUbhI6NzsPdqeSWvAAeGDrxjWjNmibDIdFf9/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.2.tgz", + "integrity": "sha512-v7qRI7gXLRINcOGXt+7YmAZ6iFuyZVMIoXAxhd8oP+DR9dLfL9GfNIx7PLMxmhZdvq8waUJBQiWN9EKNy+TRBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tauri-apps/api": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.11.0.tgz", + "integrity": "sha512-7CinYODhky9lmO23xHnUFv0Xt43fbtWMyxZcLcRBlFkcgXKuEirBvHpmtJ89YMhyeGcq20Wuc47Fa4XjyniywA==", + "license": "Apache-2.0 OR MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + } + }, + "node_modules/@tauri-apps/cli": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.11.2.tgz", + "integrity": "sha512-bk3HemqvGRoy+5D/dVMUQHKMYLglD0jVnMm/0iGMH6ufZ+p8r14m6BpIixwij3PBvZdvORUp1YifTD8QxVZ1Nw==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "bin": { + "tauri": "tauri.js" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + }, + "optionalDependencies": { + "@tauri-apps/cli-darwin-arm64": "2.11.2", + "@tauri-apps/cli-darwin-x64": "2.11.2", + "@tauri-apps/cli-linux-arm-gnueabihf": "2.11.2", + "@tauri-apps/cli-linux-arm64-gnu": "2.11.2", + "@tauri-apps/cli-linux-arm64-musl": "2.11.2", + "@tauri-apps/cli-linux-riscv64-gnu": "2.11.2", + "@tauri-apps/cli-linux-x64-gnu": "2.11.2", + "@tauri-apps/cli-linux-x64-musl": "2.11.2", + "@tauri-apps/cli-win32-arm64-msvc": "2.11.2", + "@tauri-apps/cli-win32-ia32-msvc": "2.11.2", + "@tauri-apps/cli-win32-x64-msvc": "2.11.2" + } + }, + "node_modules/@tauri-apps/cli-darwin-arm64": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.11.2.tgz", + "integrity": "sha512-+4UZzLt+eOAEQCwgd+TqKgyUJMrvx+BgdXLLaqJYmPqzP+nE6YZr/hY6CWLYGQb8jFn99jEkmC6uA3tNvamA1w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-darwin-x64": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.11.2.tgz", + "integrity": "sha512-VjYYtZUPqDMLutSfJEyxFE3Bz+DPi7c8wC3imckgvciLDZLq4qwKJxBicg0BXGhXjJsl8vKWgWRFNMPELQ+Xyg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm-gnueabihf": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.11.2.tgz", + "integrity": "sha512-yMemD6f4i95AQriS8EazyOFzbE34yjnP16i3IOzpHGQvBoy2DjypFMFBq0NtPuITURv/cOGguRtHR5d79/9CSA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm64-gnu": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.11.2.tgz", + "integrity": "sha512-cgI91D2wL8GSgoWwZXDqt+DwnuZCP2/bz03QAE4TrhgAKIsrB4hX26W/H1EONPUUNkqrsgeCD0wU6pcNjV/5kw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm64-musl": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.11.2.tgz", + "integrity": "sha512-X1rm0BERqAAggtYTESSgXrS3sz4Sb/OiPiz54UqISlXW+GkR3vNIGnsy/lejNmoXGVqri3Q53BCfQiclOIyRPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-riscv64-gnu": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.11.2.tgz", + "integrity": "sha512-usbMLJbT3KtkOrBMDVeGYNM35aTHXx38SJSzTMSqqjeUIOQ+iVPjb2yAGNAE+KqmBbAx4FOFIyMeKXx2M/JKGQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-x64-gnu": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.11.2.tgz", + "integrity": "sha512-Ru4gwJKPG0ctVGchRGpRup4Y4lW2SSfFnrbQcyHhCliKy4g8Qz97TrUgCur4CbWyAgKxvGh3SjrkA0LDYzDGiw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-x64-musl": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.11.2.tgz", + "integrity": "sha512-eUm7T6clN1MMmNSRQ9gaWsQdyehQx2Gmn5hht/QUlqZQI/qcP2OJK5dnaxqwFzCr2HdsEo9ydxaqcS1oJzMvUw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-arm64-msvc": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.11.2.tgz", + "integrity": "sha512-HeeZW80jU+gVTOEX4X/hC6NVSAdDVXajwP5fxIZ/3z9WvUC7qrudX2GMTilYq6Dg0e0sk0XgsAJD1hZ5wPBXUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-ia32-msvc": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.11.2.tgz", + "integrity": "sha512-YhjQNZcXfbkCLyazSv1nPnJ9iRFE1wm6kc51FDbU10/Dk09io+6PAGMLjkxnX2GdM0qMnDmTjstY8mTDVvtKeA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-x64-msvc": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.11.2.tgz", + "integrity": "sha512-d2JchlFIpZevZVReyqhQOekJmb1UH3rhZ5VX6sH3ty9ETE0TKQavpihvoScUXfKKpW6HZC0MrFGRU0ZtD+w3gA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/plugin-dialog": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.7.1.tgz", + "integrity": "sha512-OK1UBXYt+ojcmxMktzzuyonYIFta8CmAASpX+CA+DTGK24KlHjhYI6x2iOJ/TjZF4N7/ACK1oFmEOjIY9IhzOQ==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.11.0" + } + }, + "node_modules/@tauri-apps/plugin-process": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-process/-/plugin-process-2.3.1.tgz", + "integrity": "sha512-nCa4fGVaDL/B9ai03VyPOjfAHRHSBz5v6F/ObsB73r/dA3MHHhZtldaDMIc0V/pnUw9ehzr2iEG+XkSEyC0JJA==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.8.0" + } + }, + "node_modules/@tauri-apps/plugin-shell": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.3.5.tgz", + "integrity": "sha512-jewtULhiQ7lI7+owCKAjc8tYLJr92U16bPOeAa472LHJdgaibLP83NcfAF2e+wkEcA53FxKQAZ7byDzs2eeizg==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.10.1" + } + }, + "node_modules/@tauri-apps/plugin-updater": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-updater/-/plugin-updater-2.10.1.tgz", + "integrity": "sha512-NFYMg+tWOZPJdzE/PpFj2qfqwAWwNS3kXrb1tm1gnBJ9mYzZ4WDRrwy8udzWoAnfGCHLuePNLY1WVCNHnh3eRA==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.10.1" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", + "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.29", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.29.tgz", + "integrity": "sha512-ch0qJdr2JY0r04NXSprbK6TXOgnaJ1Tz23fm5W+z0/CBah6BSBc3n96h7K9GOtwh0HrilNWHIBzE1Ko4Dcw/Wg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", + "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.27", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.32", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.32.tgz", + "integrity": "sha512-wbPvpyjJPC0zdfdKXxqEL3Ea+bOMD/87X4lftiJkkaBiuG6ALQy1SLmEd7BSmVCuwCQsBrCamgBoLyfFDD1EPg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001793", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001793.tgz", + "integrity": "sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.362", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.362.tgz", + "integrity": "sha512-PUY2DrLvkjkUuWqq+KPL2iWshrJsZOcIojzRQ7eXFacc9dWga7MGMJAa15VbiejSZB1PAXaRLAiKgruHP8LB1w==", + "dev": true, + "license": "ISC" + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.46", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.46.tgz", + "integrity": "sha512-GYVXHE2KnrzAfsAjl4uP++evGFCrAU1jta4ubEjIG7YWt/64Gqv66a30yKwWczVjA6j3bM4nBwH7Pk1JmDHaxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.15", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", + "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rolldown": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.2.tgz", + "integrity": "sha512-oZx5zVDtVB44AW3eaifgDml1gWRDZGvjcfdxonE4swNPG98PrrXjaO/KrnUjzlMnztCCRVlUueA1kCXhARGk6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.132.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.2", + "@rolldown/binding-darwin-arm64": "1.0.2", + "@rolldown/binding-darwin-x64": "1.0.2", + "@rolldown/binding-freebsd-x64": "1.0.2", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.2", + "@rolldown/binding-linux-arm64-gnu": "1.0.2", + "@rolldown/binding-linux-arm64-musl": "1.0.2", + "@rolldown/binding-linux-ppc64-gnu": "1.0.2", + "@rolldown/binding-linux-s390x-gnu": "1.0.2", + "@rolldown/binding-linux-x64-gnu": "1.0.2", + "@rolldown/binding-linux-x64-musl": "1.0.2", + "@rolldown/binding-openharmony-arm64": "1.0.2", + "@rolldown/binding-wasm32-wasi": "1.0.2", + "@rolldown/binding-win32-arm64-msvc": "1.0.2", + "@rolldown/binding-win32-x64-msvc": "1.0.2" + } + }, + "node_modules/rolldown/node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/vite": { + "version": "8.0.14", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.14.tgz", + "integrity": "sha512-s4BJJ+5y1pYL6Otw51FHhVJQhPnuRinKig64g/1+EUNaJsd3gCKdD31IPFvswUgW9/60QT9oFHbZHbQK5imcxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.32.0", + "picomatch": "^4.0.4", + "postcss": "^8.5.15", + "rolldown": "1.0.2", + "tinyglobby": "^0.2.16" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.1.18", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..f535bbb --- /dev/null +++ b/package.json @@ -0,0 +1,29 @@ +{ + "name": "psg-launcher", + "private": true, + "version": "0.1.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "preview": "vite preview", + "tauri": "tauri" + }, + "dependencies": { + "@tauri-apps/api": "^2", + "@tauri-apps/plugin-dialog": "^2", + "@tauri-apps/plugin-process": "^2", + "@tauri-apps/plugin-shell": "^2", + "@tauri-apps/plugin-updater": "^2", + "react": "^18.3.1", + "react-dom": "^18.3.1" + }, + "devDependencies": { + "@tauri-apps/cli": "^2", + "@types/react": "^18.3.1", + "@types/react-dom": "^18.3.1", + "@vitejs/plugin-react": "^4.3.1", + "typescript": "^5.5.3", + "vite": "^8.0.14" + } +} diff --git a/scripts/_openssl.ps1 b/scripts/_openssl.ps1 new file mode 100644 index 0000000..0699eb9 --- /dev/null +++ b/scripts/_openssl.ps1 @@ -0,0 +1,54 @@ +<# +.SYNOPSIS + Shared helper — locate OpenSSL and add its bin dir to the session PATH. + Dot-source this at the top of any script that needs openssl: + . "$PSScriptRoot\_openssl.ps1" +#> + +function Find-OpenSSL { + # 1. Already on PATH? + if (Get-Command openssl -ErrorAction SilentlyContinue) { + return (Get-Command openssl).Source + } + + # 2. Probe well-known Windows install locations + $candidates = @( + "$env:ProgramFiles\OpenSSL-Win64\bin\openssl.exe" + "$env:ProgramFiles\OpenSSL\bin\openssl.exe" + "${env:ProgramFiles(x86)}\OpenSSL-Win32\bin\openssl.exe" + "C:\Program Files\OpenSSL-Win64\bin\openssl.exe" + "C:\Program Files\OpenSSL\bin\openssl.exe" + "C:\tools\OpenSSL\bin\openssl.exe" + "$env:ChocolateyInstall\bin\openssl.exe" + "$env:ProgramFiles\Git\usr\bin\openssl.exe" + "$env:LocalAppData\Programs\Git\usr\bin\openssl.exe" + ) + + foreach ($candidate in $candidates) { + if (Test-Path $candidate) { + # Add the bin directory to the session PATH so subsequent + # `& openssl ...` calls work without a full path. + $binDir = Split-Path $candidate + $env:PATH = "$binDir;$env:PATH" + Write-Host "Found OpenSSL at: $candidate" -ForegroundColor Cyan + return $candidate + } + } + + # 3. Nothing found — give actionable guidance + Write-Error @" +OpenSSL not found in PATH or any of the standard install locations. + +If it is installed somewhere else, add its bin directory to your PATH: + `$env:PATH = 'C:\Path\To\OpenSSL\bin;' + `$env:PATH + +Otherwise install it: + winget install ShiningLight.OpenSSL.Light + # — then restart this terminal — +"@ + exit 1 +} + +# Run on dot-source — sets `$openssl` in the caller's scope +$openssl = Find-OpenSSL +Write-Host "OpenSSL ready: $(& $openssl version)" -ForegroundColor DarkGray diff --git a/scripts/keygen.ps1 b/scripts/keygen.ps1 new file mode 100644 index 0000000..58bc77a --- /dev/null +++ b/scripts/keygen.ps1 @@ -0,0 +1,66 @@ +<# +.SYNOPSIS + Generate the ed25519 keypair used to sign the apps manifest and app packages. + +.DESCRIPTION + Produces two files in .\keys\ : + manifest-private.pem — KEEP SECRET. Never commit, never put on the server. + manifest-public.pem — Safe to commit; goes in src-tauri/src/config.rs. + + Also prints the raw 32-byte public key as base64 (the value for config.rs). + +.NOTES + Requires OpenSSL 3.x. Install via: winget install ShiningLight.OpenSSL.Light + Verify: openssl version +#> + +param( + [string]$OutputDir = ".\keys" +) + +$ErrorActionPreference = "Stop" + +# ── Locate OpenSSL (probes common Windows install paths if not on PATH) ─────── +. "$PSScriptRoot\_openssl.ps1" + +New-Item -ItemType Directory -Force -Path $OutputDir | Out-Null + +$privPath = Join-Path $OutputDir "manifest-private.pem" +$pubPath = Join-Path $OutputDir "manifest-public.pem" + +# ── Generate ed25519 keypair ───────────────────────────────────────────────── +Write-Host "`nGenerating Ed25519 keypair..." -ForegroundColor Yellow +& openssl genpkey -algorithm ed25519 -out $privPath +& openssl pkey -in $privPath -pubout -out $pubPath + +# ── Extract raw 32-byte public key as base64 ───────────────────────────────── +# OpenSSL DER-encodes the public key as SubjectPublicKeyInfo (SPKI). +# Ed25519 SPKI = 12-byte header + 32-byte raw key = 44 bytes total. +# Write to a temp file so we can read the raw bytes. +$tempDer = Join-Path $env:TEMP "psg-pubkey-$([System.Guid]::NewGuid()).der" +& openssl pkey -in $privPath -pubout -outform DER -out $tempDer +$derBytes = [IO.File]::ReadAllBytes($tempDer) +Remove-Item $tempDer -Force + +# Skip the 12-byte SPKI header to get the raw 32-byte key +$rawKeyBytes = $derBytes[12..43] +$rawKeyB64 = [Convert]::ToBase64String($rawKeyBytes) + +# ── Output ─────────────────────────────────────────────────────────────────── +Write-Host "" +Write-Host "Keys written to $OutputDir" -ForegroundColor Green +Write-Host " Private : $privPath ← KEEP SECRET, never commit" -ForegroundColor Red +Write-Host " Public : $pubPath" +Write-Host "" +Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Yellow +Write-Host "Paste this value into src-tauri/src/config.rs as MANIFEST_PUBLIC_KEY_B64:" -ForegroundColor Yellow +Write-Host "" +Write-Host " $rawKeyB64" -ForegroundColor Cyan +Write-Host "" +Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Yellow +Write-Host "" +Write-Host "Next steps:" +Write-Host " 1. Copy the base64 value above into config.rs" +Write-Host " 2. Store manifest-private.pem as the Gitea CI secret MANIFEST_SIGNING_KEY" +Write-Host " 3. Run 'npm run tauri signer generate' for the Tauri self-updater key" +Write-Host " and store that in CI as TAURI_SIGNING_PRIVATE_KEY" diff --git a/scripts/sign-manifest.ps1 b/scripts/sign-manifest.ps1 new file mode 100644 index 0000000..3669d34 --- /dev/null +++ b/scripts/sign-manifest.ps1 @@ -0,0 +1,122 @@ +<# +.SYNOPSIS + Sign (or re-sign) manifests/apps.json and produce apps.json.sig. + +.DESCRIPTION + Reads the private key from either: + -KeyPath (a PEM file path, default .\keys\manifest-private.pem) + or the env var MANIFEST_SIGNING_KEY (base64-encoded DER private key, used in CI) + + Produces manifests/apps.json.sig — a file containing the base64-encoded + ed25519 signature of the raw apps.json bytes. + + This detached-signature approach means the JSON is never modified and there + are no canonicalisation issues. + +.EXAMPLE + # Local development + .\scripts\sign-manifest.ps1 + + # CI (key stored as base64 DER in an env var) + $env:MANIFEST_SIGNING_KEY = "" + .\scripts\sign-manifest.ps1 +#> + +param( + [string]$KeyPath = ".\keys\manifest-private.pem", + [string]$ManifestPath = ".\manifests\apps.json", + [string]$SigPath = ".\manifests\apps.json.sig" +) + +$ErrorActionPreference = "Stop" + +# ── Locate OpenSSL (probes common Windows install paths if not on PATH) ─────── +. "$PSScriptRoot\_openssl.ps1" + +# ── Resolve all paths to absolute using PowerShell's CWD ───────────────────── +# [IO.File] uses .NET's Environment.CurrentDirectory, which differs from +# PowerShell's $PWD when the session was started from another location. +# GetUnresolvedProviderPathFromPSPath works even for paths that don't exist yet. +$ManifestPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($ManifestPath) +$SigPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($SigPath) +$KeyPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($KeyPath) + +# ── Resolve private key ────────────────────────────────────────────────────── +$tempKeyFile = $null + +if ($env:MANIFEST_SIGNING_KEY) { + Write-Host "Using MANIFEST_SIGNING_KEY from environment" -ForegroundColor Cyan + # CI provides the PEM content as an env var + $tempKeyFile = Join-Path $env:TEMP "psg-sign-key-$([System.Guid]::NewGuid()).pem" + [IO.File]::WriteAllText($tempKeyFile, $env:MANIFEST_SIGNING_KEY) + $resolvedKey = $tempKeyFile +} elseif (Test-Path $KeyPath) { + Write-Host "Using key file: $KeyPath" -ForegroundColor Cyan + $resolvedKey = Resolve-Path $KeyPath +} else { + Write-Error "No signing key found.`nRun scripts/keygen.ps1 first, or set the MANIFEST_SIGNING_KEY env var." + exit 1 +} + +try { + # ── Sign ───────────────────────────────────────────────────────────────── + $tempSig = Join-Path $env:TEMP "psg-manifest-sig-$([System.Guid]::NewGuid()).bin" + + Write-Host "Signing $ManifestPath..." -ForegroundColor Yellow + & openssl pkeyutl ` + -sign ` + -inkey $resolvedKey ` + -rawin ` + -in (Resolve-Path $ManifestPath) ` + -out $tempSig + + if ($LASTEXITCODE -ne 0) { + Write-Error "OpenSSL signing failed (exit $LASTEXITCODE)" + exit 1 + } + + # Base64-encode the raw signature bytes + $sigBytes = [IO.File]::ReadAllBytes($tempSig) + $sigB64 = [Convert]::ToBase64String($sigBytes) + [IO.File]::WriteAllText($SigPath, $sigB64) + + Remove-Item $tempSig -Force + + Write-Host "Signature written to $SigPath" -ForegroundColor Green + Write-Host "Sig (base64): $sigB64" -ForegroundColor Gray + +} finally { + # Clean up temp key file if we created one + if ($tempKeyFile -and (Test-Path $tempKeyFile)) { + Remove-Item $tempKeyFile -Force + } +} + +# ── Verify round-trip ──────────────────────────────────────────────────────── +Write-Host "`nVerifying round-trip..." -ForegroundColor Yellow + +$tempVerifySig = Join-Path $env:TEMP "psg-verify-sig-$([System.Guid]::NewGuid()).bin" +$sigBytesBack = [Convert]::FromBase64String($sigB64) +[IO.File]::WriteAllBytes($tempVerifySig, $sigBytesBack) + +# Use the public key for verification +$pubKeyPath = $KeyPath -replace '-private\.pem$', '-public.pem' +if (-not (Test-Path $pubKeyPath)) { + Write-Warning "Public key not found at $pubKeyPath — skipping verify step" +} else { + & openssl pkeyutl ` + -verify ` + -inkey $pubKeyPath ` + -pubin ` + -rawin ` + -in (Resolve-Path $ManifestPath) ` + -sigfile $tempVerifySig + + if ($LASTEXITCODE -eq 0) { + Write-Host "Round-trip verification passed ✓" -ForegroundColor Green + } else { + Write-Error "Round-trip verification FAILED — signature is corrupt!" + } +} + +Remove-Item $tempVerifySig -Force -ErrorAction SilentlyContinue diff --git a/scripts/sign-package.ps1 b/scripts/sign-package.ps1 new file mode 100644 index 0000000..503d0f6 --- /dev/null +++ b/scripts/sign-package.ps1 @@ -0,0 +1,75 @@ +<# +.SYNOPSIS + Sign a single app package file and output its hash + signature for the manifest. + +.DESCRIPTION + Run this once per app package you want to add to apps.json. + Copy the output values into the appropriate platforms entry in manifests/apps.json, + then re-run sign-manifest.ps1 to re-sign the updated manifest. + +.EXAMPLE + .\scripts\sign-package.ps1 -PackagePath .\dist\my-app.exe +#> + +param( + [Parameter(Mandatory)] + [string]$PackagePath, + + [string]$KeyPath = ".\keys\manifest-private.pem" +) + +$ErrorActionPreference = "Stop" + +# ── Locate OpenSSL (probes common Windows install paths if not on PATH) ─────── +. "$PSScriptRoot\_openssl.ps1" + +# Resolve to absolute paths so .NET IO methods use the correct CWD +$PackagePath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($PackagePath) +$KeyPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($KeyPath) + +$resolvedPkg = Resolve-Path $PackagePath +$resolvedKey = $null +$tempKeyFile = $null + +if ($env:MANIFEST_SIGNING_KEY) { + $tempKeyFile = Join-Path $env:TEMP "psg-sign-key-$([System.Guid]::NewGuid()).pem" + [IO.File]::WriteAllText($tempKeyFile, $env:MANIFEST_SIGNING_KEY) + $resolvedKey = $tempKeyFile +} else { + $resolvedKey = Resolve-Path $KeyPath +} + +try { + # SHA-256 hash + $hashObj = Get-FileHash -Path $resolvedPkg -Algorithm SHA256 + $hash = $hashObj.Hash.ToLower() + + # File size + $sizeBytes = (Get-Item $resolvedPkg).Length + + # ed25519 signature + $tempSig = Join-Path $env:TEMP "psg-pkg-sig-$([System.Guid]::NewGuid()).bin" + & openssl pkeyutl -sign -inkey $resolvedKey -rawin -in $resolvedPkg -out $tempSig + if ($LASTEXITCODE -ne 0) { throw "openssl signing failed" } + + $sigB64 = [Convert]::ToBase64String([IO.File]::ReadAllBytes($tempSig)) + Remove-Item $tempSig -Force + + Write-Host "" + Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Yellow + Write-Host "Add this to the relevant platforms entry in manifests/apps.json:" -ForegroundColor Yellow + Write-Host "" + Write-Host @" + "hash_sha256": "$hash", + "size_bytes": $sizeBytes, + "signature": "$sigB64" +"@ -ForegroundColor Cyan + Write-Host "" + Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Yellow + Write-Host "Then re-run: .\scripts\sign-manifest.ps1" + +} finally { + if ($tempKeyFile -and (Test-Path $tempKeyFile)) { + Remove-Item $tempKeyFile -Force + } +} diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock new file mode 100644 index 0000000..c1d1bce --- /dev/null +++ b/src-tauri/Cargo.lock @@ -0,0 +1,6236 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" + +[[package]] +name = "anstyle-parse" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.61.2", +] + +[[package]] +name = "anyhow" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" + +[[package]] +name = "arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" +dependencies = [ + "derive_arbitrary", +] + +[[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 = "base64ct" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" + +[[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.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +dependencies = [ + "serde_core", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" +dependencies = [ + "objc2", +] + +[[package]] +name = "brotli" +version = "8.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "bytemuck" +version = "1.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +dependencies = [ + "serde", +] + +[[package]] +name = "bzip2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49ecfb22d906f800d4fe833b6282cf4dc1c298f5057ca0b5445e5c209735ca47" +dependencies = [ + "bzip2-sys", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.13+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" +dependencies = [ + "cc", + "pkg-config", +] + +[[package]] +name = "cairo-rs" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" +dependencies = [ + "bitflags 2.11.1", + "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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" +dependencies = [ + "serde_core", +] + +[[package]] +name = "cargo-platform" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror 2.0.18", +] + +[[package]] +name = "cargo_toml" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77" +dependencies = [ + "serde", + "toml 0.9.12+spec-1.1.0", +] + +[[package]] +name = "cc" +version = "1.2.62" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" +dependencies = [ + "find-msvc-tools", + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfb" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" +dependencies = [ + "byteorder", + "fnv", + "uuid", +] + +[[package]] +name = "cfg-expr" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +dependencies = [ + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chrono" +version = "0.4.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-link 0.2.1", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "colorchoice" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + +[[package]] +name = "cookie_store" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b2c103cf610ec6cae3da84a766285b42fd16aad564758459e6ecf128c75206" +dependencies = [ + "cookie", + "document-features", + "idna", + "log", + "publicsuffix", + "serde", + "serde_derive", + "serde_json", + "time", + "url", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[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.11.1", + "core-foundation 0.10.1", + "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.11.1", + "core-foundation 0.10.1", + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "cssparser" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dae61cf9c0abb83bd659dab65b7e4e38d8236824c85f0f804f173567bda257d2" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa", + "phf", + "smallvec", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" +dependencies = [ + "quote", + "syn 2.0.117", +] + +[[package]] +name = "ctor" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "352d39c2f7bef1d6ad73db6f5160efcaed66d94ef8c6c573a8410c00bf909a98" +dependencies = [ + "ctor-proc-macro", + "dtor", +] + +[[package]] +name = "ctor-proc-macro" +version = "0.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52560adf09603e58c9a7ee1fe1dcb95a16927b17c127f0ac02d6e768a0e25bc1" + +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "darling" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" +dependencies = [ + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.117", +] + +[[package]] +name = "darling_macro" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "data-url" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376" + +[[package]] +name = "dbus" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b942602992bb7acfd1f51c49811c58a610ef9181b6e66f3e519d79b540a3bf73" +dependencies = [ + "libc", + "libdbus-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "deflate64" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac6b926516df9c60bfa16e107b21086399f8285a44ca9711344b9e553c5146e2" + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" +dependencies = [ + "powerfmt", + "serde_core", +] + +[[package]] +name = "derive_arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[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.117", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys 0.4.1", +] + +[[package]] +name = "dirs" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +dependencies = [ + "dirs-sys 0.5.0", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users 0.4.6", + "windows-sys 0.48.0", +] + +[[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 0.5.2", + "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.11.1", + "block2", + "libc", + "objc2", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[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.117", +] + +[[package]] +name = "document-features" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +dependencies = [ + "litrs", +] + +[[package]] +name = "dom_query" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521e380c0c8afb8d9a1e83a1822ee03556fc3e3e7dbc1fd30be14e37f9cb3f89" +dependencies = [ + "bit-set", + "cssparser", + "foldhash 0.2.0", + "html5ever", + "precomputed-hash", + "selectors", + "tendril", +] + +[[package]] +name = "dpi" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" +dependencies = [ + "serde", +] + +[[package]] +name = "dtoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c3cf4824e2d5f025c7b531afcb2325364084a16806f6d47fbc1f5fbd9960590" + +[[package]] +name = "dtoa-short" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" +dependencies = [ + "dtoa", +] + +[[package]] +name = "dtor" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1057d6c64987086ff8ed0fd3fbf377a6b7d205cc7715868cd401705f715cbe4" +dependencies = [ + "dtor-proc-macro", +] + +[[package]] +name = "dtor-proc-macro" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f678cf4a922c215c63e0de95eb1ff08a958a81d47e485cf9da1e27bf6305cfa5" + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +dependencies = [ + "curve25519-dalek", + "ed25519", + "serde", + "sha2", + "subtle", + "zeroize", +] + +[[package]] +name = "embed-resource" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31a88c8d26de40ed18fe748c547845aa39de1db3afd958f8cb91579f3644bcb" +dependencies = [ + "cc", + "memchr", + "rustc_version", + "toml 1.1.2+spec-1.1.0", + "vswhom", + "winreg", +] + +[[package]] +name = "embed_plist" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "env_filter" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "jiff", + "log", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "erased-serde" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2add8a07dd6a8d93ff627029c51de145e12686fbc36ecb298ac22e74cf02dec" +dependencies = [ + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "fastrand" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" + +[[package]] +name = "fdeflate" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[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 = "filetime" +version = "0.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759" +dependencies = [ + "cfg-if", + "libc", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-executor" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + +[[package]] +name = "futures-macro" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", +] + +[[package]] +name = "gdk" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9f245958c627ac99d8e529166f9823fb3b838d1d41fd2b297af3075093c2691" +dependencies = [ + "cairo-rs", + "gdk-pixbuf", + "gdk-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50e1f5f1b0bfb830d6ccc8066d18db35c487b1b2b1e8589b5dfe9f07e8defaec" +dependencies = [ + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", + "once_cell", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9839ea644ed9c97a34d129ad56d38a25e6756f99f3a88e15cd39c20629caf7" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gdk-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c2d13f38594ac1e66619e188c6d5a1adb98d11b2fcf7894fc416ad76aa2f3f7" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gdkwayland-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "140071d506d223f7572b9f09b5e155afbd77428cd5cc7af8f2694c41d98dfe69" +dependencies = [ + "gdk-sys", + "glib-sys", + "gobject-sys", + "libc", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gdkx11" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3caa00e14351bebbc8183b3c36690327eb77c49abc2268dd4bd36b856db3fbfe" +dependencies = [ + "gdk", + "gdkx11-sys", + "gio", + "glib", + "libc", + "x11", +] + +[[package]] +name = "gdkx11-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e7445fe01ac26f11601db260dd8608fe172514eb63b3b5e261ea6b0f4428d" +dependencies = [ + "gdk-sys", + "glib-sys", + "libc", + "system-deps", + "x11", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi 5.3.0", + "wasip2", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", + "wasip2", + "wasip3", +] + +[[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.11.1", + "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.117", +] + +[[package]] +name = "glib-sys" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063ce2eb6a8d0ea93d2bf8ba1957e78dbab6be1c2220dd3daca57d5a9d869898" +dependencies = [ + "libc", + "system-deps", +] + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "gobject-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gtk" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd56fb197bfc42bd5d2751f4f017d44ff59fbb58140c6b49f9b3b2bdab08506a" +dependencies = [ + "atk", + "cairo-rs", + "field-offset", + "futures-channel", + "gdk", + "gdk-pixbuf", + "gio", + "glib", + "gtk-sys", + "gtk3-macros", + "libc", + "pango", + "pkg-config", +] + +[[package]] +name = "gtk-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f29a1c21c59553eb7dd40e918be54dccd60c52b049b75119d5d96ce6b624414" +dependencies = [ + "atk-sys", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "gtk3-macros" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ff3c5b21f14f0736fed6dcfc0bfb4225ebf5725f3c0209edeec181e4d73e9d" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "h2" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap 2.14.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash 0.1.5", +] + +[[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 = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "html5ever" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1054432bae2f14e0061e33d23402fbaa67a921d319d56adc6bcf887ddad1cbc2" +dependencies = [ + "log", + "markup5ever", +] + +[[package]] +name = "http" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be7462df143984c4598a256ef469b251d7d7f9e271135073e78fc535414f3d0" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "hyper" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "system-configuration", + "tokio", + "tower-service", + "tracing", + "windows-registry", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core 0.62.2", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ico" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e795dff5605e0f04bff85ca41b51a96b83e80b281e96231bcaaf1ac35103371" +dependencies = [ + "byteorder", + "png 0.17.16", +] + +[[package]] +name = "icu_collections" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" +dependencies = [ + "displaydoc", + "potential_utf", + "utf8_iter", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" + +[[package]] +name = "icu_properties" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" + +[[package]] +name = "icu_provider" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", + "serde", + "serde_core", +] + +[[package]] +name = "infer" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7" +dependencies = [ + "cfb", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + +[[package]] +name = "ipnet" +version = "2.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" + +[[package]] +name = "is-docker" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" +dependencies = [ + "once_cell", +] + +[[package]] +name = "is-wsl" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" +dependencies = [ + "is-docker", + "once_cell", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[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.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "392c70591e8749fe235ddaf513e6f58b26bce3dcc16524cecc8936f75afa161e" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", +] + +[[package]] +name = "jiff-static" +version = "0.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b605b0c050d845fc355bb11eb3f9a8deddc218ea60c76e61aa1f2adfb2c96a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[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" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +dependencies = [ + "cfg-if", + "combine", + "jni-macros", + "jni-sys 0.4.1", + "log", + "simd_cesu8", + "thiserror 2.0.18", + "walkdir", + "windows-link 0.2.1", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn 2.0.117", +] + +[[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.117", +] + +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11" +dependencies = [ + "cfg-if", + "futures-util", + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "json-patch" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "863726d7afb6bc2590eeff7135d923545e5e964f004c2ccf8716c25e70a86f08" +dependencies = [ + "jsonptr", + "serde", + "serde_json", + "thiserror 1.0.69", +] + +[[package]] +name = "jsonptr" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dea2b27dd239b2556ed7a25ba842fe47fd602e7fc7433c2a8d6106d4d9edd70" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "keyboard-types" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" +dependencies = [ + "bitflags 2.11.1", + "serde", + "unicode-segmentation", +] + +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + +[[package]] +name = "libappindicator" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03589b9607c868cc7ae54c0b2a22c8dc03dd41692d48f2d7df73615c6a95dc0a" +dependencies = [ + "glib", + "gtk", + "gtk-sys", + "libappindicator-sys", + "log", +] + +[[package]] +name = "libappindicator-sys" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e9ec52138abedcc58dc17a7c6c0c00a2bdb4f3427c7f63fa97fd0d859155caf" +dependencies = [ + "gtk-sys", + "libloading", + "once_cell", +] + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "libdbus-sys" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "328c4789d42200f1eeec05bd86c9c13c7f091d2ba9a6ea35acdf51f31bc0f043" +dependencies = [ + "pkg-config", +] + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libredox" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" +dependencies = [ + "libc", +] + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "litemap" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" + +[[package]] +name = "litrs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" + +[[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.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616ec5685824bcc94416c6d4a7a446eea774a31efd7062c8480ba6fd06d7a6e5" + +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + +[[package]] +name = "lzma-rs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e" +dependencies = [ + "byteorder", + "crc", +] + +[[package]] +name = "lzma-sys" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "markup5ever" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8983d30f2915feeaaab2d6babdd6bc7e9ed1a00b66b5e6d74df19aa9c0e91862" +dependencies = [ + "log", + "tendril", + "web_atoms", +] + +[[package]] +name = "memchr" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + +[[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 = "minisign-verify" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22f9645cb765ea72b8111f36c522475d2daa0d22c957a9826437e97534bc4e9e" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + +[[package]] +name = "muda" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47a2e3dff89cd322c66647942668faee0a2b1f88ea6cbb4d374b4a8d7e92528c" +dependencies = [ + "crossbeam-channel", + "dpi", + "gtk", + "keyboard-types", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", + "once_cell", + "png 0.18.1", + "serde", + "thiserror 2.0.18", + "windows-sys 0.61.2", +] + +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.11.1", + "jni-sys 0.3.1", + "log", + "ndk-sys", + "num_enum", + "raw-window-handle", + "thiserror 1.0.69", +] + +[[package]] +name = "ndk-sys" +version = "0.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +dependencies = [ + "jni-sys 0.3.1", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "num-conv" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" +dependencies = [ + "proc-macro-crate 3.5.0", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "objc2" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" +dependencies = [ + "objc2-encode", + "objc2-exception-helper", +] + +[[package]] +name = "objc2-app-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" +dependencies = [ + "bitflags 2.11.1", + "block2", + "objc2", + "objc2-core-foundation", + "objc2-foundation", +] + +[[package]] +name = "objc2-cloud-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" +dependencies = [ + "bitflags 2.11.1", + "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.11.1", + "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.11.1", + "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.11.1", + "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.11.1", + "block2", + "libc", + "objc2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-io-surface" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" +dependencies = [ + "bitflags 2.11.1", + "objc2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-osa-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f112d1746737b0da274ef79a23aac283376f335f4095a083a267a082f21db0c0" +dependencies = [ + "bitflags 2.11.1", + "objc2", + "objc2-app-kit", + "objc2-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.11.1", + "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.11.1", + "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.11.1", + "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 = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "open" +version = "5.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fbaa89d2ddc8473c78a3adf69eea8cffa28c483b8e02a971ef31527cd0fc92c" +dependencies = [ + "dunce", + "is-wsl", + "libc", + "pathdiff", +] + +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "os_pipe" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "osakit" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "732c71caeaa72c065bb69d7ea08717bd3f4863a4f451402fc9513e29dbd5261b" +dependencies = [ + "objc2", + "objc2-foundation", + "objc2-osa-kit", + "serde", + "serde_json", + "thiserror 2.0.18", +] + +[[package]] +name = "pango" +version = "0.18.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ca27ec1eb0457ab26f3036ea52229edbdb74dee1edd29063f5b9b010e7ebee4" +dependencies = [ + "gio", + "glib", + "libc", + "once_cell", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436737e391a843e5933d6d9aa102cb126d501e815b83601365a948a518555dc5" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link 0.2.1", +] + +[[package]] +name = "pathdiff" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" + +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest", + "hmac", +] + +[[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.117", +] + +[[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 = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + +[[package]] +name = "plist" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "092791278e026273c1b65bbdcfbba3a300f2994c896bd01ab01da613c29c46f1" +dependencies = [ + "base64 0.22.1", + "indexmap 2.14.0", + "quick-xml", + "serde", + "time", +] + +[[package]] +name = "png" +version = "0.17.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "png" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" +dependencies = [ + "bitflags 2.11.1", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" + +[[package]] +name = "portable-atomic-util" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "potential_utf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" +dependencies = [ + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn 2.0.117", +] + +[[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.11+spec-1.1.0", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "psg-launcher" +version = "0.1.0" +dependencies = [ + "base64 0.22.1", + "chrono", + "dirs 5.0.1", + "ed25519-dalek", + "env_logger", + "hex", + "log", + "reqwest 0.12.28", + "semver", + "serde", + "serde_json", + "sha2", + "tauri", + "tauri-build", + "tauri-plugin-dialog", + "tauri-plugin-fs", + "tauri-plugin-http", + "tauri-plugin-process", + "tauri-plugin-shell", + "tauri-plugin-updater", + "thiserror 1.0.69", + "tokio", + "zip 2.4.2", +] + +[[package]] +name = "psl-types" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" + +[[package]] +name = "publicsuffix" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42ea446cab60335f76979ec15e12619a2165b5ae2c12166bef27d283a9fadf" +dependencies = [ + "idna", + "psl-types", +] + +[[package]] +name = "quick-xml" +version = "0.39.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdcc8dd4e2f670d309a5f0e83fe36dfdc05af317008fea29144da1a2ac858e5e" +dependencies = [ + "memchr", +] + +[[package]] +name = "quinn" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror 2.0.18", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" +dependencies = [ + "bytes", + "getrandom 0.3.4", + "lru-slab", + "rand", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.18", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.60.2", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "rand" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +dependencies = [ + "rand_chacha", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.17", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + +[[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.11.1", +] + +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom 0.2.17", + "libredox", + "thiserror 1.0.69", +] + +[[package]] +name = "redox_users" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" +dependencies = [ + "getrandom 0.2.17", + "libredox", + "thiserror 2.0.18", +] + +[[package]] +name = "ref-cast" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "regex" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" + +[[package]] +name = "reqwest" +version = "0.12.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +dependencies = [ + "base64 0.22.1", + "bytes", + "cookie", + "cookie_store", + "encoding_rs", + "futures-core", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "mime", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", +] + +[[package]] +name = "reqwest" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "rustls", + "rustls-pki-types", + "rustls-platform-verifier", + "serde", + "serde_json", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tokio-util", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", +] + +[[package]] +name = "rfd" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a15ad77d9e70a92437d8f74c35d99b4e4691128df018833e99f90bcd36152672" +dependencies = [ + "block2", + "dispatch2", + "glib-sys", + "gobject-sys", + "gtk-sys", + "js-sys", + "log", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", + "raw-window-handle", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-sys 0.60.2", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustc-hash" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags 2.11.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls" +version = "0.23.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pki-types" +version = "1.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-platform-verifier" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" +dependencies = [ + "core-foundation 0.10.1", + "core-foundation-sys", + "jni 0.22.4", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + +[[package]] +name = "rustls-webpki" +version = "0.103.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "schemars" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" +dependencies = [ + "dyn-clone", + "indexmap 1.9.3", + "schemars_derive", + "serde", + "serde_json", + "url", + "uuid", +] + +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.117", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "security-framework" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" +dependencies = [ + "bitflags 2.11.1", + "core-foundation 0.10.1", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "selectors" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5d9c0c92a92d33f08817311cf3f2c29a3538a8240e94a6a3c622ce652d7e00c" +dependencies = [ + "bitflags 2.11.1", + "cssparser", + "derive_more", + "log", + "new_debug_unreachable", + "phf", + "phf_codegen", + "precomputed-hash", + "rustc-hash", + "servo_arc", + "smallvec", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde-untagged" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9faf48a4a2d2693be24c6289dbe26552776eb7737074e6722891fadbe6c5058" +dependencies = [ + "erased-serde", + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[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.117", +] + +[[package]] +name = "serde_json" +version = "1.0.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_repr" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_spanned" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "3.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e72c1c2cb7b223fafb600a619537a871c2818583d619401b785e7c0b746ccde2" +dependencies = [ + "base64 0.22.1", + "bs58", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.14.0", + "schemars 0.9.0", + "schemars 1.2.1", + "serde_core", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b90c488738ecb4fb0262f41f43bc40efc5868d9fb744319ddf5f5317f417bfac" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[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.117", +] + +[[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 = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[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 = "shared_child" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e362d9935bc50f019969e2f9ecd66786612daae13e8f277be7bfb66e8bed3f7" +dependencies = [ + "libc", + "sigchld", + "windows-sys 0.60.2", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "sigchld" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47106eded3c154e70176fc83df9737335c94ce22f821c32d17ed1db1f83badb1" +dependencies = [ + "libc", + "os_pipe", + "signal-hook", +] + +[[package]] +name = "signal-hook" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "simd-adler32" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" + +[[package]] +name = "simd_cesu8" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" +dependencies = [ + "rustc_version", + "simdutf8", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + +[[package]] +name = "siphasher" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +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 = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "string_cache" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18596f8c785a729f2819c0f6a7eae6ebeebdfffbfe4214ae6b087f690e31901" +dependencies = [ + "new_debug_unreachable", + "parking_lot", + "phf_shared", + "precomputed-hash", +] + +[[package]] +name = "string_cache_codegen" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "585635e46db231059f76c5849798146164652513eb9e8ab2685939dd90f29b69" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "swift-rs" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4057c98e2e852d51fdcfca832aac7b571f6b351ad159f9eda5db1655f8d0c4d7" +dependencies = [ + "base64 0.21.7", + "serde", + "serde_json", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "system-configuration" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" +dependencies = [ + "bitflags 2.11.1", + "core-foundation 0.9.4", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "system-deps" +version = "6.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" +dependencies = [ + "cfg-expr", + "heck 0.5.0", + "pkg-config", + "toml 0.8.2", + "version-compare", +] + +[[package]] +name = "tao" +version = "0.35.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1c93047acf68669466a34690ac58cca7010bd1b201e1ec86f1fd0a75d3dd4a9" +dependencies = [ + "bitflags 2.11.1", + "block2", + "core-foundation 0.10.1", + "core-graphics", + "crossbeam-channel", + "dbus", + "dispatch2", + "dlopen2", + "dpi", + "gdkwayland-sys", + "gdkx11-sys", + "gtk", + "jni 0.21.1", + "libc", + "log", + "ndk", + "ndk-sys", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "objc2-ui-kit", + "once_cell", + "parking_lot", + "percent-encoding", + "raw-window-handle", + "tao-macros", + "unicode-segmentation", + "url", + "windows", + "windows-core 0.61.2", + "windows-version", + "x11-dl", +] + +[[package]] +name = "tao-macros" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "tar" +version = "0.4.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6221d9a6003c78398e3b239969f352578258df48c8eb051caadae0015bc840" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "target-lexicon" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + +[[package]] +name = "tauri" +version = "2.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "437404997acf375d85f1177afa7e11bb971f274ed6a7b83a2a3e339015f4cc28" +dependencies = [ + "anyhow", + "bytes", + "cookie", + "dirs 6.0.0", + "dunce", + "embed_plist", + "getrandom 0.3.4", + "glob", + "gtk", + "heck 0.5.0", + "http", + "jni 0.21.1", + "libc", + "log", + "mime", + "muda", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "objc2-ui-kit", + "objc2-web-kit", + "percent-encoding", + "plist", + "raw-window-handle", + "reqwest 0.13.4", + "serde", + "serde_json", + "serde_repr", + "serialize-to-javascript", + "swift-rs", + "tauri-build", + "tauri-macros", + "tauri-runtime", + "tauri-runtime-wry", + "tauri-utils", + "thiserror 2.0.18", + "tokio", + "tray-icon", + "url", + "webkit2gtk", + "webview2-com", + "window-vibrancy", + "windows", +] + +[[package]] +name = "tauri-build" +version = "2.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aa1f9055fc23919a54e4e125052bed16ed04aef0487086e758fe01a67b451c7" +dependencies = [ + "anyhow", + "cargo_toml", + "dirs 6.0.0", + "glob", + "heck 0.5.0", + "json-patch", + "schemars 0.8.22", + "semver", + "serde", + "serde_json", + "tauri-utils", + "tauri-winres", + "walkdir", +] + +[[package]] +name = "tauri-codegen" +version = "2.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a0319528a025a38c4078e7dae2c446f4e63620ddb0659a643ede1cb38f90e9" +dependencies = [ + "base64 0.22.1", + "brotli", + "ico", + "json-patch", + "plist", + "png 0.17.16", + "proc-macro2", + "quote", + "semver", + "serde", + "serde_json", + "sha2", + "syn 2.0.117", + "tauri-utils", + "thiserror 2.0.18", + "time", + "url", + "uuid", + "walkdir", +] + +[[package]] +name = "tauri-macros" +version = "2.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae6cb4e3896c21d2f6da5b31251d2faea0153bba56ed0e970f918115dbee4924" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.117", + "tauri-codegen", + "tauri-utils", +] + +[[package]] +name = "tauri-plugin" +version = "2.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e126abc9e84e35cdfd01596140a73a1850cdb0df0a23acf0185776c30b469a6e" +dependencies = [ + "anyhow", + "glob", + "plist", + "schemars 0.8.22", + "serde", + "serde_json", + "tauri-utils", + "walkdir", +] + +[[package]] +name = "tauri-plugin-dialog" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65981abb771e74e571a38196c3baa11c459379164791eba0e67abc1a5fac9884" +dependencies = [ + "log", + "raw-window-handle", + "rfd", + "serde", + "serde_json", + "tauri", + "tauri-plugin", + "tauri-plugin-fs", + "thiserror 2.0.18", + "url", +] + +[[package]] +name = "tauri-plugin-fs" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7ecc274121aca0c036a2b42d1cbe83d368d348f54e0bb8a735c2b1548e8f371" +dependencies = [ + "anyhow", + "dunce", + "glob", + "log", + "objc2-foundation", + "percent-encoding", + "schemars 0.8.22", + "serde", + "serde_json", + "serde_repr", + "tauri", + "tauri-plugin", + "tauri-utils", + "thiserror 2.0.18", + "toml 1.1.2+spec-1.1.0", + "url", +] + +[[package]] +name = "tauri-plugin-http" +version = "2.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5bd512048e1985b7ec78f96d99083e2ddaf7e0d906b2b63c44ce5bb8b894067" +dependencies = [ + "bytes", + "cookie_store", + "data-url", + "http", + "regex", + "reqwest 0.12.28", + "schemars 0.8.22", + "serde", + "serde_json", + "tauri", + "tauri-plugin", + "tauri-plugin-fs", + "thiserror 2.0.18", + "tokio", + "url", + "urlpattern", +] + +[[package]] +name = "tauri-plugin-process" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d55511a7bf6cd70c8767b02c97bf8134fa434daf3926cfc1be0a0f94132d165a" +dependencies = [ + "tauri", + "tauri-plugin", +] + +[[package]] +name = "tauri-plugin-shell" +version = "2.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8457dbf9e2bab1edd8df22bb2c20857a59a9868e79cb3eac5ed639eec4d0c73b" +dependencies = [ + "encoding_rs", + "log", + "open", + "os_pipe", + "regex", + "schemars 0.8.22", + "serde", + "serde_json", + "shared_child", + "tauri", + "tauri-plugin", + "thiserror 2.0.18", + "tokio", +] + +[[package]] +name = "tauri-plugin-updater" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "806d9dac662c2e4594ff03c647a552f2c9bd544e7d0f683ec58f872f952ce4af" +dependencies = [ + "base64 0.22.1", + "dirs 6.0.0", + "flate2", + "futures-util", + "http", + "infer", + "log", + "minisign-verify", + "osakit", + "percent-encoding", + "reqwest 0.13.4", + "rustls", + "semver", + "serde", + "serde_json", + "tar", + "tauri", + "tauri-plugin", + "tempfile", + "thiserror 2.0.18", + "time", + "tokio", + "url", + "windows-sys 0.60.2", + "zip 4.6.1", +] + +[[package]] +name = "tauri-runtime" +version = "2.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48222d7116c8807eaa6fe2f372e023fae125084e61e6eca6d70b7961cdf129ef" +dependencies = [ + "cookie", + "dpi", + "gtk", + "http", + "jni 0.21.1", + "objc2", + "objc2-ui-kit", + "objc2-web-kit", + "raw-window-handle", + "serde", + "serde_json", + "tauri-utils", + "thiserror 2.0.18", + "url", + "webkit2gtk", + "webview2-com", + "windows", +] + +[[package]] +name = "tauri-runtime-wry" +version = "2.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b83849ee63ecb27a8e8d0fe51915ca215076914aca43f96db1179f0f415f6cd9" +dependencies = [ + "gtk", + "http", + "jni 0.21.1", + "log", + "objc2", + "objc2-app-kit", + "once_cell", + "percent-encoding", + "raw-window-handle", + "softbuffer", + "tao", + "tauri-runtime", + "tauri-utils", + "url", + "webkit2gtk", + "webview2-com", + "windows", + "wry", +] + +[[package]] +name = "tauri-utils" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "092379df9a707631978e6c56b1bc2401d387f01e2d4a3c123360d167bbb9aa95" +dependencies = [ + "anyhow", + "brotli", + "cargo_metadata", + "ctor", + "dom_query", + "dunce", + "glob", + "http", + "infer", + "json-patch", + "log", + "memchr", + "phf", + "plist", + "proc-macro2", + "quote", + "regex", + "schemars 0.8.22", + "semver", + "serde", + "serde-untagged", + "serde_json", + "serde_with", + "swift-rs", + "thiserror 2.0.18", + "toml 1.1.2+spec-1.1.0", + "url", + "urlpattern", + "uuid", + "walkdir", +] + +[[package]] +name = "tauri-winres" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc65d45c68858bfe420dd29e834b5d15dbecf8a07a8a16cf4d532c7b1f69d4b6" +dependencies = [ + "dunce", + "embed-resource", + "toml 1.1.2+spec-1.1.0", +] + +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom 0.4.2", + "once_cell", + "rustix", + "windows-sys 0.61.2", +] + +[[package]] +name = "tendril" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4790fc369d5a530f4b544b094e31388b9b3a37c0f4652ade4505945f5660d24" +dependencies = [ + "new_debug_unreachable", + "utf-8", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl 2.0.18", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "time" +version = "0.3.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde_core", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" + +[[package]] +name = "time-macros" +version = "0.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinystr" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" +dependencies = [ + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-macros" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +dependencies = [ + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.3", + "toml_edit 0.20.2", +] + +[[package]] +name = "toml" +version = "0.9.12+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" +dependencies = [ + "indexmap 2.14.0", + "serde_core", + "serde_spanned 1.1.1", + "toml_datetime 0.7.5+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 0.7.15", +] + +[[package]] +name = "toml" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" +dependencies = [ + "indexmap 2.14.0", + "serde_core", + "serde_spanned 1.1.1", + "toml_datetime 1.1.1+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 1.0.3", +] + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.14.0", + "toml_datetime 0.6.3", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +dependencies = [ + "indexmap 2.14.0", + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.3", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.25.11+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" +dependencies = [ + "indexmap 2.14.0", + "toml_datetime 1.1.1+spec-1.1.0", + "toml_parser", + "winnow 1.0.3", +] + +[[package]] +name = "toml_parser" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +dependencies = [ + "winnow 1.0.3", +] + +[[package]] +name = "toml_writer" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" +dependencies = [ + "bitflags 2.11.1", + "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.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15edbb0d80583e85ee8df283410038e17314df5cba30da2087a54a85216c0773" +dependencies = [ + "crossbeam-channel", + "dirs 6.0.0", + "libappindicator", + "muda", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation", + "once_cell", + "png 0.18.1", + "serde", + "thiserror 2.0.18", + "windows-sys 0.61.2", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + +[[package]] +name = "typenum" +version = "1.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" + +[[package]] +name = "unic-char-property" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" +dependencies = [ + "unic-char-range", +] + +[[package]] +name = "unic-char-range" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" + +[[package]] +name = "unic-common" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" + +[[package]] +name = "unic-ucd-ident" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e230a37c0381caa9219d67cf063aa3a375ffed5bf541a452db16e744bdab6987" +dependencies = [ + "unic-char-property", + "unic-char-range", + "unic-ucd-version", +] + +[[package]] +name = "unic-ucd-version" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" +dependencies = [ + "unic-common", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-segmentation" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", + "serde_derive", +] + +[[package]] +name = "urlpattern" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70acd30e3aa1450bc2eece896ce2ad0d178e9c079493819301573dae3c37ba6d" +dependencies = [ + "regex", + "serde", + "unic-ucd-ident", + "url", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "uuid" +version = "1.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" +dependencies = [ + "getrandom 0.4.2", + "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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.3+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" +dependencies = [ + "wit-bindgen 0.57.1", +] + +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen 0.51.0", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9473dbd2991ae90b6291c3c32c30c6187ac49aa32f9905d1cce280ec1e110b0f" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.117", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap 2.14.0", + "wasm-encoder", + "wasmparser", +] + +[[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 = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags 2.11.1", + "hashbrown 0.15.5", + "indexmap 2.14.0", + "semver", +] + +[[package]] +name = "web-sys" +version = "0.3.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621441cfc37b84979402712047321980c178f299193a3589d05b99e8763436" +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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7cff6eef815df1834fd250e3a2ff436044d82a9f1bc1980ca1dbdf07effc538" +dependencies = [ + "phf", + "phf_codegen", + "string_cache", + "string_cache_codegen", +] + +[[package]] +name = "webkit2gtk" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1027150013530fb2eaf806408df88461ae4815a45c541c8975e61d6f2fc4793" +dependencies = [ + "bitflags 1.3.2", + "cairo-rs", + "gdk", + "gdk-sys", + "gio", + "gio-sys", + "glib", + "glib-sys", + "gobject-sys", + "gtk", + "gtk-sys", + "javascriptcore-rs", + "libc", + "once_cell", + "soup3", + "webkit2gtk-sys", +] + +[[package]] +name = "webkit2gtk-sys" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "916a5f65c2ef0dfe12fff695960a2ec3d4565359fdbb2e9943c974e06c734ea5" +dependencies = [ + "bitflags 1.3.2", + "cairo-sys-rs", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "gtk-sys", + "javascriptcore-rs-sys", + "libc", + "pkg-config", + "soup3-sys", + "system-deps", +] + +[[package]] +name = "webpki-root-certs" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "webpki-roots" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "webview2-com" +version = "0.38.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7130243a7a5b33c54a444e54842e6a9e133de08b5ad7b5861cd8ed9a6a5bc96a" +dependencies = [ + "webview2-com-macros", + "webview2-com-sys", + "windows", + "windows-core 0.61.2", + "windows-implement", + "windows-interface", +] + +[[package]] +name = "webview2-com-macros" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a921c1b6914c367b2b823cd4cde6f96beec77d30a939c8199bb377cf9b9b54" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "webview2-com-sys" +version = "0.38.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "381336cfffd772377d291702245447a5251a2ffa5bad679c99e61bc48bacbf9c" +dependencies = [ + "thiserror 2.0.18", + "windows", + "windows-core 0.61.2", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "window-vibrancy" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9bec5a31f3f9362f2258fd0e9c9dd61a9ca432e7306cc78c444258f0dce9a9c" +dependencies = [ + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", + "raw-window-handle", + "windows-sys 0.59.0", + "windows-version", +] + +[[package]] +name = "windows" +version = "0.61.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" +dependencies = [ + "windows-collections", + "windows-core 0.61.2", + "windows-future", + "windows-link 0.1.3", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" +dependencies = [ + "windows-core 0.61.2", +] + +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", +] + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + +[[package]] +name = "windows-future" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" +dependencies = [ + "windows-core 0.61.2", + "windows-link 0.1.3", + "windows-threading", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[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.117", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-numerics" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" +dependencies = [ + "windows-core 0.61.2", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" +dependencies = [ + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link 0.2.1", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", +] + +[[package]] +name = "windows-threading" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-version" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4060a1da109b9d0326b7262c8e12c84df67cc0dbc9e33cf49e01ccc2eb63631" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" + +[[package]] +name = "winnow" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.55.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb5a765337c50e9ec252c2069be9bf91c7df47afb103b642ba3a53bf8101be97" +dependencies = [ + "cfg-if", + "windows-sys 0.59.0", +] + +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck 0.5.0", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck 0.5.0", + "indexmap 2.14.0", + "prettyplease", + "syn 2.0.117", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.117", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags 2.11.1", + "indexmap 2.14.0", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap 2.14.0", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] + +[[package]] +name = "writeable" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" + +[[package]] +name = "wry" +version = "0.55.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186f9871daa55fd9c016578b810d149de58367113db7fb72b462d2323ce19514" +dependencies = [ + "base64 0.22.1", + "block2", + "cookie", + "crossbeam-channel", + "dirs 6.0.0", + "dom_query", + "dpi", + "dunce", + "gdkx11", + "gtk", + "http", + "javascriptcore-rs", + "jni 0.21.1", + "libc", + "ndk", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", + "objc2-ui-kit", + "objc2-web-kit", + "once_cell", + "percent-encoding", + "raw-window-handle", + "sha2", + "soup3", + "tao-macros", + "thiserror 2.0.18", + "url", + "webkit2gtk", + "webkit2gtk-sys", + "webview2-com", + "windows", + "windows-core 0.61.2", + "windows-version", + "x11-dl", +] + +[[package]] +name = "x11" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "xattr" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" +dependencies = [ + "libc", + "rustix", +] + +[[package]] +name = "xz2" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" +dependencies = [ + "lzma-sys", +] + +[[package]] +name = "yoke" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "zerofrom" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "zerotrie" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "zip" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabe6324e908f85a1c52063ce7aa26b68dcb7eb6dbc83a2d148403c9bc3eba50" +dependencies = [ + "aes", + "arbitrary", + "bzip2", + "constant_time_eq", + "crc32fast", + "crossbeam-utils", + "deflate64", + "displaydoc", + "flate2", + "getrandom 0.3.4", + "hmac", + "indexmap 2.14.0", + "lzma-rs", + "memchr", + "pbkdf2", + "sha1", + "thiserror 2.0.18", + "time", + "xz2", + "zeroize", + "zopfli", + "zstd", +] + +[[package]] +name = "zip" +version = "4.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caa8cd6af31c3b31c6631b8f483848b91589021b28fffe50adada48d4f4d2ed1" +dependencies = [ + "arbitrary", + "crc32fast", + "indexmap 2.14.0", + "memchr", +] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" + +[[package]] +name = "zopfli" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05cd8797d63865425ff89b5c4a48804f35ba0ce8d125800027ad6017d2b5249" +dependencies = [ + "bumpalo", + "crc32fast", + "log", + "simd-adler32", +] + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.16+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml new file mode 100644 index 0000000..388a19d --- /dev/null +++ b/src-tauri/Cargo.toml @@ -0,0 +1,60 @@ +[package] +name = "psg-launcher" +version = "0.1.0" +description = "PSG Launcher — all-in-one app launcher with signed OTA updates" +authors = ["Bailey Taylor"] +edition = "2021" +rust-version = "1.77" + +[lib] +name = "psg_launcher_lib" +crate-type = ["staticlib", "cdylib", "rlib"] + +[build-dependencies] +tauri-build = { version = "2", features = [] } + +[dependencies] +# Tauri core + plugins +tauri = { version = "2", features = ["tray-icon"] } +tauri-plugin-updater = "2" +tauri-plugin-dialog = "2" +tauri-plugin-shell = "2" +tauri-plugin-process = "2" +tauri-plugin-http = "2" +tauri-plugin-fs = "2" + +# Serialisation +serde = { version = "1", features = ["derive"] } +serde_json = "1" + +# Async runtime +tokio = { version = "1", features = ["full"] } + +# Cryptography — manifest + package verification +ed25519-dalek = "2" +sha2 = "0.10" +hex = "0.4" +base64 = "0.22" + +# HTTP client (rustls so we get TLS without OpenSSL system lib dep) +reqwest = { version = "0.12", features = ["json", "rustls-tls"], default-features = false } + +# ZIP extraction for zip-type app installs +zip = "2" + +# Error handling +thiserror = "1" + +# Utilities +chrono = { version = "0.4", features = ["serde"] } +semver = { version = "1", features = ["serde"] } +dirs = "5" +log = "0.4" +env_logger = "0.11" + +[profile.release] +opt-level = "s" # optimise for binary size +lto = true +codegen-units = 1 +strip = true +panic = "abort" diff --git a/src-tauri/build.rs b/src-tauri/build.rs new file mode 100644 index 0000000..d860e1e --- /dev/null +++ b/src-tauri/build.rs @@ -0,0 +1,3 @@ +fn main() { + tauri_build::build() +} diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json new file mode 100644 index 0000000..29e7843 --- /dev/null +++ b/src-tauri/capabilities/default.json @@ -0,0 +1,23 @@ +{ + "$schema": "../gen/schemas/desktop-schema.json", + "identifier": "default", + "description": "Default capabilities for the main launcher window", + "windows": ["main"], + "permissions": [ + "core:default", + "updater:default", + "updater:allow-check", + "updater:allow-download-and-install", + "dialog:default", + "dialog:allow-message", + "shell:default", + "process:default", + "process:allow-exit", + "process:allow-restart", + "http:default", + "http:allow-fetch", + "fs:default", + "fs:allow-app-read-recursive", + "fs:allow-app-write-recursive" + ] +} diff --git a/src-tauri/icons/128x128.png b/src-tauri/icons/128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..4b9c6051ab6439f17e1ef1c1b35571706c3400b2 GIT binary patch literal 1370 zcmcJP>pRm60LOoJ!{RtX7bVMC>}e!vR`$3|Gj!2iR&FU#6Cq=gE#s7)tX*mi8rH*>m#Xm20+sFI$C| z3)^niq46o`3!}tOezAMWDd^k_(mJtpCK0F>3v|OZb|^RNRuBaE9~p$UtKG>N8N3fOI~GGwD=V0=qzRfT zfZ@<#kl|5_VNS1W*y~+OEOxVlT42T(Z__tx_MsHTb~cGL9#ezbkgB6_B8x5tr+Ki) ziwMQVv7{YF`c~GrtHkG*j+#OS8KB8d*{C0Nqx_4(v%_m7ZGu@e-KrU@7Dw_m+pu<` zV8J)UUW9Pfv%>8T3tJmphC1K%NKSnfiWtNwDxVXnlAYP03*1)T6Rw%X4u_iKrAF{N z1$izb>r-|^NedTAX6~M1L!^k&ZVe7KBgBThq;m6Y6$bb`bemHG(Q*D|7r$U)K{3gvaUM}w_no3?{hIn^7Tv6GnEA(7$**>34(d$B=&%;vbY};zwrd>y zt}rexC$j1`GAsS@z}@3j$iS)|;v;9k@;BJ775-fAaqpcYt(kY$kjVxocXt8KgDJ`D zn}&mI`N`|`$!=3q7hbi`L$wzEB&E`}RjU5+dYgrE|pWYox#pCvvk3Tt&L zNP-tvL^ZiZzjo=Aw5fi1qCRhnVw7@dY}f}KFL~8C6BCs`Yfqq6W1a;(_PnhF`(hYR zC4k^`UPHa}aaD%}XeH5`w}SfNi+^Y&$04vOHzZFc_j4wWILXdax!LVwvU@yk)g=Jl{wwp1WJgpa)6K3^<##T zB#36edtbh)8r}G3WZl2#(M-2Eji9s1*bJ>aA>-|HPXAm=+wj7oX{G96eTm3D(2~`& z@c#NNqWdL@E{T`L&2)r%&FZp{u4}~wh@ordH#ipYjD>~Dh)09nH90&+w7p4gQ26I2 zTv(F)Lfp*x-ciCmis@Nj>xga}yy0+z6{9qf)ck0fxG%auPib^%PFh3qIwgV3uhREb znq_5f3+GwXgl!L-EK*qCzrEchx7NW&g4IVH9zJ1W^3>b<0l!pbxbF@@44MJ|&|)6L z)mu8s%paKJHJYDduN)K@oh~Y|bh+-y0@4FAIK5MS14qHqE}J^qdFog1_Euu%|7^)| z6lr$>XN4-UTGU(T>m15x7&#AA4gjxfZe@6C&i&9V1-C3YcL-7{Y_x#&NEhx!;=!gan2X>H}hO{{rpNTy6jW literal 0 HcmV?d00001 diff --git a/src-tauri/icons/128x128@2x.png b/src-tauri/icons/128x128@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a11c92d9d1711a7b581eda1d7acb8f2b08665571 GIT binary patch literal 2576 zcmb_ee>~Is8vktNM^r48grPb&r$Qx3(ok`_N2=Shb4c4O=c=Qaj0xjA2N4~VBNZCz zB1gt8qP3Z{l4vKRgKJwqf0Qn5AEfWOte9hfiUKCTAoz>AiND9FbC) zGBtD(i*a?(78PaC7ihTLrAW51h3-dWL%U zD39Cwq5#?z4ky1s26&MCfM#h#AzoE4Vg!aMW>2^eU?ldL%k)QA0dj!p%<2sVS__}S z9HB0<!ZaG60gIrpi{p!5)B{9Tb^m>wDNq*%H>gvFwQ#uef==&`3pQG%h}Uu)?E zWcO~dKN0>`Sc3?pojYlsy?)AN8Ms?yEsnEH>&G!;&$`Ea5HGJ_ZP!d&+q#;WfxC9v zBtbZ)=iv~}$5Bd}z4|QRMTM?@bGv7_51tTB&GNl^Zdx*0MiO5ic^{90v)0_OEwQj4 zf$(=1o+ObPTiRKPG^bj+%pxU`&=^eEiPk;CmZdSR+}*Rj=|uWo7$w18g`{bW-k%YA zizgMZCg?aF%ZDL};NICV^iQx7eE}EOsw@^#tuGWqX{;V%5`&&6P1DJ!MuXl!@vXQ`W~jS zi}5OOhC*J}jqo0Du1i>A+hp#AWUo7-Ck^RniPoc^UM1N=m$Q6je|Q)reO!qkWZy9x z96JgID`&LrK0INLJr@ODMEkG>GwGF-sMzMoPC1rE?t%5OsKRx>ho!eYz{S8mvQX;N ze9?v~uswhQkN@62HGd(Z)`dCYr++*X{47Q8f=ygoZ(<2vID(Nk1Y-L_JYijtRVQTJ zfY@Hu0VyM~DQ1-UxA!Zn^(yX01%EXQ?QQG$!(5{D3oJ9)ENlS>78Zz_7GO^K2O^wpVku~VCQY3eG|?* z&ds6UoY}$Vx-jC-R@BgL|H_3LnjXCrH4^Pv$EIAd#5MWAa^v8t`o!}!wBqXV`Aj^d zP>=7znCNg0M9wu146>P%IQizA5?xJPpeVdrk7R!r8}`6lzndA}G!_0! zZ8;P<*g>nYN@78y;1zZsyf^N#ot?(HhjTp_eajAFK$pYjsYZsU#fLT->bTo(^oZZ>B+{5Y>Xg>Bw-Ac zW+#W}vl75_G87d%FXBF4ZlguAR~Aatsz>c;?V{R78;r=A)YZn`iR`!5&Xi$l;Kl9^ zp@+tZI_W)K;YmTZqnd&+nJG(8%V&!D<<2v`WpF~7|F+AUFt2qwQ}((50($M z7{f%7K%i$*YKZ_WTB!gV>owHt!ic3QFdQm$x*6U-6rxZ#uS6~Y&XNTgU}rl*7>Zx3 za(wcIZZ|a$$^k;=&0fqjKSy@<)3X?dM`JubWoR}9wl+gs3$8U)qzE~lUli`|6I|a+ z%y+9L7uGBlVBwv%qurKRTeU87EyOV`0GGB4=I$TtHxSlf>LJU3%d3g`$yT`(V&O(K z7$}U#gnnP)_AWuMmznM8YJoGrJiGIY7!RG)tU$FY3i+RZ8|pEiI|!@^jTND*p9>Gh zf+FI%0cZxn*}uLi4Iwd2xFeDl7lqrfNzV0FTn#J@cR`{O4x?mhg{1^aISqN6u{cqQ j_W>e*Bk}+q;P2uak$#bnf~ssB00000NkvXXu0mjfY52S9 literal 0 HcmV?d00001 diff --git a/src-tauri/icons/64x64.png b/src-tauri/icons/64x64.png new file mode 100644 index 0000000000000000000000000000000000000000..64a25cfcf34b517dde67cf5fe6425bc21e6122fe GIT binary patch literal 727 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEV4COY;uunK>+P)5d6ykT+Wt#g zfA@Br$aOQMiFJ*}hQ?1U3J2Lfa(KMi@#cY}fb@}Ig*@wwg*rP`V-GH4Vm+v~c9xpo z8=m507AqI$6+4`>ymTVy*reip#WU-VeapXh%P=D0^Tr2i3@i-{0t`$J3>*xM3Jffm zoQBg=X7MHSKR^DMl_{b2SOJI2#Er}!-q>r3PMvM6=FIT!uIA#(80++@UcxWlO1}BZ zV>Op!zFm99R_7o4HZ}7fy2Ci(b8nkn&8LVO%iXUYpL)ta@9ydOS2?K}DR@>Fo%r0)Tduq%O7T@`>r_$xZ1JKKPapj> zVDX#3X@BgQhhJwat_n5%e(c0GmdPF4a_8=^5KTDAB*CL2ApMp7yY_`FuI#Tp?->ea zu%+ML9;U^{{62J2IPTT8yRnadIcD8F$-nQ_{p^cFW)Sw+QwgnZxrf>G}Tu z9Unei+{b)qDQm=crp{#c-Z}4YsqNTjcjR(9qnonA{O7kNHZm%-&k?AycDk)sy+tPI zOZ{KD9BapWLNf%No*1Ma zaLk?XmU*HJ$3zY(e{+YK_JT%f&t_e7xykMzJGW=n?AO0$?LYTlv*Fx%i}UPZ-@?|u wc=>jAr^YXNpOf1UO-L@po*uv{WrN2z_HyAj4no|E_b>o~r>mdKI;Vst0L(K%6#xJL literal 0 HcmV?d00001 diff --git a/src-tauri/icons/Square107x107Logo.png b/src-tauri/icons/Square107x107Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..efa42de2aa83b21a62ca5d2a6aa15ed32a4bf6c4 GIT binary patch literal 1226 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 literal 0 HcmV?d00001 diff --git a/src-tauri/icons/Square284x284Logo.png b/src-tauri/icons/Square284x284Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..d873bfa07cde8020e6da21bfa4a49ddca81dc87b GIT binary patch literal 2681 zcmbuBdpHyNAIIkql50gZbBQ_~*G0uPGli&*rciU|pj;~EzFczLDrS>VG%S?cT*8s& z+RWyZOD)$XESDBy&3%nI>W|L(=lA<{p5Gte=l#6D&+GYoKYx6m&*z-*YY}CmR~96aFMY#2kl{ z@o2;T5~QbgMqJNPE?WOlQWBT8_OQU5cxvCg+HbRK zK0~9qs|y;8=MNW0?sYG!$Te1CcX94p{d|pm@7|(!Mcu0F70mGcqDUe1PD#ENKtxOy z1fU3sh#g1&EwZ3*?wfoCw%m8_KjA;hQG~wN`)Aqz_jw8z1rV23g#hA&#if5|{Vl4H zZ|<9X1-9IGP8G5qqX=|tvCTMl_&WJ`buHsH@9OOyKIHH!UW*_va8- zISH)tD?GIT19e1WXgP+lM;#Y+-Viyu>R$(}4(CL{mpZ~y@CvP{l#mEZkKSqXri%$r zz6Ab!NO9^F6SAOaaZPSk~@cyI@6;6gp0RC=Jh+U#MW&c1&L12p;HmxTp-yVJq#?HCSyD{sX+|cd= zU+jv4FIVw~Zg8%`H>2vE#em8RN|abnd)*-H9vtb89S7WmE{SSfuSpx?J$HT=KIYuC z;Acpu11)iTg&U5ts(x=M%m{#P>#PTDOlFc83=8MQB*wF4F~ay=8GL)b*+yty(dJLv z#AclNFXYbQz4YPx3ag^7tF;6#dhxvHR+yu139Q2p)rp#LXwBP&(f7}$71O6UN|4u1 zy`%tfX<<+v=v@?a+nA%A434^??W&`jEz{^=hQ1veiI~NVA}@w4M7o6e zY9S&nk(|w+=BY#4StH=!@_JCTT>xp{!*wQa!+-6aJ#TNqEd(`}E_pLb&)PaX)v?gE z9)-9=_U#=;1+uZ$N`3<|tw@WxoLT}m?N>{Wj*VbF=ze${wIR=9>K8T7#btuD_IgCA zvHt>%h<%1~WoXvt`GiLV(xxhg*6|-quj-5TpDL;R_=r^HN5kg^3n(JDPB>8={6#Xr zf_Sk=F4nClBa$=OF|Tc*R7@OAxl-jTUwCK0RJ9Dl^-4Xeq#2vXnl|LMj5T69+D~tUxpB%!u<>cVEo^t_$1Zk8 zPi{w?a6tA?-QCL`eB;{lgG?K|Us1A_mkQVdO2&KgB`C2a_{0~T?8eoQ@oDcbg*got z2X#;-B4YP|Q>&(f&%~P12}a#H6c(_ zIF4H8TK)3u8zQD=7k}mY+ICw_q-h8}`Qx*Kgsll-CfQf(Kt2?h8!qZ3Dsct!r0)_p zrCUrFm{i;2H?VRwlVles+?nF9rVD8$e{Qdz9nZ3nBZWG^IR>Lq^REecYX}C7?TqPB z+#dcZ3%k8huwA<87-Sbs*+8Ym%Zo;F0ObjbMb;rSV>RSwH#Y658-)?z77XV7QX=eA z%t$^aP8chBjDN+@JBM-G+QrbZ(^IPdLM2}%3p?mK3oSf@erQsYojupOIp1v?7#7HE ziwd8bHRLS^5p#=)d0>_MPi|~|T6!}u^TdnN-X(!6`CQb-K=n`)*#U1g1A~2-LN#z# zJB;)UE(_~o>5^7(d>GSI;6T5`CBEvOI>>S5d2_T3pkrYZn4Iv@v?0m<+O-@v@4-s) zx61C5LIzA8xA;p1WssysBrhpv*XA1W8KITQwok&b zj$g}nXfo-ky3y+fy73ruQ8NI(TXAb-O#{!~eDnbJ_)uO>>fCA*xN-PqoN|97R=Gm^H}p3 zBU@a$^UrBpWV}D0k?)9q+g)X-_gltRC%d5y8iW4&utRUK>csnu8hkuUwxiZZGEVrv vMS_3R?f*y`-!jO*P9#5?T(-D!)aEt~FGU5KhWh+gqy(Hki8QY?b&vZC5@*we literal 0 HcmV?d00001 diff --git a/src-tauri/icons/Square30x30Logo.png b/src-tauri/icons/Square30x30Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..cde503f66e5c577987841a1bf5a81094dfa06d49 GIT binary patch literal 421 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 literal 0 HcmV?d00001 diff --git a/src-tauri/icons/Square44x44Logo.png b/src-tauri/icons/Square44x44Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..a442039a782ee86d2dfcb32dfc680b36db1ad473 GIT binary patch literal 588 zcmV-S0<-;zP)`LjIo~ow=bOL)+kC5Fo6aE;QL&z`3-0!7E#!Hp35;9hIqyw7?>d1ZI0@cjgKF) z=yZBS1m<}hmscFkW{BNAUmOUqZ8gwVqUee!PD~hh{mLBrnwhu2+-wHRD{Wj{a9CDy zXydMLq%WrHrQbo5=Djb!HiTO_soQS*?`GbJLT447Kh@o|L1qfo9-PB`{|`=}oT$T literal 0 HcmV?d00001 diff --git a/src-tauri/icons/Square71x71Logo.png b/src-tauri/icons/Square71x71Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..20a9958e9d9a05bdb70e579a82d3b0e895ecdb91 GIT binary patch literal 859 zcmeAS@N?(olHy`uVBq!ia0vp^?jX#;1|&l_M9DKSFe`bwIEGZ*dVAYDTf|X-{X_lv zWc8cwW(x#PhAJi~aRq)^bg{WYaDU4KM;DfZ>y?@+COvTNU$lbV_J>D^!TQa+vh=t- zuceefzv}lj@4a7&^B#-2DXS7^q^LK3>0kBgmE5D4eVeonE`DDyqoGiu9f2wg_#Pvp z4+%2I5@n8^lVA06k?N0Ok4wZ zU%OEIXG62}_3l@ZdP?s8Q{H)dD?Sr*;^E_Zb3gsziI(PtiVNonODw&$u-WX~oU)H! zX7+mtg+_{HDrdS1FEN?rpYYD#+%P8Be^$b}Sly(gJAwCKhrYfMD1JWv$ISn8r=6Vj zn3p3&c!HO!#*D3|o$dWmcR4PvEK^wN$jq$tdFfq^zMk8GF5*iCmR>&}Z}_To=gM`!Y!&oxs+cOHcXu=vD|N0!QHbG_v>9UOj5S9y?tx9 zTv%e>b-hD}4?C3}KCW&Xv+G4^uqX50I$;S(%1)wau>n zx88v_za1W?&W&=jPVthzF1mNuqy~$!e9r$L3=iC`=H04)`fBC5`_(#KLc2eI{Z!O* z+&`+~=c(|DmZ`J%in@9fIW@K(UE(~CfA_?|^~YCSO{)2KN${PpOvB*m>gTe~DWM4f@?emB literal 0 HcmV?d00001 diff --git a/src-tauri/icons/Square89x89Logo.png b/src-tauri/icons/Square89x89Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..b894ac9e2bab96445afb44c8b701455431b6516f GIT binary patch literal 1057 zcmV++1m63JP)xh6e&50~rBi zAOjfzWFRAe3}hf9fDB|HBY+HK1dxFYWCW0bi~ur_fs6n$kb#T@tC5(R&z zO7!4iLD%9qDuZ@*I@EVFOFccFzRt9DjNZ}V(4m7aeV8ceuEUmr(8_XQB9jpsxVcGC zlR6q31?X<{;}z%}OvmBIQ; zl#A`v>qvor`yN-FX4}}p)g3YqXs-JFb+kKG*F0=171kpQC72x8_{=R@y8`a+b}Nw0 z`P1j9qE-WWlL$gdOUvaoil|(IsjbbS+iLQW@x`z1B6$O*K1SsG0?4&aw~wk$;lg=e zp%FDVJ8C*D=*01q?lcT62j2is{UtA6hBQAP>%q~cbqp(!O?I9-nbJqKKH6MkfG4LS zdNLU3NsDa@MV`$A9AmBj*qbb8T%NEnFt>Ae?&d3|W+fJ z(ZX$Y;8U}@AW+%qlvnOKOL_hI%hy<~C70;UaFJ$bW6I@(l^JaP+68Cv(DRTUKMnLi z$KPYfHMN|{2fyZNH&3~v*zQMA)~>>FghfetRT7eqml&TjH#z$wJV@PMO?H2-8z&!} z#&rN&KhtVi-&+B&xdq5T-jP9XU9|x6cFXSitpVoD8(Jig|H1=Pb>0c0Qp83aHEG6Kjz1~LN3Kt=!=$UsH_8OT6J02#;#AOji52p|I) bQ5in~h+uw5IWNVU00000NkvXXu0mjfv{&it literal 0 HcmV?d00001 diff --git a/src-tauri/icons/StoreLogo.png b/src-tauri/icons/StoreLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..b1bc6c8870d1514469b2b12a2f485cf418ba3fef GIT binary patch literal 610 zcmV-o0-gPdP)3&DC)l;Rs;{le?~m0RJ@7@{TuY8=)qjI{sJS_ zL=vQ!ZP@I4zIoe(TH2HEg>0RHVPSV!=JRIeJMV3L^VTne6JRk;hzW>*2#A0Ph=2%) zfCz|y2+02pqSW!vj46EKL9_;bj|}Kw@Yc!RP}VCIvK|iTpFud#JO`GS3FpsMU=C35 zvvd#G-PPFnuF>mhBncsk{KI(3NH#HOHY42Fs2}^zcx>?URffk;_K;=p4x@a0gv&|i z#s$VD#u++nwHo2#g(_}uHrzXl+w4@7674t1gRKVdv8}B|E^9;!R$50{VoRxBC)+!O!B9J&%5xlG zdIbYXQ{&{g-#2KtA~a8_S?>&odNx}YezLExM_5@QwA&FbU#hx$Tw1JNozBF`a4A5p zUprcgw;rYF^);53$g6tIWv|6q`1mQu(`RG6dq43G5ftR1UHR@ejjG+23rDS$H9t&jblRpr^cPTqat`4JvTR>L9{8+36WQSWT*J+H`!miU8R819d$Wqo)3q6 wrIcs(c?U0lQ3OOl1VlgtL_h>YK;~nA0L&81nA + + + + \ No newline at end of file diff --git a/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png b/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..3a4dcd7cd266b09aa0f1b6f8510c2dfc780ef89a GIT binary patch literal 647 zcmV;20(kw2P)i*p2@e z7=D%jPO|NM=0waYq!ODT5=4SX5D6kd_*lmFdTowQmCSzOytx}~ub3eSAj^O1kZrIOo^G1Q^FZS^IjX=B2;tVGWle%t*gbkmUvjQtC5>rzJ z?%pY#;nUMCykD%b(bH(Pm{ZEf;yyjX4mo&rRbuJ0!t9*DrzPp0kx~;^IF#}mPCQuI z%Nfd&j5SuFgOGFHXQ!NtW9bvjx~6N7!V_0Hu3gVDIobTo`VWO~-?alYu|n*JQ=TzA zyk9wYQ|!|sHRfIkZ1*)f7yRWzFeND7cWjvz!Y27pV{J|2?YzM9vO=fh7a&N-b`4G$ zJbku{FJBd^ieYO@yS)$q!63-cKfAU8_L~P3Qq<(ADur18U!B+i0M8CprUI@y6-ARP zp#Z!$J86@5I3yJelpYO)+W)NN9fE|=*2@(8@8*YCwDVCd4SGG}x^zedyeeTvL*T}y z#`;g~VzeCPfiY+3JVC}%0$0`e!YD{}()(jYI-Vwo1d$*T#BsCJY5!6tCB~^l>}nim h8%v3uAQHrp^%q|`?+aJweQf{$002ovPDHLkV1mS^DL?=K literal 0 HcmV?d00001 diff --git a/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png b/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..85930bd594ab02a26154da62a5300f3ca685e298 GIT binary patch literal 1659 zcmbuAX*kpg0LF(}SBx1gYMjp?SCX8u?lBC5T+6zOL6jpiG0IKLf6AEJ!Q>bts ziPYSOJh3?va8QOwkqml8RgJ*qz;THQ%yV1x=iykw6eA2r2*-fIzmdRi#$u0R%vYzHqb~sz%XwZ^WOYck-5s zOTnRSB_i!C`N2>0qt8m#so)P}$$WGO4nK0rux z&$;U1JJ?N64IGY;o|&1&B?8`b&h^(wm7vF6+YN#%bbsUZDf^Js@tn1}lMa|<@D3=Ww+L-oCH{G%-r(8@W&0?i+k268L=G`Q#gkF z<)lT%A7wVzr}3nEiJhsqV%TbOH*$)&`cZtWA0kEz_lc+$ir?@n$pKiS{{SmN|8 z?0i{%p_+kTk|rmAV{MHWM*r;AGM_smz4;F4@LcT(pJMPwpVwSiXZ2IeHbj<+RmMz0 zTN13KIMb3 zVl$g-ZfOO*9;c?HF4(9#G1HG;pq+d6JGEw*pElW;iygO|svhU8cN@=0Z@;Ti=V1|# z9f%sW%x&0cqlH#g^g@L1&|7EL*zUBP-9zJsH-;>HpVgr*Zo@a=;zFX2_@9E`Ce1_*%a;|mGbP1a zscx}}Bh&bjHu`bvD*#aO#;D#GwbB!|Jo;W|)q29wZi!=$#qI`J&*)f882=DwS{T6z zGs#wjG*zC3@d~1r#17xgBp-{Hx7y87O3{#|^|{~#2V(bLXk}xddI71fcqjfkm;pi3 zC%AdKw(&vbJ7r)e!_vu!pPBL7-MI>l&m_0BfrpN4ImT|t7o2S^iP&~vto5jBGgFE2 z%p*As7(w|}dF@Bb7dWb{BnmrTu%vObs0O{z2VSw>?Kc}(M=mIEs$2d8s49XTr`YK( zTF+PJcWqFXT86dx=g&&P7fl>|lVzzmuL~0-FB&)F>SyH=ZpH2$dljgO z#BPU=A-n2hcFpRoG}r59FU8?-WjF{f2p3fT z4?ysY^H+2y_C0NjC{yDqa6TT~-^!9G6T8hZlK<$>J&9%whmi`|J_hA#)shfcz6zuMPjaB|DS` rqyZp61Q7Xmz7hVB{onFoW6@RM^r>uQ>W9d$rvgIRxgZ!eS2F$rTpQ_d literal 0 HcmV?d00001 diff --git a/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png b/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..125a14f2838effd579b1833a4836fbd89c668312 GIT binary patch literal 818 zcmV-21I_%2P)#0`LmI{+d=um>rDMA>A4 z6O#Bp(?wU0jYIe(v3n+Mla@!;*wXZSQ?EW#H324I1!p9Vv2Nb_&hq{2$qc2n2e}4& z(&d62od$5%gvbZ*qmog+5g29<-qsn4a<}oS7$)uxPF3FyJ=yzFh3}~G}DL$-}1gL@dE3jj*=|OidA@ z$Q=PBz!nLaf%*`rm6_Hk-gpk_Uh_U>tg-@Sj=R}k%f3Uib2KwLH()d=> zD3u5^#_EfU0d8C`VSZkr*<=JkMrFrIBT(OQYug(4A2e|HUL6k~HH?hdI{U&x4wo*5 zXtrSe#5)q!iTm;}WcK&9IT)|scCqrl`!j-^n^Ts6%SaWZk>psytrEZB-|~b=%?2*= zyk#R1E6kJC{gtJ_9ARQ0bN5%*B1=k0up=_T!I(R$HTr;NO@z90yMmm#xJ-gatIFQ#hDm_+I$HwIU$)JEY-C1>th|$x$fM`1ySo}MmfJRz z3X$~T)aH)IdJv6ftK!%S z`FsLAihlJQ???z}DKiR%1YxngT#5%GiL@I?Mp;lu&e%dtAhio}6BqUETkI{TWz_vv`%)JLBLRO1hb~}g$ zPj+cq;IQli*U!@IO9wE`(Nr4EWtHX_Dy#0eN_(D`MSFkpyW+lB<0uT|>$vMAH&A6g wb53I~bsEES*L(cG!}y7MEdpn+3b|W90P(C^g`QdxO8@`>07*qoM6N<$f^x!n@&Et; literal 0 HcmV?d00001 diff --git a/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png b/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..35c1a0fa0d53a1df8ffecd3cec9613135a3c4fca GIT binary patch literal 608 zcmV-m0-ybfP)fv7pFce& zH{ByH3;!1o+AHF3(slo8z}4t`8}$Glzyo*y50E(kA<3(INqP0^G(fYdgx;CgMwlo&ITcu4i?OkJVUEp{L5jCCB|Lk|)G?DLTh0M=$9->~ z!ZwuSq;P_bJ=dTz+00g=V ztAfr#ynTRn5eF*rl}h3`#&skz5pNejIZLsW*o*GAg3HucrF486)f1?W@Z5ZafdPtx z0}i6Rk`SOL#%V27JInVUe+;C1cXwX@eDAjPUdi+>w#Rpj?f7Nd?({3pRDZwoedT@UNAoRzYYA;&o8Qln z*kIrwaR@}UFajwKW*{ZN2BZ{ufRwX@0*^o&P=x{yLLr*^uLlcVV!~B!J&6~-_}i>n z|B#uYHiyfrUXMBD`)>XznAh>#GDt(^y=WW9?V!lB(@v;Y$66NdQCS-%A}=lBnO3n* zIXin|$m+Qf5nH8BT?*3ZPGiZPn0s4B`9fadPBF19$~U)Oo_e^QYj)lIG~-G3^U9yx z`|D8mZ>j3nDv|EjB?8-0gBLAY->3cF#PrqQrIVEB`~CiC@iR1V-~O=a?)%w{4D*&m zN@T9%^>qK!yUXgS>iU}tpKo6LeU6%p6>FBuTa$}c)%%o=_lZ57A0-msyg`xUET1du z(wT``f%9WunpC{YiTvhYc`4(D`q`{Rtq13i8pv^TFI=7r>%=lR&K35H1Xx%d2?(6C!O@%UY#2@OK!H2;I{nv>ig|^ zQ`V&PTfAO=^Z5==8xGfPZ3_H&{FD$*xUXlz!LWuW^L4QH!nByZ9T$2HzPx9{<^IpK3dN^G$rQSh1MzW`Vu92 z+pP2C+9FI&uKY-WpC*@ z;p^6UFVsf04t9fDXv_;bs zRFrZw_%|$>dr9Ba|9cUKb^Yht2Sm1IF+;M?-t)T>&3pR=)GG77f4{x2cf*{C>z0;8 zmuh(_`+UzbnI#|JVOjal|D~2&c74>w7qQtZt?%{+u6A{an5Xse?Y3(?lV99gp!RD$ zOY4R?p4uY!)-`r+kSUw$`I-@t1BuM48$$Q6anG2c#l88CJFu8x@O1TaS?83{1OT{c B6@~x+ literal 0 HcmV?d00001 diff --git a/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png b/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..c9a866031aeee6e489fe5fbea10e60496171c84a GIT binary patch literal 771 zcmV+e1N{7nP)<5R9m5}&6n_C-JzQQYO=e?abGkZJsFyg}-bpqVBfvYp$h0XO@o0?Mm`Fl z*=eCa3TdoB2LhoaR;vP~5+fs#R_LKUz-1IQn*yg#`8a!~h$xg~BoiSR!bqU~L*Vn5 z1TW?SY;FovtBlkW9)2M-FowI>^yz zBq*0@ykMn}6@5spbM2mYOA$I96~IPs#i9XDU9t2&y{fPN*R|gResOEdL3e8L+Er$6~yEcQWcFv7^lYq;)|2I#Tq`r8w1&E6Gp;-?kEG&P07j zW+j&H;f@}BFV3Mopn%qD40A6-e2`UF1?k#aqEjVc_g#R5fC8vMudfTNu15O1?=#Y3 zHSo<`)~cLJ#U}86nUmH5Aso5bqC8gEz9;22yC?f`$;)lGfNbATkAIgkZ!hd-pSjqf z8D!)5ez!%b?eIK$yOityn|D1%@zg31GKLMY|JmgpVpxXcd002ovPDHLkV1mU? BUvdBd literal 0 HcmV?d00001 diff --git a/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png b/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..4ed4c2d5db82314cbc0e811dbbb03a1054d984c1 GIT binary patch literal 1125 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 izB0v literal 0 HcmV?d00001 diff --git a/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png b/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..cf3eee20879fd3cebaf2bfc45508b1d554f1db0e GIT binary patch literal 1571 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�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 literal 0 HcmV?d00001 diff --git a/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png b/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..ae3eb10c7b5d03409e8d8eefbe314cbe5dfab2d0 GIT binary patch literal 4293 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 literal 0 HcmV?d00001 diff --git a/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png b/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..a277ffa433ad8d7326e97f4869b791687dfe4b23 GIT binary patch literal 2589 zcmYk8c{tQ-8^@pD%$S+TGFfv5gGS<#zCTl2lICf z6N_d=v(N4r01izU>S$lM{b@dB#FOtLUu#$A+{xj)6b4HowvI>-}^?= z7f2oN7xpOe@5(!RbNp&YRy3ynzP0F#0+Df!SbzWk0#pEC00;o^0PuzLiMXp=>hKv+ zMfUlyMjmgeq>aUI(|?Nt3AGFuWXWI=5PTaI0tgzHV8A0LP5=fmLOh^JABzQJk|-J* zSjL4WBB-0#dLsy?ggaydf+mT_wpv?UYuqCn2~$4PZ7|f`&)nD8z*eQ4MGnl9meBV7 zsv@KeLEVj@xAS4g;*VH=1F>RiFDzIQXC({TVz7n$U_u`?zz&#_i0{d`|M4~u9MtV0 zS`jNY^fN+`iKOY$k&4tM>fsEn7yWE@ZQSkxAskyF42g6!=m$E%4h0(MITVc{)#z5x zFEmfk#BTa4ChIc|?50M3H91D}Ic8p?RNJ*FNmV6DuJm7!zLPo|H$SXsmV794qd|b# zI`LXYG*U7JoGLK0|MY$%TaE;5n{OWExil@JJ^kx@NtVm2MN?6UD1{l{@ zXla4*lEm;oa)bvw6^o3%Lb)=fM0I_%nt#vQW^r=z>B$b0Kd(%7$6T)TK9RsLi%&|) z)+Df94b#8sA#Im>!T<1esXvFjH<_K#Pi7{6joXaz@$h`Dk08$y!@?y5I*?#ORcNB(fATnz9hAR@Ue}ctfd_ zyyH8~xg~OvissLrmDu|ebv=4*dLHmR>f+{dnRuyxQ&Al^h^(N>b0nxT z>(;kR?cNGK<)5gGC=vRcps=$2(0yq1-D5_QbjI=GZdYGJwpfZs>%+obuROd-N5Jw9 zfDCMGjwkF2o4|IPcOOc1?-w8{85Q)GPW)RFeV67BRN~RIo!wHe4RQ*4 zb%Id@x3uDcG^884)_NYD(8F9nudag7NS)He?c)DCwD*Pi4K;ET@M{k3?mEH5xeH?1# zIX~$dkM21B9%)4;4A(ijEMO7@fmE@bm%&y|AhOb#6`*{Oz4?XF4^4q&9*SiEZ zqgl;o1uE6V5viZ-U0ig^Js53dKmQ(KI8!}v&o5<1%hM%#^_oDvbf`I|E1K4?_$kjq z%`q+3R3~KE5^JdeE(c z%AkC_E%k_Rl67;S_Z5p&iiBKE4MU}o=#f#-;xrwWhcmW}7uP}<@V}ZuB_^wn%6u%# z&Sxn0p=;LHZ|7V|@&8gqlpJ1Q4CstiM(;%SUo5?`P#rdz$1R=2MgmxZO7|C=J85!H zTi(d0{-wNl@$7S2S1ZGlJ$iqwy3yw2$F;rsN6GTnd6CFvg%h!2P}YL{FB-$SNgk%e zAf;&cXH%{{g?ps5VCx6#+?)I@!jM7L#$LP1)KWZSfdTg&-TA=A8xv9Zp-z zE*Z>UI}D+^eN?D9%G*&ugSj-*^8ml^Z(+PY`Fs6YTCtU=oOjRMfF9)f8=m~UNcW)c zV6z8b^X>iOvftHedh*On!fUAplXImsG74hsd+)ybP%s_Qb>nyzEW$yo(DNUxH0ruu z7AWp18r(muHrP>;Z=8>s#ldQa3)TGIZk1t+nk*aS1~RQ6gh6w?)gY}VWJ%C0mCp-ua9V9;DPOFV3c{;k>mCx| zfgn)TWBp_lxLF(rkqo)-+Y0bPVO#DQ;DKiNG~*DE8Nm(=3GE4zK?KN3(ehB+#Q~-{ z62w|y=xngf)|l_O7#ks2hK-7aKW%D%m*)TW@}#j!7;uQ${dC|8w#>zW4)_#!Kt@AD zlo2u-IYg-=quGWiX=F5Jh!RXj9~z?AlhGVQ6sKqn;f42T_q*wjW1(EkAPI*S + + #fff + \ No newline at end of file diff --git a/src-tauri/icons/icon.icns b/src-tauri/icons/icon.icns new file mode 100644 index 0000000000000000000000000000000000000000..082eb5b7725e80612f2123710bd0358d9b05776c GIT binary patch literal 26657 zcmeHv2Ut_tw(v>lMFEi}AVD2PK|v8g5fW_7jEa>eRVkrJk*a_s2#AUT$|zEUVx4-(G`MhWNlrQ zw?PopTVlaxX=!D7)q>5~$l!F41=ktd%BCW_)0P1i+?M8N=K=lUF7z9|Z+z`uQ_$Kt8+GBgaNWL|F)lXZg-DF6?`*3p zrEqFR;bMEDh}>o&5|SPI5B@Z9lus+#dwLSOMh~xGmy?PO;dJcBP3`fQuAnz+$*tgA zQ=fQKNg;y&*iG#sPWW|;`_7q@awB&{gwNs#Av1E@ToyfUncTkitLxUAy|?$>xpT(w zFpU2_j1hC7F$n7E0OwZ#gliZnusv^a|7BWyL zP~_DwZXA-H|DCwuePvrU#hFSj_CH{HA@`QaRHOH{#r+4PstsnwRNHlUv}$3tEhF~h zo?ah)h!I5|ftE4T{V+Bzq^I?8vAZtH|_3ozl~}Q+gsUrZUxhJL=JI0f-yNPgwa8T^uUAAEs;nR+ zzwDK7yJ2PJYZCutotJxFLy~R$y8ZFh2XfX!%bsx_mBfUH+wMBjK|25R7khj98b!rI z^{pY4fVV@u$d$QHN;IdT{6|PIEF`Kqj))y$JoxVJJ38H9vFCjU2p$Q zcXmULIl~PDMPv`;8}3OpzJW={{A$9l*#Zg@WO-vM&S(89d3+Twtgyj?Z$G=7&0ymN zlZeX{4apnHi&N}2JHm@EARgiGUw5v}N|iWE3)nl->0#8@_H-4_H zeV%Vu|=pwpq zXPndYD$$qVZ?+0?N!wsJOI^>g^@`PKP)+B)G!L$ennK2}gth3Wi30w2&l+auh*!Ne zyGrxO*pTh`i{TDu3j5q@+S@p8uk!~D2>gk9hx7(+j|indIke$Yva|+8m1cap-41~$ z*d_El_wE!uU6CEt#0`D^DdI5?r!A9d0QibVa4*zb}v_}RaiU@*|n{>ZI^+17E^CRoq4UIIB2`fb0?zSKSDmu$~6w^KwF zYyn%8S#VfcTU%LKMp!_Gcmt&2X{$dhc+ObGKYg6=hl8=@EwJUDwwd#T*{1wWtZrHG zp0OE%BmJ7;M&=xNH3H)f+=TnA&U||1Z&dW>+$cOT2h#$L0Upm8n^CysP40PP%Ww;B zCYslALsKg-2IME;08^~xZ41sb*mf$;#PY5M(#FOz$^vobbPU*{VT%z9*c!Gjvqsq1 z;%y*ogf(Q0H$oa)+WcY7V`Xzc>FL8e&gR%#U?aD*XUTe*`HI)dei)7pXn~u|mR^m* zmwpR}`)#aPbE9yeDd~&3Ng(SLbDLX$r2Qz|TASx>h7Gsowz40AeRPda174sqn1F*$ z+hK28b6VMTQ2orYcde0j_Sh(Egq39s*!N-U5o>q?p6H#pG=6sin!(Q^sgvV(CLo3% zjATrY-=5&2!!y$~co7Ua>G1R@6{g=|UYs7EXI%tC1_K5!S@X2T`6+ zMK6Q`q!19;48cysBnk;GmE_-_`bqH5On!*^XYkK5ed`(?`T-R_llUR<&&I$*&g}oD zc~C!RO#uES+aFNsGx!%S`*}BhV*I0C|1WYf8MEWpej)i6qI^Gkew;0StT{WEhBa;| zky#}Op~w;bvYzl8Gi#h)%8u zGABgd0iA`Qvuqd$y26a`HBi?w2=9q7XM@Zop&cOP!OP9eRUpJfMPLemF#(1Vb5*Q? zt`H#zl7z^jP#U<7=;ZE1$54&tM4Vm|DLpt2JOpWS^CY=pAk37KARAsA|7JVq0i&nE zq5xc{omV^+1wpbNt^eYgm9fAONz!?B^Ndx|X#T9T;2I83WK}}%x zvv0bDP=W#ogyi>@sQBBW>g9+(tuF{ifHf}I0ki!{<_ui`nD9Krjf9*Rx!57|IWYG` zot6S?vACtpfQv^R=Zs)~2x?tGAfS^nG)EZ7mwgcfLG?ieEog2?sh}H+19MD?M`Q#c z{0BglX)7kA6vBKCAS=-TMR5ke#w9!&ZIw99A!=FcQl z3pRB`1@~zhx*U)?d2eJ1Ss+ zW&bV4|4R(S-^o*a@}c~ZopkOr_KKk z<@XYdU^%Jn(cx2k8r03xD$`rmv~xHu2ww6mj^g+%RqUBoZ*lC@_>pv#?T0;D z-#hSi{UVv1I~*1mK=viQck=M?Z!46&SIT|VVozVS>Fe!iZI79{4Dldsi`|-5Haj@7cI-9cOI6W*z`ZlhY~|>f zuyMzs*Pcngh&3pPn16`PN@%-dV3fJVWpnA)%}_)ZU*D+Au&Q8#`JikSzAEYJ{7b#u zm1jO2*e))2y&}NZ?8D3!En-CE$bg-nGI@9YRIs=}?7L)4<|f{G0#0&pD?yz*ndgSc zy(9vkK>4LLUAYJw&f@o^qK(UBw;s+}drMR-uqExc8mgZ0GKFQHTK88hPq4HLe8~R$ z&Se*()76e$okgs{t(}BccaC*Q-t@g0dMWX&6mZEG4pdTuAYSpW9SBwmh-a1qja{Bt zLl95nKdLt)Cn>B1c>+63O||Gh`Su9({NqMvgzm;oo8kpAzZ~_;+1rYeU7onKtu{+Yb&mw3{eSz4nsYJG^72*@#GA{7vs| zSaQOhS@hWJf+?Nu4d}vV0dsA;IeoBtxIs+enak*ZWbi*n=}(FNJ(4Y_j_o^i==zNJ z7KK)ZJ-rAPMUpGI;8tUF^T=esgkQB(Kw0P1l=o<}?n(3(8CrO_KXHMee~leU<`iJ; z6;SDVbMNV0`&llbCIz~d<*wK(;Wz@(H%5-L`lUoAm&|l`bEYqK)^5kzM~|)zHY)Q< zuqm^HnxeP!)mq$ghLf~y$h0?lV#HeIiEEnTA8h&c3SDn|9gTewB)w-3okW`!y-is& z!C0iEiRPV8uD{@9E~QC($d-3%l zcRT0dIpdx31LY>3BBQA5i%*~6IDFo@U-QztwY8GyKf9x=ky2eAira2N_o_i2P;u3Q z=GZO5%&5to`PxPk(Z&BbM_&P_z12~R}@Wuf5*k>nop^=WX!fVZc4nvVIl)r=P>V|)vRm6Zd3DM4b+cDd4bhPjTT;XV1MA{&R=iw24Mj3SNv zehW(6nr16#`RcPL`-ek)Z4*zuHNrKd)y*tCAy8J*y6Z#Kkw~%}@G}?8xG3B!bg?(r zbM?oma~)DW@b0>+`es9=2Z^uCJ`h#AC4-{tS0hRe#4|ENcW)C>yi*m}((A7iE*za- zjYvhPiO6v|uAX-tCwd5_0eQ81BVE$QI?PI`L-e^iLd(SKjK*$SprZPY?(#3bSJ8htsWF zb3Qr(_+BTOtXFG29=C*wg=VS_XJ9>c&hbGOvTMU6FZT4wL@0Vjqz(wUN_Wcl@^_N` zuG(1$iLr6uw?+y{DXP*99B}x|%4Pcx!5nyTg3+~H-KLhY>BLNAN$RTCg`Ar?S3qZc zJa}Fq)a&IE-Pt75`F0}7;)h|^W(L7itgGkc1xeiHK+NzP6^;uZmLtrA;&_|7k3dcL zCTS#%#*Qn}6d|bGL4({r>37e^&N*|WWb9;-$7?$5EEFc5WaO8dqVGu87(RtB20Pz%nU)Oq1Ow)v!|Xfl@|RE~n$YRsKT3vTA(;ld?2&Qyfb z{bJmd^+|7DpZVIS_a4Di>3}MIuiCRa7orhqy<9k*7S}{ZFroTnOJF^5d8oUlqYu@N z<^}^@nwElDs^uf0p{3w3@a!D?!siTp3|JagMWo zCq|o$K|iK1zAElend88ZsE)>pK8LF2q*)swK#lRen5KPxi*iU=FrFJS8s;u)57dY{GZ0S3gL-B=D_zO`jni(9{HIFW z3(MZVe&J>YT}inRs2Tcp=Ntid&%`8V$bIZAjF);h?`A&Q>^joiX@l!LvEN6nrzGx$_$37C;$@BH5WpA@OFFK8a>&d2rH=RDb zjPQDp>w){Ianb&LjXD?3_ki!6Mo(GDV)_)(N24)!Dt7XAORU^vbqw7-W{<+H;z#$qeD zQG@LGx-Mio0rW1Ig?*y!xpn{)_o*(7s&cHuth@|MsLvkMy2<$+0_Y`t}F)4n85na(yo zjNT}6J6d`DUTCy!W5NYvb?oimg$G6?hN=9!Vz~*LK{lCt=Zc>B3%qDWgiYPJtm!jp z;IlJ-u=`anQqzZjV(vE?deLeB_}eGpo#Q-jTIXFgN87g?@!GR~8|pW2 zm&z&p4bQdDPst9t2i_JDuorWw?CqLYV%H%&BbmJZK#i77)K!@+uWVoszmnw;OFA!N z{t_w9uOKK%<(id$W5;Vxy*>sx-{r)%Wa}v)sZlPq4%=528K8`ePV>I4UF&lr%t>N< z-J$sBkMbU0Inm>3-Tub4h=`@&A1K-^_MomTzIZ8YI@r)=(!HQ%_x|ioVM#XB5Wg7wHPDZNKG$}1?^pWI~kY~}Gb99{JE6rH>G*_oT= znvX}11PI+Ijp3g;(@%o0jE~nAvAuZ6VK9rlYQc3QW~_OAPLXD59Tst5EsD_JBA$*w z1;q$@sqbmo;{9Ce_%x2b+QM6XPqw{rbGTertH>mu>=11#!mke5^Casi?}flqn@2ff z)V11I+!fl>qhv+aatIq?ySb11Ciki%s+dT$&^GJ7sD^#-xiHeP*Q26`7NSTs@J4(M zMUBFxH=~y_@Np#is@#Iip_kb&!Ys~xJ04h(lJ@Him#6SBW(8kD0R$djg!lHpo7Ujq z!fZ35fMLLC??<~-cmV$2ZaX>u-LzgZ{%33cS0DV{wEnwk{dd!v+3)$P@A~Jpznj(= zV4lCoBmaN$``2Fk3pv3)#PsXGwGT0|zGa1f-LzKzyXX1;wT=3B&-3q|=ifcgzk8m4 z_dNgZdH&t={JZD*Gwoea?fsVy>;GiWQwf5$ZT`CF3ECZiC#&a)la>eX8rnL%)bku} zvky1Hx^EcIq-56THQgy~LOtY^JVL(wJL)OYFEUY_w_l`bos6vRya!L#1rgycRW|YC zJnUz$OSne9ST&q}s@%?G!KLPXMkBb#c_h0z@BJN$<^nxY$302$TINIELWaG@kOZv+ zU1Y>;xTd}1Tn%bnW~&A~m?H?qd}1Dvmg;9#LkEmOISfG<=F^wMzr@3{FhDI19$%37 zHXe!v_C3~L;r*b#yYe8CCHtfxaT~J%0Z& zRWU4CzQ_72Isap-qFA#0?@;wCt-og?cIfXU&Ga3f<-jjY_r(yyn){v=S-@YB_#PgL zMe_#(<}X=)wJCg$HJ-)#3;n(r{x#kYii~10VF7I$9U2KU{kUPxJ5$pA-(4n_f3u#cVdB!*U9QV?TUZM|awr`R_(uZ3!$(o2t3 z=T+Z{ws$9v`wkSFQm^G}8am4hvt@6SMXh8Z${ZNNZQ-^FPXA*}fHP1UlCB*Rk@;v@ zoN|c&^#gq8!=kNyrDR$F*;yRC1F&$xThSzs`Vu5vlO$W;?!((Ii7Oq+uXaABbMEkZq|TVJgqryFZ0?@zWUdPuYgqNY=7X1b zg)Z0U@FQV_{CbWgEM$TX~E>=($Sj`cpo+j$Ret?vQn8*rnAO5;VOQuE;L@H zzhUA?$NTGO#yL^{a0$Wb#NY5uv7CZP7PvvDATTD9u|T{$Q9f_@M}1?mNlbk{Vsc1( zZ9XsobvF`$wX@E1mChl)?lJECmJ4sp{I^)5{Tm%p>2x8$3!z5XBGtb?G_To8m2E5R!;ybDV_*>=-Y&c*D09~?aPM|z=2LnBvTBlrRbZec*K zEt*s9tSV-dZEjHiGW87EZQ_hFPnciv`2tlQ6#qZ;P{nx68|6adk#@YDk$cx8Che!Z zhrw-XmX@xnWVcn+x1{>|`^ynU3;O^*f$|$ZyTfsY?fL<4K90j|kl=d2Yu8MP4z;eP z_&0njSC}_KhcH@ynw%f;DzB5$g%0I-uFbPVaUb>(;#nGjz+M>(^%pg@E)N^)clWc> zoq+ExP#@ZDGB>7s?cT=2vK%T;lP9bSL1OgC#nGZqYlw^wCWX)SV^zChJz4U_dGKDQ z!e5UrZMdjBRh~EPf?){^Y|U`&<=vBkr)eK<^xeTztE}iMJ5@RpG0=+A08QndXk1e0T>MA*poN_&gZ(*e($Zal)JUoaE!dWCFt1}$9$D1tt2ko!r zr0JD6G_)VbEV)aKyD|yB>>9L2SujVh@KN}qMYOmYCxmH2fHSLtEG9|+;`jteouN>V zh@ZWE#==y>u?#c@oZRmMlMOg>hdm=x%J4XN7B>hc*m!6 zd}DXj2M3E)d7<$S@lXH{Q*$n8{#7($hia99$>y%g--V9&)BGG^;L-M>}W~kp{4b7WmE?_y_hS2>UwqiQ5iuUF=>r2knMbN zO2WwKgB&aA;H@Ir#a~O`DbS0BDUEK&M}2F+XC_!aFi3oee@~}u#P3Ere|VwL(BR?7 zA)YG&;gx{l-tlU zckRDC(Pxw)*ZPmy<^(9IJ_S0GFT%>=WS7+(YSVgnQ&)L%pLM%b=O_6d7KoTzBz$D_ z50JWK@M&xilxI;}<1D{PY*r3aG#hzjHfa|<3-(Mhtf^Wp^tP6EQ7p@51z5D7IDMy3|TOT(O5kL2!Stv{k50*I4 zPr;^<^l^MkJI+irJbTwNltPYrHnOJ)K5txlRd~M!$GDT?fn?o$NJmPst112df~qc9 z&j6Kt|1uPOYBx6hy&ECeS}lJ2*0f)>m3Jhrh34%%5C-hrco0*fdE*rQxL(tIgYtU2 zI`8(0xU%WC(XKvR#q;JJ=p@G2YGU3?@E-3Z_38=D4V)_<$_#fLbEKiqijf~4w4(2T z+nQJ<1SC5A8mB%(D1%7_X%a-b*Q%1!rRjr-*%#Fjqrab)NcY_-_G-V+Xommb_4%CT z$S$1?oWF-7WM;PDGq6b}5GA>^gwPry#>i~u826eQ>mM*-%(6j92+Ao-f#1(ly5J3P zk%?#97>W2~%omnJ;zv@fAJD?#LVYfT1b0t`faqkl@>V6Z1d4wSd=~H|MH7xQU6}Bo zr}LZbwqWkGX;1c>)Yn(nIEcE*clSAvaGnvlR<-A8297rs2hUB46=jQ{y=?QhjAy(- z8_+sxN-^pZVckRTi}m7t)AFIL?C7V#1)G%6sZ#I1X+ z_s`DEXSQ|kKFC;bdYqn_i+cd;t>=6uezE^Z#)9`Vb^4pVjYl}|a?hbcki!}|KJD{) zE}6+r$Vy7JwIizlgo5uC_-??2(6RmKVEARvsF<_i_AFSVL`yVkf9weVK?jwuKi7S08M-8TliFym{ir#^*XZXDt^v96tX10J!F=% zj1`E^T-hs29d!7oudNrX+&VqH&+L?9_oAX>8L6C+wN{kGoaJoOFc|Alg^h+gHcohYz7A$9wLqM;>Bp zZFhhwJRR98%WhPUa%wMSSD8tcFF5Q*6RWK7R)(bun-8(~%=R$+JrXpseOIEKEGxCm zf;OyP#$rF4$nv3yR;UO?JJ3Cf29*^}ATM-|HthB}N7Jc*TB_eQ`(S`Fxzt}4A>?kjt$Ob9*xB;=sf@h2P#Y)F@z?D` za+py>?1IH3M3IIjq-? z3{wT0NwouCoCtK92L%>(IH+}dT4FfWj&DZ3w!#OQT&$2qTP}-=ND@XcOB;*=Z5_sN zj9u+Q;+5oC9JTp*`&j}(^2RVyZ8$RX*&^Wt*y>QfJZ57DALRmDU!V#9-E5@gEKHlX z_36*Ov2c4VyDZrR3aYAGk;`SCpNEJq+$99P0OhjzvAy_$WvIQN#)+%XMqaPj?=$kU zDVr}|&Mmu}yn;Nl9$#R(_3?U_^fQ`AP6)HMR`Z+SlhduMfFN8EhJMa{r|Has9X@M;UbwtWk}K%}$u>V02znH9f6sc29UeEGFIaFg z;6NlCqZV!TWR*l!=U2vG*P@;%ov_$XAEdzhWcgXSCQa&E+e3U%%)BQ^+~AkI;ulC= z7PGhw1PKUg)SaoQ{2AZH801ly4U@wGJ_!CW8nW?3OnZ7Do=;jlv;eUL%1pe$9a;Rs z4*Z(IXvmn2o3$VeilQM-dg8c@SbC9ZIaA1NTjPrgMDCT~)67i8&rcAr4DEz9A<~<> zLY->5)F}=PMAeR{5#KiVY_RJC{_);vM1~5M2@iG@T}MVL+gcxBB~Zt zVvW&2PG*4@zbH#SE1F)YTi&2YExIqmva^c_qs~?owvs}dmPRW3&$VK?sEbo(Y^*3; zE(Tv{2PN+H5xX9^R(oOMo$7&!K#IUD2h=zMyu>Wl;$3CQ52B!^=CkXezI-^kzGBjV ztYJc<(BB`d07o|FYOJtt_2R+e3>Q6j^MJSBevW=H*Ax>sImv>3It6X2*in|MXR^K zXd?%hKtgnynjzK9nzGwqeUJ5!%cgiIaT!$)G|X53-dO{h?g*19sdm7t*t_b-FySH124Q3!rfyIklU=11QJ zL)qCS18@`?Bslf8Ub*C|8QXXvSq495wlMcj!V?62Eas|uX{FHX{4$8r+6ODyZc z4U?kSL$7kOj+K`mu$_jNFwd znW`~VW5<<>q(<5#$+u$$o`0bk%ot{nZV5vXRbHPxreLELz29Dxs88&3$64*3bVe6Z ztIx$Ob}5DEnT&v#Sk|rM0PM>W*f)dEpw1I+iV2U@{t&Tt}yVHbZ{uc zD~5g|bh`Va(~a({#FJ(4E7K%((j({0Hg|0Z>{$D8oa;igS*b$wIC0cKwT(V(j-KoA zqE_NO;Fd0Uu)ffBgcmN!hOy4uq;@W{b_IhsT{ty`uI9{Vd6UHJK}qQ_5$CWHN7whZ zfNgj0m~mP}LyjQ)?k8ax8B?H~547usjdZuR5D(B~a6U&BX$SRFdknlYq}~|hkHD;~ z5F(N`5()DoT&8iZ3CTo8OY7@di_zD(0a_4%2v`did^T@m))eWO$b9a&B8Ar91Sf

BA1N%#ElZm#1wEl4(Qm%2+yU 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 literal 0 HcmV?d00001 diff --git a/src-tauri/icons/icon.ico b/src-tauri/icons/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..dc8e423b476e5f5c3176debaf3dc6e7ed2e53467 GIT binary patch literal 5433 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 literal 0 HcmV?d00001 diff --git a/src-tauri/icons/ios/AppIcon-20x20@1x.png b/src-tauri/icons/ios/AppIcon-20x20@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..2693d0b5a6efcaf1985eb69d49cc4e4c6d77c506 GIT binary patch literal 338 zcmV-Y0j>UtP)j5)uUP z{9+gk3`)tb(5b*Mgtwt(Yg4hetLXO)X&P{P_Ri(iC+)WQ3#Ua;b(2#O$B<=~{lkp= z2hGm5s`auG==xy_Xtl&EU0V(5^$M@-XS3=(wBtj%uwLcHdd&4r&iTa$&E`Kmbn={% zr1WYuvK*fbePfbDyuUL8-2pcuk57i%J58q}9_aS##zv}s8&`6kLs6FPMrH1o^4;Y| kqk2SUekp$`aru4m1uzh2V(6622LJ#707*qoM6N<$g0R4qfdBvi literal 0 HcmV?d00001 diff --git a/src-tauri/icons/ios/AppIcon-20x20@2x-1.png b/src-tauri/icons/ios/AppIcon-20x20@2x-1.png new file mode 100644 index 0000000000000000000000000000000000000000..09e189db0a10f8f6f9cbb2636027033e5f9cd606 GIT binary patch literal 511 zcmVI7zglw(z~;-f>o!^-BjqHpFlr}D8-K;I6C+t#I-s}oz+3XI(8Kot?$rQrM1_W zBqn#gIusXk&;t`V=so2wKb|K~F4p?yhd_jfg@_LWG(ZD1Km#;D1N?nZIvx|kzajzr z`V!z0LxO<(5tC@!CWyrV&L;>Y5>qJHm~woGO4^_gv|0jB&kXIhKq5i3v-u~Wn$(g{ z7B><|rO4R-jV4Fw(8X1y?;&+ENwrGc@zeA9DNwBrP^&TTK08CPRZJqEx8S-0luQU1 zjJtb=-Mu!pcUm|ucSrG+Wg9(Nc0wl%RNb6OtHvOxT=z%uRMKCoI_of$eUQn@zQ1!1 zxU}%|%6db1I6@}14-O~Jzu6QxJ?nWO)v@s@qFvfh zGpI_P$xsROW5E^54x#gKdiWJlnPW_Z3e(D<%9w(bj$BMn6TG}~?|>jggpOMZczWIg zXa09N5sw%!C~@$m2)neQHiO literal 0 HcmV?d00001 diff --git a/src-tauri/icons/ios/AppIcon-20x20@2x.png b/src-tauri/icons/ios/AppIcon-20x20@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..09e189db0a10f8f6f9cbb2636027033e5f9cd606 GIT binary patch literal 511 zcmVI7zglw(z~;-f>o!^-BjqHpFlr}D8-K;I6C+t#I-s}oz+3XI(8Kot?$rQrM1_W zBqn#gIusXk&;t`V=so2wKb|K~F4p?yhd_jfg@_LWG(ZD1Km#;D1N?nZIvx|kzajzr z`V!z0LxO<(5tC@!CWyrV&L;>Y5>qJHm~woGO4^_gv|0jB&kXIhKq5i3v-u~Wn$(g{ z7B><|rO4R-jV4Fw(8X1y?;&+ENwrGc@zeA9DNwBrP^&TTK08CPRZJqEx8S-0luQU1 zjJtb=-Mu!pcUm|ucSrG+Wg9(Nc0wl%RNb6OtHvOxT=z%uRMKCoI_of$eUQn@zQ1!1 zxU}%|%6db1I6@}14-O~Jzu6QxJ?nWO)v@s@qFvfh zGpI_P$xsROW5E^54x#gKdiWJlnPW_Z3e(D<%9w(bj$BMn6TG}~?|>jggpOMZczWIg zXa09N5sw%!C~@$m2)neQHiO literal 0 HcmV?d00001 diff --git a/src-tauri/icons/ios/AppIcon-20x20@3x.png b/src-tauri/icons/ios/AppIcon-20x20@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..9b65f8a7842e7ea8d4bd56df6fe3ad3dea8ffe34 GIT binary patch literal 737 zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw1|+Ti+$>^XU|Qkn;uunK>+LMxyvq(E$Nw8| z`y8mQt8imW(BVa~;Q@IKyWBZ8F7fcV!&u0yBGw^%po__TK>=gH)llZO8RDU?69Xo% z$TaADn|SYrTkot*tJvr4Q|~p}sB3M%|Nrk9fp^&Xt+}3`h?!%YoWPcb1KFKzVOVlS z_?D8$%Y!BBF6BD^I`gcRP3^`(1`ejwXN%8WE{JUm(wup`(6RC5@$bJ6Tx~mYsA>80 z!xv26mx=Q6i+p6RPY6Ip+qY4kkCVrl>W(YLjq;@7Jlc>9(^JDzVe=o?p!kYfl8+P#gngJNbH@n(~`Yk{^yRmv(D?6Puig$#j`qO*UaOx>_4{2 zCnqbLT$(#`V#XP(XEhQ*I?UgvYya3JIqUu6NBay?J5{_6oK5RUKVLm#mXI5(x4C!3 zzHrm$FJ^g*FXe3h`qgpWrD+>d=BXQ4Y6h(44AEj*E&uDr-QG5%FH=t!E&0RExn@f= zXHVPgSF5fDsT=)?D2<9-Tv)QCCnsI{oIu8IS#jgcxnc8LeU{kT>K1$ZCI_20>N5`*(1&50zL4n`;&$A_@)vYMirf#VurP{sYu{1*i ywW;o&+x<6#WF^S@yJGgFs+o-J9HR z7GakDPqXwij(#LKInk)s1w79^_OC*Pkqn0#tE&7c0 z6-XRnrK`}*mL&P}c*We_#*?Q#G#a)DUB4FK=8YiDO=_1f`B+(zXty;g6*u`R zkwcRPG&cuRcx))Y*$Q!Rkfgm$p9#0LD4}9^y_yR&>s>+xf!*$mh46T&7cNJCN5-** zcDp(a;k7kyl*4qqYx3AL7bI@qs-;*eMijPRO%CtxC#Y6Y zOlbBPxUufz`DW7;B7ymN8>32DB(+zs2d1|vKMUNWbm3HK7ZxV7g!UbqpJrdY>|?j3 zOtBJE$K1j|smO$(M*C3Pd^8vuOLuk@-o1}Z&L+;0&Y^Viglm0?vH7ew0u2T_El!lT zc_4FtAI%de1-mc6u5r-Bb$A9t=WLfLgJ6 zztpJJ1ipQbM^8ZistFhWGqSH>dIInJB@A5(TbfRpR&h%=3#c{E>oSy~3}q-o8Ol(G hGL)eVWhg^uwqJgI_Qf+mdv*W-002ovPDHLkV1jszLD>KR literal 0 HcmV?d00001 diff --git a/src-tauri/icons/ios/AppIcon-29x29@2x.png b/src-tauri/icons/ios/AppIcon-29x29@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..ef01d4c03c14ba7aee13e538c5980ec184f6ca4f GIT binary patch literal 699 zcmV;s0!00ZP);o&+x<6#WF^S@yJGgFs+o-J9HR z7GakDPqXwij(#LKInk)s1w79^_OC*Pkqn0#tE&7c0 z6-XRnrK`}*mL&P}c*We_#*?Q#G#a)DUB4FK=8YiDO=_1f`B+(zXty;g6*u`R zkwcRPG&cuRcx))Y*$Q!Rkfgm$p9#0LD4}9^y_yR&>s>+xf!*$mh46T&7cNJCN5-** zcDp(a;k7kyl*4qqYx3AL7bI@qs-;*eMijPRO%CtxC#Y6Y zOlbBPxUufz`DW7;B7ymN8>32DB(+zs2d1|vKMUNWbm3HK7ZxV7g!UbqpJrdY>|?j3 zOtBJE$K1j|smO$(M*C3Pd^8vuOLuk@-o1}Z&L+;0&Y^Viglm0?vH7ew0u2T_El!lT zc_4FtAI%de1-mc6u5r-Bb$A9t=WLfLgJ6 zztpJJ1ipQbM^8ZistFhWGqSH>dIInJB@A5(TbfRpR&h%=3#c{E>oSy~3}q-o8Ol(G hGL)eVWhg^uwqJgI_Qf+mdv*W-002ovPDHLkV1jszLD>KR literal 0 HcmV?d00001 diff --git a/src-tauri/icons/ios/AppIcon-29x29@3x.png b/src-tauri/icons/ios/AppIcon-29x29@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..4fc64b33c0de3219f27f6ac43ae235d65d3996d6 GIT binary patch literal 1011 zcmeAS@N?(olHy`uVBq!ia0vp^;ULVx1|$nl+{|HMVBY2F;uunK>+PJ|-XVb^$FA=@ zb982)qoeVmQwA-I4(wO0)?@mp`of>%m$*`ooN~tkxkci})jF4|G&fyw*t3NH+XUsf zXLD|*Z@+H0`T4aM3&iq1{!S@AW_f)2{WYK0=C3z?abGHKI?G@2pAHN=8n_wt9x&;# z02w<3fQ$!DKn9W^HreczGU{<|LC3fYW@~iKYUX9~JetIsVe~RUE7d&ZzlQe4fC*Qw zKfipUfLqjg<^7UZ>n6WCUMhR)x$><$Q?{(z$FYBlPDYyBg-4SV&UY)C|8DS;iD5gG z;8(iacfI}H;A-CR*U$A`tA6FQi;1(QZtg2>h_yVFcqlCr$-Nn|Xa5SA z{=5;AX_g$Gw1F?r*j`M_a?M)T-E*d&*xA03=iB4HzGL5Qm$RE}*~@UPv1IQJtsBWZ zBfqXVd*o={{$ulh%G^G9Dr?ECnaO9%ZfyT}EuEF|_+v*vRq9Dk10a>E6@ze@^i`J~eV~d8B^4=oH<8 zAcv>#_Ns;z{Q7OXSL$g(@Wy9{CFXOyIGp0Kb53mL!R=cMXa2aV!5sel&PQ`b+qzA@ zGka>ArSD%marDDCsUshDeEiwX;t(*(I=j(uKn9pl5}Ci)$0AB&Cy}T z?dvbQ{`waCg0bq{p}@soH@BW#Il)anH@JHC;?LUM?8Y`LK3=WN%Zcnhcq@}T^ybvb zOvm+-`Tt}bH`(Jhk7vj48HN)4Ywd;R{rmUWlkee0E0!JVIZraALPEUQjGUgz)op$d zId{@A78xVckFRp_|B;*}+*7XORy%VD*) z{-pnbXIsqP6?dBZB`RlKU9qX(_(t+)SDOQ^4B`ch;!H6ISYtSVi~>a<11tzI7zglw(z~;-f>o!^-BjqHpFlr}D8-K;I6C+t#I-s}oz+3XI(8Kot?$rQrM1_W zBqn#gIusXk&;t`V=so2wKb|K~F4p?yhd_jfg@_LWG(ZD1Km#;D1N?nZIvx|kzajzr z`V!z0LxO<(5tC@!CWyrV&L;>Y5>qJHm~woGO4^_gv|0jB&kXIhKq5i3v-u~Wn$(g{ z7B><|rO4R-jV4Fw(8X1y?;&+ENwrGc@zeA9DNwBrP^&TTK08CPRZJqEx8S-0luQU1 zjJtb=-Mu!pcUm|ucSrG+Wg9(Nc0wl%RNb6OtHvOxT=z%uRMKCoI_of$eUQn@zQ1!1 zxU}%|%6db1I6@}14-O~Jzu6QxJ?nWO)v@s@qFvfh zGpI_P$xsROW5E^54x#gKdiWJlnPW_Z3e(D<%9w(bj$BMn6TG}~?|>jggpOMZczWIg zXa09N5sw%!C~@$m2)neQHiO literal 0 HcmV?d00001 diff --git a/src-tauri/icons/ios/AppIcon-40x40@2x-1.png b/src-tauri/icons/ios/AppIcon-40x40@2x-1.png new file mode 100644 index 0000000000000000000000000000000000000000..536f5a25e35e902d03a0ae579587ae3750e5b92e GIT binary patch literal 918 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 X$V(^DtBbeA5Pvkc+?Bq=<-&gfg`@zx literal 0 HcmV?d00001 diff --git a/src-tauri/icons/ios/AppIcon-60x60@2x.png b/src-tauri/icons/ios/AppIcon-60x60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..8926f6b10e1e9310eb210faceb6667e085b1ce2e GIT binary patch literal 1297 zcmeAS@N?(olHy`uVBq!ia0vp^6(G#P1|%(0%q}r7u-x!;aSW-r^>$8dzDTGGK3c3wOqyn5y=Rxo7&Z=t~(UZvUG)>kkR|{!vk>THMK0zT)Bw)j)@y zpdAgDx{qMEyc3mY>y!4eE2( zzdXOb{@8~3%@6(yiat%@Z9et3%r$E5n|%eg{k^O~E1#^tEOJm;aoc6V%Ew=4ov{^r ze(2C!r@I_|F7IaipH=fYO>1Ih?b|3V?fPY#cFZ`@`}D}Ewbz?vdwDqioo{>Qvuv5u z&E4i3j&JaJD{NU}uxWk2-Q4)sUtRv~xHEb4{gS80=Ub^=Vivyov@1=&JwrBcs>;ds z`*Y9T%T+y#rHbEs{?sa~ zDa!swihcxadAYZF($w_%l9Si_mF8Sqn>ywE%u-G3NUiUOj=E%RjXAf}`=`L)qthF0 zzNYAKAI~bY(3`a8@D8`%ZytKAi}%l2`)2clAij%_A2&{oUd{S##*7o*tFl6${Fb-+ z^pE{)u6=Typ3=!riYG61lz2{)i*lZCeSPZbWhXa=vS+8M867TuQ2TiCl&1ETi^bQg z+`g|eX=2LHT^<{2l<)2`ow-(?CWM7Ms=?R8-j zWA+M~oYMbyYqGZ5>1$QDz8h)kJr3AYutw|b*4}%c>y$&LGni(%b}5J7UtV<1^}JpF$(6>r zGw0~E-?_w9cVU^0`rWyAjUL_IJ+tPE=jEK+FTIkL5>EHMFWzGP`dn}R{@16jFTY)M zI_K&|p4~aSwY@cOOmnUE<=L*k>+ZQVCsZ#lv#H;wZa+IYRn>I0Pot02PR~=@BK5`o z+_&AAR_3i1WSZ(X%k%!U+dg^s&%KFU|N6V>%uTC(-*kU#zq;QzGS2U9RKfo}ub;(S zZ@-qE>bb0JYQo*B#lL5Ff3w(qCbGip`7r`FBc4reQfD*P`K=zYH1yE{y;J6AX64QjIUO72_14&R_sZnZSsY=F z`~TiM{gmzK?8~Ny4h!tOckbXWt}R!~!j!K6R_V5!X2dDb11=E=6$NZ8%80V0Apu;Z d7i zo(+B9&JQi}@|ILBTNl6Gyy|eY)g}X2ObG8#id~g*=A|^Fu2~d-sG((YAR?^-#s^T(T_5=e`EUO5?N9#k?N9#6zQg}dcHOy_{FKgPWgA$1{IF+XZ}pjcsxSX_ zyoW!EOzn*8zgOmD{#F zCRA02t#9iQqqXvD_rJm+>TCw1uEmIM2DRLOJUZ zdMoXhu%0a6G4;vPe}UjEdv8^jvfMJeBapOCUHuxqUgwo1*IdRHo`#gDX}WXi4BOTl zqha42dOirm5Tmbfis8fPU?N%zu82Z<3L+ zo3fuz6p%n%ILk+XO^J}0)T&N4FZ(0Qco$2q4VF}63MM$1*}>-P8Qqny%C`Ixq^=!u zIlgz*2{nsI(MNaB*WN8tK*qMA8$IOe85DMlC8cc^^%;bQFTPRDjD@$K71 zF7FZ^UTM~M!ao5<%sDr{Nv*Qbs7L?=hIhSPGEj zI&O{i79~u0`n>Ze)ALML11w3eKe(flEZrSp&W(QhAL_v+DMP5e+vNDi93H-Y}a94H&xI6>af z(N2mTJy8Q6mJ2Snd)J14i9xG4Zi}T23hIpo2_ARUcW7-`DEiBGP(S(iYuEY*)h9y> zm1#BKOX*LSiZZ&*OrUFBjKkVOO8sDXXzY6HDeBvjfDVe0OepjV(VF zNkcjg9vW$)DYymU#|AIN~7l76NMvrA;h$7OI*z7~u_BiETM zXLP$(NDoOS*X&XTsu2SpaL35EgjHN1YB+ye9H0vr3TVJwZ(teA~s`gIn*e! U#&%7}P7wmUJbgWA?pKL_0FXd&`v3p{ literal 0 HcmV?d00001 diff --git a/src-tauri/icons/ios/AppIcon-76x76@1x.png b/src-tauri/icons/ios/AppIcon-76x76@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..7758761ddcca3573daaa34e4959097e78ce17057 GIT binary patch literal 906 zcmV;519kj~P)#0K7=1JE_I2hYca+JCK44D zaG@a)At;|^+UZ>9+;U5iN^rvr^na28(hh&~5R701BN)N{CzKrVhmE{HL2H7c8UdAxHfa9} z$5HVCxNiJ)d|sr}gSV+*QH<5zuCRBHYv7uhiObwvgmM7PFK8?+X=JlNTbnZ9-!fp5 zF^h{DCwj8Del@@Dxj~>&E(6oQB8-ewG4QI4FQZiy@~XC+bqg&?`(h=-TxaDmS#~z# zaybFxi%5I7$6r)c`12BY4j8VL+?3B`lxioJ$vSxN^A- zrIN0n({gQv#hQuV(>L}tj5l}%Ki=c^?{iQns8#0)-np|L1_vt`{uCmgPi9X`1=#3V zh}(A-;1`sskj0`x?|Bawdvo=3EKc{)EQa2PD5w@&lB@n|t}sYo8IdsrP&P%RhrUFdrK(xH7w46wPLqeG#y(?!qmY`v?OLo!c_!OMY4qGM9xV1m)r z<>J=OLetsPVoBV4P{PzyWU6UPf;FPqWoGs&RjZPApDLF%?%prq^_vRX{bYym#KCN1 z+H6LY4Sw)#1$|Eg{FsOm$4X77|LuDf&tH_yz%7r-20!sL!uWWE>FLPqZNA@Pmv`0! zo1Bc$|12f2a{e;X%&>JcE2^%{hqhVW3ZXXhf4&7q=D?jhR;r<7S`c5x`8}f(8>mye zBn3onV$9F$HMijGyhyMn_a~d-Xicy!^_~g#VFV)>!3f467{LfeFoF?`K`??5j9>&~ g5R701BiQzeKVuX?QWiNZSO5S307*qoM6N<$f=aln5&!@I literal 0 HcmV?d00001 diff --git a/src-tauri/icons/ios/AppIcon-76x76@2x.png b/src-tauri/icons/ios/AppIcon-76x76@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..b7819ee914182fea20e088e806dc11e5f6f3d377 GIT binary patch literal 1605 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 Result { + let content = tokio::fs::read_to_string(db_path(&app)?).await?; + Ok(serde_json::from_str(&content)?) +} + +// ── Mutations ───────────────────────────────────────────────────────────────── + +/// Download, verify (hash + signature), and install an app entry from the manifest. +#[tauri::command] +pub async fn download_and_install_app( + app: AppHandle, + entry: AppEntry, +) -> Result { + let platform = entry + .platforms + .get(PLATFORM) + .ok_or_else(|| Error::PlatformNotSupported(PLATFORM.into()))?; + + log::info!( + "Downloading {} v{} from {}", + entry.name, + entry.current_version, + platform.download_url + ); + + // ── 1. Download ─────────────────────────────────────────────────────── + let client = build_https_client()?; + let resp = client.get(&platform.download_url).send().await?; + if !resp.status().is_success() { + return Err(Error::Network(format!( + "Download returned HTTP {}", + resp.status() + ))); + } + let bytes = resp.bytes().await?.to_vec(); + + // ── 2. SHA-256 integrity check ──────────────────────────────────────── + let actual_hash = { + let mut h = Sha256::new(); + h.update(&bytes); + hex::encode(h.finalize()) + }; + if actual_hash != platform.hash_sha256 { + return Err(Error::HashMismatch { + expected: platform.hash_sha256.clone(), + actual: actual_hash, + }); + } + log::info!("SHA-256 hash verified ✓"); + + // ── 3. ed25519 authenticity check ───────────────────────────────────── + let sig_bytes = base64::engine::general_purpose::STANDARD + .decode(&platform.signature) + .map_err(|_| Error::SignatureVerification("Package signature is not valid base64".into()))?; + verify_ed25519(&bytes, &sig_bytes)?; + log::info!("Package signature verified ✓"); + + // ── 4. Resolve install directory ────────────────────────────────────── + let install_dir = resolve_install_dir(&app, &entry, platform.install_path.as_deref())?; + tokio::fs::create_dir_all(&install_dir).await?; + + // ── 5. Install ──────────────────────────────────────────────────────── + let executable = install_package(&bytes, &install_dir, &entry, platform.install_type.clone()).await?; + + // ── 6. Persist install record ───────────────────────────────────────── + let record = InstalledApp { + id: entry.id.clone(), + version: entry.current_version.clone(), + install_path: install_dir.to_string_lossy().into_owned(), + installed_at: chrono::Utc::now().to_rfc3339(), + executable, + }; + + let db = db_path(&app)?; + let mut state: InstalledApps = serde_json::from_str(&tokio::fs::read_to_string(&db).await?)?; + state.apps.insert(entry.id.clone(), record.clone()); + tokio::fs::write(&db, serde_json::to_string_pretty(&state)?).await?; + + Ok(record) +} + +/// Launch an already-installed app by ID. +#[tauri::command] +pub async fn launch_app(app: AppHandle, app_id: String) -> Result<(), Error> { + let state: InstalledApps = + serde_json::from_str(&tokio::fs::read_to_string(db_path(&app)?).await?)?; + + let record = state + .apps + .get(&app_id) + .ok_or_else(|| Error::AppNotFound(app_id.clone()))?; + + let exe = match &record.executable { + Some(rel) => PathBuf::from(&record.install_path).join(rel), + None => PathBuf::from(&record.install_path), + }; + + if !exe.exists() { + return Err(Error::LaunchFailed(format!( + "Executable not found at {}", + exe.display() + ))); + } + + std::process::Command::new(&exe) + .spawn() + .map_err(|e| Error::LaunchFailed(e.to_string()))?; + + Ok(()) +} + +/// Remove an app's install record. Does NOT delete files — the user keeps +/// their data; they can delete the folder manually if desired. +#[tauri::command] +pub async fn uninstall_app(app: AppHandle, app_id: String) -> Result<(), Error> { + let db = db_path(&app)?; + let mut state: InstalledApps = + serde_json::from_str(&tokio::fs::read_to_string(&db).await?)?; + + if state.apps.remove(&app_id).is_none() { + return Err(Error::AppNotFound(app_id)); + } + + tokio::fs::write(&db, serde_json::to_string_pretty(&state)?).await?; + Ok(()) +} + +// ── Helpers ─────────────────────────────────────────────────────────────────── + +fn db_path(app: &AppHandle) -> Result { + Ok(app + .path() + .app_data_dir() + .map_err(|e| Error::Io(e.to_string()))? + .join("installed.json")) +} + +fn resolve_install_dir( + app: &AppHandle, + entry: &AppEntry, + custom: Option<&str>, +) -> Result { + if let Some(template) = custom { + let expanded = template + .replace( + "%APPDATA%", + &std::env::var("APPDATA").unwrap_or_default(), + ) + .replace( + "%LOCALAPPDATA%", + &std::env::var("LOCALAPPDATA").unwrap_or_default(), + ) + .replace( + "%PROGRAMFILES%", + &std::env::var("PROGRAMFILES").unwrap_or_default(), + ); + return Ok(PathBuf::from(expanded)); + } + + // Default: /../PSG/ + // Resolves to %APPDATA%\PSG\ on Windows + let base = app + .path() + .app_data_dir() + .map_err(|e| Error::Io(e.to_string()))? + .parent() + .unwrap_or_else(|| std::path::Path::new(".")) + .join("PSG") + .join(&entry.id); + + Ok(base) +} + +async fn install_package( + bytes: &[u8], + install_dir: &PathBuf, + entry: &AppEntry, + install_type: InstallType, +) -> Result, Error> { + match install_type { + InstallType::Portable => { + let exe_name = format!("{}.exe", entry.id); + tokio::fs::write(install_dir.join(&exe_name), bytes).await?; + Ok(Some(exe_name)) + } + + InstallType::Zip => { + let tmp = std::env::temp_dir() + .join(format!("{}-{}.zip", entry.id, entry.current_version)); + tokio::fs::write(&tmp, bytes).await?; + extract_zip(&tmp, install_dir)?; + tokio::fs::remove_file(&tmp).await.ok(); + Ok(None) // executable path comes from the manifest or user configuration + } + + InstallType::Installer => { + let tmp = std::env::temp_dir() + .join(format!("{}-{}-setup.exe", entry.id, entry.current_version)); + tokio::fs::write(&tmp, bytes).await?; + // Run the installer silently (NSIS /S flag) + let status = std::process::Command::new(&tmp) + .arg("/S") + .status() + .map_err(|e| Error::LaunchFailed(e.to_string()))?; + tokio::fs::remove_file(&tmp).await.ok(); + if !status.success() { + return Err(Error::LaunchFailed(format!( + "Installer exited with code {:?}", + status.code() + ))); + } + Ok(None) + } + } +} + +fn extract_zip(zip_path: &PathBuf, dest: &PathBuf) -> Result<(), Error> { + let file = std::fs::File::open(zip_path)?; + let mut archive = + zip::ZipArchive::new(file).map_err(|e| Error::Io(e.to_string()))?; + + for i in 0..archive.len() { + let mut entry = archive + .by_index(i) + .map_err(|e| Error::Io(e.to_string()))?; + let out = dest.join(entry.mangled_name()); + + if entry.is_dir() { + std::fs::create_dir_all(&out)?; + } else { + if let Some(parent) = out.parent() { + std::fs::create_dir_all(parent)?; + } + let mut f = std::fs::File::create(&out)?; + std::io::copy(&mut entry, &mut f)?; + } + } + Ok(()) +} diff --git a/src-tauri/src/commands/manifest.rs b/src-tauri/src/commands/manifest.rs new file mode 100644 index 0000000..826096f --- /dev/null +++ b/src-tauri/src/commands/manifest.rs @@ -0,0 +1,115 @@ +//! Fetches, verifies, and returns the apps manifest. +//! +//! Security model +//! ────────────── +//! 1. Manifest bytes are fetched over HTTPS (TLS prevents MITM on transport). +//! 2. A detached ed25519 signature is fetched from a second URL. +//! 3. The signature is verified against the raw manifest bytes using the +//! public key embedded at compile time. Signature failure is fatal — +//! we never parse or return manifests that haven't been verified. +//! 4. Only after successful verification is the JSON parsed into our types. +//! +//! This means a compromised Gitea server or CDN can serve garbage but the +//! launcher will refuse to act on it, because the attacker doesn't have your +//! private key. + +use crate::config::{MANIFEST_PUBLIC_KEY_B64, MANIFEST_SIG_URL, MANIFEST_URL}; +use crate::error::Error; +use crate::models::manifest::AppManifest; +use base64::Engine; +use ed25519_dalek::{Signature, VerifyingKey, PUBLIC_KEY_LENGTH}; +use tauri::AppHandle; + +/// Fetch the apps manifest, verify its signature, and return the parsed data. +/// All verification happens before any data is returned to the frontend. +#[tauri::command] +pub async fn fetch_app_manifest(_app: AppHandle) -> Result { + let client = build_https_client()?; + + // ── 1. Fetch manifest bytes ─────────────────────────────────────────── + let manifest_bytes = get_bytes(&client, MANIFEST_URL).await?; + + // ── 2. Fetch detached signature ─────────────────────────────────────── + let sig_text = get_text(&client, MANIFEST_SIG_URL).await?; + let sig_bytes = base64::engine::general_purpose::STANDARD + .decode(sig_text.trim()) + .map_err(|_| Error::SignatureVerification("Signature is not valid base64".into()))?; + + // ── 3. Verify signature (BEFORE parsing JSON) ───────────────────────── + verify_ed25519(&manifest_bytes, &sig_bytes)?; + log::info!("Manifest signature verified ✓"); + + // ── 4. Parse into typed model ───────────────────────────────────────── + let manifest: AppManifest = serde_json::from_slice(&manifest_bytes)?; + + Ok(manifest) +} + +// ── Shared crypto helper ────────────────────────────────────────────────────── + +/// Verify a raw ed25519 signature against `data` using the compile-time public key. +pub(crate) fn verify_ed25519(data: &[u8], sig_bytes: &[u8]) -> Result<(), Error> { + use ed25519_dalek::Verifier; + + // Decode the embedded public key + let pubkey_bytes = base64::engine::general_purpose::STANDARD + .decode(MANIFEST_PUBLIC_KEY_B64) + .map_err(|_| Error::Crypto("Embedded public key is not valid base64".into()))?; + + if pubkey_bytes.len() != PUBLIC_KEY_LENGTH { + return Err(Error::Crypto(format!( + "Public key must be {PUBLIC_KEY_LENGTH} bytes, got {}", + pubkey_bytes.len() + ))); + } + + let key_array: [u8; PUBLIC_KEY_LENGTH] = pubkey_bytes + .try_into() + .map_err(|_| Error::Crypto("Key array conversion failed".into()))?; + + let verifying_key = VerifyingKey::from_bytes(&key_array) + .map_err(|e| Error::Crypto(e.to_string()))?; + + let signature = Signature::from_slice(sig_bytes) + .map_err(|e| Error::SignatureVerification(e.to_string()))?; + + verifying_key + .verify(data, &signature) + .map_err(|_| { + Error::SignatureVerification( + "Signature verification failed — content may have been tampered with".into(), + ) + }) +} + +// ── HTTP helpers ────────────────────────────────────────────────────────────── + +pub(crate) fn build_https_client() -> Result { + reqwest::Client::builder() + .https_only(true) // never fall back to plain HTTP + .user_agent(concat!("PSG-Launcher/", env!("CARGO_PKG_VERSION"))) + .build() + .map_err(|e| Error::Network(e.to_string())) +} + +async fn get_bytes(client: &reqwest::Client, url: &str) -> Result, Error> { + let resp = client.get(url).send().await?; + if !resp.status().is_success() { + return Err(Error::Network(format!( + "GET {url} returned HTTP {}", + resp.status() + ))); + } + Ok(resp.bytes().await?.to_vec()) +} + +async fn get_text(client: &reqwest::Client, url: &str) -> Result { + let resp = client.get(url).send().await?; + if !resp.status().is_success() { + return Err(Error::Network(format!( + "GET {url} returned HTTP {}", + resp.status() + ))); + } + Ok(resp.text().await?) +} diff --git a/src-tauri/src/commands/mod.rs b/src-tauri/src/commands/mod.rs new file mode 100644 index 0000000..c00b6f6 --- /dev/null +++ b/src-tauri/src/commands/mod.rs @@ -0,0 +1,3 @@ +pub mod apps; +pub mod manifest; +pub mod updater; diff --git a/src-tauri/src/commands/updater.rs b/src-tauri/src/commands/updater.rs new file mode 100644 index 0000000..5259c34 --- /dev/null +++ b/src-tauri/src/commands/updater.rs @@ -0,0 +1,75 @@ +//! Self-update commands for the launcher binary itself. +//! +//! Tauri's built-in updater plugin handles ALL the cryptography here — it +//! fetches `latest.json` from the configured endpoint, verifies the ed25519 +//! signature on the installer package, and applies the update. +//! +//! The public key used here (in tauri.conf.json `plugins.updater.pubkey`) is +//! generated separately from the manifest key via `npm run tauri signer generate`. + +use crate::error::Error; +use serde::{Deserialize, Serialize}; +use tauri::AppHandle; +use tauri_plugin_updater::UpdaterExt; + +#[derive(Debug, Serialize, Deserialize)] +pub struct UpdateInfo { + pub available: bool, + pub version: Option, + pub notes: Option, + pub date: Option, +} + +/// Check whether a new version of the launcher is available. +/// Returns immediately with cached/live data; does not block the UI. +#[tauri::command] +pub async fn check_for_launcher_update(app: AppHandle) -> Result { + let updater = app + .updater_builder() + .build() + .map_err(|e| Error::Update(e.to_string()))?; + + match updater.check().await { + Ok(Some(update)) => Ok(UpdateInfo { + available: true, + version: Some(update.version.clone()), + notes: update.body.clone(), + date: update.date.map(|d| d.to_string()), + }), + Ok(None) => Ok(UpdateInfo { + available: false, + version: None, + notes: None, + date: None, + }), + Err(e) => Err(Error::Update(e.to_string())), + } +} + +/// Download and install the pending launcher update. +/// Tauri will restart the app automatically after installation completes. +#[tauri::command] +pub async fn install_launcher_update(app: AppHandle) -> Result<(), Error> { + let updater = app + .updater_builder() + .build() + .map_err(|e| Error::Update(e.to_string()))?; + + let update = updater + .check() + .await + .map_err(|e| Error::Update(e.to_string()))? + .ok_or_else(|| Error::Update("No update available".into()))?; + + update + .download_and_install( + // on_chunk: called for each downloaded chunk — could emit progress events + |_chunk_len, _content_len| {}, + // on_finish: called when download completes + || {}, + ) + .await + .map_err(|e| Error::Update(e.to_string()))?; + + Ok(()) +} diff --git a/src-tauri/src/config.rs b/src-tauri/src/config.rs new file mode 100644 index 0000000..7907c92 --- /dev/null +++ b/src-tauri/src/config.rs @@ -0,0 +1,31 @@ +//! Compile-time configuration constants. +//! +//! The public key and manifest URL are the two values you MUST update before +//! building a production release: +//! +//! 1. Run `scripts/keygen.ps1` to generate your ed25519 keypair. +//! 2. Paste the output "Raw public key (base64)" value into MANIFEST_PUBLIC_KEY. +//! 3. Replace the YOURDOMAIN / OWNER placeholders in MANIFEST_URL and +//! MANIFEST_SIG_URL with your actual Gitea instance details. + +/// Raw 32-byte ed25519 public key, base64-encoded. +/// Generated by scripts/keygen.ps1. The matching private key signs both the +/// apps manifest and individual app packages in CI. +/// +/// ⚠ Replace this placeholder before building! +pub const MANIFEST_PUBLIC_KEY_B64: &str = + "z217KMG/Z1uq1gRI2ZZMANA79KLt4TkCQtO5fWihYlI="; + +/// URL of the apps manifest JSON on your Gitea instance. +/// Hosted on the `releases` branch so the URL is stable across releases. +pub const MANIFEST_URL: &str = + "https://git.psg.net.au/sonderau/psg-conduit/raw/branch/releases/manifests/apps.json"; + +/// URL of the detached ed25519 signature for the apps manifest. +/// Contains the base64-encoded signature of the raw apps.json bytes. +pub const MANIFEST_SIG_URL: &str = + "https://git.psg.net.au/sonderau/psg-conduit/raw/branch/releases/manifests/apps.json.sig"; + +/// Platform string used to look up platform-specific entries in the manifest. +/// Only Windows x86-64 is supported for now. +pub const PLATFORM: &str = "windows-x86_64"; diff --git a/src-tauri/src/error.rs b/src-tauri/src/error.rs new file mode 100644 index 0000000..bf125f1 --- /dev/null +++ b/src-tauri/src/error.rs @@ -0,0 +1,62 @@ +use serde::Serialize; +use thiserror::Error; + +/// All errors that can be surfaced to the frontend via Tauri's invoke bridge. +/// `Serialize` is required so Tauri can serialise the error into JSON for TS. +#[derive(Debug, Error, Serialize)] +#[serde(tag = "kind", content = "message")] +pub enum Error { + #[error("Network error: {0}")] + Network(String), + + #[error("Manifest parse error: {0}")] + ManifestParse(String), + + /// Signature didn't match — treat this as a potential attack, not a soft error. + #[error("Signature verification failed: {0}")] + SignatureVerification(String), + + #[error("Hash mismatch — expected {expected}, got {actual}")] + HashMismatch { expected: String, actual: String }, + + #[error("Version downgrade rejected — current {current}, offered {offered}")] + VersionDowngrade { current: String, offered: String }, + + #[error("App not found: {0}")] + AppNotFound(String), + + #[error("Platform not supported: {0}")] + PlatformNotSupported(String), + + #[error("IO error: {0}")] + Io(String), + + #[error("Launch failed: {0}")] + LaunchFailed(String), + + #[error("Update check failed: {0}")] + Update(String), + + #[error("Invalid key material: {0}")] + Crypto(String), +} + +// ── From impls ─────────────────────────────────────────────────────────────── + +impl From for Error { + fn from(e: std::io::Error) -> Self { + Error::Io(e.to_string()) + } +} + +impl From for Error { + fn from(e: reqwest::Error) -> Self { + Error::Network(e.to_string()) + } +} + +impl From for Error { + fn from(e: serde_json::Error) -> Self { + Error::ManifestParse(e.to_string()) + } +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs new file mode 100644 index 0000000..1fbcf70 --- /dev/null +++ b/src-tauri/src/lib.rs @@ -0,0 +1,52 @@ +use tauri::Manager; + +mod commands; +mod config; +mod error; +mod models; + +pub use error::Error; + +#[cfg_attr(mobile, tauri::mobile_entry_point)] +pub fn run() { + env_logger::Builder::from_env( + env_logger::Env::default().default_filter_or("warn,psg_launcher=info"), + ) + .init(); + + tauri::Builder::default() + .plugin(tauri_plugin_updater::Builder::new().build()) + .plugin(tauri_plugin_dialog::init()) + .plugin(tauri_plugin_shell::init()) + .plugin(tauri_plugin_process::init()) + .plugin(tauri_plugin_http::init()) + .plugin(tauri_plugin_fs::init()) + .setup(|app| { + // Ensure the app-data directory and initial installed.json exist + let data_dir = app.path().app_data_dir()?; + std::fs::create_dir_all(&data_dir)?; + + let db = data_dir.join("installed.json"); + if !db.exists() { + let empty = models::installed::InstalledApps::default(); + std::fs::write(&db, serde_json::to_string_pretty(&empty)?)?; + } + + log::info!("PSG Launcher starting — data dir: {}", data_dir.display()); + Ok(()) + }) + .invoke_handler(tauri::generate_handler![ + // Manifest + commands::manifest::fetch_app_manifest, + // Apps + commands::apps::get_installed_apps, + commands::apps::download_and_install_app, + commands::apps::launch_app, + commands::apps::uninstall_app, + // Self-updater + commands::updater::check_for_launcher_update, + commands::updater::install_launcher_update, + ]) + .run(tauri::generate_context!()) + .expect("error while running PSG Launcher"); +} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs new file mode 100644 index 0000000..f2ac8ea --- /dev/null +++ b/src-tauri/src/main.rs @@ -0,0 +1,6 @@ +// Prevents a console window from appearing on Windows in release builds. +#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] + +fn main() { + psg_launcher_lib::run() +} diff --git a/src-tauri/src/models/installed.rs b/src-tauri/src/models/installed.rs new file mode 100644 index 0000000..921d04d --- /dev/null +++ b/src-tauri/src/models/installed.rs @@ -0,0 +1,21 @@ +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +/// Local state file (`installed.json`) recording every app the launcher has +/// installed on this machine. +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +pub struct InstalledApps { + pub apps: HashMap, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct InstalledApp { + pub id: String, + /// The version that is currently installed locally. + pub version: String, + /// Absolute path to the directory where the app is installed. + pub install_path: String, + pub installed_at: String, + /// Relative path (from install_path) to the executable, if known. + pub executable: Option, +} diff --git a/src-tauri/src/models/manifest.rs b/src-tauri/src/models/manifest.rs new file mode 100644 index 0000000..a77bb51 --- /dev/null +++ b/src-tauri/src/models/manifest.rs @@ -0,0 +1,65 @@ +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +/// Top-level structure of `apps.json`. +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct AppManifest { + pub schema_version: u32, + pub generated_at: String, + /// The launcher must be at least this version to use this manifest. + pub minimum_launcher_version: String, + pub apps: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct AppEntry { + /// Stable, URL-safe identifier. Used as the key in installed.json. + pub id: String, + pub name: String, + pub description: String, + pub category: AppCategory, + /// Latest available version in the manifest. + pub current_version: String, + pub icon_url: Option, + pub changelog: Option, + pub tags: Vec, + /// Keyed by platform string, e.g. "windows-x86_64". + pub platforms: HashMap, +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +#[serde(rename_all = "lowercase")] +pub enum AppCategory { + Tools, + Utilities, + Games, + Media, + Development, + Network, + Other, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct PlatformEntry { + pub download_url: String, + /// Lowercase hex SHA-256 of the download file. + pub hash_sha256: String, + pub size_bytes: u64, + pub install_type: InstallType, + /// Optional override install path. Supports %APPDATA%, %LOCALAPPDATA%. + pub install_path: Option, + /// Base64-encoded ed25519 signature of the raw download bytes. + /// Signed with the same key as the manifest. + pub signature: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] +pub enum InstallType { + /// Single executable — copied directly to the install directory. + Portable, + /// ZIP archive — extracted into the install directory. + Zip, + /// NSIS/MSI installer — executed silently (/S flag). + Installer, +} diff --git a/src-tauri/src/models/mod.rs b/src-tauri/src/models/mod.rs new file mode 100644 index 0000000..237b9ce --- /dev/null +++ b/src-tauri/src/models/mod.rs @@ -0,0 +1,2 @@ +pub mod installed; +pub mod manifest; diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json new file mode 100644 index 0000000..5fd92e4 --- /dev/null +++ b/src-tauri/tauri.conf.json @@ -0,0 +1,53 @@ +{ + "productName": "PSG Launcher", + "version": "0.1.0", + "identifier": "net.yeahnah.psg-launcher", + "build": { + "frontendDist": "../dist", + "devUrl": "http://localhost:1420", + "beforeDevCommand": "npm run dev", + "beforeBuildCommand": "npm run build" + }, + "app": { + "windows": [ + { + "title": "PSG Launcher", + "width": 1280, + "height": 800, + "minWidth": 960, + "minHeight": 620, + "resizable": true, + "decorations": false, + "shadow": true, + "center": true + } + ], + "security": { + "csp": "default-src 'self' ipc: http://ipc.localhost; img-src 'self' data: blob: https://gitea.YOURDOMAIN.com; style-src 'self' 'unsafe-inline'; connect-src ipc: http://ipc.localhost" + } + }, + "bundle": { + "active": true, + "targets": ["nsis", "msi"], + "icon": [ + "icons/32x32.png", + "icons/128x128.png", + "icons/128x128@2x.png", + "icons/icon.icns", + "icons/icon.ico" + ], + "windows": { + "digestAlgorithm": "sha256", + "timestampUrl": "http://timestamp.digicert.com" + } + }, + "plugins": { + "updater": { + "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEZCNjJFQzRBMEQzQjQ5RDgKUldUWVNUc05TdXhpKzB0RGZseGMvTm9XQ0plRDk2Qko4OVI2aGM1a3FtNjlxSjdCano4dzJYWjgK", + "endpoints": [ + "https://git.psg.net.au/sonderau/psg-conduit/raw/branch/releases/manifests/latest.json" + ], + "dialog": false + } + } +} diff --git a/src/App.css b/src/App.css new file mode 100644 index 0000000..a8f4307 --- /dev/null +++ b/src/App.css @@ -0,0 +1,85 @@ +.launcher { + display: flex; + flex-direction: column; + height: 100vh; + overflow: hidden; +} + +.launcher__body { + display: flex; + flex: 1; + overflow: hidden; +} + +.launcher__content { + flex: 1; + overflow-y: auto; + display: flex; + flex-direction: column; +} + +/* Loading state */ +.launcher__status { + display: flex; + align-items: center; + justify-content: center; + gap: 10px; + flex: 1; + color: var(--text-2); + font-size: 14px; +} + +.spinner { + display: inline-block; + width: 18px; + height: 18px; + border: 2px solid var(--surface-3); + border-top-color: var(--accent); + border-radius: 50%; + animation: spin 0.7s linear infinite; +} + +@keyframes spin { + to { transform: rotate(360deg); } +} + +/* Error state */ +.launcher__error { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 10px; + flex: 1; + padding: 40px; + text-align: center; +} + +.launcher__error h2 { + margin: 0; + font-size: 16px; + color: var(--danger); +} + +.launcher__error-detail { + margin: 0; + font-size: 12px; + color: var(--text-2); + max-width: 480px; + word-break: break-word; +} + +.launcher__retry { + padding: 8px 20px; + border-radius: 6px; + border: 1px solid var(--border); + background: var(--surface-3); + color: var(--text); + font-size: 13px; + cursor: pointer; + transition: background 0.12s; +} + +.launcher__retry:hover { + background: var(--surface-2); +} diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..3293516 --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,75 @@ +import { useState } from "react"; +import { AppGrid } from "./components/AppGrid"; +import { Sidebar } from "./components/Sidebar"; +import { TitleBar } from "./components/TitleBar"; +import { UpdateBanner } from "./components/UpdateBanner"; +import { useAppManifest } from "./hooks/useAppManifest"; +import { useLauncherUpdate } from "./hooks/useLauncherUpdate"; +import type { AppCategory } from "./types/manifest"; +import "./App.css"; + +export function App() { + const { manifest, installed, loading, error, refresh } = useAppManifest(); + const launcherUpdate = useLauncherUpdate(); + const [activeCategory, setActiveCategory] = useState("all"); + + const categories = manifest + ? ([...new Set(manifest.apps.map((a) => a.category))] as AppCategory[]) + : []; + + const filteredApps = + manifest?.apps.filter( + (app) => activeCategory === "all" || app.category === activeCategory + ) ?? []; + + return ( +

+ + + {launcherUpdate.update?.available && ( + + )} + +
+ + +
+ {loading && ( +
+ + Fetching manifest… +
+ )} + + {error && !loading && ( +
+

Could not load manifest

+

{error}

+ +
+ )} + + {!loading && !error && ( + + )} +
+
+
+ ); +} diff --git a/src/components/AppCard.css b/src/components/AppCard.css new file mode 100644 index 0000000..08dea1f --- /dev/null +++ b/src/components/AppCard.css @@ -0,0 +1,191 @@ +.app-card { + position: relative; + display: flex; + flex-direction: column; + background: var(--surface); + border: 1px solid var(--border); + border-radius: 10px; + padding: 16px; + width: 200px; + min-height: 230px; + transition: border-color 0.15s, transform 0.1s, box-shadow 0.15s; +} + +.app-card:hover { + border-color: var(--border-hover); + transform: translateY(-1px); + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35); +} + +.app-card--has-update { + border-color: color-mix(in srgb, var(--accent) 45%, transparent); +} + +/* Update badge */ +.app-card__update-badge { + position: absolute; + top: 10px; + right: 10px; + background: var(--accent); + color: #fff; + font-size: 11px; + font-weight: 700; + width: 20px; + height: 20px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; +} + +/* Icon area */ +.app-card__icon { + width: 56px; + height: 56px; + border-radius: 12px; + overflow: hidden; + background: var(--surface-3); + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 12px; + flex-shrink: 0; +} + +.app-card__icon img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.app-card__icon-fallback { + font-size: 22px; + font-weight: 700; + color: var(--accent); +} + +/* Info */ +.app-card__info { + flex: 1; +} + +.app-card__name { + margin: 0 0 4px; + font-size: 14px; + font-weight: 600; + color: var(--text); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.app-card__desc { + margin: 0 0 8px; + font-size: 11px; + color: var(--text-2); + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; + line-height: 1.45; +} + +.app-card__meta { + display: flex; + align-items: center; + justify-content: space-between; + gap: 4px; +} + +.app-card__version { + font-size: 11px; + color: var(--text-3); + font-variant-numeric: tabular-nums; +} + +.app-card__installed-ver { + color: var(--success); +} + +.app-card__available-ver { + color: var(--accent); +} + +.app-card__category { + font-size: 10px; + color: var(--text-3); + background: var(--surface-3); + padding: 2px 6px; + border-radius: 4px; + text-transform: capitalize; +} + +/* Error */ +.app-card__error { + margin: 6px 0 0; + font-size: 11px; + color: var(--danger); + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; +} + +/* Actions */ +.app-card__actions { + display: flex; + gap: 6px; + margin-top: 12px; + align-items: center; +} + +.app-card__btn { + flex: 1; + padding: 7px 10px; + border-radius: 6px; + border: none; + font-size: 12px; + font-weight: 600; + cursor: pointer; + transition: background 0.12s, opacity 0.12s; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.app-card__btn:disabled { + opacity: 0.55; + cursor: not-allowed; +} + +.app-card__btn--primary { + background: var(--accent); + color: #fff; +} + +.app-card__btn--primary:hover:not(:disabled) { + background: var(--accent-hover); +} + +.app-card__btn--secondary { + background: var(--surface-3); + color: var(--accent); + border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent); +} + +.app-card__btn--secondary:hover:not(:disabled) { + background: color-mix(in srgb, var(--accent) 15%, var(--surface-3)); +} + +.app-card__btn--ghost { + flex: 0; + padding: 7px 9px; + background: transparent; + color: var(--text-3); + font-size: 11px; +} + +.app-card__btn--ghost:hover:not(:disabled) { + background: var(--surface-3); + color: var(--danger); +} diff --git a/src/components/AppCard.tsx b/src/components/AppCard.tsx new file mode 100644 index 0000000..ea30976 --- /dev/null +++ b/src/components/AppCard.tsx @@ -0,0 +1,153 @@ +import { useState } from "react"; +import { + downloadAndInstallApp, + launchApp, + uninstallApp, +} from "../lib/commands"; +import type { AppEntry, InstalledApp } from "../types/manifest"; +import "./AppCard.css"; + +interface Props { + app: AppEntry; + installed?: InstalledApp; + onRefresh: () => void; +} + +type ActionState = "idle" | "downloading" | "launching" | "error"; + +export function AppCard({ app, installed, onRefresh }: Props) { + const [state, setState] = useState("idle"); + const [errMsg, setErrMsg] = useState(null); + + const isInstalled = !!installed; + const hasUpdate = isInstalled && installed.version !== app.current_version; + const initial = app.name.charAt(0).toUpperCase(); + + async function handleInstallOrUpdate() { + setState("downloading"); + setErrMsg(null); + try { + await downloadAndInstallApp(app); + onRefresh(); + } catch (e: unknown) { + const msg = + e && typeof e === "object" && "message" in e + ? String((e as { message: unknown }).message) + : String(e); + setErrMsg(msg); + setState("error"); + return; + } + setState("idle"); + } + + async function handleLaunch() { + setState("launching"); + setErrMsg(null); + try { + await launchApp(app.id); + } catch (e: unknown) { + const msg = + e && typeof e === "object" && "message" in e + ? String((e as { message: unknown }).message) + : String(e); + setErrMsg(msg); + setState("error"); + return; + } + setState("idle"); + } + + async function handleUninstall() { + if (!confirm(`Remove ${app.name} from the launcher? (Files are kept.)`)) return; + try { + await uninstallApp(app.id); + onRefresh(); + } catch (e: unknown) { + console.error(e); + } + } + + const busy = state === "downloading" || state === "launching"; + + return ( +
+ {hasUpdate && ( + + ↑ + + )} + +
+ {app.icon_url ? ( + {app.name} + ) : ( + {initial} + )} +
+ +
+

{app.name}

+

{app.description}

+
+ + {isInstalled ? ( + <> + {installed.version} + {hasUpdate && ( + → {app.current_version} + )} + + ) : ( + `v${app.current_version}` + )} + + {app.category} +
+
+ + {state === "error" && errMsg && ( +

+ {errMsg} +

+ )} + +
+ {isInstalled && ( + + )} + + {(!isInstalled || hasUpdate) && ( + + )} + + {isInstalled && ( + + )} +
+
+ ); +} diff --git a/src/components/AppGrid.css b/src/components/AppGrid.css new file mode 100644 index 0000000..c5d5179 --- /dev/null +++ b/src/components/AppGrid.css @@ -0,0 +1,16 @@ +.app-grid { + display: flex; + flex-wrap: wrap; + gap: 14px; + padding: 20px; + align-content: flex-start; +} + +.app-grid__empty { + display: flex; + align-items: center; + justify-content: center; + flex: 1; + color: var(--text-3); + font-size: 14px; +} diff --git a/src/components/AppGrid.tsx b/src/components/AppGrid.tsx new file mode 100644 index 0000000..85ebc94 --- /dev/null +++ b/src/components/AppGrid.tsx @@ -0,0 +1,32 @@ +import { AppCard } from "./AppCard"; +import type { AppEntry, InstalledApps } from "../types/manifest"; +import "./AppGrid.css"; + +interface Props { + apps: AppEntry[]; + installed: InstalledApps | null; + onRefresh: () => void; +} + +export function AppGrid({ apps, installed, onRefresh }: Props) { + if (apps.length === 0) { + return ( +
+

No apps in this category.

+
+ ); + } + + return ( +
+ {apps.map((app) => ( + + ))} +
+ ); +} diff --git a/src/components/Sidebar.css b/src/components/Sidebar.css new file mode 100644 index 0000000..993974d --- /dev/null +++ b/src/components/Sidebar.css @@ -0,0 +1,75 @@ +.sidebar { + width: 192px; + flex-shrink: 0; + display: flex; + flex-direction: column; + background: var(--surface); + border-right: 1px solid var(--border); + padding: 12px 8px; + overflow-y: auto; +} + +.sidebar__list { + list-style: none; + margin: 0; + padding: 0; + flex: 1; +} + +.sidebar__item { + display: block; + width: 100%; + text-align: left; + padding: 8px 12px; + border-radius: 6px; + border: none; + background: transparent; + color: var(--text-2); + font-size: 13px; + cursor: pointer; + transition: background 0.12s, color 0.12s; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.sidebar__item:hover { + background: var(--surface-3); + color: var(--text); +} + +.sidebar__item--active { + background: color-mix(in srgb, var(--accent) 18%, transparent); + color: var(--accent); + font-weight: 600; +} + +.sidebar__footer { + padding-top: 12px; + border-top: 1px solid var(--border); + margin-top: 8px; +} + +.sidebar__refresh { + display: flex; + align-items: center; + gap: 6px; + width: 100%; + padding: 7px 12px; + border-radius: 6px; + border: none; + background: transparent; + color: var(--text-3); + font-size: 12px; + cursor: pointer; + transition: background 0.12s, color 0.12s; +} + +.sidebar__refresh:hover { + background: var(--surface-3); + color: var(--text-2); +} + +.sidebar__refresh-icon { + font-size: 14px; +} diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx new file mode 100644 index 0000000..5fe5eab --- /dev/null +++ b/src/components/Sidebar.tsx @@ -0,0 +1,48 @@ +import type { AppCategory } from "../types/manifest"; +import "./Sidebar.css"; + +const CATEGORY_LABELS: Record = { + all: "All Apps", + tools: "Tools", + utilities: "Utilities", + games: "Games", + media: "Media", + development: "Development", + network: "Network", + other: "Other", +}; + +interface Props { + categories: AppCategory[]; + active: AppCategory | "all"; + onSelect: (cat: AppCategory | "all") => void; + onRefresh: () => void; +} + +export function Sidebar({ categories, active, onSelect, onRefresh }: Props) { + const items: (AppCategory | "all")[] = ["all", ...categories]; + + return ( + + ); +} diff --git a/src/components/TitleBar.css b/src/components/TitleBar.css new file mode 100644 index 0000000..21af9cf --- /dev/null +++ b/src/components/TitleBar.css @@ -0,0 +1,66 @@ +.titlebar { + display: flex; + align-items: center; + justify-content: space-between; + height: 36px; + padding: 0 4px 0 14px; + background: var(--surface); + border-bottom: 1px solid var(--border); + user-select: none; + flex-shrink: 0; +} + +.titlebar__brand { + display: flex; + align-items: center; + gap: 8px; + cursor: default; +} + +.titlebar__logo { + font-size: 11px; + font-weight: 700; + letter-spacing: 0.12em; + color: var(--accent); + background: color-mix(in srgb, var(--accent) 15%, transparent); + padding: 2px 7px; + border-radius: 4px; +} + +.titlebar__name { + font-size: 12px; + font-weight: 500; + color: var(--text-2); + letter-spacing: 0.02em; +} + +.titlebar__controls { + display: flex; + align-items: stretch; + height: 100%; +} + +.titlebar__btn { + display: flex; + align-items: center; + justify-content: center; + width: 46px; + height: 100%; + border: none; + background: transparent; + color: var(--text-2); + font-family: "Segoe MDL2 Assets", "Segoe Fluent Icons", sans-serif; + font-size: 10px; + cursor: pointer; + transition: background 0.1s, color 0.1s; +} + +.titlebar__btn:hover { + background: var(--surface-3); + color: var(--text); +} + +.titlebar__btn--close:hover { + background: #c42b1c; + color: #fff; +} diff --git a/src/components/TitleBar.tsx b/src/components/TitleBar.tsx new file mode 100644 index 0000000..94c0b8c --- /dev/null +++ b/src/components/TitleBar.tsx @@ -0,0 +1,39 @@ +import { getCurrentWindow } from "@tauri-apps/api/window"; +import "./TitleBar.css"; + +export function TitleBar() { + const win = getCurrentWindow(); + + return ( +
+
+ PSG + Launcher +
+ +
+ + + +
+
+ ); +} diff --git a/src/components/UpdateBanner.css b/src/components/UpdateBanner.css new file mode 100644 index 0000000..2211772 --- /dev/null +++ b/src/components/UpdateBanner.css @@ -0,0 +1,51 @@ +.update-banner { + display: flex; + align-items: center; + gap: 12px; + padding: 10px 18px; + background: color-mix(in srgb, var(--accent) 12%, var(--surface)); + border-bottom: 1px solid color-mix(in srgb, var(--accent) 35%, transparent); + flex-shrink: 0; +} + +.update-banner__icon { + font-size: 18px; + color: var(--accent); + line-height: 1; +} + +.update-banner__body { + flex: 1; + display: flex; + align-items: center; + gap: 12px; + font-size: 13px; + color: var(--text); +} + +.update-banner__notes { + font-size: 12px; + color: var(--text-2); +} + +.update-banner__btn { + padding: 6px 16px; + border-radius: 6px; + border: none; + background: var(--accent); + color: #fff; + font-size: 12px; + font-weight: 600; + cursor: pointer; + transition: background 0.15s, opacity 0.15s; + white-space: nowrap; +} + +.update-banner__btn:hover:not(:disabled) { + background: var(--accent-hover); +} + +.update-banner__btn:disabled { + opacity: 0.6; + cursor: not-allowed; +} diff --git a/src/components/UpdateBanner.tsx b/src/components/UpdateBanner.tsx new file mode 100644 index 0000000..1a33213 --- /dev/null +++ b/src/components/UpdateBanner.tsx @@ -0,0 +1,27 @@ +import "./UpdateBanner.css"; + +interface Props { + version?: string; + notes?: string; + installing: boolean; + onInstall: () => void; +} + +export function UpdateBanner({ version, notes, installing, onInstall }: Props) { + return ( +
+
+
+ Launcher update available{version ? ` — v${version}` : ""} + {notes && {notes}} +
+ +
+ ); +} diff --git a/src/hooks/useAppManifest.ts b/src/hooks/useAppManifest.ts new file mode 100644 index 0000000..9def813 --- /dev/null +++ b/src/hooks/useAppManifest.ts @@ -0,0 +1,55 @@ +import { useCallback, useEffect, useRef, useState } from "react"; +import { + fetchAppManifest, + getInstalledApps, +} from "../lib/commands"; +import type { AppManifest, InstalledApps } from "../types/manifest"; + +export interface ManifestState { + manifest: AppManifest | null; + installed: InstalledApps | null; + loading: boolean; + error: string | null; + refresh: () => void; +} + +export function useAppManifest(): ManifestState { + const [manifest, setManifest] = useState(null); + const [installed, setInstalled] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + const cancelled = useRef(false); + + const load = useCallback(async () => { + cancelled.current = false; + setLoading(true); + setError(null); + try { + const [m, i] = await Promise.all([fetchAppManifest(), getInstalledApps()]); + if (!cancelled.current) { + setManifest(m); + setInstalled(i); + } + } catch (err: unknown) { + if (!cancelled.current) { + // Tauri serialises Rust errors as { kind, message } + const msg = + err && typeof err === "object" && "message" in err + ? String((err as { message: unknown }).message) + : String(err); + setError(msg); + } + } finally { + if (!cancelled.current) setLoading(false); + } + }, []); + + useEffect(() => { + load(); + return () => { + cancelled.current = true; + }; + }, [load]); + + return { manifest, installed, loading, error, refresh: load }; +} diff --git a/src/hooks/useLauncherUpdate.ts b/src/hooks/useLauncherUpdate.ts new file mode 100644 index 0000000..4512f2e --- /dev/null +++ b/src/hooks/useLauncherUpdate.ts @@ -0,0 +1,33 @@ +import { useEffect, useState } from "react"; +import { + checkForLauncherUpdate, + installLauncherUpdate, +} from "../lib/commands"; +import type { UpdateInfo } from "../types/manifest"; + +export function useLauncherUpdate() { + const [update, setUpdate] = useState(null); + const [installing, setInstalling] = useState(false); + const [error, setError] = useState(null); + + useEffect(() => { + checkForLauncherUpdate() + .then(setUpdate) + .catch((e) => console.error("Launcher update check failed:", e)); + }, []); + + const install = async () => { + setInstalling(true); + setError(null); + try { + await installLauncherUpdate(); + // App will restart automatically after install + } catch (e: unknown) { + setError(e && typeof e === "object" && "message" in e ? String((e as { message: unknown }).message) : String(e)); + } finally { + setInstalling(false); + } + }; + + return { update, install, installing, error }; +} diff --git a/src/index.css b/src/index.css new file mode 100644 index 0000000..61c43fa --- /dev/null +++ b/src/index.css @@ -0,0 +1,51 @@ +/* ─── Design tokens ──────────────────────────────────────────────────────── */ +:root { + --bg: #0d0d0d; + --surface: #181818; + --surface-2: #202020; + --surface-3: #2a2a2a; + --border: #2e2e2e; + --border-hover: #444444; + + --accent: #6366f1; + --accent-hover: #4f46e5; + + --text: #efefef; + --text-2: #a0a0a0; + --text-3: #5e5e5e; + + --success: #22c55e; + --warning: #f59e0b; + --danger: #ef4444; + + --radius: 8px; + --font-sans: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; +} + +/* ─── Reset ──────────────────────────────────────────────────────────────── */ +*, *::before, *::after { + box-sizing: border-box; +} + +html, body, #root { + margin: 0; + padding: 0; + height: 100%; + overflow: hidden; +} + +body { + font-family: var(--font-sans); + font-size: 14px; + line-height: 1.5; + background: var(--bg); + color: var(--text); + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* Scrollbars */ +::-webkit-scrollbar { width: 6px; height: 6px; } +::-webkit-scrollbar-track { background: transparent; } +::-webkit-scrollbar-thumb { background: var(--surface-3); border-radius: 3px; } +::-webkit-scrollbar-thumb:hover { background: var(--border-hover); } diff --git a/src/lib/commands.ts b/src/lib/commands.ts new file mode 100644 index 0000000..342e5fa --- /dev/null +++ b/src/lib/commands.ts @@ -0,0 +1,34 @@ +/** + * Type-safe wrappers around Tauri invoke calls. + * All heavy lifting (crypto verification, HTTP) happens in Rust. + */ + +import { invoke } from "@tauri-apps/api/core"; +import type { + AppEntry, + AppManifest, + InstalledApp, + InstalledApps, + UpdateInfo, +} from "../types/manifest"; + +export const fetchAppManifest = (): Promise => + invoke("fetch_app_manifest"); + +export const getInstalledApps = (): Promise => + invoke("get_installed_apps"); + +export const launchApp = (appId: string): Promise => + invoke("launch_app", { appId }); + +export const downloadAndInstallApp = (entry: AppEntry): Promise => + invoke("download_and_install_app", { entry }); + +export const uninstallApp = (appId: string): Promise => + invoke("uninstall_app", { appId }); + +export const checkForLauncherUpdate = (): Promise => + invoke("check_for_launcher_update"); + +export const installLauncherUpdate = (): Promise => + invoke("install_launcher_update"); diff --git a/src/main.tsx b/src/main.tsx new file mode 100644 index 0000000..fd7970f --- /dev/null +++ b/src/main.tsx @@ -0,0 +1,10 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; +import { App } from "./App"; +import "./index.css"; + +ReactDOM.createRoot(document.getElementById("root")!).render( + + + +); diff --git a/src/types/manifest.ts b/src/types/manifest.ts new file mode 100644 index 0000000..983e148 --- /dev/null +++ b/src/types/manifest.ts @@ -0,0 +1,61 @@ +export type AppCategory = + | "tools" + | "utilities" + | "games" + | "media" + | "development" + | "network" + | "other"; + +export interface PlatformEntry { + download_url: string; + hash_sha256: string; + size_bytes: number; + install_type: "portable" | "zip" | "installer"; + install_path?: string; + signature: string; +} + +export interface AppEntry { + id: string; + name: string; + description: string; + category: AppCategory; + current_version: string; + icon_url?: string; + changelog?: string; + tags: string[]; + platforms: Record; +} + +export interface AppManifest { + schema_version: number; + generated_at: string; + minimum_launcher_version: string; + apps: AppEntry[]; +} + +export interface InstalledApp { + id: string; + version: string; + install_path: string; + installed_at: string; + executable?: string; +} + +export interface InstalledApps { + apps: Record; +} + +export interface UpdateInfo { + available: boolean; + version?: string; + notes?: string; + date?: string; +} + +/** Serialised Tauri error shape matching our Rust Error enum */ +export interface TauriError { + kind: string; + message: string; +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..3934b8f --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 0000000..fe1e070 --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "noEmit": true, + "strict": true + }, + "include": ["vite.config.ts"] +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..2d6d9bf --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,25 @@ +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; + +// Tauri dev server host (set by the CLI when using --host) +const host = process.env.TAURI_DEV_HOST; + +export default defineConfig({ + plugins: [react()], + + // Prevent Vite from obscuring Rust errors + clearScreen: false, + + server: { + port: 1420, + strictPort: true, + host: host || false, + hmr: host + ? { protocol: "ws", host, port: 1421 } + : undefined, + watch: { + // Tell Vite to ignore watching `src-tauri` + ignored: ["**/src-tauri/**"], + }, + }, +});