diff --git a/apps/frontend/.env.example b/apps/frontend/.env.example
new file mode 100644
index 0000000..ff04daf
--- /dev/null
+++ b/apps/frontend/.env.example
@@ -0,0 +1,4 @@
+# Backend API base URL (no trailing slash, no /api suffix)
+# Dev local: http://localhost:3000
+# Prod VPS: https://api.ti-pote.example.com
+VITE_API_URL=http://localhost:3000
diff --git a/apps/frontend/.gitignore b/apps/frontend/.gitignore
new file mode 100644
index 0000000..fdaeba9
--- /dev/null
+++ b/apps/frontend/.gitignore
@@ -0,0 +1,39 @@
+# Dependencies
+node_modules/
+.pnp
+.pnp.js
+
+# Build output
+dist/
+dist-ssr/
+build/
+*.local
+
+# Vite
+.vite/
+
+# Env
+.env
+.env.local
+.env.*.local
+
+# IDE
+.vscode/*
+!.vscode/extensions.json
+.idea/
+*.swp
+*.swo
+.DS_Store
+
+# Logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# Tauri (Rust build artifacts)
+src-tauri/target/
+src-tauri/Cargo.lock
+src-tauri/gen/schemas/
+src-tauri/WixTools/
diff --git a/apps/frontend/README.md b/apps/frontend/README.md
new file mode 100644
index 0000000..f81119c
--- /dev/null
+++ b/apps/frontend/README.md
@@ -0,0 +1,68 @@
+# @ti-pote/frontend
+
+Desktop companion app for Ti-Pote. **Vite + React + TypeScript + Tailwind**,
+wrappable as a native desktop app with **Tauri v2**.
+
+## Features
+
+- Auth: register / login / auto refresh-token rotation
+- Session persistence (Tauri Store plugin on desktop, localStorage in browser)
+- Dashboard: list of associated robots (`GET /api/devices`)
+- Robot pairing: 6-digit code screen wired to `POST /api/pairing/confirm`
+
+## Quick start (web dev)
+
+```bash
+cd apps/frontend
+cp .env.example .env # point VITE_API_URL to your backend
+pnpm install
+pnpm dev # http://localhost:1420
+```
+
+## Desktop build (Tauri v2)
+
+Prerequisites: Rust toolchain (`rustup`) and the
+[Tauri prerequisites](https://v2.tauri.app/start/prerequisites/) for your OS.
+
+```bash
+# First time only: generate the bundle icons from any source PNG
+pnpm tauri icon path/to/logo.png
+
+# Dev (hot reload + native window)
+pnpm tauri dev
+
+# Production bundle (.dmg / .app on macOS, .msi on Windows, .deb/.AppImage on Linux)
+pnpm tauri build
+```
+
+## Project layout
+
+```
+apps/frontend/
+├── src/
+│ ├── components/ Button / Input / Card / ProtectedRoute
+│ ├── context/ AuthContext (React)
+│ ├── lib/
+│ │ ├── api.ts fetch wrapper + typed endpoints + auto-refresh
+│ │ └── storage.ts Tauri Store ↔ localStorage fallback
+│ ├── pages/ Login / Register / Dashboard / PairRobot
+│ ├── styles/ Tailwind entry
+│ ├── App.tsx Router
+│ └── main.tsx Entry point
+└── src-tauri/ Tauri v2 Rust wrapper
+ ├── Cargo.toml
+ ├── tauri.conf.json
+ ├── capabilities/
+ └── src/{main.rs,lib.rs}
+```
+
+## Backend API used
+
+| Flow | Endpoint | Notes |
+| -------- | ---------------------------- | ---------------------------------- |
+| Register | `POST /api/auth/register` | Creates user + home |
+| Login | `POST /api/auth/login` | |
+| Refresh | `POST /api/auth/refresh` | Called transparently on 401 |
+| Me | `GET /api/auth/me` | |
+| Devices | `GET /api/devices` | Dashboard |
+| Pair | `POST /api/pairing/confirm` | `{ code }` — 6-digit from robot UI |
diff --git a/apps/frontend/index.html b/apps/frontend/index.html
new file mode 100644
index 0000000..e306f6d
--- /dev/null
+++ b/apps/frontend/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+ Ti-Pote
+
+
+
+
+
+
diff --git a/apps/frontend/package.json b/apps/frontend/package.json
new file mode 100644
index 0000000..3249f76
--- /dev/null
+++ b/apps/frontend/package.json
@@ -0,0 +1,32 @@
+{
+ "name": "@ti-pote/frontend",
+ "private": true,
+ "version": "0.0.1",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "tsc -b && vite build",
+ "preview": "vite preview",
+ "lint": "eslint src --ext ts,tsx --max-warnings 0",
+ "tauri": "tauri"
+ },
+ "dependencies": {
+ "@tauri-apps/api": "^2.0.0",
+ "@tauri-apps/plugin-store": "^2.0.0",
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1",
+ "react-router-dom": "^6.26.0",
+ "zustand": "^4.5.5"
+ },
+ "devDependencies": {
+ "@tauri-apps/cli": "^2.0.0",
+ "@types/react": "^18.3.3",
+ "@types/react-dom": "^18.3.0",
+ "@vitejs/plugin-react": "^4.3.1",
+ "autoprefixer": "^10.4.20",
+ "postcss": "^8.4.41",
+ "tailwindcss": "^3.4.10",
+ "typescript": "^5.5.4",
+ "vite": "^5.4.2"
+ }
+}
diff --git a/apps/frontend/postcss.config.js b/apps/frontend/postcss.config.js
new file mode 100644
index 0000000..2aa7205
--- /dev/null
+++ b/apps/frontend/postcss.config.js
@@ -0,0 +1,6 @@
+export default {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+};
diff --git a/apps/frontend/src-tauri/.gitignore b/apps/frontend/src-tauri/.gitignore
new file mode 100644
index 0000000..1b03424
--- /dev/null
+++ b/apps/frontend/src-tauri/.gitignore
@@ -0,0 +1,6 @@
+# Generated by Cargo
+target/
+Cargo.lock
+
+# Generated by Tauri
+gen/schemas/
diff --git a/apps/frontend/src-tauri/Cargo.toml b/apps/frontend/src-tauri/Cargo.toml
new file mode 100644
index 0000000..9650bbf
--- /dev/null
+++ b/apps/frontend/src-tauri/Cargo.toml
@@ -0,0 +1,25 @@
+[package]
+name = "ti-pote-desktop"
+version = "0.0.1"
+description = "Ti-Pote desktop companion app"
+authors = ["Arthur"]
+edition = "2021"
+rust-version = "1.77"
+
+[lib]
+name = "ti_pote_desktop_lib"
+crate-type = ["staticlib", "cdylib", "rlib"]
+
+[build-dependencies]
+tauri-build = { version = "2", features = [] }
+
+[dependencies]
+tauri = { version = "2", features = [] }
+tauri-plugin-store = "2"
+serde = { version = "1", features = ["derive"] }
+serde_json = "1"
+
+[features]
+# This feature is used for production builds or when a dev server is not specified,
+# DO NOT REMOVE!!
+custom-protocol = ["tauri/custom-protocol"]
diff --git a/apps/frontend/src-tauri/build.rs b/apps/frontend/src-tauri/build.rs
new file mode 100644
index 0000000..d860e1e
--- /dev/null
+++ b/apps/frontend/src-tauri/build.rs
@@ -0,0 +1,3 @@
+fn main() {
+ tauri_build::build()
+}
diff --git a/apps/frontend/src-tauri/capabilities/default.json b/apps/frontend/src-tauri/capabilities/default.json
new file mode 100644
index 0000000..b9fc682
--- /dev/null
+++ b/apps/frontend/src-tauri/capabilities/default.json
@@ -0,0 +1,10 @@
+{
+ "$schema": "../gen/schemas/desktop-schema.json",
+ "identifier": "default",
+ "description": "Default permissions for the main window",
+ "windows": ["main"],
+ "permissions": [
+ "core:default",
+ "store:default"
+ ]
+}
diff --git a/apps/frontend/src-tauri/icons/128x128.png b/apps/frontend/src-tauri/icons/128x128.png
new file mode 100644
index 0000000..53606db
Binary files /dev/null and b/apps/frontend/src-tauri/icons/128x128.png differ
diff --git a/apps/frontend/src-tauri/icons/128x128@2x.png b/apps/frontend/src-tauri/icons/128x128@2x.png
new file mode 100644
index 0000000..3a8827f
Binary files /dev/null and b/apps/frontend/src-tauri/icons/128x128@2x.png differ
diff --git a/apps/frontend/src-tauri/icons/32x32.png b/apps/frontend/src-tauri/icons/32x32.png
new file mode 100644
index 0000000..ab7f0d8
Binary files /dev/null and b/apps/frontend/src-tauri/icons/32x32.png differ
diff --git a/apps/frontend/src-tauri/icons/64x64.png b/apps/frontend/src-tauri/icons/64x64.png
new file mode 100644
index 0000000..8858528
Binary files /dev/null and b/apps/frontend/src-tauri/icons/64x64.png differ
diff --git a/apps/frontend/src-tauri/icons/Square107x107Logo.png b/apps/frontend/src-tauri/icons/Square107x107Logo.png
new file mode 100644
index 0000000..ba34e79
Binary files /dev/null and b/apps/frontend/src-tauri/icons/Square107x107Logo.png differ
diff --git a/apps/frontend/src-tauri/icons/Square142x142Logo.png b/apps/frontend/src-tauri/icons/Square142x142Logo.png
new file mode 100644
index 0000000..c0636c8
Binary files /dev/null and b/apps/frontend/src-tauri/icons/Square142x142Logo.png differ
diff --git a/apps/frontend/src-tauri/icons/Square150x150Logo.png b/apps/frontend/src-tauri/icons/Square150x150Logo.png
new file mode 100644
index 0000000..75394d1
Binary files /dev/null and b/apps/frontend/src-tauri/icons/Square150x150Logo.png differ
diff --git a/apps/frontend/src-tauri/icons/Square284x284Logo.png b/apps/frontend/src-tauri/icons/Square284x284Logo.png
new file mode 100644
index 0000000..a0dcb03
Binary files /dev/null and b/apps/frontend/src-tauri/icons/Square284x284Logo.png differ
diff --git a/apps/frontend/src-tauri/icons/Square30x30Logo.png b/apps/frontend/src-tauri/icons/Square30x30Logo.png
new file mode 100644
index 0000000..7646530
Binary files /dev/null and b/apps/frontend/src-tauri/icons/Square30x30Logo.png differ
diff --git a/apps/frontend/src-tauri/icons/Square310x310Logo.png b/apps/frontend/src-tauri/icons/Square310x310Logo.png
new file mode 100644
index 0000000..af294f6
Binary files /dev/null and b/apps/frontend/src-tauri/icons/Square310x310Logo.png differ
diff --git a/apps/frontend/src-tauri/icons/Square44x44Logo.png b/apps/frontend/src-tauri/icons/Square44x44Logo.png
new file mode 100644
index 0000000..ae45b6f
Binary files /dev/null and b/apps/frontend/src-tauri/icons/Square44x44Logo.png differ
diff --git a/apps/frontend/src-tauri/icons/Square71x71Logo.png b/apps/frontend/src-tauri/icons/Square71x71Logo.png
new file mode 100644
index 0000000..c90805d
Binary files /dev/null and b/apps/frontend/src-tauri/icons/Square71x71Logo.png differ
diff --git a/apps/frontend/src-tauri/icons/Square89x89Logo.png b/apps/frontend/src-tauri/icons/Square89x89Logo.png
new file mode 100644
index 0000000..8b3d51b
Binary files /dev/null and b/apps/frontend/src-tauri/icons/Square89x89Logo.png differ
diff --git a/apps/frontend/src-tauri/icons/StoreLogo.png b/apps/frontend/src-tauri/icons/StoreLogo.png
new file mode 100644
index 0000000..55d6d54
Binary files /dev/null and b/apps/frontend/src-tauri/icons/StoreLogo.png differ
diff --git a/apps/frontend/src-tauri/icons/android/mipmap-anydpi-v26/ic_launcher.xml b/apps/frontend/src-tauri/icons/android/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..2ffbf24
--- /dev/null
+++ b/apps/frontend/src-tauri/icons/android/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/apps/frontend/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png b/apps/frontend/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..3e7b56b
Binary files /dev/null and b/apps/frontend/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png differ
diff --git a/apps/frontend/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png b/apps/frontend/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..40df639
Binary files /dev/null and b/apps/frontend/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png differ
diff --git a/apps/frontend/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png b/apps/frontend/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..8dd9584
Binary files /dev/null and b/apps/frontend/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/apps/frontend/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png b/apps/frontend/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..bf35071
Binary files /dev/null and b/apps/frontend/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png differ
diff --git a/apps/frontend/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png b/apps/frontend/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..918e3a7
Binary files /dev/null and b/apps/frontend/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png differ
diff --git a/apps/frontend/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png b/apps/frontend/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..2191b62
Binary files /dev/null and b/apps/frontend/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/apps/frontend/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png b/apps/frontend/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..5096c30
Binary files /dev/null and b/apps/frontend/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png differ
diff --git a/apps/frontend/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png b/apps/frontend/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..7ee84f7
Binary files /dev/null and b/apps/frontend/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png differ
diff --git a/apps/frontend/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png b/apps/frontend/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..b9c87bb
Binary files /dev/null and b/apps/frontend/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/apps/frontend/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png b/apps/frontend/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..962b36e
Binary files /dev/null and b/apps/frontend/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/apps/frontend/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png b/apps/frontend/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..e9a0fce
Binary files /dev/null and b/apps/frontend/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png differ
diff --git a/apps/frontend/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png b/apps/frontend/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..ec00bd9
Binary files /dev/null and b/apps/frontend/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/apps/frontend/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png b/apps/frontend/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..5cd79a7
Binary files /dev/null and b/apps/frontend/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/apps/frontend/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png b/apps/frontend/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..238cfa2
Binary files /dev/null and b/apps/frontend/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png differ
diff --git a/apps/frontend/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png b/apps/frontend/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..4ba62fc
Binary files /dev/null and b/apps/frontend/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/apps/frontend/src-tauri/icons/android/values/ic_launcher_background.xml b/apps/frontend/src-tauri/icons/android/values/ic_launcher_background.xml
new file mode 100644
index 0000000..ea9c223
--- /dev/null
+++ b/apps/frontend/src-tauri/icons/android/values/ic_launcher_background.xml
@@ -0,0 +1,4 @@
+
+
+ #fff
+
\ No newline at end of file
diff --git a/apps/frontend/src-tauri/icons/icon.icns b/apps/frontend/src-tauri/icons/icon.icns
new file mode 100644
index 0000000..c369568
Binary files /dev/null and b/apps/frontend/src-tauri/icons/icon.icns differ
diff --git a/apps/frontend/src-tauri/icons/icon.ico b/apps/frontend/src-tauri/icons/icon.ico
new file mode 100644
index 0000000..e30cc8e
Binary files /dev/null and b/apps/frontend/src-tauri/icons/icon.ico differ
diff --git a/apps/frontend/src-tauri/icons/icon.png b/apps/frontend/src-tauri/icons/icon.png
new file mode 100644
index 0000000..38ac00d
Binary files /dev/null and b/apps/frontend/src-tauri/icons/icon.png differ
diff --git a/apps/frontend/src-tauri/icons/ios/AppIcon-20x20@1x.png b/apps/frontend/src-tauri/icons/ios/AppIcon-20x20@1x.png
new file mode 100644
index 0000000..aa597d2
Binary files /dev/null and b/apps/frontend/src-tauri/icons/ios/AppIcon-20x20@1x.png differ
diff --git a/apps/frontend/src-tauri/icons/ios/AppIcon-20x20@2x-1.png b/apps/frontend/src-tauri/icons/ios/AppIcon-20x20@2x-1.png
new file mode 100644
index 0000000..7471fe8
Binary files /dev/null and b/apps/frontend/src-tauri/icons/ios/AppIcon-20x20@2x-1.png differ
diff --git a/apps/frontend/src-tauri/icons/ios/AppIcon-20x20@2x.png b/apps/frontend/src-tauri/icons/ios/AppIcon-20x20@2x.png
new file mode 100644
index 0000000..7471fe8
Binary files /dev/null and b/apps/frontend/src-tauri/icons/ios/AppIcon-20x20@2x.png differ
diff --git a/apps/frontend/src-tauri/icons/ios/AppIcon-20x20@3x.png b/apps/frontend/src-tauri/icons/ios/AppIcon-20x20@3x.png
new file mode 100644
index 0000000..77822c2
Binary files /dev/null and b/apps/frontend/src-tauri/icons/ios/AppIcon-20x20@3x.png differ
diff --git a/apps/frontend/src-tauri/icons/ios/AppIcon-29x29@1x.png b/apps/frontend/src-tauri/icons/ios/AppIcon-29x29@1x.png
new file mode 100644
index 0000000..ae51c15
Binary files /dev/null and b/apps/frontend/src-tauri/icons/ios/AppIcon-29x29@1x.png differ
diff --git a/apps/frontend/src-tauri/icons/ios/AppIcon-29x29@2x-1.png b/apps/frontend/src-tauri/icons/ios/AppIcon-29x29@2x-1.png
new file mode 100644
index 0000000..8c3d4c8
Binary files /dev/null and b/apps/frontend/src-tauri/icons/ios/AppIcon-29x29@2x-1.png differ
diff --git a/apps/frontend/src-tauri/icons/ios/AppIcon-29x29@2x.png b/apps/frontend/src-tauri/icons/ios/AppIcon-29x29@2x.png
new file mode 100644
index 0000000..8c3d4c8
Binary files /dev/null and b/apps/frontend/src-tauri/icons/ios/AppIcon-29x29@2x.png differ
diff --git a/apps/frontend/src-tauri/icons/ios/AppIcon-29x29@3x.png b/apps/frontend/src-tauri/icons/ios/AppIcon-29x29@3x.png
new file mode 100644
index 0000000..19c3dd7
Binary files /dev/null and b/apps/frontend/src-tauri/icons/ios/AppIcon-29x29@3x.png differ
diff --git a/apps/frontend/src-tauri/icons/ios/AppIcon-40x40@1x.png b/apps/frontend/src-tauri/icons/ios/AppIcon-40x40@1x.png
new file mode 100644
index 0000000..7471fe8
Binary files /dev/null and b/apps/frontend/src-tauri/icons/ios/AppIcon-40x40@1x.png differ
diff --git a/apps/frontend/src-tauri/icons/ios/AppIcon-40x40@2x-1.png b/apps/frontend/src-tauri/icons/ios/AppIcon-40x40@2x-1.png
new file mode 100644
index 0000000..019101a
Binary files /dev/null and b/apps/frontend/src-tauri/icons/ios/AppIcon-40x40@2x-1.png differ
diff --git a/apps/frontend/src-tauri/icons/ios/AppIcon-40x40@2x.png b/apps/frontend/src-tauri/icons/ios/AppIcon-40x40@2x.png
new file mode 100644
index 0000000..019101a
Binary files /dev/null and b/apps/frontend/src-tauri/icons/ios/AppIcon-40x40@2x.png differ
diff --git a/apps/frontend/src-tauri/icons/ios/AppIcon-40x40@3x.png b/apps/frontend/src-tauri/icons/ios/AppIcon-40x40@3x.png
new file mode 100644
index 0000000..3e74ee7
Binary files /dev/null and b/apps/frontend/src-tauri/icons/ios/AppIcon-40x40@3x.png differ
diff --git a/apps/frontend/src-tauri/icons/ios/AppIcon-512@2x.png b/apps/frontend/src-tauri/icons/ios/AppIcon-512@2x.png
new file mode 100644
index 0000000..f43db73
Binary files /dev/null and b/apps/frontend/src-tauri/icons/ios/AppIcon-512@2x.png differ
diff --git a/apps/frontend/src-tauri/icons/ios/AppIcon-60x60@2x.png b/apps/frontend/src-tauri/icons/ios/AppIcon-60x60@2x.png
new file mode 100644
index 0000000..3e74ee7
Binary files /dev/null and b/apps/frontend/src-tauri/icons/ios/AppIcon-60x60@2x.png differ
diff --git a/apps/frontend/src-tauri/icons/ios/AppIcon-60x60@3x.png b/apps/frontend/src-tauri/icons/ios/AppIcon-60x60@3x.png
new file mode 100644
index 0000000..2b3351e
Binary files /dev/null and b/apps/frontend/src-tauri/icons/ios/AppIcon-60x60@3x.png differ
diff --git a/apps/frontend/src-tauri/icons/ios/AppIcon-76x76@1x.png b/apps/frontend/src-tauri/icons/ios/AppIcon-76x76@1x.png
new file mode 100644
index 0000000..6926f2e
Binary files /dev/null and b/apps/frontend/src-tauri/icons/ios/AppIcon-76x76@1x.png differ
diff --git a/apps/frontend/src-tauri/icons/ios/AppIcon-76x76@2x.png b/apps/frontend/src-tauri/icons/ios/AppIcon-76x76@2x.png
new file mode 100644
index 0000000..88956f3
Binary files /dev/null and b/apps/frontend/src-tauri/icons/ios/AppIcon-76x76@2x.png differ
diff --git a/apps/frontend/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png b/apps/frontend/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png
new file mode 100644
index 0000000..eb9166a
Binary files /dev/null and b/apps/frontend/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png differ
diff --git a/apps/frontend/src-tauri/src/lib.rs b/apps/frontend/src-tauri/src/lib.rs
new file mode 100644
index 0000000..de33c66
--- /dev/null
+++ b/apps/frontend/src-tauri/src/lib.rs
@@ -0,0 +1,7 @@
+#[cfg_attr(mobile, tauri::mobile_entry_point)]
+pub fn run() {
+ tauri::Builder::default()
+ .plugin(tauri_plugin_store::Builder::new().build())
+ .run(tauri::generate_context!())
+ .expect("error while running tauri application");
+}
diff --git a/apps/frontend/src-tauri/src/main.rs b/apps/frontend/src-tauri/src/main.rs
new file mode 100644
index 0000000..b6a1e01
--- /dev/null
+++ b/apps/frontend/src-tauri/src/main.rs
@@ -0,0 +1,6 @@
+// Prevents additional console window on Windows in release
+#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
+
+fn main() {
+ ti_pote_desktop_lib::run()
+}
diff --git a/apps/frontend/src-tauri/tauri.conf.json b/apps/frontend/src-tauri/tauri.conf.json
new file mode 100644
index 0000000..db4d753
--- /dev/null
+++ b/apps/frontend/src-tauri/tauri.conf.json
@@ -0,0 +1,40 @@
+{
+ "$schema": "https://schema.tauri.app/config/2",
+ "productName": "Ti-Pote",
+ "version": "0.0.1",
+ "identifier": "com.tipote.desktop",
+ "build": {
+ "beforeDevCommand": "pnpm dev",
+ "devUrl": "http://localhost:1420",
+ "beforeBuildCommand": "pnpm build",
+ "frontendDist": "../dist"
+ },
+ "app": {
+ "windows": [
+ {
+ "title": "Ti-Pote",
+ "width": 1100,
+ "height": 760,
+ "minWidth": 900,
+ "minHeight": 600,
+ "resizable": true,
+ "fullscreen": false
+ }
+ ],
+ "security": {
+ "csp": null
+ }
+ },
+ "bundle": {
+ "active": true,
+ "targets": "all",
+ "icon": [
+ "icons/32x32.png",
+ "icons/128x128.png",
+ "icons/128x128@2x.png",
+ "icons/icon.icns",
+ "icons/icon.ico"
+ ]
+ },
+ "plugins": {}
+}
diff --git a/apps/frontend/src/App.tsx b/apps/frontend/src/App.tsx
new file mode 100644
index 0000000..7737f29
--- /dev/null
+++ b/apps/frontend/src/App.tsx
@@ -0,0 +1,52 @@
+import { Navigate, Route, Routes } from 'react-router-dom';
+import { ProtectedRoute } from './components/ProtectedRoute';
+import { useAuth } from './context/AuthContext';
+import { DashboardPage } from './pages/DashboardPage';
+import { LoginPage } from './pages/LoginPage';
+import { PairRobotPage } from './pages/PairRobotPage';
+import { RegisterPage } from './pages/RegisterPage';
+
+/**
+ * Router.
+ *
+ * - Public routes (login/register) auto-redirect to "/" when the user
+ * is already authenticated — avoids the annoying loop where a logged-in
+ * user clicks back and lands on a login form.
+ * - Protected routes are gated by .
+ */
+export function App() {
+ const { status } = useAuth();
+ const authed = status === 'authenticated';
+
+ return (
+
+ : }
+ />
+ : }
+ />
+
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+
+ } />
+
+ );
+}
diff --git a/apps/frontend/src/components/ProtectedRoute.tsx b/apps/frontend/src/components/ProtectedRoute.tsx
new file mode 100644
index 0000000..90bf2d0
--- /dev/null
+++ b/apps/frontend/src/components/ProtectedRoute.tsx
@@ -0,0 +1,31 @@
+import type { ReactNode } from 'react';
+import { Navigate, useLocation } from 'react-router-dom';
+import { useAuth } from '../context/AuthContext';
+
+/**
+ * Gate a subtree behind an authenticated user.
+ *
+ * - While the auth state is still bootstrapping (refreshing the session
+ * from storage), render a neutral splash.
+ * - If the user is unauthenticated, redirect to /login while keeping
+ * the original destination in location state so we can bounce back
+ * after login.
+ */
+export function ProtectedRoute({ children }: { children: ReactNode }) {
+ const { status } = useAuth();
+ const location = useLocation();
+
+ if (status === 'loading') {
+ return (
+
+ );
+ }
+
+ if (status === 'unauthenticated') {
+ return ;
+ }
+
+ return <>{children}>;
+}
diff --git a/apps/frontend/src/components/ui.tsx b/apps/frontend/src/components/ui.tsx
new file mode 100644
index 0000000..2ec1868
--- /dev/null
+++ b/apps/frontend/src/components/ui.tsx
@@ -0,0 +1,148 @@
+import type { ButtonHTMLAttributes, InputHTMLAttributes, ReactNode } from 'react';
+
+// ─── Button ─────────────────────────────────────────────────────────
+
+type Variant = 'primary' | 'secondary' | 'ghost' | 'danger';
+
+interface ButtonProps extends ButtonHTMLAttributes {
+ variant?: Variant;
+ loading?: boolean;
+}
+
+const VARIANT_CLASSES: Record = {
+ primary:
+ 'bg-brand-500 hover:bg-brand-400 active:bg-brand-600 text-white shadow-lg shadow-brand-500/30',
+ secondary: 'bg-slate-800 hover:bg-slate-700 text-slate-100 border border-slate-700',
+ ghost: 'bg-transparent hover:bg-slate-800/60 text-slate-300',
+ danger: 'bg-red-600 hover:bg-red-500 text-white',
+};
+
+export function Button({
+ variant = 'primary',
+ loading = false,
+ disabled,
+ className = '',
+ children,
+ ...rest
+}: ButtonProps) {
+ return (
+
+ {loading && (
+
+
+
+
+ )}
+ {children}
+
+ );
+}
+
+// ─── Input ──────────────────────────────────────────────────────────
+
+interface InputProps extends InputHTMLAttributes {
+ label?: string;
+ error?: string | null;
+}
+
+export function Input({ label, error, className = '', id, ...rest }: InputProps) {
+ const inputId = id || rest.name;
+ return (
+
+ {label && (
+
+ {label}
+
+ )}
+
+ {error &&
{error}
}
+
+ );
+}
+
+// ─── Card ───────────────────────────────────────────────────────────
+
+export function Card({
+ children,
+ className = '',
+}: {
+ children: ReactNode;
+ className?: string;
+}) {
+ return (
+
+ {children}
+
+ );
+}
+
+// ─── StatusBadge ───────────────────────────────────────────────────
+
+export function StatusBadge({ status }: { status: 'online' | 'offline' | 'updating' }) {
+ const styles = {
+ online: 'bg-emerald-500/10 text-emerald-400 border-emerald-500/30',
+ offline: 'bg-slate-500/10 text-slate-400 border-slate-500/30',
+ updating: 'bg-amber-500/10 text-amber-400 border-amber-500/30',
+ }[status];
+
+ const dot = {
+ online: 'bg-emerald-400 shadow-emerald-400/60',
+ offline: 'bg-slate-500',
+ updating: 'bg-amber-400 shadow-amber-400/60 animate-pulse',
+ }[status];
+
+ return (
+
+
+ {status}
+
+ );
+}
diff --git a/apps/frontend/src/context/AuthContext.tsx b/apps/frontend/src/context/AuthContext.tsx
new file mode 100644
index 0000000..6874673
--- /dev/null
+++ b/apps/frontend/src/context/AuthContext.tsx
@@ -0,0 +1,98 @@
+import {
+ createContext,
+ useCallback,
+ useContext,
+ useEffect,
+ useMemo,
+ useState,
+ type ReactNode,
+} from 'react';
+import {
+ api,
+ hasStoredSession,
+ type LoginInput,
+ type Me,
+ type RegisterInput,
+} from '../lib/api';
+
+type AuthStatus = 'loading' | 'authenticated' | 'unauthenticated';
+
+interface AuthContextValue {
+ status: AuthStatus;
+ user: Me | null;
+ login: (input: LoginInput) => Promise;
+ register: (input: RegisterInput) => Promise;
+ logout: () => Promise;
+ refreshMe: () => Promise;
+}
+
+const AuthContext = createContext(null);
+
+export function AuthProvider({ children }: { children: ReactNode }) {
+ const [status, setStatus] = useState('loading');
+ const [user, setUser] = useState(null);
+
+ // Bootstrap: if we have a refresh token on disk, try /auth/me
+ useEffect(() => {
+ let cancelled = false;
+
+ (async () => {
+ if (!(await hasStoredSession())) {
+ if (!cancelled) setStatus('unauthenticated');
+ return;
+ }
+ try {
+ const me = await api.me();
+ if (cancelled) return;
+ setUser(me);
+ setStatus('authenticated');
+ } catch {
+ if (cancelled) return;
+ setUser(null);
+ setStatus('unauthenticated');
+ }
+ })();
+
+ return () => {
+ cancelled = true;
+ };
+ }, []);
+
+ const login = useCallback(async (input: LoginInput) => {
+ await api.login(input);
+ const me = await api.me();
+ setUser(me);
+ setStatus('authenticated');
+ }, []);
+
+ const register = useCallback(async (input: RegisterInput) => {
+ await api.register(input);
+ const me = await api.me();
+ setUser(me);
+ setStatus('authenticated');
+ }, []);
+
+ const logout = useCallback(async () => {
+ await api.logout();
+ setUser(null);
+ setStatus('unauthenticated');
+ }, []);
+
+ const refreshMe = useCallback(async () => {
+ const me = await api.me();
+ setUser(me);
+ }, []);
+
+ const value = useMemo(
+ () => ({ status, user, login, register, logout, refreshMe }),
+ [status, user, login, register, logout, refreshMe],
+ );
+
+ return {children} ;
+}
+
+export function useAuth(): AuthContextValue {
+ const ctx = useContext(AuthContext);
+ if (!ctx) throw new Error('useAuth must be used inside ');
+ return ctx;
+}
diff --git a/apps/frontend/src/lib/api.ts b/apps/frontend/src/lib/api.ts
new file mode 100644
index 0000000..d6d893d
--- /dev/null
+++ b/apps/frontend/src/lib/api.ts
@@ -0,0 +1,233 @@
+/**
+ * Thin typed wrapper around fetch with:
+ * - base URL from VITE_API_URL (default http://localhost:3000)
+ * - automatic `Authorization: Bearer ` injection
+ * - transparent refresh-token rotation on 401
+ * - typed error class
+ *
+ * Token persistence is delegated to `lib/storage.ts` (Tauri store in
+ * desktop builds, localStorage in pure browser dev).
+ */
+
+import { storage } from './storage';
+
+const BASE_URL =
+ (import.meta.env.VITE_API_URL as string | undefined)?.replace(/\/$/, '') ||
+ 'http://localhost:3000';
+
+const API_PREFIX = '/api';
+
+const ACCESS_KEY = 'auth.accessToken';
+const REFRESH_KEY = 'auth.refreshToken';
+
+// ─── Types ──────────────────────────────────────────────────────────
+
+export interface Tokens {
+ accessToken: string;
+ refreshToken: string;
+}
+
+export interface Me {
+ id: string;
+ email: string;
+ homeId: string;
+ type: 'user';
+}
+
+export interface RegisterInput {
+ email: string;
+ password: string;
+ displayName: string;
+ homeName: string;
+}
+
+export interface LoginInput {
+ email: string;
+ password: string;
+}
+
+export interface DeviceSummary {
+ id: string;
+ homeId: string;
+ name: string;
+ status: 'online' | 'offline' | 'updating';
+ firmwareVersion: string | null;
+ lastSeenAt: string | null;
+ createdAt: string;
+ updatedAt: string;
+}
+
+export interface PairingConfirmResult {
+ deviceId: string;
+ deviceName: string;
+}
+
+// ─── Error ──────────────────────────────────────────────────────────
+
+export class ApiError extends Error {
+ constructor(
+ public readonly status: number,
+ message: string,
+ public readonly body?: unknown,
+ ) {
+ super(message);
+ this.name = 'ApiError';
+ }
+}
+
+// ─── Token helpers ──────────────────────────────────────────────────
+
+async function getAccessToken(): Promise {
+ return storage.get(ACCESS_KEY);
+}
+
+async function getRefreshToken(): Promise {
+ return storage.get(REFRESH_KEY);
+}
+
+export async function saveTokens(tokens: Tokens): Promise {
+ await storage.set(ACCESS_KEY, tokens.accessToken);
+ await storage.set(REFRESH_KEY, tokens.refreshToken);
+}
+
+export async function clearTokens(): Promise {
+ await storage.delete(ACCESS_KEY);
+ await storage.delete(REFRESH_KEY);
+}
+
+export async function hasStoredSession(): Promise {
+ const [a, r] = await Promise.all([getAccessToken(), getRefreshToken()]);
+ return Boolean(a && r);
+}
+
+// ─── Core fetch with refresh-on-401 ─────────────────────────────────
+
+interface RequestOptions {
+ method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
+ body?: unknown;
+ auth?: boolean; // default true
+ // Internal: prevents infinite refresh loops
+ _retried?: boolean;
+}
+
+async function request(path: string, opts: RequestOptions = {}): Promise {
+ const { method = 'GET', body, auth = true, _retried = false } = opts;
+
+ const headers: Record = {
+ 'Content-Type': 'application/json',
+ Accept: 'application/json',
+ };
+
+ if (auth) {
+ const token = await getAccessToken();
+ if (token) headers.Authorization = `Bearer ${token}`;
+ }
+
+ const res = await fetch(`${BASE_URL}${API_PREFIX}${path}`, {
+ method,
+ headers,
+ body: body !== undefined ? JSON.stringify(body) : undefined,
+ });
+
+ // Attempt transparent refresh on 401 (once)
+ if (res.status === 401 && auth && !_retried) {
+ const refreshed = await tryRefresh();
+ if (refreshed) {
+ return request(path, { ...opts, _retried: true });
+ }
+ await clearTokens();
+ }
+
+ const isJson = res.headers.get('content-type')?.includes('application/json');
+ const payload: unknown = isJson ? await res.json().catch(() => null) : null;
+
+ if (!res.ok) {
+ const message =
+ (payload &&
+ typeof payload === 'object' &&
+ 'message' in payload &&
+ String((payload as { message: unknown }).message)) ||
+ res.statusText ||
+ `HTTP ${res.status}`;
+ throw new ApiError(res.status, message, payload);
+ }
+
+ return payload as T;
+}
+
+let refreshInFlight: Promise | null = null;
+
+async function tryRefresh(): Promise {
+ if (refreshInFlight) return refreshInFlight;
+
+ refreshInFlight = (async () => {
+ const refreshToken = await getRefreshToken();
+ if (!refreshToken) return false;
+ try {
+ const res = await fetch(`${BASE_URL}${API_PREFIX}/auth/refresh`, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ refreshToken }),
+ });
+ if (!res.ok) return false;
+ const tokens = (await res.json()) as Tokens;
+ await saveTokens(tokens);
+ return true;
+ } catch {
+ return false;
+ } finally {
+ // Release slot after microtask so concurrent callers can await
+ setTimeout(() => {
+ refreshInFlight = null;
+ }, 0);
+ }
+ })();
+
+ return refreshInFlight;
+}
+
+// ─── Typed endpoint wrappers ────────────────────────────────────────
+
+export const api = {
+ // Auth
+ async register(input: RegisterInput): Promise {
+ const tokens = await request('/auth/register', {
+ method: 'POST',
+ body: input,
+ auth: false,
+ });
+ await saveTokens(tokens);
+ return tokens;
+ },
+
+ async login(input: LoginInput): Promise {
+ const tokens = await request('/auth/login', {
+ method: 'POST',
+ body: input,
+ auth: false,
+ });
+ await saveTokens(tokens);
+ return tokens;
+ },
+
+ async me(): Promise {
+ return request('/auth/me');
+ },
+
+ async logout(): Promise {
+ await clearTokens();
+ },
+
+ // Devices
+ async listDevices(): Promise {
+ return request('/devices');
+ },
+
+ // Pairing
+ async confirmPairing(code: string): Promise {
+ return request('/pairing/confirm', {
+ method: 'POST',
+ body: { code },
+ });
+ },
+};
diff --git a/apps/frontend/src/lib/storage.ts b/apps/frontend/src/lib/storage.ts
new file mode 100644
index 0000000..d6ab005
--- /dev/null
+++ b/apps/frontend/src/lib/storage.ts
@@ -0,0 +1,100 @@
+/**
+ * Persistent key-value storage.
+ *
+ * In a Tauri desktop build we prefer the `@tauri-apps/plugin-store` plugin
+ * (encrypted, per-app location). In a plain browser dev build we fall back
+ * to `localStorage`. The same async API is exposed in both cases so callers
+ * never care which backend they are talking to.
+ */
+
+type StorageBackend = {
+ get(key: string): Promise;
+ set(key: string, value: unknown): Promise;
+ delete(key: string): Promise;
+ clear(): Promise;
+};
+
+let backendPromise: Promise | null = null;
+
+function isTauri(): boolean {
+ return (
+ typeof window !== 'undefined' &&
+ // Tauri v2 sets these globals on window at runtime
+ ('__TAURI_INTERNALS__' in window || '__TAURI__' in window)
+ );
+}
+
+async function createBackend(): Promise {
+ if (isTauri()) {
+ try {
+ const { Store } = await import('@tauri-apps/plugin-store');
+ const store = await Store.load('ti-pote.json');
+ return {
+ async get(key: string) {
+ const value = await store.get(key);
+ return value ?? null;
+ },
+ async set(key, value) {
+ await store.set(key, value);
+ await store.save();
+ },
+ async delete(key) {
+ await store.delete(key);
+ await store.save();
+ },
+ async clear() {
+ await store.clear();
+ await store.save();
+ },
+ };
+ } catch (err) {
+ console.warn('[storage] Tauri store unavailable, falling back to localStorage', err);
+ }
+ }
+
+ // Browser fallback
+ return {
+ async get(key: string) {
+ const raw = localStorage.getItem(key);
+ if (raw == null) return null;
+ try {
+ return JSON.parse(raw) as T;
+ } catch {
+ return null;
+ }
+ },
+ async set(key, value) {
+ localStorage.setItem(key, JSON.stringify(value));
+ },
+ async delete(key) {
+ localStorage.removeItem(key);
+ },
+ async clear() {
+ localStorage.clear();
+ },
+ };
+}
+
+function getBackend(): Promise {
+ if (!backendPromise) backendPromise = createBackend();
+ return backendPromise;
+}
+
+export const storage = {
+ async get(key: string): Promise {
+ const b = await getBackend();
+ return b.get(key);
+ },
+ async set(key: string, value: unknown): Promise {
+ const b = await getBackend();
+ return b.set(key, value);
+ },
+ async delete(key: string): Promise {
+ const b = await getBackend();
+ return b.delete(key);
+ },
+ async clear(): Promise {
+ const b = await getBackend();
+ return b.clear();
+ },
+};
diff --git a/apps/frontend/src/main.tsx b/apps/frontend/src/main.tsx
new file mode 100644
index 0000000..3359db9
--- /dev/null
+++ b/apps/frontend/src/main.tsx
@@ -0,0 +1,16 @@
+import React from 'react';
+import ReactDOM from 'react-dom/client';
+import { BrowserRouter } from 'react-router-dom';
+import { App } from './App';
+import { AuthProvider } from './context/AuthContext';
+import './styles/index.css';
+
+ReactDOM.createRoot(document.getElementById('root')!).render(
+
+
+
+
+
+
+ ,
+);
diff --git a/apps/frontend/src/pages/DashboardPage.tsx b/apps/frontend/src/pages/DashboardPage.tsx
new file mode 100644
index 0000000..67acaf8
--- /dev/null
+++ b/apps/frontend/src/pages/DashboardPage.tsx
@@ -0,0 +1,118 @@
+import { useEffect, useState } from 'react';
+import { Link } from 'react-router-dom';
+import { Button, Card, StatusBadge } from '../components/ui';
+import { useAuth } from '../context/AuthContext';
+import { api, ApiError, type DeviceSummary } from '../lib/api';
+
+export function DashboardPage() {
+ const { user, logout } = useAuth();
+ const [devices, setDevices] = useState(null);
+ const [error, setError] = useState(null);
+ const [loading, setLoading] = useState(true);
+
+ async function fetchDevices() {
+ setLoading(true);
+ setError(null);
+ try {
+ const list = await api.listDevices();
+ setDevices(list);
+ } catch (err) {
+ setError(err instanceof ApiError ? err.message : 'Erreur réseau');
+ setDevices([]);
+ } finally {
+ setLoading(false);
+ }
+ }
+
+ useEffect(() => {
+ void fetchDevices();
+ }, []);
+
+ return (
+
+ {/* ─ Header ─ */}
+
+
+
Tableau de bord
+
+ Bonjour{user ? `, ${user.email.split('@')[0]}` : ''} 👋
+
+
+ void logout()}>
+ Déconnexion
+
+
+
+ {/* ─ Actions ─ */}
+
+
Tes robots
+
+ void fetchDevices()}>
+ Rafraîchir
+
+
+ + Associer un robot
+
+
+
+
+ {/* ─ Device list ─ */}
+ {loading && (
+
Chargement…
+ )}
+
+ {!loading && error && (
+
+ {error}
+
+ )}
+
+ {!loading && !error && devices && devices.length === 0 && (
+
+
+ 🤖
+
+
+
Aucun robot associé
+
+ Allume ton Ti-Pote puis associe-le avec le code qui s'affichera.
+
+
+
+ Associer un robot
+
+
+ )}
+
+ {!loading && !error && devices && devices.length > 0 && (
+
+ {devices.map((d) => (
+
+
+
+
{d.name}
+
+ {d.id}
+
+
+
+
+
+
+
Firmware :
+ {d.firmwareVersion || '—'}
+
+
+
Vu pour la dernière fois :
+
+ {d.lastSeenAt ? new Date(d.lastSeenAt).toLocaleString() : 'jamais'}
+
+
+
+
+ ))}
+
+ )}
+
+ );
+}
diff --git a/apps/frontend/src/pages/LoginPage.tsx b/apps/frontend/src/pages/LoginPage.tsx
new file mode 100644
index 0000000..850439f
--- /dev/null
+++ b/apps/frontend/src/pages/LoginPage.tsx
@@ -0,0 +1,97 @@
+import { useState, type FormEvent } from 'react';
+import { Link, useLocation, useNavigate } from 'react-router-dom';
+import { Button, Card, Input } from '../components/ui';
+import { useAuth } from '../context/AuthContext';
+import { ApiError } from '../lib/api';
+
+interface LocationState {
+ from?: { pathname: string };
+}
+
+export function LoginPage() {
+ const { login } = useAuth();
+ const navigate = useNavigate();
+ const location = useLocation();
+ const from = (location.state as LocationState | null)?.from?.pathname || '/';
+
+ const [email, setEmail] = useState('');
+ const [password, setPassword] = useState('');
+ const [submitting, setSubmitting] = useState(false);
+ const [error, setError] = useState(null);
+
+ async function onSubmit(e: FormEvent) {
+ e.preventDefault();
+ setError(null);
+ setSubmitting(true);
+ try {
+ await login({ email, password });
+ navigate(from, { replace: true });
+ } catch (err) {
+ if (err instanceof ApiError) {
+ setError(
+ err.status === 401
+ ? 'Email ou mot de passe incorrect.'
+ : err.message || 'Erreur de connexion.',
+ );
+ } else {
+ setError('Impossible de joindre le serveur.');
+ }
+ } finally {
+ setSubmitting(false);
+ }
+ }
+
+ return (
+
+
+
+
+
+
+
+ Pas encore de compte ?{' '}
+
+ Créer un compte
+
+
+
+
+ );
+}
diff --git a/apps/frontend/src/pages/PairRobotPage.tsx b/apps/frontend/src/pages/PairRobotPage.tsx
new file mode 100644
index 0000000..a801cd3
--- /dev/null
+++ b/apps/frontend/src/pages/PairRobotPage.tsx
@@ -0,0 +1,193 @@
+import { useMemo, useRef, useState, type ClipboardEvent, type KeyboardEvent } from 'react';
+import { Link, useNavigate } from 'react-router-dom';
+import { Button, Card } from '../components/ui';
+import { api, ApiError } from '../lib/api';
+
+const CODE_LENGTH = 6;
+
+/**
+ * Pairing flow (user side).
+ *
+ * The robot-client calls POST /pairing/request on first boot, displays a
+ * 6-digit code, and polls GET /pairing/status/:requestId until it sees a
+ * `confirmed` response.
+ *
+ * Here we just collect the 6 digits from the user and POST them to
+ * /pairing/confirm — the backend then flips the pairing request to
+ * confirmed and the robot picks up its device credentials on its next poll.
+ */
+export function PairRobotPage() {
+ const navigate = useNavigate();
+ const [digits, setDigits] = useState(() =>
+ Array.from({ length: CODE_LENGTH }, () => ''),
+ );
+ const [submitting, setSubmitting] = useState(false);
+ const [error, setError] = useState(null);
+ const [success, setSuccess] = useState<{ deviceId: string; deviceName: string } | null>(
+ null,
+ );
+ const inputsRef = useRef<(HTMLInputElement | null)[]>([]);
+
+ const code = useMemo(() => digits.join(''), [digits]);
+ const isComplete = code.length === CODE_LENGTH && digits.every((d) => /\d/.test(d));
+
+ function setDigitAt(index: number, value: string) {
+ const cleaned = value.replace(/\D/g, '').slice(0, 1);
+ setDigits((prev) => {
+ const next = [...prev];
+ next[index] = cleaned;
+ return next;
+ });
+ if (cleaned && index < CODE_LENGTH - 1) {
+ inputsRef.current[index + 1]?.focus();
+ }
+ }
+
+ function onKeyDown(index: number, e: KeyboardEvent) {
+ if (e.key === 'Backspace' && !digits[index] && index > 0) {
+ inputsRef.current[index - 1]?.focus();
+ } else if (e.key === 'ArrowLeft' && index > 0) {
+ inputsRef.current[index - 1]?.focus();
+ } else if (e.key === 'ArrowRight' && index < CODE_LENGTH - 1) {
+ inputsRef.current[index + 1]?.focus();
+ } else if (e.key === 'Enter' && isComplete) {
+ void submit();
+ }
+ }
+
+ function onPaste(e: ClipboardEvent) {
+ const pasted = e.clipboardData.getData('text').replace(/\D/g, '').slice(0, CODE_LENGTH);
+ if (!pasted) return;
+ e.preventDefault();
+ const next = Array.from({ length: CODE_LENGTH }, (_, i) => pasted[i] ?? '');
+ setDigits(next);
+ const lastFilled = Math.min(pasted.length, CODE_LENGTH) - 1;
+ inputsRef.current[lastFilled < 0 ? 0 : lastFilled]?.focus();
+ }
+
+ async function submit() {
+ setError(null);
+ setSubmitting(true);
+ try {
+ const result = await api.confirmPairing(code);
+ setSuccess(result);
+ } catch (err) {
+ if (err instanceof ApiError) {
+ if (err.status === 400) {
+ setError('Code invalide ou expiré. Vérifie le code affiché sur le robot.');
+ } else {
+ setError(err.message || "Erreur lors de l'association.");
+ }
+ } else {
+ setError('Impossible de joindre le serveur.');
+ }
+ } finally {
+ setSubmitting(false);
+ }
+ }
+
+ // ─── Success screen ─────────────────────────────────────────────
+ if (success) {
+ return (
+
+
+
+ ✅
+
+ Robot associé !
+
+ {success.deviceName} fait
+ maintenant partie de ton foyer.
+
+ {success.deviceId}
+
+
+ {
+ setSuccess(null);
+ setDigits(Array.from({ length: CODE_LENGTH }, () => ''));
+ inputsRef.current[0]?.focus();
+ }}
+ >
+ Associer un autre
+
+ navigate('/')}>
+ Terminer
+
+
+
+
+ );
+ }
+
+ // ─── Input screen ───────────────────────────────────────────────
+ return (
+
+
+
+
+
+
+
+
+ ← Retour au tableau de bord
+
+
+
+
+
💡 Comment obtenir le code ?
+
+ Allume ton Ti-Pote. Lors du premier démarrage, il annonce vocalement un code à
+ 6 chiffres et l'affiche (écran / LED / logs). Ce code n'est valable que 10 minutes.
+
+
+
+
+ );
+}
diff --git a/apps/frontend/src/pages/RegisterPage.tsx b/apps/frontend/src/pages/RegisterPage.tsx
new file mode 100644
index 0000000..b8d0d73
--- /dev/null
+++ b/apps/frontend/src/pages/RegisterPage.tsx
@@ -0,0 +1,119 @@
+import { useState, type FormEvent } from 'react';
+import { Link, useNavigate } from 'react-router-dom';
+import { Button, Card, Input } from '../components/ui';
+import { useAuth } from '../context/AuthContext';
+import { ApiError } from '../lib/api';
+
+export function RegisterPage() {
+ const { register } = useAuth();
+ const navigate = useNavigate();
+
+ const [displayName, setDisplayName] = useState('');
+ const [homeName, setHomeName] = useState('');
+ const [email, setEmail] = useState('');
+ const [password, setPassword] = useState('');
+ const [submitting, setSubmitting] = useState(false);
+ const [error, setError] = useState(null);
+
+ async function onSubmit(e: FormEvent) {
+ e.preventDefault();
+ setError(null);
+
+ if (password.length < 8) {
+ setError('Le mot de passe doit faire au moins 8 caractères.');
+ return;
+ }
+
+ setSubmitting(true);
+ try {
+ await register({ email, password, displayName, homeName });
+ navigate('/', { replace: true });
+ } catch (err) {
+ if (err instanceof ApiError) {
+ setError(
+ err.status === 409
+ ? 'Cette adresse email est déjà utilisée.'
+ : err.message || "Erreur lors de l'inscription.",
+ );
+ } else {
+ setError('Impossible de joindre le serveur.');
+ }
+ } finally {
+ setSubmitting(false);
+ }
+ }
+
+ return (
+
+
+
+
+
+
+
+ Déjà un compte ?{' '}
+
+ Se connecter
+
+
+
+
+ );
+}
diff --git a/apps/frontend/src/styles/index.css b/apps/frontend/src/styles/index.css
new file mode 100644
index 0000000..b91dc9c
--- /dev/null
+++ b/apps/frontend/src/styles/index.css
@@ -0,0 +1,15 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+@layer base {
+ html,
+ body,
+ #root {
+ height: 100%;
+ }
+
+ body {
+ @apply bg-gradient-to-br from-slate-950 via-slate-900 to-slate-950 text-slate-100;
+ }
+}
diff --git a/apps/frontend/tailwind.config.js b/apps/frontend/tailwind.config.js
new file mode 100644
index 0000000..a90d558
--- /dev/null
+++ b/apps/frontend/tailwind.config.js
@@ -0,0 +1,33 @@
+/** @type {import('tailwindcss').Config} */
+export default {
+ content: ['./index.html', './src/**/*.{ts,tsx}'],
+ theme: {
+ extend: {
+ colors: {
+ brand: {
+ 50: '#f0f9ff',
+ 100: '#e0f2fe',
+ 200: '#bae6fd',
+ 300: '#7dd3fc',
+ 400: '#38bdf8',
+ 500: '#0ea5e9',
+ 600: '#0284c7',
+ 700: '#0369a1',
+ 800: '#075985',
+ 900: '#0c4a6e',
+ },
+ },
+ fontFamily: {
+ sans: [
+ 'Inter',
+ '-apple-system',
+ 'system-ui',
+ 'Segoe UI',
+ 'Roboto',
+ 'sans-serif',
+ ],
+ },
+ },
+ },
+ plugins: [],
+};
diff --git a/apps/frontend/tsconfig.json b/apps/frontend/tsconfig.json
new file mode 100644
index 0000000..3b7d21c
--- /dev/null
+++ b/apps/frontend/tsconfig.json
@@ -0,0 +1,26 @@
+{
+ "compilerOptions": {
+ "target": "ES2022",
+ "useDefineForClassFields": true,
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "moduleDetection": "force",
+ "noEmit": true,
+ "jsx": "react-jsx",
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true,
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["src/*"]
+ }
+ },
+ "include": ["src"],
+ "references": [{ "path": "./tsconfig.node.json" }]
+}
diff --git a/apps/frontend/tsconfig.node.json b/apps/frontend/tsconfig.node.json
new file mode 100644
index 0000000..97ede7e
--- /dev/null
+++ b/apps/frontend/tsconfig.node.json
@@ -0,0 +1,11 @@
+{
+ "compilerOptions": {
+ "composite": true,
+ "skipLibCheck": true,
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "allowSyntheticDefaultImports": true,
+ "strict": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/apps/frontend/vite.config.ts b/apps/frontend/vite.config.ts
new file mode 100644
index 0000000..14549a5
--- /dev/null
+++ b/apps/frontend/vite.config.ts
@@ -0,0 +1,32 @@
+import { defineConfig } from 'vite';
+import react from '@vitejs/plugin-react';
+import path from 'node:path';
+
+// @ts-expect-error process is provided by Node at config time
+const host = process.env.TAURI_DEV_HOST;
+
+export default defineConfig({
+ plugins: [react()],
+ resolve: {
+ alias: {
+ '@': path.resolve(__dirname, './src'),
+ },
+ },
+ // Tauri expects a fixed port and silences console noise
+ clearScreen: false,
+ server: {
+ port: 1420,
+ strictPort: true,
+ host: host || false,
+ hmr: host
+ ? {
+ protocol: 'ws',
+ host,
+ port: 1421,
+ }
+ : undefined,
+ watch: {
+ ignored: ['**/src-tauri/**'],
+ },
+ },
+});
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 957e317..20fa950 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -115,19 +115,19 @@ importers:
version: 4.0.1
'@typescript-eslint/eslint-plugin':
specifier: ^8.57.2
- version: 8.57.2(@typescript-eslint/parser@8.57.2(eslint@10.1.0)(typescript@5.8.3))(eslint@10.1.0)(typescript@5.8.3)
+ version: 8.57.2(@typescript-eslint/parser@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.8.3))(eslint@10.1.0(jiti@1.21.7))(typescript@5.8.3)
'@typescript-eslint/parser':
specifier: ^8.57.2
- version: 8.57.2(eslint@10.1.0)(typescript@5.8.3)
+ version: 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.8.3)
eslint:
specifier: ^10.1.0
- version: 10.1.0
+ version: 10.1.0(jiti@1.21.7)
eslint-config-prettier:
specifier: ^10.1.8
- version: 10.1.8(eslint@10.1.0)
+ version: 10.1.8(eslint@10.1.0(jiti@1.21.7))
eslint-plugin-prettier:
specifier: ^5.5.5
- version: 5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.1.0))(eslint@10.1.0)(prettier@3.8.1)
+ version: 5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.1.0(jiti@1.21.7)))(eslint@10.1.0(jiti@1.21.7))(prettier@3.8.1)
jest:
specifier: ^30.3.0
version: 30.3.0(@types/node@25.5.0)(ts-node@10.9.2(@types/node@25.5.0)(typescript@5.8.3))
@@ -150,18 +150,54 @@ importers:
specifier: ^5.8.3
version: 5.8.3
- apps/desktop:
+ apps/frontend:
dependencies:
'@tauri-apps/api':
- specifier: ^2
+ specifier: ^2.0.0
version: 2.10.1
+ '@tauri-apps/plugin-store':
+ specifier: ^2.0.0
+ version: 2.4.2
+ react:
+ specifier: ^18.3.1
+ version: 18.3.1
+ react-dom:
+ specifier: ^18.3.1
+ version: 18.3.1(react@18.3.1)
+ react-router-dom:
+ specifier: ^6.26.0
+ version: 6.30.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ zustand:
+ specifier: ^4.5.5
+ version: 4.5.7(@types/react@18.3.28)(react@18.3.1)
devDependencies:
'@tauri-apps/cli':
- specifier: ^2
+ specifier: ^2.0.0
version: 2.10.1
- serve:
- specifier: ^14
- version: 14.2.6
+ '@types/react':
+ specifier: ^18.3.3
+ version: 18.3.28
+ '@types/react-dom':
+ specifier: ^18.3.0
+ version: 18.3.7(@types/react@18.3.28)
+ '@vitejs/plugin-react':
+ specifier: ^4.3.1
+ version: 4.7.0(vite@5.4.21(@types/node@25.5.0)(lightningcss@1.32.0)(terser@5.46.1))
+ autoprefixer:
+ specifier: ^10.4.20
+ version: 10.4.27(postcss@8.5.8)
+ postcss:
+ specifier: ^8.4.41
+ version: 8.5.8
+ tailwindcss:
+ specifier: ^3.4.10
+ version: 3.4.19(tsx@4.21.0)
+ typescript:
+ specifier: ^5.5.4
+ version: 5.9.3
+ vite:
+ specifier: ^5.4.2
+ version: 5.4.21(@types/node@25.5.0)(lightningcss@1.32.0)(terser@5.46.1)
apps/robot-client:
dependencies:
@@ -186,13 +222,13 @@ importers:
version: 22.19.15
eslint:
specifier: ^10.1.0
- version: 10.1.0
+ version: 10.1.0(jiti@1.21.7)
prettier:
specifier: ^3.8.1
version: 3.8.1
tsup:
specifier: ^8.5.0
- version: 8.5.1(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3)
+ version: 8.5.1(jiti@1.21.7)(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3)
tsx:
specifier: ^4.21.0
version: 4.21.0
@@ -201,7 +237,7 @@ importers:
version: 5.9.3
vitest:
specifier: ^3.2.1
- version: 3.2.4(@types/node@22.19.15)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)
+ version: 3.2.4(@types/node@22.19.15)(lightningcss@1.32.0)(terser@5.46.1)
apps/simulator:
dependencies:
@@ -223,13 +259,13 @@ importers:
version: 19.2.3(@types/react@19.2.14)
'@vitejs/plugin-react':
specifier: ^6.0.1
- version: 6.0.1(vite@8.0.3(@types/node@25.5.0)(esbuild@0.27.4)(terser@5.46.1)(tsx@4.21.0))
+ version: 6.0.1(vite@8.0.3(@types/node@25.5.0)(esbuild@0.27.4)(jiti@1.21.7)(terser@5.46.1)(tsx@4.21.0))
typescript:
specifier: ~5.9.3
version: 5.9.3
vite:
specifier: ^8.0.1
- version: 8.0.3(@types/node@25.5.0)(esbuild@0.27.4)(terser@5.46.1)(tsx@4.21.0)
+ version: 8.0.3(@types/node@25.5.0)(esbuild@0.27.4)(jiti@1.21.7)(terser@5.46.1)(tsx@4.21.0)
packages:
@@ -277,6 +313,10 @@ packages:
peerDependencies:
zod: ^3.23.8
+ '@alloc/quick-lru@5.2.0':
+ resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
+ engines: {node: '>=10'}
+
'@angular-devkit/core@19.2.17':
resolution: {integrity: sha512-Ah008x2RJkd0F+NLKqIpA34/vUGwjlprRCkvddjDopAWRzYn6xCkz1Tqwuhn0nR1Dy47wTLKYD999TYl5ONOAQ==}
engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'}
@@ -467,6 +507,18 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0-0
+ '@babel/plugin-transform-react-jsx-self@7.27.1':
+ resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@babel/plugin-transform-react-jsx-source@7.27.1':
+ resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
'@babel/runtime@7.29.2':
resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==}
engines: {node: '>=6.9.0'}
@@ -510,102 +562,204 @@ packages:
'@emnapi/wasi-threads@1.2.0':
resolution: {integrity: sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==}
+ '@esbuild/aix-ppc64@0.21.5':
+ resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [aix]
+
'@esbuild/aix-ppc64@0.27.4':
resolution: {integrity: sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [aix]
+ '@esbuild/android-arm64@0.21.5':
+ resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [android]
+
'@esbuild/android-arm64@0.27.4':
resolution: {integrity: sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==}
engines: {node: '>=18'}
cpu: [arm64]
os: [android]
+ '@esbuild/android-arm@0.21.5':
+ resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [android]
+
'@esbuild/android-arm@0.27.4':
resolution: {integrity: sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==}
engines: {node: '>=18'}
cpu: [arm]
os: [android]
+ '@esbuild/android-x64@0.21.5':
+ resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [android]
+
'@esbuild/android-x64@0.27.4':
resolution: {integrity: sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==}
engines: {node: '>=18'}
cpu: [x64]
os: [android]
+ '@esbuild/darwin-arm64@0.21.5':
+ resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [darwin]
+
'@esbuild/darwin-arm64@0.27.4':
resolution: {integrity: sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==}
engines: {node: '>=18'}
cpu: [arm64]
os: [darwin]
+ '@esbuild/darwin-x64@0.21.5':
+ resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [darwin]
+
'@esbuild/darwin-x64@0.27.4':
resolution: {integrity: sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==}
engines: {node: '>=18'}
cpu: [x64]
os: [darwin]
+ '@esbuild/freebsd-arm64@0.21.5':
+ resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [freebsd]
+
'@esbuild/freebsd-arm64@0.27.4':
resolution: {integrity: sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==}
engines: {node: '>=18'}
cpu: [arm64]
os: [freebsd]
+ '@esbuild/freebsd-x64@0.21.5':
+ resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [freebsd]
+
'@esbuild/freebsd-x64@0.27.4':
resolution: {integrity: sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [freebsd]
+ '@esbuild/linux-arm64@0.21.5':
+ resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [linux]
+
'@esbuild/linux-arm64@0.27.4':
resolution: {integrity: sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==}
engines: {node: '>=18'}
cpu: [arm64]
os: [linux]
+ '@esbuild/linux-arm@0.21.5':
+ resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [linux]
+
'@esbuild/linux-arm@0.27.4':
resolution: {integrity: sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==}
engines: {node: '>=18'}
cpu: [arm]
os: [linux]
+ '@esbuild/linux-ia32@0.21.5':
+ resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [linux]
+
'@esbuild/linux-ia32@0.27.4':
resolution: {integrity: sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==}
engines: {node: '>=18'}
cpu: [ia32]
os: [linux]
+ '@esbuild/linux-loong64@0.21.5':
+ resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==}
+ engines: {node: '>=12'}
+ cpu: [loong64]
+ os: [linux]
+
'@esbuild/linux-loong64@0.27.4':
resolution: {integrity: sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==}
engines: {node: '>=18'}
cpu: [loong64]
os: [linux]
+ '@esbuild/linux-mips64el@0.21.5':
+ resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==}
+ engines: {node: '>=12'}
+ cpu: [mips64el]
+ os: [linux]
+
'@esbuild/linux-mips64el@0.27.4':
resolution: {integrity: sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==}
engines: {node: '>=18'}
cpu: [mips64el]
os: [linux]
+ '@esbuild/linux-ppc64@0.21.5':
+ resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [linux]
+
'@esbuild/linux-ppc64@0.27.4':
resolution: {integrity: sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [linux]
+ '@esbuild/linux-riscv64@0.21.5':
+ resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==}
+ engines: {node: '>=12'}
+ cpu: [riscv64]
+ os: [linux]
+
'@esbuild/linux-riscv64@0.27.4':
resolution: {integrity: sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==}
engines: {node: '>=18'}
cpu: [riscv64]
os: [linux]
+ '@esbuild/linux-s390x@0.21.5':
+ resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==}
+ engines: {node: '>=12'}
+ cpu: [s390x]
+ os: [linux]
+
'@esbuild/linux-s390x@0.27.4':
resolution: {integrity: sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==}
engines: {node: '>=18'}
cpu: [s390x]
os: [linux]
+ '@esbuild/linux-x64@0.21.5':
+ resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [linux]
+
'@esbuild/linux-x64@0.27.4':
resolution: {integrity: sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==}
engines: {node: '>=18'}
@@ -618,6 +772,12 @@ packages:
cpu: [arm64]
os: [netbsd]
+ '@esbuild/netbsd-x64@0.21.5':
+ resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [netbsd]
+
'@esbuild/netbsd-x64@0.27.4':
resolution: {integrity: sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==}
engines: {node: '>=18'}
@@ -630,6 +790,12 @@ packages:
cpu: [arm64]
os: [openbsd]
+ '@esbuild/openbsd-x64@0.21.5':
+ resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [openbsd]
+
'@esbuild/openbsd-x64@0.27.4':
resolution: {integrity: sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==}
engines: {node: '>=18'}
@@ -642,24 +808,48 @@ packages:
cpu: [arm64]
os: [openharmony]
+ '@esbuild/sunos-x64@0.21.5':
+ resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [sunos]
+
'@esbuild/sunos-x64@0.27.4':
resolution: {integrity: sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==}
engines: {node: '>=18'}
cpu: [x64]
os: [sunos]
+ '@esbuild/win32-arm64@0.21.5':
+ resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [win32]
+
'@esbuild/win32-arm64@0.27.4':
resolution: {integrity: sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [win32]
+ '@esbuild/win32-ia32@0.21.5':
+ resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [win32]
+
'@esbuild/win32-ia32@0.27.4':
resolution: {integrity: sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==}
engines: {node: '>=18'}
cpu: [ia32]
os: [win32]
+ '@esbuild/win32-x64@0.21.5':
+ resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [win32]
+
'@esbuild/win32-x64@0.27.4':
resolution: {integrity: sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==}
engines: {node: '>=18'}
@@ -1133,6 +1323,18 @@ packages:
'@nestjs/platform-socket.io':
optional: true
+ '@nodelib/fs.scandir@2.1.5':
+ resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.stat@2.0.5':
+ resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.walk@1.2.8':
+ resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+ engines: {node: '>= 8'}
+
'@nuxt/opencollective@0.4.1':
resolution: {integrity: sha512-GXD3wy50qYbxCJ652bDrDzgMr3NFEkIS374+IgFQKkCvk9yiYcLvX2XDYr7UyQxf4wK0e+yqDYRubZ0DtOxnmQ==}
engines: {node: ^14.18.0 || >=16.10.0, npm: '>=5.10.0'}
@@ -1152,6 +1354,10 @@ packages:
resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==}
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
+ '@remix-run/router@1.23.2':
+ resolution: {integrity: sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w==}
+ engines: {node: '>=14.0.0'}
+
'@rolldown/binding-android-arm64@1.0.0-rc.12':
resolution: {integrity: sha512-pv1y2Fv0JybcykuiiD3qBOBdz6RteYojRFY1d+b95WVuzx211CRh+ytI/+9iVyWQ6koTh5dawe4S/yRfOFjgaA==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -1247,6 +1453,9 @@ packages:
cpu: [x64]
os: [win32]
+ '@rolldown/pluginutils@1.0.0-beta.27':
+ resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==}
+
'@rolldown/pluginutils@1.0.0-rc.12':
resolution: {integrity: sha512-HHMwmarRKvoFsJorqYlFeFRzXZqCt2ETQlEDOb9aqssrnVBB1/+xgTGtuTrIk5vzLNX1MjMtTf7W9z3tsSbrxw==}
@@ -1628,6 +1837,9 @@ packages:
engines: {node: '>= 10'}
hasBin: true
+ '@tauri-apps/plugin-store@2.4.2':
+ resolution: {integrity: sha512-0ClHS50Oq9HEvLPhNzTNFxbWVOqoAp3dRvtewQBeqfIQ0z5m3JRnOISIn2ZVPCrQC0MyGyhTS9DWhHjpigQE7A==}
+
'@tokenizer/inflate@0.4.1':
resolution: {integrity: sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==}
engines: {node: '>=18'}
@@ -1746,17 +1958,28 @@ packages:
'@types/passport@1.0.17':
resolution: {integrity: sha512-aciLyx+wDwT2t2/kJGJR2AEeBz0nJU4WuRX04Wu9Dqc5lSUtwu0WERPHYsLhF9PtseiAMPBGNUOtFjxZ56prsg==}
+ '@types/prop-types@15.7.15':
+ resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==}
+
'@types/qs@6.15.0':
resolution: {integrity: sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow==}
'@types/range-parser@1.2.7':
resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==}
+ '@types/react-dom@18.3.7':
+ resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==}
+ peerDependencies:
+ '@types/react': ^18.0.0
+
'@types/react-dom@19.2.3':
resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==}
peerDependencies:
'@types/react': ^19.2.0
+ '@types/react@18.3.28':
+ resolution: {integrity: sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==}
+
'@types/react@19.2.14':
resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==}
@@ -1952,6 +2175,12 @@ packages:
cpu: [x64]
os: [win32]
+ '@vitejs/plugin-react@4.7.0':
+ resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ peerDependencies:
+ vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0
+
'@vitejs/plugin-react@6.0.1':
resolution: {integrity: sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -2045,9 +2274,6 @@ packages:
'@xtuc/long@4.2.2':
resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==}
- '@zeit/schemas@2.36.0':
- resolution: {integrity: sha512-7kjMwcChYEzMKjeex9ZFXkt1AyNov9R5HZtjBKVsmVpw7pa7ZtlCGvCBC2vnnXctaYN+aRI61HjIqeetZW5ROg==}
-
abort-controller@3.0.0:
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
engines: {node: '>=6.5'}
@@ -2115,9 +2341,6 @@ packages:
ajv@8.18.0:
resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==}
- ansi-align@3.0.1:
- resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==}
-
ansi-colors@4.1.3:
resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==}
engines: {node: '>=6'}
@@ -2164,9 +2387,6 @@ packages:
append-field@1.0.0:
resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==}
- arch@2.2.0:
- resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==}
-
arg@4.1.3:
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
@@ -2196,6 +2416,13 @@ packages:
resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==}
engines: {node: '>=8.0.0'}
+ autoprefixer@10.4.27:
+ resolution: {integrity: sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA==}
+ engines: {node: ^10 || ^12 || >=14}
+ hasBin: true
+ peerDependencies:
+ postcss: ^8.1.0
+
available-typed-arrays@1.0.7:
resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
engines: {node: '>= 0.4'}
@@ -2248,6 +2475,10 @@ packages:
resolution: {integrity: sha512-cU8v/EGSrnH+HnxV2z0J7/blxH8gq7Xh2JFT6Aroax7UohdmiJJlxApMxtKfuI7z68NvvVcmR78k2LbT6efhRg==}
engines: {node: '>= 18'}
+ binary-extensions@2.3.0:
+ resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
+ engines: {node: '>=8'}
+
bl@4.1.0:
resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
@@ -2259,10 +2490,6 @@ packages:
resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==}
engines: {node: '>=18'}
- boxen@7.0.0:
- resolution: {integrity: sha512-j//dBVuyacJbvW+tvZ9HuH03fZ46QcaKvvhZickZqtB271DxJ7SNRSNxrV/dZX0085m7hISRZWbzWlJvx/rHSg==}
- engines: {node: '>=14.16'}
-
brace-expansion@1.1.12:
resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==}
@@ -2273,6 +2500,10 @@ packages:
resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==}
engines: {node: 18 || 20 || >=22}
+ braces@3.0.3:
+ resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
+ engines: {node: '>=8'}
+
browserslist@4.28.1:
resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==}
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
@@ -2307,10 +2538,6 @@ packages:
resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==}
engines: {node: '>=10.16.0'}
- bytes@3.0.0:
- resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==}
- engines: {node: '>= 0.8'}
-
bytes@3.1.2:
resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
engines: {node: '>= 0.8'}
@@ -2335,6 +2562,10 @@ packages:
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
engines: {node: '>=6'}
+ camelcase-css@2.0.1:
+ resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
+ engines: {node: '>= 6'}
+
camelcase@5.3.1:
resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
engines: {node: '>=6'}
@@ -2343,10 +2574,6 @@ packages:
resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
engines: {node: '>=10'}
- camelcase@7.0.1:
- resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==}
- engines: {node: '>=14.16'}
-
caniuse-lite@1.0.30001781:
resolution: {integrity: sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw==}
@@ -2354,18 +2581,10 @@ packages:
resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==}
engines: {node: '>=18'}
- chalk-template@0.4.0:
- resolution: {integrity: sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==}
- engines: {node: '>=12'}
-
chalk@4.1.2:
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
engines: {node: '>=10'}
- chalk@5.0.1:
- resolution: {integrity: sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==}
- engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
-
char-regex@1.0.2:
resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==}
engines: {node: '>=10'}
@@ -2377,6 +2596,10 @@ packages:
resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==}
engines: {node: '>= 16'}
+ chokidar@3.6.0:
+ resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
+ engines: {node: '>= 8.10.0'}
+
chokidar@4.0.3:
resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
engines: {node: '>= 14.16.0'}
@@ -2398,10 +2621,6 @@ packages:
class-validator@0.15.1:
resolution: {integrity: sha512-LqoS80HBBSCVhz/3KloUly0ovokxpdOLR++Al3J3+dHXWt9sTKlKd4eYtoxhxyUjoe5+UcIM+5k9MIxyBWnRTw==}
- cli-boxes@3.0.0:
- resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==}
- engines: {node: '>=10'}
-
cli-cursor@3.1.0:
resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==}
engines: {node: '>=8'}
@@ -2418,10 +2637,6 @@ packages:
resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==}
engines: {node: '>= 12'}
- clipboardy@3.0.0:
- resolution: {integrity: sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg==}
- engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
-
cliui@8.0.1:
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
engines: {node: '>=12'}
@@ -2469,14 +2684,6 @@ packages:
resolution: {integrity: sha512-r1To31BQD5060QdkC+Iheai7gHwoSZobzunqkf2/kQ6xIAfJyrKNAFUwdKvkK7Qgu7pVTKQEa7ok7Ed3ycAJgg==}
engines: {node: '>= 6'}
- compressible@2.0.18:
- resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==}
- engines: {node: '>= 0.6'}
-
- compression@1.8.1:
- resolution: {integrity: sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==}
- engines: {node: '>= 0.8.0'}
-
concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
@@ -2491,10 +2698,6 @@ packages:
resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==}
engines: {node: ^14.18.0 || >=16.10.0}
- content-disposition@0.5.2:
- resolution: {integrity: sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==}
- engines: {node: '>= 0.6'}
-
content-disposition@0.5.4:
resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==}
engines: {node: '>= 0.6'}
@@ -2544,6 +2747,11 @@ packages:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
+ cssesc@3.0.0:
+ resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
+ engines: {node: '>=4'}
+ hasBin: true
+
csstype@3.2.3:
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
@@ -2591,10 +2799,6 @@ packages:
resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==}
engines: {node: '>=6'}
- deep-extend@0.6.0:
- resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==}
- engines: {node: '>=4.0.0'}
-
deep-is@0.1.4:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
@@ -2633,10 +2837,16 @@ packages:
resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==}
engines: {node: '>=8'}
+ didyoumean@1.2.2:
+ resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
+
diff@4.0.4:
resolution: {integrity: sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==}
engines: {node: '>=0.3.1'}
+ dlv@1.1.3:
+ resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
+
dotenv-expand@12.0.3:
resolution: {integrity: sha512-uc47g4b+4k/M/SeaW1y4OApx+mtLWl92l5LMPP0GNXctZqELk+YGgOPIIC5elYmUH4OuoK3JLhuRUYegeySiFA==}
engines: {node: '>=12'}
@@ -2730,6 +2940,11 @@ packages:
resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
engines: {node: '>= 0.4'}
+ esbuild@0.21.5:
+ resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==}
+ engines: {node: '>=12'}
+ hasBin: true
+
esbuild@0.27.4:
resolution: {integrity: sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==}
engines: {node: '>=18'}
@@ -2899,6 +3114,10 @@ packages:
fast-diff@1.3.0:
resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==}
+ fast-glob@3.3.3:
+ resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
+ engines: {node: '>=8.6.0'}
+
fast-json-stable-stringify@2.1.0:
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
@@ -2911,6 +3130,9 @@ packages:
fast-uri@3.1.0:
resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==}
+ fastq@1.20.1:
+ resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==}
+
fb-watchman@2.0.2:
resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==}
@@ -2935,6 +3157,10 @@ packages:
resolution: {integrity: sha512-DLkUvGwep3poOV2wpzbHCOnSKGk1LzyXTv+aHFgN2VFl96wnp8YA9YjO2qPzg5PuL8q/SW9Pdi6WTkYOIh995w==}
engines: {node: '>=20'}
+ fill-range@7.1.1:
+ resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
+ engines: {node: '>=8'}
+
finalhandler@1.3.2:
resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==}
engines: {node: '>= 0.8'}
@@ -2992,6 +3218,9 @@ packages:
resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
engines: {node: '>= 0.6'}
+ fraction.js@5.3.4:
+ resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==}
+
fresh@0.5.2:
resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==}
engines: {node: '>= 0.6'}
@@ -3049,6 +3278,10 @@ packages:
get-tsconfig@4.13.7:
resolution: {integrity: sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==}
+ glob-parent@5.1.2:
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+ engines: {node: '>= 6'}
+
glob-parent@6.0.2:
resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
engines: {node: '>=10.13.0'}
@@ -3180,9 +3413,6 @@ packages:
inherits@2.0.4:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
- ini@1.3.8:
- resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
-
ioredis@5.10.1:
resolution: {integrity: sha512-HuEDBTI70aYdx1v6U97SbNx9F1+svQKBDo30o0b9fw055LMepzpOOd0Ccg9Q6tbqmBSJaMuY0fB7yw9/vjBYCA==}
engines: {node: '>=12.22.0'}
@@ -3198,14 +3428,17 @@ packages:
is-arrayish@0.2.1:
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
+ is-binary-path@2.1.0:
+ resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
+ engines: {node: '>=8'}
+
is-callable@1.2.7:
resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
engines: {node: '>= 0.4'}
- is-docker@2.2.1:
- resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==}
- engines: {node: '>=8'}
- hasBin: true
+ is-core-module@2.16.1:
+ resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==}
+ engines: {node: '>= 0.4'}
is-extendable@0.1.1:
resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==}
@@ -3235,14 +3468,14 @@ packages:
resolution: {integrity: sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw==}
engines: {node: '>=16'}
+ is-number@7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+
is-plain-obj@4.1.0:
resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
engines: {node: '>=12'}
- is-port-reachable@4.0.0:
- resolution: {integrity: sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==}
- engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
-
is-promise@4.0.0:
resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==}
@@ -3266,10 +3499,6 @@ packages:
resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==}
engines: {node: '>=18'}
- is-wsl@2.2.0:
- resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==}
- engines: {node: '>=8'}
-
isarray@2.0.5:
resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
@@ -3435,6 +3664,10 @@ packages:
node-notifier:
optional: true
+ jiti@1.21.7:
+ resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==}
+ hasBin: true
+
jose@6.2.2:
resolution: {integrity: sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==}
@@ -3670,6 +3903,10 @@ packages:
resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==}
engines: {node: '>=10'}
+ loose-envify@1.4.0:
+ resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
+ hasBin: true
+
loupe@3.2.1:
resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==}
@@ -3722,13 +3959,17 @@ packages:
merge-stream@2.0.0:
resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
+ merge2@1.4.1:
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+ engines: {node: '>= 8'}
+
methods@1.1.2:
resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==}
engines: {node: '>= 0.6'}
- mime-db@1.33.0:
- resolution: {integrity: sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==}
- engines: {node: '>= 0.6'}
+ micromatch@4.0.8:
+ resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
+ engines: {node: '>=8.6'}
mime-db@1.52.0:
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
@@ -3738,10 +3979,6 @@ packages:
resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==}
engines: {node: '>= 0.6'}
- mime-types@2.1.18:
- resolution: {integrity: sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==}
- engines: {node: '>= 0.6'}
-
mime-types@2.1.35:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'}
@@ -3817,10 +4054,6 @@ packages:
resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==}
engines: {node: '>= 0.6'}
- negotiator@0.6.4:
- resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==}
- engines: {node: '>= 0.6'}
-
negotiator@1.0.0:
resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==}
engines: {node: '>= 0.6'}
@@ -3896,10 +4129,6 @@ packages:
resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==}
engines: {node: '>= 0.8'}
- on-headers@1.1.0:
- resolution: {integrity: sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==}
- engines: {node: '>= 0.8'}
-
once@1.4.0:
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
@@ -3996,9 +4225,6 @@ packages:
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
engines: {node: '>=0.10.0'}
- path-is-inside@1.0.2:
- resolution: {integrity: sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==}
-
path-key@3.1.1:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'}
@@ -4007,6 +4233,9 @@ packages:
resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==}
engines: {node: '>=12'}
+ path-parse@1.0.7:
+ resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+
path-scurry@1.11.1:
resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
engines: {node: '>=16 || 14 >=14.18'}
@@ -4018,9 +4247,6 @@ packages:
path-to-regexp@0.1.13:
resolution: {integrity: sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==}
- path-to-regexp@3.3.0:
- resolution: {integrity: sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==}
-
path-to-regexp@8.3.0:
resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==}
@@ -4087,6 +4313,10 @@ packages:
resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==}
engines: {node: '>=12'}
+ pify@2.3.0:
+ resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
+ engines: {node: '>=0.10.0'}
+
pino-abstract-transport@2.0.0:
resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==}
@@ -4127,6 +4357,18 @@ packages:
resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
engines: {node: '>= 0.4'}
+ postcss-import@15.1.0:
+ resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ postcss: ^8.0.0
+
+ postcss-js@4.1.0:
+ resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==}
+ engines: {node: ^12 || ^14 || >= 16}
+ peerDependencies:
+ postcss: ^8.4.21
+
postcss-load-config@6.0.1:
resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==}
engines: {node: '>= 18'}
@@ -4145,6 +4387,19 @@ packages:
yaml:
optional: true
+ postcss-nested@6.2.0:
+ resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==}
+ engines: {node: '>=12.0'}
+ peerDependencies:
+ postcss: ^8.2.14
+
+ postcss-selector-parser@6.1.2:
+ resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
+ engines: {node: '>=4'}
+
+ postcss-value-parser@4.2.0:
+ resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
+
postcss@8.5.8:
resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==}
engines: {node: ^10 || ^12 || >=14}
@@ -4218,6 +4473,9 @@ packages:
quansync@0.2.11:
resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==}
+ queue-microtask@1.2.3:
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+
quick-format-unescaped@4.0.4:
resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==}
@@ -4225,10 +4483,6 @@ packages:
resolution: {integrity: sha512-h36JMxKRqrAxVD8201FrCpyeNuUY9Y5zZwujr20fFO77tpUtGa6EZzfKw/3WaiBX95fq7+MpsuMLNdSnORAwSA==}
engines: {node: '>=14.18.0'}
- range-parser@1.2.0:
- resolution: {integrity: sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==}
- engines: {node: '>= 0.6'}
-
range-parser@1.2.1:
resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
engines: {node: '>= 0.6'}
@@ -4241,9 +4495,10 @@ packages:
resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==}
engines: {node: '>= 0.10'}
- rc@1.2.8:
- resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
- hasBin: true
+ react-dom@18.3.1:
+ resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==}
+ peerDependencies:
+ react: ^18.3.1
react-dom@19.2.4:
resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==}
@@ -4253,10 +4508,34 @@ packages:
react-is@18.3.1:
resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==}
+ react-refresh@0.17.0:
+ resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==}
+ engines: {node: '>=0.10.0'}
+
+ react-router-dom@6.30.3:
+ resolution: {integrity: sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ react: '>=16.8'
+ react-dom: '>=16.8'
+
+ react-router@6.30.3:
+ resolution: {integrity: sha512-XRnlbKMTmktBkjCLE8/XcZFlnHvr2Ltdr1eJX4idL55/9BbORzyZEaIkBFDhFGCEWBBItsVrDxwx3gnisMitdw==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ react: '>=16.8'
+
+ react@18.3.1:
+ resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
+ engines: {node: '>=0.10.0'}
+
react@19.2.4:
resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==}
engines: {node: '>=0.10.0'}
+ read-cache@1.0.0:
+ resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
+
readable-stream@3.6.2:
resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
engines: {node: '>= 6'}
@@ -4265,6 +4544,10 @@ packages:
resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ readdirp@3.6.0:
+ resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
+ engines: {node: '>=8.10.0'}
+
readdirp@4.1.2:
resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
engines: {node: '>= 14.18.0'}
@@ -4284,13 +4567,6 @@ packages:
reflect-metadata@0.2.2:
resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==}
- registry-auth-token@3.3.2:
- resolution: {integrity: sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==}
-
- registry-url@3.1.0:
- resolution: {integrity: sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==}
- engines: {node: '>=0.10.0'}
-
require-directory@2.1.1:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'}
@@ -4314,10 +4590,19 @@ packages:
resolve-pkg-maps@1.0.0:
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
+ resolve@1.22.11:
+ resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==}
+ engines: {node: '>= 0.4'}
+ hasBin: true
+
restore-cursor@3.1.0:
resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==}
engines: {node: '>=8'}
+ reusify@1.1.0:
+ resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+
rolldown@1.0.0-rc.12:
resolution: {integrity: sha512-yP4USLIMYrwpPHEFB5JGH1uxhcslv6/hL0OyvTuY+3qlOSJvZ7ntYnoWpehBxufkgN0cvXxppuTu5hHa/zPh+A==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -4332,6 +4617,9 @@ packages:
resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==}
engines: {node: '>= 18'}
+ run-parallel@1.2.0:
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+
rxjs@7.8.1:
resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==}
@@ -4348,6 +4636,9 @@ packages:
safer-buffer@2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
+ scheduler@0.23.2:
+ resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==}
+
scheduler@0.27.0:
resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
@@ -4390,9 +4681,6 @@ packages:
resolution: {integrity: sha512-AmH3D9hHPFmnF/oq/rvigfiAouAKyK/TjnrkwZRYSFZxNggJxwvbAbfYrLeuvq7ktUdhuHdVdSjj852Z55R+uA==}
engines: {node: '>=16.0.0'}
- serve-handler@6.1.7:
- resolution: {integrity: sha512-CinAq1xWb0vR3twAv9evEU8cNWkXCb9kd5ePAHUKJBkOsUpR1wt/CvGdeca7vqumL1U5cSaeVQ6zZMxiJ3yWsg==}
-
serve-static@1.16.3:
resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==}
engines: {node: '>= 0.8.0'}
@@ -4401,11 +4689,6 @@ packages:
resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==}
engines: {node: '>= 18'}
- serve@14.2.6:
- resolution: {integrity: sha512-QEjUSA+sD4Rotm1znR8s50YqA3kYpRGPmtd5GlFxbaL9n/FdUNbqMhxClqdditSk0LlZyA/dhud6XNRTOC9x2Q==}
- engines: {node: '>= 14'}
- hasBin: true
-
set-function-length@1.2.2:
resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
engines: {node: '>= 0.4'}
@@ -4571,10 +4854,6 @@ packages:
resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==}
engines: {node: '>=18'}
- strip-json-comments@2.0.1:
- resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==}
- engines: {node: '>=0.10.0'}
-
strip-json-comments@3.1.1:
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
engines: {node: '>=8'}
@@ -4603,6 +4882,10 @@ packages:
resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
engines: {node: '>=10'}
+ supports-preserve-symlinks-flag@1.0.0:
+ resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
+ engines: {node: '>= 0.4'}
+
symbol-observable@4.0.0:
resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==}
engines: {node: '>=0.10'}
@@ -4611,6 +4894,11 @@ packages:
resolution: {integrity: sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==}
engines: {node: ^14.18.0 || >=16.0.0}
+ tailwindcss@3.4.19:
+ resolution: {integrity: sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==}
+ engines: {node: '>=14.0.0'}
+ hasBin: true
+
tapable@2.3.2:
resolution: {integrity: sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==}
engines: {node: '>=6'}
@@ -4679,6 +4967,10 @@ packages:
resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==}
engines: {node: '>= 0.4'}
+ to-regex-range@5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+
toidentifier@1.0.1:
resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
engines: {node: '>=0.6'}
@@ -4794,10 +5086,6 @@ packages:
resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==}
engines: {node: '>=10'}
- type-fest@2.19.0:
- resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==}
- engines: {node: '>=12.20'}
-
type-fest@4.41.0:
resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==}
engines: {node: '>=16'}
@@ -4925,15 +5213,17 @@ packages:
peerDependencies:
browserslist: '>= 4.21.0'
- update-check@1.5.4:
- resolution: {integrity: sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ==}
-
uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
url-join@4.0.1:
resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==}
+ use-sync-external-store@1.6.0:
+ resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+
util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
@@ -4965,27 +5255,22 @@ packages:
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
hasBin: true
- vite@7.3.1:
- resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==}
- engines: {node: ^20.19.0 || >=22.12.0}
+ vite@5.4.21:
+ resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==}
+ engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
peerDependencies:
- '@types/node': ^20.19.0 || >=22.12.0
- jiti: '>=1.21.0'
- less: ^4.0.0
+ '@types/node': ^18.0.0 || >=20.0.0
+ less: '*'
lightningcss: ^1.21.0
- sass: ^1.70.0
- sass-embedded: ^1.70.0
- stylus: '>=0.54.8'
- sugarss: ^5.0.0
- terser: ^5.16.0
- tsx: ^4.8.1
- yaml: ^2.4.2
+ sass: '*'
+ sass-embedded: '*'
+ stylus: '*'
+ sugarss: '*'
+ terser: ^5.4.0
peerDependenciesMeta:
'@types/node':
optional: true
- jiti:
- optional: true
less:
optional: true
lightningcss:
@@ -5000,10 +5285,6 @@ packages:
optional: true
terser:
optional: true
- tsx:
- optional: true
- yaml:
- optional: true
vite@8.0.3:
resolution: {integrity: sha512-B9ifbFudT1TFhfltfaIPgjo9Z3mDynBTJSUYxTjOQruf/zHH+ezCQKcoqO+h7a9Pw9Nm/OtlXAiGT1axBgwqrQ==}
@@ -5124,10 +5405,6 @@ packages:
engines: {node: '>=8'}
hasBin: true
- widest-line@4.0.1:
- resolution: {integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==}
- engines: {node: '>=12'}
-
word-wrap@1.2.5:
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
engines: {node: '>=0.10.0'}
@@ -5237,6 +5514,21 @@ packages:
zod@4.3.6:
resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==}
+ zustand@4.5.7:
+ resolution: {integrity: sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==}
+ engines: {node: '>=12.7.0'}
+ peerDependencies:
+ '@types/react': '>=16.8'
+ immer: '>=9.0.6'
+ react: '>=16.8'
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ immer:
+ optional: true
+ react:
+ optional: true
+
snapshots:
'@a2a-js/sdk@0.2.5':
@@ -5294,6 +5586,8 @@ snapshots:
zod: 4.3.6
zod-to-json-schema: 3.25.2(zod@4.3.6)
+ '@alloc/quick-lru@5.2.0': {}
+
'@angular-devkit/core@19.2.17(chokidar@4.0.3)':
dependencies:
ajv: 8.17.1
@@ -5518,6 +5812,16 @@ snapshots:
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
+ '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.28.6
+
+ '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.28.6
+
'@babel/runtime@7.29.2': {}
'@babel/template@7.28.6':
@@ -5577,87 +5881,156 @@ snapshots:
tslib: 2.8.1
optional: true
+ '@esbuild/aix-ppc64@0.21.5':
+ optional: true
+
'@esbuild/aix-ppc64@0.27.4':
optional: true
+ '@esbuild/android-arm64@0.21.5':
+ optional: true
+
'@esbuild/android-arm64@0.27.4':
optional: true
+ '@esbuild/android-arm@0.21.5':
+ optional: true
+
'@esbuild/android-arm@0.27.4':
optional: true
+ '@esbuild/android-x64@0.21.5':
+ optional: true
+
'@esbuild/android-x64@0.27.4':
optional: true
+ '@esbuild/darwin-arm64@0.21.5':
+ optional: true
+
'@esbuild/darwin-arm64@0.27.4':
optional: true
+ '@esbuild/darwin-x64@0.21.5':
+ optional: true
+
'@esbuild/darwin-x64@0.27.4':
optional: true
+ '@esbuild/freebsd-arm64@0.21.5':
+ optional: true
+
'@esbuild/freebsd-arm64@0.27.4':
optional: true
+ '@esbuild/freebsd-x64@0.21.5':
+ optional: true
+
'@esbuild/freebsd-x64@0.27.4':
optional: true
+ '@esbuild/linux-arm64@0.21.5':
+ optional: true
+
'@esbuild/linux-arm64@0.27.4':
optional: true
+ '@esbuild/linux-arm@0.21.5':
+ optional: true
+
'@esbuild/linux-arm@0.27.4':
optional: true
+ '@esbuild/linux-ia32@0.21.5':
+ optional: true
+
'@esbuild/linux-ia32@0.27.4':
optional: true
+ '@esbuild/linux-loong64@0.21.5':
+ optional: true
+
'@esbuild/linux-loong64@0.27.4':
optional: true
+ '@esbuild/linux-mips64el@0.21.5':
+ optional: true
+
'@esbuild/linux-mips64el@0.27.4':
optional: true
+ '@esbuild/linux-ppc64@0.21.5':
+ optional: true
+
'@esbuild/linux-ppc64@0.27.4':
optional: true
+ '@esbuild/linux-riscv64@0.21.5':
+ optional: true
+
'@esbuild/linux-riscv64@0.27.4':
optional: true
+ '@esbuild/linux-s390x@0.21.5':
+ optional: true
+
'@esbuild/linux-s390x@0.27.4':
optional: true
+ '@esbuild/linux-x64@0.21.5':
+ optional: true
+
'@esbuild/linux-x64@0.27.4':
optional: true
'@esbuild/netbsd-arm64@0.27.4':
optional: true
+ '@esbuild/netbsd-x64@0.21.5':
+ optional: true
+
'@esbuild/netbsd-x64@0.27.4':
optional: true
'@esbuild/openbsd-arm64@0.27.4':
optional: true
+ '@esbuild/openbsd-x64@0.21.5':
+ optional: true
+
'@esbuild/openbsd-x64@0.27.4':
optional: true
'@esbuild/openharmony-arm64@0.27.4':
optional: true
+ '@esbuild/sunos-x64@0.21.5':
+ optional: true
+
'@esbuild/sunos-x64@0.27.4':
optional: true
+ '@esbuild/win32-arm64@0.21.5':
+ optional: true
+
'@esbuild/win32-arm64@0.27.4':
optional: true
+ '@esbuild/win32-ia32@0.21.5':
+ optional: true
+
'@esbuild/win32-ia32@0.27.4':
optional: true
+ '@esbuild/win32-x64@0.21.5':
+ optional: true
+
'@esbuild/win32-x64@0.27.4':
optional: true
- '@eslint-community/eslint-utils@4.9.1(eslint@10.1.0)':
+ '@eslint-community/eslint-utils@4.9.1(eslint@10.1.0(jiti@1.21.7))':
dependencies:
- eslint: 10.1.0
+ eslint: 10.1.0(jiti@1.21.7)
eslint-visitor-keys: 3.4.3
'@eslint-community/regexpp@4.12.2': {}
@@ -6310,6 +6683,18 @@ snapshots:
optionalDependencies:
'@nestjs/platform-socket.io': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.17)(rxjs@7.8.2)
+ '@nodelib/fs.scandir@2.1.5':
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ run-parallel: 1.2.0
+
+ '@nodelib/fs.stat@2.0.5': {}
+
+ '@nodelib/fs.walk@1.2.8':
+ dependencies:
+ '@nodelib/fs.scandir': 2.1.5
+ fastq: 1.20.1
+
'@nuxt/opencollective@0.4.1':
dependencies:
consola: 3.4.2
@@ -6323,6 +6708,8 @@ snapshots:
'@pkgr/core@0.2.9': {}
+ '@remix-run/router@1.23.2': {}
+
'@rolldown/binding-android-arm64@1.0.0-rc.12':
optional: true
@@ -6370,6 +6757,8 @@ snapshots:
'@rolldown/binding-win32-x64-msvc@1.0.0-rc.12':
optional: true
+ '@rolldown/pluginutils@1.0.0-beta.27': {}
+
'@rolldown/pluginutils@1.0.0-rc.12': {}
'@rolldown/pluginutils@1.0.0-rc.7': {}
@@ -6598,6 +6987,10 @@ snapshots:
'@tauri-apps/cli-win32-ia32-msvc': 2.10.1
'@tauri-apps/cli-win32-x64-msvc': 2.10.1
+ '@tauri-apps/plugin-store@2.4.2':
+ dependencies:
+ '@tauri-apps/api': 2.10.1
+
'@tokenizer/inflate@0.4.1':
dependencies:
debug: 4.4.3
@@ -6756,14 +7149,25 @@ snapshots:
dependencies:
'@types/express': 5.0.6
+ '@types/prop-types@15.7.15': {}
+
'@types/qs@6.15.0': {}
'@types/range-parser@1.2.7': {}
+ '@types/react-dom@18.3.7(@types/react@18.3.28)':
+ dependencies:
+ '@types/react': 18.3.28
+
'@types/react-dom@19.2.3(@types/react@19.2.14)':
dependencies:
'@types/react': 19.2.14
+ '@types/react@18.3.28':
+ dependencies:
+ '@types/prop-types': 15.7.15
+ csstype: 3.2.3
+
'@types/react@19.2.14':
dependencies:
csstype: 3.2.3
@@ -6802,15 +7206,15 @@ snapshots:
dependencies:
'@types/yargs-parser': 21.0.3
- '@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@10.1.0)(typescript@5.8.3))(eslint@10.1.0)(typescript@5.8.3)':
+ '@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.8.3))(eslint@10.1.0(jiti@1.21.7))(typescript@5.8.3)':
dependencies:
'@eslint-community/regexpp': 4.12.2
- '@typescript-eslint/parser': 8.57.2(eslint@10.1.0)(typescript@5.8.3)
+ '@typescript-eslint/parser': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.8.3)
'@typescript-eslint/scope-manager': 8.57.2
- '@typescript-eslint/type-utils': 8.57.2(eslint@10.1.0)(typescript@5.8.3)
- '@typescript-eslint/utils': 8.57.2(eslint@10.1.0)(typescript@5.8.3)
+ '@typescript-eslint/type-utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.8.3)
+ '@typescript-eslint/utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.8.3)
'@typescript-eslint/visitor-keys': 8.57.2
- eslint: 10.1.0
+ eslint: 10.1.0(jiti@1.21.7)
ignore: 7.0.5
natural-compare: 1.4.0
ts-api-utils: 2.5.0(typescript@5.8.3)
@@ -6818,14 +7222,14 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/parser@8.57.2(eslint@10.1.0)(typescript@5.8.3)':
+ '@typescript-eslint/parser@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.8.3)':
dependencies:
'@typescript-eslint/scope-manager': 8.57.2
'@typescript-eslint/types': 8.57.2
'@typescript-eslint/typescript-estree': 8.57.2(typescript@5.8.3)
'@typescript-eslint/visitor-keys': 8.57.2
debug: 4.4.3
- eslint: 10.1.0
+ eslint: 10.1.0(jiti@1.21.7)
typescript: 5.8.3
transitivePeerDependencies:
- supports-color
@@ -6848,13 +7252,13 @@ snapshots:
dependencies:
typescript: 5.8.3
- '@typescript-eslint/type-utils@8.57.2(eslint@10.1.0)(typescript@5.8.3)':
+ '@typescript-eslint/type-utils@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.8.3)':
dependencies:
'@typescript-eslint/types': 8.57.2
'@typescript-eslint/typescript-estree': 8.57.2(typescript@5.8.3)
- '@typescript-eslint/utils': 8.57.2(eslint@10.1.0)(typescript@5.8.3)
+ '@typescript-eslint/utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.8.3)
debug: 4.4.3
- eslint: 10.1.0
+ eslint: 10.1.0(jiti@1.21.7)
ts-api-utils: 2.5.0(typescript@5.8.3)
typescript: 5.8.3
transitivePeerDependencies:
@@ -6877,13 +7281,13 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/utils@8.57.2(eslint@10.1.0)(typescript@5.8.3)':
+ '@typescript-eslint/utils@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.8.3)':
dependencies:
- '@eslint-community/eslint-utils': 4.9.1(eslint@10.1.0)
+ '@eslint-community/eslint-utils': 4.9.1(eslint@10.1.0(jiti@1.21.7))
'@typescript-eslint/scope-manager': 8.57.2
'@typescript-eslint/types': 8.57.2
'@typescript-eslint/typescript-estree': 8.57.2(typescript@5.8.3)
- eslint: 10.1.0
+ eslint: 10.1.0(jiti@1.21.7)
typescript: 5.8.3
transitivePeerDependencies:
- supports-color
@@ -6954,10 +7358,22 @@ snapshots:
'@unrs/resolver-binding-win32-x64-msvc@1.11.1':
optional: true
- '@vitejs/plugin-react@6.0.1(vite@8.0.3(@types/node@25.5.0)(esbuild@0.27.4)(terser@5.46.1)(tsx@4.21.0))':
+ '@vitejs/plugin-react@4.7.0(vite@5.4.21(@types/node@25.5.0)(lightningcss@1.32.0)(terser@5.46.1))':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0)
+ '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0)
+ '@rolldown/pluginutils': 1.0.0-beta.27
+ '@types/babel__core': 7.20.5
+ react-refresh: 0.17.0
+ vite: 5.4.21(@types/node@25.5.0)(lightningcss@1.32.0)(terser@5.46.1)
+ transitivePeerDependencies:
+ - supports-color
+
+ '@vitejs/plugin-react@6.0.1(vite@8.0.3(@types/node@25.5.0)(esbuild@0.27.4)(jiti@1.21.7)(terser@5.46.1)(tsx@4.21.0))':
dependencies:
'@rolldown/pluginutils': 1.0.0-rc.7
- vite: 8.0.3(@types/node@25.5.0)(esbuild@0.27.4)(terser@5.46.1)(tsx@4.21.0)
+ vite: 8.0.3(@types/node@25.5.0)(esbuild@0.27.4)(jiti@1.21.7)(terser@5.46.1)(tsx@4.21.0)
'@vitest/expect@3.2.4':
dependencies:
@@ -6967,13 +7383,13 @@ snapshots:
chai: 5.3.3
tinyrainbow: 2.0.0
- '@vitest/mocker@3.2.4(vite@7.3.1(@types/node@22.19.15)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0))':
+ '@vitest/mocker@3.2.4(vite@5.4.21(@types/node@22.19.15)(lightningcss@1.32.0)(terser@5.46.1))':
dependencies:
'@vitest/spy': 3.2.4
estree-walker: 3.0.3
magic-string: 0.30.17
optionalDependencies:
- vite: 7.3.1(@types/node@22.19.15)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)
+ vite: 5.4.21(@types/node@22.19.15)(lightningcss@1.32.0)(terser@5.46.1)
'@vitest/pretty-format@3.2.4':
dependencies:
@@ -7081,8 +7497,6 @@ snapshots:
'@xtuc/long@4.2.2': {}
- '@zeit/schemas@2.36.0': {}
-
abort-controller@3.0.0:
dependencies:
event-target-shim: 5.0.1
@@ -7153,10 +7567,6 @@ snapshots:
json-schema-traverse: 1.0.0
require-from-string: 2.0.2
- ansi-align@3.0.1:
- dependencies:
- string-width: 4.2.3
-
ansi-colors@4.1.3: {}
ansi-escapes@4.3.2:
@@ -7188,8 +7598,6 @@ snapshots:
append-field@1.0.0: {}
- arch@2.2.0: {}
-
arg@4.1.3: {}
arg@5.0.2: {}
@@ -7210,6 +7618,15 @@ snapshots:
atomic-sleep@1.0.0: {}
+ autoprefixer@10.4.27(postcss@8.5.8):
+ dependencies:
+ browserslist: 4.28.1
+ caniuse-lite: 1.0.30001781
+ fraction.js: 5.3.4
+ picocolors: 1.1.1
+ postcss: 8.5.8
+ postcss-value-parser: 4.2.0
+
available-typed-arrays@1.0.7:
dependencies:
possible-typed-array-names: 1.1.0
@@ -7281,6 +7698,8 @@ snapshots:
node-addon-api: 8.7.0
node-gyp-build: 4.8.4
+ binary-extensions@2.3.0: {}
+
bl@4.1.0:
dependencies:
buffer: 5.7.1
@@ -7318,17 +7737,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- boxen@7.0.0:
- dependencies:
- ansi-align: 3.0.1
- camelcase: 7.0.1
- chalk: 5.0.1
- cli-boxes: 3.0.0
- string-width: 5.1.2
- type-fest: 2.19.0
- widest-line: 4.0.1
- wrap-ansi: 8.1.0
-
brace-expansion@1.1.12:
dependencies:
balanced-match: 1.0.2
@@ -7342,6 +7750,10 @@ snapshots:
dependencies:
balanced-match: 4.0.4
+ braces@3.0.3:
+ dependencies:
+ fill-range: 7.1.1
+
browserslist@4.28.1:
dependencies:
baseline-browser-mapping: 2.10.11
@@ -7381,8 +7793,6 @@ snapshots:
dependencies:
streamsearch: 1.1.0
- bytes@3.0.0: {}
-
bytes@3.1.2: {}
cac@6.7.14: {}
@@ -7406,12 +7816,12 @@ snapshots:
callsites@3.1.0: {}
+ camelcase-css@2.0.1: {}
+
camelcase@5.3.1: {}
camelcase@6.3.0: {}
- camelcase@7.0.1: {}
-
caniuse-lite@1.0.30001781: {}
chai@5.3.3:
@@ -7422,23 +7832,29 @@ snapshots:
loupe: 3.2.1
pathval: 2.0.1
- chalk-template@0.4.0:
- dependencies:
- chalk: 4.1.2
-
chalk@4.1.2:
dependencies:
ansi-styles: 4.3.0
supports-color: 7.2.0
- chalk@5.0.1: {}
-
char-regex@1.0.2: {}
chardet@2.1.1: {}
check-error@2.1.3: {}
+ chokidar@3.6.0:
+ dependencies:
+ anymatch: 3.1.3
+ braces: 3.0.3
+ glob-parent: 5.1.2
+ is-binary-path: 2.1.0
+ is-glob: 4.0.3
+ normalize-path: 3.0.0
+ readdirp: 3.6.0
+ optionalDependencies:
+ fsevents: 2.3.3
+
chokidar@4.0.3:
dependencies:
readdirp: 4.1.2
@@ -7457,8 +7873,6 @@ snapshots:
libphonenumber-js: 1.12.40
validator: 13.15.26
- cli-boxes@3.0.0: {}
-
cli-cursor@3.1.0:
dependencies:
restore-cursor: 3.1.0
@@ -7473,12 +7887,6 @@ snapshots:
cli-width@4.1.0: {}
- clipboardy@3.0.0:
- dependencies:
- arch: 2.2.0
- execa: 5.1.1
- is-wsl: 2.2.0
-
cliui@8.0.1:
dependencies:
string-width: 4.2.3
@@ -7517,22 +7925,6 @@ snapshots:
core-util-is: 1.0.3
esprima: 4.0.1
- compressible@2.0.18:
- dependencies:
- mime-db: 1.54.0
-
- compression@1.8.1:
- dependencies:
- bytes: 3.1.2
- compressible: 2.0.18
- debug: 2.6.9
- negotiator: 0.6.4
- on-headers: 1.1.0
- safe-buffer: 5.2.1
- vary: 1.1.2
- transitivePeerDependencies:
- - supports-color
-
concat-map@0.0.1: {}
concat-stream@2.0.0:
@@ -7546,8 +7938,6 @@ snapshots:
consola@3.4.2: {}
- content-disposition@0.5.2: {}
-
content-disposition@0.5.4:
dependencies:
safe-buffer: 5.2.1
@@ -7588,6 +7978,8 @@ snapshots:
shebang-command: 2.0.0
which: 2.0.2
+ cssesc@3.0.0: {}
+
csstype@3.2.3: {}
dateformat@4.6.3: {}
@@ -7610,8 +8002,6 @@ snapshots:
deep-eql@5.0.2: {}
- deep-extend@0.6.0: {}
-
deep-is@0.1.4: {}
deepmerge@4.3.1: {}
@@ -7638,8 +8028,12 @@ snapshots:
detect-newline@3.1.0: {}
+ didyoumean@1.2.2: {}
+
diff@4.0.4: {}
+ dlv@1.1.3: {}
+
dotenv-expand@12.0.3:
dependencies:
dotenv: 16.6.1
@@ -7751,6 +8145,32 @@ snapshots:
has-tostringtag: 1.0.2
hasown: 2.0.2
+ esbuild@0.21.5:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.21.5
+ '@esbuild/android-arm': 0.21.5
+ '@esbuild/android-arm64': 0.21.5
+ '@esbuild/android-x64': 0.21.5
+ '@esbuild/darwin-arm64': 0.21.5
+ '@esbuild/darwin-x64': 0.21.5
+ '@esbuild/freebsd-arm64': 0.21.5
+ '@esbuild/freebsd-x64': 0.21.5
+ '@esbuild/linux-arm': 0.21.5
+ '@esbuild/linux-arm64': 0.21.5
+ '@esbuild/linux-ia32': 0.21.5
+ '@esbuild/linux-loong64': 0.21.5
+ '@esbuild/linux-mips64el': 0.21.5
+ '@esbuild/linux-ppc64': 0.21.5
+ '@esbuild/linux-riscv64': 0.21.5
+ '@esbuild/linux-s390x': 0.21.5
+ '@esbuild/linux-x64': 0.21.5
+ '@esbuild/netbsd-x64': 0.21.5
+ '@esbuild/openbsd-x64': 0.21.5
+ '@esbuild/sunos-x64': 0.21.5
+ '@esbuild/win32-arm64': 0.21.5
+ '@esbuild/win32-ia32': 0.21.5
+ '@esbuild/win32-x64': 0.21.5
+
esbuild@0.27.4:
optionalDependencies:
'@esbuild/aix-ppc64': 0.27.4
@@ -7790,19 +8210,19 @@ snapshots:
escape-string-regexp@5.0.0: {}
- eslint-config-prettier@10.1.8(eslint@10.1.0):
+ eslint-config-prettier@10.1.8(eslint@10.1.0(jiti@1.21.7)):
dependencies:
- eslint: 10.1.0
+ eslint: 10.1.0(jiti@1.21.7)
- eslint-plugin-prettier@5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.1.0))(eslint@10.1.0)(prettier@3.8.1):
+ eslint-plugin-prettier@5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.1.0(jiti@1.21.7)))(eslint@10.1.0(jiti@1.21.7))(prettier@3.8.1):
dependencies:
- eslint: 10.1.0
+ eslint: 10.1.0(jiti@1.21.7)
prettier: 3.8.1
prettier-linter-helpers: 1.0.1
synckit: 0.11.12
optionalDependencies:
'@types/eslint': 9.6.1
- eslint-config-prettier: 10.1.8(eslint@10.1.0)
+ eslint-config-prettier: 10.1.8(eslint@10.1.0(jiti@1.21.7))
eslint-scope@5.1.1:
dependencies:
@@ -7820,9 +8240,9 @@ snapshots:
eslint-visitor-keys@5.0.1: {}
- eslint@10.1.0:
+ eslint@10.1.0(jiti@1.21.7):
dependencies:
- '@eslint-community/eslint-utils': 4.9.1(eslint@10.1.0)
+ '@eslint-community/eslint-utils': 4.9.1(eslint@10.1.0(jiti@1.21.7))
'@eslint-community/regexpp': 4.12.2
'@eslint/config-array': 0.23.3
'@eslint/config-helpers': 0.5.3
@@ -7852,6 +8272,8 @@ snapshots:
minimatch: 10.2.4
natural-compare: 1.4.0
optionator: 0.9.4
+ optionalDependencies:
+ jiti: 1.21.7
transitivePeerDependencies:
- supports-color
@@ -8017,6 +8439,14 @@ snapshots:
fast-diff@1.3.0: {}
+ fast-glob@3.3.3:
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.8
+
fast-json-stable-stringify@2.1.0: {}
fast-levenshtein@2.0.6: {}
@@ -8025,6 +8455,10 @@ snapshots:
fast-uri@3.1.0: {}
+ fastq@1.20.1:
+ dependencies:
+ reusify: 1.1.0
+
fb-watchman@2.0.2:
dependencies:
bser: 2.1.1
@@ -8050,6 +8484,10 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ fill-range@7.1.1:
+ dependencies:
+ to-regex-range: 5.0.1
+
finalhandler@1.3.2:
dependencies:
debug: 2.6.9
@@ -8136,6 +8574,8 @@ snapshots:
forwarded@0.2.0: {}
+ fraction.js@5.3.4: {}
+
fresh@0.5.2: {}
fresh@2.0.0: {}
@@ -8190,6 +8630,10 @@ snapshots:
dependencies:
resolve-pkg-maps: 1.0.0
+ glob-parent@5.1.2:
+ dependencies:
+ is-glob: 4.0.3
+
glob-parent@6.0.2:
dependencies:
is-glob: 4.0.3
@@ -8316,8 +8760,6 @@ snapshots:
inherits@2.0.4: {}
- ini@1.3.8: {}
-
ioredis@5.10.1:
dependencies:
'@ioredis/commands': 1.5.1
@@ -8338,9 +8780,15 @@ snapshots:
is-arrayish@0.2.1: {}
+ is-binary-path@2.1.0:
+ dependencies:
+ binary-extensions: 2.3.0
+
is-callable@1.2.7: {}
- is-docker@2.2.1: {}
+ is-core-module@2.16.1:
+ dependencies:
+ hasown: 2.0.2
is-extendable@0.1.1: {}
@@ -8358,9 +8806,9 @@ snapshots:
is-network-error@1.3.1: {}
- is-plain-obj@4.1.0: {}
+ is-number@7.0.0: {}
- is-port-reachable@4.0.0: {}
+ is-plain-obj@4.1.0: {}
is-promise@4.0.0: {}
@@ -8376,10 +8824,6 @@ snapshots:
is-unicode-supported@2.1.0: {}
- is-wsl@2.2.0:
- dependencies:
- is-docker: 2.2.1
-
isarray@2.0.5: {}
isexe@2.0.0: {}
@@ -8740,6 +9184,8 @@ snapshots:
- supports-color
- ts-node
+ jiti@1.21.7: {}
+
jose@6.2.2: {}
joycon@3.1.1: {}
@@ -8927,6 +9373,10 @@ snapshots:
chalk: 4.1.2
is-unicode-supported: 0.1.0
+ loose-envify@1.4.0:
+ dependencies:
+ js-tokens: 4.0.0
+
loupe@3.2.1: {}
lru-cache@10.4.3: {}
@@ -8967,18 +9417,19 @@ snapshots:
merge-stream@2.0.0: {}
+ merge2@1.4.1: {}
+
methods@1.1.2: {}
- mime-db@1.33.0: {}
+ micromatch@4.0.8:
+ dependencies:
+ braces: 3.0.3
+ picomatch: 2.3.2
mime-db@1.52.0: {}
mime-db@1.54.0: {}
- mime-types@2.1.18:
- dependencies:
- mime-db: 1.33.0
-
mime-types@2.1.35:
dependencies:
mime-db: 1.52.0
@@ -9043,8 +9494,6 @@ snapshots:
negotiator@0.6.3: {}
- negotiator@0.6.4: {}
-
negotiator@1.0.0: {}
neo-async@2.6.2: {}
@@ -9094,8 +9543,6 @@ snapshots:
dependencies:
ee-first: 1.1.1
- on-headers@1.1.0: {}
-
once@1.4.0:
dependencies:
wrappy: 1.0.2
@@ -9190,12 +9637,12 @@ snapshots:
path-is-absolute@1.0.1: {}
- path-is-inside@1.0.2: {}
-
path-key@3.1.1: {}
path-key@4.0.0: {}
+ path-parse@1.0.7: {}
+
path-scurry@1.11.1:
dependencies:
lru-cache: 10.4.3
@@ -9208,8 +9655,6 @@ snapshots:
path-to-regexp@0.1.13: {}
- path-to-regexp@3.3.0: {}
-
path-to-regexp@8.3.0: {}
path-type@4.0.0: {}
@@ -9263,6 +9708,8 @@ snapshots:
picomatch@4.0.4: {}
+ pify@2.3.0: {}
+
pino-abstract-transport@2.0.0:
dependencies:
split2: 4.2.0
@@ -9321,13 +9768,38 @@ snapshots:
possible-typed-array-names@1.1.0: {}
- postcss-load-config@6.0.1(postcss@8.5.8)(tsx@4.21.0):
+ postcss-import@15.1.0(postcss@8.5.8):
+ dependencies:
+ postcss: 8.5.8
+ postcss-value-parser: 4.2.0
+ read-cache: 1.0.0
+ resolve: 1.22.11
+
+ postcss-js@4.1.0(postcss@8.5.8):
+ dependencies:
+ camelcase-css: 2.0.1
+ postcss: 8.5.8
+
+ postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.8)(tsx@4.21.0):
dependencies:
lilconfig: 3.1.3
optionalDependencies:
+ jiti: 1.21.7
postcss: 8.5.8
tsx: 4.21.0
+ postcss-nested@6.2.0(postcss@8.5.8):
+ dependencies:
+ postcss: 8.5.8
+ postcss-selector-parser: 6.1.2
+
+ postcss-selector-parser@6.1.2:
+ dependencies:
+ cssesc: 3.0.0
+ util-deprecate: 1.0.2
+
+ postcss-value-parser@4.2.0: {}
+
postcss@8.5.8:
dependencies:
nanoid: 3.3.11
@@ -9390,12 +9862,12 @@ snapshots:
quansync@0.2.11: {}
+ queue-microtask@1.2.3: {}
+
quick-format-unescaped@4.0.4: {}
radash@12.1.1: {}
- range-parser@1.2.0: {}
-
range-parser@1.2.1: {}
raw-body@2.5.3:
@@ -9412,12 +9884,11 @@ snapshots:
iconv-lite: 0.7.2
unpipe: 1.0.0
- rc@1.2.8:
+ react-dom@18.3.1(react@18.3.1):
dependencies:
- deep-extend: 0.6.0
- ini: 1.3.8
- minimist: 1.2.8
- strip-json-comments: 2.0.1
+ loose-envify: 1.4.0
+ react: 18.3.1
+ scheduler: 0.23.2
react-dom@19.2.4(react@19.2.4):
dependencies:
@@ -9426,8 +9897,30 @@ snapshots:
react-is@18.3.1: {}
+ react-refresh@0.17.0: {}
+
+ react-router-dom@6.30.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
+ dependencies:
+ '@remix-run/router': 1.23.2
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+ react-router: 6.30.3(react@18.3.1)
+
+ react-router@6.30.3(react@18.3.1):
+ dependencies:
+ '@remix-run/router': 1.23.2
+ react: 18.3.1
+
+ react@18.3.1:
+ dependencies:
+ loose-envify: 1.4.0
+
react@19.2.4: {}
+ read-cache@1.0.0:
+ dependencies:
+ pify: 2.3.0
+
readable-stream@3.6.2:
dependencies:
inherits: 2.0.4
@@ -9442,6 +9935,10 @@ snapshots:
process: 0.11.10
string_decoder: 1.3.0
+ readdirp@3.6.0:
+ dependencies:
+ picomatch: 2.3.2
+
readdirp@4.1.2: {}
real-require@0.2.0: {}
@@ -9454,15 +9951,6 @@ snapshots:
reflect-metadata@0.2.2: {}
- registry-auth-token@3.3.2:
- dependencies:
- rc: 1.2.8
- safe-buffer: 5.2.1
-
- registry-url@3.1.0:
- dependencies:
- rc: 1.2.8
-
require-directory@2.1.1: {}
require-from-string@2.0.2: {}
@@ -9477,11 +9965,19 @@ snapshots:
resolve-pkg-maps@1.0.0: {}
+ resolve@1.22.11:
+ dependencies:
+ is-core-module: 2.16.1
+ path-parse: 1.0.7
+ supports-preserve-symlinks-flag: 1.0.0
+
restore-cursor@3.1.0:
dependencies:
onetime: 5.1.2
signal-exit: 3.0.7
+ reusify@1.1.0: {}
+
rolldown@1.0.0-rc.12:
dependencies:
'@oxc-project/types': 0.122.0
@@ -9544,6 +10040,10 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ run-parallel@1.2.0:
+ dependencies:
+ queue-microtask: 1.2.3
+
rxjs@7.8.1:
dependencies:
tslib: 2.8.1
@@ -9558,6 +10058,10 @@ snapshots:
safer-buffer@2.1.2: {}
+ scheduler@0.23.2:
+ dependencies:
+ loose-envify: 1.4.0
+
scheduler@0.27.0: {}
schema-utils@3.3.0:
@@ -9639,16 +10143,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- serve-handler@6.1.7:
- dependencies:
- bytes: 3.0.0
- content-disposition: 0.5.2
- mime-types: 2.1.18
- minimatch: 3.1.5
- path-is-inside: 1.0.2
- path-to-regexp: 3.3.0
- range-parser: 1.2.0
-
serve-static@1.16.3:
dependencies:
encodeurl: 2.0.0
@@ -9667,22 +10161,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- serve@14.2.6:
- dependencies:
- '@zeit/schemas': 2.36.0
- ajv: 8.18.0
- arg: 5.0.2
- boxen: 7.0.0
- chalk: 5.0.1
- chalk-template: 0.4.0
- clipboardy: 3.0.0
- compression: 1.8.1
- is-port-reachable: 4.0.0
- serve-handler: 6.1.7
- update-check: 1.5.4
- transitivePeerDependencies:
- - supports-color
-
set-function-length@1.2.2:
dependencies:
define-data-property: 1.1.4
@@ -9864,8 +10342,6 @@ snapshots:
strip-final-newline@4.0.0: {}
- strip-json-comments@2.0.1: {}
-
strip-json-comments@3.1.1: {}
strip-json-comments@5.0.3: {}
@@ -9896,12 +10372,42 @@ snapshots:
dependencies:
has-flag: 4.0.0
+ supports-preserve-symlinks-flag@1.0.0: {}
+
symbol-observable@4.0.0: {}
synckit@0.11.12:
dependencies:
'@pkgr/core': 0.2.9
+ tailwindcss@3.4.19(tsx@4.21.0):
+ dependencies:
+ '@alloc/quick-lru': 5.2.0
+ arg: 5.0.2
+ chokidar: 3.6.0
+ didyoumean: 1.2.2
+ dlv: 1.1.3
+ fast-glob: 3.3.3
+ glob-parent: 6.0.2
+ is-glob: 4.0.3
+ jiti: 1.21.7
+ lilconfig: 3.1.3
+ micromatch: 4.0.8
+ normalize-path: 3.0.0
+ object-hash: 3.0.0
+ picocolors: 1.1.1
+ postcss: 8.5.8
+ postcss-import: 15.1.0(postcss@8.5.8)
+ postcss-js: 4.1.0(postcss@8.5.8)
+ postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.8)(tsx@4.21.0)
+ postcss-nested: 6.2.0(postcss@8.5.8)
+ postcss-selector-parser: 6.1.2
+ resolve: 1.22.11
+ sucrase: 3.35.1
+ transitivePeerDependencies:
+ - tsx
+ - yaml
+
tapable@2.3.2: {}
terser-webpack-plugin@5.4.0(webpack@5.104.1):
@@ -9960,6 +10466,10 @@ snapshots:
safe-buffer: 5.2.1
typed-array-buffer: 1.0.3
+ to-regex-range@5.0.1:
+ dependencies:
+ is-number: 7.0.0
+
toidentifier@1.0.1: {}
token-types@6.1.2:
@@ -10033,7 +10543,7 @@ snapshots:
tslib@2.8.1: {}
- tsup@8.5.1(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3):
+ tsup@8.5.1(jiti@1.21.7)(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3):
dependencies:
bundle-require: 5.1.0(esbuild@0.27.4)
cac: 6.7.14
@@ -10044,7 +10554,7 @@ snapshots:
fix-dts-default-cjs-exports: 1.0.1
joycon: 3.1.1
picocolors: 1.1.1
- postcss-load-config: 6.0.1(postcss@8.5.8)(tsx@4.21.0)
+ postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.8)(tsx@4.21.0)
resolve-from: 5.0.0
rollup: 4.60.1
source-map: 0.7.6
@@ -10076,8 +10586,6 @@ snapshots:
type-fest@0.21.3: {}
- type-fest@2.19.0: {}
-
type-fest@4.41.0: {}
type-is@1.6.18:
@@ -10179,17 +10687,16 @@ snapshots:
escalade: 3.2.0
picocolors: 1.1.1
- update-check@1.5.4:
- dependencies:
- registry-auth-token: 3.3.2
- registry-url: 3.1.0
-
uri-js@4.4.1:
dependencies:
punycode: 2.3.1
url-join@4.0.1: {}
+ use-sync-external-store@1.6.0(react@18.3.1):
+ dependencies:
+ react: 18.3.1
+
util-deprecate@1.0.2: {}
utils-merge@1.0.1: {}
@@ -10208,16 +10715,15 @@ snapshots:
vary@1.1.2: {}
- vite-node@3.2.4(@types/node@22.19.15)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0):
+ vite-node@3.2.4(@types/node@22.19.15)(lightningcss@1.32.0)(terser@5.46.1):
dependencies:
cac: 6.7.14
debug: 4.4.3
es-module-lexer: 1.7.0
pathe: 2.0.3
- vite: 7.3.1(@types/node@22.19.15)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)
+ vite: 5.4.21(@types/node@22.19.15)(lightningcss@1.32.0)(terser@5.46.1)
transitivePeerDependencies:
- '@types/node'
- - jiti
- less
- lightningcss
- sass
@@ -10226,25 +10732,30 @@ snapshots:
- sugarss
- supports-color
- terser
- - tsx
- - yaml
- vite@7.3.1(@types/node@22.19.15)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0):
+ vite@5.4.21(@types/node@22.19.15)(lightningcss@1.32.0)(terser@5.46.1):
dependencies:
- esbuild: 0.27.4
- fdir: 6.5.0(picomatch@4.0.4)
- picomatch: 4.0.4
+ esbuild: 0.21.5
postcss: 8.5.8
rollup: 4.60.1
- tinyglobby: 0.2.15
optionalDependencies:
'@types/node': 22.19.15
fsevents: 2.3.3
lightningcss: 1.32.0
terser: 5.46.1
- tsx: 4.21.0
- vite@8.0.3(@types/node@25.5.0)(esbuild@0.27.4)(terser@5.46.1)(tsx@4.21.0):
+ vite@5.4.21(@types/node@25.5.0)(lightningcss@1.32.0)(terser@5.46.1):
+ dependencies:
+ esbuild: 0.21.5
+ postcss: 8.5.8
+ rollup: 4.60.1
+ optionalDependencies:
+ '@types/node': 25.5.0
+ fsevents: 2.3.3
+ lightningcss: 1.32.0
+ terser: 5.46.1
+
+ vite@8.0.3(@types/node@25.5.0)(esbuild@0.27.4)(jiti@1.21.7)(terser@5.46.1)(tsx@4.21.0):
dependencies:
lightningcss: 1.32.0
picomatch: 4.0.4
@@ -10255,14 +10766,15 @@ snapshots:
'@types/node': 25.5.0
esbuild: 0.27.4
fsevents: 2.3.3
+ jiti: 1.21.7
terser: 5.46.1
tsx: 4.21.0
- vitest@3.2.4(@types/node@22.19.15)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0):
+ vitest@3.2.4(@types/node@22.19.15)(lightningcss@1.32.0)(terser@5.46.1):
dependencies:
'@types/chai': 5.2.3
'@vitest/expect': 3.2.4
- '@vitest/mocker': 3.2.4(vite@7.3.1(@types/node@22.19.15)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0))
+ '@vitest/mocker': 3.2.4(vite@5.4.21(@types/node@22.19.15)(lightningcss@1.32.0)(terser@5.46.1))
'@vitest/pretty-format': 3.2.4
'@vitest/runner': 3.2.4
'@vitest/snapshot': 3.2.4
@@ -10280,13 +10792,12 @@ snapshots:
tinyglobby: 0.2.15
tinypool: 1.1.1
tinyrainbow: 2.0.0
- vite: 7.3.1(@types/node@22.19.15)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)
- vite-node: 3.2.4(@types/node@22.19.15)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)
+ vite: 5.4.21(@types/node@22.19.15)(lightningcss@1.32.0)(terser@5.46.1)
+ vite-node: 3.2.4(@types/node@22.19.15)(lightningcss@1.32.0)(terser@5.46.1)
why-is-node-running: 2.3.0
optionalDependencies:
'@types/node': 22.19.15
transitivePeerDependencies:
- - jiti
- less
- lightningcss
- msw
@@ -10296,8 +10807,6 @@ snapshots:
- sugarss
- supports-color
- terser
- - tsx
- - yaml
walker@1.0.8:
dependencies:
@@ -10374,10 +10883,6 @@ snapshots:
siginfo: 2.0.0
stackback: 0.0.2
- widest-line@4.0.1:
- dependencies:
- string-width: 5.1.2
-
word-wrap@1.2.5: {}
wordwrap@1.0.0: {}
@@ -10456,3 +10961,10 @@ snapshots:
zod@3.25.76: {}
zod@4.3.6: {}
+
+ zustand@4.5.7(@types/react@18.3.28)(react@18.3.1):
+ dependencies:
+ use-sync-external-store: 1.6.0(react@18.3.1)
+ optionalDependencies:
+ '@types/react': 18.3.28
+ react: 18.3.1