From 187cfebdc36177864bd0554a7f6dc7bbe87d95e0 Mon Sep 17 00:00:00 2001 From: Maxime Colliat Date: Wed, 2 Apr 2025 15:50:54 +0200 Subject: [PATCH 1/6] Update vendor --- package.json | 2 + pnpm-lock.yaml | 32 ++ src-tauri/Cargo.lock | 444 ++++++------------ src-tauri/Cargo.toml | 2 +- src-tauri/tauri.conf.json | 1 + .../fileflowui/extract/download/Download.tsx | 28 +- .../hooks/database/DatabaseDialog.tsx | 300 ++++++------ .../hooks/database/DatabaseForm.tsx | 2 +- ...tDatabase.tsx => SelectDatabaseEngine.tsx} | 4 +- src/components/hooks/database/SqliteForm.tsx | 2 +- src/components/hooks/file/InputTextDialog.tsx | 2 +- src/components/hooks/utils.tsx | 25 + tsconfig.json | 3 +- 13 files changed, 378 insertions(+), 469 deletions(-) rename src/components/hooks/database/{SelectDatabase.tsx => SelectDatabaseEngine.tsx} (91%) diff --git a/package.json b/package.json index d5422f6..e784048 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { "name": "fileflow", + "version": "1.0.2", "private": true, "type": "module", "scripts": { @@ -9,6 +10,7 @@ "tauri": "tauri" }, "dependencies": { + "@radix-ui/react-checkbox": "^1.1.4", "@radix-ui/react-dialog": "^1.1.6", "@radix-ui/react-dropdown-menu": "^2.1.6", "@radix-ui/react-icons": "^1.3.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0aaa9de..81fc368 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: dependencies: + '@radix-ui/react-checkbox': + specifier: ^1.1.4 + version: 1.1.4(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-dialog': specifier: ^1.1.6 version: 1.1.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -427,6 +430,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-checkbox@1.1.4': + resolution: {integrity: sha512-wP0CPAHq+P5I4INKe3hJrIa1WoNqqrejzW+zoU0rOvo1b9gDEJJFl2rYfO1PYJUQCc2H1WZxIJmyv9BS8i5fLw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-collection@1.1.2': resolution: {integrity: sha512-9z54IEKRxIa9VityapoEYMuByaG42iSy1ZXlY2KcuLSEtq8x4987/N6m15ppoMffgZX72gER2uHe1D9Y6Unlcw==} peerDependencies: @@ -2135,6 +2151,22 @@ snapshots: '@types/react': 18.3.18 '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@radix-ui/react-checkbox@1.1.4(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.18)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@radix-ui/react-collection@1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 6064f60..07da22f 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -4,7 +4,7 @@ version = 4 [[package]] name = "FileFlow" -version = "1.0.1" +version = "1.0.2" dependencies = [ "csv", "serde", @@ -126,9 +126,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.87" +version = "0.1.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d556ec1359574147ec0c4fc5eb525f3f23263a592b1a9c07e0a75b427de55c97" +checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", @@ -202,9 +202,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.7.2" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8faa168b8c4ffca39c2699e772943af41ec2b75fb1683dda07b28a6d285c53dc" +checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" [[package]] name = "bitflags" @@ -355,9 +355,9 @@ dependencies = [ [[package]] name = "cargo_toml" -version = "0.21.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fbd1fe9db3ebf71b89060adaf7b0504c2d6a425cf061313099547e382c2e472" +checksum = "02260d489095346e5cafd04dea8e8cb54d1d74fcd759022a9b72986ebe9a1257" dependencies = [ "serde", "toml", @@ -365,9 +365,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.16" +version = "1.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" +checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" dependencies = [ "shlex", ] @@ -642,9 +642,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" dependencies = [ "darling_core", "darling_macro", @@ -652,9 +652,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" dependencies = [ "fnv", "ident_case", @@ -666,9 +666,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", @@ -688,9 +688,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.11" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "28cfac68e08048ae1883171632c2aef3ebc555621ae56fbccce1cbf22dd7f058" dependencies = [ "powerfmt", "serde", @@ -942,9 +942,9 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" dependencies = [ "event-listener", "pin-project-lite", @@ -977,9 +977,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" +checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" dependencies = [ "crc32fast", "miniz_oxide", @@ -1004,9 +1004,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "foreign-types" @@ -1302,22 +1302,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "wasm-bindgen", ] [[package]] name = "getrandom" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" dependencies = [ "cfg-if", "libc", - "wasi 0.13.3+wasi-0.2.2", - "windows-targets 0.52.6", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", ] [[package]] @@ -1635,29 +1633,11 @@ dependencies = [ "want", ] -[[package]] -name = "hyper-rustls" -version = "0.27.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" -dependencies = [ - "futures-util", - "http", - "hyper", - "hyper-util", - "rustls", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tower-service", - "webpki-roots", -] - [[package]] name = "hyper-util" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2" dependencies = [ "bytes", "futures-channel", @@ -1665,6 +1645,7 @@ dependencies = [ "http", "http-body", "hyper", + "libc", "pin-project-lite", "socket2", "tokio", @@ -1674,16 +1655,17 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.61" +version = "0.1.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", + "log", "wasm-bindgen", - "windows-core 0.52.0", + "windows-core 0.61.0", ] [[package]] @@ -1746,9 +1728,9 @@ dependencies = [ [[package]] name = "icu_locid_transform_data" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" +checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" [[package]] name = "icu_normalizer" @@ -1770,9 +1752,9 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" +checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" [[package]] name = "icu_properties" @@ -1791,9 +1773,9 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" +checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" [[package]] name = "icu_provider" @@ -2078,9 +2060,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9c683daf087dc577b7506e9695b3d556a9f3849903fa28186283afd6809e9" +checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" [[package]] name = "litemap" @@ -2100,9 +2082,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.26" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "mac" @@ -2572,9 +2554,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.0" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde51589ab56b20a6f686b2c68f7a0bd6add753d697abf720d63f8db3ab7b1ad" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "openssl" @@ -2880,9 +2862,9 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "plist" -version = "1.7.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016" +checksum = "eac26e981c03a6e53e0aee43c113e3202f5581d5360dae7bd2c70e800dd0451d" dependencies = [ "base64 0.22.1", "indexmap 2.8.0", @@ -3001,58 +2983,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "quinn" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef" -dependencies = [ - "bytes", - "pin-project-lite", - "quinn-proto", - "quinn-udp", - "rustc-hash", - "rustls", - "socket2", - "thiserror 2.0.12", - "tokio", - "tracing", -] - -[[package]] -name = "quinn-proto" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" -dependencies = [ - "bytes", - "getrandom 0.2.15", - "rand 0.8.5", - "ring", - "rustc-hash", - "rustls", - "rustls-pki-types", - "slab", - "thiserror 2.0.12", - "tinyvec", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-udp" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e46f3055866785f6b92bc6164b76be02ca8f2eb4b002c0354b28cf4c119e5944" -dependencies = [ - "cfg_aliases", - "libc", - "once_cell", - "socket2", - "tracing", - "windows-sys 0.59.0", -] - [[package]] name = "quote" version = "1.0.40" @@ -3062,6 +2992,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + [[package]] name = "rand" version = "0.7.3" @@ -3152,7 +3088,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.1", + "getrandom 0.3.2", ] [[package]] @@ -3230,9 +3166,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" -version = "0.12.14" +version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989e327e510263980e231de548a33e63d34962d29ae61b467389a1a09627a254" +checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" dependencies = [ "base64 0.22.1", "bytes", @@ -3242,7 +3178,6 @@ dependencies = [ "http-body", "http-body-util", "hyper", - "hyper-rustls", "hyper-util", "ipnet", "js-sys", @@ -3251,16 +3186,11 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "quinn", - "rustls", - "rustls-pemfile", - "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper", "tokio", - "tokio-rustls", "tokio-util", "tower", "tower-service", @@ -3269,7 +3199,6 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots", "windows-registry", ] @@ -3298,20 +3227,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[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.15", - "libc", - "untrusted", - "windows-sys 0.52.0", -] - [[package]] name = "rsa" version = "0.9.8" @@ -3338,12 +3253,6 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" -[[package]] -name = "rustc-hash" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" - [[package]] name = "rustc_version" version = "0.4.1" @@ -3355,9 +3264,9 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.2" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7178faa4b75a30e269c71e61c353ce2748cf3d76f0c44c393f4e60abf49b825" +checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" dependencies = [ "bitflags 2.9.0", "errno", @@ -3366,49 +3275,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "rustls" -version = "0.23.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395" -dependencies = [ - "once_cell", - "ring", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls-pemfile" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" -dependencies = [ - "rustls-pki-types", -] - -[[package]] -name = "rustls-pki-types" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" -dependencies = [ - "web-time", -] - -[[package]] -name = "rustls-webpki" -version = "0.102.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" -dependencies = [ - "ring", - "rustls-pki-types", - "untrusted", -] - [[package]] name = "rustversion" version = "1.0.20" @@ -3757,9 +3623,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" dependencies = [ "libc", "windows-sys 0.52.0", @@ -4034,9 +3900,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "string_cache" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938d512196766101d333398efde81bc1f37b00cb42c2f8350e5df639f040bbbe" +checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" dependencies = [ "new_debug_unreachable", "parking_lot", @@ -4204,9 +4070,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tauri" -version = "2.3.1" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be747b26bf28674977fac47bdf6963fd9c7578271c3fbeb25d8686de6596f35" +checksum = "4d08db1ff9e011e04014e737ec022610d756c0eae0b3b3a9037bccaf3003173a" dependencies = [ "anyhow", "bytes", @@ -4254,9 +4120,9 @@ dependencies = [ [[package]] name = "tauri-build" -version = "2.0.6" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51a2e96f3c0baa0581656bb58e6fdd0f7c9c31eaf6721a0c08689d938fe85f2d" +checksum = "0fd20e4661c2cce65343319e6e8da256958f5af958cafc47c0d0af66a55dcd17" dependencies = [ "anyhow", "cargo_toml", @@ -4276,9 +4142,9 @@ dependencies = [ [[package]] name = "tauri-codegen" -version = "2.0.5" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e357ec3daf8faad1029bc7109e7f5b308ceb63b6073d110d7388923a4cce5e55" +checksum = "458258b19032450ccf975840116ecf013e539eadbb74420bd890e8c56ab2b1a4" dependencies = [ "base64 0.22.1", "brotli", @@ -4303,9 +4169,9 @@ dependencies = [ [[package]] name = "tauri-macros" -version = "2.0.5" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "447ee4dd94690d77f1422f2b57e783c654ba75c535ad6f6e727887330804fff2" +checksum = "d402813d3b9c773a0fa58697c457c771f10e735498fdcb7b343264d18e5a601f" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -4317,9 +4183,9 @@ dependencies = [ [[package]] name = "tauri-plugin" -version = "2.0.5" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad3021d8e60ec7672f51ecb67c5e1a514a4d7a9a5ffc9d85090739378047502" +checksum = "a4190775d6ff73fe66d9af44c012739a2659720efd9c0e1e56a918678038699d" dependencies = [ "anyhow", "glob", @@ -4334,9 +4200,9 @@ dependencies = [ [[package]] name = "tauri-plugin-dialog" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b59fd750551b1066744ab956a1cd6b1ea3e1b3763b0b9153ac27a044d596426" +checksum = "bcaf6e5d6062423a0f711a23c2a573ccba222b6a16a9322d8499928f27e41376" dependencies = [ "log", "raw-window-handle", @@ -4352,9 +4218,9 @@ dependencies = [ [[package]] name = "tauri-plugin-fs" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a1edf18000f02903a7c2e5997fb89aca455ecbc0acc15c6535afbb883be223" +checksum = "88371e340ad2f07409a3b68294abe73f20bc9c1bc1b631a31dc37a3d0161f682" dependencies = [ "anyhow", "dunce", @@ -4390,10 +4256,11 @@ dependencies = [ [[package]] name = "tauri-runtime" -version = "2.4.0" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e758a405ab39e25f4d1235c5f06fe563f44b01ee18bbe38ddec5356d4f581908" +checksum = "00ada7ac2f9276f09b8c3afffd3215fd5d9bff23c22df8a7c70e7ef67cacd532" dependencies = [ + "cookie", "dpi", "gtk", "http", @@ -4409,9 +4276,9 @@ dependencies = [ [[package]] name = "tauri-runtime-wry" -version = "2.4.1" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2beb90decade4c71e8b09c9e4a9245837a8a97693f945b77e32baf13f51fec" +checksum = "cf2e5842c57e154af43a20a49c7efee0ce2578c20b4c2bdf266852b422d2e421" dependencies = [ "gtk", "http", @@ -4436,10 +4303,11 @@ dependencies = [ [[package]] name = "tauri-utils" -version = "2.2.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "107a959dbd5ff53d89a98f6f2e3e987c611334141a43630caae1d80e79446dd6" +checksum = "1f037e66c7638cc0a2213f61566932b9a06882b8346486579c90e4b019bac447" dependencies = [ + "anyhow", "brotli", "cargo_metadata", "ctor", @@ -4483,13 +4351,12 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.18.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c317e0a526ee6120d8dabad239c8dadca62b24b6f168914bbbc8e2fb1f0e567" +checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" dependencies = [ - "cfg-if", "fastrand", - "getrandom 0.3.1", + "getrandom 0.3.2", "once_cell", "rustix", "windows-sys 0.59.0", @@ -4554,9 +4421,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.39" +version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad298b01a40a23aac4580b67e3dbedb7cc8402f3592d7f49469de2ea4aecdd8" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" dependencies = [ "deranged", "itoa 1.0.15", @@ -4569,15 +4436,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "765c97a5b985b7c11d7bc27fa927dc4fe6af3a6dfb021d28deb60d3bf51e76ef" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" -version = "0.2.20" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8093bc3e81c3bc5f7879de09619d06c9a5a5e45ca44dfeeb7225bae38005c5c" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" dependencies = [ "num-conv", "time-core", @@ -4637,16 +4504,6 @@ dependencies = [ "syn 2.0.100", ] -[[package]] -name = "tokio-rustls" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" -dependencies = [ - "rustls", - "tokio", -] - [[package]] name = "tokio-stream" version = "0.1.17" @@ -4911,12 +4768,6 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" -[[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.4" @@ -4961,11 +4812,11 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" -version = "1.15.1" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0f540e3240398cce6128b64ba83fdbdd86129c16a3aa1a3a252efd66eb3d587" +checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" dependencies = [ - "getrandom 0.3.1", + "getrandom 0.3.2", "serde", ] @@ -5040,9 +4891,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasi" -version = "0.13.3+wasi-0.2.2" +version = "0.14.2+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" dependencies = [ "wit-bindgen-rt", ] @@ -5147,16 +4998,6 @@ dependencies = [ "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 = "webkit2gtk" version = "2.0.1" @@ -5201,15 +5042,6 @@ dependencies = [ "system-deps", ] -[[package]] -name = "webpki-roots" -version = "0.26.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9" -dependencies = [ - "rustls-pki-types", -] - [[package]] name = "webview2-com" version = "0.36.0" @@ -5220,7 +5052,7 @@ dependencies = [ "webview2-com-sys", "windows", "windows-core 0.60.1", - "windows-implement", + "windows-implement 0.59.0", "windows-interface", ] @@ -5248,9 +5080,9 @@ dependencies = [ [[package]] name = "whoami" -version = "1.5.2" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d" +checksum = "6994d13118ab492c3c80c1f81928718159254c53c472bf9ce36f8dae4add02a7" dependencies = [ "redox_syscall", "wasite", @@ -5326,24 +5158,28 @@ dependencies = [ [[package]] name = "windows-core" -version = "0.52.0" +version = "0.60.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "ca21a92a9cae9bf4ccae5cf8368dce0837100ddf6e6d57936749e85f152f6247" dependencies = [ - "windows-targets 0.52.6", + "windows-implement 0.59.0", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings 0.3.1", ] [[package]] name = "windows-core" -version = "0.60.1" +version = "0.61.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca21a92a9cae9bf4ccae5cf8368dce0837100ddf6e6d57936749e85f152f6247" +checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" dependencies = [ - "windows-implement", + "windows-implement 0.60.0", "windows-interface", "windows-link", "windows-result", - "windows-strings", + "windows-strings 0.4.0", ] [[package]] @@ -5367,11 +5203,22 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "windows-interface" -version = "0.59.0" +version = "0.59.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb26fd936d991781ea39e87c3a27285081e3c0da5ca0fcbc02d368cc6f52ff01" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" dependencies = [ "proc-macro2", "quote", @@ -5380,9 +5227,9 @@ dependencies = [ [[package]] name = "windows-link" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" [[package]] name = "windows-numerics" @@ -5401,15 +5248,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" dependencies = [ "windows-result", - "windows-strings", + "windows-strings 0.3.1", "windows-targets 0.53.0", ] [[package]] name = "windows-result" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06374efe858fab7e4f881500e6e86ec8bc28f9462c47e5a9941a0142ad86b189" +checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" dependencies = [ "windows-link", ] @@ -5423,6 +5270,15 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-strings" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -5523,9 +5379,9 @@ dependencies = [ [[package]] name = "windows-version" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bfbcc4996dd183ff1376a20ade1242da0d2dcaff83cc76710a588d24fd4c5db" +checksum = "e04a5c6627e310a23ad2358483286c7df260c964eb2d003d8efd6d0f4e79265c" dependencies = [ "windows-link", ] @@ -5740,9 +5596,9 @@ dependencies = [ [[package]] name = "wit-bindgen-rt" -version = "0.33.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ "bitflags 2.9.0", ] @@ -5761,9 +5617,9 @@ checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" [[package]] name = "wry" -version = "0.50.4" +version = "0.50.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804a7d1613bd699beccaa60f3b3c679acee21cebba1945a693f5eab95c08d1fa" +checksum = "b19b78efae8b853c6c817e8752fc1dbf9cab8a8ffe9c30f399bd750ccf0f0730" dependencies = [ "base64 0.22.1", "block2 0.6.0", @@ -5917,18 +5773,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.23" +version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" +checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.23" +version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" +checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" dependencies = [ "proc-macro2", "quote", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 2da748f..c4aa586 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "FileFlow" -version = "1.0.1" +version = "1.0.2" description = "An app to manipulate DBMS tables" authors = ["Maxime-Cllt"] edition = "2021" diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 7f558f1..12e04e2 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -18,6 +18,7 @@ }, "productName": "FileFlow", "mainBinaryName": "FileFlow", + "version" : "1.0.2", "identifier": "com.fileflow.app", "plugins": {}, "app": { diff --git a/src/components/fileflowui/extract/download/Download.tsx b/src/components/fileflowui/extract/download/Download.tsx index 52ef223..ff6515e 100644 --- a/src/components/fileflowui/extract/download/Download.tsx +++ b/src/components/fileflowui/extract/download/Download.tsx @@ -2,7 +2,7 @@ import React, {useEffect, useState} from 'react'; import {invoke} from "@tauri-apps/api/core"; import {Label} from "@/components/ui/label.tsx"; import {ComboboxComponent} from "@/components/hooks/component/ComboboxComponent.tsx"; -import {log_error} from "@/components/hooks/utils.tsx"; +import {log_error, requestAllTablesFromConnection} from "@/components/hooks/utils.tsx"; import {Select, SelectContent, SelectItem, SelectTrigger} from "@/components/ui/select.tsx"; import {Card, CardContent, CardHeader, CardTitle} from "@/components/ui/card.tsx"; import {toast} from "sonner"; @@ -38,23 +38,13 @@ const Download: React.FC = () => { const retrieveTables = async (): Promise => { try { - console.log('Retrieving tables...'); - const get_table_list_response: boolean | ComboItem[] = await invoke | boolean>('get_table_list'); - - if (typeof get_table_list_response === "boolean") { - throw new Error('Failed to get table list'); - } + let parsedData = await requestAllTablesFromConnection(); - if (get_table_list_response.length === 0) { - throw new Error('No tables found'); + if (typeof parsedData === "boolean") { + throw new Error("Failed to retrieve tables"); } - const parsedData: ComboItem[] = get_table_list_response.map(item => ({ - value: item.value, - label: item.label - })); - setTables(parsedData); } catch (error) { log_error(error) @@ -127,10 +117,12 @@ const Download: React.FC = () => {
- - Export Configuration - +
+ + Export Configuration + +
diff --git a/src/components/hooks/database/DatabaseDialog.tsx b/src/components/hooks/database/DatabaseDialog.tsx index b5469f6..d1e66c7 100644 --- a/src/components/hooks/database/DatabaseDialog.tsx +++ b/src/components/hooks/database/DatabaseDialog.tsx @@ -1,150 +1,150 @@ -import React from "react"; -import { - Dialog, - DialogClose, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger -} from "@/components/ui/dialog"; -import {Button} from "@/components/ui/button"; -import {Play} from "lucide-react"; -import {Label} from "@/components/ui/label"; -import {Input} from "@/components/ui/input"; -import {DatabaseConfig} from "@/interfaces/DatabaseConfig.tsx"; - -interface DataBaseDialogProps { - dbConfig: DatabaseConfig; - sql: string; - updateDbConfigField: (field: keyof DatabaseConfig, value: DatabaseConfig[keyof DatabaseConfig]) => void; - executeSQL: () => void; -} - -const DataBaseDialog: React.FC = (props: DataBaseDialogProps) => { - - return ( -
- - {/* Trigger Button */} - - {props.sql !== "" && ( - - )} - - - {/* Dialog Content */} - - - Database Configuration - - Configure the database connection and execute your SQL query. - - - - {/* Form Layout */} -
- - - {/* First Row: Username and Password */} -
-
- - props.updateDbConfigField("username", e.target.value)} - className="w-full border rounded-md p-2 shadow-sm focus:ring-purple-300 focus:border-purple-500" - /> -
-
- - props.updateDbConfigField("password", e.target.value)} - className="w-full border rounded-md p-2 shadow-sm focus:ring-purple-300 focus:border-purple-500" - /> -
-
- - {/* Second Row: URL and Port */} -
-
- - props.updateDbConfigField("db_host", e.target.value)} - className="w-full border rounded-md p-2 shadow-sm focus:ring-purple-300 focus:border-purple-500" - /> -
-
- - props.updateDbConfigField("port", e.target.value)} - className="w-full border rounded-md p-2 shadow-sm focus:ring-purple-300 focus:border-purple-500" - /> -
-
- - {/* Third Row: Database Name */} -
- - props.updateDbConfigField("db_name", e.target.value)} - className="w-full border rounded-md p-2 shadow-sm focus:ring-purple-300 focus:border-purple-500" - /> -
-
- - {/* Dialog Footer */} - -
- - - -
- -
-
-
-
- ); -}; - -export default DataBaseDialog; +// import React from "react"; +// import { +// Dialog, +// DialogClose, +// DialogContent, +// DialogDescription, +// DialogFooter, +// DialogHeader, +// DialogTitle, +// DialogTrigger +// } from "@/components/ui/dialog"; +// import {Button} from "@/components/ui/button"; +// import {Play} from "lucide-react"; +// import {Label} from "@/components/ui/label"; +// import {Input} from "@/components/ui/input"; +// import {DatabaseConfig} from "@/interfaces/DatabaseConfig.tsx"; +// +// interface DataBaseDialogProps { +// dbConfig: DatabaseConfig; +// sql: string; +// updateDbConfigField: (field: keyof DatabaseConfig, value: DatabaseConfig[keyof DatabaseConfig]) => void; +// executeSQL: () => void; +// } +// +// const DataBaseDialog: React.FC = (props: DataBaseDialogProps) => { +// +// return ( +//
+// +// {/* Trigger Button */} +// +// {props.sql !== "" && ( +// +// )} +// +// +// {/* Dialog Content */} +// +// +// Database Configuration +// +// Configure the database connection and execute your SQL query. +// +// +// +// {/* Form Layout */} +//
+// +// +// {/* First Row: Username and Password */} +//
+//
+// +// props.updateDbConfigField("username", e.target.value)} +// className="w-full border rounded-md p-2 shadow-sm focus:ring-purple-300 focus:border-purple-500" +// /> +//
+//
+// +// props.updateDbConfigField("password", e.target.value)} +// className="w-full border rounded-md p-2 shadow-sm focus:ring-purple-300 focus:border-purple-500" +// /> +//
+//
+// +// {/* Second Row: URL and Port */} +//
+//
+// +// props.updateDbConfigField("db_host", e.target.value)} +// className="w-full border rounded-md p-2 shadow-sm focus:ring-purple-300 focus:border-purple-500" +// /> +//
+//
+// +// props.updateDbConfigField("port", e.target.value)} +// className="w-full border rounded-md p-2 shadow-sm focus:ring-purple-300 focus:border-purple-500" +// /> +//
+//
+// +// {/* Third Row: Database Name */} +//
+// +// props.updateDbConfigField("db_name", e.target.value)} +// className="w-full border rounded-md p-2 shadow-sm focus:ring-purple-300 focus:border-purple-500" +// /> +//
+//
+// +// {/* Dialog Footer */} +// +//
+// +// +// +//
+// +//
+//
+//
+//
+// ); +// }; +// +// export default DataBaseDialog; diff --git a/src/components/hooks/database/DatabaseForm.tsx b/src/components/hooks/database/DatabaseForm.tsx index ebdb16e..723a481 100644 --- a/src/components/hooks/database/DatabaseForm.tsx +++ b/src/components/hooks/database/DatabaseForm.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import SelectDBMS from "@/components/hooks/database/SelectDatabase.tsx"; +import SelectDBMS from "@/components/hooks/database/SelectDatabaseEngine.tsx"; import {Input} from "@/components/ui/input.tsx"; import SqliteForm from "@/components/hooks/database/SqliteForm.tsx"; import {DatabaseFormProps} from "@/interfaces/DatabaseFormProps.tsx"; diff --git a/src/components/hooks/database/SelectDatabase.tsx b/src/components/hooks/database/SelectDatabaseEngine.tsx similarity index 91% rename from src/components/hooks/database/SelectDatabase.tsx rename to src/components/hooks/database/SelectDatabaseEngine.tsx index ed11955..0466e1a 100644 --- a/src/components/hooks/database/SelectDatabase.tsx +++ b/src/components/hooks/database/SelectDatabaseEngine.tsx @@ -7,7 +7,7 @@ interface SelectDatabaseProps { updateDbConfigField: (field: keyof DatabaseConfig, value: DatabaseConfig[keyof DatabaseConfig]) => void; } -const SelectDatabase: React.FC = (props: SelectDatabaseProps) => { +const SelectDatabaseEngine: React.FC = (props: SelectDatabaseProps) => { const databaseOptions = { mysql: "MySQL", @@ -40,4 +40,4 @@ const SelectDatabase: React.FC = (props: SelectDatabaseProp ); }; -export default SelectDatabase; +export default SelectDatabaseEngine; diff --git a/src/components/hooks/database/SqliteForm.tsx b/src/components/hooks/database/SqliteForm.tsx index 2ddf366..b2004aa 100644 --- a/src/components/hooks/database/SqliteForm.tsx +++ b/src/components/hooks/database/SqliteForm.tsx @@ -2,7 +2,7 @@ import React from 'react'; import {Input} from "@/components/ui/input.tsx"; import {Button} from "@/components/ui/button.tsx"; import {HardDrive} from "lucide-react"; -import SelectDBMS from "@/components/hooks/database/SelectDatabase.tsx"; +import SelectDBMS from "@/components/hooks/database/SelectDatabaseEngine.tsx"; import * as dialog from "@tauri-apps/plugin-dialog"; import {toast} from "sonner"; import {DatabaseConfig} from "@/interfaces/DatabaseConfig.tsx"; diff --git a/src/components/hooks/file/InputTextDialog.tsx b/src/components/hooks/file/InputTextDialog.tsx index 2ea5394..2b61eba 100644 --- a/src/components/hooks/file/InputTextDialog.tsx +++ b/src/components/hooks/file/InputTextDialog.tsx @@ -71,7 +71,7 @@ const InputTextDialog: React.FC = (props: SaveConfigDialo Cancel - +
+ + + + + + No item found. + + {props.lists.map((item) => ( + handleSelect(currentValue)} + > + handleSelect(item.value)} + className="mr-2" + /> + {item.label} + + ))} + + +
+ + +
+
+
+ + ) +} diff --git a/src/components/hooks/file/FileUpload.tsx b/src/components/hooks/file/FileUpload.tsx index a4a2122..3b58ac9 100644 --- a/src/components/hooks/file/FileUpload.tsx +++ b/src/components/hooks/file/FileUpload.tsx @@ -4,45 +4,52 @@ import {Button} from "@/components/ui/button.tsx"; import {FileArchive} from "lucide-react"; import {invoke} from "@tauri-apps/api/core"; import * as dialog from "@tauri-apps/plugin-dialog" -import {toast} from "sonner"; -import {getFileNameFromPath} from "@/components/hooks/utils.tsx"; +import {getFileNameFromPath, log_error} from "@/components/hooks/utils.tsx"; interface FileUploadProps { - filePath: string; - setFilePath: (path: string) => void; + filesPath: string[]; + setFilePath: (path: string[]) => void + multiple?: boolean; } const FileUpload: React.FC = (props: FileUploadProps) => { - const [fileSize, setFileSize] = React.useState(''); + const [message, setMessage] = React.useState(''); - const [fileName, setFileName] = React.useState(''); - - const openFileDialog = async () => { + const openFileDialog = async (): Promise => { try { - const selectedFilePath = await dialog.open({ + const selectedFilePath: string | null = await dialog.open({ filters: [{name: 'CSV Files', extensions: ['csv']}], - multiple: false, + multiple: props.multiple || false, directory: false, }); - setFileName(getFileNameFromPath(selectedFilePath?.toString() || '')); - - if (selectedFilePath && selectedFilePath !== fileName) { - const path: string = selectedFilePath?.toString(); + if (!selectedFilePath) { + return; + } - props.setFilePath(path) + if (Array.isArray(selectedFilePath)) { + let message: string = ''; + for (const filePath of selectedFilePath) { - const response = await invoke('get_size_of_file', {filePath: path}); + const fileName: string = getFileNameFromPath(filePath?.toString() || ''); + const fileSize: string = await invoke('get_size_of_file', {filePath: filePath?.toString() || ''}); + message += `${fileName} (${fileSize})`; - if (typeof response !== 'string') { - throw new Error('Error getting file size'); + if (filePath !== selectedFilePath[selectedFilePath.length - 1]) { + message += ', '; + } } - - setFileSize(response); + setMessage(message); + props.setFilePath(selectedFilePath); + } else { + const fileName: string = getFileNameFromPath(selectedFilePath); + const fileSize: string = await invoke('get_size_of_file', {filePath: selectedFilePath}); + setMessage(`${fileName} (${fileSize})`); + props.setFilePath([selectedFilePath]); } } catch (error) { - toast.error(`Error opening file`); + log_error(error); } }; @@ -62,7 +69,7 @@ const FileUpload: React.FC = (props: FileUploadProps) => {
path.split("\\").toString().split('/').pop() || ''; +export const getFileNameFromPath = (path: string) => { + if (!path) return ''; + if (path.includes('/')) { + return path.split('/').pop() || ''; + } + if (path.includes('\\')) { + return path.split('\\').pop() || ''; + } + return path; +}; // Return the normalized table name from a path From f5e84c49a71fe3ff504d28fad1fee08ddbca8de6 Mon Sep 17 00:00:00 2001 From: Maxime Colliat Date: Thu, 3 Apr 2025 13:45:16 +0200 Subject: [PATCH 3/6] Multiple tables to insert + unit test --- src-tauri/src/fileflow/action/actions.rs | 143 +++++--- ...atabase_actions.rs => database_command.rs} | 2 +- .../src/fileflow/action/insertion_mode.rs | 35 +- src-tauri/src/fileflow/action/mod.rs | 2 +- .../sql.rs => database/database_actions.rs} | 307 +++++----------- src-tauri/src/fileflow/database/mod.rs | 2 + .../src/fileflow/database/sql_builder.rs | 332 ++++++++++++++++++ src-tauri/src/fileflow/stuct/insert_config.rs | 2 +- src-tauri/src/fileflow/utils/csv_utils.rs | 24 ++ src-tauri/src/fileflow/utils/fileflowlib.rs | 53 --- src-tauri/src/fileflow/utils/mod.rs | 3 +- .../src/fileflow/utils/string_formater.rs | 45 +++ src-tauri/src/main.rs | 4 +- src-tauri/src/tests/action_test.rs | 2 +- .../{standard_test.rs => csv_utils_test.rs} | 23 +- src-tauri/src/tests/database_test.rs | 198 +---------- src-tauri/src/tests/mod.rs | 8 +- src-tauri/src/tests/string_formater_test.rs | 56 +++ src-tauri/src/tests/struct_test.rs | 4 +- .../src/tests/{utils.rs => utils_tests.rs} | 0 .../load/insert/ButtonGroupAction.tsx | 19 +- .../fileflowui/load/insert/Insert.tsx | 28 +- src/components/ui/checkbox.tsx | 27 ++ 23 files changed, 724 insertions(+), 595 deletions(-) rename src-tauri/src/fileflow/action/{database_actions.rs => database_command.rs} (98%) rename src-tauri/src/fileflow/{utils/sql.rs => database/database_actions.rs} (54%) create mode 100644 src-tauri/src/fileflow/database/sql_builder.rs create mode 100644 src-tauri/src/fileflow/utils/csv_utils.rs create mode 100644 src-tauri/src/fileflow/utils/string_formater.rs rename src-tauri/src/tests/{standard_test.rs => csv_utils_test.rs} (52%) create mode 100644 src-tauri/src/tests/string_formater_test.rs rename src-tauri/src/tests/{utils.rs => utils_tests.rs} (100%) create mode 100644 src/components/ui/checkbox.tsx diff --git a/src-tauri/src/fileflow/action/actions.rs b/src-tauri/src/fileflow/action/actions.rs index 32976bf..def9ab8 100644 --- a/src-tauri/src/fileflow/action/actions.rs +++ b/src-tauri/src/fileflow/action/actions.rs @@ -4,9 +4,9 @@ use crate::fileflow::enumeration::insertion_type::InsertionType; use crate::fileflow::stuct::insert_config::InsertConfig; use crate::fileflow::stuct::save_config::SaveConfig; use crate::fileflow::utils::constants::DATABASE_CONFIG_FILE; -use crate::fileflow::utils::fileflowlib::{ - find_separator, get_all_saved_configs, get_formated_column_names, read_first_line, save_config, -}; +use crate::fileflow::utils::csv_utils::{find_separator, read_first_line}; +use crate::fileflow::utils::fileflowlib::{get_all_saved_configs, save_config}; +use crate::fileflow::utils::string_formater::{get_formated_column_names, sanitize_column}; use csv::{Reader, ReaderBuilder}; use std::fs::{File, Metadata}; use std::sync::Arc; @@ -20,57 +20,88 @@ pub struct DatabaseState(pub Mutex>); pub async fn insert_csv_data( state: State<'_, Arc>, csv: InsertConfig, -) -> Result { +) -> Result { let conn_guard = state.0.lock().await; if conn_guard.is_none() { - eprint!("Error: Connection is not established"); - return Err(false); + return Err("Error: Connection is not established".into()); + } + + let tables_names: Vec = csv.table_name.split(',').map(|s| s.trim().into()).collect(); // Split the table names by comma + if tables_names.len() != csv.files_path.len() { + return Err("Error: The number of table names must match the number of files".into()); } let connection: &Connection = conn_guard.as_ref().unwrap(); - let file: File = File::open(&csv.file_path).expect("Failed to open file"); - let first_line: String = read_first_line(&csv.file_path).expect("Failed to read first line"); - let separator: char = find_separator(&first_line).expect("Failed to find separator"); - let start: Instant = Instant::now(); - - let final_columns_name: Vec = get_formated_column_names( - first_line - .split(separator) - .map(|s| s.replace("\"", "")) - .collect(), - ); - - let mut reader: Reader = ReaderBuilder::new() - .delimiter(separator as u8) - .has_headers(true) - .from_reader(file); - - let line_count: u32 = match csv.mode { - InsertionType::Fast => fast_insert( - connection, - &mut reader, - &final_columns_name, - &csv.table_name, - &csv.db_driver, - ) - .await - .map_err(|_| false)?, - InsertionType::Optimized => optimized_insert( - connection, - &mut reader, - &final_columns_name, - &csv.table_name, - &csv.db_driver, - ) - .await - .map_err(|_| false)?, - }; + let mut table_inserted: u16 = 0; // Counter for the number of tables inserted + let mut total_lines: u64 = 0; // Counter for the total number of lines inserted + let start: Instant = Instant::now(); // Timer for the insertion process + + for (index, file_path) in csv.files_path.iter().enumerate() { + let file: File = File::open(file_path).expect("Failed to open file"); + let first_line: String = read_first_line(file_path).expect("Failed to read first line"); // Read the first line of the file to detect the separator + let separator: char = find_separator(&first_line).expect("Failed to find separator"); // Separator detection of the file + + let final_columns_name: Vec = get_formated_column_names( + &first_line + .split(separator) + .map(|s| sanitize_column(s)) + .collect::>(), + ); + + let mut reader: Reader = ReaderBuilder::new() + .delimiter(u8::try_from(separator).unwrap()) + .has_headers(true) + .from_reader(file); + + match csv.mode { + InsertionType::Fast => { + match fast_insert( + connection, + &mut reader, + &final_columns_name, + &tables_names[index], + &csv.db_driver, + ) + .await + { + Ok(lines) => { + total_lines += u64::from(lines); + table_inserted += 1; + } + Err(_) => { + eprint!("Error: Failed to insert data"); + continue; + } + } + } + InsertionType::Optimized => { + match optimized_insert( + connection, + &mut reader, + &final_columns_name, + &tables_names[index], + &csv.db_driver, + ) + .await + { + Ok(lines) => { + total_lines += u64::from(lines); + table_inserted += 1; + } + Err(_) => { + eprint!("Error: Failed to insert data"); + continue; + } + } + } + }; + } Ok(format!( - "Data inserted successfully in {:.2?}, {line_count} rows inserted in table {}", + "Inserted {table_inserted} out of {} for a total of {total_lines} lines in {:?} seconds", + csv.files_path.len(), start.elapsed(), - csv.table_name )) } @@ -85,10 +116,9 @@ pub async fn save_database_config(save: SaveConfig) -> Result { } existing_configs.push(save); - match save_config(&existing_configs, DATABASE_CONFIG_FILE) { - Ok(_) => Ok(true), - Err(_) => Err(false), - } + save_config(&existing_configs, DATABASE_CONFIG_FILE) + .map(|_| true) + .map_err(|_| false) } #[command] @@ -96,8 +126,7 @@ pub async fn get_all_database_configs_name() -> Result { let configs: Vec = get_all_saved_configs(DATABASE_CONFIG_FILE); // Get all saved configs let configs_names: Vec = configs.iter().map(|c| c.config_name.clone()).collect(); // Get only the names let configs_json: String = match serde_json::to_string(&configs_names) { - // Convert to json string - Ok(json) => json, + Ok(json) => json, // Convert to json string Err(_) => return Err(false), }; Ok(configs_json) @@ -110,8 +139,7 @@ pub async fn load_database_config_by_name(name: String) -> Result // Find the config with the given name if config.config_name == name { return match serde_json::to_string(&config) { - // Convert to json string - Ok(json) => Ok(json), + Ok(json) => Ok(json), // Convert to json string Err(_) => Err(false), }; } @@ -135,13 +163,12 @@ pub async fn delete_database_config(name: String) -> Result { } if !found { - Err(false)?; + return Err(false); } - match save_config(&new_configs, DATABASE_CONFIG_FILE) { - Ok(_) => Ok(true), - Err(_) => Err(false), - } + save_config(&new_configs, DATABASE_CONFIG_FILE) + .map(|_| true) + .map_err(|_| false) } #[command] diff --git a/src-tauri/src/fileflow/action/database_actions.rs b/src-tauri/src/fileflow/action/database_command.rs similarity index 98% rename from src-tauri/src/fileflow/action/database_actions.rs rename to src-tauri/src/fileflow/action/database_command.rs index bab1a9b..b2a42e9 100644 --- a/src-tauri/src/fileflow/action/database_actions.rs +++ b/src-tauri/src/fileflow/action/database_command.rs @@ -3,7 +3,7 @@ use crate::fileflow::database::connection::{Connection, QueryResult}; use crate::fileflow::stuct::combo_item::ComboItem; use crate::fileflow::stuct::db_config::DbConfig; use crate::fileflow::stuct::download_config::DownloadConfig; -use crate::fileflow::utils::sql::{build_query_all_tables, export_table}; +use crate::fileflow::database::sql_builder::{build_query_all_tables, export_table}; use serde_json::{json, Value}; use sqlx::Row; use std::sync::Arc; diff --git a/src-tauri/src/fileflow/action/insertion_mode.rs b/src-tauri/src/fileflow/action/insertion_mode.rs index b0cf01f..9120c8b 100644 --- a/src-tauri/src/fileflow/action/insertion_mode.rs +++ b/src-tauri/src/fileflow/action/insertion_mode.rs @@ -1,10 +1,12 @@ use crate::fileflow::database::connection::Connection; -use crate::fileflow::enumeration::database_engine::DatabaseEngine; -use crate::fileflow::utils::fileflowlib::{escaped_values, sanitize_value}; -use crate::fileflow::utils::sql::{ +use crate::fileflow::database::database_actions::{ batch_insert, create_and_copy_final_table, drop_table_if_exists, execute_query, - get_create_statement, get_insert_into_statement, }; +use crate::fileflow::database::sql_builder::{ + build_create_table_sql, build_prepared_statement_sql, +}; +use crate::fileflow::enumeration::database_engine::DatabaseEngine; +use crate::fileflow::utils::string_formater::{escaped_values, sanitize_value}; use csv::{Reader, StringRecord}; use std::collections::HashMap; use std::fs::File; @@ -30,8 +32,7 @@ pub async fn optimized_insert( // Create the temporary table let create_temp_table_query: String = - get_create_statement(db_driver, temporary_table_name, final_columns_name) - .expect("Failed to create temporary table query"); + build_create_table_sql(db_driver, temporary_table_name, final_columns_name); execute_query( connection, @@ -43,15 +44,14 @@ pub async fn optimized_insert( // Initialize variables const MAX_BATCH_SIZE: usize = 4000; - let mut batch: Vec = Vec::with_capacity(MAX_BATCH_SIZE); - let mut columns_size_map: HashMap<&str, usize> = - initialize_columns_size_map(final_columns_name); - let insert_query_base: String = get_insert_into_statement( + let insert_query_base: String = build_prepared_statement_sql( db_driver, temporary_table_name, &final_columns_name.join(", "), - ) - .expect("Failed to insert into temporary table"); + ); + let mut batch: Vec = Vec::with_capacity(MAX_BATCH_SIZE); + let mut columns_size_map: HashMap<&str, usize> = + initialize_columns_size_map(final_columns_name); let mut line_count: u32 = 0; // Read and process records from the CSV @@ -172,11 +172,14 @@ pub async fn fast_insert( return Err(err); } + let build_create_table_statement: String = + build_create_table_sql(db_driver, final_table_name, final_columns_name); + // Create the table if let Err(err) = execute_query( connection, - get_create_statement(db_driver, final_table_name, final_columns_name)?.as_str(), - "Failed to create table {final_table_name}", + &build_create_table_statement, + "Failed to create table", ) .await { @@ -190,8 +193,8 @@ pub async fn fast_insert( let mut batch: Vec = Vec::with_capacity(MAX_BATCH_SIZE); // Prepare the insert query - let insert_query_base: &str = &get_insert_into_statement(db_driver, final_table_name, columns) - .expect("Failed to insert batch data"); + let insert_query_base: &str = + &build_prepared_statement_sql(db_driver, final_table_name, columns); for result in reader.records() { let record: StringRecord = result.unwrap(); diff --git a/src-tauri/src/fileflow/action/mod.rs b/src-tauri/src/fileflow/action/mod.rs index f693f22..5e92c1b 100644 --- a/src-tauri/src/fileflow/action/mod.rs +++ b/src-tauri/src/fileflow/action/mod.rs @@ -1,3 +1,3 @@ pub mod actions; -pub mod database_actions; +pub mod database_command; pub mod insertion_mode; diff --git a/src-tauri/src/fileflow/utils/sql.rs b/src-tauri/src/fileflow/database/database_actions.rs similarity index 54% rename from src-tauri/src/fileflow/utils/sql.rs rename to src-tauri/src/fileflow/database/database_actions.rs index 95b7ab1..6b062c7 100644 --- a/src-tauri/src/fileflow/utils/sql.rs +++ b/src-tauri/src/fileflow/database/database_actions.rs @@ -1,233 +1,12 @@ +use std::collections::HashMap; +use std::fs::File; +use csv::{Writer, WriterBuilder}; +use sqlx::{Column, Row}; use crate::fileflow::database::connection::{Connection, QueryResult}; +use crate::fileflow::database::sql_builder::{build_copy_table_sql, build_create_with_fixed_size_sql, build_drop_statement_sql}; use crate::fileflow::enumeration::database_engine::DatabaseEngine; use crate::fileflow::enumeration::separator::SeparatorType; use crate::fileflow::stuct::download_config::DownloadConfig; -use csv::{Writer, WriterBuilder}; -use sqlx::{Column, Row}; -use std::collections::HashMap; -use std::fs::File; - -/// This function is used to generate the DROP TABLE statement for different database drivers. -pub fn get_drop_statement( - db_driver: &DatabaseEngine, - final_table_name: &str, -) -> Result { - match db_driver { - DatabaseEngine::SQLite | DatabaseEngine::Postgres => { - Ok(format!("DROP TABLE IF EXISTS \"{final_table_name}\"")) - } - DatabaseEngine::MariaDB | DatabaseEngine::MySQL => { - Ok(format!("DROP TABLE IF EXISTS `{final_table_name}`")) - } - } -} - -/// This function is used to generate the INSERT INTO statement for different database drivers. -pub fn get_insert_into_statement( - db_driver: &DatabaseEngine, - final_table_name: &str, - columns: &str, -) -> Result { - let quote: char = match db_driver { - DatabaseEngine::SQLite | DatabaseEngine::Postgres => '\"', - DatabaseEngine::MariaDB | DatabaseEngine::MySQL => '`', - }; - - Ok(format!( - "INSERT INTO {quote}{final_table_name}{quote} ({columns}) VALUES " - )) -} - -/// This function is used to generate the COPY statement for different database drivers. -pub fn get_copy_temp_to_final_table( - db_driver: &DatabaseEngine, - temporary_table_name: &str, - final_table_name: &str, -) -> Result { - let quote: char = match db_driver { - DatabaseEngine::SQLite | DatabaseEngine::Postgres => '\"', - DatabaseEngine::MySQL | DatabaseEngine::MariaDB => '`', - }; - Ok(format!( - "INSERT INTO {quote}{final_table_name}{quote} SELECT * FROM {quote}{temporary_table_name}{quote}" - )) -} - -/// This function is used to generate the CREATE TABLE statement with fixed size for each column for different database drivers. -pub fn get_create_statement_with_fixed_size( - driver: &DatabaseEngine, - final_table_name: &str, - map_column_max_length: &HashMap<&str, usize>, - snake_case_headers: &[String], -) -> Result { - // Constants - const MAX_VARCHAR_LENGTH: usize = 255; - const TEXT_TYPE: &str = "TEXT"; - const VARCHAR_TYPE: &str = "VARCHAR"; - - // Determine database-specific formatting - let quote = match driver { - DatabaseEngine::SQLite | DatabaseEngine::Postgres => '"', - DatabaseEngine::MySQL | DatabaseEngine::MariaDB => '`', - }; - - let mut columns: Vec = Vec::with_capacity(snake_case_headers.len()); - let mut total_length: usize = 0; - - // Build column definitions - for header in snake_case_headers { - let max_length = map_column_max_length - .get(header.as_str()) - .copied() - .unwrap_or(MAX_VARCHAR_LENGTH); - - // Determine column type - let type_str = if max_length <= MAX_VARCHAR_LENGTH { - format!("{}({})", VARCHAR_TYPE, max_length) - } else { - TEXT_TYPE.to_string() - }; - - // Format column definition - let column = format!("{0}{1}{0} {2}", quote, header, type_str); - total_length += column.len(); - columns.push(column); - } - - // Pre-calculate final string capacity - let table_quoted: String = format!("{0}{1}{0}", quote, final_table_name); - let mut result: String = String::with_capacity( - 15 + // "CREATE TABLE ();" - table_quoted.len() + - total_length + - columns.len() * 2, // ", " separators - ); - - // Build the final SQL statement - result.push_str("CREATE TABLE "); - result.push_str(&table_quoted); - result.push_str(" ("); - result.push_str(&columns.join(", ")); - result.push_str(");"); - - Ok(result) -} - -/// This function is used to generate the CREATE TABLE statement for different database drivers. -pub fn get_create_statement( - driver: &DatabaseEngine, - final_table_name: &str, - snake_case_headers: &[String], -) -> Result { - match driver { - DatabaseEngine::SQLite | DatabaseEngine::Postgres => Ok(format!( - "CREATE TABLE \"{final_table_name}\" ({})", - snake_case_headers - .iter() - .map(|h| format!("{h} TEXT")) - .collect::>() - .join(", ") - )), - DatabaseEngine::MariaDB | DatabaseEngine::MySQL => Ok(format!( - "CREATE TABLE `{final_table_name}` ({})", - snake_case_headers - .iter() - .map(|h| format!("{h} TEXT")) - .collect::>() - .join(", ") - )), - } -} - -/// Helper function to drop a table if it exists -pub async fn drop_table_if_exists( - connection: &Connection, - db_driver: &DatabaseEngine, - table_name: &str, -) -> Result<(), String> { - let drop_query: &str = &get_drop_statement(db_driver, table_name)?; - execute_query( - connection, - drop_query, - &format!("Failed to drop table '{table_name}'"), - ) - .await -} - -/// Helper function to execute a query and handle errors -pub async fn execute_query( - connection: &Connection, - query: &str, - context: &str, -) -> Result<(), String> { - connection - .query(query) - .await - .map_err(|err| format!("{context}: {err}")) -} - -/// Helper function to batch-insert records into a table -pub async fn batch_insert( - connection: &Connection, - insert_query_base: &str, - batch: &[String], - context: &str, -) -> Result<(), String> { - if batch.is_empty() { - return Ok(()); - } - let insert_query: String = format!("{insert_query_base}{}", batch.join(", ")); - execute_query(connection, &insert_query, context).await -} - -/// Create the final table and copy data from the temporary table -pub async fn create_and_copy_final_table( - connection: &Connection, - db_driver: &DatabaseEngine, - final_table_name: &str, - temporary_table_name: &str, - columns_size_map: &HashMap<&str, usize>, - final_columns_name: &[String], -) -> Result<(), String> { - let create_final_table_query: String = get_create_statement_with_fixed_size( - db_driver, - final_table_name, - columns_size_map, - final_columns_name, - )?; - execute_query( - connection, - &create_final_table_query, - "Failed to create final table", - ) - .await?; - - let copy_data_query: String = - get_copy_temp_to_final_table(db_driver, temporary_table_name, final_table_name)?; - - execute_query( - connection, - ©_data_query, - "Failed to copy data to final table", - ) - .await?; - - Ok(()) -} - -/// Get the query to fetch all tables from the database for different drivers -pub fn build_query_all_tables(driver: &DatabaseEngine, schema: &str) -> String { - let query: String = match driver { - &DatabaseEngine::MySQL | &DatabaseEngine::MariaDB => format!( - "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = '{schema}';" - ), - &DatabaseEngine::Postgres => { - "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'public';".into() - } - &DatabaseEngine::SQLite => "SELECT name FROM sqlite_master WHERE type='table';".into(), - }; - query -} /// Exports a table’s data into a CSV file. It uses offset/LIMIT pagination to retrieve data in batches pub async fn export_table( @@ -349,3 +128,79 @@ pub async fn export_table( wtr.flush().expect("Failed to flush CSV writer"); Ok(()) } + +/// Helper function to drop a table if it exists +pub async fn drop_table_if_exists( + connection: &Connection, + db_driver: &DatabaseEngine, + table_name: &str, +) -> Result<(), String> { + let drop_query: &str = &build_drop_statement_sql(db_driver, table_name)?; + execute_query( + connection, + drop_query, + &format!("Failed to drop table '{table_name}'"), + ) + .await +} + +/// Helper function to execute a query and handle errors +pub async fn execute_query( + connection: &Connection, + query: &str, + context: &str, +) -> Result<(), String> { + connection + .query(query) + .await + .map_err(|err| format!("{context}: {err}")) +} + +/// Helper function to batch-insert records into a table +pub async fn batch_insert( + connection: &Connection, + insert_query_base: &str, + batch: &[String], + context: &str, +) -> Result<(), String> { + if batch.is_empty() { + return Ok(()); + } + let insert_query: String = format!("{insert_query_base}{}", batch.join(", ")); + execute_query(connection, &insert_query, context).await +} + +/// Create the final table and copy data from the temporary table +pub async fn create_and_copy_final_table( + connection: &Connection, + db_driver: &DatabaseEngine, + final_table_name: &str, + temporary_table_name: &str, + columns_size_map: &HashMap<&str, usize>, + final_columns_name: &[String], +) -> Result<(), String> { + let create_final_table_query: String = build_create_with_fixed_size_sql( + db_driver, + final_table_name, + columns_size_map, + final_columns_name, + ); + execute_query( + connection, + &create_final_table_query, + "Failed to create final table", + ) + .await?; + + let copy_data_query: String = + build_copy_table_sql(db_driver, temporary_table_name, final_table_name); + + execute_query( + connection, + ©_data_query, + "Failed to copy data to final table", + ) + .await?; + + Ok(()) +} diff --git a/src-tauri/src/fileflow/database/mod.rs b/src-tauri/src/fileflow/database/mod.rs index b3b606b..ea950e6 100644 --- a/src-tauri/src/fileflow/database/mod.rs +++ b/src-tauri/src/fileflow/database/mod.rs @@ -1 +1,3 @@ pub mod connection; +pub mod sql_builder; +pub mod database_actions; diff --git a/src-tauri/src/fileflow/database/sql_builder.rs b/src-tauri/src/fileflow/database/sql_builder.rs new file mode 100644 index 0000000..01e4722 --- /dev/null +++ b/src-tauri/src/fileflow/database/sql_builder.rs @@ -0,0 +1,332 @@ +use crate::fileflow::enumeration::database_engine::DatabaseEngine; +use sqlx::Row; +use std::collections::HashMap; + +/// This function is used to generate the DROP TABLE statement for different database drivers. +pub fn build_drop_statement_sql( + db_driver: &DatabaseEngine, + final_table_name: &str, +) -> Result { + match db_driver { + DatabaseEngine::SQLite | DatabaseEngine::Postgres => { + Ok(format!("DROP TABLE IF EXISTS \"{final_table_name}\"")) + } + DatabaseEngine::MariaDB | DatabaseEngine::MySQL => { + Ok(format!("DROP TABLE IF EXISTS `{final_table_name}`")) + } + } +} + +/// This function is used to generate the INSERT INTO statement for different database drivers. +pub fn build_prepared_statement_sql( + db_driver: &DatabaseEngine, + final_table_name: &str, + columns: &str, +) -> String { + let quote: char = match db_driver { + DatabaseEngine::SQLite | DatabaseEngine::Postgres => '\"', + DatabaseEngine::MariaDB | DatabaseEngine::MySQL => '`', + }; + format!("INSERT INTO {quote}{final_table_name}{quote} ({columns}) VALUES ") +} + +/// This function is used to generate the COPY statement for different database drivers. +pub fn build_copy_table_sql( + db_driver: &DatabaseEngine, + temporary_table_name: &str, + final_table_name: &str, +) -> String { + let quote: char = match db_driver { + DatabaseEngine::SQLite | DatabaseEngine::Postgres => '\"', + DatabaseEngine::MySQL | DatabaseEngine::MariaDB => '`', + }; + format!( + "INSERT INTO {quote}{final_table_name}{quote} SELECT * FROM {quote}{temporary_table_name}{quote}" + ) +} + +/// This function is used to generate the CREATE TABLE statement with fixed size for each column for different database drivers. +pub fn build_create_with_fixed_size_sql( + driver: &DatabaseEngine, + final_table_name: &str, + map_column_max_length: &HashMap<&str, usize>, + snake_case_headers: &[String], +) -> String { + // Constants + const MAX_VARCHAR_LENGTH: usize = 255; + const TEXT_TYPE: &str = "TEXT"; + const VARCHAR_TYPE: &str = "VARCHAR"; + + // Determine database-specific formatting + let quote: char = match driver { + DatabaseEngine::SQLite | DatabaseEngine::Postgres => '"', + DatabaseEngine::MySQL | DatabaseEngine::MariaDB => '`', + }; + + let mut columns: Vec = Vec::with_capacity(snake_case_headers.len()); + let mut total_length: usize = 0; + + // Build column definitions + for header in snake_case_headers { + let max_length = map_column_max_length + .get(header.as_str()) + .copied() + .unwrap_or(MAX_VARCHAR_LENGTH); + + // Determine column type + let type_str: String = if max_length <= MAX_VARCHAR_LENGTH { + format!("{VARCHAR_TYPE}({max_length})") // VARCHAR(n) + } else { + TEXT_TYPE.into() + }; + + // Format column definition + let column: String = format!("{0}{1}{0} {2}", quote, header, type_str); + total_length += column.len(); + columns.push(column); + } + + // Pre-calculate final string capacity + let table_quoted: String = format!("{0}{1}{0}", quote, final_table_name); + let mut result: String = String::with_capacity( + 15 + // "CREATE TABLE ();" + table_quoted.len() + + total_length + + columns.len() * 2, // ", " separators + ); + + // Build the final SQL statement + result.push_str("CREATE TABLE "); + result.push_str(&table_quoted); + result.push_str(" ("); + result.push_str(&columns.join(", ")); + result.push_str(");"); + + result +} + +/// This function is used to generate the CREATE TABLE statement for different database drivers. +pub fn build_create_table_sql( + driver: &DatabaseEngine, + final_table_name: &str, + snake_case_headers: &[String], +) -> String { + match driver { + DatabaseEngine::SQLite | DatabaseEngine::Postgres => format!( + "CREATE TABLE \"{final_table_name}\" ({})", + snake_case_headers + .iter() + .map(|h| format!("{h} TEXT")) + .collect::>() + .join(", ") + ), + DatabaseEngine::MariaDB | DatabaseEngine::MySQL => format!( + "CREATE TABLE `{final_table_name}` ({})", + snake_case_headers + .iter() + .map(|h| format!("`{h}` TEXT")) + .collect::>() + .join(", ") + ), + } +} + +/// Get the query to fetch all tables from the database for different drivers +pub fn build_query_all_tables(driver: &DatabaseEngine, schema: &str) -> String { + let query: String = match driver { + &DatabaseEngine::MySQL | &DatabaseEngine::MariaDB => format!( + "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = '{schema}';" + ), + &DatabaseEngine::Postgres => { + "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'public';".into() + } + &DatabaseEngine::SQLite => "SELECT name FROM sqlite_master WHERE type='table';".into(), + }; + query +} + +#[cfg(test)] +mod test { + use crate::fileflow::database::sql_builder::{ + build_create_table_sql, build_create_with_fixed_size_sql, build_drop_statement_sql, + build_prepared_statement_sql, + }; + use crate::fileflow::enumeration::database_engine::DatabaseEngine; + use std::collections::HashMap; + + #[tokio::test] + async fn test_get_drop_statement() { + assert_eq!( + build_drop_statement_sql(&DatabaseEngine::SQLite, "table_name").unwrap(), + "DROP TABLE IF EXISTS \"table_name\"" + ); + assert_eq!( + build_drop_statement_sql(&DatabaseEngine::MySQL, "table_name").unwrap(), + "DROP TABLE IF EXISTS `table_name`" + ); + assert_eq!( + build_drop_statement_sql(&DatabaseEngine::Postgres, "table_name").unwrap(), + "DROP TABLE IF EXISTS \"table_name\"" + ); + assert_eq!( + build_drop_statement_sql(&DatabaseEngine::SQLite, "").unwrap(), + "DROP TABLE IF EXISTS \"\"" + ); + assert_eq!( + build_drop_statement_sql(&DatabaseEngine::MySQL, "").unwrap(), + "DROP TABLE IF EXISTS ``" + ); + assert_eq!( + build_drop_statement_sql(&DatabaseEngine::Postgres, "").unwrap(), + "DROP TABLE IF EXISTS \"\"" + ); + } + + #[tokio::test] + async fn test_get_insert_into_statement() { + assert_eq!( + build_prepared_statement_sql(&DatabaseEngine::SQLite, "table_name", "columns"), + "INSERT INTO \"table_name\" (columns) VALUES " + ); + assert_eq!( + build_prepared_statement_sql(&DatabaseEngine::MySQL, "table_name", "columns"), + "INSERT INTO `table_name` (columns) VALUES " + ); + assert_eq!( + build_prepared_statement_sql(&DatabaseEngine::Postgres, "table_name", "columns"), + "INSERT INTO \"table_name\" (columns) VALUES " + ); + + assert_eq!( + build_prepared_statement_sql(&DatabaseEngine::SQLite, "table_name", ""), + "INSERT INTO \"table_name\" () VALUES " + ); + assert_eq!( + build_prepared_statement_sql(&DatabaseEngine::MySQL, "table_name", ""), + "INSERT INTO `table_name` () VALUES " + ); + assert_eq!( + build_prepared_statement_sql(&DatabaseEngine::Postgres, "table_name", ""), + "INSERT INTO \"table_name\" () VALUES " + ); + + assert_eq!( + build_prepared_statement_sql(&DatabaseEngine::SQLite, "table_name", "header1, header2"), + "INSERT INTO \"table_name\" (header1, header2) VALUES " + ); + assert_eq!( + build_prepared_statement_sql(&DatabaseEngine::MySQL, "table_name", "header1, header2"), + "INSERT INTO `table_name` (`header1`, header2) VALUES " + ); + assert_eq!( + build_prepared_statement_sql( + &DatabaseEngine::Postgres, + "table_name", + "header1, header2" + ), + "INSERT INTO \"table_name\" (header1, header2) VALUES " + ); + } + + #[tokio::test] + async fn test_get_create_statement() { + let snake_case_headers: Vec = vec!["header1".into(), "header2".into()]; + assert_eq!( + build_create_table_sql(&DatabaseEngine::SQLite, "table_name", &snake_case_headers), + "CREATE TABLE \"table_name\" (header1 TEXT, header2 TEXT)" + ); + assert_eq!( + build_create_table_sql(&DatabaseEngine::MySQL, "table_name", &snake_case_headers), + "CREATE TABLE `table_name` (`header1` TEXT, `header2` TEXT)" + ); + assert_eq!( + build_create_table_sql(&DatabaseEngine::Postgres, "table_name", &snake_case_headers), + "CREATE TABLE \"table_name\" (header1 TEXT, header2 TEXT)" + ); + + let snake_case_headers: Vec = vec!["header1".into()]; + assert_eq!( + build_create_table_sql(&DatabaseEngine::SQLite, "table_name", &snake_case_headers), + "CREATE TABLE \"table_name\" (header1 TEXT)" + ); + assert_eq!( + build_create_table_sql(&DatabaseEngine::MySQL, "table_name", &snake_case_headers), + "CREATE TABLE `table_name` (`header1` TEXT)" + ); + assert_eq!( + build_create_table_sql(&DatabaseEngine::Postgres, "table_name", &snake_case_headers), + "CREATE TABLE \"table_name\" (header1 TEXT)" + ); + } + + #[tokio::test] + async fn test_get_create_statement_with_fixed_size() { + const FINAL_TABLE_NAME: &str = "test_table"; + + let snake_case_headers: Vec = vec!["header1".into(), "header2".into()]; + let map_max_length: HashMap<&str, usize> = + snake_case_headers.iter().map(|h| (h.as_str(), 0)).collect(); + + let mut db_driver: HashMap<&DatabaseEngine, &str> = HashMap::new(); + db_driver.insert( + &DatabaseEngine::Postgres, + "CREATE TABLE \"test_table\" (\"header1\" VARCHAR(0), \"header2\" VARCHAR(0));", + ); + db_driver.insert( + &DatabaseEngine::MySQL, + "CREATE TABLE `test_table` (`header1` VARCHAR(0), `header2` VARCHAR(0));", + ); + db_driver.insert( + &DatabaseEngine::MariaDB, + "CREATE TABLE `test_table` (`header1` VARCHAR(0), `header2` VARCHAR(0));", + ); + db_driver.insert( + &DatabaseEngine::SQLite, + "CREATE TABLE \"test_table\" (\"header1\" VARCHAR(0), \"header2\" VARCHAR(0));", + ); + + let final_columns: Vec = vec!["header1".into(), "header2".into()]; + + for (driver, expected) in db_driver { + let result: String = build_create_with_fixed_size_sql( + driver, + FINAL_TABLE_NAME, + &map_max_length, + &final_columns, + ); + assert_eq!(result, expected); + } + + let map_max_length: HashMap<&str, usize> = snake_case_headers + .iter() + .map(|h| (h.as_str(), 10)) + .collect(); + let mut db_driver: HashMap<&DatabaseEngine, &str> = HashMap::new(); + db_driver.insert( + &DatabaseEngine::Postgres, + "CREATE TABLE \"test_table\" (\"header1\" VARCHAR(10), \"header2\" VARCHAR(10));", + ); + db_driver.insert( + &DatabaseEngine::MySQL, + "CREATE TABLE `test_table` (`header1` VARCHAR(10), `header2` VARCHAR(10));", + ); + db_driver.insert( + &DatabaseEngine::MariaDB, + "CREATE TABLE `test_table` (`header1` VARCHAR(10), `header2` VARCHAR(10));", + ); + db_driver.insert( + &DatabaseEngine::SQLite, + "CREATE TABLE \"test_table\" (\"header1\" VARCHAR(10), \"header2\" VARCHAR(10));", + ); + + for (driver, expected) in db_driver { + let result: String = build_create_with_fixed_size_sql( + driver, + FINAL_TABLE_NAME, + &map_max_length, + &final_columns, + ); + assert_eq!(result, expected); + } + } +} diff --git a/src-tauri/src/fileflow/stuct/insert_config.rs b/src-tauri/src/fileflow/stuct/insert_config.rs index 1c38979..54bdbd2 100644 --- a/src-tauri/src/fileflow/stuct/insert_config.rs +++ b/src-tauri/src/fileflow/stuct/insert_config.rs @@ -4,7 +4,7 @@ use serde::Deserialize; #[derive(Deserialize)] pub struct InsertConfig { - pub file_path: String, + pub files_path: Vec, pub table_name: String, pub mode: InsertionType, pub db_driver: DatabaseEngine, diff --git a/src-tauri/src/fileflow/utils/csv_utils.rs b/src-tauri/src/fileflow/utils/csv_utils.rs new file mode 100644 index 0000000..94b8246 --- /dev/null +++ b/src-tauri/src/fileflow/utils/csv_utils.rs @@ -0,0 +1,24 @@ +use std::fs::File; +use std::io; +use std::io::{BufRead, BufReader}; + +/// This function is used to detect the separator from a string. +pub fn find_separator(line: &str) -> Result { + const POSSIBLE_SEPARATORS: [char; 6] = [',', ';', '\t', '|', ' ', '\0']; + for sep in POSSIBLE_SEPARATORS.iter() { + if line.contains(*sep) { + return Ok(*sep); + } + } + Err("Could not detect a valid separator".into()) +} + +/// Read the first line of a file +pub fn read_first_line(file_path: &str) -> io::Result { + let file: File = File::open(file_path).expect("Could not open file"); + let reader: BufReader = BufReader::new(file); + if let Some(line) = reader.lines().next() { + return line; + } + Err(io::Error::new(io::ErrorKind::NotFound, "File is empty")) +} diff --git a/src-tauri/src/fileflow/utils/fileflowlib.rs b/src-tauri/src/fileflow/utils/fileflowlib.rs index 51fee09..65325b0 100644 --- a/src-tauri/src/fileflow/utils/fileflowlib.rs +++ b/src-tauri/src/fileflow/utils/fileflowlib.rs @@ -1,61 +1,8 @@ use crate::fileflow::stuct::save_config::SaveConfig; -use csv::StringRecord; use std::fs::{File, OpenOptions}; use std::io; -use std::io::{BufRead, BufReader}; use std::path::PathBuf; -/// This function is used to generate the column names for a CSV file. -pub fn get_formated_column_names(headers: Vec) -> Vec { - const COLUMN_PREFIX: &str = "column_"; - - let mut headers: Vec = headers; - for (i, item) in headers.iter_mut().enumerate() { - if item.trim().is_empty() { - *item = format!("{COLUMN_PREFIX}{}", i + 1); - } - } - headers - .iter() - .map(|h| h.to_lowercase().replace(' ', "_")) - .collect() -} - -/// This function is used to detect the separator from a string. -pub fn find_separator(line: &str) -> Result { - const POSSIBLE_SEPARATORS: [char; 6] = [',', ';', '\t', '|', ' ', '\0']; - for sep in POSSIBLE_SEPARATORS.iter() { - if line.contains(*sep) { - return Ok(*sep); - } - } - Err("Could not detect a valid separator".into()) -} - -/// Sanitize a value for safe insertion into the database -pub fn sanitize_value(value: &str) -> String { - value.trim().replace("'", "''").replace("\\", "\\\\") -} - -/// Read the first line of a file -pub fn read_first_line(file_path: &str) -> io::Result { - let file: File = File::open(file_path).expect("Could not open file"); - let reader: BufReader = BufReader::new(file); - if let Some(line) = reader.lines().next() { - return line; - } - Err(io::Error::new(io::ErrorKind::NotFound, "File is empty")) -} - -/// Escape values for SQL insert statement to avoid SQL injection attacks and other issues with special characters in values. -pub fn escaped_values(values: StringRecord) -> String { - let vec: Vec = values - .iter() - .map(|v| format!("'{}'", sanitize_value(v))) - .collect(); - vec.join(", ") -} - /// This function is used to get the size of a file. pub fn get_all_saved_configs(config_file: &str) -> Vec { let default_configs: Vec = Vec::new(); diff --git a/src-tauri/src/fileflow/utils/mod.rs b/src-tauri/src/fileflow/utils/mod.rs index 036348e..2934cbd 100644 --- a/src-tauri/src/fileflow/utils/mod.rs +++ b/src-tauri/src/fileflow/utils/mod.rs @@ -1,3 +1,4 @@ pub mod constants; +pub mod csv_utils; pub mod fileflowlib; -pub mod sql; +pub mod string_formater; diff --git a/src-tauri/src/fileflow/utils/string_formater.rs b/src-tauri/src/fileflow/utils/string_formater.rs new file mode 100644 index 0000000..dc1c98e --- /dev/null +++ b/src-tauri/src/fileflow/utils/string_formater.rs @@ -0,0 +1,45 @@ +use csv::StringRecord; + +/// This function is used to generate the column names for a CSV file. +pub fn get_formated_column_names(headers: &[String]) -> Vec { + const COLUMN_PREFIX: &str = "column_"; + let mut safe_headers: Vec = Vec::with_capacity(headers.len()); + + for (index, item) in headers.iter().enumerate() { + let trimmed_column_name: &str = item.trim(); + if trimmed_column_name.is_empty() { + safe_headers.push(format!("{COLUMN_PREFIX}{}", index + 1)); + } else { + safe_headers.push(sanitize_column(trimmed_column_name)); + } + } + safe_headers +} + +/// Sanitize a value for safe insertion into the database +pub fn sanitize_value(value: &str) -> String { + value + .trim() + .replace("'", "''") // Escape single quotes + .replace("\\", "\\\\") // Escape backslashes + .replace("\"", "") // Remove double quotes +} + +/// Sanitize a column name for safe insertion into the database +pub fn sanitize_column(value: &str) -> String { + value + .trim() + .replace("'", "") // Remove single quotes + .replace("\\", "_") // Replace backslashes with underscores + .replace("\"", "") // Remove double quotes + .replace(" ", "_") // Replace spaces with underscores +} + +/// Escape values for SQL insert statement to avoid SQL injection attacks and other issues with special characters in values. +pub fn escaped_values(values: StringRecord) -> String { + let vec: Vec = values + .iter() + .map(|v| format!("'{}'", sanitize_value(v))) + .collect(); + vec.join(", ") +} \ No newline at end of file diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index d172cd9..7b344e6 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -6,9 +6,9 @@ mod fileflow; #[cfg(test)] mod tests; -use crate::fileflow::action::database_actions::get_table_list; +use crate::fileflow::action::database_command::get_table_list; use fileflow::action::actions::*; -use fileflow::action::database_actions::*; +use fileflow::action::database_command::*; use std::sync::Arc; use tokio::sync::Mutex; diff --git a/src-tauri/src/tests/action_test.rs b/src-tauri/src/tests/action_test.rs index 2c20c2a..f6a925b 100644 --- a/src-tauri/src/tests/action_test.rs +++ b/src-tauri/src/tests/action_test.rs @@ -4,7 +4,7 @@ use crate::fileflow::enumeration::database_engine::DatabaseEngine; use crate::fileflow::stuct::db_config::DbConfig; use crate::fileflow::stuct::save_config::SaveConfig; use crate::fileflow::utils::fileflowlib::{get_all_saved_configs, save_config}; -use crate::tests::utils::{ +use crate::tests::utils_tests::{ create_test_db, delete_config_file, generate_csv_file, get_test_save_config, get_test_sqlite_config, remove_csv_file, remove_test_db, }; diff --git a/src-tauri/src/tests/standard_test.rs b/src-tauri/src/tests/csv_utils_test.rs similarity index 52% rename from src-tauri/src/tests/standard_test.rs rename to src-tauri/src/tests/csv_utils_test.rs index 23d1ab7..6ef8443 100644 --- a/src-tauri/src/tests/standard_test.rs +++ b/src-tauri/src/tests/csv_utils_test.rs @@ -1,6 +1,5 @@ -use crate::fileflow::utils::fileflowlib::{escaped_values, find_separator, read_first_line}; -use crate::tests::utils::{generate_csv_file, remove_csv_file}; -use csv::StringRecord; +use crate::fileflow::utils::csv_utils::{find_separator, read_first_line}; +use crate::tests::utils_tests::{generate_csv_file, remove_csv_file}; #[tokio::test] async fn test_detect_separator() { @@ -22,22 +21,6 @@ async fn test_detect_separator() { } } -#[tokio::test] -async fn test_escape_values() { - let record: StringRecord = StringRecord::from(vec!["value1", "value2"]); - let values: String = escaped_values(record); - assert_eq!(values, "'value1', 'value2'"); - - let record: StringRecord = StringRecord::from(vec![ - "INSERT INTO test_table VALUES (1,2);", - "UPDATE test_table SET column1 = 1;", - "DELETE FROM test_table WHERE column1 = 1;", - "SELECT * FROM test_table;", - ]); - let values: String = escaped_values(record); - assert_eq!(values, "'INSERT INTO test_table VALUES (1,2);', 'UPDATE test_table SET column1 = 1;', 'DELETE FROM test_table WHERE column1 = 1;', 'SELECT * FROM test_table;'"); -} - #[tokio::test] async fn test_read_first_line() { let csv_file_path: String = @@ -45,4 +28,4 @@ async fn test_read_first_line() { let first_line: String = read_first_line(&csv_file_path).expect("Failed to read first line"); assert_eq!(first_line, "header1,header2"); remove_csv_file("test_read_first_line").expect("Failed to remove csv file"); -} +} \ No newline at end of file diff --git a/src-tauri/src/tests/database_test.rs b/src-tauri/src/tests/database_test.rs index d62482c..e80239e 100644 --- a/src-tauri/src/tests/database_test.rs +++ b/src-tauri/src/tests/database_test.rs @@ -1,14 +1,13 @@ use crate::fileflow::database::connection::{Connection, QueryResult}; +use crate::fileflow::database::sql_builder::{ + build_create_table_sql, build_create_with_fixed_size_sql, build_drop_statement_sql, + build_prepared_statement_sql, build_query_all_tables, +}; use crate::fileflow::enumeration::database_engine::DatabaseEngine; use crate::fileflow::enumeration::separator::SeparatorType; use crate::fileflow::stuct::db_config::DbConfig; use crate::fileflow::stuct::download_config::DownloadConfig; -use crate::fileflow::utils::fileflowlib::get_formated_column_names; -use crate::fileflow::utils::sql::{ - build_query_all_tables, export_table, get_create_statement, - get_create_statement_with_fixed_size, get_drop_statement, get_insert_into_statement, -}; -use crate::tests::utils::{ +use crate::tests::utils_tests::{ create_test_db, get_test_maridb_config, get_test_mysql_config, get_test_pg_config, get_test_sqlite_config, remove_test_db, }; @@ -53,194 +52,7 @@ async fn test_sqlite_connection() { remove_test_db("sqlite_connection").expect("Failed to remove test table"); } -#[tokio::test] -async fn test_get_drop_statement() { - assert_eq!( - get_drop_statement(&DatabaseEngine::SQLite, "table_name").unwrap(), - "DROP TABLE IF EXISTS \"table_name\"" - ); - assert_eq!( - get_drop_statement(&DatabaseEngine::MySQL, "table_name").unwrap(), - "DROP TABLE IF EXISTS `table_name`" - ); - assert_eq!( - get_drop_statement(&DatabaseEngine::Postgres, "table_name").unwrap(), - "DROP TABLE IF EXISTS \"table_name\"" - ); - assert_eq!( - get_drop_statement(&DatabaseEngine::SQLite, "").unwrap(), - "DROP TABLE IF EXISTS \"\"" - ); - assert_eq!( - get_drop_statement(&DatabaseEngine::MySQL, "").unwrap(), - "DROP TABLE IF EXISTS ``" - ); - assert_eq!( - get_drop_statement(&DatabaseEngine::Postgres, "").unwrap(), - "DROP TABLE IF EXISTS \"\"" - ); -} -#[tokio::test] -async fn test_get_insert_into_statement() { - assert_eq!( - get_insert_into_statement(&DatabaseEngine::SQLite, "table_name", "columns").unwrap(), - "INSERT INTO \"table_name\" (columns) VALUES " - ); - assert_eq!( - get_insert_into_statement(&DatabaseEngine::MySQL, "table_name", "columns").unwrap(), - "INSERT INTO `table_name` (columns) VALUES " - ); - assert_eq!( - get_insert_into_statement(&DatabaseEngine::Postgres, "table_name", "columns").unwrap(), - "INSERT INTO \"table_name\" (columns) VALUES " - ); - - assert_eq!( - get_insert_into_statement(&DatabaseEngine::SQLite, "table_name", "").unwrap(), - "INSERT INTO \"table_name\" () VALUES " - ); - assert_eq!( - get_insert_into_statement(&DatabaseEngine::MySQL, "table_name", "").unwrap(), - "INSERT INTO `table_name` () VALUES " - ); - assert_eq!( - get_insert_into_statement(&DatabaseEngine::Postgres, "table_name", "").unwrap(), - "INSERT INTO \"table_name\" () VALUES " - ); - - assert_eq!( - get_insert_into_statement(&DatabaseEngine::SQLite, "table_name", "header1, header2") - .unwrap(), - "INSERT INTO \"table_name\" (header1, header2) VALUES " - ); - assert_eq!( - get_insert_into_statement(&DatabaseEngine::MySQL, "table_name", "header1, header2") - .unwrap(), - "INSERT INTO `table_name` (header1, header2) VALUES " - ); - assert_eq!( - get_insert_into_statement(&DatabaseEngine::Postgres, "table_name", "header1, header2") - .unwrap(), - "INSERT INTO \"table_name\" (header1, header2) VALUES " - ); -} - -#[tokio::test] -async fn test_get_create_statement() { - let snake_case_headers: Vec = vec!["header1".into(), "header2".into()]; - assert_eq!( - get_create_statement(&DatabaseEngine::SQLite, "table_name", &snake_case_headers).unwrap(), - "CREATE TABLE \"table_name\" (header1 TEXT, header2 TEXT)" - ); - assert_eq!( - get_create_statement(&DatabaseEngine::MySQL, "table_name", &snake_case_headers).unwrap(), - "CREATE TABLE `table_name` (header1 TEXT, header2 TEXT)" - ); - assert_eq!( - get_create_statement(&DatabaseEngine::Postgres, "table_name", &snake_case_headers).unwrap(), - "CREATE TABLE \"table_name\" (header1 TEXT, header2 TEXT)" - ); - - let snake_case_headers: Vec = vec!["header1".into()]; - assert_eq!( - get_create_statement(&DatabaseEngine::SQLite, "table_name", &snake_case_headers).unwrap(), - "CREATE TABLE \"table_name\" (header1 TEXT)" - ); - assert_eq!( - get_create_statement(&DatabaseEngine::MySQL, "table_name", &snake_case_headers).unwrap(), - "CREATE TABLE `table_name` (header1 TEXT)" - ); - assert_eq!( - get_create_statement(&DatabaseEngine::Postgres, "table_name", &snake_case_headers).unwrap(), - "CREATE TABLE \"table_name\" (header1 TEXT)" - ); -} - -#[tokio::test] -async fn test_get_create_statement_with_fixed_size() { - const FINAL_TABLE_NAME: &str = "test_table"; - - let snake_case_headers: Vec = vec!["header1".into(), "header2".into()]; - let map_max_length: HashMap<&str, usize> = - snake_case_headers.iter().map(|h| (h.as_str(), 0)).collect(); - - let mut db_driver: HashMap<&DatabaseEngine, &str> = HashMap::new(); - db_driver.insert( - &DatabaseEngine::Postgres, - "CREATE TABLE \"test_table\" (\"header1\" VARCHAR(0), \"header2\" VARCHAR(0));", - ); - db_driver.insert( - &DatabaseEngine::MySQL, - "CREATE TABLE `test_table` (`header1` VARCHAR(0), `header2` VARCHAR(0));", - ); - db_driver.insert( - &DatabaseEngine::MariaDB, - "CREATE TABLE `test_table` (`header1` VARCHAR(0), `header2` VARCHAR(0));", - ); - db_driver.insert( - &DatabaseEngine::SQLite, - "CREATE TABLE \"test_table\" (\"header1\" VARCHAR(0), \"header2\" VARCHAR(0));", - ); - - let final_columns: Vec = vec!["header1".into(), "header2".into()]; - - for (driver, expected) in db_driver { - let result: Result = get_create_statement_with_fixed_size( - driver, - FINAL_TABLE_NAME, - &map_max_length, - &final_columns, - ); - assert_eq!(result.unwrap(), expected); - } - - let map_max_length: HashMap<&str, usize> = snake_case_headers - .iter() - .map(|h| (h.as_str(), 10)) - .collect(); - let mut db_driver: HashMap<&DatabaseEngine, &str> = HashMap::new(); - db_driver.insert( - &DatabaseEngine::Postgres, - "CREATE TABLE \"test_table\" (\"header1\" VARCHAR(10), \"header2\" VARCHAR(10));", - ); - db_driver.insert( - &DatabaseEngine::MySQL, - "CREATE TABLE `test_table` (`header1` VARCHAR(10), `header2` VARCHAR(10));", - ); - db_driver.insert( - &DatabaseEngine::MariaDB, - "CREATE TABLE `test_table` (`header1` VARCHAR(10), `header2` VARCHAR(10));", - ); - db_driver.insert( - &DatabaseEngine::SQLite, - "CREATE TABLE \"test_table\" (\"header1\" VARCHAR(10), \"header2\" VARCHAR(10));", - ); - - for (driver, expected) in db_driver { - let result: Result = get_create_statement_with_fixed_size( - driver, - FINAL_TABLE_NAME, - &map_max_length, - &final_columns, - ); - assert_eq!(result.unwrap(), expected); - } -} - -#[tokio::test] -async fn test_get_formated_column_names() { - let headers: Vec = vec!["header 1".into(), " header2".into()]; - let formatted_headers: Vec = get_formated_column_names(headers); - assert_eq!(formatted_headers, vec!["header_1", "_header2"]); - - let headers: Vec = vec!["header 1".into(), String::new(), "header2".into()]; - let formatted_headers: Vec = get_formated_column_names(headers); - assert_eq!( - formatted_headers, - vec!["header____1", "column_2", "header2"] - ); -} #[tokio::test] async fn test_query_many_with_result() { diff --git a/src-tauri/src/tests/mod.rs b/src-tauri/src/tests/mod.rs index b2de678..435098b 100644 --- a/src-tauri/src/tests/mod.rs +++ b/src-tauri/src/tests/mod.rs @@ -1,10 +1,12 @@ #[cfg(test)] mod action_test; #[cfg(test)] -mod database_test; +mod csv_utils_test; #[cfg(test)] -mod standard_test; +mod database_test; #[cfg(test)] mod struct_test; #[cfg(test)] -mod utils; +mod utils_tests; +#[cfg(test)] +mod string_formater_test; diff --git a/src-tauri/src/tests/string_formater_test.rs b/src-tauri/src/tests/string_formater_test.rs new file mode 100644 index 0000000..af97c80 --- /dev/null +++ b/src-tauri/src/tests/string_formater_test.rs @@ -0,0 +1,56 @@ +use crate::fileflow::utils::string_formater::{ + escaped_values, get_formated_column_names, sanitize_column, sanitize_value, +}; +use csv::StringRecord; + +#[tokio::test] +async fn test_escape_values() { + let record: StringRecord = StringRecord::from(vec!["value1", "value2"]); + let values: String = escaped_values(record); + assert_eq!(values, "'value1', 'value2'"); + + let record: StringRecord = StringRecord::from(vec![ + "\"INSERT INTO test_table VALUES (1,2);\"", + "UPDATE test_table SET column1 = 1;", + "DELETE FROM test_table WHERE column1 = 1;", + "SELECT * FROM test_table;", + ]); + let values: String = escaped_values(record); + assert_eq!(values, "'INSERT INTO test_table VALUES (1,2);', 'UPDATE test_table SET column1 = 1;', 'DELETE FROM test_table WHERE column1 = 1;', 'SELECT * FROM test_table;'"); +} + +#[tokio::test] +async fn test_sanitize_value() { + assert_eq!(sanitize_value("value1"), "value1"); + assert_eq!(sanitize_value("'value1'"), "''value1''"); + assert_eq!(sanitize_value("value1'"), "value1''"); + assert_eq!(sanitize_value("value1\\value2"), "value1\\\\value2"); + assert_eq!(sanitize_value("value1\"value2"), "value1value2"); +} + +#[tokio::test] +async fn test_sanitize_column() { + assert_eq!(sanitize_column("column1"), "column1"); + assert_eq!(sanitize_column("'column1'"), "column1"); + assert_eq!(sanitize_column("column1'"), "column1"); + assert_eq!(sanitize_column("column1\\column2"), "column1_column2"); + assert_eq!(sanitize_column("column1\"column2"), "column1column2"); + assert_eq!(sanitize_column("column 1"), "column_1"); + assert_eq!(sanitize_column("column 1'"), "column_1"); +} + +#[tokio::test] +async fn test_get_formated_column_names() { + assert_eq!( + get_formated_column_names(&vec!["header 1".into(), " header2".into()]), + vec!["header_1", "header2"] + ); + assert_eq!( + get_formated_column_names(&vec!["header 1".into(), String::new(), "header2".into()]), + vec!["header____1", "column_2", "header2"] + ); + assert_eq!( + get_formated_column_names(&vec!["header'\" 1".into(), "header 2''\\".into()]), + vec!["header_1", "header_2"] + ); +} diff --git a/src-tauri/src/tests/struct_test.rs b/src-tauri/src/tests/struct_test.rs index fbbb6bd..e14f8e5 100644 --- a/src-tauri/src/tests/struct_test.rs +++ b/src-tauri/src/tests/struct_test.rs @@ -30,14 +30,14 @@ async fn test_db_config() { #[tokio::test] async fn test_insert_config() { let config = InsertConfig { - file_path: "file_path".into(), + files_path: vec!["file_path".into()], table_name: "table_name".into(), mode: InsertionType::Fast, db_driver: DatabaseEngine::Postgres, }; assert_eq!(config.db_driver, DatabaseEngine::Postgres); - assert_eq!(config.file_path, "file_path"); + assert_eq!(config.files_path, vec!["file_path"]); assert_eq!(config.table_name, "table_name"); assert_eq!(config.mode, InsertionType::Fast); } diff --git a/src-tauri/src/tests/utils.rs b/src-tauri/src/tests/utils_tests.rs similarity index 100% rename from src-tauri/src/tests/utils.rs rename to src-tauri/src/tests/utils_tests.rs diff --git a/src/components/fileflowui/load/insert/ButtonGroupAction.tsx b/src/components/fileflowui/load/insert/ButtonGroupAction.tsx index 730ae7e..1a2b083 100644 --- a/src/components/fileflowui/load/insert/ButtonGroupAction.tsx +++ b/src/components/fileflowui/load/insert/ButtonGroupAction.tsx @@ -9,8 +9,8 @@ import {DatabaseConfig} from "@/interfaces/DatabaseConfig.tsx"; interface ButtonGroupProps { dbConfig: DatabaseConfig; updateDbConfigField: (field: keyof DatabaseConfig, value: DatabaseConfig[keyof DatabaseConfig]) => void; - filePath: string; - setFilePath: (path: string) => void; + filesPath: string[]; + setFilesPath: (path: string[]) => void; tableName: string; setTableName: (name: string) => void mode: string; @@ -24,7 +24,7 @@ const ButtonGroupAction: React.FC = (props: ButtonGroupProps) const handleInsert = async (e: React.FormEvent) => { e.preventDefault(); try { - if (!props.filePath) { + if (!props.filesPath) { toast.warning('Please select a file'); return; } @@ -34,19 +34,20 @@ const ButtonGroupAction: React.FC = (props: ButtonGroupProps) return; } + props.setShowLoader(true); - const insert_csv_data_response: string | boolean = await invoke('insert_csv_data', { + const insert_csv_data_response: string = await invoke('insert_csv_data', { csv: { table_name: props.tableName, - file_path: props.filePath, + files_path: props.filesPath, db_driver: props.dbConfig.db_driver.toLowerCase(), mode: props.mode, }, }); - if (typeof insert_csv_data_response !== "string") { - throw new Error('Error inserting data'); + if (insert_csv_data_response.startsWith("Error:")) { + throw new Error(insert_csv_data_response); } toast.success(insert_csv_data_response); @@ -66,12 +67,12 @@ const ButtonGroupAction: React.FC = (props: ButtonGroupProps) props.updateDbConfigField('sqlite_file_path', ''); props.setMode('fast'); - props.setFilePath(''); + props.setFilesPath([]); props.setTableName(''); props.setShowLoader(false); }; - const insertOk: boolean = props.filePath !== "" && props.dbConfig.is_connected; + const insertOk: boolean = props.filesPath.length > 0 && props.dbConfig.is_connected; return (
diff --git a/src/components/fileflowui/load/insert/Insert.tsx b/src/components/fileflowui/load/insert/Insert.tsx index 6e211d2..6efc2af 100644 --- a/src/components/fileflowui/load/insert/Insert.tsx +++ b/src/components/fileflowui/load/insert/Insert.tsx @@ -24,7 +24,7 @@ const Insert: React.FC = () => { is_connected: false }); - const [filePath, setFilePath] = useState(''); + const [filesPath, setFilesPath] = useState([]); const [mode, setMode] = useState<"fast" | "optimized">("fast"); const [showLoader, setShowLoader] = useState(false); const [tableName, setTableName] = useState(''); @@ -37,11 +37,22 @@ const Insert: React.FC = () => { ); useEffect(() => { - if (filePath && filePath !== "") { - setTableName(getNormalizedTableName(filePath)); + updateTablesName(); + }, [filesPath]); + + + const updateTablesName = (): void => { + let tableMessage: string = ''; + for (const file of filesPath) { + const tableName: string = getNormalizedTableName(file); + if (file !== filesPath[filesPath.length - 1]) { + tableMessage += `${tableName}, `; + } else { + tableMessage += `${tableName}`; + } } - - }, [filePath]); + setTableName(tableMessage); + } return (
@@ -72,8 +83,9 @@ const Insert: React.FC = () => { + {/* File Upload */} - + {/* Table Name Input */} @@ -96,8 +108,8 @@ const Insert: React.FC = () => { , + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + + + +)) +Checkbox.displayName = CheckboxPrimitive.Root.displayName + +export { Checkbox } From 368cd8dc672f204269dad7394a4edf4b9eb49b48 Mon Sep 17 00:00:00 2001 From: Maxime Colliat Date: Thu, 3 Apr 2025 16:22:45 +0200 Subject: [PATCH 4/6] Fix value escaping + unit test --- src-tauri/src/fileflow/action/actions.rs | 118 ++++----- .../src/fileflow/action/database_command.rs | 179 +++++++++++++- .../src/fileflow/action/insertion_mode.rs | 231 ------------------ src-tauri/src/fileflow/action/mod.rs | 3 +- src-tauri/src/fileflow/database/connection.rs | 14 +- .../src/fileflow/database/database_actions.rs | 32 ++- src-tauri/src/fileflow/database/mod.rs | 2 +- .../src/fileflow/database/sql_builder.rs | 100 ++++++-- src-tauri/src/fileflow/enumeration/mod.rs | 2 +- src-tauri/src/fileflow/mod.rs | 2 +- src-tauri/src/fileflow/stuct/db_config.rs | 4 +- src-tauri/src/fileflow/stuct/insert_config.rs | 2 +- src-tauri/src/fileflow/stuct/mod.rs | 4 +- src-tauri/src/fileflow/stuct/save_config.rs | 2 +- .../src/fileflow/utils/string_formater.rs | 33 ++- src-tauri/src/tests/action_test.rs | 2 +- src-tauri/src/tests/csv_utils_test.rs | 2 +- src-tauri/src/tests/database_test.rs | 67 +---- src-tauri/src/tests/mod.rs | 4 +- src-tauri/src/tests/string_formater_test.rs | 12 +- src-tauri/src/tests/struct_test.rs | 4 +- .../load/insert/ButtonGroupAction.tsx | 33 +-- .../fileflowui/load/insert/Insert.tsx | 8 +- .../fileflowui/load/insert/ModeSelection.tsx | 9 +- 24 files changed, 429 insertions(+), 440 deletions(-) delete mode 100644 src-tauri/src/fileflow/action/insertion_mode.rs diff --git a/src-tauri/src/fileflow/action/actions.rs b/src-tauri/src/fileflow/action/actions.rs index def9ab8..6bb16ea 100644 --- a/src-tauri/src/fileflow/action/actions.rs +++ b/src-tauri/src/fileflow/action/actions.rs @@ -1,4 +1,4 @@ -use crate::fileflow::action::insertion_mode::{fast_insert, optimized_insert}; +use crate::fileflow::action::database_command::{fast_insert, optimized_insert}; use crate::fileflow::database::connection::Connection; use crate::fileflow::enumeration::insertion_type::InsertionType; use crate::fileflow::stuct::insert_config::InsertConfig; @@ -27,80 +27,68 @@ pub async fn insert_csv_data( return Err("Error: Connection is not established".into()); } - let tables_names: Vec = csv.table_name.split(',').map(|s| s.trim().into()).collect(); // Split the table names by comma - if tables_names.len() != csv.files_path.len() { - return Err("Error: The number of table names must match the number of files".into()); - } - let connection: &Connection = conn_guard.as_ref().unwrap(); - let mut table_inserted: u16 = 0; // Counter for the number of tables inserted let mut total_lines: u64 = 0; // Counter for the total number of lines inserted let start: Instant = Instant::now(); // Timer for the insertion process - for (index, file_path) in csv.files_path.iter().enumerate() { - let file: File = File::open(file_path).expect("Failed to open file"); - let first_line: String = read_first_line(file_path).expect("Failed to read first line"); // Read the first line of the file to detect the separator - let separator: char = find_separator(&first_line).expect("Failed to find separator"); // Separator detection of the file - - let final_columns_name: Vec = get_formated_column_names( - &first_line - .split(separator) - .map(|s| sanitize_column(s)) - .collect::>(), - ); - - let mut reader: Reader = ReaderBuilder::new() - .delimiter(u8::try_from(separator).unwrap()) - .has_headers(true) - .from_reader(file); - - match csv.mode { - InsertionType::Fast => { - match fast_insert( - connection, - &mut reader, - &final_columns_name, - &tables_names[index], - &csv.db_driver, - ) - .await - { - Ok(lines) => { - total_lines += u64::from(lines); - table_inserted += 1; - } - Err(_) => { - eprint!("Error: Failed to insert data"); - continue; - } + let file: File = File::open(&csv.file_path).expect("Failed to open file"); + let first_line: String = read_first_line(&csv.file_path).expect("Failed to read first line"); // Read the first line of the file to detect the separator + let separator: char = find_separator(&first_line).expect("Failed to find separator"); // Separator detection of the file + + let final_columns_name: Vec = get_formated_column_names( + &first_line + .split(separator) + .map(|s| sanitize_column(s)) + .collect::>(), + ); + + let mut reader: Reader = ReaderBuilder::new() + .delimiter(u8::try_from(separator).unwrap()) + .has_headers(true) + .from_reader(file); + + match csv.mode { + InsertionType::Fast => { + match fast_insert( + connection, + &mut reader, + &final_columns_name, + &csv.table_name, + &csv.db_driver, + ) + .await + { + Ok(lines) => { + total_lines += u64::from(lines); + } + Err(e) => { + return Err(format!("Error: Failed to insert data: {}", e.to_string())); } } - InsertionType::Optimized => { - match optimized_insert( - connection, - &mut reader, - &final_columns_name, - &tables_names[index], - &csv.db_driver, - ) - .await - { - Ok(lines) => { - total_lines += u64::from(lines); - table_inserted += 1; - } - Err(_) => { - eprint!("Error: Failed to insert data"); - continue; - } + } + InsertionType::Optimized => { + match optimized_insert( + connection, + &mut reader, + &final_columns_name, + &csv.table_name, + &csv.db_driver, + ) + .await + { + Ok(lines) => { + total_lines += u64::from(lines); + } + Err(e) => { + return Err(format!("Error: Failed to insert data: {}", e.to_string())); } } - }; - } + } + }; Ok(format!( - "Inserted {table_inserted} out of {} for a total of {total_lines} lines in {:?} seconds", - csv.files_path.len(), + "Inserted {total_lines} lines into {} tables in {:?} seconds", + csv.table_name, start.elapsed(), )) } diff --git a/src-tauri/src/fileflow/action/database_command.rs b/src-tauri/src/fileflow/action/database_command.rs index b2a42e9..c631ec7 100644 --- a/src-tauri/src/fileflow/action/database_command.rs +++ b/src-tauri/src/fileflow/action/database_command.rs @@ -1,11 +1,22 @@ use crate::fileflow::action::actions::DatabaseState; use crate::fileflow::database::connection::{Connection, QueryResult}; +use crate::fileflow::database::database_actions::{ + batch_insert, create_and_copy_final_table, drop_existing_tables, drop_table_if_exists, + execute_query, export_table, +}; +use crate::fileflow::database::sql_builder::{ + build_create_table_sql, build_prepared_statement_sql, build_query_all_tables, +}; +use crate::fileflow::enumeration::database_engine::DatabaseEngine; use crate::fileflow::stuct::combo_item::ComboItem; use crate::fileflow::stuct::db_config::DbConfig; use crate::fileflow::stuct::download_config::DownloadConfig; -use crate::fileflow::database::sql_builder::{build_query_all_tables, export_table}; +use crate::fileflow::utils::string_formater::{escaped_record, sanitize_value}; +use csv::{Reader, StringRecord}; use serde_json::{json, Value}; use sqlx::Row; +use std::collections::HashMap; +use std::fs::File; use std::sync::Arc; use std::time::Instant; use tauri::{command, State}; @@ -144,7 +155,7 @@ pub async fn download_table( }; let mut exported_table: u32 = 0; - for table_name in &config.table_name_list { + for table_name in config.table_name_list.iter() { if let Err(err) = export_table(connection, &config, table_name).await { println!("{err}"); continue; @@ -164,3 +175,167 @@ pub async fn download_table( Ok(response) } + +/// Fast insert data the csv file into the database table +pub async fn fast_insert( + connection: &Connection, + reader: &mut Reader, + final_columns_name: &[String], + final_table_name: &str, + db_driver: &DatabaseEngine, +) -> Result { + // Drop the table if it exists + if let Err(err) = drop_table_if_exists(connection, db_driver, final_table_name).await { + eprintln!("Error: {err}"); + return Err(err); + } + + let build_create_table_statement: String = + build_create_table_sql(db_driver, final_table_name, final_columns_name); + + // Create the table + if let Err(err) = execute_query( + connection, + &build_create_table_statement, + "Failed to create table", + ) + .await + { + eprintln!("Error: {err}"); + return Err(err); + } + + const MAX_BATCH_SIZE: usize = 5_000; + let mut line_count: u32 = 0; + let mut batch: Vec = Vec::with_capacity(MAX_BATCH_SIZE); + + // Prepare the insert query + let insert_query_base: &str = + &build_prepared_statement_sql(db_driver, final_table_name, &final_columns_name); + + for result in reader.records() { + let values: String = match result { + Ok(record) => escaped_record(record), + Err(_) => continue, + }; + + batch.push(format!("({values})")); + + if batch.len() >= MAX_BATCH_SIZE { + line_count += insert_batch(connection, insert_query_base, &batch).await; + batch.clear(); + } + } + + // Insert the remaining records if any + line_count += insert_batch(connection, insert_query_base, &batch).await; + + Ok(line_count) +} + +/// Insert data into the database using the optimized table creation and insertion method +pub async fn optimized_insert( + connection: &Connection, + reader: &mut Reader, + final_columns_name: &[String], + final_table_name: &str, + db_driver: &DatabaseEngine, +) -> Result { + // Drop existing tables + let temporary_table_name: String = format!("{final_table_name}_temporary"); + drop_existing_tables( + connection, + &[&temporary_table_name, final_table_name], + db_driver, + ) + .await + .expect("Failed to drop existing tables"); + + // Create the temporary table + let create_temp_table_query: String = + build_create_table_sql(db_driver, &temporary_table_name, final_columns_name); + + execute_query( + connection, + &create_temp_table_query, + "Failed to create temporary table", + ) + .await + .expect("Failed to create temporary table query"); + + // Initialize variables + const MAX_BATCH_SIZE: usize = 5_000; + let insert_query_base: String = + build_prepared_statement_sql(db_driver, &temporary_table_name, &final_columns_name); + + let mut columns_size_map: HashMap<&str, usize> = final_columns_name + .iter() + .map(|col| (col.as_str(), 0)) + .collect(); // Initialize column size map for each column -> 0 (id,size) + let mut line_count: u32 = 0; + let mut batch: Vec = Vec::with_capacity(MAX_BATCH_SIZE); + + for result in reader.records() { + let record: StringRecord = match result { + Ok(record) => record, + Err(_) => continue, + }; + + let mut values: Vec = Vec::with_capacity(record.len()); + + for (i, value) in record.iter().enumerate() { + let sanitized_value: String = sanitize_value(value); + let max_length: &mut usize = columns_size_map + .get_mut(final_columns_name[i].as_str()) + .ok_or("Column name mismatch") + .expect("Column name mismatch"); + *max_length = (*max_length).max(sanitized_value.len() + 1); + values.push(format!("'{sanitized_value}'")); + } + + batch.push(format!("({})", values.join(", "))); + + if batch.len() >= MAX_BATCH_SIZE { + line_count += insert_batch(connection, &insert_query_base, &batch).await; + batch.clear(); + } + } + + // Insert remaining records + if !batch.is_empty() { + line_count += insert_batch(connection, &insert_query_base, &batch).await; + } + + // Create final table and copy data + create_and_copy_final_table( + connection, + db_driver, + final_table_name, + &temporary_table_name, + &columns_size_map, + final_columns_name, + ) + .await?; + + drop_table_if_exists(connection, db_driver, &temporary_table_name).await?; // Drop the temporary table + + Ok(line_count) +} + +/// Insert a batch of records into the database +async fn insert_batch(connection: &Connection, insert_query_base: &str, batch: &[String]) -> u32 { + match batch_insert( + connection, + insert_query_base, + batch, + "Failed to insert batch data", + ) + .await + { + Ok(_) => u32::try_from(batch.len()).unwrap_or(5_000), + Err(err) => { + eprintln!("Error inserting batch: {err}"); + 0 + } + } +} diff --git a/src-tauri/src/fileflow/action/insertion_mode.rs b/src-tauri/src/fileflow/action/insertion_mode.rs deleted file mode 100644 index 9120c8b..0000000 --- a/src-tauri/src/fileflow/action/insertion_mode.rs +++ /dev/null @@ -1,231 +0,0 @@ -use crate::fileflow::database::connection::Connection; -use crate::fileflow::database::database_actions::{ - batch_insert, create_and_copy_final_table, drop_table_if_exists, execute_query, -}; -use crate::fileflow::database::sql_builder::{ - build_create_table_sql, build_prepared_statement_sql, -}; -use crate::fileflow::enumeration::database_engine::DatabaseEngine; -use crate::fileflow::utils::string_formater::{escaped_values, sanitize_value}; -use csv::{Reader, StringRecord}; -use std::collections::HashMap; -use std::fs::File; - -/// Insert data into the database using the optimized table creation and insertion method -pub async fn optimized_insert( - connection: &Connection, - reader: &mut Reader, - final_columns_name: &[String], - final_table_name: &str, - db_driver: &DatabaseEngine, -) -> Result { - let temporary_table_name: &str = &format!("{final_table_name}_temporary"); - - // Drop existing tables - drop_existing_tables( - connection, - &[temporary_table_name, final_table_name], - db_driver, - ) - .await - .expect("Failed to drop existing tables"); - - // Create the temporary table - let create_temp_table_query: String = - build_create_table_sql(db_driver, temporary_table_name, final_columns_name); - - execute_query( - connection, - &create_temp_table_query, - "Failed to create temporary table", - ) - .await - .expect("Failed to create temporary table query"); - - // Initialize variables - const MAX_BATCH_SIZE: usize = 4000; - let insert_query_base: String = build_prepared_statement_sql( - db_driver, - temporary_table_name, - &final_columns_name.join(", "), - ); - let mut batch: Vec = Vec::with_capacity(MAX_BATCH_SIZE); - let mut columns_size_map: HashMap<&str, usize> = - initialize_columns_size_map(final_columns_name); - let mut line_count: u32 = 0; - - // Read and process records from the CSV - for result in reader.records() { - let record: StringRecord = match result { - Ok(record) => record, - Err(_) => continue, - }; - - process_record( - &record, - &mut batch, - &mut columns_size_map, - final_columns_name, - ) - .expect("Failed to process record"); - - if batch.len() >= MAX_BATCH_SIZE { - line_count += insert_batch(connection, &insert_query_base, &batch).await?; - batch.clear(); - } - } - - // Insert remaining records - if !batch.is_empty() { - line_count += insert_batch(connection, &insert_query_base, &batch).await?; - } - - // Create final table and copy data - create_and_copy_final_table( - connection, - db_driver, - final_table_name, - temporary_table_name, - &columns_size_map, - final_columns_name, - ) - .await?; - - // Drop the temporary table - drop_table_if_exists(connection, db_driver, temporary_table_name).await?; - - Ok(line_count) -} - -/// Drop a list of tables if they exist -async fn drop_existing_tables( - connection: &Connection, - table_names: &[&str], - db_driver: &DatabaseEngine, -) -> Result<(), String> { - for table_name in table_names.iter() { - if let Err(e) = drop_table_if_exists(connection, db_driver, table_name).await { - eprintln!("Error: {e}"); - } - } - Ok(()) -} - -/// Initialize the column size map with default sizes -fn initialize_columns_size_map(final_columns_name: &[String]) -> HashMap<&str, usize> { - final_columns_name - .iter() - .map(|col| (col.as_str(), 0)) - .collect() -} - -/// Sanitize and process a CSV record, updating batch and column size map -fn process_record( - record: &StringRecord, - batch: &mut Vec, - columns_size_map: &mut HashMap<&str, usize>, - final_columns_name: &[String], -) -> Result<(), String> { - let mut values: Vec = Vec::with_capacity(record.len()); - - for (i, value) in record.iter().enumerate() { - let sanitized_value: String = sanitize_value(value); - let max_length: &mut usize = columns_size_map - .get_mut(final_columns_name[i].as_str()) - .ok_or("Column name mismatch") - .expect("Column name mismatch"); - *max_length = (*max_length).max(sanitized_value.len() + 1); - values.push(format!("'{sanitized_value}'")); - } - - batch.push(format!("({})", values.join(", "))); - Ok(()) -} - -/// Insert a batch of records into the database -async fn insert_batch( - connection: &Connection, - insert_query_base: &str, - batch: &[String], -) -> Result { - batch_insert( - connection, - insert_query_base, - batch, - "Failed to insert batch data", - ) - .await - .map(|_| u32::try_from(batch.len()).expect("Failed to convert batch len")) -} - -/// Fast insert data the csv file into the database table -pub async fn fast_insert( - connection: &Connection, - reader: &mut Reader, - final_columns_name: &[String], - final_table_name: &str, - db_driver: &DatabaseEngine, -) -> Result { - // Drop the table if it exists - if let Err(err) = drop_table_if_exists(connection, db_driver, final_table_name).await { - eprintln!("Error: {err}"); - return Err(err); - } - - let build_create_table_statement: String = - build_create_table_sql(db_driver, final_table_name, final_columns_name); - - // Create the table - if let Err(err) = execute_query( - connection, - &build_create_table_statement, - "Failed to create table", - ) - .await - { - eprintln!("Error: {err}"); - return Err(err); - } - - const MAX_BATCH_SIZE: usize = 10_000; - let columns: &str = &final_columns_name.join(", "); - let mut line_count: u32 = 0; - let mut batch: Vec = Vec::with_capacity(MAX_BATCH_SIZE); - - // Prepare the insert query - let insert_query_base: &str = - &build_prepared_statement_sql(db_driver, final_table_name, columns); - - for result in reader.records() { - let record: StringRecord = result.unwrap(); - let values: String = escaped_values(record); - batch.push(format!("({values})")); - - if batch.len() == MAX_BATCH_SIZE { - batch_insert( - connection, - insert_query_base, - &batch, - "Failed to insert batch data", - ) - .await - .expect("Failed to insert batch data"); - line_count += u32::try_from(batch.len()).expect("Failed to convert batch len"); - batch.clear(); - } - } - - // Insert the remaining records if any - batch_insert( - connection, - insert_query_base, - &batch, - "Failed to insert batch data", - ) - .await - .map_err(|e| format!("Failed to insert batch data: {e}"))?; - - line_count += u32::try_from(batch.len()).expect("Failed to convert batch len"); - - Ok(line_count) -} diff --git a/src-tauri/src/fileflow/action/mod.rs b/src-tauri/src/fileflow/action/mod.rs index 5e92c1b..339c2ac 100644 --- a/src-tauri/src/fileflow/action/mod.rs +++ b/src-tauri/src/fileflow/action/mod.rs @@ -1,3 +1,2 @@ pub mod actions; -pub mod database_command; -pub mod insertion_mode; +pub mod database_command; \ No newline at end of file diff --git a/src-tauri/src/fileflow/database/connection.rs b/src-tauri/src/fileflow/database/connection.rs index 67cccb5..85ff25e 100644 --- a/src-tauri/src/fileflow/database/connection.rs +++ b/src-tauri/src/fileflow/database/connection.rs @@ -21,7 +21,7 @@ pub struct Connection { impl Connection { pub async fn connect(config: &DbConfig) -> Result { - let connection_str: String = Self::get_connection_url(config)?; + let connection_str: String = Self::get_connection_url(config); let connection_enum: ConnectionEnum = match config.db_driver { DatabaseEngine::Postgres => { @@ -81,9 +81,9 @@ impl Connection { Ok(()) } - pub(crate) fn get_connection_url(config: &DbConfig) -> Result { + pub(crate) fn get_connection_url(config: &DbConfig) -> String { match config.db_driver { - DatabaseEngine::Postgres => Ok(format!( + DatabaseEngine::Postgres => format!( "postgres://{}{}@{}:{}/{}", config.username, if config.password.is_empty() { @@ -94,8 +94,8 @@ impl Connection { config.db_host, config.port, config.db_name - )), - DatabaseEngine::MySQL | DatabaseEngine::MariaDB => Ok(format!( + ), + DatabaseEngine::MySQL | DatabaseEngine::MariaDB => format!( "mysql://{}{}@{}:{}/{}", config.username, if config.password.is_empty() { @@ -106,8 +106,8 @@ impl Connection { config.db_host, config.port, config.db_name - )), - DatabaseEngine::SQLite => Ok(config.sqlite_file_path.clone()), + ), + DatabaseEngine::SQLite => config.sqlite_file_path.clone(), } } diff --git a/src-tauri/src/fileflow/database/database_actions.rs b/src-tauri/src/fileflow/database/database_actions.rs index 6b062c7..d2a0749 100644 --- a/src-tauri/src/fileflow/database/database_actions.rs +++ b/src-tauri/src/fileflow/database/database_actions.rs @@ -1,12 +1,14 @@ -use std::collections::HashMap; -use std::fs::File; -use csv::{Writer, WriterBuilder}; -use sqlx::{Column, Row}; use crate::fileflow::database::connection::{Connection, QueryResult}; -use crate::fileflow::database::sql_builder::{build_copy_table_sql, build_create_with_fixed_size_sql, build_drop_statement_sql}; +use crate::fileflow::database::sql_builder::{ + build_copy_table_sql, build_create_with_fixed_size_sql, build_drop_statement_sql, +}; use crate::fileflow::enumeration::database_engine::DatabaseEngine; use crate::fileflow::enumeration::separator::SeparatorType; use crate::fileflow::stuct::download_config::DownloadConfig; +use csv::{Writer, WriterBuilder}; +use sqlx::{Column, Row}; +use std::collections::HashMap; +use std::fs::File; /// Exports a table’s data into a CSV file. It uses offset/LIMIT pagination to retrieve data in batches pub async fn export_table( @@ -141,7 +143,7 @@ pub async fn drop_table_if_exists( drop_query, &format!("Failed to drop table '{table_name}'"), ) - .await + .await } /// Helper function to execute a query and handle errors @@ -190,7 +192,7 @@ pub async fn create_and_copy_final_table( &create_final_table_query, "Failed to create final table", ) - .await?; + .await?; let copy_data_query: String = build_copy_table_sql(db_driver, temporary_table_name, final_table_name); @@ -200,7 +202,21 @@ pub async fn create_and_copy_final_table( ©_data_query, "Failed to copy data to final table", ) - .await?; + .await?; Ok(()) } + +/// Drop a list of tables if they exist +pub async fn drop_existing_tables( + connection: &Connection, + table_names: &[&str], + db_driver: &DatabaseEngine, +) -> Result<(), String> { + for table_name in table_names.iter() { + if let Err(e) = drop_table_if_exists(connection, db_driver, table_name).await { + eprintln!("Error: {e}"); + } + } + Ok(()) +} diff --git a/src-tauri/src/fileflow/database/mod.rs b/src-tauri/src/fileflow/database/mod.rs index ea950e6..bc2f05a 100644 --- a/src-tauri/src/fileflow/database/mod.rs +++ b/src-tauri/src/fileflow/database/mod.rs @@ -1,3 +1,3 @@ pub mod connection; -pub mod sql_builder; pub mod database_actions; +pub mod sql_builder; diff --git a/src-tauri/src/fileflow/database/sql_builder.rs b/src-tauri/src/fileflow/database/sql_builder.rs index 01e4722..ea10047 100644 --- a/src-tauri/src/fileflow/database/sql_builder.rs +++ b/src-tauri/src/fileflow/database/sql_builder.rs @@ -1,5 +1,4 @@ use crate::fileflow::enumeration::database_engine::DatabaseEngine; -use sqlx::Row; use std::collections::HashMap; /// This function is used to generate the DROP TABLE statement for different database drivers. @@ -20,14 +19,25 @@ pub fn build_drop_statement_sql( /// This function is used to generate the INSERT INTO statement for different database drivers. pub fn build_prepared_statement_sql( db_driver: &DatabaseEngine, - final_table_name: &str, - columns: &str, + table_name: &str, + columns: &[String], ) -> String { let quote: char = match db_driver { DatabaseEngine::SQLite | DatabaseEngine::Postgres => '\"', DatabaseEngine::MariaDB | DatabaseEngine::MySQL => '`', }; - format!("INSERT INTO {quote}{final_table_name}{quote} ({columns}) VALUES ") + let mut query = format!("INSERT INTO {quote}{table_name}{quote} ("); + for column in columns.iter() { + if column.is_empty() { + continue; + } + query.push_str(&format!("{quote}{column}{quote}")); + if column != columns.last().unwrap() { + query.push_str(", "); + } + } + query.push_str(") VALUES "); + query } /// This function is used to generate the COPY statement for different database drivers. @@ -149,7 +159,7 @@ pub fn build_query_all_tables(driver: &DatabaseEngine, schema: &str) -> String { mod test { use crate::fileflow::database::sql_builder::{ build_create_table_sql, build_create_with_fixed_size_sql, build_drop_statement_sql, - build_prepared_statement_sql, + build_prepared_statement_sql, build_query_all_tables, }; use crate::fileflow::enumeration::database_engine::DatabaseEngine; use std::collections::HashMap; @@ -185,46 +195,62 @@ mod test { #[tokio::test] async fn test_get_insert_into_statement() { assert_eq!( - build_prepared_statement_sql(&DatabaseEngine::SQLite, "table_name", "columns"), - "INSERT INTO \"table_name\" (columns) VALUES " + build_prepared_statement_sql( + &DatabaseEngine::SQLite, + "table_name", + &["columns".into()] + ), + "INSERT INTO \"table_name\" (\"columns\") VALUES " ); assert_eq!( - build_prepared_statement_sql(&DatabaseEngine::MySQL, "table_name", "columns"), - "INSERT INTO `table_name` (columns) VALUES " + build_prepared_statement_sql(&DatabaseEngine::MySQL, "table_name", &["columns".into()]), + "INSERT INTO `table_name` (`columns`) VALUES " ); assert_eq!( - build_prepared_statement_sql(&DatabaseEngine::Postgres, "table_name", "columns"), - "INSERT INTO \"table_name\" (columns) VALUES " + build_prepared_statement_sql( + &DatabaseEngine::Postgres, + "table_name", + &["columns".into()] + ), + "INSERT INTO \"table_name\" (\"columns\") VALUES " ); assert_eq!( - build_prepared_statement_sql(&DatabaseEngine::SQLite, "table_name", ""), + build_prepared_statement_sql(&DatabaseEngine::SQLite, "table_name", &["".into()]), "INSERT INTO \"table_name\" () VALUES " ); assert_eq!( - build_prepared_statement_sql(&DatabaseEngine::MySQL, "table_name", ""), + build_prepared_statement_sql(&DatabaseEngine::MySQL, "table_name", &["".into()]), "INSERT INTO `table_name` () VALUES " ); assert_eq!( - build_prepared_statement_sql(&DatabaseEngine::Postgres, "table_name", ""), + build_prepared_statement_sql(&DatabaseEngine::Postgres, "table_name", &["".into()]), "INSERT INTO \"table_name\" () VALUES " ); assert_eq!( - build_prepared_statement_sql(&DatabaseEngine::SQLite, "table_name", "header1, header2"), - "INSERT INTO \"table_name\" (header1, header2) VALUES " + build_prepared_statement_sql( + &DatabaseEngine::SQLite, + "table_name", + &["header1".into(), "header2".into()] + ), + "INSERT INTO \"table_name\" (\"header1\", \"header2\") VALUES " ); assert_eq!( - build_prepared_statement_sql(&DatabaseEngine::MySQL, "table_name", "header1, header2"), - "INSERT INTO `table_name` (`header1`, header2) VALUES " + build_prepared_statement_sql( + &DatabaseEngine::MySQL, + "table_name", + &["header1".into(), "header2".into()] + ), + "INSERT INTO `table_name` (`header1`, `header2`) VALUES " ); assert_eq!( build_prepared_statement_sql( &DatabaseEngine::Postgres, "table_name", - "header1, header2" + &["header1".into(), "header2".into()] ), - "INSERT INTO \"table_name\" (header1, header2) VALUES " + "INSERT INTO \"table_name\" (\"header1\", \"header2\") VALUES " ); } @@ -329,4 +355,38 @@ mod test { assert_eq!(result, expected); } } + + #[tokio::test] + async fn test_build_query_all_tables() { + let test_cases: Vec<(&DatabaseEngine, String)> = vec![ + ( + &DatabaseEngine::MySQL, + "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'test';" + .into(), + ), + ( + &DatabaseEngine::MariaDB, + "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'test';" + .into(), + ), + ( + &DatabaseEngine::Postgres, + "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'public';" + .into(), + ), + ( + &DatabaseEngine::SQLite, + "SELECT name FROM sqlite_master WHERE type='table';".into(), + ), + ]; + + for (driver, expected) in test_cases { + assert_eq!( + build_query_all_tables(driver, "test"), + expected, + "Failed for driver: {:?}", + driver + ); + } + } } diff --git a/src-tauri/src/fileflow/enumeration/mod.rs b/src-tauri/src/fileflow/enumeration/mod.rs index cd0b48a..11cfdf4 100644 --- a/src-tauri/src/fileflow/enumeration/mod.rs +++ b/src-tauri/src/fileflow/enumeration/mod.rs @@ -1,3 +1,3 @@ pub mod database_engine; pub mod insertion_type; -pub mod separator; \ No newline at end of file +pub mod separator; diff --git a/src-tauri/src/fileflow/mod.rs b/src-tauri/src/fileflow/mod.rs index 1a626aa..b879a2f 100644 --- a/src-tauri/src/fileflow/mod.rs +++ b/src-tauri/src/fileflow/mod.rs @@ -1,5 +1,5 @@ pub mod action; pub mod database; +pub mod enumeration; pub mod stuct; pub mod utils; -pub mod enumeration; diff --git a/src-tauri/src/fileflow/stuct/db_config.rs b/src-tauri/src/fileflow/stuct/db_config.rs index 8fb44bf..d81fe75 100644 --- a/src-tauri/src/fileflow/stuct/db_config.rs +++ b/src-tauri/src/fileflow/stuct/db_config.rs @@ -1,5 +1,5 @@ -use serde::{Deserialize, Serialize}; use crate::fileflow::enumeration::database_engine::DatabaseEngine; +use serde::{Deserialize, Serialize}; #[derive(Deserialize, Clone, Serialize)] pub struct DbConfig { @@ -10,4 +10,4 @@ pub struct DbConfig { pub password: String, pub db_name: String, pub sqlite_file_path: String, -} \ No newline at end of file +} diff --git a/src-tauri/src/fileflow/stuct/insert_config.rs b/src-tauri/src/fileflow/stuct/insert_config.rs index 54bdbd2..1c38979 100644 --- a/src-tauri/src/fileflow/stuct/insert_config.rs +++ b/src-tauri/src/fileflow/stuct/insert_config.rs @@ -4,7 +4,7 @@ use serde::Deserialize; #[derive(Deserialize)] pub struct InsertConfig { - pub files_path: Vec, + pub file_path: String, pub table_name: String, pub mode: InsertionType, pub db_driver: DatabaseEngine, diff --git a/src-tauri/src/fileflow/stuct/mod.rs b/src-tauri/src/fileflow/stuct/mod.rs index 5012f4a..a4a4752 100644 --- a/src-tauri/src/fileflow/stuct/mod.rs +++ b/src-tauri/src/fileflow/stuct/mod.rs @@ -1,5 +1,5 @@ +pub mod combo_item; pub mod db_config; +pub mod download_config; pub mod insert_config; pub mod save_config; -pub mod combo_item; -pub mod download_config; diff --git a/src-tauri/src/fileflow/stuct/save_config.rs b/src-tauri/src/fileflow/stuct/save_config.rs index 1f7a942..194ab03 100644 --- a/src-tauri/src/fileflow/stuct/save_config.rs +++ b/src-tauri/src/fileflow/stuct/save_config.rs @@ -1,5 +1,5 @@ -use serde::{Deserialize, Serialize}; use crate::fileflow::enumeration::database_engine::DatabaseEngine; +use serde::{Deserialize, Serialize}; #[derive(Deserialize, Serialize, Clone)] pub struct SaveConfig { diff --git a/src-tauri/src/fileflow/utils/string_formater.rs b/src-tauri/src/fileflow/utils/string_formater.rs index dc1c98e..19cf87c 100644 --- a/src-tauri/src/fileflow/utils/string_formater.rs +++ b/src-tauri/src/fileflow/utils/string_formater.rs @@ -18,28 +18,39 @@ pub fn get_formated_column_names(headers: &[String]) -> Vec { /// Sanitize a value for safe insertion into the database pub fn sanitize_value(value: &str) -> String { - value - .trim() - .replace("'", "''") // Escape single quotes - .replace("\\", "\\\\") // Escape backslashes - .replace("\"", "") // Remove double quotes + let mut sanitized:String = String::with_capacity(value.len()); + + for c in value.trim().chars() { + match c { + '\'' => sanitized.push_str("''"), // Escape single quotes + '\\' => sanitized.push_str("\\\\"), // Escape backslashes + '\"' | '\0' => {} // Remove double quotes and null characters + '\r' | '\n' => sanitized.push(' '), // Normalize newlines + _ => sanitized.push(c), + } + } + + sanitized } /// Sanitize a column name for safe insertion into the database pub fn sanitize_column(value: &str) -> String { value .trim() - .replace("'", "") // Remove single quotes - .replace("\\", "_") // Replace backslashes with underscores - .replace("\"", "") // Remove double quotes - .replace(" ", "_") // Replace spaces with underscores + .chars() + .filter_map(|c| match c { + '\'' | '\\' | '\"' => None, // Remove these characters + ' ' => Some('_'), // Replace spaces with underscores + _ => Some(c), // Keep everything else + }) + .collect() } /// Escape values for SQL insert statement to avoid SQL injection attacks and other issues with special characters in values. -pub fn escaped_values(values: StringRecord) -> String { +pub fn escaped_record(values: StringRecord) -> String { let vec: Vec = values .iter() .map(|v| format!("'{}'", sanitize_value(v))) .collect(); vec.join(", ") -} \ No newline at end of file +} diff --git a/src-tauri/src/tests/action_test.rs b/src-tauri/src/tests/action_test.rs index f6a925b..8c5c1b2 100644 --- a/src-tauri/src/tests/action_test.rs +++ b/src-tauri/src/tests/action_test.rs @@ -1,4 +1,3 @@ -use crate::fileflow::action::insertion_mode::fast_insert; use crate::fileflow::database::connection::Connection; use crate::fileflow::enumeration::database_engine::DatabaseEngine; use crate::fileflow::stuct::db_config::DbConfig; @@ -12,6 +11,7 @@ use csv::{Reader, ReaderBuilder}; use sqlx::sqlite::SqliteRow; use sqlx::{Error, Pool, Row, Sqlite}; use std::fs::File; +use crate::fileflow::action::database_command::fast_insert; #[tokio::test] async fn test_fast_insert() { diff --git a/src-tauri/src/tests/csv_utils_test.rs b/src-tauri/src/tests/csv_utils_test.rs index 6ef8443..6cc0894 100644 --- a/src-tauri/src/tests/csv_utils_test.rs +++ b/src-tauri/src/tests/csv_utils_test.rs @@ -28,4 +28,4 @@ async fn test_read_first_line() { let first_line: String = read_first_line(&csv_file_path).expect("Failed to read first line"); assert_eq!(first_line, "header1,header2"); remove_csv_file("test_read_first_line").expect("Failed to remove csv file"); -} \ No newline at end of file +} diff --git a/src-tauri/src/tests/database_test.rs b/src-tauri/src/tests/database_test.rs index e80239e..fe0ea02 100644 --- a/src-tauri/src/tests/database_test.rs +++ b/src-tauri/src/tests/database_test.rs @@ -1,9 +1,5 @@ use crate::fileflow::database::connection::{Connection, QueryResult}; -use crate::fileflow::database::sql_builder::{ - build_create_table_sql, build_create_with_fixed_size_sql, build_drop_statement_sql, - build_prepared_statement_sql, build_query_all_tables, -}; -use crate::fileflow::enumeration::database_engine::DatabaseEngine; +use crate::fileflow::database::database_actions::export_table; use crate::fileflow::enumeration::separator::SeparatorType; use crate::fileflow::stuct::db_config::DbConfig; use crate::fileflow::stuct::download_config::DownloadConfig; @@ -13,30 +9,24 @@ use crate::tests::utils_tests::{ }; use sqlx::testing::TestTermination; use sqlx::{Error, Row}; -use std::collections::HashMap; use std::path::PathBuf; #[tokio::test] async fn test_get_connection_url() { - let pg_config: DbConfig = get_test_pg_config(); - let mariadb_config: DbConfig = get_test_maridb_config(); - let mysql_config: DbConfig = get_test_mysql_config(); - let sqlite_config: DbConfig = get_test_sqlite_config(String::new()); - assert_eq!( - Connection::get_connection_url(&pg_config).unwrap(), + Connection::get_connection_url(&get_test_pg_config()), "postgres://postgres:password@localhost:5432/test_db" ); assert_eq!( - Connection::get_connection_url(&mariadb_config).unwrap(), + Connection::get_connection_url(&get_test_maridb_config()), "mysql://root:password@localhost:3306/test_db" ); assert_eq!( - Connection::get_connection_url(&mysql_config).unwrap(), + Connection::get_connection_url(&get_test_mysql_config()), "mysql://root:password@localhost:3306/test_db" ); assert_eq!( - Connection::get_connection_url(&sqlite_config).unwrap(), + Connection::get_connection_url(&get_test_sqlite_config(String::new())), "test_db.db" ); } @@ -46,14 +36,16 @@ async fn test_sqlite_connection() { let file_path: String = create_test_db("sqlite_connection"); let config: DbConfig = get_test_sqlite_config(file_path); let conn = Connection::connect(&config).await; + assert!(conn.is_success(), "Failed to connect to the database"); assert!(conn.is_ok()); + + let conn: Connection = conn.unwrap(); + conn.disconnect(); drop(conn); remove_test_db("sqlite_connection").expect("Failed to remove test table"); } - - #[tokio::test] async fn test_query_many_with_result() { let file_path: String = create_test_db("test_query_many_with_result"); @@ -82,8 +74,6 @@ async fn test_query_many_with_result() { .await; assert!(query_result.is_ok()); - drop(conn); - let query_result: QueryResult = query_result.unwrap(); if let QueryResult::SQLite(rows) = query_result { @@ -91,41 +81,11 @@ async fn test_query_many_with_result() { assert_eq!(rows[0].len(), 2); } + conn.disconnect(); + drop(conn); remove_test_db("test_query_many_with_result").expect("Failed to remove test query"); } -#[tokio::test] -async fn test_build_query_all_tables() { - let test_cases: Vec<(&DatabaseEngine, String)> = vec![ - ( - &DatabaseEngine::MySQL, - "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'test';".into(), - ), - ( - &DatabaseEngine::MariaDB, - "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'test';".into(), - ), - ( - &DatabaseEngine::Postgres, - "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'public';" - .into(), - ), - ( - &DatabaseEngine::SQLite, - "SELECT name FROM sqlite_master WHERE type='table';".into(), - ), - ]; - - for (driver, expected) in test_cases { - assert_eq!( - build_query_all_tables(driver, "test"), - expected, - "Failed for driver: {:?}", - driver - ); - } -} - #[tokio::test] async fn test_download_table() { let file_path: String = create_test_db("test_download_table"); @@ -176,8 +136,7 @@ async fn test_download_table() { .await .expect("Failed to export table"); - // check if file exists - assert!(std::path::Path::new(&file_path).exists()); + assert!(std::path::Path::new(&file_path).exists()); // check if file exists // get the content of the file let content: String = std::fs::read_to_string(&file_path).expect("Failed to read file"); @@ -206,8 +165,8 @@ async fn test_download_table() { "Failed to export table" ); + // Clean up - drop(conn); std::fs::remove_file(&file_path).expect("Failed to remove file"); remove_test_db("test_download_table").expect("Failed to remove test table"); } diff --git a/src-tauri/src/tests/mod.rs b/src-tauri/src/tests/mod.rs index 435098b..3824798 100644 --- a/src-tauri/src/tests/mod.rs +++ b/src-tauri/src/tests/mod.rs @@ -5,8 +5,8 @@ mod csv_utils_test; #[cfg(test)] mod database_test; #[cfg(test)] +mod string_formater_test; +#[cfg(test)] mod struct_test; #[cfg(test)] mod utils_tests; -#[cfg(test)] -mod string_formater_test; diff --git a/src-tauri/src/tests/string_formater_test.rs b/src-tauri/src/tests/string_formater_test.rs index af97c80..b6b13e1 100644 --- a/src-tauri/src/tests/string_formater_test.rs +++ b/src-tauri/src/tests/string_formater_test.rs @@ -1,12 +1,12 @@ use crate::fileflow::utils::string_formater::{ - escaped_values, get_formated_column_names, sanitize_column, sanitize_value, + escaped_record, get_formated_column_names, sanitize_column, sanitize_value, }; use csv::StringRecord; #[tokio::test] async fn test_escape_values() { let record: StringRecord = StringRecord::from(vec!["value1", "value2"]); - let values: String = escaped_values(record); + let values: String = escaped_record(record); assert_eq!(values, "'value1', 'value2'"); let record: StringRecord = StringRecord::from(vec![ @@ -15,7 +15,7 @@ async fn test_escape_values() { "DELETE FROM test_table WHERE column1 = 1;", "SELECT * FROM test_table;", ]); - let values: String = escaped_values(record); + let values: String = escaped_record(record); assert_eq!(values, "'INSERT INTO test_table VALUES (1,2);', 'UPDATE test_table SET column1 = 1;', 'DELETE FROM test_table WHERE column1 = 1;', 'SELECT * FROM test_table;'"); } @@ -33,7 +33,7 @@ async fn test_sanitize_column() { assert_eq!(sanitize_column("column1"), "column1"); assert_eq!(sanitize_column("'column1'"), "column1"); assert_eq!(sanitize_column("column1'"), "column1"); - assert_eq!(sanitize_column("column1\\column2"), "column1_column2"); + assert_eq!(sanitize_column("column1\\column2"), "column1column2"); assert_eq!(sanitize_column("column1\"column2"), "column1column2"); assert_eq!(sanitize_column("column 1"), "column_1"); assert_eq!(sanitize_column("column 1'"), "column_1"); @@ -46,8 +46,8 @@ async fn test_get_formated_column_names() { vec!["header_1", "header2"] ); assert_eq!( - get_formated_column_names(&vec!["header 1".into(), String::new(), "header2".into()]), - vec!["header____1", "column_2", "header2"] + get_formated_column_names(&vec!["header 1".into(), String::new(), "header2".into(), "".into()]), + vec!["header____1", "column_2", "header2", "column_4"] ); assert_eq!( get_formated_column_names(&vec!["header'\" 1".into(), "header 2''\\".into()]), diff --git a/src-tauri/src/tests/struct_test.rs b/src-tauri/src/tests/struct_test.rs index e14f8e5..fbbb6bd 100644 --- a/src-tauri/src/tests/struct_test.rs +++ b/src-tauri/src/tests/struct_test.rs @@ -30,14 +30,14 @@ async fn test_db_config() { #[tokio::test] async fn test_insert_config() { let config = InsertConfig { - files_path: vec!["file_path".into()], + file_path: "file_path".into(), table_name: "table_name".into(), mode: InsertionType::Fast, db_driver: DatabaseEngine::Postgres, }; assert_eq!(config.db_driver, DatabaseEngine::Postgres); - assert_eq!(config.files_path, vec!["file_path"]); + assert_eq!(config.file_path, "file_path"); assert_eq!(config.table_name, "table_name"); assert_eq!(config.mode, InsertionType::Fast); } diff --git a/src/components/fileflowui/load/insert/ButtonGroupAction.tsx b/src/components/fileflowui/load/insert/ButtonGroupAction.tsx index 1a2b083..a31fbb7 100644 --- a/src/components/fileflowui/load/insert/ButtonGroupAction.tsx +++ b/src/components/fileflowui/load/insert/ButtonGroupAction.tsx @@ -5,6 +5,7 @@ import {invoke} from "@tauri-apps/api/core"; import {Tooltip, TooltipContent, TooltipProvider, TooltipTrigger} from "@/components/ui/tooltip.tsx"; import {log_error} from "@/components/hooks/utils.tsx"; import {DatabaseConfig} from "@/interfaces/DatabaseConfig.tsx"; +import {InsertionModeEnum} from "@/components/fileflowui/load/insert/Insert.tsx"; interface ButtonGroupProps { dbConfig: DatabaseConfig; @@ -14,7 +15,7 @@ interface ButtonGroupProps { tableName: string; setTableName: (name: string) => void mode: string; - setMode: (mode: "fast" | "optimized") => void; + setMode: (mode: InsertionModeEnum) => void; showLoader: boolean; setShowLoader: (showLoader: boolean) => void; } @@ -37,20 +38,24 @@ const ButtonGroupAction: React.FC = (props: ButtonGroupProps) props.setShowLoader(true); - const insert_csv_data_response: string = await invoke('insert_csv_data', { - csv: { - table_name: props.tableName, - files_path: props.filesPath, - db_driver: props.dbConfig.db_driver.toLowerCase(), - mode: props.mode, - }, - }); - - if (insert_csv_data_response.startsWith("Error:")) { - throw new Error(insert_csv_data_response); + const tableName: string[] = props.tableName.split(',').map((name) => name.trim()); + + for (const [index, file] of props.filesPath.entries()) { + const insert_csv_data_response: string = await invoke('insert_csv_data', { + csv: { + table_name: tableName[index], + file_path: file, + db_driver: props.dbConfig.db_driver.toLowerCase(), + mode: props.mode, + }, + }); + + if (insert_csv_data_response.startsWith("Error:")) { + log_error(insert_csv_data_response); + } + toast.success(insert_csv_data_response); } - toast.success(insert_csv_data_response); } catch (error) { log_error(error); } @@ -66,7 +71,7 @@ const ButtonGroupAction: React.FC = (props: ButtonGroupProps) props.updateDbConfigField('db_name', ''); props.updateDbConfigField('sqlite_file_path', ''); - props.setMode('fast'); + props.setMode(InsertionModeEnum.Fast); props.setFilesPath([]); props.setTableName(''); props.setShowLoader(false); diff --git a/src/components/fileflowui/load/insert/Insert.tsx b/src/components/fileflowui/load/insert/Insert.tsx index 6efc2af..483d8f2 100644 --- a/src/components/fileflowui/load/insert/Insert.tsx +++ b/src/components/fileflowui/load/insert/Insert.tsx @@ -10,6 +10,12 @@ import ConnectionForm from "@/components/hooks/database/ConnectionForm.tsx"; import {Card, CardContent, CardHeader, CardTitle} from "@/components/ui/card.tsx"; import {DatabaseConfig} from "@/interfaces/DatabaseConfig.tsx"; + +export enum InsertionModeEnum { + Fast = "fast", + Optimized = "optimized", +} + const Insert: React.FC = () => { const [dbConfig, setDbConfig] = useState({ @@ -25,7 +31,7 @@ const Insert: React.FC = () => { }); const [filesPath, setFilesPath] = useState([]); - const [mode, setMode] = useState<"fast" | "optimized">("fast"); + const [mode, setMode] = useState(InsertionModeEnum.Fast); const [showLoader, setShowLoader] = useState(false); const [tableName, setTableName] = useState(''); diff --git a/src/components/fileflowui/load/insert/ModeSelection.tsx b/src/components/fileflowui/load/insert/ModeSelection.tsx index 1215631..bb19feb 100644 --- a/src/components/fileflowui/load/insert/ModeSelection.tsx +++ b/src/components/fileflowui/load/insert/ModeSelection.tsx @@ -2,9 +2,10 @@ import React from 'react'; import {RadioGroup, RadioGroupItem} from "@/components/ui/radio-group.tsx"; import {Label} from "@/components/ui/label.tsx"; import {Tooltip, TooltipContent, TooltipProvider, TooltipTrigger} from "@/components/ui/tooltip.tsx"; +import {InsertionModeEnum} from "@/components/fileflowui/load/insert/Insert.tsx"; interface ModeSelectionProps { - setMode: (mode: "fast" | "optimized") => void; + setMode: (mode: InsertionModeEnum) => void; } const ModeSelection: React.FC = (props: ModeSelectionProps) => { @@ -12,7 +13,7 @@ const ModeSelection: React.FC = (props: ModeSelectionProps)
{ - if (e === "fast" || e === "optimized") { + if (e === InsertionModeEnum.Fast || e === InsertionModeEnum.Optimized) { props.setMode(e); } } @@ -21,7 +22,7 @@ const ModeSelection: React.FC = (props: ModeSelectionProps)
- +
@@ -36,7 +37,7 @@ const ModeSelection: React.FC = (props: ModeSelectionProps)
- +
From 4ea2c2c052b017b57b895d68e04d128f489d460f Mon Sep 17 00:00:00 2001 From: Maxime Colliat Date: Fri, 4 Apr 2025 09:59:46 +0200 Subject: [PATCH 5/6] Update vendor --- package.json | 16 +- pnpm-lock.yaml | 1283 +++++++++++++++++++++--------------------- src-tauri/Cargo.lock | 4 +- 3 files changed, 661 insertions(+), 642 deletions(-) diff --git a/package.json b/package.json index e784048..3174f82 100644 --- a/package.json +++ b/package.json @@ -24,12 +24,12 @@ "@radix-ui/react-switch": "^1.1.3", "@radix-ui/react-tabs": "^1.1.3", "@radix-ui/react-tooltip": "^1.1.8", - "@tauri-apps/api": "^2.3.0", - "@tauri-apps/plugin-dialog": "~2.2.0", + "@tauri-apps/api": "^2.4.1", + "@tauri-apps/plugin-dialog": "~2.2.1", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "1.0.0", - "framer-motion": "^12.5.0", + "framer-motion": "^12.6.3", "lucide-react": "^0.441.0", "next-themes": "^0.4.6", "react": "^18.3.1", @@ -40,15 +40,15 @@ "tailwindcss-animate": "^1.0.7" }, "devDependencies": { - "@tauri-apps/cli": "^2.3.1", - "@types/node": "^22.13.10", - "@types/react": "^18.3.18", - "@types/react-dom": "^18.3.5", + "@tauri-apps/cli": "^2.4.1", + "@types/node": "^22.14.0", + "@types/react": "^18.3.20", + "@types/react-dom": "^18.3.6", "@vitejs/plugin-react": "^4.3.4", "autoprefixer": "^10.4.21", "postcss": "^8.5.3", "tailwindcss": "^3.4.17", "typescript": "^5.8.2", - "vite": "^5.4.14" + "vite": "^5.4.17" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 81fc368..8cd8dab 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,52 +10,52 @@ importers: dependencies: '@radix-ui/react-checkbox': specifier: ^1.1.4 - version: 1.1.4(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-dialog': specifier: ^1.1.6 - version: 1.1.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 1.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-dropdown-menu': specifier: ^2.1.6 - version: 2.1.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 2.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-icons': specifier: ^1.3.2 version: 1.3.2(react@18.3.1) '@radix-ui/react-label': specifier: ^2.1.2 - version: 2.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 2.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-menubar': specifier: ^1.1.6 - version: 1.1.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 1.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-popover': specifier: ^1.1.6 - version: 1.1.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 1.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-radio-group': specifier: ^1.2.3 - version: 1.2.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 1.2.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-select': specifier: ^2.1.6 - version: 2.1.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 2.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-separator': specifier: ^1.1.2 - version: 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-slot': specifier: ^1.1.2 - version: 1.1.2(@types/react@18.3.18)(react@18.3.1) + version: 1.1.2(@types/react@18.3.20)(react@18.3.1) '@radix-ui/react-switch': specifier: ^1.1.3 - version: 1.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-tabs': specifier: ^1.1.3 - version: 1.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-tooltip': specifier: ^1.1.8 - version: 1.1.8(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 1.1.8(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@tauri-apps/api': - specifier: ^2.3.0 - version: 2.3.0 + specifier: ^2.4.1 + version: 2.4.1 '@tauri-apps/plugin-dialog': - specifier: ~2.2.0 - version: 2.2.0 + specifier: ~2.2.1 + version: 2.2.1 class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -64,10 +64,10 @@ importers: version: 2.1.1 cmdk: specifier: 1.0.0 - version: 1.0.0(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 1.0.0(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) framer-motion: - specifier: ^12.5.0 - version: 12.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^12.6.3 + version: 12.6.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) lucide-react: specifier: ^0.441.0 version: 0.441.0(react@18.3.1) @@ -94,20 +94,20 @@ importers: version: 1.0.7(tailwindcss@3.4.17) devDependencies: '@tauri-apps/cli': - specifier: ^2.3.1 - version: 2.3.1 + specifier: ^2.4.1 + version: 2.4.1 '@types/node': - specifier: ^22.13.10 - version: 22.13.10 + specifier: ^22.14.0 + version: 22.14.0 '@types/react': - specifier: ^18.3.18 - version: 18.3.18 + specifier: ^18.3.20 + version: 18.3.20 '@types/react-dom': - specifier: ^18.3.5 - version: 18.3.5(@types/react@18.3.18) + specifier: ^18.3.6 + version: 18.3.6(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.4 - version: 4.3.4(vite@5.4.14(@types/node@22.13.10)) + version: 4.3.4(vite@5.4.17(@types/node@22.14.0)) autoprefixer: specifier: ^10.4.21 version: 10.4.21(postcss@8.5.3) @@ -121,8 +121,8 @@ importers: specifier: ^5.8.2 version: 5.8.2 vite: - specifier: ^5.4.14 - version: 5.4.14(@types/node@22.13.10) + specifier: ^5.4.17 + version: 5.4.17(@types/node@22.14.0) packages: @@ -146,12 +146,12 @@ packages: resolution: {integrity: sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==} engines: {node: '>=6.9.0'} - '@babel/generator@7.26.10': - resolution: {integrity: sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==} + '@babel/generator@7.27.0': + resolution: {integrity: sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.26.5': - resolution: {integrity: sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==} + '@babel/helper-compilation-targets@7.27.0': + resolution: {integrity: sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==} engines: {node: '>=6.9.0'} '@babel/helper-module-imports@7.25.9': @@ -180,12 +180,12 @@ packages: resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.26.10': - resolution: {integrity: sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==} + '@babel/helpers@7.27.0': + resolution: {integrity: sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==} engines: {node: '>=6.9.0'} - '@babel/parser@7.26.10': - resolution: {integrity: sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==} + '@babel/parser@7.27.0': + resolution: {integrity: sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==} engines: {node: '>=6.0.0'} hasBin: true @@ -201,20 +201,20 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/runtime@7.26.10': - resolution: {integrity: sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==} + '@babel/runtime@7.27.0': + resolution: {integrity: sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==} engines: {node: '>=6.9.0'} - '@babel/template@7.26.9': - resolution: {integrity: sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==} + '@babel/template@7.27.0': + resolution: {integrity: sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.26.10': - resolution: {integrity: sha512-k8NuDrxr0WrPH5Aupqb2LCVURP/S0vBEn5mK6iH+GIYob66U5EtoZvcdudR2jQ4cmTwhEwW1DLB+Yyas9zjF6A==} + '@babel/traverse@7.27.0': + resolution: {integrity: sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==} engines: {node: '>=6.9.0'} - '@babel/types@7.26.10': - resolution: {integrity: sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==} + '@babel/types@7.27.0': + resolution: {integrity: sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==} engines: {node: '>=6.9.0'} '@esbuild/aix-ppc64@0.21.5': @@ -1004,200 +1004,211 @@ packages: resolution: {integrity: sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==} engines: {node: '>=14.0.0'} - '@rollup/rollup-android-arm-eabi@4.35.0': - resolution: {integrity: sha512-uYQ2WfPaqz5QtVgMxfN6NpLD+no0MYHDBywl7itPYd3K5TjjSghNKmX8ic9S8NU8w81NVhJv/XojcHptRly7qQ==} + '@rollup/rollup-android-arm-eabi@4.39.0': + resolution: {integrity: sha512-lGVys55Qb00Wvh8DMAocp5kIcaNzEFTmGhfFd88LfaogYTRKrdxgtlO5H6S49v2Nd8R2C6wLOal0qv6/kCkOwA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.35.0': - resolution: {integrity: sha512-FtKddj9XZudurLhdJnBl9fl6BwCJ3ky8riCXjEw3/UIbjmIY58ppWwPEvU3fNu+W7FUsAsB1CdH+7EQE6CXAPA==} + '@rollup/rollup-android-arm64@4.39.0': + resolution: {integrity: sha512-It9+M1zE31KWfqh/0cJLrrsCPiF72PoJjIChLX+rEcujVRCb4NLQ5QzFkzIZW8Kn8FTbvGQBY5TkKBau3S8cCQ==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.35.0': - resolution: {integrity: sha512-Uk+GjOJR6CY844/q6r5DR/6lkPFOw0hjfOIzVx22THJXMxktXG6CbejseJFznU8vHcEBLpiXKY3/6xc+cBm65Q==} + '@rollup/rollup-darwin-arm64@4.39.0': + resolution: {integrity: sha512-lXQnhpFDOKDXiGxsU9/l8UEGGM65comrQuZ+lDcGUx+9YQ9dKpF3rSEGepyeR5AHZ0b5RgiligsBhWZfSSQh8Q==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.35.0': - resolution: {integrity: sha512-3IrHjfAS6Vkp+5bISNQnPogRAW5GAV1n+bNCrDwXmfMHbPl5EhTmWtfmwlJxFRUCBZ+tZ/OxDyU08aF6NI/N5Q==} + '@rollup/rollup-darwin-x64@4.39.0': + resolution: {integrity: sha512-mKXpNZLvtEbgu6WCkNij7CGycdw9cJi2k9v0noMb++Vab12GZjFgUXD69ilAbBh034Zwn95c2PNSz9xM7KYEAQ==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.35.0': - resolution: {integrity: sha512-sxjoD/6F9cDLSELuLNnY0fOrM9WA0KrM0vWm57XhrIMf5FGiN8D0l7fn+bpUeBSU7dCgPV2oX4zHAsAXyHFGcQ==} + '@rollup/rollup-freebsd-arm64@4.39.0': + resolution: {integrity: sha512-jivRRlh2Lod/KvDZx2zUR+I4iBfHcu2V/BA2vasUtdtTN2Uk3jfcZczLa81ESHZHPHy4ih3T/W5rPFZ/hX7RtQ==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.35.0': - resolution: {integrity: sha512-2mpHCeRuD1u/2kruUiHSsnjWtHjqVbzhBkNVQ1aVD63CcexKVcQGwJ2g5VphOd84GvxfSvnnlEyBtQCE5hxVVw==} + '@rollup/rollup-freebsd-x64@4.39.0': + resolution: {integrity: sha512-8RXIWvYIRK9nO+bhVz8DwLBepcptw633gv/QT4015CpJ0Ht8punmoHU/DuEd3iw9Hr8UwUV+t+VNNuZIWYeY7Q==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.35.0': - resolution: {integrity: sha512-mrA0v3QMy6ZSvEuLs0dMxcO2LnaCONs1Z73GUDBHWbY8tFFocM6yl7YyMu7rz4zS81NDSqhrUuolyZXGi8TEqg==} + '@rollup/rollup-linux-arm-gnueabihf@4.39.0': + resolution: {integrity: sha512-mz5POx5Zu58f2xAG5RaRRhp3IZDK7zXGk5sdEDj4o96HeaXhlUwmLFzNlc4hCQi5sGdR12VDgEUqVSHer0lI9g==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.35.0': - resolution: {integrity: sha512-DnYhhzcvTAKNexIql8pFajr0PiDGrIsBYPRvCKlA5ixSS3uwo/CWNZxB09jhIapEIg945KOzcYEAGGSmTSpk7A==} + '@rollup/rollup-linux-arm-musleabihf@4.39.0': + resolution: {integrity: sha512-+YDwhM6gUAyakl0CD+bMFpdmwIoRDzZYaTWV3SDRBGkMU/VpIBYXXEvkEcTagw/7VVkL2vA29zU4UVy1mP0/Yw==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.35.0': - resolution: {integrity: sha512-uagpnH2M2g2b5iLsCTZ35CL1FgyuzzJQ8L9VtlJ+FckBXroTwNOaD0z0/UF+k5K3aNQjbm8LIVpxykUOQt1m/A==} + '@rollup/rollup-linux-arm64-gnu@4.39.0': + resolution: {integrity: sha512-EKf7iF7aK36eEChvlgxGnk7pdJfzfQbNvGV/+l98iiMwU23MwvmV0Ty3pJ0p5WQfm3JRHOytSIqD9LB7Bq7xdQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.35.0': - resolution: {integrity: sha512-XQxVOCd6VJeHQA/7YcqyV0/88N6ysSVzRjJ9I9UA/xXpEsjvAgDTgH3wQYz5bmr7SPtVK2TsP2fQ2N9L4ukoUg==} + '@rollup/rollup-linux-arm64-musl@4.39.0': + resolution: {integrity: sha512-vYanR6MtqC7Z2SNr8gzVnzUul09Wi1kZqJaek3KcIlI/wq5Xtq4ZPIZ0Mr/st/sv/NnaPwy/D4yXg5x0B3aUUA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.35.0': - resolution: {integrity: sha512-5pMT5PzfgwcXEwOaSrqVsz/LvjDZt+vQ8RT/70yhPU06PTuq8WaHhfT1LW+cdD7mW6i/J5/XIkX/1tCAkh1W6g==} + '@rollup/rollup-linux-loongarch64-gnu@4.39.0': + resolution: {integrity: sha512-NMRUT40+h0FBa5fb+cpxtZoGAggRem16ocVKIv5gDB5uLDgBIwrIsXlGqYbLwW8YyO3WVTk1FkFDjMETYlDqiw==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.35.0': - resolution: {integrity: sha512-c+zkcvbhbXF98f4CtEIP1EBA/lCic5xB0lToneZYvMeKu5Kamq3O8gqrxiYYLzlZH6E3Aq+TSW86E4ay8iD8EA==} + '@rollup/rollup-linux-powerpc64le-gnu@4.39.0': + resolution: {integrity: sha512-0pCNnmxgduJ3YRt+D+kJ6Ai/r+TaePu9ZLENl+ZDV/CdVczXl95CbIiwwswu4L+K7uOIGf6tMo2vm8uadRaICQ==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.35.0': - resolution: {integrity: sha512-s91fuAHdOwH/Tad2tzTtPX7UZyytHIRR6V4+2IGlV0Cej5rkG0R61SX4l4y9sh0JBibMiploZx3oHKPnQBKe4g==} + '@rollup/rollup-linux-riscv64-gnu@4.39.0': + resolution: {integrity: sha512-t7j5Zhr7S4bBtksT73bO6c3Qa2AV/HqiGlj9+KB3gNF5upcVkx+HLgxTm8DK4OkzsOYqbdqbLKwvGMhylJCPhQ==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.35.0': - resolution: {integrity: sha512-hQRkPQPLYJZYGP+Hj4fR9dDBMIM7zrzJDWFEMPdTnTy95Ljnv0/4w/ixFw3pTBMEuuEuoqtBINYND4M7ujcuQw==} + '@rollup/rollup-linux-riscv64-musl@4.39.0': + resolution: {integrity: sha512-m6cwI86IvQ7M93MQ2RF5SP8tUjD39Y7rjb1qjHgYh28uAPVU8+k/xYWvxRO3/tBN2pZkSMa5RjnPuUIbrwVxeA==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.39.0': + resolution: {integrity: sha512-iRDJd2ebMunnk2rsSBYlsptCyuINvxUfGwOUldjv5M4tpa93K8tFMeYGpNk2+Nxl+OBJnBzy2/JCscGeO507kA==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.35.0': - resolution: {integrity: sha512-Pim1T8rXOri+0HmV4CdKSGrqcBWX0d1HoPnQ0uw0bdp1aP5SdQVNBy8LjYncvnLgu3fnnCt17xjWGd4cqh8/hA==} + '@rollup/rollup-linux-x64-gnu@4.39.0': + resolution: {integrity: sha512-t9jqYw27R6Lx0XKfEFe5vUeEJ5pF3SGIM6gTfONSMb7DuG6z6wfj2yjcoZxHg129veTqU7+wOhY6GX8wmf90dA==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.35.0': - resolution: {integrity: sha512-QysqXzYiDvQWfUiTm8XmJNO2zm9yC9P/2Gkrwg2dH9cxotQzunBHYr6jk4SujCTqnfGxduOmQcI7c2ryuW8XVg==} + '@rollup/rollup-linux-x64-musl@4.39.0': + resolution: {integrity: sha512-ThFdkrFDP55AIsIZDKSBWEt/JcWlCzydbZHinZ0F/r1h83qbGeenCt/G/wG2O0reuENDD2tawfAj2s8VK7Bugg==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.35.0': - resolution: {integrity: sha512-OUOlGqPkVJCdJETKOCEf1mw848ZyJ5w50/rZ/3IBQVdLfR5jk/6Sr5m3iO2tdPgwo0x7VcncYuOvMhBWZq8ayg==} + '@rollup/rollup-win32-arm64-msvc@4.39.0': + resolution: {integrity: sha512-jDrLm6yUtbOg2TYB3sBF3acUnAwsIksEYjLeHL+TJv9jg+TmTwdyjnDex27jqEMakNKf3RwwPahDIt7QXCSqRQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.35.0': - resolution: {integrity: sha512-2/lsgejMrtwQe44glq7AFFHLfJBPafpsTa6JvP2NGef/ifOa4KBoglVf7AKN7EV9o32evBPRqfg96fEHzWo5kw==} + '@rollup/rollup-win32-ia32-msvc@4.39.0': + resolution: {integrity: sha512-6w9uMuza+LbLCVoNKL5FSLE7yvYkq9laSd09bwS0tMjkwXrmib/4KmoJcrKhLWHvw19mwU+33ndC69T7weNNjQ==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.35.0': - resolution: {integrity: sha512-PIQeY5XDkrOysbQblSW7v3l1MDZzkTEzAfTPkj5VAu3FW8fS4ynyLg2sINp0fp3SjZ8xkRYpLqoKcYqAkhU1dw==} + '@rollup/rollup-win32-x64-msvc@4.39.0': + resolution: {integrity: sha512-yAkUOkIKZlK5dl7u6dg897doBgLXmUHhIINM2c+sND3DZwnrdQkkSiDh7N75Ll4mM4dxSkYfXqU9fW3lLkMFug==} cpu: [x64] os: [win32] - '@tauri-apps/api@2.3.0': - resolution: {integrity: sha512-33Z+0lX2wgZbx1SPFfqvzI6su63hCBkbzv+5NexeYjIx7WA9htdOKoRR7Dh3dJyltqS5/J8vQFyybiRoaL0hlA==} + '@tauri-apps/api@2.4.1': + resolution: {integrity: sha512-5sYwZCSJb6PBGbBL4kt7CnE5HHbBqwH+ovmOW6ZVju3nX4E3JX6tt2kRklFEH7xMOIwR0btRkZktuLhKvyEQYg==} - '@tauri-apps/cli-darwin-arm64@2.3.1': - resolution: {integrity: sha512-TOhSdsXYt+f+asRU+Dl+Wufglj/7+CX9h8RO4hl5k7D6lR4L8yTtdhpS7btaclOMmjYC4piNfJE70GoxhOoYWw==} + '@tauri-apps/cli-darwin-arm64@2.4.1': + resolution: {integrity: sha512-QME7s8XQwy3LWClTVlIlwXVSLKkeJ/z88pr917Mtn9spYOjnBfsgHAgGdmpWD3NfJxjg7CtLbhH49DxoFL+hLg==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@tauri-apps/cli-darwin-x64@2.3.1': - resolution: {integrity: sha512-LDwGg3AuBQ3aCeMAFaFwt0MSGOVFoXuXEe0z4QxQ7jZE5tdAOhKABaq4i569V5lShCgQZ6nLD/tmA5+GipvHnA==} + '@tauri-apps/cli-darwin-x64@2.4.1': + resolution: {integrity: sha512-/r89IcW6Ya1sEsFUEH7wLNruDTj7WmDWKGpPy7gATFtQr5JEY4heernqE82isjTUimnHZD8SCr0jA3NceI4ybw==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@tauri-apps/cli-linux-arm-gnueabihf@2.3.1': - resolution: {integrity: sha512-hu3HpbbtJBvHXw5i54QHwLxOUoXWqhf7CL2YYSPOrWEEQo10NKddulP61L5gfr5z+bSSaitfLwqgTidgnaNJCA==} + '@tauri-apps/cli-linux-arm-gnueabihf@2.4.1': + resolution: {integrity: sha512-9tDijkRB+CchAGjXxYdY9l/XzFpLp1yihUtGXJz9eh+3qIoRI043n3e+6xmU8ZURr7XPnu+R4sCmXs6HD+NCEQ==} engines: {node: '>= 10'} cpu: [arm] os: [linux] - '@tauri-apps/cli-linux-arm64-gnu@2.3.1': - resolution: {integrity: sha512-mEGgwkiGSKYXWHhGodo7zU9PCd2I/d6KkR+Wp1nzK+DxsCrEK6yJ5XxYLSQSDcKkM4dCxpVEPUiVMbDhmn08jg==} + '@tauri-apps/cli-linux-arm64-gnu@2.4.1': + resolution: {integrity: sha512-pnFGDEXBAzS4iDYAVxTRhAzNu3K2XPGflYyBc0czfHDBXopqRgMyj5Q9Wj7HAwv6cM8BqzXINxnb2ZJFGmbSgA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@tauri-apps/cli-linux-arm64-musl@2.3.1': - resolution: {integrity: sha512-tqQkafikGfnc7ISnGjSYkbpnzJKEyO8XSa0YOXTAL3J8R5Pss5ZIZY7G8kq1mwQSR/dPVR1ZLTVXgZGuysjP8w==} + '@tauri-apps/cli-linux-arm64-musl@2.4.1': + resolution: {integrity: sha512-Hp0zXgeZNKmT+eoJSCxSBUm2QndNuRxR55tmIeNm3vbyUMJN/49uW7nurZ5fBPsacN4Pzwlx1dIMK+Gnr9A69w==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@tauri-apps/cli-linux-x64-gnu@2.3.1': - resolution: {integrity: sha512-I3puDJ2wGEauXlXbzIHn2etz78TaWs1cpN6zre02maHr6ZR7nf7euTCOGPhhfoMG0opA5mT/eLuYpVw648/VAA==} + '@tauri-apps/cli-linux-riscv64-gnu@2.4.1': + resolution: {integrity: sha512-3T3bo2E4fdYRvzcXheWUeQOVB+LunEEi92iPRgOyuSVexVE4cmHYl+MPJF+EUV28Et0hIVTsHibmDO0/04lAFg==} + engines: {node: '>= 10'} + cpu: [riscv64] + os: [linux] + + '@tauri-apps/cli-linux-x64-gnu@2.4.1': + resolution: {integrity: sha512-kLN0FdNONO+2i+OpU9+mm6oTGufRC00e197TtwjpC0N6K2K8130w7Q3FeODIM2CMyg0ov3tH+QWqKW7GNhHFzg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@tauri-apps/cli-linux-x64-musl@2.3.1': - resolution: {integrity: sha512-rbWiCOBuQN7tPySkUyBs914uUikE3mEUOqV/IFospvKESw4UC3G1DL5+ybfXH7Orb8/in3JpJuVzYQjo+OSbBA==} + '@tauri-apps/cli-linux-x64-musl@2.4.1': + resolution: {integrity: sha512-a8exvA5Ub9eg66a6hsMQKJIkf63QAf9OdiuFKOsEnKZkNN2x0NLgfvEcqdw88VY0UMs9dBoZ1AGbWMeYnLrLwQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@tauri-apps/cli-win32-arm64-msvc@2.3.1': - resolution: {integrity: sha512-PdTmUzSeTHjJuBpCV7L+V29fPhPtToU+NZU46slHKSA1aT38MiFDXBZ/6P5Zudrt9QPMfIubqnJKbK8Ivvv7Ww==} + '@tauri-apps/cli-win32-arm64-msvc@2.4.1': + resolution: {integrity: sha512-4JFrslsMCJQG1c573T9uqQSAbF3j/tMKkMWzsIssv8jvPiP++OG61A2/F+y9te9/Q/O95cKhDK63kaiO5xQaeg==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@tauri-apps/cli-win32-ia32-msvc@2.3.1': - resolution: {integrity: sha512-K/Xa97kspWT4UWj3t26lL2D3QsopTAxS7kWi5kObdqtAGn3qD52qBi24FH38TdvHYz4QlnLIb30TukviCgh4gw==} + '@tauri-apps/cli-win32-ia32-msvc@2.4.1': + resolution: {integrity: sha512-9eXfFORehYSCRwxg2KodfmX/mhr50CI7wyBYGbPLePCjr5z0jK/9IyW6r0tC+ZVjwpX48dkk7hKiUgI25jHjzA==} engines: {node: '>= 10'} cpu: [ia32] os: [win32] - '@tauri-apps/cli-win32-x64-msvc@2.3.1': - resolution: {integrity: sha512-RgwzXbP8gAno3kQEsybMtgLp6D1Z1Nec2cftryYbPTJmoMJs6e4qgtxuTSbUz5SKnHe8rGgMiFSvEGoHvbG72Q==} + '@tauri-apps/cli-win32-x64-msvc@2.4.1': + resolution: {integrity: sha512-60a4Ov7Jrwqz2hzDltlS7301dhSAmM9dxo+IRBD3xz7yobKrgaHXYpWvnRomYItHcDd51VaKc9292H8/eE/gsw==} engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@tauri-apps/cli@2.3.1': - resolution: {integrity: sha512-xewcw/ZsCqgilTy2h7+pp2Baxoy7zLR2wXOV7SZLzkb6SshHVbm1BFAjn8iFATURRW85KLzl6wSGJ2dQHjVHqw==} + '@tauri-apps/cli@2.4.1': + resolution: {integrity: sha512-9Ta81jx9+57FhtU/mPIckDcOBtPTUdKM75t4+aA0X84b8Sclb0jy1xA8NplmcRzp2fsfIHNngU2NiRxsW5+yOQ==} engines: {node: '>= 10'} hasBin: true - '@tauri-apps/plugin-dialog@2.2.0': - resolution: {integrity: sha512-6bLkYK68zyK31418AK5fNccCdVuRnNpbxquCl8IqgFByOgWFivbiIlvb79wpSXi0O+8k8RCSsIpOquebusRVSg==} + '@tauri-apps/plugin-dialog@2.2.1': + resolution: {integrity: sha512-wZmCouo4PgTosh/UoejPw9DPs6RllS5Pp3fuOV2JobCu36mR5AXU2MzU9NZiVaFi/5Zfc8RN0IhcZHnksJ1o8A==} '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} - '@types/babel__generator@7.6.8': - resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} '@types/babel__template@7.4.4': resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - '@types/babel__traverse@7.20.6': - resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} + '@types/babel__traverse@7.20.7': + resolution: {integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==} - '@types/estree@1.0.6': - resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + '@types/estree@1.0.7': + resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} - '@types/node@22.13.10': - resolution: {integrity: sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==} + '@types/node@22.14.0': + resolution: {integrity: sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==} '@types/prop-types@15.7.14': resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==} - '@types/react-dom@18.3.5': - resolution: {integrity: sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==} + '@types/react-dom@18.3.6': + resolution: {integrity: sha512-nf22//wEbKXusP6E9pfOCDwFdHAX4u172eaJI4YkDRQEZiorm6KfYnSC2SWLDMVWUOWPERmJnN0ujeAfTBLvrw==} peerDependencies: '@types/react': ^18.0.0 - '@types/react@18.3.18': - resolution: {integrity: sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==} + '@types/react@18.3.20': + resolution: {integrity: sha512-IPaCZN7PShZK/3t6Q87pfTkRm6oLTd4vztyoj+cbHUF1g3FfVb2tFIL79uCRKEfv16AhqDMBywP2VW3KIZUvcg==} '@vitejs/plugin-react@4.3.4': resolution: {integrity: sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==} @@ -1265,8 +1276,8 @@ packages: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} - caniuse-lite@1.0.30001704: - resolution: {integrity: sha512-+L2IgBbV6gXB4ETf0keSvLr7JUrRVbIaB/lrQ1+z8mRcQiisG5k+lG6O4n6Y5q6f5EuNfaYXKgymucphlEXQew==} + caniuse-lite@1.0.30001710: + resolution: {integrity: sha512-B5C0I0UmaGqHgo5FuqJ7hBd4L57A4dDD+Xi+XX1nXOoxGeDdY4Ko38qJYOyqznBVJEqON5p8P1x5zRR3+rsnxA==} chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} @@ -1332,8 +1343,8 @@ packages: eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - electron-to-chromium@1.5.116: - resolution: {integrity: sha512-mufxTCJzLBQVvSdZzX1s5YAuXsN1M4tTyYxOOL1TcSKtIzQ9rjIrm7yFK80rN5dwGTePgdoABDSHpuVtRQh0Zw==} + electron-to-chromium@1.5.131: + resolution: {integrity: sha512-fJFRYXVEJgDCiqFOgRGJm8XR97hZ13tw7FXI9k2yC5hgY+nyzC2tMO8baq1cQR7Ur58iCkASx2zrkZPZUnfzPg==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1368,8 +1379,8 @@ packages: fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} - framer-motion@12.5.0: - resolution: {integrity: sha512-buPlioFbH9/W7rDzYh1C09AuZHAk2D1xTA1BlounJ2Rb9aRg84OXexP0GLd+R83v0khURdMX7b5MKnGTaSg5iA==} + framer-motion@12.6.3: + resolution: {integrity: sha512-2hsqknz23aloK85bzMc9nSR2/JP+fValQ459ZTVElFQ0xgwR2YqNjYSuDZdFBPOwVCt4Q9jgyTt6hg6sVOALzw==} peerDependencies: '@emotion/is-prop-valid': '*' react: ^18.0.0 || ^19.0.0 @@ -1503,11 +1514,11 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} - motion-dom@12.5.0: - resolution: {integrity: sha512-uH2PETDh7m+Hjd1UQQ56yHqwn83SAwNjimNPE/kC+Kds0t4Yh7+29rfo5wezVFpPOv57U4IuWved5d1x0kNhbQ==} + motion-dom@12.6.3: + resolution: {integrity: sha512-gRY08RjcnzgFYLemUZ1lo/e9RkBxR+6d4BRvoeZDSeArG4XQXERSPapKl3LNQRu22Sndjf1h+iavgY0O4NrYqA==} - motion-utils@12.5.0: - resolution: {integrity: sha512-+hFFzvimn0sBMP9iPxBa9OtRX35ZQ3py0UHnb8U29VD+d8lQ8zH3dTygJWqK7av2v6yhg7scj9iZuvTS0f4+SA==} + motion-utils@12.6.3: + resolution: {integrity: sha512-R/b3Ia2VxtTNZ4LTEO5pKYau1OUNHOuUfxuP0WFCTDYdHkeTBR9UtxR1cc8mDmKr8PEhmmfnTKGz3rSMjNRoRg==} ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -1515,8 +1526,8 @@ packages: mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - nanoid@3.3.9: - resolution: {integrity: sha512-SppoicMGpZvbF1l3z4x7No3OlIjP7QJvC9XR7AhZr1kL133KHnKPztkKDc+Ir4aJ/1VhTySrtKhrsycmrMQfvg==} + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -1570,8 +1581,8 @@ packages: resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} engines: {node: '>=0.10.0'} - pirates@4.0.6: - resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} postcss-import@15.1.0: @@ -1703,8 +1714,8 @@ packages: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rollup@4.35.0: - resolution: {integrity: sha512-kg6oI4g+vc41vePJyO6dHt/yl0Rz3Thv0kJeVQ3D1kS3E5XSuKbPc29G4IpT/Kv1KQwgHVcN+HtyS+HYLNSvQg==} + rollup@4.39.0: + resolution: {integrity: sha512-thI8kNc02yNvnmJp8dr3fNWJ9tCONDhp6TV35X6HkKGGs9E6q7YWCHbe5vKiTa7TAiNcFEmXKj3X/pG2b3ci0g==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -1800,8 +1811,8 @@ packages: engines: {node: '>=14.17'} hasBin: true - undici-types@6.20.0: - resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} update-browserslist-db@1.1.3: resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} @@ -1832,8 +1843,8 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - vite@5.4.14: - resolution: {integrity: sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==} + vite@5.4.17: + resolution: {integrity: sha512-5+VqZryDj4wgCs55o9Lp+p8GE78TLVg0lasCH5xFZ4jacZjtqZa6JUw9/p0WeAojaOfncSM6v77InkFPGnvPvg==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -1879,8 +1890,8 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yaml@2.7.0: - resolution: {integrity: sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==} + yaml@2.7.1: + resolution: {integrity: sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==} engines: {node: '>= 14'} hasBin: true @@ -1905,14 +1916,14 @@ snapshots: dependencies: '@ampproject/remapping': 2.3.0 '@babel/code-frame': 7.26.2 - '@babel/generator': 7.26.10 - '@babel/helper-compilation-targets': 7.26.5 + '@babel/generator': 7.27.0 + '@babel/helper-compilation-targets': 7.27.0 '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.10) - '@babel/helpers': 7.26.10 - '@babel/parser': 7.26.10 - '@babel/template': 7.26.9 - '@babel/traverse': 7.26.10 - '@babel/types': 7.26.10 + '@babel/helpers': 7.27.0 + '@babel/parser': 7.27.0 + '@babel/template': 7.27.0 + '@babel/traverse': 7.27.0 + '@babel/types': 7.27.0 convert-source-map: 2.0.0 debug: 4.4.0 gensync: 1.0.0-beta.2 @@ -1921,15 +1932,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/generator@7.26.10': + '@babel/generator@7.27.0': dependencies: - '@babel/parser': 7.26.10 - '@babel/types': 7.26.10 + '@babel/parser': 7.27.0 + '@babel/types': 7.27.0 '@jridgewell/gen-mapping': 0.3.8 '@jridgewell/trace-mapping': 0.3.25 jsesc: 3.1.0 - '@babel/helper-compilation-targets@7.26.5': + '@babel/helper-compilation-targets@7.27.0': dependencies: '@babel/compat-data': 7.26.8 '@babel/helper-validator-option': 7.25.9 @@ -1939,8 +1950,8 @@ snapshots: '@babel/helper-module-imports@7.25.9': dependencies: - '@babel/traverse': 7.26.10 - '@babel/types': 7.26.10 + '@babel/traverse': 7.27.0 + '@babel/types': 7.27.0 transitivePeerDependencies: - supports-color @@ -1949,7 +1960,7 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-module-imports': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 - '@babel/traverse': 7.26.10 + '@babel/traverse': 7.27.0 transitivePeerDependencies: - supports-color @@ -1961,14 +1972,14 @@ snapshots: '@babel/helper-validator-option@7.25.9': {} - '@babel/helpers@7.26.10': + '@babel/helpers@7.27.0': dependencies: - '@babel/template': 7.26.9 - '@babel/types': 7.26.10 + '@babel/template': 7.27.0 + '@babel/types': 7.27.0 - '@babel/parser@7.26.10': + '@babel/parser@7.27.0': dependencies: - '@babel/types': 7.26.10 + '@babel/types': 7.27.0 '@babel/plugin-transform-react-jsx-self@7.25.9(@babel/core@7.26.10)': dependencies: @@ -1980,29 +1991,29 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.26.5 - '@babel/runtime@7.26.10': + '@babel/runtime@7.27.0': dependencies: regenerator-runtime: 0.14.1 - '@babel/template@7.26.9': + '@babel/template@7.27.0': dependencies: '@babel/code-frame': 7.26.2 - '@babel/parser': 7.26.10 - '@babel/types': 7.26.10 + '@babel/parser': 7.27.0 + '@babel/types': 7.27.0 - '@babel/traverse@7.26.10': + '@babel/traverse@7.27.0': dependencies: '@babel/code-frame': 7.26.2 - '@babel/generator': 7.26.10 - '@babel/parser': 7.26.10 - '@babel/template': 7.26.9 - '@babel/types': 7.26.10 + '@babel/generator': 7.27.0 + '@babel/parser': 7.27.0 + '@babel/template': 7.27.0 + '@babel/types': 7.27.0 debug: 4.4.0 globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/types@7.26.10': + '@babel/types@7.27.0': dependencies: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 @@ -2138,755 +2149,762 @@ snapshots: '@radix-ui/primitive@1.0.1': dependencies: - '@babel/runtime': 7.26.10 + '@babel/runtime': 7.27.0 '@radix-ui/primitive@1.1.1': {} - '@radix-ui/react-arrow@1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-arrow@1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-checkbox@1.1.4(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-checkbox@1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-collection@1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-collection@1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.2(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-compose-refs@1.0.1(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-compose-refs@1.0.1(@types/react@18.3.20)(react@18.3.1)': dependencies: - '@babel/runtime': 7.26.10 + '@babel/runtime': 7.27.0 react: 18.3.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - '@radix-ui/react-compose-refs@1.1.1(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-compose-refs@1.1.1(@types/react@18.3.20)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - '@radix-ui/react-context@1.0.1(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-context@1.0.1(@types/react@18.3.20)(react@18.3.1)': dependencies: - '@babel/runtime': 7.26.10 + '@babel/runtime': 7.27.0 react: 18.3.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - '@radix-ui/react-context@1.1.1(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-context@1.1.1(@types/react@18.3.20)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - '@radix-ui/react-dialog@1.0.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-dialog@1.0.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.26.10 + '@babel/runtime': 7.27.0 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.0.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.0.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.0.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.0.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.0.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.0.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.3.20)(react@18.3.1) aria-hidden: 1.2.4 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.5.5(@types/react@18.3.18)(react@18.3.1) + react-remove-scroll: 2.5.5(@types/react@18.3.20)(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-dialog@1.1.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-dialog@1.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.20)(react@18.3.1) aria-hidden: 1.2.4 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.6.3(@types/react@18.3.18)(react@18.3.1) + react-remove-scroll: 2.6.3(@types/react@18.3.20)(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-direction@1.1.0(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-direction@1.1.0(@types/react@18.3.20)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - '@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.26.10 + '@babel/runtime': 7.27.0 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-dismissable-layer@1.1.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-dismissable-layer@1.1.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-dropdown-menu@2.1.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-dropdown-menu@2.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-menu': 2.1.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-menu': 2.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-focus-guards@1.0.1(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-focus-guards@1.0.1(@types/react@18.3.20)(react@18.3.1)': dependencies: - '@babel/runtime': 7.26.10 + '@babel/runtime': 7.27.0 react: 18.3.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - '@radix-ui/react-focus-guards@1.1.1(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-focus-guards@1.1.1(@types/react@18.3.20)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - '@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.26.10 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.18)(react@18.3.1) + '@babel/runtime': 7.27.0 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-focus-scope@1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-focus-scope@1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) '@radix-ui/react-icons@1.3.2(react@18.3.1)': dependencies: react: 18.3.1 - '@radix-ui/react-id@1.0.1(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-id@1.0.1(@types/react@18.3.20)(react@18.3.1)': dependencies: - '@babel/runtime': 7.26.10 - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.3.18)(react@18.3.1) + '@babel/runtime': 7.27.0 + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - '@radix-ui/react-id@1.1.0(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-id@1.1.0(@types/react@18.3.20)(react@18.3.1)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - '@radix-ui/react-label@2.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-label@2.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-menu@2.1.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-menu@2.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-direction': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.20)(react@18.3.1) aria-hidden: 1.2.4 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.6.3(@types/react@18.3.18)(react@18.3.1) + react-remove-scroll: 2.6.3(@types/react@18.3.20)(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-menubar@1.1.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-menubar@1.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-direction': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-menu': 2.1.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-menu': 2.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-popover@1.1.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-popover@1.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.20)(react@18.3.1) aria-hidden: 1.2.4 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.6.3(@types/react@18.3.18)(react@18.3.1) + react-remove-scroll: 2.6.3(@types/react@18.3.20)(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-popper@1.2.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-popper@1.2.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@floating-ui/react-dom': 2.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-arrow': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-rect': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-arrow': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-rect': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.20)(react@18.3.1) '@radix-ui/rect': 1.1.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-portal@1.0.4(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-portal@1.0.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.26.10 - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@babel/runtime': 7.27.0 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-portal@1.1.4(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-portal@1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-presence@1.0.1(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-presence@1.0.1(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.26.10 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.3.18)(react@18.3.1) + '@babel/runtime': 7.27.0 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-presence@1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-presence@1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-primitive@1.0.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-primitive@1.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.26.10 - '@radix-ui/react-slot': 1.0.2(@types/react@18.3.18)(react@18.3.1) + '@babel/runtime': 7.27.0 + '@radix-ui/react-slot': 1.0.2(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-primitive@2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-primitive@2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-slot': 1.1.2(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-radio-group@1.2.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-radio-group@1.2.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-direction': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-roving-focus@1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-roving-focus@1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-direction': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-select@2.1.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-select@2.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/number': 1.1.0 '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-direction': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) aria-hidden: 1.2.4 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.6.3(@types/react@18.3.18)(react@18.3.1) + react-remove-scroll: 2.6.3(@types/react@18.3.20)(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-separator@1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-separator@1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-slot@1.0.2(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-slot@1.0.2(@types/react@18.3.20)(react@18.3.1)': dependencies: - '@babel/runtime': 7.26.10 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.18)(react@18.3.1) + '@babel/runtime': 7.27.0 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - '@radix-ui/react-slot@1.1.2(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-slot@1.1.2(@types/react@18.3.20)(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - '@radix-ui/react-switch@1.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-switch@1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-tabs@1.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-tabs@1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-direction': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-tooltip@1.1.8(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-tooltip@1.1.8(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.3.20)(react@18.3.1)': dependencies: - '@babel/runtime': 7.26.10 + '@babel/runtime': 7.27.0 react: 18.3.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - '@radix-ui/react-use-callback-ref@1.1.0(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-use-callback-ref@1.1.0(@types/react@18.3.20)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - '@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.3.20)(react@18.3.1)': dependencies: - '@babel/runtime': 7.26.10 - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.18)(react@18.3.1) + '@babel/runtime': 7.27.0 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - '@radix-ui/react-use-controllable-state@1.1.0(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-use-controllable-state@1.1.0(@types/react@18.3.20)(react@18.3.1)': dependencies: - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - '@radix-ui/react-use-escape-keydown@1.0.3(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-use-escape-keydown@1.0.3(@types/react@18.3.20)(react@18.3.1)': dependencies: - '@babel/runtime': 7.26.10 - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.18)(react@18.3.1) + '@babel/runtime': 7.27.0 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - '@radix-ui/react-use-escape-keydown@1.1.0(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-use-escape-keydown@1.1.0(@types/react@18.3.20)(react@18.3.1)': dependencies: - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - '@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.3.20)(react@18.3.1)': dependencies: - '@babel/runtime': 7.26.10 + '@babel/runtime': 7.27.0 react: 18.3.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - '@radix-ui/react-use-layout-effect@1.1.0(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-use-layout-effect@1.1.0(@types/react@18.3.20)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - '@radix-ui/react-use-previous@1.1.0(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-use-previous@1.1.0(@types/react@18.3.20)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - '@radix-ui/react-use-rect@1.1.0(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-use-rect@1.1.0(@types/react@18.3.20)(react@18.3.1)': dependencies: '@radix-ui/rect': 1.1.0 react: 18.3.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - '@radix-ui/react-use-size@1.1.0(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-use-size@1.1.0(@types/react@18.3.20)(react@18.3.1)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - '@radix-ui/react-visually-hidden@1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-visually-hidden@1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) '@radix-ui/rect@1.1.0': {} '@remix-run/router@1.23.0': {} - '@rollup/rollup-android-arm-eabi@4.35.0': + '@rollup/rollup-android-arm-eabi@4.39.0': + optional: true + + '@rollup/rollup-android-arm64@4.39.0': optional: true - '@rollup/rollup-android-arm64@4.35.0': + '@rollup/rollup-darwin-arm64@4.39.0': optional: true - '@rollup/rollup-darwin-arm64@4.35.0': + '@rollup/rollup-darwin-x64@4.39.0': optional: true - '@rollup/rollup-darwin-x64@4.35.0': + '@rollup/rollup-freebsd-arm64@4.39.0': optional: true - '@rollup/rollup-freebsd-arm64@4.35.0': + '@rollup/rollup-freebsd-x64@4.39.0': optional: true - '@rollup/rollup-freebsd-x64@4.35.0': + '@rollup/rollup-linux-arm-gnueabihf@4.39.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.35.0': + '@rollup/rollup-linux-arm-musleabihf@4.39.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.35.0': + '@rollup/rollup-linux-arm64-gnu@4.39.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.35.0': + '@rollup/rollup-linux-arm64-musl@4.39.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.35.0': + '@rollup/rollup-linux-loongarch64-gnu@4.39.0': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.35.0': + '@rollup/rollup-linux-powerpc64le-gnu@4.39.0': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.35.0': + '@rollup/rollup-linux-riscv64-gnu@4.39.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.35.0': + '@rollup/rollup-linux-riscv64-musl@4.39.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.35.0': + '@rollup/rollup-linux-s390x-gnu@4.39.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.35.0': + '@rollup/rollup-linux-x64-gnu@4.39.0': optional: true - '@rollup/rollup-linux-x64-musl@4.35.0': + '@rollup/rollup-linux-x64-musl@4.39.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.35.0': + '@rollup/rollup-win32-arm64-msvc@4.39.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.35.0': + '@rollup/rollup-win32-ia32-msvc@4.39.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.35.0': + '@rollup/rollup-win32-x64-msvc@4.39.0': optional: true - '@tauri-apps/api@2.3.0': {} + '@tauri-apps/api@2.4.1': {} + + '@tauri-apps/cli-darwin-arm64@2.4.1': + optional: true - '@tauri-apps/cli-darwin-arm64@2.3.1': + '@tauri-apps/cli-darwin-x64@2.4.1': optional: true - '@tauri-apps/cli-darwin-x64@2.3.1': + '@tauri-apps/cli-linux-arm-gnueabihf@2.4.1': optional: true - '@tauri-apps/cli-linux-arm-gnueabihf@2.3.1': + '@tauri-apps/cli-linux-arm64-gnu@2.4.1': optional: true - '@tauri-apps/cli-linux-arm64-gnu@2.3.1': + '@tauri-apps/cli-linux-arm64-musl@2.4.1': optional: true - '@tauri-apps/cli-linux-arm64-musl@2.3.1': + '@tauri-apps/cli-linux-riscv64-gnu@2.4.1': optional: true - '@tauri-apps/cli-linux-x64-gnu@2.3.1': + '@tauri-apps/cli-linux-x64-gnu@2.4.1': optional: true - '@tauri-apps/cli-linux-x64-musl@2.3.1': + '@tauri-apps/cli-linux-x64-musl@2.4.1': optional: true - '@tauri-apps/cli-win32-arm64-msvc@2.3.1': + '@tauri-apps/cli-win32-arm64-msvc@2.4.1': optional: true - '@tauri-apps/cli-win32-ia32-msvc@2.3.1': + '@tauri-apps/cli-win32-ia32-msvc@2.4.1': optional: true - '@tauri-apps/cli-win32-x64-msvc@2.3.1': + '@tauri-apps/cli-win32-x64-msvc@2.4.1': optional: true - '@tauri-apps/cli@2.3.1': + '@tauri-apps/cli@2.4.1': optionalDependencies: - '@tauri-apps/cli-darwin-arm64': 2.3.1 - '@tauri-apps/cli-darwin-x64': 2.3.1 - '@tauri-apps/cli-linux-arm-gnueabihf': 2.3.1 - '@tauri-apps/cli-linux-arm64-gnu': 2.3.1 - '@tauri-apps/cli-linux-arm64-musl': 2.3.1 - '@tauri-apps/cli-linux-x64-gnu': 2.3.1 - '@tauri-apps/cli-linux-x64-musl': 2.3.1 - '@tauri-apps/cli-win32-arm64-msvc': 2.3.1 - '@tauri-apps/cli-win32-ia32-msvc': 2.3.1 - '@tauri-apps/cli-win32-x64-msvc': 2.3.1 + '@tauri-apps/cli-darwin-arm64': 2.4.1 + '@tauri-apps/cli-darwin-x64': 2.4.1 + '@tauri-apps/cli-linux-arm-gnueabihf': 2.4.1 + '@tauri-apps/cli-linux-arm64-gnu': 2.4.1 + '@tauri-apps/cli-linux-arm64-musl': 2.4.1 + '@tauri-apps/cli-linux-riscv64-gnu': 2.4.1 + '@tauri-apps/cli-linux-x64-gnu': 2.4.1 + '@tauri-apps/cli-linux-x64-musl': 2.4.1 + '@tauri-apps/cli-win32-arm64-msvc': 2.4.1 + '@tauri-apps/cli-win32-ia32-msvc': 2.4.1 + '@tauri-apps/cli-win32-x64-msvc': 2.4.1 - '@tauri-apps/plugin-dialog@2.2.0': + '@tauri-apps/plugin-dialog@2.2.1': dependencies: - '@tauri-apps/api': 2.3.0 + '@tauri-apps/api': 2.4.1 '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.26.10 - '@babel/types': 7.26.10 - '@types/babel__generator': 7.6.8 + '@babel/parser': 7.27.0 + '@babel/types': 7.27.0 + '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.20.6 + '@types/babel__traverse': 7.20.7 - '@types/babel__generator@7.6.8': + '@types/babel__generator@7.27.0': dependencies: - '@babel/types': 7.26.10 + '@babel/types': 7.27.0 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.26.10 - '@babel/types': 7.26.10 + '@babel/parser': 7.27.0 + '@babel/types': 7.27.0 - '@types/babel__traverse@7.20.6': + '@types/babel__traverse@7.20.7': dependencies: - '@babel/types': 7.26.10 + '@babel/types': 7.27.0 - '@types/estree@1.0.6': {} + '@types/estree@1.0.7': {} - '@types/node@22.13.10': + '@types/node@22.14.0': dependencies: - undici-types: 6.20.0 + undici-types: 6.21.0 '@types/prop-types@15.7.14': {} - '@types/react-dom@18.3.5(@types/react@18.3.18)': + '@types/react-dom@18.3.6(@types/react@18.3.20)': dependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - '@types/react@18.3.18': + '@types/react@18.3.20': dependencies: '@types/prop-types': 15.7.14 csstype: 3.1.3 - '@vitejs/plugin-react@4.3.4(vite@5.4.14(@types/node@22.13.10))': + '@vitejs/plugin-react@4.3.4(vite@5.4.17(@types/node@22.14.0))': dependencies: '@babel/core': 7.26.10 '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.10) '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.10) '@types/babel__core': 7.20.5 react-refresh: 0.14.2 - vite: 5.4.14(@types/node@22.13.10) + vite: 5.4.17(@types/node@22.14.0) transitivePeerDependencies: - supports-color @@ -2916,7 +2934,7 @@ snapshots: autoprefixer@10.4.21(postcss@8.5.3): dependencies: browserslist: 4.24.4 - caniuse-lite: 1.0.30001704 + caniuse-lite: 1.0.30001710 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 @@ -2937,14 +2955,14 @@ snapshots: browserslist@4.24.4: dependencies: - caniuse-lite: 1.0.30001704 - electron-to-chromium: 1.5.116 + caniuse-lite: 1.0.30001710 + electron-to-chromium: 1.5.131 node-releases: 2.0.19 update-browserslist-db: 1.1.3(browserslist@4.24.4) camelcase-css@2.0.1: {} - caniuse-lite@1.0.30001704: {} + caniuse-lite@1.0.30001710: {} chokidar@3.6.0: dependencies: @@ -2964,10 +2982,10 @@ snapshots: clsx@2.1.1: {} - cmdk@1.0.0(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + cmdk@1.0.0(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@radix-ui/react-dialog': 1.0.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-dialog': 1.0.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) transitivePeerDependencies: @@ -3006,7 +3024,7 @@ snapshots: eastasianwidth@0.2.0: {} - electron-to-chromium@1.5.116: {} + electron-to-chromium@1.5.131: {} emoji-regex@8.0.0: {} @@ -3063,10 +3081,10 @@ snapshots: fraction.js@4.3.7: {} - framer-motion@12.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + framer-motion@12.6.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - motion-dom: 12.5.0 - motion-utils: 12.5.0 + motion-dom: 12.6.3 + motion-utils: 12.6.3 tslib: 2.8.1 optionalDependencies: react: 18.3.1 @@ -3169,11 +3187,11 @@ snapshots: minipass@7.1.2: {} - motion-dom@12.5.0: + motion-dom@12.6.3: dependencies: - motion-utils: 12.5.0 + motion-utils: 12.6.3 - motion-utils@12.5.0: {} + motion-utils@12.6.3: {} ms@2.1.3: {} @@ -3183,7 +3201,7 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 - nanoid@3.3.9: {} + nanoid@3.3.11: {} next-themes@0.4.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: @@ -3217,7 +3235,7 @@ snapshots: pify@2.3.0: {} - pirates@4.0.6: {} + pirates@4.0.7: {} postcss-import@15.1.0(postcss@8.5.3): dependencies: @@ -3234,7 +3252,7 @@ snapshots: postcss-load-config@4.0.2(postcss@8.5.3): dependencies: lilconfig: 3.1.3 - yaml: 2.7.0 + yaml: 2.7.1 optionalDependencies: postcss: 8.5.3 @@ -3252,7 +3270,7 @@ snapshots: postcss@8.5.3: dependencies: - nanoid: 3.3.9 + nanoid: 3.3.11 picocolors: 1.1.1 source-map-js: 1.2.1 @@ -3266,35 +3284,35 @@ snapshots: react-refresh@0.14.2: {} - react-remove-scroll-bar@2.3.8(@types/react@18.3.18)(react@18.3.1): + react-remove-scroll-bar@2.3.8(@types/react@18.3.20)(react@18.3.1): dependencies: react: 18.3.1 - react-style-singleton: 2.2.3(@types/react@18.3.18)(react@18.3.1) + react-style-singleton: 2.2.3(@types/react@18.3.20)(react@18.3.1) tslib: 2.8.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - react-remove-scroll@2.5.5(@types/react@18.3.18)(react@18.3.1): + react-remove-scroll@2.5.5(@types/react@18.3.20)(react@18.3.1): dependencies: react: 18.3.1 - react-remove-scroll-bar: 2.3.8(@types/react@18.3.18)(react@18.3.1) - react-style-singleton: 2.2.3(@types/react@18.3.18)(react@18.3.1) + react-remove-scroll-bar: 2.3.8(@types/react@18.3.20)(react@18.3.1) + react-style-singleton: 2.2.3(@types/react@18.3.20)(react@18.3.1) tslib: 2.8.1 - use-callback-ref: 1.3.3(@types/react@18.3.18)(react@18.3.1) - use-sidecar: 1.1.3(@types/react@18.3.18)(react@18.3.1) + use-callback-ref: 1.3.3(@types/react@18.3.20)(react@18.3.1) + use-sidecar: 1.1.3(@types/react@18.3.20)(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - react-remove-scroll@2.6.3(@types/react@18.3.18)(react@18.3.1): + react-remove-scroll@2.6.3(@types/react@18.3.20)(react@18.3.1): dependencies: react: 18.3.1 - react-remove-scroll-bar: 2.3.8(@types/react@18.3.18)(react@18.3.1) - react-style-singleton: 2.2.3(@types/react@18.3.18)(react@18.3.1) + react-remove-scroll-bar: 2.3.8(@types/react@18.3.20)(react@18.3.1) + react-style-singleton: 2.2.3(@types/react@18.3.20)(react@18.3.1) tslib: 2.8.1 - use-callback-ref: 1.3.3(@types/react@18.3.18)(react@18.3.1) - use-sidecar: 1.1.3(@types/react@18.3.18)(react@18.3.1) + use-callback-ref: 1.3.3(@types/react@18.3.20)(react@18.3.1) + use-sidecar: 1.1.3(@types/react@18.3.20)(react@18.3.1) optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: @@ -3308,13 +3326,13 @@ snapshots: '@remix-run/router': 1.23.0 react: 18.3.1 - react-style-singleton@2.2.3(@types/react@18.3.18)(react@18.3.1): + react-style-singleton@2.2.3(@types/react@18.3.20)(react@18.3.1): dependencies: get-nonce: 1.0.1 react: 18.3.1 tslib: 2.8.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 react@18.3.1: dependencies: @@ -3338,29 +3356,30 @@ snapshots: reusify@1.1.0: {} - rollup@4.35.0: - dependencies: - '@types/estree': 1.0.6 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.35.0 - '@rollup/rollup-android-arm64': 4.35.0 - '@rollup/rollup-darwin-arm64': 4.35.0 - '@rollup/rollup-darwin-x64': 4.35.0 - '@rollup/rollup-freebsd-arm64': 4.35.0 - '@rollup/rollup-freebsd-x64': 4.35.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.35.0 - '@rollup/rollup-linux-arm-musleabihf': 4.35.0 - '@rollup/rollup-linux-arm64-gnu': 4.35.0 - '@rollup/rollup-linux-arm64-musl': 4.35.0 - '@rollup/rollup-linux-loongarch64-gnu': 4.35.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.35.0 - '@rollup/rollup-linux-riscv64-gnu': 4.35.0 - '@rollup/rollup-linux-s390x-gnu': 4.35.0 - '@rollup/rollup-linux-x64-gnu': 4.35.0 - '@rollup/rollup-linux-x64-musl': 4.35.0 - '@rollup/rollup-win32-arm64-msvc': 4.35.0 - '@rollup/rollup-win32-ia32-msvc': 4.35.0 - '@rollup/rollup-win32-x64-msvc': 4.35.0 + rollup@4.39.0: + dependencies: + '@types/estree': 1.0.7 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.39.0 + '@rollup/rollup-android-arm64': 4.39.0 + '@rollup/rollup-darwin-arm64': 4.39.0 + '@rollup/rollup-darwin-x64': 4.39.0 + '@rollup/rollup-freebsd-arm64': 4.39.0 + '@rollup/rollup-freebsd-x64': 4.39.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.39.0 + '@rollup/rollup-linux-arm-musleabihf': 4.39.0 + '@rollup/rollup-linux-arm64-gnu': 4.39.0 + '@rollup/rollup-linux-arm64-musl': 4.39.0 + '@rollup/rollup-linux-loongarch64-gnu': 4.39.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.39.0 + '@rollup/rollup-linux-riscv64-gnu': 4.39.0 + '@rollup/rollup-linux-riscv64-musl': 4.39.0 + '@rollup/rollup-linux-s390x-gnu': 4.39.0 + '@rollup/rollup-linux-x64-gnu': 4.39.0 + '@rollup/rollup-linux-x64-musl': 4.39.0 + '@rollup/rollup-win32-arm64-msvc': 4.39.0 + '@rollup/rollup-win32-ia32-msvc': 4.39.0 + '@rollup/rollup-win32-x64-msvc': 4.39.0 fsevents: 2.3.3 run-parallel@1.2.0: @@ -3415,7 +3434,7 @@ snapshots: glob: 10.4.5 lines-and-columns: 1.2.4 mz: 2.7.0 - pirates: 4.0.6 + pirates: 4.0.7 ts-interface-checker: 0.1.13 supports-preserve-symlinks-flag@1.0.0: {} @@ -3471,7 +3490,7 @@ snapshots: typescript@5.8.2: {} - undici-types@6.20.0: {} + undici-types@6.21.0: {} update-browserslist-db@1.1.3(browserslist@4.24.4): dependencies: @@ -3479,30 +3498,30 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 - use-callback-ref@1.3.3(@types/react@18.3.18)(react@18.3.1): + use-callback-ref@1.3.3(@types/react@18.3.20)(react@18.3.1): dependencies: react: 18.3.1 tslib: 2.8.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 - use-sidecar@1.1.3(@types/react@18.3.18)(react@18.3.1): + use-sidecar@1.1.3(@types/react@18.3.20)(react@18.3.1): dependencies: detect-node-es: 1.1.0 react: 18.3.1 tslib: 2.8.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 18.3.20 util-deprecate@1.0.2: {} - vite@5.4.14(@types/node@22.13.10): + vite@5.4.17(@types/node@22.14.0): dependencies: esbuild: 0.21.5 postcss: 8.5.3 - rollup: 4.35.0 + rollup: 4.39.0 optionalDependencies: - '@types/node': 22.13.10 + '@types/node': 22.14.0 fsevents: 2.3.3 which@2.0.2: @@ -3523,4 +3542,4 @@ snapshots: yallist@3.1.1: {} - yaml@2.7.0: {} + yaml@2.7.1: {} diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 07da22f..23eb941 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -2145,9 +2145,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.8.5" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +checksum = "ff70ce3e48ae43fa075863cef62e8b43b71a4f2382229920e0df362592919430" dependencies = [ "adler2", "simd-adler32", From 576f57a21c6244701257356e4ccd2e964a599fc2 Mon Sep 17 00:00:00 2001 From: Maxime <98154358+Maxime-Cllt@users.noreply.github.com> Date: Sun, 13 Apr 2025 13:47:54 +0200 Subject: [PATCH 6/6] update vendor --- package.json | 34 +- pnpm-lock.yaml | 882 +++++++++--------- src-tauri/Cargo.lock | 74 +- .../src/fileflow/utils/string_formater.rs | 8 +- src-tauri/src/tests/string_formater_test.rs | 1 + 5 files changed, 500 insertions(+), 499 deletions(-) diff --git a/package.json b/package.json index 3174f82..a4d7dcf 100644 --- a/package.json +++ b/package.json @@ -10,26 +10,26 @@ "tauri": "tauri" }, "dependencies": { - "@radix-ui/react-checkbox": "^1.1.4", - "@radix-ui/react-dialog": "^1.1.6", - "@radix-ui/react-dropdown-menu": "^2.1.6", + "@radix-ui/react-checkbox": "^1.1.5", + "@radix-ui/react-dialog": "^1.1.7", + "@radix-ui/react-dropdown-menu": "^2.1.7", "@radix-ui/react-icons": "^1.3.2", - "@radix-ui/react-label": "^2.1.2", - "@radix-ui/react-menubar": "^1.1.6", - "@radix-ui/react-popover": "^1.1.6", - "@radix-ui/react-radio-group": "^1.2.3", - "@radix-ui/react-select": "^2.1.6", - "@radix-ui/react-separator": "^1.1.2", - "@radix-ui/react-slot": "^1.1.2", - "@radix-ui/react-switch": "^1.1.3", - "@radix-ui/react-tabs": "^1.1.3", - "@radix-ui/react-tooltip": "^1.1.8", + "@radix-ui/react-label": "^2.1.3", + "@radix-ui/react-menubar": "^1.1.7", + "@radix-ui/react-popover": "^1.1.7", + "@radix-ui/react-radio-group": "^1.2.4", + "@radix-ui/react-select": "^2.1.7", + "@radix-ui/react-separator": "^1.1.3", + "@radix-ui/react-slot": "^1.2.0", + "@radix-ui/react-switch": "^1.1.4", + "@radix-ui/react-tabs": "^1.1.4", + "@radix-ui/react-tooltip": "^1.2.0", "@tauri-apps/api": "^2.4.1", "@tauri-apps/plugin-dialog": "~2.2.1", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "1.0.0", - "framer-motion": "^12.6.3", + "framer-motion": "^12.6.5", "lucide-react": "^0.441.0", "next-themes": "^0.4.6", "react": "^18.3.1", @@ -41,14 +41,14 @@ }, "devDependencies": { "@tauri-apps/cli": "^2.4.1", - "@types/node": "^22.14.0", + "@types/node": "^22.14.1", "@types/react": "^18.3.20", "@types/react-dom": "^18.3.6", "@vitejs/plugin-react": "^4.3.4", "autoprefixer": "^10.4.21", "postcss": "^8.5.3", "tailwindcss": "^3.4.17", - "typescript": "^5.8.2", - "vite": "^5.4.17" + "typescript": "^5.8.3", + "vite": "^5.4.18" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8cd8dab..36feba7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,47 +9,47 @@ importers: .: dependencies: '@radix-ui/react-checkbox': - specifier: ^1.1.4 - version: 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.1.5 + version: 1.1.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-dialog': - specifier: ^1.1.6 - version: 1.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.1.7 + version: 1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-dropdown-menu': - specifier: ^2.1.6 - version: 2.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^2.1.7 + version: 2.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-icons': specifier: ^1.3.2 version: 1.3.2(react@18.3.1) '@radix-ui/react-label': - specifier: ^2.1.2 - version: 2.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^2.1.3 + version: 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-menubar': - specifier: ^1.1.6 - version: 1.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.1.7 + version: 1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-popover': - specifier: ^1.1.6 - version: 1.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.1.7 + version: 1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-radio-group': - specifier: ^1.2.3 - version: 1.2.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.2.4 + version: 1.2.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-select': - specifier: ^2.1.6 - version: 2.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^2.1.7 + version: 2.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-separator': - specifier: ^1.1.2 - version: 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': - specifier: ^1.1.2 - version: 1.1.2(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-switch': specifier: ^1.1.3 version: 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': + specifier: ^1.2.0 + version: 1.2.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-switch': + specifier: ^1.1.4 + version: 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-tabs': - specifier: ^1.1.3 - version: 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.1.4 + version: 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-tooltip': - specifier: ^1.1.8 - version: 1.1.8(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.2.0 + version: 1.2.0(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@tauri-apps/api': specifier: ^2.4.1 version: 2.4.1 @@ -66,8 +66,8 @@ importers: specifier: 1.0.0 version: 1.0.0(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) framer-motion: - specifier: ^12.6.3 - version: 12.6.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^12.6.5 + version: 12.6.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) lucide-react: specifier: ^0.441.0 version: 0.441.0(react@18.3.1) @@ -97,8 +97,8 @@ importers: specifier: ^2.4.1 version: 2.4.1 '@types/node': - specifier: ^22.14.0 - version: 22.14.0 + specifier: ^22.14.1 + version: 22.14.1 '@types/react': specifier: ^18.3.20 version: 18.3.20 @@ -107,7 +107,7 @@ importers: version: 18.3.6(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.4 - version: 4.3.4(vite@5.4.17(@types/node@22.14.0)) + version: 4.3.4(vite@5.4.18(@types/node@22.14.1)) autoprefixer: specifier: ^10.4.21 version: 10.4.21(postcss@8.5.3) @@ -118,11 +118,11 @@ importers: specifier: ^3.4.17 version: 3.4.17 typescript: - specifier: ^5.8.2 - version: 5.8.2 + specifier: ^5.8.3 + version: 5.8.3 vite: - specifier: ^5.4.17 - version: 5.4.17(@types/node@22.14.0) + specifier: ^5.4.18 + version: 5.4.18(@types/node@22.14.1) packages: @@ -408,17 +408,17 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@radix-ui/number@1.1.0': - resolution: {integrity: sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==} + '@radix-ui/number@1.1.1': + resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} '@radix-ui/primitive@1.0.1': resolution: {integrity: sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==} - '@radix-ui/primitive@1.1.1': - resolution: {integrity: sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==} + '@radix-ui/primitive@1.1.2': + resolution: {integrity: sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==} - '@radix-ui/react-arrow@1.1.2': - resolution: {integrity: sha512-G+KcpzXHq24iH0uGG/pF8LyzpFJYGD4RfLjCIBfGdSLXvjLHST31RUiRVrupIBMvIppMgSzQ6l66iAxl03tdlg==} + '@radix-ui/react-arrow@1.1.3': + resolution: {integrity: sha512-2dvVU4jva0qkNZH6HHWuSz5FN5GeU5tymvCgutF8WaXz9WnD1NgUhy73cqzkjkN4Zkn8lfTPv5JIfrC221W+Nw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -430,8 +430,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-checkbox@1.1.4': - resolution: {integrity: sha512-wP0CPAHq+P5I4INKe3hJrIa1WoNqqrejzW+zoU0rOvo1b9gDEJJFl2rYfO1PYJUQCc2H1WZxIJmyv9BS8i5fLw==} + '@radix-ui/react-checkbox@1.1.5': + resolution: {integrity: sha512-B0gYIVxl77KYDR25AY9EGe/G//ef85RVBIxQvK+m5pxAC7XihAc/8leMHhDvjvhDu02SBSb6BuytlWr/G7F3+g==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -443,8 +443,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-collection@1.1.2': - resolution: {integrity: sha512-9z54IEKRxIa9VityapoEYMuByaG42iSy1ZXlY2KcuLSEtq8x4987/N6m15ppoMffgZX72gER2uHe1D9Y6Unlcw==} + '@radix-ui/react-collection@1.1.3': + resolution: {integrity: sha512-mM2pxoQw5HJ49rkzwOs7Y6J4oYH22wS8BfK2/bBxROlI4xuR0c4jEenQP63LlTlDkO6Buj2Vt+QYAYcOgqtrXA==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -465,8 +465,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-compose-refs@1.1.1': - resolution: {integrity: sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==} + '@radix-ui/react-compose-refs@1.1.2': + resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -483,8 +483,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-context@1.1.1': - resolution: {integrity: sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==} + '@radix-ui/react-context@1.1.2': + resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -505,8 +505,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-dialog@1.1.6': - resolution: {integrity: sha512-/IVhJV5AceX620DUJ4uYVMymzsipdKBzo3edo+omeskCKGm9FRHM0ebIdbPnlQVJqyuHbuBltQUOG2mOTq2IYw==} + '@radix-ui/react-dialog@1.1.7': + resolution: {integrity: sha512-EIdma8C0C/I6kL6sO02avaCRqi3fmWJpxH6mqbVScorW6nNktzKJT/le7VPho3o/7wCsyRg3z0+Q+Obr0Gy/VQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -518,8 +518,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-direction@1.1.0': - resolution: {integrity: sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==} + '@radix-ui/react-direction@1.1.1': + resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -540,8 +540,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-dismissable-layer@1.1.5': - resolution: {integrity: sha512-E4TywXY6UsXNRhFrECa5HAvE5/4BFcGyfTyK36gP+pAW1ed7UTK4vKwdr53gAJYwqbfCWC6ATvJa3J3R/9+Qrg==} + '@radix-ui/react-dismissable-layer@1.1.6': + resolution: {integrity: sha512-7gpgMT2gyKym9Jz2ZhlRXSg2y6cNQIK8d/cqBZ0RBCaps8pFryCWXiUKI+uHGFrhMrbGUP7U6PWgiXzIxoyF3Q==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -553,8 +553,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-dropdown-menu@2.1.6': - resolution: {integrity: sha512-no3X7V5fD487wab/ZYSHXq3H37u4NVeLDKI/Ks724X/eEFSSEFYZxWgsIlr1UBeEyDaM29HM5x9p1Nv8DuTYPA==} + '@radix-ui/react-dropdown-menu@2.1.7': + resolution: {integrity: sha512-7/1LiuNZuCQE3IzdicGoHdQOHkS2Q08+7p8w6TXZ6ZjgAULaCI85ZY15yPl4o4FVgoKLRT43/rsfNVN8osClQQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -575,8 +575,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-focus-guards@1.1.1': - resolution: {integrity: sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==} + '@radix-ui/react-focus-guards@1.1.2': + resolution: {integrity: sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -597,8 +597,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-focus-scope@1.1.2': - resolution: {integrity: sha512-zxwE80FCU7lcXUGWkdt6XpTTCKPitG1XKOwViTxHVKIJhZl9MvIl2dVHeZENCWD9+EdWv05wlaEkRXUykU27RA==} + '@radix-ui/react-focus-scope@1.1.3': + resolution: {integrity: sha512-4XaDlq0bPt7oJwR+0k0clCiCO/7lO7NKZTAaJBYxDNQT/vj4ig0/UvctrRscZaFREpRvUTkpKR96ov1e6jptQg==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -624,8 +624,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-id@1.1.0': - resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==} + '@radix-ui/react-id@1.1.1': + resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -633,8 +633,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-label@2.1.2': - resolution: {integrity: sha512-zo1uGMTaNlHehDyFQcDZXRJhUPDuukcnHz0/jnrup0JA6qL+AFpAnty+7VKa9esuU5xTblAZzTGYJKSKaBxBhw==} + '@radix-ui/react-label@2.1.3': + resolution: {integrity: sha512-zwSQ1NzSKG95yA0tvBMgv6XPHoqapJCcg9nsUBaQQ66iRBhZNhlpaQG2ERYYX4O4stkYFK5rxj5NsWfO9CS+Hg==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -646,8 +646,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-menu@2.1.6': - resolution: {integrity: sha512-tBBb5CXDJW3t2mo9WlO7r6GTmWV0F0uzHZVFmlRmYpiSK1CDU5IKojP1pm7oknpBOrFZx/YgBRW9oorPO2S/Lg==} + '@radix-ui/react-menu@2.1.7': + resolution: {integrity: sha512-tBODsrk68rOi1/iQzbM54toFF+gSw/y+eQgttFflqlGekuSebNqvFNHjJgjqPhiMb4Fw9A0zNFly1QT6ZFdQ+Q==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -659,8 +659,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-menubar@1.1.6': - resolution: {integrity: sha512-FHq7+3DlXwh/7FOM4i0G4bC4vPjiq89VEEvNF4VMLchGnaUuUbE5uKXMUCjdKaOghEEMeiKa5XCa2Pk4kteWmg==} + '@radix-ui/react-menubar@1.1.7': + resolution: {integrity: sha512-YB2zFhGdZ5SWEgRS+PgrF7EkwpsjEHntIFB/LRbT49LJdnIeK/xQQyuwLiRcOCgTDN+ALlPXQ08f0P0+TfR41g==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -672,8 +672,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-popover@1.1.6': - resolution: {integrity: sha512-NQouW0x4/GnkFJ/pRqsIS3rM/k97VzKnVb2jB7Gq7VEGPy5g7uNV1ykySFt7eWSp3i2uSGFwaJcvIRJBAHmmFg==} + '@radix-ui/react-popover@1.1.7': + resolution: {integrity: sha512-I38OYWDmJF2kbO74LX8UsFydSHWOJuQ7LxPnTefjxxvdvPLempvAnmsyX9UsBlywcbSGpRH7oMLfkUf+ij4nrw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -685,8 +685,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-popper@1.2.2': - resolution: {integrity: sha512-Rvqc3nOpwseCyj/rgjlJDYAgyfw7OC1tTkKn2ivhaMGcYt8FSBlahHOZak2i3QwkRXUXgGgzeEe2RuqeEHuHgA==} + '@radix-ui/react-popper@1.2.3': + resolution: {integrity: sha512-iNb9LYUMkne9zIahukgQmHlSBp9XWGeQQ7FvUGNk45ywzOb6kQa+Ca38OphXlWDiKvyneo9S+KSJsLfLt8812A==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -711,8 +711,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-portal@1.1.4': - resolution: {integrity: sha512-sn2O9k1rPFYVyKd5LAJfo96JlSGVFpa1fS6UuBJfrZadudiw5tAmru+n1x7aMRQ84qDM71Zh1+SzK5QwU0tJfA==} + '@radix-ui/react-portal@1.1.5': + resolution: {integrity: sha512-ps/67ZqsFm+Mb6lSPJpfhRLrVL2i2fntgCmGMqqth4eaGUf+knAuuRtWVJrNjUhExgmdRqftSgzpf0DF0n6yXA==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -737,8 +737,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-presence@1.1.2': - resolution: {integrity: sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==} + '@radix-ui/react-presence@1.1.3': + resolution: {integrity: sha512-IrVLIhskYhH3nLvtcBLQFZr61tBG7wx7O3kEmdzcYwRGAEBmBicGGL7ATzNgruYJ3xBTbuzEEq9OXJM3PAX3tA==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -763,8 +763,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-primitive@2.0.2': - resolution: {integrity: sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==} + '@radix-ui/react-primitive@2.0.3': + resolution: {integrity: sha512-Pf/t/GkndH7CQ8wE2hbkXA+WyZ83fhQQn5DDmwDiDo6AwN/fhaH8oqZ0jRjMrO2iaMhDi6P1HRx6AZwyMinY1g==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -776,8 +776,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-radio-group@1.2.3': - resolution: {integrity: sha512-xtCsqt8Rp09FK50ItqEqTJ7Sxanz8EM8dnkVIhJrc/wkMMomSmXHvYbhv3E7Zx4oXh98aaLt9W679SUYXg4IDA==} + '@radix-ui/react-radio-group@1.2.4': + resolution: {integrity: sha512-oLz7ATfKgVTUbpr5OBu6Q7hQcnV22uPT306bmG0QwgnKqBStR98RfWfJGCfW/MmhL4ISmrmmBPBW+c77SDwV9g==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -789,8 +789,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-roving-focus@1.1.2': - resolution: {integrity: sha512-zgMQWkNO169GtGqRvYrzb0Zf8NhMHS2DuEB/TiEmVnpr5OqPU3i8lfbxaAmC2J/KYuIQxyoQQ6DxepyXp61/xw==} + '@radix-ui/react-roving-focus@1.1.3': + resolution: {integrity: sha512-ufbpLUjZiOg4iYgb2hQrWXEPYX6jOLBbR27bDyAff5GYMRrCzcze8lukjuXVUQvJ6HZe8+oL+hhswDcjmcgVyg==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -802,8 +802,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-select@2.1.6': - resolution: {integrity: sha512-T6ajELxRvTuAMWH0YmRJ1qez+x4/7Nq7QIx7zJ0VK3qaEWdnWpNbEDnmWldG1zBDwqrLy5aLMUWcoGirVj5kMg==} + '@radix-ui/react-select@2.1.7': + resolution: {integrity: sha512-exzGIRtc7S8EIM2KjFg+7lJZsH7O7tpaBaJbBNVDnOZNhtoQ2iV+iSNfi2Wth0m6h3trJkMVvzAehB3c6xj/3Q==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -815,8 +815,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-separator@1.1.2': - resolution: {integrity: sha512-oZfHcaAp2Y6KFBX6I5P1u7CQoy4lheCGiYj+pGFrHy8E/VNRb5E39TkTr3JrV520csPBTZjkuKFdEsjS5EUNKQ==} + '@radix-ui/react-separator@1.1.3': + resolution: {integrity: sha512-2omrWKJvxR0U/tkIXezcc1nFMwtLU0+b/rDK40gnzJqTLWQ/TD/D5IYVefp9sC3QWfeQbpSbEA6op9MQKyaALQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -837,8 +837,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-slot@1.1.2': - resolution: {integrity: sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==} + '@radix-ui/react-slot@1.2.0': + resolution: {integrity: sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -846,8 +846,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-switch@1.1.3': - resolution: {integrity: sha512-1nc+vjEOQkJVsJtWPSiISGT6OKm4SiOdjMo+/icLxo2G4vxz1GntC5MzfL4v8ey9OEfw787QCD1y3mUv0NiFEQ==} + '@radix-ui/react-switch@1.1.4': + resolution: {integrity: sha512-zGP6W8plLeogoeGMiTHJ/uvf+TE1C2chVsEwfP8YlvpQKJHktG+iCkUtCLGPAuDV8/qDSmIRPm4NggaTxFMVBQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -859,8 +859,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-tabs@1.1.3': - resolution: {integrity: sha512-9mFyI30cuRDImbmFF6O2KUJdgEOsGh9Vmx9x/Dh9tOhL7BngmQPQfwW4aejKm5OHpfWIdmeV6ySyuxoOGjtNng==} + '@radix-ui/react-tabs@1.1.4': + resolution: {integrity: sha512-fuHMHWSf5SRhXke+DbHXj2wVMo+ghVH30vhX3XVacdXqDl+J4XWafMIGOOER861QpBx1jxgwKXL2dQnfrsd8MQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -872,8 +872,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-tooltip@1.1.8': - resolution: {integrity: sha512-YAA2cu48EkJZdAMHC0dqo9kialOcRStbtiY4nJPaht7Ptrhcvpo+eDChaM6BIs8kL6a8Z5l5poiqLnXcNduOkA==} + '@radix-ui/react-tooltip@1.2.0': + resolution: {integrity: sha512-b1Sdc75s7zN9B8ONQTGBSHL3XS8+IcjcOIY51fhM4R1Hx8s0YbgqgyNZiri4qcYMVZK8hfCZVBiyCm7N9rs0rw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -894,8 +894,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-use-callback-ref@1.1.0': - resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==} + '@radix-ui/react-use-callback-ref@1.1.1': + resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -912,8 +912,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-use-controllable-state@1.1.0': - resolution: {integrity: sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==} + '@radix-ui/react-use-controllable-state@1.1.1': + resolution: {integrity: sha512-YnEXIy8/ga01Y1PN0VfaNH//MhA91JlEGVBDxDzROqwrAtG5Yr2QGEPz8A/rJA3C7ZAHryOYGaUv8fLSW2H/mg==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -930,8 +930,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-use-escape-keydown@1.1.0': - resolution: {integrity: sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==} + '@radix-ui/react-use-escape-keydown@1.1.1': + resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -948,8 +948,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-use-layout-effect@1.1.0': - resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==} + '@radix-ui/react-use-layout-effect@1.1.1': + resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -957,8 +957,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-use-previous@1.1.0': - resolution: {integrity: sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==} + '@radix-ui/react-use-previous@1.1.1': + resolution: {integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -966,8 +966,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-use-rect@1.1.0': - resolution: {integrity: sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==} + '@radix-ui/react-use-rect@1.1.1': + resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -975,8 +975,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-use-size@1.1.0': - resolution: {integrity: sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==} + '@radix-ui/react-use-size@1.1.1': + resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -984,8 +984,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-visually-hidden@1.1.2': - resolution: {integrity: sha512-1SzA4ns2M1aRlvxErqhLHsBHoS5eI5UUcI2awAMgGUp4LoaoWOKYmvqDY2s/tltuPkh3Yk77YF/r3IRj+Amx4Q==} + '@radix-ui/react-visually-hidden@1.1.3': + resolution: {integrity: sha512-oXSF3ZQRd5fvomd9hmUCb2EHSZbPp3ZSHAHJJU/DlF9XoFkJBBW8RHU/E8WEH+RbSfJd/QFA0sl8ClJXknBwHQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -997,110 +997,110 @@ packages: '@types/react-dom': optional: true - '@radix-ui/rect@1.1.0': - resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==} + '@radix-ui/rect@1.1.1': + resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} '@remix-run/router@1.23.0': resolution: {integrity: sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==} engines: {node: '>=14.0.0'} - '@rollup/rollup-android-arm-eabi@4.39.0': - resolution: {integrity: sha512-lGVys55Qb00Wvh8DMAocp5kIcaNzEFTmGhfFd88LfaogYTRKrdxgtlO5H6S49v2Nd8R2C6wLOal0qv6/kCkOwA==} + '@rollup/rollup-android-arm-eabi@4.40.0': + resolution: {integrity: sha512-+Fbls/diZ0RDerhE8kyC6hjADCXA1K4yVNlH0EYfd2XjyH0UGgzaQ8MlT0pCXAThfxv3QUAczHaL+qSv1E4/Cg==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.39.0': - resolution: {integrity: sha512-It9+M1zE31KWfqh/0cJLrrsCPiF72PoJjIChLX+rEcujVRCb4NLQ5QzFkzIZW8Kn8FTbvGQBY5TkKBau3S8cCQ==} + '@rollup/rollup-android-arm64@4.40.0': + resolution: {integrity: sha512-PPA6aEEsTPRz+/4xxAmaoWDqh67N7wFbgFUJGMnanCFs0TV99M0M8QhhaSCks+n6EbQoFvLQgYOGXxlMGQe/6w==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.39.0': - resolution: {integrity: sha512-lXQnhpFDOKDXiGxsU9/l8UEGGM65comrQuZ+lDcGUx+9YQ9dKpF3rSEGepyeR5AHZ0b5RgiligsBhWZfSSQh8Q==} + '@rollup/rollup-darwin-arm64@4.40.0': + resolution: {integrity: sha512-GwYOcOakYHdfnjjKwqpTGgn5a6cUX7+Ra2HeNj/GdXvO2VJOOXCiYYlRFU4CubFM67EhbmzLOmACKEfvp3J1kQ==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.39.0': - resolution: {integrity: sha512-mKXpNZLvtEbgu6WCkNij7CGycdw9cJi2k9v0noMb++Vab12GZjFgUXD69ilAbBh034Zwn95c2PNSz9xM7KYEAQ==} + '@rollup/rollup-darwin-x64@4.40.0': + resolution: {integrity: sha512-CoLEGJ+2eheqD9KBSxmma6ld01czS52Iw0e2qMZNpPDlf7Z9mj8xmMemxEucinev4LgHalDPczMyxzbq+Q+EtA==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.39.0': - resolution: {integrity: sha512-jivRRlh2Lod/KvDZx2zUR+I4iBfHcu2V/BA2vasUtdtTN2Uk3jfcZczLa81ESHZHPHy4ih3T/W5rPFZ/hX7RtQ==} + '@rollup/rollup-freebsd-arm64@4.40.0': + resolution: {integrity: sha512-r7yGiS4HN/kibvESzmrOB/PxKMhPTlz+FcGvoUIKYoTyGd5toHp48g1uZy1o1xQvybwwpqpe010JrcGG2s5nkg==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.39.0': - resolution: {integrity: sha512-8RXIWvYIRK9nO+bhVz8DwLBepcptw633gv/QT4015CpJ0Ht8punmoHU/DuEd3iw9Hr8UwUV+t+VNNuZIWYeY7Q==} + '@rollup/rollup-freebsd-x64@4.40.0': + resolution: {integrity: sha512-mVDxzlf0oLzV3oZOr0SMJ0lSDd3xC4CmnWJ8Val8isp9jRGl5Dq//LLDSPFrasS7pSm6m5xAcKaw3sHXhBjoRw==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.39.0': - resolution: {integrity: sha512-mz5POx5Zu58f2xAG5RaRRhp3IZDK7zXGk5sdEDj4o96HeaXhlUwmLFzNlc4hCQi5sGdR12VDgEUqVSHer0lI9g==} + '@rollup/rollup-linux-arm-gnueabihf@4.40.0': + resolution: {integrity: sha512-y/qUMOpJxBMy8xCXD++jeu8t7kzjlOCkoxxajL58G62PJGBZVl/Gwpm7JK9+YvlB701rcQTzjUZ1JgUoPTnoQA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.39.0': - resolution: {integrity: sha512-+YDwhM6gUAyakl0CD+bMFpdmwIoRDzZYaTWV3SDRBGkMU/VpIBYXXEvkEcTagw/7VVkL2vA29zU4UVy1mP0/Yw==} + '@rollup/rollup-linux-arm-musleabihf@4.40.0': + resolution: {integrity: sha512-GoCsPibtVdJFPv/BOIvBKO/XmwZLwaNWdyD8TKlXuqp0veo2sHE+A/vpMQ5iSArRUz/uaoj4h5S6Pn0+PdhRjg==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.39.0': - resolution: {integrity: sha512-EKf7iF7aK36eEChvlgxGnk7pdJfzfQbNvGV/+l98iiMwU23MwvmV0Ty3pJ0p5WQfm3JRHOytSIqD9LB7Bq7xdQ==} + '@rollup/rollup-linux-arm64-gnu@4.40.0': + resolution: {integrity: sha512-L5ZLphTjjAD9leJzSLI7rr8fNqJMlGDKlazW2tX4IUF9P7R5TMQPElpH82Q7eNIDQnQlAyiNVfRPfP2vM5Avvg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.39.0': - resolution: {integrity: sha512-vYanR6MtqC7Z2SNr8gzVnzUul09Wi1kZqJaek3KcIlI/wq5Xtq4ZPIZ0Mr/st/sv/NnaPwy/D4yXg5x0B3aUUA==} + '@rollup/rollup-linux-arm64-musl@4.40.0': + resolution: {integrity: sha512-ATZvCRGCDtv1Y4gpDIXsS+wfFeFuLwVxyUBSLawjgXK2tRE6fnsQEkE4csQQYWlBlsFztRzCnBvWVfcae/1qxQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.39.0': - resolution: {integrity: sha512-NMRUT40+h0FBa5fb+cpxtZoGAggRem16ocVKIv5gDB5uLDgBIwrIsXlGqYbLwW8YyO3WVTk1FkFDjMETYlDqiw==} + '@rollup/rollup-linux-loongarch64-gnu@4.40.0': + resolution: {integrity: sha512-wG9e2XtIhd++QugU5MD9i7OnpaVb08ji3P1y/hNbxrQ3sYEelKJOq1UJ5dXczeo6Hj2rfDEL5GdtkMSVLa/AOg==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.39.0': - resolution: {integrity: sha512-0pCNnmxgduJ3YRt+D+kJ6Ai/r+TaePu9ZLENl+ZDV/CdVczXl95CbIiwwswu4L+K7uOIGf6tMo2vm8uadRaICQ==} + '@rollup/rollup-linux-powerpc64le-gnu@4.40.0': + resolution: {integrity: sha512-vgXfWmj0f3jAUvC7TZSU/m/cOE558ILWDzS7jBhiCAFpY2WEBn5jqgbqvmzlMjtp8KlLcBlXVD2mkTSEQE6Ixw==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.39.0': - resolution: {integrity: sha512-t7j5Zhr7S4bBtksT73bO6c3Qa2AV/HqiGlj9+KB3gNF5upcVkx+HLgxTm8DK4OkzsOYqbdqbLKwvGMhylJCPhQ==} + '@rollup/rollup-linux-riscv64-gnu@4.40.0': + resolution: {integrity: sha512-uJkYTugqtPZBS3Z136arevt/FsKTF/J9dEMTX/cwR7lsAW4bShzI2R0pJVw+hcBTWF4dxVckYh72Hk3/hWNKvA==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.39.0': - resolution: {integrity: sha512-m6cwI86IvQ7M93MQ2RF5SP8tUjD39Y7rjb1qjHgYh28uAPVU8+k/xYWvxRO3/tBN2pZkSMa5RjnPuUIbrwVxeA==} + '@rollup/rollup-linux-riscv64-musl@4.40.0': + resolution: {integrity: sha512-rKmSj6EXQRnhSkE22+WvrqOqRtk733x3p5sWpZilhmjnkHkpeCgWsFFo0dGnUGeA+OZjRl3+VYq+HyCOEuwcxQ==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.39.0': - resolution: {integrity: sha512-iRDJd2ebMunnk2rsSBYlsptCyuINvxUfGwOUldjv5M4tpa93K8tFMeYGpNk2+Nxl+OBJnBzy2/JCscGeO507kA==} + '@rollup/rollup-linux-s390x-gnu@4.40.0': + resolution: {integrity: sha512-SpnYlAfKPOoVsQqmTFJ0usx0z84bzGOS9anAC0AZ3rdSo3snecihbhFTlJZ8XMwzqAcodjFU4+/SM311dqE5Sw==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.39.0': - resolution: {integrity: sha512-t9jqYw27R6Lx0XKfEFe5vUeEJ5pF3SGIM6gTfONSMb7DuG6z6wfj2yjcoZxHg129veTqU7+wOhY6GX8wmf90dA==} + '@rollup/rollup-linux-x64-gnu@4.40.0': + resolution: {integrity: sha512-RcDGMtqF9EFN8i2RYN2W+64CdHruJ5rPqrlYw+cgM3uOVPSsnAQps7cpjXe9be/yDp8UC7VLoCoKC8J3Kn2FkQ==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.39.0': - resolution: {integrity: sha512-ThFdkrFDP55AIsIZDKSBWEt/JcWlCzydbZHinZ0F/r1h83qbGeenCt/G/wG2O0reuENDD2tawfAj2s8VK7Bugg==} + '@rollup/rollup-linux-x64-musl@4.40.0': + resolution: {integrity: sha512-HZvjpiUmSNx5zFgwtQAV1GaGazT2RWvqeDi0hV+AtC8unqqDSsaFjPxfsO6qPtKRRg25SisACWnJ37Yio8ttaw==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.39.0': - resolution: {integrity: sha512-jDrLm6yUtbOg2TYB3sBF3acUnAwsIksEYjLeHL+TJv9jg+TmTwdyjnDex27jqEMakNKf3RwwPahDIt7QXCSqRQ==} + '@rollup/rollup-win32-arm64-msvc@4.40.0': + resolution: {integrity: sha512-UtZQQI5k/b8d7d3i9AZmA/t+Q4tk3hOC0tMOMSq2GlMYOfxbesxG4mJSeDp0EHs30N9bsfwUvs3zF4v/RzOeTQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.39.0': - resolution: {integrity: sha512-6w9uMuza+LbLCVoNKL5FSLE7yvYkq9laSd09bwS0tMjkwXrmib/4KmoJcrKhLWHvw19mwU+33ndC69T7weNNjQ==} + '@rollup/rollup-win32-ia32-msvc@4.40.0': + resolution: {integrity: sha512-+m03kvI2f5syIqHXCZLPVYplP8pQch9JHyXKZ3AGMKlg8dCyr2PKHjwRLiW53LTrN/Nc3EqHOKxUxzoSPdKddA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.39.0': - resolution: {integrity: sha512-yAkUOkIKZlK5dl7u6dg897doBgLXmUHhIINM2c+sND3DZwnrdQkkSiDh7N75Ll4mM4dxSkYfXqU9fW3lLkMFug==} + '@rollup/rollup-win32-x64-msvc@4.40.0': + resolution: {integrity: sha512-lpPE1cLfP5oPzVjKMx10pgBmKELQnFJXHgvtHCtuJWOv8MxqdEIMNtgHgBFf7Ea2/7EuVwa9fodWUfXAlXZLZQ==} cpu: [x64] os: [win32] @@ -1196,8 +1196,8 @@ packages: '@types/estree@1.0.7': resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} - '@types/node@22.14.0': - resolution: {integrity: sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==} + '@types/node@22.14.1': + resolution: {integrity: sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==} '@types/prop-types@15.7.14': resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==} @@ -1276,8 +1276,8 @@ packages: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} - caniuse-lite@1.0.30001710: - resolution: {integrity: sha512-B5C0I0UmaGqHgo5FuqJ7hBd4L57A4dDD+Xi+XX1nXOoxGeDdY4Ko38qJYOyqznBVJEqON5p8P1x5zRR3+rsnxA==} + caniuse-lite@1.0.30001713: + resolution: {integrity: sha512-wCIWIg+A4Xr7NfhTuHdX+/FKh3+Op3LBbSp2N5Pfx6T/LhdQy3GTyoTg48BReaW/MyMNZAkTadsBtai3ldWK0Q==} chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} @@ -1343,8 +1343,8 @@ packages: eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - electron-to-chromium@1.5.131: - resolution: {integrity: sha512-fJFRYXVEJgDCiqFOgRGJm8XR97hZ13tw7FXI9k2yC5hgY+nyzC2tMO8baq1cQR7Ur58iCkASx2zrkZPZUnfzPg==} + electron-to-chromium@1.5.136: + resolution: {integrity: sha512-kL4+wUTD7RSA5FHx5YwWtjDnEEkIIikFgWHR4P6fqjw1PPLlqYkxeOb++wAauAssat0YClCy8Y3C5SxgSkjibQ==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1379,8 +1379,8 @@ packages: fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} - framer-motion@12.6.3: - resolution: {integrity: sha512-2hsqknz23aloK85bzMc9nSR2/JP+fValQ459ZTVElFQ0xgwR2YqNjYSuDZdFBPOwVCt4Q9jgyTt6hg6sVOALzw==} + framer-motion@12.6.5: + resolution: {integrity: sha512-MKvnWov0paNjvRJuIy6x418w23tFqRfS6CXHhZrCiSEpXVlo/F+usr8v4/3G6O0u7CpsaO1qop+v4Ip7PRCBqQ==} peerDependencies: '@emotion/is-prop-valid': '*' react: ^18.0.0 || ^19.0.0 @@ -1514,11 +1514,11 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} - motion-dom@12.6.3: - resolution: {integrity: sha512-gRY08RjcnzgFYLemUZ1lo/e9RkBxR+6d4BRvoeZDSeArG4XQXERSPapKl3LNQRu22Sndjf1h+iavgY0O4NrYqA==} + motion-dom@12.6.5: + resolution: {integrity: sha512-jpM9TQLXzYMWMJ7Ec7sAj0iis8oIuu6WvjI3yNKJLdrZyrsI/b2cRInDVL8dCl683zQQq19DpL9cSMP+k8T1NA==} - motion-utils@12.6.3: - resolution: {integrity: sha512-R/b3Ia2VxtTNZ4LTEO5pKYau1OUNHOuUfxuP0WFCTDYdHkeTBR9UtxR1cc8mDmKr8PEhmmfnTKGz3rSMjNRoRg==} + motion-utils@12.6.5: + resolution: {integrity: sha512-IsOeKsOF+FWBhxQEDFBO6ZYC8/jlidmVbbLpe9/lXSA9j9kzGIMUuIBx2SZY+0reAS0DjZZ1i7dJp4NHrjocPw==} ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -1714,8 +1714,8 @@ packages: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rollup@4.39.0: - resolution: {integrity: sha512-thI8kNc02yNvnmJp8dr3fNWJ9tCONDhp6TV35X6HkKGGs9E6q7YWCHbe5vKiTa7TAiNcFEmXKj3X/pG2b3ci0g==} + rollup@4.40.0: + resolution: {integrity: sha512-Noe455xmA96nnqH5piFtLobsGbCij7Tu+tb3c1vYjNbTkfzGqXqQXG3wJaYXkRZuQ0vEYN4bhwg7QnIrqB5B+w==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -1806,8 +1806,8 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - typescript@5.8.2: - resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} + typescript@5.8.3: + resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} engines: {node: '>=14.17'} hasBin: true @@ -1843,8 +1843,8 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - vite@5.4.17: - resolution: {integrity: sha512-5+VqZryDj4wgCs55o9Lp+p8GE78TLVg0lasCH5xFZ4jacZjtqZa6JUw9/p0WeAojaOfncSM6v77InkFPGnvPvg==} + vite@5.4.18: + resolution: {integrity: sha512-1oDcnEp3lVyHCuQ2YFelM4Alm2o91xNoMncRm1U7S+JdYfYOvbiGZ3/CxGttrOu2M/KcGz7cRC2DoNUA6urmMA==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -2145,45 +2145,45 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@radix-ui/number@1.1.0': {} + '@radix-ui/number@1.1.1': {} '@radix-ui/primitive@1.0.1': dependencies: '@babel/runtime': 7.27.0 - '@radix-ui/primitive@1.1.1': {} + '@radix-ui/primitive@1.1.2': {} - '@radix-ui/react-arrow@1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-arrow@1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: '@types/react': 18.3.20 '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-checkbox@1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-checkbox@1.1.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-presence': 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: '@types/react': 18.3.20 '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-collection@1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-collection@1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.0(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: @@ -2197,7 +2197,7 @@ snapshots: optionalDependencies: '@types/react': 18.3.20 - '@radix-ui/react-compose-refs@1.1.1(@types/react@18.3.20)(react@18.3.1)': + '@radix-ui/react-compose-refs@1.1.2(@types/react@18.3.20)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: @@ -2210,7 +2210,7 @@ snapshots: optionalDependencies: '@types/react': 18.3.20 - '@radix-ui/react-context@1.1.1(@types/react@18.3.20)(react@18.3.1)': + '@radix-ui/react-context@1.1.2(@types/react@18.3.20)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: @@ -2239,20 +2239,20 @@ snapshots: '@types/react': 18.3.20 '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-dialog@1.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.1.2(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-dialog@1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-portal': 1.1.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.1(@types/react@18.3.20)(react@18.3.1) aria-hidden: 1.2.4 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -2261,7 +2261,7 @@ snapshots: '@types/react': 18.3.20 '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-direction@1.1.0(@types/react@18.3.20)(react@18.3.1)': + '@radix-ui/react-direction@1.1.1(@types/react@18.3.20)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: @@ -2281,28 +2281,28 @@ snapshots: '@types/react': 18.3.20 '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-dismissable-layer@1.1.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-dismissable-layer@1.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: '@types/react': 18.3.20 '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-dropdown-menu@2.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-dropdown-menu@2.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-id': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-menu': 2.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-menu': 2.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.1(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: @@ -2316,7 +2316,7 @@ snapshots: optionalDependencies: '@types/react': 18.3.20 - '@radix-ui/react-focus-guards@1.1.1(@types/react@18.3.20)(react@18.3.1)': + '@radix-ui/react-focus-guards@1.1.2(@types/react@18.3.20)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: @@ -2334,11 +2334,11 @@ snapshots: '@types/react': 18.3.20 '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-focus-scope@1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-focus-scope@1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: @@ -2357,40 +2357,40 @@ snapshots: optionalDependencies: '@types/react': 18.3.20 - '@radix-ui/react-id@1.1.0(@types/react@18.3.20)(react@18.3.1)': + '@radix-ui/react-id@1.1.1(@types/react@18.3.20)(react@18.3.1)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 optionalDependencies: '@types/react': 18.3.20 - '@radix-ui/react-label@2.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-label@2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: '@types/react': 18.3.20 '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-menu@2.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-direction': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.1.2(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-menu@2.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-collection': 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-popper': 1.2.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.20)(react@18.3.1) aria-hidden: 1.2.4 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -2399,39 +2399,39 @@ snapshots: '@types/react': 18.3.20 '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-menubar@1.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-menubar@1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-direction': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-id': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-menu': 2.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-collection': 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-menu': 2.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.1(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: '@types/react': 18.3.20 '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-popover@1.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.1.2(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-popover@1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-popper': 1.2.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.1(@types/react@18.3.20)(react@18.3.1) aria-hidden: 1.2.4 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -2440,18 +2440,18 @@ snapshots: '@types/react': 18.3.20 '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-popper@1.2.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-popper@1.2.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@floating-ui/react-dom': 2.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-arrow': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-use-rect': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/rect': 1.1.0 + '@radix-ui/react-arrow': 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-rect': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/rect': 1.1.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: @@ -2468,10 +2468,10 @@ snapshots: '@types/react': 18.3.20 '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-portal@1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-portal@1.1.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: @@ -2489,10 +2489,10 @@ snapshots: '@types/react': 18.3.20 '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-presence@1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-presence@1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: @@ -2509,71 +2509,71 @@ snapshots: '@types/react': 18.3.20 '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-primitive@2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-primitive@2.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-slot': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-slot': 1.2.0(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: '@types/react': 18.3.20 '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-radio-group@1.2.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-radio-group@1.2.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-direction': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-presence': 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: '@types/react': 18.3.20 '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-roving-focus@1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-roving-focus@1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-direction': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-id': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-collection': 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.1(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: '@types/react': 18.3.20 '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-select@2.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/number': 1.1.0 - '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-direction': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.1.2(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-select@2.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/number': 1.1.1 + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-collection': 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-popper': 1.2.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) aria-hidden: 1.2.4 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -2582,9 +2582,9 @@ snapshots: '@types/react': 18.3.20 '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-separator@1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-separator@1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: @@ -2599,58 +2599,58 @@ snapshots: optionalDependencies: '@types/react': 18.3.20 - '@radix-ui/react-slot@1.1.2(@types/react@18.3.20)(react@18.3.1)': + '@radix-ui/react-slot@1.2.0(@types/react@18.3.20)(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 optionalDependencies: '@types/react': 18.3.20 - '@radix-ui/react-switch@1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-switch@1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: '@types/react': 18.3.20 '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-tabs@1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-tabs@1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-direction': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-id': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-presence': 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.1(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: '@types/react': 18.3.20 '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/react-tooltip@1.1.8(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-context': 1.1.1(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.1.2(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.20)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-tooltip@1.2.0(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.6(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-popper': 1.2.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: @@ -2664,7 +2664,7 @@ snapshots: optionalDependencies: '@types/react': 18.3.20 - '@radix-ui/react-use-callback-ref@1.1.0(@types/react@18.3.20)(react@18.3.1)': + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@18.3.20)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: @@ -2678,9 +2678,9 @@ snapshots: optionalDependencies: '@types/react': 18.3.20 - '@radix-ui/react-use-controllable-state@1.1.0(@types/react@18.3.20)(react@18.3.1)': + '@radix-ui/react-use-controllable-state@1.1.1(@types/react@18.3.20)(react@18.3.1)': dependencies: - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 optionalDependencies: '@types/react': 18.3.20 @@ -2693,9 +2693,9 @@ snapshots: optionalDependencies: '@types/react': 18.3.20 - '@radix-ui/react-use-escape-keydown@1.1.0(@types/react@18.3.20)(react@18.3.1)': + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@18.3.20)(react@18.3.1)': dependencies: - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 optionalDependencies: '@types/react': 18.3.20 @@ -2707,103 +2707,103 @@ snapshots: optionalDependencies: '@types/react': 18.3.20 - '@radix-ui/react-use-layout-effect@1.1.0(@types/react@18.3.20)(react@18.3.1)': + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@18.3.20)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: '@types/react': 18.3.20 - '@radix-ui/react-use-previous@1.1.0(@types/react@18.3.20)(react@18.3.1)': + '@radix-ui/react-use-previous@1.1.1(@types/react@18.3.20)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: '@types/react': 18.3.20 - '@radix-ui/react-use-rect@1.1.0(@types/react@18.3.20)(react@18.3.1)': + '@radix-ui/react-use-rect@1.1.1(@types/react@18.3.20)(react@18.3.1)': dependencies: - '@radix-ui/rect': 1.1.0 + '@radix-ui/rect': 1.1.1 react: 18.3.1 optionalDependencies: '@types/react': 18.3.20 - '@radix-ui/react-use-size@1.1.0(@types/react@18.3.20)(react@18.3.1)': + '@radix-ui/react-use-size@1.1.1(@types/react@18.3.20)(react@18.3.1)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.20)(react@18.3.1) react: 18.3.1 optionalDependencies: '@types/react': 18.3.20 - '@radix-ui/react-visually-hidden@1.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-visually-hidden@1.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: '@types/react': 18.3.20 '@types/react-dom': 18.3.6(@types/react@18.3.20) - '@radix-ui/rect@1.1.0': {} + '@radix-ui/rect@1.1.1': {} '@remix-run/router@1.23.0': {} - '@rollup/rollup-android-arm-eabi@4.39.0': + '@rollup/rollup-android-arm-eabi@4.40.0': optional: true - '@rollup/rollup-android-arm64@4.39.0': + '@rollup/rollup-android-arm64@4.40.0': optional: true - '@rollup/rollup-darwin-arm64@4.39.0': + '@rollup/rollup-darwin-arm64@4.40.0': optional: true - '@rollup/rollup-darwin-x64@4.39.0': + '@rollup/rollup-darwin-x64@4.40.0': optional: true - '@rollup/rollup-freebsd-arm64@4.39.0': + '@rollup/rollup-freebsd-arm64@4.40.0': optional: true - '@rollup/rollup-freebsd-x64@4.39.0': + '@rollup/rollup-freebsd-x64@4.40.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.39.0': + '@rollup/rollup-linux-arm-gnueabihf@4.40.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.39.0': + '@rollup/rollup-linux-arm-musleabihf@4.40.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.39.0': + '@rollup/rollup-linux-arm64-gnu@4.40.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.39.0': + '@rollup/rollup-linux-arm64-musl@4.40.0': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.39.0': + '@rollup/rollup-linux-loongarch64-gnu@4.40.0': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.39.0': + '@rollup/rollup-linux-powerpc64le-gnu@4.40.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.39.0': + '@rollup/rollup-linux-riscv64-gnu@4.40.0': optional: true - '@rollup/rollup-linux-riscv64-musl@4.39.0': + '@rollup/rollup-linux-riscv64-musl@4.40.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.39.0': + '@rollup/rollup-linux-s390x-gnu@4.40.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.39.0': + '@rollup/rollup-linux-x64-gnu@4.40.0': optional: true - '@rollup/rollup-linux-x64-musl@4.39.0': + '@rollup/rollup-linux-x64-musl@4.40.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.39.0': + '@rollup/rollup-win32-arm64-msvc@4.40.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.39.0': + '@rollup/rollup-win32-ia32-msvc@4.40.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.39.0': + '@rollup/rollup-win32-x64-msvc@4.40.0': optional: true '@tauri-apps/api@2.4.1': {} @@ -2882,7 +2882,7 @@ snapshots: '@types/estree@1.0.7': {} - '@types/node@22.14.0': + '@types/node@22.14.1': dependencies: undici-types: 6.21.0 @@ -2897,14 +2897,14 @@ snapshots: '@types/prop-types': 15.7.14 csstype: 3.1.3 - '@vitejs/plugin-react@4.3.4(vite@5.4.17(@types/node@22.14.0))': + '@vitejs/plugin-react@4.3.4(vite@5.4.18(@types/node@22.14.1))': dependencies: '@babel/core': 7.26.10 '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.10) '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.10) '@types/babel__core': 7.20.5 react-refresh: 0.14.2 - vite: 5.4.17(@types/node@22.14.0) + vite: 5.4.18(@types/node@22.14.1) transitivePeerDependencies: - supports-color @@ -2934,7 +2934,7 @@ snapshots: autoprefixer@10.4.21(postcss@8.5.3): dependencies: browserslist: 4.24.4 - caniuse-lite: 1.0.30001710 + caniuse-lite: 1.0.30001713 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 @@ -2955,14 +2955,14 @@ snapshots: browserslist@4.24.4: dependencies: - caniuse-lite: 1.0.30001710 - electron-to-chromium: 1.5.131 + caniuse-lite: 1.0.30001713 + electron-to-chromium: 1.5.136 node-releases: 2.0.19 update-browserslist-db: 1.1.3(browserslist@4.24.4) camelcase-css@2.0.1: {} - caniuse-lite@1.0.30001710: {} + caniuse-lite@1.0.30001713: {} chokidar@3.6.0: dependencies: @@ -3024,7 +3024,7 @@ snapshots: eastasianwidth@0.2.0: {} - electron-to-chromium@1.5.131: {} + electron-to-chromium@1.5.136: {} emoji-regex@8.0.0: {} @@ -3081,10 +3081,10 @@ snapshots: fraction.js@4.3.7: {} - framer-motion@12.6.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + framer-motion@12.6.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - motion-dom: 12.6.3 - motion-utils: 12.6.3 + motion-dom: 12.6.5 + motion-utils: 12.6.5 tslib: 2.8.1 optionalDependencies: react: 18.3.1 @@ -3187,11 +3187,11 @@ snapshots: minipass@7.1.2: {} - motion-dom@12.6.3: + motion-dom@12.6.5: dependencies: - motion-utils: 12.6.3 + motion-utils: 12.6.5 - motion-utils@12.6.3: {} + motion-utils@12.6.5: {} ms@2.1.3: {} @@ -3356,30 +3356,30 @@ snapshots: reusify@1.1.0: {} - rollup@4.39.0: + rollup@4.40.0: dependencies: '@types/estree': 1.0.7 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.39.0 - '@rollup/rollup-android-arm64': 4.39.0 - '@rollup/rollup-darwin-arm64': 4.39.0 - '@rollup/rollup-darwin-x64': 4.39.0 - '@rollup/rollup-freebsd-arm64': 4.39.0 - '@rollup/rollup-freebsd-x64': 4.39.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.39.0 - '@rollup/rollup-linux-arm-musleabihf': 4.39.0 - '@rollup/rollup-linux-arm64-gnu': 4.39.0 - '@rollup/rollup-linux-arm64-musl': 4.39.0 - '@rollup/rollup-linux-loongarch64-gnu': 4.39.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.39.0 - '@rollup/rollup-linux-riscv64-gnu': 4.39.0 - '@rollup/rollup-linux-riscv64-musl': 4.39.0 - '@rollup/rollup-linux-s390x-gnu': 4.39.0 - '@rollup/rollup-linux-x64-gnu': 4.39.0 - '@rollup/rollup-linux-x64-musl': 4.39.0 - '@rollup/rollup-win32-arm64-msvc': 4.39.0 - '@rollup/rollup-win32-ia32-msvc': 4.39.0 - '@rollup/rollup-win32-x64-msvc': 4.39.0 + '@rollup/rollup-android-arm-eabi': 4.40.0 + '@rollup/rollup-android-arm64': 4.40.0 + '@rollup/rollup-darwin-arm64': 4.40.0 + '@rollup/rollup-darwin-x64': 4.40.0 + '@rollup/rollup-freebsd-arm64': 4.40.0 + '@rollup/rollup-freebsd-x64': 4.40.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.40.0 + '@rollup/rollup-linux-arm-musleabihf': 4.40.0 + '@rollup/rollup-linux-arm64-gnu': 4.40.0 + '@rollup/rollup-linux-arm64-musl': 4.40.0 + '@rollup/rollup-linux-loongarch64-gnu': 4.40.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.40.0 + '@rollup/rollup-linux-riscv64-gnu': 4.40.0 + '@rollup/rollup-linux-riscv64-musl': 4.40.0 + '@rollup/rollup-linux-s390x-gnu': 4.40.0 + '@rollup/rollup-linux-x64-gnu': 4.40.0 + '@rollup/rollup-linux-x64-musl': 4.40.0 + '@rollup/rollup-win32-arm64-msvc': 4.40.0 + '@rollup/rollup-win32-ia32-msvc': 4.40.0 + '@rollup/rollup-win32-x64-msvc': 4.40.0 fsevents: 2.3.3 run-parallel@1.2.0: @@ -3488,7 +3488,7 @@ snapshots: tslib@2.8.1: {} - typescript@5.8.2: {} + typescript@5.8.3: {} undici-types@6.21.0: {} @@ -3515,13 +3515,13 @@ snapshots: util-deprecate@1.0.2: {} - vite@5.4.17(@types/node@22.14.0): + vite@5.4.18(@types/node@22.14.1): dependencies: esbuild: 0.21.5 postcss: 8.5.3 - rollup: 4.39.0 + rollup: 4.40.0 optionalDependencies: - '@types/node': 22.14.0 + '@types/node': 22.14.1 fsevents: 2.3.3 which@2.0.2: diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 23eb941..15c6ad5 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -365,9 +365,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.17" +version = "1.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" +checksum = "8e3a13707ac958681c13b39b458c073d0d9bc8a22cb1b2f4c8e55eb72c13f362" dependencies = [ "shlex", ] @@ -550,9 +550,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.14" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" dependencies = [ "crossbeam-utils", ] @@ -688,9 +688,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.4.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cfac68e08048ae1883171632c2aef3ebc555621ae56fbccce1cbf22dd7f058" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" dependencies = [ "powerfmt", "serde", @@ -910,9 +910,9 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" dependencies = [ "libc", "windows-sys 0.59.0", @@ -1845,9 +1845,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", "hashbrown 0.15.2", @@ -2060,9 +2060,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" [[package]] name = "litemap" @@ -2145,9 +2145,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.8.7" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff70ce3e48ae43fa075863cef62e8b43b71a4f2382229920e0df362592919430" +checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" dependencies = [ "adler2", "simd-adler32", @@ -2560,9 +2560,9 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "openssl" -version = "0.10.71" +version = "0.10.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" +checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da" dependencies = [ "bitflags 2.9.0", "cfg-if", @@ -2592,9 +2592,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.106" +version = "0.9.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" +checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07" dependencies = [ "cc", "libc", @@ -2867,7 +2867,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eac26e981c03a6e53e0aee43c113e3202f5581d5360dae7bd2c70e800dd0451d" dependencies = [ "base64 0.22.1", - "indexmap 2.8.0", + "indexmap 2.9.0", "quick-xml", "serde", "time", @@ -3117,9 +3117,9 @@ checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" [[package]] name = "redox_syscall" -version = "0.5.10" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" +checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" dependencies = [ "bitflags 2.9.0", ] @@ -3486,7 +3486,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.8.0", + "indexmap 2.9.0", "serde", "serde_derive", "serde_json", @@ -3614,9 +3614,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" dependencies = [ "serde", ] @@ -3728,7 +3728,7 @@ dependencies = [ "futures-util", "hashbrown 0.15.2", "hashlink", - "indexmap 2.8.0", + "indexmap 2.9.0", "log", "memchr", "native-tls", @@ -4477,9 +4477,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.44.1" +version = "1.44.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" +checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48" dependencies = [ "backtrace", "bytes", @@ -4555,7 +4555,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.8.0", + "indexmap 2.9.0", "toml_datetime", "winnow 0.5.40", ] @@ -4566,7 +4566,7 @@ version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" dependencies = [ - "indexmap 2.8.0", + "indexmap 2.9.0", "toml_datetime", "winnow 0.5.40", ] @@ -4577,11 +4577,11 @@ version = "0.22.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" dependencies = [ - "indexmap 2.8.0", + "indexmap 2.9.0", "serde", "serde_spanned", "toml_datetime", - "winnow 0.7.4", + "winnow 0.7.6", ] [[package]] @@ -5577,9 +5577,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" +checksum = "63d3fcd9bba44b03821e7d699eeee959f3126dcc4aa8e4ae18ec617c2a5cea10" dependencies = [ "memchr", ] @@ -5737,7 +5737,7 @@ dependencies = [ "tracing", "uds_windows", "windows-sys 0.59.0", - "winnow 0.7.4", + "winnow 0.7.6", "xdg-home", "zbus_macros", "zbus_names", @@ -5767,7 +5767,7 @@ checksum = "7be68e64bf6ce8db94f63e72f0c7eb9a60d733f7e0499e628dfab0f84d6bcb97" dependencies = [ "serde", "static_assertions", - "winnow 0.7.4", + "winnow 0.7.6", "zvariant", ] @@ -5851,7 +5851,7 @@ dependencies = [ "serde", "static_assertions", "url", - "winnow 0.7.4", + "winnow 0.7.6", "zvariant_derive", "zvariant_utils", ] @@ -5880,5 +5880,5 @@ dependencies = [ "serde", "static_assertions", "syn 2.0.100", - "winnow 0.7.4", + "winnow 0.7.6", ] diff --git a/src-tauri/src/fileflow/utils/string_formater.rs b/src-tauri/src/fileflow/utils/string_formater.rs index 19cf87c..1ec4562 100644 --- a/src-tauri/src/fileflow/utils/string_formater.rs +++ b/src-tauri/src/fileflow/utils/string_formater.rs @@ -18,7 +18,7 @@ pub fn get_formated_column_names(headers: &[String]) -> Vec { /// Sanitize a value for safe insertion into the database pub fn sanitize_value(value: &str) -> String { - let mut sanitized:String = String::with_capacity(value.len()); + let mut sanitized: String = String::with_capacity(value.len()); for c in value.trim().chars() { match c { @@ -39,9 +39,9 @@ pub fn sanitize_column(value: &str) -> String { .trim() .chars() .filter_map(|c| match c { - '\'' | '\\' | '\"' => None, // Remove these characters - ' ' => Some('_'), // Replace spaces with underscores - _ => Some(c), // Keep everything else + '\'' | '\\' | '\"' => None, // Remove these characters + ' ' => Some('_'), // Replace spaces with underscores + _ => Some(c.to_ascii_lowercase()), // to lowercase }) .collect() } diff --git a/src-tauri/src/tests/string_formater_test.rs b/src-tauri/src/tests/string_formater_test.rs index b6b13e1..5973aa3 100644 --- a/src-tauri/src/tests/string_formater_test.rs +++ b/src-tauri/src/tests/string_formater_test.rs @@ -37,6 +37,7 @@ async fn test_sanitize_column() { assert_eq!(sanitize_column("column1\"column2"), "column1column2"); assert_eq!(sanitize_column("column 1"), "column_1"); assert_eq!(sanitize_column("column 1'"), "column_1"); + assert_eq!(sanitize_column("COlUMn 1'"), "column_1"); } #[tokio::test]