diff --git a/.github/workflows/update-pnpm-hash.yaml b/.github/workflows/update-pnpm-hash.yaml index 53bcc51f..739bec7f 100644 --- a/.github/workflows/update-pnpm-hash.yaml +++ b/.github/workflows/update-pnpm-hash.yaml @@ -48,7 +48,7 @@ jobs: # Match the line containing "hash = " that follows the # attribute definition block (${attr} ... = fetchPnpmDeps). local CURRENT - CURRENT=$(awk "/^[[:space:]]*${attr} = fetchPnpmDeps/,/;[[:space:]]*\$/" nix/package.nix \ + CURRENT=$(awk "/^[[:space:]]*${attr} = fetchPnpmDeps/,/^[[:space:]]*};[[:space:]]*\$/" nix/package.nix \ | sed -n 's/^[[:space:]]*hash = "\(sha256-[^"]*\)".*/\1/p' | head -1) if [ -z "$CURRENT" ]; then @@ -59,7 +59,7 @@ jobs: echo "${attr}_current=${CURRENT}" >> "$GITHUB_OUTPUT" # Swap in the fake hash. - sed -i "/^[[:space:]]*${attr} = fetchPnpmDeps/,/;[[:space:]]*\$/{s|hash = \"${CURRENT}\"|hash = \"${FAKE}\"|}" nix/package.nix + sed -i "/^[[:space:]]*${attr} = fetchPnpmDeps/,/^[[:space:]]*};[[:space:]]*\$/{s|hash = \"${CURRENT}\"|hash = \"${FAKE}\"|}" nix/package.nix # Build only this fixed-output derivation. echo "building ${attr} for ${SYSTEM}..." @@ -81,7 +81,7 @@ jobs: echo "${attr}_new=${NEW}" >> "$GITHUB_OUTPUT" # Write the correct hash back. - sed -i "/^[[:space:]]*${attr} = fetchPnpmDeps/,/;[[:space:]]*\$/{s|hash = \"${FAKE}\"|hash = \"${NEW}\"|}" nix/package.nix + sed -i "/^[[:space:]]*${attr} = fetchPnpmDeps/,/^[[:space:]]*};[[:space:]]*\$/{s|hash = \"${FAKE}\"|hash = \"${NEW}\"|}" nix/package.nix # Track whether this hash changed. if [ "$CURRENT" != "$NEW" ]; then diff --git a/new-ui/package.json b/new-ui/package.json index 2a69a841..9f1a1a99 100644 --- a/new-ui/package.json +++ b/new-ui/package.json @@ -36,7 +36,7 @@ "dayjs": "^1.11.21", "motion": "^12.42.0", "p-timeout": "^7.0.1", - "prettier": "^3.9.1", + "prettier": "^3.9.4", "qrcode.react": "^4.2.0", "radashi": "^12.9.1", "react": "^19.2.7", diff --git a/new-ui/pnpm-lock.yaml b/new-ui/pnpm-lock.yaml index cd3043f7..fa50734c 100644 --- a/new-ui/pnpm-lock.yaml +++ b/new-ui/pnpm-lock.yaml @@ -78,8 +78,8 @@ importers: specifier: ^7.0.1 version: 7.0.1 prettier: - specifier: ^3.9.1 - version: 3.9.1 + specifier: ^3.9.4 + version: 3.9.4 qrcode.react: specifier: ^4.2.0 version: 4.2.0(react@19.2.7) @@ -134,7 +134,7 @@ importers: version: 6.0.3(vite@8.1.0(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0)) autoprefixer: specifier: ^10.5.2 - version: 10.5.2(postcss@8.5.15) + version: 10.5.2(postcss@8.5.16) globals: specifier: ^17.7.0 version: 17.7.0 @@ -143,7 +143,7 @@ importers: version: 17.14.0(typescript@6.0.3) stylelint-config-standard-scss: specifier: ^17.0.0 - version: 17.0.0(postcss@8.5.15)(stylelint@17.14.0(typescript@6.0.3)) + version: 17.0.0(postcss@8.5.16)(stylelint@17.14.0(typescript@6.0.3)) stylelint-scss: specifier: ^7.2.0 version: 7.2.0(stylelint@17.14.0(typescript@6.0.3)) @@ -299,8 +299,8 @@ packages: peerDependencies: '@csstools/css-tokenizer': ^4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.5': - resolution: {integrity: sha512-oNjBvzLq2GPZtJphCjLqXow/cHySHSgtxvKZb7OqSZ/xHgw6NWNhfad+6AB9cLeVm6eA9d/qMll3JdEHjy6M+A==} + '@csstools/css-syntax-patches-for-csstree@1.1.6': + resolution: {integrity: sha512-TcJCWFbXLPpJYq6z7bfOyjWYJDiDg2/I4gyUC9pqPNqHFRIey0EB0q0L5cSnQDfWJg8Jd6VadakxdIez/3zkqQ==} peerDependencies: css-tree: ^3.2.1 peerDependenciesMeta: @@ -1133,8 +1133,8 @@ packages: resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==} engines: {node: '>=0.3.1'} - electron-to-chromium@1.5.380: - resolution: {integrity: sha512-W6d5AbuEoRayO447cqrg6lKJIlscgRnnxOZl/08kfV71BQDoEBC7Wwis68z87LjyK6f4kWyTaubuDbhHKrZkbA==} + electron-to-chromium@1.5.381: + resolution: {integrity: sha512-n9Wa6yB+vDsGuA8AKbl/0z7HbvWqt5jxIdvr1IUicd0ryPrk7/xzwqLv8D9AbbvZ6avVNtXYLTfmgFHkwkyelg==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1163,8 +1163,8 @@ packages: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} - fast-uri@3.1.2: - resolution: {integrity: sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==} + fast-uri@3.1.3: + resolution: {integrity: sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg==} fastest-levenshtein@1.0.16: resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} @@ -1279,8 +1279,8 @@ packages: resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} engines: {node: '>= 4'} - immutable@5.1.8: - resolution: {integrity: sha512-TM5YqrGeTsVIPPpILzeqZ8D2Zc2TvNgSDi88zPF2a4cyqQdWV/wVWBDRDbNzzrLeRWScrFcOX9lW2iX6GOtUDw==} + immutable@5.1.9: + resolution: {integrity: sha512-m8nVez3rwrgmWxtLMt1ZYXB2Lv7OKYn/disyxAlSDYAlKSlFoPPfIAmAM/M5xqL4m4C/wAPw7S2/CNaUii1Hxg==} import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} @@ -1676,12 +1676,12 @@ packages: postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - postcss@8.5.15: - resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} + postcss@8.5.16: + resolution: {integrity: sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==} engines: {node: ^10 || ^12 || >=14} - prettier@3.9.1: - resolution: {integrity: sha512-ppiDo2CSwexck1eyZUwJHg/N3nf1+6IRCv7W/VJ5vaLnVCmB7+3CdRfMwoCHBBX6xTrREDTksZ4OZl5SSf4zXA==} + prettier@3.9.4: + resolution: {integrity: sha512-yWG/o/4oJfo036EKAfK6ACAoDOfHeRHx4tuxkfBZiauURiaSmYwlpOr5LQqKtIkRD2z1PLteme2WoxEnj4tHTg==} engines: {node: '>=14'} hasBin: true @@ -1941,8 +1941,8 @@ packages: unist-util-visit@5.1.0: resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} - unplugin@3.2.0: - resolution: {integrity: sha512-6nGlT7EHsS+tTcTdAkYFqXIUwDrMJyJvHFNYGSr4x2/2ySIcV4f5e1RAJUeDyfOJPR8TF0auE8l+82PLhKjqsA==} + unplugin@3.3.0: + resolution: {integrity: sha512-qa66K+crbfyE6JK10GjvbJeRrOsuC/JpbnHctfyp/i4oBTxWOzJfRZyDiOk1PtErMFRu8JhsU/wPvOdBNWe5Rg==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: '@farmfe/core': '*' @@ -2245,7 +2245,7 @@ snapshots: dependencies: '@csstools/css-tokenizer': 4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.5(css-tree@3.2.1)': + '@csstools/css-syntax-patches-for-csstree@1.1.6(css-tree@3.2.1)': optionalDependencies: css-tree: 3.2.1 @@ -2657,7 +2657,7 @@ snapshots: '@tanstack/virtual-file-routes': 1.162.0 jiti: 2.7.0 magic-string: 0.30.21 - prettier: 3.9.1 + prettier: 3.9.4 zod: 4.4.3 transitivePeerDependencies: - supports-color @@ -2671,7 +2671,7 @@ snapshots: '@tanstack/router-generator': 1.167.17 '@tanstack/router-utils': 1.162.2 chokidar: 5.0.0 - unplugin: 3.2.0(rolldown@1.1.3)(vite@8.1.0(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0)) + unplugin: 3.3.0(rolldown@1.1.3)(vite@8.1.0(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0)) zod: 4.4.3 optionalDependencies: '@tanstack/react-router': 1.170.16(react-dom@19.2.7(react@19.2.7))(react@19.2.7) @@ -2793,7 +2793,7 @@ snapshots: ajv@8.20.0: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.1.2 + fast-uri: 3.1.3 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 @@ -2811,13 +2811,13 @@ snapshots: astral-regex@2.0.0: {} - autoprefixer@10.5.2(postcss@8.5.15): + autoprefixer@10.5.2(postcss@8.5.16): dependencies: browserslist: 4.28.4 caniuse-lite: 1.0.30001799 fraction.js: 5.3.4 picocolors: 1.1.1 - postcss: 8.5.15 + postcss: 8.5.16 postcss-value-parser: 4.2.0 babel-dead-code-elimination@1.0.12: @@ -2841,7 +2841,7 @@ snapshots: dependencies: baseline-browser-mapping: 2.10.40 caniuse-lite: 1.0.30001799 - electron-to-chromium: 1.5.380 + electron-to-chromium: 1.5.381 node-releases: 2.0.50 update-browserslist-db: 1.2.3(browserslist@4.28.4) @@ -2935,7 +2935,7 @@ snapshots: diff@8.0.4: {} - electron-to-chromium@1.5.380: {} + electron-to-chromium@1.5.381: {} emoji-regex@8.0.0: {} @@ -2961,7 +2961,7 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.8 - fast-uri@3.1.2: {} + fast-uri@3.1.3: {} fastest-levenshtein@1.0.16: {} @@ -3074,7 +3074,7 @@ snapshots: ignore@7.0.5: {} - immutable@5.1.8: {} + immutable@5.1.9: {} import-fresh@3.3.1: dependencies: @@ -3535,13 +3535,13 @@ snapshots: postcss-resolve-nested-selector@0.1.6: {} - postcss-safe-parser@7.0.1(postcss@8.5.15): + postcss-safe-parser@7.0.1(postcss@8.5.16): dependencies: - postcss: 8.5.15 + postcss: 8.5.16 - postcss-scss@4.0.9(postcss@8.5.15): + postcss-scss@4.0.9(postcss@8.5.16): dependencies: - postcss: 8.5.15 + postcss: 8.5.16 postcss-selector-parser@7.1.4: dependencies: @@ -3550,13 +3550,13 @@ snapshots: postcss-value-parser@4.2.0: {} - postcss@8.5.15: + postcss@8.5.16: dependencies: nanoid: 3.3.15 picocolors: 1.1.1 source-map-js: 1.2.1 - prettier@3.9.1: {} + prettier@3.9.4: {} property-information@7.2.0: {} @@ -3663,7 +3663,7 @@ snapshots: sass@1.101.0: dependencies: chokidar: 5.0.0 - immutable: 5.1.8 + immutable: 5.1.9 source-map-js: 1.2.1 optionalDependencies: '@parcel/watcher': 2.5.6 @@ -3726,26 +3726,26 @@ snapshots: dependencies: inline-style-parser: 0.2.7 - stylelint-config-recommended-scss@17.0.1(postcss@8.5.15)(stylelint@17.14.0(typescript@6.0.3)): + stylelint-config-recommended-scss@17.0.1(postcss@8.5.16)(stylelint@17.14.0(typescript@6.0.3)): dependencies: - postcss-scss: 4.0.9(postcss@8.5.15) + postcss-scss: 4.0.9(postcss@8.5.16) stylelint: 17.14.0(typescript@6.0.3) stylelint-config-recommended: 18.0.0(stylelint@17.14.0(typescript@6.0.3)) stylelint-scss: 7.2.0(stylelint@17.14.0(typescript@6.0.3)) optionalDependencies: - postcss: 8.5.15 + postcss: 8.5.16 stylelint-config-recommended@18.0.0(stylelint@17.14.0(typescript@6.0.3)): dependencies: stylelint: 17.14.0(typescript@6.0.3) - stylelint-config-standard-scss@17.0.0(postcss@8.5.15)(stylelint@17.14.0(typescript@6.0.3)): + stylelint-config-standard-scss@17.0.0(postcss@8.5.16)(stylelint@17.14.0(typescript@6.0.3)): dependencies: stylelint: 17.14.0(typescript@6.0.3) - stylelint-config-recommended-scss: 17.0.1(postcss@8.5.15)(stylelint@17.14.0(typescript@6.0.3)) + stylelint-config-recommended-scss: 17.0.1(postcss@8.5.16)(stylelint@17.14.0(typescript@6.0.3)) stylelint-config-standard: 40.0.0(stylelint@17.14.0(typescript@6.0.3)) optionalDependencies: - postcss: 8.5.15 + postcss: 8.5.16 stylelint-config-standard@40.0.0(stylelint@17.14.0(typescript@6.0.3)): dependencies: @@ -3756,7 +3756,7 @@ snapshots: dependencies: '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) - '@csstools/css-syntax-patches-for-csstree': 1.1.5(css-tree@3.2.1) + '@csstools/css-syntax-patches-for-csstree': 1.1.6(css-tree@3.2.1) '@csstools/css-tokenizer': 4.0.0 css-tree: 3.2.1 is-plain-object: 5.0.0 @@ -3771,7 +3771,7 @@ snapshots: dependencies: '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) - '@csstools/css-syntax-patches-for-csstree': 1.1.5(css-tree@3.2.1) + '@csstools/css-syntax-patches-for-csstree': 1.1.6(css-tree@3.2.1) '@csstools/css-tokenizer': 4.0.0 '@csstools/media-query-list-parser': 5.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/selector-resolve-nested': 4.0.0(postcss-selector-parser@7.1.4) @@ -3795,8 +3795,8 @@ snapshots: micromatch: 4.0.8 normalize-path: 3.0.0 picocolors: 1.1.1 - postcss: 8.5.15 - postcss-safe-parser: 7.0.1(postcss@8.5.15) + postcss: 8.5.16 + postcss-safe-parser: 7.0.1(postcss@8.5.16) postcss-selector-parser: 7.1.4 postcss-value-parser: 4.2.0 string-width: 8.2.1 @@ -3881,7 +3881,7 @@ snapshots: unist-util-is: 6.0.1 unist-util-visit-parents: 6.0.2 - unplugin@3.2.0(rolldown@1.1.3)(vite@8.1.0(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0)): + unplugin@3.3.0(rolldown@1.1.3)(vite@8.1.0(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0)): dependencies: '@jridgewell/remapping': 2.3.5 picomatch: 4.0.4 @@ -3916,7 +3916,7 @@ snapshots: dependencies: lightningcss: 1.32.0 picomatch: 4.0.4 - postcss: 8.5.15 + postcss: 8.5.16 rolldown: 1.1.3 tinyglobby: 0.2.17 optionalDependencies: diff --git a/nix/package.nix b/nix/package.nix index 69b8c437..b7621cb2 100644 --- a/nix/package.nix +++ b/nix/package.nix @@ -90,7 +90,7 @@ inherit pname version pnpm; src = ../.; fetcherVersion = 3; - hash = "sha256-D7yf3x7OAeM3Wdjgo8TxeSCNoLxN3IfgqTzRoBdBwhc="; + hash = "sha256-fGsjHg4FfjlH1yNzdZaXWjn07gV4j/mxv32t45RAyzM="; }; # Prefetch pnpm dependencies for the new UI (separate pnpm project). @@ -99,7 +99,7 @@ inherit version pnpm; src = ../new-ui; fetcherVersion = 3; - hash = "sha256-N6YZ7COM99gtEBDFAKCPKWep52eY6ShxQYeJGDF/H38="; + hash = "sha256-Xi71thwlHXUSQYYIX62hLk3Sw5bEtRE28PJSLQaHJ8g="; }; # Pre-build the new UI frontend so Tauri can serve it as WebviewUrl::App("compact/") and "full/". diff --git a/package.json b/package.json index 4b621c50..d7d5699f 100644 --- a/package.json +++ b/package.json @@ -41,8 +41,8 @@ "@react-hook/resize-observer": "^2.0.2", "@stablelib/base64": "^2.0.1", "@stablelib/x25519": "^2.0.1", - "@tanstack/query-core": "^5.101.1", - "@tanstack/react-virtual": "^3.14.3", + "@tanstack/query-core": "^5.101.2", + "@tanstack/react-virtual": "^3.14.4", "@tauri-apps/api": "^2.11.1", "@tauri-apps/plugin-clipboard-manager": "^2.3.2", "@tauri-apps/plugin-deep-link": "^2.4.9", @@ -69,11 +69,11 @@ "get-text-width": "^1.0.3", "html-react-parser": "^6.1.3", "itertools": "^2.7.1", - "js-base64": "^3.7.8", + "js-base64": "^3.8.0", "lodash-es": "^4.18.1", "merge-refs": "^2.0.0", "millify": "^6.1.0", - "motion": "^12.41.0", + "motion": "^12.42.0", "p-timeout": "^7.0.1", "prop-types": "^15.8.1", "radash": "^12.1.1", @@ -82,7 +82,7 @@ "react-click-away-listener": "^2.4.2", "react-dom": "^19.2.7", "react-hook-form": "^7.80.0", - "react-hotkeys-hook": "^5.3.2", + "react-hotkeys-hook": "^5.3.3", "react-loading-skeleton": "^3.5.0", "react-markdown": "^10.1.0", "react-qr-code": "^2.2.0", @@ -100,9 +100,9 @@ "@biomejs/biome": "2.4.16", "@hookform/devtools": "^4.4.0", "@svgr/cli": "^8.1.0", - "@tanstack/react-query": "^5.101.1", - "@tanstack/react-query-devtools": "^5.101.1", - "@tauri-apps/cli": "^2.11.3", + "@tanstack/react-query": "^5.101.2", + "@tanstack/react-query-devtools": "^5.101.2", + "@tauri-apps/cli": "^2.11.4", "@types/file-saver": "^2.0.7", "@types/lodash-es": "^4.17.12", "@types/node": "^25.9.4", @@ -110,15 +110,15 @@ "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.2.0", "@vitejs/plugin-react-swc": "^4.3.1", - "autoprefixer": "^10.5.1", + "autoprefixer": "^10.5.2", "npm-run-all": "^4.1.5", - "postcss": "^8.5.15", - "prettier": "^3.8.4", + "postcss": "^8.5.16", + "prettier": "^3.9.4", "sass": "~1.92.1", "typedoc": "^0.28.19", "typesafe-i18n": "^5.27.1", "typescript": "^6.0.3", - "vite": "^7.3.5" + "vite": "^7.3.6" }, "volta": { "node": "20.5.1" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 042e995d..6ea97754 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24,11 +24,11 @@ importers: specifier: ^2.0.1 version: 2.0.1 '@tanstack/query-core': - specifier: ^5.101.1 - version: 5.101.1 + specifier: ^5.101.2 + version: 5.101.2 '@tanstack/react-virtual': - specifier: ^3.14.3 - version: 3.14.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + specifier: ^3.14.4 + version: 3.14.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@tauri-apps/api': specifier: ^2.11.1 version: 2.11.1 @@ -108,8 +108,8 @@ importers: specifier: ^2.7.1 version: 2.7.1 js-base64: - specifier: ^3.7.8 - version: 3.7.8 + specifier: ^3.8.0 + version: 3.8.0 lodash-es: specifier: ^4.18.1 version: 4.18.1 @@ -120,8 +120,8 @@ importers: specifier: ^6.1.0 version: 6.1.0 motion: - specifier: ^12.41.0 - version: 12.41.0(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + specifier: ^12.42.0 + version: 12.42.0(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) p-timeout: specifier: ^7.0.1 version: 7.0.1 @@ -147,8 +147,8 @@ importers: specifier: ^7.80.0 version: 7.80.0(react@19.2.7) react-hotkeys-hook: - specifier: ^5.3.2 - version: 5.3.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + specifier: ^5.3.3 + version: 5.3.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7) react-loading-skeleton: specifier: ^3.5.0 version: 3.5.0(react@19.2.7) @@ -196,14 +196,14 @@ importers: specifier: ^8.1.0 version: 8.1.0(typescript@6.0.3) '@tanstack/react-query': - specifier: ^5.101.1 - version: 5.101.1(react@19.2.7) + specifier: ^5.101.2 + version: 5.101.2(react@19.2.7) '@tanstack/react-query-devtools': - specifier: ^5.101.1 - version: 5.101.1(@tanstack/react-query@5.101.1(react@19.2.7))(react@19.2.7) + specifier: ^5.101.2 + version: 5.101.2(@tanstack/react-query@5.101.2(react@19.2.7))(react@19.2.7) '@tauri-apps/cli': - specifier: ^2.11.3 - version: 2.11.3 + specifier: ^2.11.4 + version: 2.11.4 '@types/file-saver': specifier: ^2.0.7 version: 2.0.7 @@ -221,22 +221,22 @@ importers: version: 19.2.3(@types/react@19.2.17) '@vitejs/plugin-react': specifier: ^5.2.0 - version: 5.2.0(vite@7.3.5(@types/node@25.9.4)(sass@1.92.1)(yaml@2.9.0)) + version: 5.2.0(vite@7.3.6(@types/node@25.9.4)(sass@1.92.1)(yaml@2.9.0)) '@vitejs/plugin-react-swc': specifier: ^4.3.1 - version: 4.3.1(vite@7.3.5(@types/node@25.9.4)(sass@1.92.1)(yaml@2.9.0)) + version: 4.3.1(vite@7.3.6(@types/node@25.9.4)(sass@1.92.1)(yaml@2.9.0)) autoprefixer: - specifier: ^10.5.1 - version: 10.5.1(postcss@8.5.15) + specifier: ^10.5.2 + version: 10.5.2(postcss@8.5.16) npm-run-all: specifier: ^4.1.5 version: 4.1.5 postcss: - specifier: ^8.5.15 - version: 8.5.15 + specifier: ^8.5.16 + version: 8.5.16 prettier: - specifier: ^3.8.4 - version: 3.8.4 + specifier: ^3.9.4 + version: 3.9.4 sass: specifier: ~1.92.1 version: 1.92.1 @@ -250,8 +250,8 @@ importers: specifier: ^6.0.3 version: 6.0.3 vite: - specifier: ^7.3.5 - version: 7.3.5(@types/node@25.9.4)(sass@1.92.1)(yaml@2.9.0) + specifier: ^7.3.6 + version: 7.3.6(@types/node@25.9.4)(sass@1.92.1)(yaml@2.9.0) packages: @@ -453,158 +453,158 @@ packages: '@emotion/weak-memoize@0.4.0': resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==} - '@esbuild/aix-ppc64@0.27.7': - resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} + '@esbuild/aix-ppc64@0.28.1': + resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.27.7': - resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} + '@esbuild/android-arm64@0.28.1': + resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.27.7': - resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} + '@esbuild/android-arm@0.28.1': + resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.27.7': - resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} + '@esbuild/android-x64@0.28.1': + resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.27.7': - resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} + '@esbuild/darwin-arm64@0.28.1': + resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.27.7': - resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} + '@esbuild/darwin-x64@0.28.1': + resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.27.7': - resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} + '@esbuild/freebsd-arm64@0.28.1': + resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.27.7': - resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} + '@esbuild/freebsd-x64@0.28.1': + resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.27.7': - resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} + '@esbuild/linux-arm64@0.28.1': + resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.27.7': - resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} + '@esbuild/linux-arm@0.28.1': + resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.27.7': - resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} + '@esbuild/linux-ia32@0.28.1': + resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.27.7': - resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} + '@esbuild/linux-loong64@0.28.1': + resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.27.7': - resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} + '@esbuild/linux-mips64el@0.28.1': + resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.27.7': - resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} + '@esbuild/linux-ppc64@0.28.1': + resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.27.7': - resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} + '@esbuild/linux-riscv64@0.28.1': + resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.27.7': - resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} + '@esbuild/linux-s390x@0.28.1': + resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.27.7': - resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} + '@esbuild/linux-x64@0.28.1': + resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.27.7': - resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} + '@esbuild/netbsd-arm64@0.28.1': + resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.27.7': - resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} + '@esbuild/netbsd-x64@0.28.1': + resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.27.7': - resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} + '@esbuild/openbsd-arm64@0.28.1': + resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.27.7': - resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} + '@esbuild/openbsd-x64@0.28.1': + resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.27.7': - resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} + '@esbuild/openharmony-arm64@0.28.1': + resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] - '@esbuild/sunos-x64@0.27.7': - resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} + '@esbuild/sunos-x64@0.28.1': + resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.27.7': - resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} + '@esbuild/win32-arm64@0.28.1': + resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.27.7': - resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} + '@esbuild/win32-ia32@0.28.1': + resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.27.7': - resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} + '@esbuild/win32-x64@0.28.1': + resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==} engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -1145,108 +1145,108 @@ packages: '@swc/types@0.1.27': resolution: {integrity: sha512-K6h3iUlqeM946U4sXFYeahefR1YBbXJvko+hv8WS8/0BNJ4OHiHRywMnQUJCqkR7Y9+hqQ1TvEpiKqUhz7NEFg==} - '@tanstack/query-core@5.101.1': - resolution: {integrity: sha512-Y6Y92dkXtNqx67m2pMSxUsA3zOCwv862JexZRP8/EPwvKXMPu9m8rv43spiXWzOUIggQ3SQApttALStzhA8B4g==} + '@tanstack/query-core@5.101.2': + resolution: {integrity: sha512-hH5MLoJhF7KaIGd7q3xTXGXvslI+GYlM1Z/35aSHHWaCJWB7XvTSHYuV3eM7tw+aE0mT/xMro4M4Q9rCGHT0lw==} - '@tanstack/query-devtools@5.101.1': - resolution: {integrity: sha512-37RQ9U2PxlXQiv1era2t+uHgVhmiyvxqTMu30+KoVf0rufiucu6rpGRKFJk61Wh5OAZFKqCQd6lxTzFWfLZiuQ==} + '@tanstack/query-devtools@5.101.2': + resolution: {integrity: sha512-o+wHcqgN7Pp0s8v1i0UGq/ZrrEKrxdIiMQmKRdYb2w7NPtylYSJ4+wg/tIn71m9DLstwUwdEGAvROdly6HXP6w==} - '@tanstack/react-query-devtools@5.101.1': - resolution: {integrity: sha512-OXFR9XKdEslraq3cpl3kCUeNvTIq/xGWEZiFZdn2bLB/q4WxSALMEDKYZ5yYjMQytsfnQxwQYqV4qtVEf0nuog==} + '@tanstack/react-query-devtools@5.101.2': + resolution: {integrity: sha512-eU7HctdA9gDjqoERoEdzLbw9DiqnBDfh5+Hu0u26gjqoHJezOpQAuiesDL2VvkU+2cPV76zgv0tMZsOrI4LjnQ==} peerDependencies: - '@tanstack/react-query': ^5.101.1 + '@tanstack/react-query': ^5.101.2 react: ^18 || ^19 - '@tanstack/react-query@5.101.1': - resolution: {integrity: sha512-ZnONUuQKJe1bJMStXUL1s5uKN9FcfC28j5cK+iDZcdSHtUv1wtin1cGc/Oewhf2Oc4eKY7lggtpvT/AbMmhHew==} + '@tanstack/react-query@5.101.2': + resolution: {integrity: sha512-seDkr6kzGzX1okaaTtZPtgA688CDPlXUz1C6xSg0ESqn04Vuc8tlrYms1s3de+znBqhPVxFRfpAfUf+6XvfPWg==} peerDependencies: react: ^18 || ^19 - '@tanstack/react-virtual@3.14.3': - resolution: {integrity: sha512-k/cnHPVaOfn46hSbiY6n4Dzf4QjCGWSF40zR5QIIYUqPAjpA6TN7InfYmcMiDVQGP2iUn9xsRbAl8u1v3UmeVQ==} + '@tanstack/react-virtual@3.14.4': + resolution: {integrity: sha512-dZzAQP2uCDAd+9sAehqmx/DcU+B91Q4Gb0aDSM7t9bJvWDyGF9sapFNW5r1gNLsHs4wTb6ScZENJeYaHxJLiOw==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - '@tanstack/virtual-core@3.17.1': - resolution: {integrity: sha512-VZyW2Uiml5tmBZwPGrSD3Sz73OxzljQMCmzYHsUTPEuTsERf5xwa+uWb01xEzkz3ZSYTjj8NEb/mKHvgKxyZdA==} + '@tanstack/virtual-core@3.17.2': + resolution: {integrity: sha512-w43MvWvmShpb6kIC9MOoLyUkLmRTLPjt61bHWs+X29hACSpX+n8DvgZ3qM7cUfflKlRRcHR9KVJE6TmcqnQvcA==} '@tauri-apps/api@2.11.1': resolution: {integrity: sha512-M2FPuYND2m+wh5hfW9ZpSdxMPdEJovPBWwoHJmwUpysTYNHaOkVFN419m/K0LIgjb/7KU2vBgsUepJWugQCvAA==} - '@tauri-apps/cli-darwin-arm64@2.11.3': - resolution: {integrity: sha512-BxpaM8bsCoXs3wd4WKYhas/G1gs7+r7B+e4WnyRk2GEoVOouJB1hoL6E6YLXZDXbYci6VFdrNnobQwd2uVL4ew==} + '@tauri-apps/cli-darwin-arm64@2.11.4': + resolution: {integrity: sha512-1ryOF3ZhpZ/nemHV5zVwBQBz9jDGKmKPvWPADOhc83ig0P4bMc2iER4NbC6r9sjeIZ6RVQ4g3RZIYvezhcl4TQ==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@tauri-apps/cli-darwin-x64@2.11.3': - resolution: {integrity: sha512-DbZYuPB1ZEzcAHYeyCvo3ltzM27+aXwPloCrtexPnmgPgulYJm3TOq6aC4S+wPhSXteddg8zImtNkvx/gQzmwg==} + '@tauri-apps/cli-darwin-x64@2.11.4': + resolution: {integrity: sha512-uFsGQAAfuyz1k/yGLmkWfkBlgKAqZfxqlHmLWx81QU27RJWfmbNHCIq8T8w1e+VClleIuZUjpHWfoE4E3DLo3A==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@tauri-apps/cli-linux-arm-gnueabihf@2.11.3': - resolution: {integrity: sha512-741NduqBmz1XkdU8yz3OI/kBZtqHbvxo9F9ytIeWYU69/Ba9dcZEbqOU++Dp0G/XU8vAI0TfTywEl+p+BbLvaA==} + '@tauri-apps/cli-linux-arm-gnueabihf@2.11.4': + resolution: {integrity: sha512-IaHZn5CdBL21oUmjiVOS1ctw6Ip1O0pjp70FwOWmYz1myWe0SY96ZIj2FYf7pT0m8bI2h/hrs5ZbEXXh44/MkQ==} engines: {node: '>= 10'} cpu: [arm] os: [linux] - '@tauri-apps/cli-linux-arm64-gnu@2.11.3': - resolution: {integrity: sha512-RWAXT8pTqIczXcoic+LXlo6uEbAXGB0cgh6Pg7Y9xVnEbzryQ1JHtRGj9SxzrKSemBIDBH6Qc24kK2G69i8ofA==} + '@tauri-apps/cli-linux-arm64-gnu@2.11.4': + resolution: {integrity: sha512-N41/ukTRVe6XSuUTESuFdGeOW2i7k62tK+6gHK5Kd5/q5RPvvi19GaWAVPPb9u95HSGmTChSolBfzynUsssFaA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] libc: [glibc] - '@tauri-apps/cli-linux-arm64-musl@2.11.3': - resolution: {integrity: sha512-qomqYS+yAkd0gXMRmhguWXc7RfVN+XKKXaEwbf5QmKURwydLFOTldd6F8/WoZDSsBMrV8dpNxz0YneGLmobiSA==} + '@tauri-apps/cli-linux-arm64-musl@2.11.4': + resolution: {integrity: sha512-v277UnT/fB64xAfSroL5N3Km3tLmvATWqJJw/wRI+g6o+HkeD0slyE7gOhNs1MbjE41R7bQOTxMVoL3aomUJmw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] libc: [musl] - '@tauri-apps/cli-linux-riscv64-gnu@2.11.3': - resolution: {integrity: sha512-jOCXbDqeDj5XcclsOBAaXjtTgwZCVg8zEZ+dbPUCoADOgljFgL0rOkYTc96vUYgOrYEfuHYihWMxIDGaD6GwJw==} + '@tauri-apps/cli-linux-riscv64-gnu@2.11.4': + resolution: {integrity: sha512-qqgNkQ2u1yZHxjhxsZaxUtRDW8dIqIYm33rx/mzwQv0SfY9x1B+iraj8vWeFiXjjSVVhEMepXSOts1TqPzvXNQ==} engines: {node: '>= 10'} cpu: [riscv64] os: [linux] libc: [glibc] - '@tauri-apps/cli-linux-x64-gnu@2.11.3': - resolution: {integrity: sha512-+u3HO/F3gHwL48t9gWN/urqZvpaEJzBFmTaq5eSIhvy8TOvnhb+LgJr3Q3BG+5JxuBrCUjqtOEz6gMttdJFSBA==} + '@tauri-apps/cli-linux-x64-gnu@2.11.4': + resolution: {integrity: sha512-2VRNWl84FOH0m2giiDkO2h0QXlcMJeX+zJDpI5kDIQAx6s+geF3v48F4DXfJez4GS/FdoDGnPnw1C2iYGbQ7bQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] libc: [glibc] - '@tauri-apps/cli-linux-x64-musl@2.11.3': - resolution: {integrity: sha512-spr5Jpr6KF/vehkLwJ0YmdGv8QwpWU+uw7J8bgijO0sox6ZCYsSNMbcsQjTqPi4xl+p0woIYpWXgChgHYpAc8g==} + '@tauri-apps/cli-linux-x64-musl@2.11.4': + resolution: {integrity: sha512-o9GyhYor/nc7xarmwDE3ka2szuW3uuZzXjHWh64Q8YX5AtSgxdQkFWzrY4O8KiGtVNvFBI14H3Q49Qj5TOIP/A==} engines: {node: '>= 10'} cpu: [x64] os: [linux] libc: [musl] - '@tauri-apps/cli-win32-arm64-msvc@2.11.3': - resolution: {integrity: sha512-abkoRQih5xBa3vz2spWaex0kP/MzVzVPQHom2f8jnCq46R/luOD6Uy85EMU9/bfzf6ZzdorWJsgO+OMX90Fx2w==} + '@tauri-apps/cli-win32-arm64-msvc@2.11.4': + resolution: {integrity: sha512-ld5Ehb598m0VkYyylRPNeCFsBe/km0jxis6KgMpl3IGY6I/i1RwQXO05I1AsXUXO2WC6AvB/Lw4qTf/asiuEiQ==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@tauri-apps/cli-win32-ia32-msvc@2.11.3': - resolution: {integrity: sha512-Vy6AvzFm1G40hg3r+OYDB3jkuu7R4wnMzbQBKuun9v6Cgg8IierpLL7toMzrZKs/8NlG8Sg4x1iLFR52oknyHg==} + '@tauri-apps/cli-win32-ia32-msvc@2.11.4': + resolution: {integrity: sha512-12Hxi0XX/H5VFxO/bGgHkFWhml9VMgEOu9CidjeCeTNQ1l6fpUlbiGgSP7CLI3PFtW9/FfbeHieZ+kyWK5H7CA==} engines: {node: '>= 10'} cpu: [ia32] os: [win32] - '@tauri-apps/cli-win32-x64-msvc@2.11.3': - resolution: {integrity: sha512-GlciF75GdbseajOyib2aCHwE3BXIqZ1liGKWLFRvCdN5wm8h8hFssEVKQ/6E+2jsMLg9v7LCTb983YFnn0QSww==} + '@tauri-apps/cli-win32-x64-msvc@2.11.4': + resolution: {integrity: sha512-+vDiqBIU5dMISg/wNvX3sF+ZHfgJGJ5T0AcO+EHNXV9GGAG+P5fzodlDXD3QdKCRgZxMoCm5PPvj3BqLNjBthw==} engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@tauri-apps/cli@2.11.3': - resolution: {integrity: sha512-EElQe8z8uD7Pi5++tJ/UfEwWuK08rd3oCDYdeIbJAb6pZRrxlqmoF5gh5H5YvzmUPhS4IRCaLSsQhvWkrfK+GQ==} + '@tauri-apps/cli@2.11.4': + resolution: {integrity: sha512-R8xGtMpwyetawSqm9kYOuMmEqkhUbvcUy8n0aNXIxollKBLESUu5f4Fx+64hgASYm1H+jSWq6jCW6zqTnH6hqQ==} engines: {node: '>= 10'} hasBin: true @@ -1425,8 +1425,8 @@ packages: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} engines: {node: '>= 0.4'} - autoprefixer@10.5.1: - resolution: {integrity: sha512-jwM2pcTuCWUoN70FEvf5XrXyDbUgRURK4FnU8v0jWZZYU/KkVvN9T33mu1sVLFY9JW3kTWzKheEpn6xYLRc/VA==} + autoprefixer@10.5.2: + resolution: {integrity: sha512-rD5t5DwOjJdmSORcTq64j8MawTC+tbQ+HHqjR4NDumamy/ambn1UJrlKL+KdwujWxMkFjPM3pPHOEA9tl4767Q==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: @@ -1450,8 +1450,8 @@ packages: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} - baseline-browser-mapping@2.10.38: - resolution: {integrity: sha512-31/02mVB4yuQU6adKk5SlY6m+mxDwUq5KZkyYgnLrrKl7TEm1+3PyDtDBz2kOv/wxZz41GHsvV1A/u6RmiyBvw==} + baseline-browser-mapping@2.10.40: + resolution: {integrity: sha512-BSSLZ9/Cjjv7Gtj5B68ZzXcXUg8iOf3fme+FCuh8rC/Go+Kmh8cox7M3A8dolou16s64QjLPOSdngh7GxXvkSw==} engines: {node: '>=6.0.0'} hasBin: true @@ -1464,8 +1464,8 @@ packages: brace-expansion@2.1.1: resolution: {integrity: sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==} - brace-expansion@5.0.6: - resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} + brace-expansion@5.0.7: + resolution: {integrity: sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==} engines: {node: 18 || 20 || >=22} browserslist@4.28.4: @@ -1762,8 +1762,8 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} - electron-to-chromium@1.5.378: - resolution: {integrity: sha512-VinvOAuuPmdD1guEgGv5f2Qp7/vlfqOrUOMYNnOD4wj3pit8kRsQHzfIf6teyUGWo15Tg5+bOJaRunvyltpVWQ==} + electron-to-chromium@1.5.381: + resolution: {integrity: sha512-n9Wa6yB+vDsGuA8AKbl/0z7HbvWqt5jxIdvr1IUicd0ryPrk7/xzwqLv8D9AbbvZ6avVNtXYLTfmgFHkwkyelg==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1803,15 +1803,15 @@ packages: resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} engines: {node: '>= 0.4'} - es-to-primitive@1.3.1: - resolution: {integrity: sha512-CxN9N56HYfd2m/acc/NOFrZQsN9kU4eh+2kk6A707Kz1krH8tKmfrs5RnftB8WNX80T0NS7vSQsDOlg23diR2g==} + es-to-primitive@1.3.4: + resolution: {integrity: sha512-yPDz7wqpg1/mmHLmS3tcfTfbw5f1eryXvyghYBffGdERwe+mV7ZcWzTR8LR17Kvqt3qfPurjlonmnq3MKXIOXw==} engines: {node: '>= 0.4'} - es-toolkit@1.48.1: - resolution: {integrity: sha512-wfnXlwd5I75eXRtdD2vuEs50xHHESECDsGD7yiQnfFVNoa5522NwXEbmgo98LfiukSQHs+mBM7/YG3qKJB9/mQ==} + es-toolkit@1.49.0: + resolution: {integrity: sha512-G5iZ6Pc/FNRY/soKZHC+TxGDD83rHUDXxzaWhGCX44vAv/tMs56WMusnm/KMNK+luUPsgA9U28cGr4RDlSzL2g==} - esbuild@0.27.7: - resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} + esbuild@0.28.1: + resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} engines: {node: '>=18'} hasBin: true @@ -1861,8 +1861,8 @@ packages: fraction.js@5.3.4: resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} - framer-motion@12.41.0: - resolution: {integrity: sha512-OHAMNiCEON1RDBlRGuulsN5AD8ptMjvk5QWfFmYmBLPZ3zFGIJe60kQucQQf4cez1OzQmjYBWDY+dYfISkUdqg==} + framer-motion@12.42.0: + resolution: {integrity: sha512-wp7EJnfWaaEScVygKv3e20udoRz+LbtxScsuTkakAxfXmt+ReC6WyPW2nINRAGvd+hG9odwcjBLyOTPjH5pBRA==} peerDependencies: '@emotion/is-prop-valid': '*' react: ^18.0.0 || ^19.0.0 @@ -2007,8 +2007,8 @@ packages: immer@11.1.8: resolution: {integrity: sha512-/tbkHMW7y10Lx6i1crLjD4/OhNkRG+Fo7byZHtah0547nIeXYcpIXaUh0IAQY6gO5459qpGGYapcEOHtFXkIuA==} - immutable@5.1.7: - resolution: {integrity: sha512-47Xb+LFbZ/ZIjQMj6Q5J3IfK7PJFuqRdFOC9FpGgRTK6U2dAEVmkR9hp58qU4FpYux5YXpneDwkj2EP6lppzFA==} + immutable@5.1.9: + resolution: {integrity: sha512-m8nVez3rwrgmWxtLMt1ZYXB2Lv7OKYn/disyxAlSDYAlKSlFoPPfIAmAM/M5xqL4m4C/wAPw7S2/CNaUii1Hxg==} import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} @@ -2165,14 +2165,14 @@ packages: resolution: {integrity: sha512-xrbTDDdUfkJhM4EzYOwwzEf2ksPT5WLgQ5i2X9X5yUpcmXJPEjeAnpMl1tIrYDzuCD19/AEH+cbLunQHGn8v7w==} engines: {node: '>=22'} - js-base64@3.7.8: - resolution: {integrity: sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==} + js-base64@3.8.0: + resolution: {integrity: sha512-65kvbemyZhj+ExQt1PEFyBEjL5vAHysu1lJdW1AwhhChkO8ZBPizYk/m9GVrpbS2Je1hF+UYZ+6KywqtZV8mHw==} js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-yaml@4.2.0: - resolution: {integrity: sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==} + js-yaml@4.3.0: + resolution: {integrity: sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==} hasBin: true jsesc@3.1.0: @@ -2359,14 +2359,14 @@ packages: resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} engines: {node: '>=10'} - motion-dom@12.41.0: - resolution: {integrity: sha512-Lk3J39fOGg6xNr1KRZsN6usDyBf8aP7MEbUPez1VCughHt79OrP7VGqNrPyFL0riaT7WS8t9DRw1M3BHtM/xKw==} + motion-dom@12.42.0: + resolution: {integrity: sha512-M63h4n8R+quJdNhBwuLlgxM+OLYa9+I/T2pzDRboB9fLXRdbou+Gw7Zury+SkpaCyACP1JHSjHgZ1EgTkBr30w==} motion-utils@12.39.0: resolution: {integrity: sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ==} - motion@12.41.0: - resolution: {integrity: sha512-avEDKE22rFPJqDr3Ttk7gMQpeaOmNik60NoJ5T0tj+RBCNvz21D3ArY3l4uitoeQ7eIpDqueWaO3pPYFv8JOVA==} + motion@12.42.0: + resolution: {integrity: sha512-Qhwvu9sVl5/URSq5CNzwMCpSKK8Uhnrwb6VO977kZyj/wOCS7mWebJUnBoHx5cZU1Zv8a9BD5CSICWKAlrLJgA==} peerDependencies: '@emotion/is-prop-valid': '*' react: ^18.0.0 || ^19.0.0 @@ -2396,8 +2396,8 @@ packages: node-addon-api@7.1.1: resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} - node-releases@2.0.49: - resolution: {integrity: sha512-f06bl1D+8ZDkn2oOQQKAh5/otFWqVnM1Q5oerA8Pex7UfT66Tx4IPHIqVVFKqFT3FUtaDstdgkM7yT7JWhqxfw==} + node-releases@2.0.50: + resolution: {integrity: sha512-J6l92tKHX6w8Jy5nO1Vuc01NoIiRGi/d6qBKVxh+IQ8Cr3b6HbVNfKiF8ZpFKufTwpwxMmce2W3iQZ861ZRyTg==} engines: {node: '>=18'} normalize-package-data@2.5.0: @@ -2491,8 +2491,8 @@ packages: postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - postcss@8.5.15: - resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} + postcss@8.5.16: + resolution: {integrity: sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==} engines: {node: ^10 || ^12 || >=14} prettier@2.8.8: @@ -2500,8 +2500,8 @@ packages: engines: {node: '>=10.13.0'} hasBin: true - prettier@3.8.4: - resolution: {integrity: sha512-N2MylSdi48+5N/6S5j+maeHbUSIzzZ5uOcX5Hm4QpV8Dkb1HFjfAKTKX6yNPJQD9AhcT3ifHNB66tWTTJDi11Q==} + prettier@3.9.4: + resolution: {integrity: sha512-yWG/o/4oJfo036EKAfK6ACAoDOfHeRHx4tuxkfBZiauURiaSmYwlpOr5LQqKtIkRD2z1PLteme2WoxEnj4tHTg==} engines: {node: '>=14'} hasBin: true @@ -2546,8 +2546,8 @@ packages: peerDependencies: react: ^16.8.0 || ^17 || ^18 || ^19 - react-hotkeys-hook@5.3.2: - resolution: {integrity: sha512-DDDy9xK6mbTQ6aPlQvIl0dA/a90T/AWml4Rm21JXFDLlRHalIg4/Rv3equUQYs5xPTWq+oEl6RD7mi/nBpU3Uw==} + react-hotkeys-hook@5.3.3: + resolution: {integrity: sha512-aswgyWUnE25hmhzHTfKDmKzsaSE5DJ4LKaU/o6rQSXkDd/1Bh9TfAFQbHkf6fLy11HvlYkp+cDDarGdhmCDhoQ==} peerDependencies: react: '>=16.8.0' react-dom: '>=16.8.0' @@ -2738,8 +2738,8 @@ packages: resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} engines: {node: '>=0.10.0'} - shell-quote@1.8.4: - resolution: {integrity: sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ==} + shell-quote@1.9.0: + resolution: {integrity: sha512-Iov+JwFv/2HcTpcwNMKd8+IWNb8tboQJNQTkAY/LLVK7gGH9jy+LGkVqPxfekHl+yMmiqXszdGWXgkfml7hjqA==} engines: {node: '>= 0.4'} side-channel-list@1.0.1: @@ -2973,8 +2973,8 @@ packages: victory-vendor@37.3.6: resolution: {integrity: sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==} - vite@7.3.5: - resolution: {integrity: sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww==} + vite@7.3.6: + resolution: {integrity: sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -3322,82 +3322,82 @@ snapshots: '@emotion/weak-memoize@0.4.0': {} - '@esbuild/aix-ppc64@0.27.7': + '@esbuild/aix-ppc64@0.28.1': optional: true - '@esbuild/android-arm64@0.27.7': + '@esbuild/android-arm64@0.28.1': optional: true - '@esbuild/android-arm@0.27.7': + '@esbuild/android-arm@0.28.1': optional: true - '@esbuild/android-x64@0.27.7': + '@esbuild/android-x64@0.28.1': optional: true - '@esbuild/darwin-arm64@0.27.7': + '@esbuild/darwin-arm64@0.28.1': optional: true - '@esbuild/darwin-x64@0.27.7': + '@esbuild/darwin-x64@0.28.1': optional: true - '@esbuild/freebsd-arm64@0.27.7': + '@esbuild/freebsd-arm64@0.28.1': optional: true - '@esbuild/freebsd-x64@0.27.7': + '@esbuild/freebsd-x64@0.28.1': optional: true - '@esbuild/linux-arm64@0.27.7': + '@esbuild/linux-arm64@0.28.1': optional: true - '@esbuild/linux-arm@0.27.7': + '@esbuild/linux-arm@0.28.1': optional: true - '@esbuild/linux-ia32@0.27.7': + '@esbuild/linux-ia32@0.28.1': optional: true - '@esbuild/linux-loong64@0.27.7': + '@esbuild/linux-loong64@0.28.1': optional: true - '@esbuild/linux-mips64el@0.27.7': + '@esbuild/linux-mips64el@0.28.1': optional: true - '@esbuild/linux-ppc64@0.27.7': + '@esbuild/linux-ppc64@0.28.1': optional: true - '@esbuild/linux-riscv64@0.27.7': + '@esbuild/linux-riscv64@0.28.1': optional: true - '@esbuild/linux-s390x@0.27.7': + '@esbuild/linux-s390x@0.28.1': optional: true - '@esbuild/linux-x64@0.27.7': + '@esbuild/linux-x64@0.28.1': optional: true - '@esbuild/netbsd-arm64@0.27.7': + '@esbuild/netbsd-arm64@0.28.1': optional: true - '@esbuild/netbsd-x64@0.27.7': + '@esbuild/netbsd-x64@0.28.1': optional: true - '@esbuild/openbsd-arm64@0.27.7': + '@esbuild/openbsd-arm64@0.28.1': optional: true - '@esbuild/openbsd-x64@0.27.7': + '@esbuild/openbsd-x64@0.28.1': optional: true - '@esbuild/openharmony-arm64@0.27.7': + '@esbuild/openharmony-arm64@0.28.1': optional: true - '@esbuild/sunos-x64@0.27.7': + '@esbuild/sunos-x64@0.28.1': optional: true - '@esbuild/win32-arm64@0.27.7': + '@esbuild/win32-arm64@0.28.1': optional: true - '@esbuild/win32-ia32@0.27.7': + '@esbuild/win32-ia32@0.28.1': optional: true - '@esbuild/win32-x64@0.27.7': + '@esbuild/win32-x64@0.28.1': optional: true '@floating-ui/core@1.7.5': @@ -3852,77 +3852,77 @@ snapshots: dependencies: '@swc/counter': 0.1.3 - '@tanstack/query-core@5.101.1': {} + '@tanstack/query-core@5.101.2': {} - '@tanstack/query-devtools@5.101.1': {} + '@tanstack/query-devtools@5.101.2': {} - '@tanstack/react-query-devtools@5.101.1(@tanstack/react-query@5.101.1(react@19.2.7))(react@19.2.7)': + '@tanstack/react-query-devtools@5.101.2(@tanstack/react-query@5.101.2(react@19.2.7))(react@19.2.7)': dependencies: - '@tanstack/query-devtools': 5.101.1 - '@tanstack/react-query': 5.101.1(react@19.2.7) + '@tanstack/query-devtools': 5.101.2 + '@tanstack/react-query': 5.101.2(react@19.2.7) react: 19.2.7 - '@tanstack/react-query@5.101.1(react@19.2.7)': + '@tanstack/react-query@5.101.2(react@19.2.7)': dependencies: - '@tanstack/query-core': 5.101.1 + '@tanstack/query-core': 5.101.2 react: 19.2.7 - '@tanstack/react-virtual@3.14.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + '@tanstack/react-virtual@3.14.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@tanstack/virtual-core': 3.17.1 + '@tanstack/virtual-core': 3.17.2 react: 19.2.7 react-dom: 19.2.7(react@19.2.7) - '@tanstack/virtual-core@3.17.1': {} + '@tanstack/virtual-core@3.17.2': {} '@tauri-apps/api@2.11.1': {} - '@tauri-apps/cli-darwin-arm64@2.11.3': + '@tauri-apps/cli-darwin-arm64@2.11.4': optional: true - '@tauri-apps/cli-darwin-x64@2.11.3': + '@tauri-apps/cli-darwin-x64@2.11.4': optional: true - '@tauri-apps/cli-linux-arm-gnueabihf@2.11.3': + '@tauri-apps/cli-linux-arm-gnueabihf@2.11.4': optional: true - '@tauri-apps/cli-linux-arm64-gnu@2.11.3': + '@tauri-apps/cli-linux-arm64-gnu@2.11.4': optional: true - '@tauri-apps/cli-linux-arm64-musl@2.11.3': + '@tauri-apps/cli-linux-arm64-musl@2.11.4': optional: true - '@tauri-apps/cli-linux-riscv64-gnu@2.11.3': + '@tauri-apps/cli-linux-riscv64-gnu@2.11.4': optional: true - '@tauri-apps/cli-linux-x64-gnu@2.11.3': + '@tauri-apps/cli-linux-x64-gnu@2.11.4': optional: true - '@tauri-apps/cli-linux-x64-musl@2.11.3': + '@tauri-apps/cli-linux-x64-musl@2.11.4': optional: true - '@tauri-apps/cli-win32-arm64-msvc@2.11.3': + '@tauri-apps/cli-win32-arm64-msvc@2.11.4': optional: true - '@tauri-apps/cli-win32-ia32-msvc@2.11.3': + '@tauri-apps/cli-win32-ia32-msvc@2.11.4': optional: true - '@tauri-apps/cli-win32-x64-msvc@2.11.3': + '@tauri-apps/cli-win32-x64-msvc@2.11.4': optional: true - '@tauri-apps/cli@2.11.3': + '@tauri-apps/cli@2.11.4': optionalDependencies: - '@tauri-apps/cli-darwin-arm64': 2.11.3 - '@tauri-apps/cli-darwin-x64': 2.11.3 - '@tauri-apps/cli-linux-arm-gnueabihf': 2.11.3 - '@tauri-apps/cli-linux-arm64-gnu': 2.11.3 - '@tauri-apps/cli-linux-arm64-musl': 2.11.3 - '@tauri-apps/cli-linux-riscv64-gnu': 2.11.3 - '@tauri-apps/cli-linux-x64-gnu': 2.11.3 - '@tauri-apps/cli-linux-x64-musl': 2.11.3 - '@tauri-apps/cli-win32-arm64-msvc': 2.11.3 - '@tauri-apps/cli-win32-ia32-msvc': 2.11.3 - '@tauri-apps/cli-win32-x64-msvc': 2.11.3 + '@tauri-apps/cli-darwin-arm64': 2.11.4 + '@tauri-apps/cli-darwin-x64': 2.11.4 + '@tauri-apps/cli-linux-arm-gnueabihf': 2.11.4 + '@tauri-apps/cli-linux-arm64-gnu': 2.11.4 + '@tauri-apps/cli-linux-arm64-musl': 2.11.4 + '@tauri-apps/cli-linux-riscv64-gnu': 2.11.4 + '@tauri-apps/cli-linux-x64-gnu': 2.11.4 + '@tauri-apps/cli-linux-x64-musl': 2.11.4 + '@tauri-apps/cli-win32-arm64-msvc': 2.11.4 + '@tauri-apps/cli-win32-ia32-msvc': 2.11.4 + '@tauri-apps/cli-win32-x64-msvc': 2.11.4 '@tauri-apps/plugin-clipboard-manager@2.3.2': dependencies: @@ -4072,15 +4072,15 @@ snapshots: '@use-gesture/core': 10.3.1 react: 19.2.7 - '@vitejs/plugin-react-swc@4.3.1(vite@7.3.5(@types/node@25.9.4)(sass@1.92.1)(yaml@2.9.0))': + '@vitejs/plugin-react-swc@4.3.1(vite@7.3.6(@types/node@25.9.4)(sass@1.92.1)(yaml@2.9.0))': dependencies: '@rolldown/pluginutils': 1.0.1 '@swc/core': 1.15.43 - vite: 7.3.5(@types/node@25.9.4)(sass@1.92.1)(yaml@2.9.0) + vite: 7.3.6(@types/node@25.9.4)(sass@1.92.1)(yaml@2.9.0) transitivePeerDependencies: - '@swc/helpers' - '@vitejs/plugin-react@5.2.0(vite@7.3.5(@types/node@25.9.4)(sass@1.92.1)(yaml@2.9.0))': + '@vitejs/plugin-react@5.2.0(vite@7.3.6(@types/node@25.9.4)(sass@1.92.1)(yaml@2.9.0))': dependencies: '@babel/core': 7.29.7 '@babel/plugin-transform-react-jsx-self': 7.29.7(@babel/core@7.29.7) @@ -4088,7 +4088,7 @@ snapshots: '@rolldown/pluginutils': 1.0.0-rc.3 '@types/babel__core': 7.20.5 react-refresh: 0.18.0 - vite: 7.3.5(@types/node@25.9.4)(sass@1.92.1)(yaml@2.9.0) + vite: 7.3.6(@types/node@25.9.4)(sass@1.92.1)(yaml@2.9.0) transitivePeerDependencies: - supports-color @@ -4121,13 +4121,13 @@ snapshots: async-function@1.0.0: {} - autoprefixer@10.5.1(postcss@8.5.15): + autoprefixer@10.5.2(postcss@8.5.16): dependencies: browserslist: 4.28.4 caniuse-lite: 1.0.30001799 fraction.js: 5.3.4 picocolors: 1.1.1 - postcss: 8.5.15 + postcss: 8.5.16 postcss-value-parser: 4.2.0 available-typed-arrays@1.0.7: @@ -4146,7 +4146,7 @@ snapshots: balanced-match@4.0.4: {} - baseline-browser-mapping@2.10.38: {} + baseline-browser-mapping@2.10.40: {} boolbase@1.0.0: {} @@ -4159,16 +4159,16 @@ snapshots: dependencies: balanced-match: 1.0.2 - brace-expansion@5.0.6: + brace-expansion@5.0.7: dependencies: balanced-match: 4.0.4 browserslist@4.28.4: dependencies: - baseline-browser-mapping: 2.10.38 + baseline-browser-mapping: 2.10.40 caniuse-lite: 1.0.30001799 - electron-to-chromium: 1.5.378 - node-releases: 2.0.49 + electron-to-chromium: 1.5.381 + node-releases: 2.0.50 update-browserslist-db: 1.2.3(browserslist@4.28.4) byte-size@9.0.1: {} @@ -4268,7 +4268,7 @@ snapshots: cosmiconfig@8.3.6(typescript@6.0.3): dependencies: import-fresh: 3.3.1 - js-yaml: 4.2.0 + js-yaml: 4.3.0 parse-json: 5.2.0 path-type: 4.0.0 optionalDependencies: @@ -4452,7 +4452,7 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 - electron-to-chromium@1.5.378: {} + electron-to-chromium@1.5.381: {} emoji-regex@8.0.0: {} @@ -4485,7 +4485,7 @@ snapshots: es-errors: 1.3.0 es-object-atoms: 1.1.2 es-set-tostringtag: 2.1.0 - es-to-primitive: 1.3.1 + es-to-primitive: 1.3.4 function.prototype.name: 1.2.0 get-intrinsic: 1.3.0 get-proto: 1.0.1 @@ -4543,44 +4543,45 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.4 - es-to-primitive@1.3.1: + es-to-primitive@1.3.4: dependencies: es-abstract-get: 1.0.0 + es-define-property: 1.0.1 es-errors: 1.3.0 is-callable: 1.2.7 is-date-object: 1.1.0 is-symbol: 1.1.1 - es-toolkit@1.48.1: {} + es-toolkit@1.49.0: {} - esbuild@0.27.7: + esbuild@0.28.1: optionalDependencies: - '@esbuild/aix-ppc64': 0.27.7 - '@esbuild/android-arm': 0.27.7 - '@esbuild/android-arm64': 0.27.7 - '@esbuild/android-x64': 0.27.7 - '@esbuild/darwin-arm64': 0.27.7 - '@esbuild/darwin-x64': 0.27.7 - '@esbuild/freebsd-arm64': 0.27.7 - '@esbuild/freebsd-x64': 0.27.7 - '@esbuild/linux-arm': 0.27.7 - '@esbuild/linux-arm64': 0.27.7 - '@esbuild/linux-ia32': 0.27.7 - '@esbuild/linux-loong64': 0.27.7 - '@esbuild/linux-mips64el': 0.27.7 - '@esbuild/linux-ppc64': 0.27.7 - '@esbuild/linux-riscv64': 0.27.7 - '@esbuild/linux-s390x': 0.27.7 - '@esbuild/linux-x64': 0.27.7 - '@esbuild/netbsd-arm64': 0.27.7 - '@esbuild/netbsd-x64': 0.27.7 - '@esbuild/openbsd-arm64': 0.27.7 - '@esbuild/openbsd-x64': 0.27.7 - '@esbuild/openharmony-arm64': 0.27.7 - '@esbuild/sunos-x64': 0.27.7 - '@esbuild/win32-arm64': 0.27.7 - '@esbuild/win32-ia32': 0.27.7 - '@esbuild/win32-x64': 0.27.7 + '@esbuild/aix-ppc64': 0.28.1 + '@esbuild/android-arm': 0.28.1 + '@esbuild/android-arm64': 0.28.1 + '@esbuild/android-x64': 0.28.1 + '@esbuild/darwin-arm64': 0.28.1 + '@esbuild/darwin-x64': 0.28.1 + '@esbuild/freebsd-arm64': 0.28.1 + '@esbuild/freebsd-x64': 0.28.1 + '@esbuild/linux-arm': 0.28.1 + '@esbuild/linux-arm64': 0.28.1 + '@esbuild/linux-ia32': 0.28.1 + '@esbuild/linux-loong64': 0.28.1 + '@esbuild/linux-mips64el': 0.28.1 + '@esbuild/linux-ppc64': 0.28.1 + '@esbuild/linux-riscv64': 0.28.1 + '@esbuild/linux-s390x': 0.28.1 + '@esbuild/linux-x64': 0.28.1 + '@esbuild/netbsd-arm64': 0.28.1 + '@esbuild/netbsd-x64': 0.28.1 + '@esbuild/openbsd-arm64': 0.28.1 + '@esbuild/openbsd-x64': 0.28.1 + '@esbuild/openharmony-arm64': 0.28.1 + '@esbuild/sunos-x64': 0.28.1 + '@esbuild/win32-arm64': 0.28.1 + '@esbuild/win32-ia32': 0.28.1 + '@esbuild/win32-x64': 0.28.1 escalade@3.2.0: {} @@ -4610,9 +4611,9 @@ snapshots: fraction.js@5.3.4: {} - framer-motion@12.41.0(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + framer-motion@12.42.0(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: - motion-dom: 12.41.0 + motion-dom: 12.42.0 motion-utils: 12.39.0 tslib: 2.8.1 optionalDependencies: @@ -4778,7 +4779,7 @@ snapshots: immer@11.1.8: {} - immutable@5.1.7: {} + immutable@5.1.9: {} import-fresh@3.3.1: dependencies: @@ -4937,11 +4938,11 @@ snapshots: itertools@2.7.1: {} - js-base64@3.7.8: {} + js-base64@3.8.0: {} js-tokens@4.0.0: {} - js-yaml@4.2.0: + js-yaml@4.3.0: dependencies: argparse: 2.0.1 @@ -5241,7 +5242,7 @@ snapshots: minimatch@10.2.5: dependencies: - brace-expansion: 5.0.6 + brace-expansion: 5.0.7 minimatch@3.1.5: dependencies: @@ -5251,15 +5252,15 @@ snapshots: dependencies: brace-expansion: 2.1.1 - motion-dom@12.41.0: + motion-dom@12.42.0: dependencies: motion-utils: 12.39.0 motion-utils@12.39.0: {} - motion@12.41.0(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + motion@12.42.0(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: - framer-motion: 12.41.0(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + framer-motion: 12.42.0(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) tslib: 2.8.1 optionalDependencies: '@emotion/is-prop-valid': 1.4.0 @@ -5280,7 +5281,7 @@ snapshots: node-addon-api@7.1.1: optional: true - node-releases@2.0.49: {} + node-releases@2.0.50: {} normalize-package-data@2.5.0: dependencies: @@ -5298,7 +5299,7 @@ snapshots: minimatch: 3.1.5 pidtree: 0.3.1 read-pkg: 3.0.0 - shell-quote: 1.8.4 + shell-quote: 1.9.0 string.prototype.padend: 3.1.6 nth-check@2.1.1: @@ -5380,7 +5381,7 @@ snapshots: postcss-value-parser@4.2.0: {} - postcss@8.5.15: + postcss@8.5.16: dependencies: nanoid: 3.3.15 picocolors: 1.1.1 @@ -5388,7 +5389,7 @@ snapshots: prettier@2.8.8: {} - prettier@3.8.4: {} + prettier@3.9.4: {} prop-types@15.8.1: dependencies: @@ -5422,7 +5423,7 @@ snapshots: dependencies: react: 19.2.7 - react-hotkeys-hook@5.3.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + react-hotkeys-hook@5.3.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: react: 19.2.7 react-dom: 19.2.7(react@19.2.7) @@ -5508,7 +5509,7 @@ snapshots: '@reduxjs/toolkit': 2.12.0(react-redux@9.3.0(@types/react@19.2.17)(react@19.2.7)(redux@5.0.1))(react@19.2.7) clsx: 2.1.1 decimal.js-light: 2.5.1 - es-toolkit: 1.48.1 + es-toolkit: 1.49.0 eventemitter3: 5.0.4 immer: 10.2.0 react: 19.2.7 @@ -5641,7 +5642,7 @@ snapshots: sass@1.92.1: dependencies: chokidar: 4.0.3 - immutable: 5.1.7 + immutable: 5.1.9 source-map-js: 1.2.1 optionalDependencies: '@parcel/watcher': 2.5.6 @@ -5682,7 +5683,7 @@ snapshots: shebang-regex@1.0.0: {} - shell-quote@1.8.4: {} + shell-quote@1.9.0: {} side-channel-list@1.0.1: dependencies: @@ -5988,12 +5989,12 @@ snapshots: d3-time: 3.1.0 d3-timer: 3.0.1 - vite@7.3.5(@types/node@25.9.4)(sass@1.92.1)(yaml@2.9.0): + vite@7.3.6(@types/node@25.9.4)(sass@1.92.1)(yaml@2.9.0): dependencies: - esbuild: 0.27.7 + esbuild: 0.28.1 fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 - postcss: 8.5.15 + postcss: 8.5.16 rollup: 4.62.2 tinyglobby: 0.2.17 optionalDependencies: diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 6126e667..e4c29f4d 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -155,9 +155,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" [[package]] name = "arbitrary" @@ -588,9 +588,9 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.17.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ec2f1fc3ec205783a5da9a7e6c1509cc69dedf09a1949e412c1e18469326d00" +checksum = "4342d8937fc7e5dd9b1c60292261c0670c882a2cd1719cfc11b1af41731e32ad" dependencies = [ "aws-lc-sys", "zeroize", @@ -598,14 +598,15 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.41.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a2f9779ce85b93ab6170dd940ad0169b5766ff848247aff13bb788b832fe3f4" +checksum = "6d9ceb1da931507a12f4fccea479dccd00da1943e1b4ae72d8e502d707361444" dependencies = [ "cc", "cmake", "dunce", "fs_extra", + "pkg-config", ] [[package]] @@ -861,9 +862,9 @@ checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "byte-unit" -version = "5.2.3" +version = "5.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37bcaa4a0975bed4a760af3efe4368825098ce5f9d37a30c5a021d635dc63d8f" +checksum = "4a813de7f2bbedb7dce265b64f1cf5908ebe4d56281ece8d847e98113788b9b0" dependencies = [ "rust_decimal", "schemars 1.2.1", @@ -947,9 +948,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.2.3" +version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ce8d3bd5823c7504d3f579f13e7b2f3da252fcb938c594d5680ee508bf846f" +checksum = "5f2d30e4173c4026932d51d31d6b0613b1fd3014bf3f9f8943d4ba139c437ba0" dependencies = [ "serde_core", ] @@ -1575,6 +1576,7 @@ name = "defguard-cli" version = "2.1.0" dependencies = [ "base64 0.22.1", + "chrono", "clap", "defguard-client-common", "defguard-client-config-sync", @@ -3180,9 +3182,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hybrid-array" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" +checksum = "818356c5132c1fede50f837ca96afbe78ff42413047f4abb886217845e1b6c8c" dependencies = [ "typenum", ] @@ -4715,14 +4717,13 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "open" -version = "5.3.5" +version = "5.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fbaa89d2ddc8473c78a3adf69eea8cffa28c483b8e02a971ef31527cd0fc92c" +checksum = "cd8d3b65c44123a56e0133d2cd06ce4361bd3ca99d41198b2f25e3c3db9b8b4a" dependencies = [ "dunce", "is-wsl", "libc", - "pathdiff", ] [[package]] @@ -4906,12 +4907,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec" -[[package]] -name = "pathdiff" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" - [[package]] name = "pem-rfc7468" version = "0.7.0" @@ -5997,9 +5992,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" +checksum = "764899a24af3980067ee14bc143654f297b22eaebfe3c7b6b211920a5a59b046" dependencies = [ "web-time", "zeroize", @@ -7466,9 +7461,9 @@ dependencies = [ [[package]] name = "tauri-runtime-wry" -version = "2.11.3" +version = "2.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe41e015bf8fc4d6477ff4926a0ef769dc64ff34c7b0038b6f7cacae892acb5c" +checksum = "4e6fac707727b7a2f48e4ded90976324267371073edbb415ffb73bb0458d203f" dependencies = [ "gtk", "http", @@ -7648,9 +7643,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.51" +version = "0.3.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c17d80feb7334b40c484e45ed1a5273dfd8bfda537c3be2e74a06a6686f327" +checksum = "18dfaaeddcb932337b5e7866ee7d0ce9b76d2fd092997146f187ec09b4558a50" dependencies = [ "deranged", "libc", @@ -7670,9 +7665,9 @@ checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" [[package]] name = "time-macros" -version = "0.2.30" +version = "0.2.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcef1a61bdb119096e153208ec5cbec23944ce8bca13be5c7f60c634f7403935" +checksum = "c431b87111666e491a90baa837f914fb45cd5dc3c268591b0220ff5057f2085f" dependencies = [ "num-conv", "time-core", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 371d6696..dbd72fbb 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -4,6 +4,7 @@ default-members = ["cli", "client-cli", "daemon", "."] [workspace.dependencies] base64 = "0.22" +chrono = { version = "0.4", features = ["serde"] } clap = { version = "4.5", features = ["cargo", "derive", "env"] } defguard_wireguard_rs = "0.10" dirs-next = "2.0" @@ -76,7 +77,7 @@ redundant_closure = "warn" anyhow = "1.0" base64.workspace = true clap.workspace = true -chrono = { version = "0.4", features = ["serde"] } +chrono.workspace = true defguard-client-proto = { path = "client-proto" } defguard-client-core = { path = "core" } defguard-client-posture = { path = "enterprise/posture" } diff --git a/src-tauri/client-cli/Cargo.toml b/src-tauri/client-cli/Cargo.toml index cb40bcba..6b5a46cc 100644 --- a/src-tauri/client-cli/Cargo.toml +++ b/src-tauri/client-cli/Cargo.toml @@ -12,6 +12,7 @@ version.workspace = true name = "defguard-cli" [dependencies] +chrono.workspace = true clap = { workspace = true, features = ["cargo", "derive", "env"] } owo-colors = { version = "4", features = ["supports-colors"] } diff --git a/src-tauri/client-cli/src/main.rs b/src-tauri/client-cli/src/main.rs index 81850fd2..edf34dd8 100644 --- a/src-tauri/client-cli/src/main.rs +++ b/src-tauri/client-cli/src/main.rs @@ -6,13 +6,14 @@ use common::check_version_flag; mod brand; mod cli; mod commands; -mod config_poll; mod exit; mod logging; mod mfa; mod mfa_code; mod mfa_qr; +mod monitor; mod output; +mod polling; mod resolve; mod state; #[cfg(all(test, target_os = "linux"))] @@ -52,7 +53,8 @@ async fn main() -> ExitCode { } }; - config_poll::poll_config(&state).await; + polling::poll_config(&state).await; + monitor::tear_down_stale_connections(&state).await; // Dispatch command. match cli.command { diff --git a/src-tauri/client-cli/src/monitor.rs b/src-tauri/client-cli/src/monitor.rs new file mode 100644 index 00000000..2c59266d --- /dev/null +++ b/src-tauri/client-cli/src/monitor.rs @@ -0,0 +1,83 @@ +use chrono::Utc; +use defguard_core::connection::{ + active_state::{active_state, ActiveConnectionInfo}, + tear_down, +}; +use tracing::error; + +use crate::state::State; + +/// Determine whether a connection is stale based on its latest WireGuard handshake. +/// +/// Returns `None` when live backend stats are unavailable or the connection has no +/// recorded handshake, because in that case the CLI cannot safely decide whether the +/// connection is stale. +fn is_stale(connection: &ActiveConnectionInfo, peer_alive_period: u32) -> bool { + if let Some(stats) = connection.stats.as_ref() { + if let Some(last_handshake) = stats.last_handshake { + let now = Utc::now().timestamp() as u64; + return now.saturating_sub(last_handshake) > u64::from(peer_alive_period); + } + } + false +} + +/// Disconnect active connections whose latest handshake is older than the configured +/// peer alive period. +/// +/// Connections without usable live stats are left untouched. Failures are logged and do +/// not stop cleanup of the remaining connections. +pub async fn tear_down_stale_connections(state: &State) { + let connections = match active_state(&state.pool).await { + Ok(connections) => connections, + Err(err) => { + error!("Failed to retrieve active connections: {err}"); + return; + } + }; + if connections.is_empty() { + return; + } + + let peer_alive_period = state.app_config.peer_alive_period; + + #[cfg(target_os = "macos")] + { + use std::sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }; + + use defguard_core::connection::apple::spawn_runloop_and_wait_for; + + let semaphore = Arc::new(AtomicBool::new(false)); + let semaphore_clone = Arc::clone(&semaphore); + let handle = tokio::spawn(async move { + for connection in connections { + if is_stale(&connection, peer_alive_period) { + eprintln!("Removing stale connection {}", connection.name); + let result = tear_down(&connection).await; + if let Err(err) = result { + error!("Error removing stale connection {}: {err}", connection.name); + } + } + } + semaphore_clone.store(true, Ordering::Release); + }); + spawn_runloop_and_wait_for(&semaphore); + let _ = handle.await.unwrap(); + } + + #[cfg(not(target_os = "macos"))] + { + for connection in connections { + if is_stale(&connection, peer_alive_period) { + eprintln!("Removing stale connection {}", connection.name); + let result = tear_down(&connection).await; + if let Err(err) = result { + error!("Error removing stale connection {}: {err}", connection.name); + } + } + } + } +} diff --git a/src-tauri/client-cli/src/config_poll.rs b/src-tauri/client-cli/src/polling.rs similarity index 100% rename from src-tauri/client-cli/src/config_poll.rs rename to src-tauri/client-cli/src/polling.rs diff --git a/src-tauri/core/src/connection/active_state.rs b/src-tauri/core/src/connection/active_state.rs index 46559079..d8e1ce4e 100644 --- a/src-tauri/core/src/connection/active_state.rs +++ b/src-tauri/core/src/connection/active_state.rs @@ -19,7 +19,7 @@ use objc2_network_extension::NEVPNStatus; use tonic::Code; #[cfg(target_os = "macos")] -use crate::database::models::get_all_tunnels_locations; +use crate::{connection::apple::tunnel_stats, database::models::get_all_tunnels_locations}; #[cfg(not(target_os = "macos"))] use crate::{ connection::daemon_client::DAEMON_CLIENT, @@ -55,6 +55,18 @@ pub struct InterfaceStats { pub last_handshake: Option, } +#[cfg(target_os = "macos")] +impl From for InterfaceStats { + fn from(stats: super::apple::Stats) -> Self { + Self { + listen_port: 0, + tx_bytes: stats.tx_bytes, + rx_bytes: stats.rx_bytes, + last_handshake: (stats.last_handshake != 0).then_some(stats.last_handshake), + } + } +} + /// Query the platform backend for all currently-up WireGuard interfaces and match each /// peer back to a known `Location` or `Tunnel`. /// @@ -62,7 +74,7 @@ pub struct InterfaceStats { /// **unfiltered** snapshot of all managed interfaces (unlike `ReadInterfaceData`, which /// drops peers that haven't completed a handshake or whose stats haven't changed). /// -/// On macOS the Network Extension path is stubbed (pending the NE spike). +/// On macOS this queries Network Extension managers and asks connected providers for stats. #[cfg(target_os = "macos")] pub async fn active_state(_pool: &DbPool) -> Result, Error> { let (tunnels, locations) = get_all_tunnels_locations().await; @@ -73,12 +85,13 @@ pub async fn active_state(_pool: &DbPool) -> Result, E let mut result = Vec::new(); for location in locations { if let Some(NEVPNStatus::Connected) = location.status() { + let stats = tunnel_stats(location.id, &ConnectionType::Location).map(Into::into); let info = ActiveConnectionInfo { connection_type: ConnectionType::Location, target_id: location.id, name: location.name, interface_name: String::new(), - stats: None, // TODO + stats, }; result.push(info); } @@ -86,12 +99,13 @@ pub async fn active_state(_pool: &DbPool) -> Result, E for tunnel in tunnels { if let Some(NEVPNStatus::Connected) = tunnel.status() { + let stats = tunnel_stats(tunnel.id, &ConnectionType::Tunnel).map(Into::into); let info = ActiveConnectionInfo { connection_type: ConnectionType::Tunnel, target_id: tunnel.id, name: tunnel.name, interface_name: String::new(), - stats: None, // TODO + stats, }; result.push(info); } diff --git a/src-tauri/core/src/connection/apple.rs b/src-tauri/core/src/connection/apple.rs index 70b9d34a..ae9420eb 100644 --- a/src-tauri/core/src/connection/apple.rs +++ b/src-tauri/core/src/connection/apple.rs @@ -17,17 +17,21 @@ const OBSERVER_CLEANUP_INTERVAL: Duration = Duration::from_secs(30); use block2::RcBlock; use objc2::{rc::Retained, runtime::ProtocolObject}; use objc2_foundation::{ - ns_string, NSArray, NSDate, NSError, NSNotification, NSNotificationCenter, NSNumber, + ns_string, NSArray, NSData, NSDate, NSError, NSNotification, NSNotificationCenter, NSNumber, NSObjectProtocol, NSOperationQueue, NSRunLoop, NSString, }; use objc2_network_extension::{ - NETunnelProviderManager, NETunnelProviderProtocol, NEVPNConnection, + NETunnelProviderManager, NETunnelProviderProtocol, NETunnelProviderSession, NEVPNConnection, NEVPNStatusDidChangeNotification, }; +use serde::Deserialize; -use crate::database::{ - models::{location::Location, tunnel::Tunnel, Id}, - DB_POOL, +use crate::{ + database::{ + models::{location::Location, tunnel::Tunnel, Id}, + DB_POOL, + }, + ConnectionType, }; pub const PLUGIN_BUNDLE_ID: &str = "net.defguard.VPNExtension"; @@ -147,6 +151,92 @@ pub fn spawn_runloop_and_wait_for(semaphore: &Arc) { } } +/// Tunnel statistics shared with VPNExtension (written in Swift). +#[derive(Deserialize)] +#[repr(C)] +#[serde(rename_all = "camelCase")] +pub struct Stats { + pub location_id: Option, + pub tunnel_id: Option, + pub tx_bytes: u64, + pub rx_bytes: u64, + pub last_handshake: u64, +} + +/// Retrieve VPN tunnel statistics from VPNExtension. +pub fn tunnel_stats(id: Id, connection_type: &ConnectionType) -> Option { + let new_stats = Arc::new(Mutex::new(None)); + let plugin_bundle_id = ns_string!(PLUGIN_BUNDLE_ID); + + let new_stats_clone = Arc::clone(&new_stats); + + let finished = Arc::new(AtomicBool::new(false)); + let finished_clone = Arc::clone(&finished); + + let response_handler = RcBlock::new(move |data_ptr: *mut NSData| { + if let Some(data) = unsafe { data_ptr.as_ref() } { + if let Ok(stats) = serde_json::from_slice(data.to_vec().as_slice()) { + if let Ok(mut new_stats_locked) = new_stats_clone.lock() { + *new_stats_locked = Some(stats); + } + } else { + warn!("Failed to deserialize tunnel stats"); + } + } else { + debug!("No data received in tunnel stats response, skipping"); + } + finished_clone.store(true, Ordering::Release); + }); + + let manager = manager_for_key_and_value( + match connection_type { + ConnectionType::Location => LOCATION_ID, + ConnectionType::Tunnel => TUNNEL_ID, + }, + id, + )?; + + let vpn_protocol = (unsafe { manager.protocolConfiguration() })?; + let Ok(tunnel_protocol) = vpn_protocol.downcast::() else { + error!("Failed to downcast to NETunnelProviderProtocol"); + return None; + }; + + // Sometimes all managers from all apps come through, so filter by bundle ID. + if let Some(bundle_id) = unsafe { tunnel_protocol.providerBundleIdentifier() } { + if &*bundle_id != plugin_bundle_id { + return None; + } + } + + let Ok(session) = unsafe { manager.connection() }.downcast::() else { + error!("Failed to downcast to NETunnelProviderSession"); + return None; + }; + + let message_data = NSData::new(); + if unsafe { + session.sendProviderMessage_returnError_responseHandler( + &message_data, + None, + Some(&response_handler), + ) + } { + debug!("Message sent to NETunnelProviderSession"); + } else { + error!("Failed to send to NETunnelProviderSession while requesting stats"); + } + + // Wait for the response handler to complete. + while !finished.load(Ordering::Acquire) { + spin_loop(); + } + + new_stats + .lock() + .map_or(None, |mut new_stats_locked| new_stats_locked.take()) +} + /// Handle VPN status change. fn vpn_status_change_handler(notification: &NSNotification) { let name = notification.name(); diff --git a/src-tauri/src/apple.rs b/src-tauri/src/apple.rs index d100dcae..ac1dde28 100644 --- a/src-tauri/src/apple.rs +++ b/src-tauri/src/apple.rs @@ -1,28 +1,13 @@ //! Interchangeability and communication with VPNExtension (written in Swift). -use std::{ - collections::HashMap, - hint::spin_loop, - sync::{ - atomic::{AtomicBool, Ordering}, - Arc, Mutex, - }, - time::Duration, -}; +use std::{collections::HashMap, time::Duration}; -use block2::RcBlock; use defguard_client_core::connection::{ active_connections::find_connection, - apple::{ - manager_for_key_and_value, LOCATION_ID, PLUGIN_BUNDLE_ID, TUNNEL_ID, VPN_STATE_UPDATE_COMMS, - }, + apple::{manager_for_key_and_value, LOCATION_ID, TUNNEL_ID, VPN_STATE_UPDATE_COMMS}, }; use objc2::rc::Retained; -use objc2_foundation::{ns_string, NSData}; -use objc2_network_extension::{ - NETunnelProviderManager, NETunnelProviderProtocol, NETunnelProviderSession, NEVPNStatus, -}; -use serde::Deserialize; +use objc2_network_extension::{NETunnelProviderManager, NEVPNStatus}; use tauri::{AppHandle, Emitter, Manager}; use tokio::time::sleep; use tracing::Level; @@ -265,18 +250,6 @@ async fn sync_connections_with_system(app_handle: &AppHandle) { } } -/// Tunnel statistics shared with VPNExtension (written in Swift). -#[derive(Deserialize)] -#[repr(C)] -#[serde(rename_all = "camelCase")] -pub(crate) struct Stats { - pub(crate) location_id: Option, - pub(crate) tunnel_id: Option, - pub(crate) tx_bytes: u64, - pub(crate) rx_bytes: u64, - pub(crate) last_handshake: u64, -} - #[must_use] pub fn get_managers_for_tunnels_and_locations( tunnels: &[Tunnel], @@ -298,79 +271,3 @@ pub fn get_managers_for_tunnels_and_locations( managers } - -/// Retrieve VPN tunnel statistics from VPNExtension. -pub(crate) fn tunnel_stats(id: Id, connection_type: &ConnectionType) -> Option { - let new_stats = Arc::new(Mutex::new(None)); - let plugin_bundle_id = ns_string!(PLUGIN_BUNDLE_ID); - - let new_stats_clone = Arc::clone(&new_stats); - - let finished = Arc::new(AtomicBool::new(false)); - let finished_clone = Arc::clone(&finished); - - let response_handler = RcBlock::new(move |data_ptr: *mut NSData| { - if let Some(data) = unsafe { data_ptr.as_ref() } { - if let Ok(stats) = serde_json::from_slice(data.to_vec().as_slice()) { - if let Ok(mut new_stats_locked) = new_stats_clone.lock() { - *new_stats_locked = Some(stats); - } - } else { - warn!("Failed to deserialize tunnel stats"); - } - } else { - debug!("No data received in tunnel stats response, skipping"); - } - finished_clone.store(true, Ordering::Release); - }); - - let manager = manager_for_key_and_value( - match connection_type { - ConnectionType::Location => LOCATION_ID, - ConnectionType::Tunnel => TUNNEL_ID, - }, - id, - )?; - - let vpn_protocol = (unsafe { manager.protocolConfiguration() })?; - let Ok(tunnel_protocol) = vpn_protocol.downcast::() else { - error!("Failed to downcast to NETunnelProviderProtocol"); - return None; - }; - - // Sometimes all managers from all apps come through, so filter by bundle ID. - if let Some(bundle_id) = unsafe { tunnel_protocol.providerBundleIdentifier() } { - if &*bundle_id != plugin_bundle_id { - return None; - } - } - - let Ok(session) = unsafe { manager.connection() }.downcast::() else { - error!("Failed to downcast to NETunnelProviderSession"); - return None; - }; - - let message_data = NSData::new(); - if unsafe { - session.sendProviderMessage_returnError_responseHandler( - &message_data, - None, - Some(&response_handler), - ) - } { - debug!("Message sent to NETunnelProviderSession"); - } else { - error!("Failed to send to NETunnelProviderSession while requesting stats"); - } - - // Wait for all handlers to complete. - while !finished.load(Ordering::Acquire) { - spin_loop(); - } - - let stats = new_stats - .lock() - .map_or(None, |mut new_stats_locked| new_stats_locked.take()); - - stats -} diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index 4711a9a9..6e3e397f 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -17,6 +17,7 @@ use defguard_client_proto::defguard::{ client_types::DeviceConfigResponse, enterprise::posture::v2::DevicePostureData, }; use defguard_client_provisioning::ProvisioningConfig; +#[cfg(not(target_os = "macos"))] use defguard_client_service_locations::to_service_location; use serde::{Deserialize, Serialize}; use struct_patch::Patch; diff --git a/src-tauri/src/utils.rs b/src-tauri/src/utils.rs index f68a7db8..0d3a118f 100644 --- a/src-tauri/src/utils.rs +++ b/src-tauri/src/utils.rs @@ -30,8 +30,6 @@ use windows_service::{ #[cfg(windows)] use windows_sys::Win32::Foundation::ERROR_SERVICE_DOES_NOT_EXIST; -#[cfg(target_os = "macos")] -use crate::apple::tunnel_stats; #[cfg(not(target_os = "macos"))] use crate::database::models::{ location_stats::peer_to_location_stats, tunnel::peer_to_tunnel_stats, @@ -48,6 +46,8 @@ use crate::{ log_watcher::service_log_watcher::spawn_log_watcher_task, ConnectionType, }; +#[cfg(target_os = "macos")] +use defguard_client_core::connection::apple::tunnel_stats; // Work-around MFA propagation delay. FIXME: remove once Core API is corrected. #[cfg(target_os = "macos")]