From 9e421d6ad897e274d3842a6fa4fcfe5c70b94505 Mon Sep 17 00:00:00 2001 From: arse09 Date: Mon, 23 Mar 2026 21:58:37 +0100 Subject: [PATCH 1/6] refactor(storage): move filesystem paths and ensure_dirs into storage module --- launcher/src-tauri/src/commands.rs | 4 ++- launcher/src-tauri/src/downloader.rs | 48 ++++++++----------------- launcher/src-tauri/src/main.rs | 3 ++ launcher/src-tauri/src/storage.rs | 53 ++++++++++++++++++++++++++++ 4 files changed, 73 insertions(+), 35 deletions(-) create mode 100644 launcher/src-tauri/src/storage.rs diff --git a/launcher/src-tauri/src/commands.rs b/launcher/src-tauri/src/commands.rs index 0a2a609f..09103df6 100644 --- a/launcher/src-tauri/src/commands.rs +++ b/launcher/src-tauri/src/commands.rs @@ -1,3 +1,5 @@ +use crate::storage; + use serde::{Deserialize, Serialize}; use std::collections::VecDeque; use std::process::Stdio; @@ -250,7 +252,7 @@ pub async fn launch_game( debug_enabled: Option, ) -> Result { let exe = find_client_binary()?; - let assets = crate::downloader::assets_dir(); + let assets = storage::assets_dir(); let account = uuid.as_deref().and_then(crate::auth::try_restore); diff --git a/launcher/src-tauri/src/downloader.rs b/launcher/src-tauri/src/downloader.rs index 379d96d1..56953d08 100644 --- a/launcher/src-tauri/src/downloader.rs +++ b/launcher/src-tauri/src/downloader.rs @@ -1,5 +1,7 @@ +use crate::storage; + use serde::Deserialize; -use std::path::{Path, PathBuf}; +use std::path::Path; use tauri::{AppHandle, Emitter}; const VERSION_MANIFEST_URL: &str = @@ -59,41 +61,20 @@ pub struct DownloadProgress { pub status: String, } -fn data_dir() -> PathBuf { - directories::ProjectDirs::from("", "", ".pomc") - .map(|d| d.data_dir().to_path_buf()) - .unwrap_or_else(|| PathBuf::from(".pomc")) -} - -pub fn assets_dir() -> PathBuf { - data_dir().join("assets") -} - -fn indexes_dir() -> PathBuf { - assets_dir().join("indexes") -} - -fn objects_dir() -> PathBuf { - assets_dir().join("objects") -} - -fn versions_dir() -> PathBuf { - data_dir().join("versions") -} - pub fn needs_download(version: &str) -> bool { - let no_index = !indexes_dir().join(format!("{version}.json")).exists(); - let no_jar = !assets_dir().join("jar").join(".extracted").exists(); + let no_index = !storage::indexes_dir() + .join(format!("{version}.json")) + .exists(); + let no_jar = !storage::assets_dir() + .join("jar") + .join(".extracted") + .exists(); no_index || no_jar } pub async fn download(app: &AppHandle, version: &str) -> Result<(), String> { - let _ = std::fs::create_dir_all(indexes_dir()); - let _ = std::fs::create_dir_all(objects_dir()); - let _ = std::fs::create_dir_all(versions_dir()); - let client = reqwest::Client::new(); - let index_path = indexes_dir().join(format!("{version}.json")); + let index_path = storage::indexes_dir().join(format!("{version}.json")); let (asset_index, version_json) = if index_path.exists() { let content = std::fs::read_to_string(&index_path).map_err(|e| e.to_string())?; @@ -154,7 +135,7 @@ async fn download_objects( let total = index.objects.len() as u32; let mut downloaded = 0u32; let mut skipped = 0u32; - let objects = objects_dir(); + let objects = storage::objects_dir(); for (name, obj) in &index.objects { let prefix = &obj.hash[..2]; @@ -202,7 +183,7 @@ async fn download_jar( version: &str, cached_vj: Option<&VersionJson>, ) -> Result<(), String> { - let jar_assets = assets_dir().join("jar"); + let jar_assets = storage::assets_dir().join("jar"); let marker = jar_assets.join(".extracted"); if marker.exists() { return Ok(()); @@ -238,7 +219,7 @@ async fn download_jar( &fetched }; - let jar_path = versions_dir().join(format!("{version}.jar")); + let jar_path = storage::versions_dir().join(format!("{version}.jar")); if !jar_path.exists() || std::fs::metadata(&jar_path).map(|m| m.len()).unwrap_or(0) != dl.size { emit_progress(app, 0, 1, "Downloading client JAR..."); let bytes = client @@ -255,7 +236,6 @@ async fn download_jar( log::warn!("JAR hash mismatch: expected {}, got {actual_hash}", dl.sha1); } - let _ = std::fs::create_dir_all(versions_dir()); std::fs::write(&jar_path, &bytes).map_err(|e| e.to_string())?; } diff --git a/launcher/src-tauri/src/main.rs b/launcher/src-tauri/src/main.rs index b01f5b0e..196b78c7 100644 --- a/launcher/src-tauri/src/main.rs +++ b/launcher/src-tauri/src/main.rs @@ -6,6 +6,8 @@ use tokio::sync::Mutex; mod auth; mod commands; mod downloader; +mod storage; + use std::collections::VecDeque; #[derive(Default)] @@ -21,6 +23,7 @@ fn main() { tauri::Builder::default() .setup(|app| { + storage::ensure_dirs(); app.manage(Mutex::new(AppState::default())); Ok(()) }) diff --git a/launcher/src-tauri/src/storage.rs b/launcher/src-tauri/src/storage.rs new file mode 100644 index 00000000..c70c0a41 --- /dev/null +++ b/launcher/src-tauri/src/storage.rs @@ -0,0 +1,53 @@ +use std::path::{Path, PathBuf}; + +fn ensure_file(path: &Path, default: &str) { + if !path.exists() { + let _ = std::fs::write(path, default); + } +} + +pub fn ensure_dirs() { + let _ = std::fs::create_dir_all(assets_dir()); + let _ = std::fs::create_dir_all(versions_dir()); + let _ = std::fs::create_dir_all(installations_dir()); + + let _ = std::fs::create_dir_all(indexes_dir()); + let _ = std::fs::create_dir_all(objects_dir()); + + ensure_file(&settings_file(), "{}"); + ensure_file(&accounts_file(), "[]"); + ensure_file(&installations_file(), "[]"); +} + +pub fn data_dir() -> PathBuf { + directories::ProjectDirs::from("", "", ".pomc") + .map(|d| d.data_dir().to_path_buf()) + .unwrap_or_else(|| PathBuf::from(".pomc")) +} + +pub fn assets_dir() -> PathBuf { + data_dir().join("assets") +} +pub fn versions_dir() -> PathBuf { + data_dir().join("versions") +} +pub fn installations_dir() -> PathBuf { + data_dir().join("installations") +} + +pub fn indexes_dir() -> PathBuf { + assets_dir().join("indexes") +} +pub fn objects_dir() -> PathBuf { + assets_dir().join("objects") +} + +pub fn settings_file() -> PathBuf { + data_dir().join("settings.json") +} +pub fn accounts_file() -> PathBuf { + data_dir().join("accounts.json") +} +pub fn installations_file() -> PathBuf { + data_dir().join("installations.json") +} From 57312304d92ccbeba0870e2364dbbc1783305cb4 Mon Sep 17 00:00:00 2001 From: arse09 Date: Tue, 24 Mar 2026 02:02:40 +0100 Subject: [PATCH 2/6] feat(storage): settings are now loaded from file --- launcher/src-tauri/src/commands.rs | 6 +++ launcher/src-tauri/src/config.rs | 65 ++++++++++++++++++++++++++++++ launcher/src-tauri/src/main.rs | 4 +- launcher/src-tauri/src/storage.rs | 1 + launcher/src/App.tsx | 3 +- launcher/src/lib/state.ts | 29 +++++++++++-- launcher/src/lib/types.ts | 6 +++ launcher/src/pages/Settings.tsx | 15 ++++--- 8 files changed, 116 insertions(+), 13 deletions(-) create mode 100644 launcher/src-tauri/src/config.rs diff --git a/launcher/src-tauri/src/commands.rs b/launcher/src-tauri/src/commands.rs index 09103df6..e1210887 100644 --- a/launcher/src-tauri/src/commands.rs +++ b/launcher/src-tauri/src/commands.rs @@ -1,5 +1,6 @@ use crate::storage; +use crate::config::LauncherSettings; use serde::{Deserialize, Serialize}; use std::collections::VecDeque; use std::process::Stdio; @@ -413,3 +414,8 @@ fn find_client_binary() -> Result { Err("POMC client not found. It will be bundled in future releases.".into()) } + +#[tauri::command] +pub async fn load_launcher_settings() -> LauncherSettings{ + LauncherSettings::load() +} diff --git a/launcher/src-tauri/src/config.rs b/launcher/src-tauri/src/config.rs new file mode 100644 index 00000000..648df822 --- /dev/null +++ b/launcher/src-tauri/src/config.rs @@ -0,0 +1,65 @@ +use crate::storage; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct LauncherSettings { + pub language: String, + pub keep_launcher_open: bool, + pub launch_with_console: bool, +} + +impl Default for LauncherSettings { + fn default() -> Self { + LauncherSettings { + language: "French".into(), + keep_launcher_open: false, + launch_with_console: true, + } + } +} + +impl LauncherSettings { + pub fn save(&self) -> Result<(), String> { + let path = storage::settings_file(); + let json = serde_json::to_string_pretty(self).map_err(|e| e.to_string())?; + std::fs::write(path, json).map_err(|e| e.to_string())?; + Ok(()) + } + + pub fn load() -> Self { + let path = storage::settings_file(); + + match std::fs::read_to_string(&path) { + Ok(content) => match serde_json::from_str::(&content) { + Ok(cfg) => return cfg, + Err(err) => { + log::warn!("Settings file invalid ({}), using defaults", err); + } + }, + Err(err) => { + log::info!( + "Settings file not found or unreadable ({}), using defaults", + err + ); + } + } + + LauncherSettings::default() + } + + pub fn set_language(&mut self, language: String) -> Result<(), String> { + self.language = language; + self.save() + } + + pub fn set_keep_launcher_open(&mut self, keep: bool) -> Result<(), String> { + self.keep_launcher_open = keep; + self.save() + } + + pub fn set_launch_with_console(&mut self, launch_with_console: bool) -> Result<(), String> { + self.launch_with_console = launch_with_console; + self.save() + } +} diff --git a/launcher/src-tauri/src/main.rs b/launcher/src-tauri/src/main.rs index 196b78c7..6bebd9dc 100644 --- a/launcher/src-tauri/src/main.rs +++ b/launcher/src-tauri/src/main.rs @@ -5,6 +5,7 @@ use tokio::sync::Mutex; mod auth; mod commands; +mod config; mod downloader; mod storage; @@ -40,7 +41,8 @@ fn main() { commands::get_patch_notes, commands::get_patch_content, commands::launch_game, - commands::get_client_logs + commands::get_client_logs, + commands::load_launcher_settings, ]) .run(tauri::generate_context!()) .expect("failed to run POMC launcher"); diff --git a/launcher/src-tauri/src/storage.rs b/launcher/src-tauri/src/storage.rs index c70c0a41..6c4fbbaa 100644 --- a/launcher/src-tauri/src/storage.rs +++ b/launcher/src-tauri/src/storage.rs @@ -1,3 +1,4 @@ +use serde::Serialize; use std::path::{Path, PathBuf}; fn ensure_file(path: &Path, default: &str) { diff --git a/launcher/src/App.tsx b/launcher/src/App.tsx index 7e6fb77f..ca89ed90 100644 --- a/launcher/src/App.tsx +++ b/launcher/src/App.tsx @@ -8,7 +8,7 @@ import { import { AuthAccount, GameVersion, PatchNote } from "./lib/types"; import Homepage from "./pages/Home"; import InstallationsPage from "./pages/Installations"; -import { useAppStateContext } from "./lib/state"; +import {useAppStateContext} from "./lib/state"; import Navbar from "./components/Navbar"; import ModsPage from "./pages/Mods"; import ServersPage from "./pages/Servers"; @@ -27,7 +27,6 @@ function App() { setActiveIndex, setAccountDropdownOpen, server, - setInstallations, editingInstall, setEditingInstall, diff --git a/launcher/src/lib/state.ts b/launcher/src/lib/state.ts index 0fa9ee3a..469cd6b1 100644 --- a/launcher/src/lib/state.ts +++ b/launcher/src/lib/state.ts @@ -1,6 +1,22 @@ -import { createElement, createContext, useContext, useState, ReactNode } from "react"; -import { Page, AuthAccount, Installation, GameVersion, PatchNote } from "./types"; +import {createElement, createContext, useContext, useState, ReactNode, useEffect} from "react"; +import { Page, AuthAccount, Installation, GameVersion, PatchNote, LauncherSettings } from "./types"; +import {invoke} from "@tauri-apps/api/core"; +const useLauncherSettings = () => { + const [launcherSettings, setLauncherSettings] = useState({ + language: "English", + keepLauncherOpen: true, + launchWithConsole: false, + }); + + useEffect(() => { + invoke("load_launcher_settings") + .then((settings) => setLauncherSettings(settings)) + .catch(console.error); + }, []); + + return launcherSettings; +} const useAppState = () => { const [page, setPage] = useState("home"); const [accounts, setAccounts] = useState([]); @@ -45,6 +61,9 @@ const useAppState = () => { body: string; } | null>(null); + const launcherSettings= useLauncherSettings(); + console.log(launcherSettings); + return { account, page, @@ -92,6 +111,8 @@ const useAppState = () => { selectedNote, setSelectedNote, username, + + launcherSettings, }; }; @@ -99,9 +120,9 @@ type AppState = ReturnType; const AppStateContext = createContext(null); -export function AppStateProvider({ children }: { children: ReactNode }) { +export function AppStateProvider({children}: { children: ReactNode }) { const state = useAppState(); - return createElement(AppStateContext.Provider, { value: state }, children); + return createElement(AppStateContext.Provider, {value: state}, children); } export function useAppStateContext(): AppState { diff --git a/launcher/src/lib/types.ts b/launcher/src/lib/types.ts index 136988e4..e5f8b7cf 100644 --- a/launcher/src/lib/types.ts +++ b/launcher/src/lib/types.ts @@ -31,3 +31,9 @@ export interface PatchNote { entry_type: string; content_path: string; } + +export interface LauncherSettings { + language: string; + keepLauncherOpen: boolean; + launchWithConsole: boolean; +} \ No newline at end of file diff --git a/launcher/src/pages/Settings.tsx b/launcher/src/pages/Settings.tsx index 8293ea27..bfc48323 100644 --- a/launcher/src/pages/Settings.tsx +++ b/launcher/src/pages/Settings.tsx @@ -5,9 +5,12 @@ export default function SettingsPage() { keepOpen, setKeepOpen, useConsole, - setUseConsole + setUseConsole, + launcherSettings, } = useAppStateContext(); + console.log("launchWithConsole:", launcherSettings.launchWithConsole); + return (

SETTINGS

@@ -24,7 +27,7 @@ export default function SettingsPage() {
@@ -40,8 +43,8 @@ export default function SettingsPage() {
@@ -59,8 +62,8 @@ export default function SettingsPage() {
From ab8bab4104485b4dbc11adf6461ca7edff28ae8c Mon Sep 17 00:00:00 2001 From: arse09 Date: Tue, 24 Mar 2026 03:31:11 +0100 Subject: [PATCH 3/6] feat(storage): settings are now also stored to file --- launcher/pnpm-lock.yaml | 1599 ++++++++++------- launcher/src-tauri/src/commands.rs | 19 +- launcher/src-tauri/src/main.rs | 5 +- .../src-tauri/src/{config.rs => settings.rs} | 37 +- launcher/src-tauri/src/storage.rs | 1 - launcher/src/App.tsx | 92 +- launcher/src/Router.tsx | 2 +- launcher/src/components/Console.tsx | 49 +- launcher/src/components/Navbar.tsx | 37 +- launcher/src/components/Titlebar.tsx | 13 +- launcher/src/lib/state.ts | 56 +- launcher/src/lib/types.ts | 2 +- launcher/src/main.tsx | 2 +- launcher/src/pages/Friends.tsx | 6 +- launcher/src/pages/Home.tsx | 37 +- launcher/src/pages/Installations.tsx | 4 +- launcher/src/pages/Mods.tsx | 94 +- launcher/src/pages/News.tsx | 38 +- launcher/src/pages/Servers.tsx | 52 +- launcher/src/pages/Settings.tsx | 46 +- 20 files changed, 1290 insertions(+), 901 deletions(-) rename launcher/src-tauri/src/{config.rs => settings.rs} (57%) diff --git a/launcher/pnpm-lock.yaml b/launcher/pnpm-lock.yaml index b7219a81..b806a041 100644 --- a/launcher/pnpm-lock.yaml +++ b/launcher/pnpm-lock.yaml @@ -1,20 +1,19 @@ -lockfileVersion: '9.0' +lockfileVersion: "9.0" settings: autoInstallPeers: true excludeLinksFromLockfile: false importers: - .: dependencies: - '@tauri-apps/api': + "@tauri-apps/api": specifier: ^2 version: 2.10.1 - '@tauri-apps/plugin-dialog': + "@tauri-apps/plugin-dialog": specifier: ^2 version: 2.6.0 - '@tauri-apps/plugin-shell': + "@tauri-apps/plugin-shell": specifier: ^2 version: 2.3.5 react: @@ -27,16 +26,16 @@ importers: specifier: ^5.6.0 version: 5.6.0(react@19.2.4) devDependencies: - '@tauri-apps/cli': + "@tauri-apps/cli": specifier: ^2 version: 2.10.1 - '@types/react': + "@types/react": specifier: ^19 version: 19.2.14 - '@types/react-dom': + "@types/react-dom": specifier: ^19 version: 19.2.3(@types/react@19.2.14) - '@vitejs/plugin-react': + "@vitejs/plugin-react": specifier: ^5 version: 5.2.0(vite@6.4.1) typescript: @@ -47,542 +46,868 @@ importers: version: 6.4.1 packages: - - '@babel/code-frame@7.29.0': - resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} - engines: {node: '>=6.9.0'} - - '@babel/compat-data@7.29.0': - resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} - engines: {node: '>=6.9.0'} - - '@babel/core@7.29.0': - resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} - engines: {node: '>=6.9.0'} - - '@babel/generator@7.29.1': - resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-compilation-targets@7.28.6': - resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-globals@7.28.0': - resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-imports@7.28.6': - resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-transforms@7.28.6': - resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} - engines: {node: '>=6.9.0'} + "@babel/code-frame@7.29.0": + resolution: + { + integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==, + } + engines: { node: ">=6.9.0" } + + "@babel/compat-data@7.29.0": + resolution: + { + integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==, + } + engines: { node: ">=6.9.0" } + + "@babel/core@7.29.0": + resolution: + { + integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==, + } + engines: { node: ">=6.9.0" } + + "@babel/generator@7.29.1": + resolution: + { + integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-compilation-targets@7.28.6": + resolution: + { + integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-globals@7.28.0": + resolution: + { + integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-module-imports@7.28.6": + resolution: + { + integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-module-transforms@7.28.6": + resolution: + { + integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==, + } + engines: { node: ">=6.9.0" } peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-plugin-utils@7.28.6': - resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} - engines: {node: '>=6.9.0'} - - '@babel/helper-string-parser@7.27.1': - resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.28.5': - resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-option@7.27.1': - resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} - engines: {node: '>=6.9.0'} - - '@babel/helpers@7.29.2': - resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.29.2': - resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} - engines: {node: '>=6.0.0'} + "@babel/core": ^7.0.0 + + "@babel/helper-plugin-utils@7.28.6": + resolution: + { + integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-string-parser@7.27.1": + resolution: + { + integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-validator-identifier@7.28.5": + resolution: + { + integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-validator-option@7.27.1": + resolution: + { + integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==, + } + engines: { node: ">=6.9.0" } + + "@babel/helpers@7.29.2": + resolution: + { + integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==, + } + engines: { node: ">=6.9.0" } + + "@babel/parser@7.29.2": + resolution: + { + integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==, + } + engines: { node: ">=6.0.0" } hasBin: true - '@babel/plugin-transform-react-jsx-self@7.27.1': - resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} - engines: {node: '>=6.9.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'} + "@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/template@7.28.6': - resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} - engines: {node: '>=6.9.0'} - - '@babel/traverse@7.29.0': - resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.29.0': - resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} - engines: {node: '>=6.9.0'} - - '@esbuild/aix-ppc64@0.25.12': - resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} - engines: {node: '>=18'} + "@babel/core": ^7.0.0-0 + + "@babel/template@7.28.6": + resolution: + { + integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==, + } + engines: { node: ">=6.9.0" } + + "@babel/traverse@7.29.0": + resolution: + { + integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==, + } + engines: { node: ">=6.9.0" } + + "@babel/types@7.29.0": + resolution: + { + integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==, + } + engines: { node: ">=6.9.0" } + + "@esbuild/aix-ppc64@0.25.12": + resolution: + { + integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==, + } + engines: { node: ">=18" } cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.25.12': - resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} - engines: {node: '>=18'} + "@esbuild/android-arm64@0.25.12": + resolution: + { + integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==, + } + engines: { node: ">=18" } cpu: [arm64] os: [android] - '@esbuild/android-arm@0.25.12': - resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} - engines: {node: '>=18'} + "@esbuild/android-arm@0.25.12": + resolution: + { + integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==, + } + engines: { node: ">=18" } cpu: [arm] os: [android] - '@esbuild/android-x64@0.25.12': - resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} - engines: {node: '>=18'} + "@esbuild/android-x64@0.25.12": + resolution: + { + integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==, + } + engines: { node: ">=18" } cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.25.12': - resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} - engines: {node: '>=18'} + "@esbuild/darwin-arm64@0.25.12": + resolution: + { + integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==, + } + engines: { node: ">=18" } cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.25.12': - resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} - engines: {node: '>=18'} + "@esbuild/darwin-x64@0.25.12": + resolution: + { + integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==, + } + engines: { node: ">=18" } cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.25.12': - resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} - engines: {node: '>=18'} + "@esbuild/freebsd-arm64@0.25.12": + resolution: + { + integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==, + } + engines: { node: ">=18" } cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.12': - resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} - engines: {node: '>=18'} + "@esbuild/freebsd-x64@0.25.12": + resolution: + { + integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==, + } + engines: { node: ">=18" } cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.25.12': - resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} - engines: {node: '>=18'} + "@esbuild/linux-arm64@0.25.12": + resolution: + { + integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==, + } + engines: { node: ">=18" } cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.25.12': - resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} - engines: {node: '>=18'} + "@esbuild/linux-arm@0.25.12": + resolution: + { + integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==, + } + engines: { node: ">=18" } cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.25.12': - resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} - engines: {node: '>=18'} + "@esbuild/linux-ia32@0.25.12": + resolution: + { + integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==, + } + engines: { node: ">=18" } cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.25.12': - resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} - engines: {node: '>=18'} + "@esbuild/linux-loong64@0.25.12": + resolution: + { + integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==, + } + engines: { node: ">=18" } cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.25.12': - resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} - engines: {node: '>=18'} + "@esbuild/linux-mips64el@0.25.12": + resolution: + { + integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==, + } + engines: { node: ">=18" } cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.25.12': - resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} - engines: {node: '>=18'} + "@esbuild/linux-ppc64@0.25.12": + resolution: + { + integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==, + } + engines: { node: ">=18" } cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.25.12': - resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} - engines: {node: '>=18'} + "@esbuild/linux-riscv64@0.25.12": + resolution: + { + integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==, + } + engines: { node: ">=18" } cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.25.12': - resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} - engines: {node: '>=18'} + "@esbuild/linux-s390x@0.25.12": + resolution: + { + integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==, + } + engines: { node: ">=18" } cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.25.12': - resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} - engines: {node: '>=18'} + "@esbuild/linux-x64@0.25.12": + resolution: + { + integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==, + } + engines: { node: ">=18" } cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.12': - resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} - engines: {node: '>=18'} + "@esbuild/netbsd-arm64@0.25.12": + resolution: + { + integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==, + } + engines: { node: ">=18" } cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.12': - resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} - engines: {node: '>=18'} + "@esbuild/netbsd-x64@0.25.12": + resolution: + { + integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==, + } + engines: { node: ">=18" } cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.12': - resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} - engines: {node: '>=18'} + "@esbuild/openbsd-arm64@0.25.12": + resolution: + { + integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==, + } + engines: { node: ">=18" } cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.12': - resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} - engines: {node: '>=18'} + "@esbuild/openbsd-x64@0.25.12": + resolution: + { + integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==, + } + engines: { node: ">=18" } cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.25.12': - resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} - engines: {node: '>=18'} + "@esbuild/openharmony-arm64@0.25.12": + resolution: + { + integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==, + } + engines: { node: ">=18" } cpu: [arm64] os: [openharmony] - '@esbuild/sunos-x64@0.25.12': - resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} - engines: {node: '>=18'} + "@esbuild/sunos-x64@0.25.12": + resolution: + { + integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==, + } + engines: { node: ">=18" } cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.25.12': - resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} - engines: {node: '>=18'} + "@esbuild/win32-arm64@0.25.12": + resolution: + { + integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==, + } + engines: { node: ">=18" } cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.25.12': - resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} - engines: {node: '>=18'} + "@esbuild/win32-ia32@0.25.12": + resolution: + { + integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==, + } + engines: { node: ">=18" } cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.25.12': - resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} - engines: {node: '>=18'} + "@esbuild/win32-x64@0.25.12": + resolution: + { + integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==, + } + engines: { node: ">=18" } cpu: [x64] os: [win32] - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - - '@jridgewell/remapping@2.3.5': - resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - - '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - - '@rolldown/pluginutils@1.0.0-rc.3': - resolution: {integrity: sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==} - - '@rollup/rollup-android-arm-eabi@4.59.0': - resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} + "@jridgewell/gen-mapping@0.3.13": + resolution: + { + integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==, + } + + "@jridgewell/remapping@2.3.5": + resolution: + { + integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==, + } + + "@jridgewell/resolve-uri@3.1.2": + resolution: + { + integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==, + } + engines: { node: ">=6.0.0" } + + "@jridgewell/sourcemap-codec@1.5.5": + resolution: + { + integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==, + } + + "@jridgewell/trace-mapping@0.3.31": + resolution: + { + integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==, + } + + "@rolldown/pluginutils@1.0.0-rc.3": + resolution: + { + integrity: sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==, + } + + "@rollup/rollup-android-arm-eabi@4.59.0": + resolution: + { + integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==, + } cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.59.0': - resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==} + "@rollup/rollup-android-arm64@4.59.0": + resolution: + { + integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==, + } cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.59.0': - resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==} + "@rollup/rollup-darwin-arm64@4.59.0": + resolution: + { + integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==, + } cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.59.0': - resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==} + "@rollup/rollup-darwin-x64@4.59.0": + resolution: + { + integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==, + } cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.59.0': - resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==} + "@rollup/rollup-freebsd-arm64@4.59.0": + resolution: + { + integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==, + } cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.59.0': - resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==} + "@rollup/rollup-freebsd-x64@4.59.0": + resolution: + { + integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==, + } cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.59.0': - resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} + "@rollup/rollup-linux-arm-gnueabihf@4.59.0": + resolution: + { + integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==, + } cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.59.0': - resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} + "@rollup/rollup-linux-arm-musleabihf@4.59.0": + resolution: + { + integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==, + } cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.59.0': - resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} + "@rollup/rollup-linux-arm64-gnu@4.59.0": + resolution: + { + integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==, + } cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.59.0': - resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} + "@rollup/rollup-linux-arm64-musl@4.59.0": + resolution: + { + integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==, + } cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loong64-gnu@4.59.0': - resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} + "@rollup/rollup-linux-loong64-gnu@4.59.0": + resolution: + { + integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==, + } cpu: [loong64] os: [linux] - '@rollup/rollup-linux-loong64-musl@4.59.0': - resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} + "@rollup/rollup-linux-loong64-musl@4.59.0": + resolution: + { + integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==, + } cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.59.0': - resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} + "@rollup/rollup-linux-ppc64-gnu@4.59.0": + resolution: + { + integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==, + } cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-ppc64-musl@4.59.0': - resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} + "@rollup/rollup-linux-ppc64-musl@4.59.0": + resolution: + { + integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==, + } cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.59.0': - resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} + "@rollup/rollup-linux-riscv64-gnu@4.59.0": + resolution: + { + integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==, + } cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.59.0': - resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} + "@rollup/rollup-linux-riscv64-musl@4.59.0": + resolution: + { + integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==, + } cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.59.0': - resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} + "@rollup/rollup-linux-s390x-gnu@4.59.0": + resolution: + { + integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==, + } cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.59.0': - resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} + "@rollup/rollup-linux-x64-gnu@4.59.0": + resolution: + { + integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==, + } cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.59.0': - resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} + "@rollup/rollup-linux-x64-musl@4.59.0": + resolution: + { + integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==, + } cpu: [x64] os: [linux] - '@rollup/rollup-openbsd-x64@4.59.0': - resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} + "@rollup/rollup-openbsd-x64@4.59.0": + resolution: + { + integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==, + } cpu: [x64] os: [openbsd] - '@rollup/rollup-openharmony-arm64@4.59.0': - resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==} + "@rollup/rollup-openharmony-arm64@4.59.0": + resolution: + { + integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==, + } cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.59.0': - resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==} + "@rollup/rollup-win32-arm64-msvc@4.59.0": + resolution: + { + integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==, + } cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.59.0': - resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==} + "@rollup/rollup-win32-ia32-msvc@4.59.0": + resolution: + { + integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==, + } cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.59.0': - resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==} + "@rollup/rollup-win32-x64-gnu@4.59.0": + resolution: + { + integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==, + } cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.59.0': - resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==} + "@rollup/rollup-win32-x64-msvc@4.59.0": + resolution: + { + integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==, + } cpu: [x64] os: [win32] - '@tauri-apps/api@2.10.1': - resolution: {integrity: sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw==} - - '@tauri-apps/cli-darwin-arm64@2.10.1': - resolution: {integrity: sha512-Z2OjCXiZ+fbYZy7PmP3WRnOpM9+Fy+oonKDEmUE6MwN4IGaYqgceTjwHucc/kEEYZos5GICve35f7ZiizgqEnQ==} - engines: {node: '>= 10'} + "@tauri-apps/api@2.10.1": + resolution: + { + integrity: sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw==, + } + + "@tauri-apps/cli-darwin-arm64@2.10.1": + resolution: + { + integrity: sha512-Z2OjCXiZ+fbYZy7PmP3WRnOpM9+Fy+oonKDEmUE6MwN4IGaYqgceTjwHucc/kEEYZos5GICve35f7ZiizgqEnQ==, + } + engines: { node: ">= 10" } cpu: [arm64] os: [darwin] - '@tauri-apps/cli-darwin-x64@2.10.1': - resolution: {integrity: sha512-V/irQVvjPMGOTQqNj55PnQPVuH4VJP8vZCN7ajnj+ZS8Kom1tEM2hR3qbbIRoS3dBKs5mbG8yg1WC+97dq17Pw==} - engines: {node: '>= 10'} + "@tauri-apps/cli-darwin-x64@2.10.1": + resolution: + { + integrity: sha512-V/irQVvjPMGOTQqNj55PnQPVuH4VJP8vZCN7ajnj+ZS8Kom1tEM2hR3qbbIRoS3dBKs5mbG8yg1WC+97dq17Pw==, + } + engines: { node: ">= 10" } cpu: [x64] os: [darwin] - '@tauri-apps/cli-linux-arm-gnueabihf@2.10.1': - resolution: {integrity: sha512-Hyzwsb4VnCWKGfTw+wSt15Z2pLw2f0JdFBfq2vHBOBhvg7oi6uhKiF87hmbXOBXUZaGkyRDkCHsdzJcIfoJC2w==} - engines: {node: '>= 10'} + "@tauri-apps/cli-linux-arm-gnueabihf@2.10.1": + resolution: + { + integrity: sha512-Hyzwsb4VnCWKGfTw+wSt15Z2pLw2f0JdFBfq2vHBOBhvg7oi6uhKiF87hmbXOBXUZaGkyRDkCHsdzJcIfoJC2w==, + } + engines: { node: ">= 10" } cpu: [arm] os: [linux] - '@tauri-apps/cli-linux-arm64-gnu@2.10.1': - resolution: {integrity: sha512-OyOYs2t5GkBIvyWjA1+h4CZxTcdz1OZPCWAPz5DYEfB0cnWHERTnQ/SLayQzncrT0kwRoSfSz9KxenkyJoTelA==} - engines: {node: '>= 10'} + "@tauri-apps/cli-linux-arm64-gnu@2.10.1": + resolution: + { + integrity: sha512-OyOYs2t5GkBIvyWjA1+h4CZxTcdz1OZPCWAPz5DYEfB0cnWHERTnQ/SLayQzncrT0kwRoSfSz9KxenkyJoTelA==, + } + engines: { node: ">= 10" } cpu: [arm64] os: [linux] - '@tauri-apps/cli-linux-arm64-musl@2.10.1': - resolution: {integrity: sha512-MIj78PDDGjkg3NqGptDOGgfXks7SYJwhiMh8SBoZS+vfdz7yP5jN18bNaLnDhsVIPARcAhE1TlsZe/8Yxo2zqg==} - engines: {node: '>= 10'} + "@tauri-apps/cli-linux-arm64-musl@2.10.1": + resolution: + { + integrity: sha512-MIj78PDDGjkg3NqGptDOGgfXks7SYJwhiMh8SBoZS+vfdz7yP5jN18bNaLnDhsVIPARcAhE1TlsZe/8Yxo2zqg==, + } + engines: { node: ">= 10" } cpu: [arm64] os: [linux] - '@tauri-apps/cli-linux-riscv64-gnu@2.10.1': - resolution: {integrity: sha512-X0lvOVUg8PCVaoEtEAnpxmnkwlE1gcMDTqfhbefICKDnOTJ5Est3qL0SrWxizDackIOKBcvtpejrSiVpuJI1kw==} - engines: {node: '>= 10'} + "@tauri-apps/cli-linux-riscv64-gnu@2.10.1": + resolution: + { + integrity: sha512-X0lvOVUg8PCVaoEtEAnpxmnkwlE1gcMDTqfhbefICKDnOTJ5Est3qL0SrWxizDackIOKBcvtpejrSiVpuJI1kw==, + } + engines: { node: ">= 10" } cpu: [riscv64] os: [linux] - '@tauri-apps/cli-linux-x64-gnu@2.10.1': - resolution: {integrity: sha512-2/12bEzsJS9fAKybxgicCDFxYD1WEI9kO+tlDwX5znWG2GwMBaiWcmhGlZ8fi+DMe9CXlcVarMTYc0L3REIRxw==} - engines: {node: '>= 10'} + "@tauri-apps/cli-linux-x64-gnu@2.10.1": + resolution: + { + integrity: sha512-2/12bEzsJS9fAKybxgicCDFxYD1WEI9kO+tlDwX5znWG2GwMBaiWcmhGlZ8fi+DMe9CXlcVarMTYc0L3REIRxw==, + } + engines: { node: ">= 10" } cpu: [x64] os: [linux] - '@tauri-apps/cli-linux-x64-musl@2.10.1': - resolution: {integrity: sha512-Y8J0ZzswPz50UcGOFuXGEMrxbjwKSPgXftx5qnkuMs2rmwQB5ssvLb6tn54wDSYxe7S6vlLob9vt0VKuNOaCIQ==} - engines: {node: '>= 10'} + "@tauri-apps/cli-linux-x64-musl@2.10.1": + resolution: + { + integrity: sha512-Y8J0ZzswPz50UcGOFuXGEMrxbjwKSPgXftx5qnkuMs2rmwQB5ssvLb6tn54wDSYxe7S6vlLob9vt0VKuNOaCIQ==, + } + engines: { node: ">= 10" } cpu: [x64] os: [linux] - '@tauri-apps/cli-win32-arm64-msvc@2.10.1': - resolution: {integrity: sha512-iSt5B86jHYAPJa/IlYw++SXtFPGnWtFJriHn7X0NFBVunF6zu9+/zOn8OgqIWSl8RgzhLGXQEEtGBdR4wzpVgg==} - engines: {node: '>= 10'} + "@tauri-apps/cli-win32-arm64-msvc@2.10.1": + resolution: + { + integrity: sha512-iSt5B86jHYAPJa/IlYw++SXtFPGnWtFJriHn7X0NFBVunF6zu9+/zOn8OgqIWSl8RgzhLGXQEEtGBdR4wzpVgg==, + } + engines: { node: ">= 10" } cpu: [arm64] os: [win32] - '@tauri-apps/cli-win32-ia32-msvc@2.10.1': - resolution: {integrity: sha512-gXyxgEzsFegmnWywYU5pEBURkcFN/Oo45EAwvZrHMh+zUSEAvO5E8TXsgPADYm31d1u7OQU3O3HsYfVBf2moHw==} - engines: {node: '>= 10'} + "@tauri-apps/cli-win32-ia32-msvc@2.10.1": + resolution: + { + integrity: sha512-gXyxgEzsFegmnWywYU5pEBURkcFN/Oo45EAwvZrHMh+zUSEAvO5E8TXsgPADYm31d1u7OQU3O3HsYfVBf2moHw==, + } + engines: { node: ">= 10" } cpu: [ia32] os: [win32] - '@tauri-apps/cli-win32-x64-msvc@2.10.1': - resolution: {integrity: sha512-6Cn7YpPFwzChy0ERz6djKEmUehWrYlM+xTaNzGPgZocw3BD7OfwfWHKVWxXzdjEW2KfKkHddfdxK1XXTYqBRLg==} - engines: {node: '>= 10'} + "@tauri-apps/cli-win32-x64-msvc@2.10.1": + resolution: + { + integrity: sha512-6Cn7YpPFwzChy0ERz6djKEmUehWrYlM+xTaNzGPgZocw3BD7OfwfWHKVWxXzdjEW2KfKkHddfdxK1XXTYqBRLg==, + } + engines: { node: ">= 10" } cpu: [x64] os: [win32] - '@tauri-apps/cli@2.10.1': - resolution: {integrity: sha512-jQNGF/5quwORdZSSLtTluyKQ+o6SMa/AUICfhf4egCGFdMHqWssApVgYSbg+jmrZoc8e1DscNvjTnXtlHLS11g==} - engines: {node: '>= 10'} + "@tauri-apps/cli@2.10.1": + resolution: + { + integrity: sha512-jQNGF/5quwORdZSSLtTluyKQ+o6SMa/AUICfhf4egCGFdMHqWssApVgYSbg+jmrZoc8e1DscNvjTnXtlHLS11g==, + } + engines: { node: ">= 10" } hasBin: true - '@tauri-apps/plugin-dialog@2.6.0': - resolution: {integrity: sha512-q4Uq3eY87TdcYzXACiYSPhmpBA76shgmQswGkSVio4C82Sz2W4iehe9TnKYwbq7weHiL88Yw19XZm7v28+Micg==} - - '@tauri-apps/plugin-shell@2.3.5': - resolution: {integrity: sha512-jewtULhiQ7lI7+owCKAjc8tYLJr92U16bPOeAa472LHJdgaibLP83NcfAF2e+wkEcA53FxKQAZ7byDzs2eeizg==} - - '@types/babel__core@7.20.5': - resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} - - '@types/babel__generator@7.27.0': - resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} - - '@types/babel__template@7.4.4': - resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - - '@types/babel__traverse@7.28.0': - resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} - - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - - '@types/react-dom@19.2.3': - resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} + "@tauri-apps/plugin-dialog@2.6.0": + resolution: + { + integrity: sha512-q4Uq3eY87TdcYzXACiYSPhmpBA76shgmQswGkSVio4C82Sz2W4iehe9TnKYwbq7weHiL88Yw19XZm7v28+Micg==, + } + + "@tauri-apps/plugin-shell@2.3.5": + resolution: + { + integrity: sha512-jewtULhiQ7lI7+owCKAjc8tYLJr92U16bPOeAa472LHJdgaibLP83NcfAF2e+wkEcA53FxKQAZ7byDzs2eeizg==, + } + + "@types/babel__core@7.20.5": + resolution: + { + integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==, + } + + "@types/babel__generator@7.27.0": + resolution: + { + integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==, + } + + "@types/babel__template@7.4.4": + resolution: + { + integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==, + } + + "@types/babel__traverse@7.28.0": + resolution: + { + integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==, + } + + "@types/estree@1.0.8": + resolution: + { + integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==, + } + + "@types/react-dom@19.2.3": + resolution: + { + integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==, + } peerDependencies: - '@types/react': ^19.2.0 - - '@types/react@19.2.14': - resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} - - '@vitejs/plugin-react@5.2.0': - resolution: {integrity: sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==} - engines: {node: ^20.19.0 || >=22.12.0} + "@types/react": ^19.2.0 + + "@types/react@19.2.14": + resolution: + { + integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==, + } + + "@vitejs/plugin-react@5.2.0": + resolution: + { + integrity: sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==, + } + engines: { node: ^20.19.0 || >=22.12.0 } peerDependencies: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 baseline-browser-mapping@2.10.9: - resolution: {integrity: sha512-OZd0e2mU11ClX8+IdXe3r0dbqMEznRiT4TfbhYIbcRPZkqJ7Qwer8ij3GZAmLsRKa+II9V1v5czCkvmHH3XZBg==} - engines: {node: '>=6.0.0'} + resolution: + { + integrity: sha512-OZd0e2mU11ClX8+IdXe3r0dbqMEznRiT4TfbhYIbcRPZkqJ7Qwer8ij3GZAmLsRKa+II9V1v5czCkvmHH3XZBg==, + } + engines: { node: ">=6.0.0" } hasBin: true browserslist@4.28.1: - resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + resolution: + { + integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==, + } + engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 } hasBin: true caniuse-lite@1.0.30001780: - resolution: {integrity: sha512-llngX0E7nQci5BPJDqoZSbuZ5Bcs9F5db7EtgfwBerX9XGtkkiO4NwfDDIRzHTTwcYC8vC7bmeUEPGrKlR/TkQ==} + resolution: + { + integrity: sha512-llngX0E7nQci5BPJDqoZSbuZ5Bcs9F5db7EtgfwBerX9XGtkkiO4NwfDDIRzHTTwcYC8vC7bmeUEPGrKlR/TkQ==, + } convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + resolution: + { + integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==, + } csstype@3.2.3: - resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + resolution: + { + integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==, + } debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} - engines: {node: '>=6.0'} + resolution: + { + integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==, + } + engines: { node: ">=6.0" } peerDependencies: - supports-color: '*' + supports-color: "*" peerDependenciesMeta: supports-color: optional: true electron-to-chromium@1.5.321: - resolution: {integrity: sha512-L2C7Q279W2D/J4PLZLk7sebOILDSWos7bMsMNN06rK482umHUrh/3lM8G7IlHFOYip2oAg5nha1rCMxr/rs6ZQ==} + resolution: + { + integrity: sha512-L2C7Q279W2D/J4PLZLk7sebOILDSWos7bMsMNN06rK482umHUrh/3lM8G7IlHFOYip2oAg5nha1rCMxr/rs6ZQ==, + } esbuild@0.25.12: - resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==, + } + engines: { node: ">=18" } hasBin: true escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==, + } + engines: { node: ">=6" } fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} + resolution: + { + integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==, + } + engines: { node: ">=12.0.0" } peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: @@ -590,119 +915,191 @@ packages: optional: true fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + resolution: + { + integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, + } + engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } os: [darwin] gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==, + } + engines: { node: ">=6.9.0" } js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + resolution: + { + integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==, + } jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==, + } + engines: { node: ">=6" } hasBin: true json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==, + } + engines: { node: ">=6" } hasBin: true lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + resolution: + { + integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==, + } ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + resolution: + { + integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==, + } nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + resolution: + { + integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==, + } + engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } hasBin: true node-releases@2.0.36: - resolution: {integrity: sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==} + resolution: + { + integrity: sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==, + } picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + resolution: + { + integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==, + } picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==, + } + engines: { node: ">=12" } postcss@8.5.8: - resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} - engines: {node: ^10 || ^12 || >=14} + resolution: + { + integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==, + } + engines: { node: ^10 || ^12 || >=14 } react-dom@19.2.4: - resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} + resolution: + { + integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==, + } peerDependencies: react: ^19.2.4 react-icons@5.6.0: - resolution: {integrity: sha512-RH93p5ki6LfOiIt0UtDyNg/cee+HLVR6cHHtW3wALfo+eOHTp8RnU2kRkI6E+H19zMIs03DyxUG/GfZMOGvmiA==} + resolution: + { + integrity: sha512-RH93p5ki6LfOiIt0UtDyNg/cee+HLVR6cHHtW3wALfo+eOHTp8RnU2kRkI6E+H19zMIs03DyxUG/GfZMOGvmiA==, + } peerDependencies: - react: '*' + react: "*" react-refresh@0.18.0: - resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==, + } + engines: { node: ">=0.10.0" } react@19.2.4: - resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==, + } + engines: { node: ">=0.10.0" } rollup@4.59.0: - resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} + resolution: + { + integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==, + } + engines: { node: ">=18.0.0", npm: ">=8.0.0" } hasBin: true scheduler@0.27.0: - resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + resolution: + { + integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==, + } semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + resolution: + { + integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==, + } hasBin: true source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==, + } + engines: { node: ">=0.10.0" } tinyglobby@0.2.15: - resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} - engines: {node: '>=12.0.0'} + resolution: + { + integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==, + } + engines: { node: ">=12.0.0" } typescript@5.9.3: - resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} - engines: {node: '>=14.17'} + resolution: + { + integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==, + } + engines: { node: ">=14.17" } hasBin: true update-browserslist-db@1.2.3: - resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + resolution: + { + integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==, + } hasBin: true peerDependencies: - browserslist: '>= 4.21.0' + browserslist: ">= 4.21.0" vite@6.4.1: - resolution: {integrity: sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + resolution: + { + integrity: sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==, + } + engines: { node: ^18.0.0 || ^20.0.0 || >=22.0.0 } hasBin: true peerDependencies: - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - jiti: '>=1.21.0' - less: '*' + "@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: ">=1.21.0" + less: "*" lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' + sass: "*" + sass-embedded: "*" + stylus: "*" + sugarss: "*" terser: ^5.16.0 tsx: ^4.8.1 yaml: ^2.4.2 peerDependenciesMeta: - '@types/node': + "@types/node": optional: true jiti: optional: true @@ -726,30 +1123,32 @@ packages: optional: true yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + resolution: + { + integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==, + } snapshots: - - '@babel/code-frame@7.29.0': + "@babel/code-frame@7.29.0": dependencies: - '@babel/helper-validator-identifier': 7.28.5 + "@babel/helper-validator-identifier": 7.28.5 js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.29.0': {} + "@babel/compat-data@7.29.0": {} - '@babel/core@7.29.0': + "@babel/core@7.29.0": dependencies: - '@babel/code-frame': 7.29.0 - '@babel/generator': 7.29.1 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) - '@babel/helpers': 7.29.2 - '@babel/parser': 7.29.2 - '@babel/template': 7.28.6 - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 - '@jridgewell/remapping': 2.3.5 + "@babel/code-frame": 7.29.0 + "@babel/generator": 7.29.1 + "@babel/helper-compilation-targets": 7.28.6 + "@babel/helper-module-transforms": 7.28.6(@babel/core@7.29.0) + "@babel/helpers": 7.29.2 + "@babel/parser": 7.29.2 + "@babel/template": 7.28.6 + "@babel/traverse": 7.29.0 + "@babel/types": 7.29.0 + "@jridgewell/remapping": 2.3.5 convert-source-map: 2.0.0 debug: 4.4.3 gensync: 1.0.0-beta.2 @@ -758,359 +1157,359 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/generator@7.29.1': + "@babel/generator@7.29.1": dependencies: - '@babel/parser': 7.29.2 - '@babel/types': 7.29.0 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 + "@babel/parser": 7.29.2 + "@babel/types": 7.29.0 + "@jridgewell/gen-mapping": 0.3.13 + "@jridgewell/trace-mapping": 0.3.31 jsesc: 3.1.0 - '@babel/helper-compilation-targets@7.28.6': + "@babel/helper-compilation-targets@7.28.6": dependencies: - '@babel/compat-data': 7.29.0 - '@babel/helper-validator-option': 7.27.1 + "@babel/compat-data": 7.29.0 + "@babel/helper-validator-option": 7.27.1 browserslist: 4.28.1 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-globals@7.28.0': {} + "@babel/helper-globals@7.28.0": {} - '@babel/helper-module-imports@7.28.6': + "@babel/helper-module-imports@7.28.6": dependencies: - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 + "@babel/traverse": 7.29.0 + "@babel/types": 7.29.0 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + "@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)": dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-imports': 7.28.6 - '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.29.0 + "@babel/core": 7.29.0 + "@babel/helper-module-imports": 7.28.6 + "@babel/helper-validator-identifier": 7.28.5 + "@babel/traverse": 7.29.0 transitivePeerDependencies: - supports-color - '@babel/helper-plugin-utils@7.28.6': {} + "@babel/helper-plugin-utils@7.28.6": {} - '@babel/helper-string-parser@7.27.1': {} + "@babel/helper-string-parser@7.27.1": {} - '@babel/helper-validator-identifier@7.28.5': {} + "@babel/helper-validator-identifier@7.28.5": {} - '@babel/helper-validator-option@7.27.1': {} + "@babel/helper-validator-option@7.27.1": {} - '@babel/helpers@7.29.2': + "@babel/helpers@7.29.2": dependencies: - '@babel/template': 7.28.6 - '@babel/types': 7.29.0 + "@babel/template": 7.28.6 + "@babel/types": 7.29.0 - '@babel/parser@7.29.2': + "@babel/parser@7.29.2": dependencies: - '@babel/types': 7.29.0 + "@babel/types": 7.29.0 - '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.29.0)': + "@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/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)': + "@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/core": 7.29.0 + "@babel/helper-plugin-utils": 7.28.6 - '@babel/template@7.28.6': + "@babel/template@7.28.6": dependencies: - '@babel/code-frame': 7.29.0 - '@babel/parser': 7.29.2 - '@babel/types': 7.29.0 + "@babel/code-frame": 7.29.0 + "@babel/parser": 7.29.2 + "@babel/types": 7.29.0 - '@babel/traverse@7.29.0': + "@babel/traverse@7.29.0": dependencies: - '@babel/code-frame': 7.29.0 - '@babel/generator': 7.29.1 - '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.29.2 - '@babel/template': 7.28.6 - '@babel/types': 7.29.0 + "@babel/code-frame": 7.29.0 + "@babel/generator": 7.29.1 + "@babel/helper-globals": 7.28.0 + "@babel/parser": 7.29.2 + "@babel/template": 7.28.6 + "@babel/types": 7.29.0 debug: 4.4.3 transitivePeerDependencies: - supports-color - '@babel/types@7.29.0': + "@babel/types@7.29.0": dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.28.5 + "@babel/helper-string-parser": 7.27.1 + "@babel/helper-validator-identifier": 7.28.5 - '@esbuild/aix-ppc64@0.25.12': + "@esbuild/aix-ppc64@0.25.12": optional: true - '@esbuild/android-arm64@0.25.12': + "@esbuild/android-arm64@0.25.12": optional: true - '@esbuild/android-arm@0.25.12': + "@esbuild/android-arm@0.25.12": optional: true - '@esbuild/android-x64@0.25.12': + "@esbuild/android-x64@0.25.12": optional: true - '@esbuild/darwin-arm64@0.25.12': + "@esbuild/darwin-arm64@0.25.12": optional: true - '@esbuild/darwin-x64@0.25.12': + "@esbuild/darwin-x64@0.25.12": optional: true - '@esbuild/freebsd-arm64@0.25.12': + "@esbuild/freebsd-arm64@0.25.12": optional: true - '@esbuild/freebsd-x64@0.25.12': + "@esbuild/freebsd-x64@0.25.12": optional: true - '@esbuild/linux-arm64@0.25.12': + "@esbuild/linux-arm64@0.25.12": optional: true - '@esbuild/linux-arm@0.25.12': + "@esbuild/linux-arm@0.25.12": optional: true - '@esbuild/linux-ia32@0.25.12': + "@esbuild/linux-ia32@0.25.12": optional: true - '@esbuild/linux-loong64@0.25.12': + "@esbuild/linux-loong64@0.25.12": optional: true - '@esbuild/linux-mips64el@0.25.12': + "@esbuild/linux-mips64el@0.25.12": optional: true - '@esbuild/linux-ppc64@0.25.12': + "@esbuild/linux-ppc64@0.25.12": optional: true - '@esbuild/linux-riscv64@0.25.12': + "@esbuild/linux-riscv64@0.25.12": optional: true - '@esbuild/linux-s390x@0.25.12': + "@esbuild/linux-s390x@0.25.12": optional: true - '@esbuild/linux-x64@0.25.12': + "@esbuild/linux-x64@0.25.12": optional: true - '@esbuild/netbsd-arm64@0.25.12': + "@esbuild/netbsd-arm64@0.25.12": optional: true - '@esbuild/netbsd-x64@0.25.12': + "@esbuild/netbsd-x64@0.25.12": optional: true - '@esbuild/openbsd-arm64@0.25.12': + "@esbuild/openbsd-arm64@0.25.12": optional: true - '@esbuild/openbsd-x64@0.25.12': + "@esbuild/openbsd-x64@0.25.12": optional: true - '@esbuild/openharmony-arm64@0.25.12': + "@esbuild/openharmony-arm64@0.25.12": optional: true - '@esbuild/sunos-x64@0.25.12': + "@esbuild/sunos-x64@0.25.12": optional: true - '@esbuild/win32-arm64@0.25.12': + "@esbuild/win32-arm64@0.25.12": optional: true - '@esbuild/win32-ia32@0.25.12': + "@esbuild/win32-ia32@0.25.12": optional: true - '@esbuild/win32-x64@0.25.12': + "@esbuild/win32-x64@0.25.12": optional: true - '@jridgewell/gen-mapping@0.3.13': + "@jridgewell/gen-mapping@0.3.13": dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 + "@jridgewell/sourcemap-codec": 1.5.5 + "@jridgewell/trace-mapping": 0.3.31 - '@jridgewell/remapping@2.3.5': + "@jridgewell/remapping@2.3.5": dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 + "@jridgewell/gen-mapping": 0.3.13 + "@jridgewell/trace-mapping": 0.3.31 - '@jridgewell/resolve-uri@3.1.2': {} + "@jridgewell/resolve-uri@3.1.2": {} - '@jridgewell/sourcemap-codec@1.5.5': {} + "@jridgewell/sourcemap-codec@1.5.5": {} - '@jridgewell/trace-mapping@0.3.31': + "@jridgewell/trace-mapping@0.3.31": dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 + "@jridgewell/resolve-uri": 3.1.2 + "@jridgewell/sourcemap-codec": 1.5.5 - '@rolldown/pluginutils@1.0.0-rc.3': {} + "@rolldown/pluginutils@1.0.0-rc.3": {} - '@rollup/rollup-android-arm-eabi@4.59.0': + "@rollup/rollup-android-arm-eabi@4.59.0": optional: true - '@rollup/rollup-android-arm64@4.59.0': + "@rollup/rollup-android-arm64@4.59.0": optional: true - '@rollup/rollup-darwin-arm64@4.59.0': + "@rollup/rollup-darwin-arm64@4.59.0": optional: true - '@rollup/rollup-darwin-x64@4.59.0': + "@rollup/rollup-darwin-x64@4.59.0": optional: true - '@rollup/rollup-freebsd-arm64@4.59.0': + "@rollup/rollup-freebsd-arm64@4.59.0": optional: true - '@rollup/rollup-freebsd-x64@4.59.0': + "@rollup/rollup-freebsd-x64@4.59.0": optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + "@rollup/rollup-linux-arm-gnueabihf@4.59.0": optional: true - '@rollup/rollup-linux-arm-musleabihf@4.59.0': + "@rollup/rollup-linux-arm-musleabihf@4.59.0": optional: true - '@rollup/rollup-linux-arm64-gnu@4.59.0': + "@rollup/rollup-linux-arm64-gnu@4.59.0": optional: true - '@rollup/rollup-linux-arm64-musl@4.59.0': + "@rollup/rollup-linux-arm64-musl@4.59.0": optional: true - '@rollup/rollup-linux-loong64-gnu@4.59.0': + "@rollup/rollup-linux-loong64-gnu@4.59.0": optional: true - '@rollup/rollup-linux-loong64-musl@4.59.0': + "@rollup/rollup-linux-loong64-musl@4.59.0": optional: true - '@rollup/rollup-linux-ppc64-gnu@4.59.0': + "@rollup/rollup-linux-ppc64-gnu@4.59.0": optional: true - '@rollup/rollup-linux-ppc64-musl@4.59.0': + "@rollup/rollup-linux-ppc64-musl@4.59.0": optional: true - '@rollup/rollup-linux-riscv64-gnu@4.59.0': + "@rollup/rollup-linux-riscv64-gnu@4.59.0": optional: true - '@rollup/rollup-linux-riscv64-musl@4.59.0': + "@rollup/rollup-linux-riscv64-musl@4.59.0": optional: true - '@rollup/rollup-linux-s390x-gnu@4.59.0': + "@rollup/rollup-linux-s390x-gnu@4.59.0": optional: true - '@rollup/rollup-linux-x64-gnu@4.59.0': + "@rollup/rollup-linux-x64-gnu@4.59.0": optional: true - '@rollup/rollup-linux-x64-musl@4.59.0': + "@rollup/rollup-linux-x64-musl@4.59.0": optional: true - '@rollup/rollup-openbsd-x64@4.59.0': + "@rollup/rollup-openbsd-x64@4.59.0": optional: true - '@rollup/rollup-openharmony-arm64@4.59.0': + "@rollup/rollup-openharmony-arm64@4.59.0": optional: true - '@rollup/rollup-win32-arm64-msvc@4.59.0': + "@rollup/rollup-win32-arm64-msvc@4.59.0": optional: true - '@rollup/rollup-win32-ia32-msvc@4.59.0': + "@rollup/rollup-win32-ia32-msvc@4.59.0": optional: true - '@rollup/rollup-win32-x64-gnu@4.59.0': + "@rollup/rollup-win32-x64-gnu@4.59.0": optional: true - '@rollup/rollup-win32-x64-msvc@4.59.0': + "@rollup/rollup-win32-x64-msvc@4.59.0": optional: true - '@tauri-apps/api@2.10.1': {} + "@tauri-apps/api@2.10.1": {} - '@tauri-apps/cli-darwin-arm64@2.10.1': + "@tauri-apps/cli-darwin-arm64@2.10.1": optional: true - '@tauri-apps/cli-darwin-x64@2.10.1': + "@tauri-apps/cli-darwin-x64@2.10.1": optional: true - '@tauri-apps/cli-linux-arm-gnueabihf@2.10.1': + "@tauri-apps/cli-linux-arm-gnueabihf@2.10.1": optional: true - '@tauri-apps/cli-linux-arm64-gnu@2.10.1': + "@tauri-apps/cli-linux-arm64-gnu@2.10.1": optional: true - '@tauri-apps/cli-linux-arm64-musl@2.10.1': + "@tauri-apps/cli-linux-arm64-musl@2.10.1": optional: true - '@tauri-apps/cli-linux-riscv64-gnu@2.10.1': + "@tauri-apps/cli-linux-riscv64-gnu@2.10.1": optional: true - '@tauri-apps/cli-linux-x64-gnu@2.10.1': + "@tauri-apps/cli-linux-x64-gnu@2.10.1": optional: true - '@tauri-apps/cli-linux-x64-musl@2.10.1': + "@tauri-apps/cli-linux-x64-musl@2.10.1": optional: true - '@tauri-apps/cli-win32-arm64-msvc@2.10.1': + "@tauri-apps/cli-win32-arm64-msvc@2.10.1": optional: true - '@tauri-apps/cli-win32-ia32-msvc@2.10.1': + "@tauri-apps/cli-win32-ia32-msvc@2.10.1": optional: true - '@tauri-apps/cli-win32-x64-msvc@2.10.1': + "@tauri-apps/cli-win32-x64-msvc@2.10.1": optional: true - '@tauri-apps/cli@2.10.1': + "@tauri-apps/cli@2.10.1": optionalDependencies: - '@tauri-apps/cli-darwin-arm64': 2.10.1 - '@tauri-apps/cli-darwin-x64': 2.10.1 - '@tauri-apps/cli-linux-arm-gnueabihf': 2.10.1 - '@tauri-apps/cli-linux-arm64-gnu': 2.10.1 - '@tauri-apps/cli-linux-arm64-musl': 2.10.1 - '@tauri-apps/cli-linux-riscv64-gnu': 2.10.1 - '@tauri-apps/cli-linux-x64-gnu': 2.10.1 - '@tauri-apps/cli-linux-x64-musl': 2.10.1 - '@tauri-apps/cli-win32-arm64-msvc': 2.10.1 - '@tauri-apps/cli-win32-ia32-msvc': 2.10.1 - '@tauri-apps/cli-win32-x64-msvc': 2.10.1 - - '@tauri-apps/plugin-dialog@2.6.0': + "@tauri-apps/cli-darwin-arm64": 2.10.1 + "@tauri-apps/cli-darwin-x64": 2.10.1 + "@tauri-apps/cli-linux-arm-gnueabihf": 2.10.1 + "@tauri-apps/cli-linux-arm64-gnu": 2.10.1 + "@tauri-apps/cli-linux-arm64-musl": 2.10.1 + "@tauri-apps/cli-linux-riscv64-gnu": 2.10.1 + "@tauri-apps/cli-linux-x64-gnu": 2.10.1 + "@tauri-apps/cli-linux-x64-musl": 2.10.1 + "@tauri-apps/cli-win32-arm64-msvc": 2.10.1 + "@tauri-apps/cli-win32-ia32-msvc": 2.10.1 + "@tauri-apps/cli-win32-x64-msvc": 2.10.1 + + "@tauri-apps/plugin-dialog@2.6.0": dependencies: - '@tauri-apps/api': 2.10.1 + "@tauri-apps/api": 2.10.1 - '@tauri-apps/plugin-shell@2.3.5': + "@tauri-apps/plugin-shell@2.3.5": dependencies: - '@tauri-apps/api': 2.10.1 + "@tauri-apps/api": 2.10.1 - '@types/babel__core@7.20.5': + "@types/babel__core@7.20.5": dependencies: - '@babel/parser': 7.29.2 - '@babel/types': 7.29.0 - '@types/babel__generator': 7.27.0 - '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.28.0 + "@babel/parser": 7.29.2 + "@babel/types": 7.29.0 + "@types/babel__generator": 7.27.0 + "@types/babel__template": 7.4.4 + "@types/babel__traverse": 7.28.0 - '@types/babel__generator@7.27.0': + "@types/babel__generator@7.27.0": dependencies: - '@babel/types': 7.29.0 + "@babel/types": 7.29.0 - '@types/babel__template@7.4.4': + "@types/babel__template@7.4.4": dependencies: - '@babel/parser': 7.29.2 - '@babel/types': 7.29.0 + "@babel/parser": 7.29.2 + "@babel/types": 7.29.0 - '@types/babel__traverse@7.28.0': + "@types/babel__traverse@7.28.0": dependencies: - '@babel/types': 7.29.0 + "@babel/types": 7.29.0 - '@types/estree@1.0.8': {} + "@types/estree@1.0.8": {} - '@types/react-dom@19.2.3(@types/react@19.2.14)': + "@types/react-dom@19.2.3(@types/react@19.2.14)": dependencies: - '@types/react': 19.2.14 + "@types/react": 19.2.14 - '@types/react@19.2.14': + "@types/react@19.2.14": dependencies: csstype: 3.2.3 - '@vitejs/plugin-react@5.2.0(vite@6.4.1)': + "@vitejs/plugin-react@5.2.0(vite@6.4.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-rc.3 - '@types/babel__core': 7.20.5 + "@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-rc.3 + "@types/babel__core": 7.20.5 react-refresh: 0.18.0 vite: 6.4.1 transitivePeerDependencies: @@ -1140,32 +1539,32 @@ snapshots: esbuild@0.25.12: optionalDependencies: - '@esbuild/aix-ppc64': 0.25.12 - '@esbuild/android-arm': 0.25.12 - '@esbuild/android-arm64': 0.25.12 - '@esbuild/android-x64': 0.25.12 - '@esbuild/darwin-arm64': 0.25.12 - '@esbuild/darwin-x64': 0.25.12 - '@esbuild/freebsd-arm64': 0.25.12 - '@esbuild/freebsd-x64': 0.25.12 - '@esbuild/linux-arm': 0.25.12 - '@esbuild/linux-arm64': 0.25.12 - '@esbuild/linux-ia32': 0.25.12 - '@esbuild/linux-loong64': 0.25.12 - '@esbuild/linux-mips64el': 0.25.12 - '@esbuild/linux-ppc64': 0.25.12 - '@esbuild/linux-riscv64': 0.25.12 - '@esbuild/linux-s390x': 0.25.12 - '@esbuild/linux-x64': 0.25.12 - '@esbuild/netbsd-arm64': 0.25.12 - '@esbuild/netbsd-x64': 0.25.12 - '@esbuild/openbsd-arm64': 0.25.12 - '@esbuild/openbsd-x64': 0.25.12 - '@esbuild/openharmony-arm64': 0.25.12 - '@esbuild/sunos-x64': 0.25.12 - '@esbuild/win32-arm64': 0.25.12 - '@esbuild/win32-ia32': 0.25.12 - '@esbuild/win32-x64': 0.25.12 + "@esbuild/aix-ppc64": 0.25.12 + "@esbuild/android-arm": 0.25.12 + "@esbuild/android-arm64": 0.25.12 + "@esbuild/android-x64": 0.25.12 + "@esbuild/darwin-arm64": 0.25.12 + "@esbuild/darwin-x64": 0.25.12 + "@esbuild/freebsd-arm64": 0.25.12 + "@esbuild/freebsd-x64": 0.25.12 + "@esbuild/linux-arm": 0.25.12 + "@esbuild/linux-arm64": 0.25.12 + "@esbuild/linux-ia32": 0.25.12 + "@esbuild/linux-loong64": 0.25.12 + "@esbuild/linux-mips64el": 0.25.12 + "@esbuild/linux-ppc64": 0.25.12 + "@esbuild/linux-riscv64": 0.25.12 + "@esbuild/linux-s390x": 0.25.12 + "@esbuild/linux-x64": 0.25.12 + "@esbuild/netbsd-arm64": 0.25.12 + "@esbuild/netbsd-x64": 0.25.12 + "@esbuild/openbsd-arm64": 0.25.12 + "@esbuild/openbsd-x64": 0.25.12 + "@esbuild/openharmony-arm64": 0.25.12 + "@esbuild/sunos-x64": 0.25.12 + "@esbuild/win32-arm64": 0.25.12 + "@esbuild/win32-ia32": 0.25.12 + "@esbuild/win32-x64": 0.25.12 escalade@3.2.0: {} @@ -1219,33 +1618,33 @@ snapshots: rollup@4.59.0: dependencies: - '@types/estree': 1.0.8 + "@types/estree": 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.59.0 - '@rollup/rollup-android-arm64': 4.59.0 - '@rollup/rollup-darwin-arm64': 4.59.0 - '@rollup/rollup-darwin-x64': 4.59.0 - '@rollup/rollup-freebsd-arm64': 4.59.0 - '@rollup/rollup-freebsd-x64': 4.59.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.59.0 - '@rollup/rollup-linux-arm-musleabihf': 4.59.0 - '@rollup/rollup-linux-arm64-gnu': 4.59.0 - '@rollup/rollup-linux-arm64-musl': 4.59.0 - '@rollup/rollup-linux-loong64-gnu': 4.59.0 - '@rollup/rollup-linux-loong64-musl': 4.59.0 - '@rollup/rollup-linux-ppc64-gnu': 4.59.0 - '@rollup/rollup-linux-ppc64-musl': 4.59.0 - '@rollup/rollup-linux-riscv64-gnu': 4.59.0 - '@rollup/rollup-linux-riscv64-musl': 4.59.0 - '@rollup/rollup-linux-s390x-gnu': 4.59.0 - '@rollup/rollup-linux-x64-gnu': 4.59.0 - '@rollup/rollup-linux-x64-musl': 4.59.0 - '@rollup/rollup-openbsd-x64': 4.59.0 - '@rollup/rollup-openharmony-arm64': 4.59.0 - '@rollup/rollup-win32-arm64-msvc': 4.59.0 - '@rollup/rollup-win32-ia32-msvc': 4.59.0 - '@rollup/rollup-win32-x64-gnu': 4.59.0 - '@rollup/rollup-win32-x64-msvc': 4.59.0 + "@rollup/rollup-android-arm-eabi": 4.59.0 + "@rollup/rollup-android-arm64": 4.59.0 + "@rollup/rollup-darwin-arm64": 4.59.0 + "@rollup/rollup-darwin-x64": 4.59.0 + "@rollup/rollup-freebsd-arm64": 4.59.0 + "@rollup/rollup-freebsd-x64": 4.59.0 + "@rollup/rollup-linux-arm-gnueabihf": 4.59.0 + "@rollup/rollup-linux-arm-musleabihf": 4.59.0 + "@rollup/rollup-linux-arm64-gnu": 4.59.0 + "@rollup/rollup-linux-arm64-musl": 4.59.0 + "@rollup/rollup-linux-loong64-gnu": 4.59.0 + "@rollup/rollup-linux-loong64-musl": 4.59.0 + "@rollup/rollup-linux-ppc64-gnu": 4.59.0 + "@rollup/rollup-linux-ppc64-musl": 4.59.0 + "@rollup/rollup-linux-riscv64-gnu": 4.59.0 + "@rollup/rollup-linux-riscv64-musl": 4.59.0 + "@rollup/rollup-linux-s390x-gnu": 4.59.0 + "@rollup/rollup-linux-x64-gnu": 4.59.0 + "@rollup/rollup-linux-x64-musl": 4.59.0 + "@rollup/rollup-openbsd-x64": 4.59.0 + "@rollup/rollup-openharmony-arm64": 4.59.0 + "@rollup/rollup-win32-arm64-msvc": 4.59.0 + "@rollup/rollup-win32-ia32-msvc": 4.59.0 + "@rollup/rollup-win32-x64-gnu": 4.59.0 + "@rollup/rollup-win32-x64-msvc": 4.59.0 fsevents: 2.3.3 scheduler@0.27.0: {} @@ -1278,4 +1677,4 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - yallist@3.1.1: {} \ No newline at end of file + yallist@3.1.1: {} diff --git a/launcher/src-tauri/src/commands.rs b/launcher/src-tauri/src/commands.rs index e1210887..b86b14f5 100644 --- a/launcher/src-tauri/src/commands.rs +++ b/launcher/src-tauri/src/commands.rs @@ -1,6 +1,6 @@ +use crate::settings::LauncherSettings; use crate::storage; -use crate::config::LauncherSettings; use serde::{Deserialize, Serialize}; use std::collections::VecDeque; use std::process::Stdio; @@ -416,6 +416,21 @@ fn find_client_binary() -> Result { } #[tauri::command] -pub async fn load_launcher_settings() -> LauncherSettings{ +pub async fn load_launcher_settings() -> LauncherSettings { LauncherSettings::load() } + +#[tauri::command] +pub async fn set_launcher_language(language: String) -> Result<(), String> { + LauncherSettings::update_settings(|s| s.language = language) +} + +#[tauri::command] +pub async fn set_keep_launcher_open(keep: bool) -> Result<(), String> { + LauncherSettings::update_settings(|s| s.keep_launcher_open = keep) +} + +#[tauri::command] +pub async fn set_launch_with_console(launch: bool) -> Result<(), String> { + LauncherSettings::update_settings(|s| s.launch_with_console = launch) +} diff --git a/launcher/src-tauri/src/main.rs b/launcher/src-tauri/src/main.rs index 6bebd9dc..564d7a59 100644 --- a/launcher/src-tauri/src/main.rs +++ b/launcher/src-tauri/src/main.rs @@ -5,8 +5,8 @@ use tokio::sync::Mutex; mod auth; mod commands; -mod config; mod downloader; +mod settings; mod storage; use std::collections::VecDeque; @@ -43,6 +43,9 @@ fn main() { commands::launch_game, commands::get_client_logs, commands::load_launcher_settings, + commands::set_launcher_language, + commands::set_keep_launcher_open, + commands::set_launch_with_console, ]) .run(tauri::generate_context!()) .expect("failed to run POMC launcher"); diff --git a/launcher/src-tauri/src/config.rs b/launcher/src-tauri/src/settings.rs similarity index 57% rename from launcher/src-tauri/src/config.rs rename to launcher/src-tauri/src/settings.rs index 648df822..90a4c8c7 100644 --- a/launcher/src-tauri/src/config.rs +++ b/launcher/src-tauri/src/settings.rs @@ -12,9 +12,9 @@ pub struct LauncherSettings { impl Default for LauncherSettings { fn default() -> Self { LauncherSettings { - language: "French".into(), - keep_launcher_open: false, - launch_with_console: true, + language: "English".into(), + keep_launcher_open: true, + launch_with_console: false, } } } @@ -37,29 +37,22 @@ impl LauncherSettings { log::warn!("Settings file invalid ({}), using defaults", err); } }, - Err(err) => { - log::info!( - "Settings file not found or unreadable ({}), using defaults", - err - ); + Err(_) => { + log::info!("Settings file not found, creating default settings"); } } - LauncherSettings::default() + let default = LauncherSettings::default(); + let _ = default.save(); + default } - pub fn set_language(&mut self, language: String) -> Result<(), String> { - self.language = language; - self.save() - } - - pub fn set_keep_launcher_open(&mut self, keep: bool) -> Result<(), String> { - self.keep_launcher_open = keep; - self.save() - } - - pub fn set_launch_with_console(&mut self, launch_with_console: bool) -> Result<(), String> { - self.launch_with_console = launch_with_console; - self.save() + pub fn update_settings(f: F) -> Result<(), String> + where + F: FnOnce(&mut LauncherSettings), + { + let mut settings = LauncherSettings::load(); + f(&mut settings); + settings.save() } } diff --git a/launcher/src-tauri/src/storage.rs b/launcher/src-tauri/src/storage.rs index 6c4fbbaa..c70c0a41 100644 --- a/launcher/src-tauri/src/storage.rs +++ b/launcher/src-tauri/src/storage.rs @@ -1,4 +1,3 @@ -use serde::Serialize; use std::path::{Path, PathBuf}; fn ensure_file(path: &Path, default: &str) { diff --git a/launcher/src/App.tsx b/launcher/src/App.tsx index ca89ed90..08bbd77e 100644 --- a/launcher/src/App.tsx +++ b/launcher/src/App.tsx @@ -1,14 +1,11 @@ import { useCallback, useEffect } from "react"; import { invoke } from "@tauri-apps/api/core"; import { open as openDialog } from "@tauri-apps/plugin-dialog"; -import { - HiChevronDown, - HiFolder, -} from "react-icons/hi2"; +import { HiChevronDown, HiFolder } from "react-icons/hi2"; import { AuthAccount, GameVersion, PatchNote } from "./lib/types"; import Homepage from "./pages/Home"; import InstallationsPage from "./pages/Installations"; -import {useAppStateContext} from "./lib/state"; +import { useAppStateContext } from "./lib/state"; import Navbar from "./components/Navbar"; import ModsPage from "./pages/Mods"; import ServersPage from "./pages/Servers"; @@ -44,7 +41,7 @@ function App() { setSkinUrl, setSelectedNote, username, - useConsole, + launcherSettings, } = useAppStateContext(); const openPatchNote = useCallback(async (note: PatchNote) => { @@ -108,19 +105,16 @@ function App() { loadSkin(accounts[index].uuid); } }, - [accounts, loadSkin] + [accounts, loadSkin], ); - const removeAccount = useCallback( - (uuid: string) => { - invoke("remove_account", { uuid }); - setAccounts((prev) => prev.filter((a) => a.uuid !== uuid)); - setActiveIndex(0); - setAccountDropdownOpen(false); - setSkinUrl(null); - }, - [] - ); + const removeAccount = useCallback((uuid: string) => { + invoke("remove_account", { uuid }); + setAccounts((prev) => prev.filter((a) => a.uuid !== uuid)); + setActiveIndex(0); + setAccountDropdownOpen(false); + setSkinUrl(null); + }, []); const handleLaunch = useCallback(async () => { setLaunching(true); @@ -131,7 +125,7 @@ function App() { const result = await invoke("launch_game", { uuid: account?.uuid || null, server: server || null, - debugEnabled: useConsole || null, + debugEnabled: launcherSettings.launchWithConsole || null, }); setStatus(result); } catch (e) { @@ -141,7 +135,7 @@ function App() { setLaunching(false); setStatus(""); }, 3000); - }, [username, server, selectedVersion, useConsole]); + }, [username, server, selectedVersion, launcherSettings.launchWithConsole]); return (
@@ -156,43 +150,38 @@ function App() {
{page === "home" && ( - + )} - {page === "installations" && ( - - )} + {page === "installations" && } - {page === "news" && ( - - )} + {page === "news" && } - {page === "servers" && ( - - )} + {page === "servers" && } - {page === "friends" && ( - - )} + {page === "friends" && } - {page === "mods" && ( - - )} + {page === "mods" && } - {page === "settings" && ( - - )} + {page === "settings" && }
{editingInstall && ( -
{ setEditingInstall(null); setDialogVersionOpen(false); }}> -
{ e.stopPropagation(); if (dialogVersionOpen) setDialogVersionOpen(false); }}> +
{ + setEditingInstall(null); + setDialogVersionOpen(false); + }} + > +
{ + e.stopPropagation(); + if (dialogVersionOpen) setDialogVersionOpen(false); + }} + >

{editingInstall.id ? "Edit Installation" : "New Installation"}

@@ -202,9 +191,7 @@ function App() { - setEditingInstall({ ...editingInstall, name: e.target.value }) - } + onChange={(e) => setEditingInstall({ ...editingInstall, name: e.target.value })} placeholder="My Installation" autoFocus /> @@ -252,9 +239,7 @@ function App() { > {v.id} {v.version_type !== "release" && ( - - {v.version_type} - + {v.version_type} )} ))} @@ -320,10 +305,7 @@ function App() {
- {accountDropdownOpen && (
@@ -118,25 +109,15 @@ export default function Navbar({ startAddAccount, switchAccount, removeAccount } key={acc.uuid} className={`account-option ${i === activeIndex ? "active" : ""}`} > - -
))} - @@ -163,11 +144,7 @@ export default function Navbar({ startAddAccount, switchAccount, removeAccount } )}
) : ( - )} diff --git a/launcher/src/components/Titlebar.tsx b/launcher/src/components/Titlebar.tsx index ec1f768d..56c83a54 100644 --- a/launcher/src/components/Titlebar.tsx +++ b/launcher/src/components/Titlebar.tsx @@ -1,5 +1,5 @@ import { getCurrentWindow } from "@tauri-apps/api/window"; -import { HiCube, HiMinus, HiSquare2Stack, HiXMark } from "react-icons/hi2" +import { HiCube, HiMinus, HiSquare2Stack, HiXMark } from "react-icons/hi2"; export default function Titlebar({ name }: { name?: string } = { name: "POMC Launcher" }) { const appWindow = getCurrentWindow(); @@ -17,7 +17,9 @@ export default function Titlebar({ name }: { name?: string } = { name: "POMC Lau return (
- + + +
{name} @@ -29,13 +31,10 @@ export default function Titlebar({ name }: { name?: string } = { name: "POMC Lau -
- ) + ); } diff --git a/launcher/src/lib/state.ts b/launcher/src/lib/state.ts index 469cd6b1..6eed5fd0 100644 --- a/launcher/src/lib/state.ts +++ b/launcher/src/lib/state.ts @@ -1,6 +1,6 @@ -import {createElement, createContext, useContext, useState, ReactNode, useEffect} from "react"; -import { Page, AuthAccount, Installation, GameVersion, PatchNote, LauncherSettings } from "./types"; -import {invoke} from "@tauri-apps/api/core"; +import { createContext, createElement, ReactNode, useContext, useEffect, useState } from "react"; +import { AuthAccount, GameVersion, Installation, LauncherSettings, Page, PatchNote } from "./types"; +import { invoke } from "@tauri-apps/api/core"; const useLauncherSettings = () => { const [launcherSettings, setLauncherSettings] = useState({ @@ -15,8 +15,38 @@ const useLauncherSettings = () => { .catch(console.error); }, []); - return launcherSettings; -} + const setLanguage = async (language: string) => { + try { + await invoke("set_launcher_language", { language }); + setLauncherSettings((prev) => ({ ...prev, language })); + } catch (err) { + console.error(err); + } + }; + const setKeepLauncherOpen = async (keep: boolean) => { + try { + await invoke("set_keep_launcher_open", { keep }); + setLauncherSettings((prev) => ({ ...prev, keepLauncherOpen: keep })); + } catch (err) { + console.error(err); + } + }; + const setLaunchWithConsole = async (launch: boolean) => { + try { + await invoke("set_launch_with_console", { launch }); + setLauncherSettings((prev) => ({ ...prev, launchWithConsole: launch })); + } catch (err) { + console.error(err); + } + }; + + return { + ...launcherSettings, + setLanguage, + setKeepLauncherOpen, + setLaunchWithConsole, + }; +}; const useAppState = () => { const [page, setPage] = useState("home"); const [accounts, setAccounts] = useState([]); @@ -24,8 +54,6 @@ const useAppState = () => { const [accountDropdownOpen, setAccountDropdownOpen] = useState(false); const [server] = useState(""); - const [keepOpen, setKeepOpen] = useState(true); - const [useConsole, setUseConsole] = useState(false); const [modView, setModView] = useState<"list" | "grid">("list"); const [modSearch, setModSearch] = useState(""); @@ -44,8 +72,7 @@ const useAppState = () => { const [activeInstall, setActiveInstall] = useState("default"); const [editingInstall, setEditingInstall] = useState(null); const [dialogVersionOpen, setDialogVersionOpen] = useState(false); - const selectedVersion = - installations.find((i) => i.id === activeInstall)?.version || "1.21.11"; + const selectedVersion = installations.find((i) => i.id === activeInstall)?.version || "1.21.11"; const [versions, setVersions] = useState([]); const [showSnapshots, setShowSnapshots] = useState(false); const [launching, setLaunching] = useState(false); @@ -61,8 +88,7 @@ const useAppState = () => { body: string; } | null>(null); - const launcherSettings= useLauncherSettings(); - console.log(launcherSettings); + const launcherSettings = useLauncherSettings(); return { account, @@ -75,10 +101,6 @@ const useAppState = () => { accountDropdownOpen, setAccountDropdownOpen, server, - keepOpen, - setKeepOpen, - useConsole, - setUseConsole, modView, setModView, modSearch, @@ -120,9 +142,9 @@ type AppState = ReturnType; const AppStateContext = createContext(null); -export function AppStateProvider({children}: { children: ReactNode }) { +export function AppStateProvider({ children }: { children: ReactNode }) { const state = useAppState(); - return createElement(AppStateContext.Provider, {value: state}, children); + return createElement(AppStateContext.Provider, { value: state }, children); } export function useAppStateContext(): AppState { diff --git a/launcher/src/lib/types.ts b/launcher/src/lib/types.ts index e5f8b7cf..0908ddae 100644 --- a/launcher/src/lib/types.ts +++ b/launcher/src/lib/types.ts @@ -36,4 +36,4 @@ export interface LauncherSettings { language: string; keepLauncherOpen: boolean; launchWithConsole: boolean; -} \ No newline at end of file +} diff --git a/launcher/src/main.tsx b/launcher/src/main.tsx index 0feacfc1..d6516efb 100644 --- a/launcher/src/main.tsx +++ b/launcher/src/main.tsx @@ -6,5 +6,5 @@ import Router from "./Router"; ReactDOM.createRoot(document.getElementById("root")!).render( - + , ); diff --git a/launcher/src/pages/Friends.tsx b/launcher/src/pages/Friends.tsx index 288d9e50..352ce98a 100644 --- a/launcher/src/pages/Friends.tsx +++ b/launcher/src/pages/Friends.tsx @@ -18,7 +18,9 @@ export default function FriendsPage() { {f.name} {f.server}
- +
))} @@ -37,5 +39,5 @@ export default function FriendsPage() { ))}
- ) + ); } diff --git a/launcher/src/pages/Home.tsx b/launcher/src/pages/Home.tsx index f4a39c22..7b4ccd2b 100644 --- a/launcher/src/pages/Home.tsx +++ b/launcher/src/pages/Home.tsx @@ -8,10 +8,7 @@ interface HomepageProps { openPatchNote: (item: PatchNote) => Promise; } -export default function Homepage({ - handleLaunch, - openPatchNote, -}: HomepageProps) { +export default function Homepage({ handleLaunch, openPatchNote }: HomepageProps) { const [versionDropdownOpen, setVersionDropdownOpen] = useState(false); const { @@ -41,18 +38,13 @@ export default function Homepage({ disabled={launching} > - - {launching ? "LAUNCHING..." : "PLAY"} - + {launching ? "LAUNCHING..." : "PLAY"}
{versionDropdownOpen && ( -
setVersionDropdownOpen(false)} - /> +
setVersionDropdownOpen(false)} /> )} {versionDropdownOpen && (
@@ -91,29 +81,18 @@ export default function Homepage({

LATEST NEWS

{news.slice(0, 3).map((item) => ( -
openPatchNote(item)} - > -
+
openPatchNote(item)}> +
{item.entry_type}
- - {item.date.replace(/-/g, ".")} - + {item.date.replace(/-/g, ".")}

{item.title}

{item.summary}

))} - {news.length === 0 && ( -

Loading patch notes...

- )} + {news.length === 0 &&

Loading patch notes...

}
diff --git a/launcher/src/pages/Installations.tsx b/launcher/src/pages/Installations.tsx index 5b43a881..9e1f4e7f 100644 --- a/launcher/src/pages/Installations.tsx +++ b/launcher/src/pages/Installations.tsx @@ -97,9 +97,7 @@ export default function InstallationsPage() { className="install-action-btn delete" title="Delete" onClick={() => { - setInstallations((prev) => - prev.filter((i) => i.id !== inst.id), - ); + setInstallations((prev) => prev.filter((i) => i.id !== inst.id)); if (activeInstall === inst.id) { setActiveInstall("default"); } diff --git a/launcher/src/pages/Mods.tsx b/launcher/src/pages/Mods.tsx index 518cbe38..2fb83c79 100644 --- a/launcher/src/pages/Mods.tsx +++ b/launcher/src/pages/Mods.tsx @@ -1,30 +1,80 @@ import { HiMagnifyingGlass, HiListBullet, HiSquares2X2, HiPuzzlePiece } from "react-icons/hi2"; import { useAppStateContext } from "../lib/state"; - export default function ModsPage() { - const { - modFilter, - modSearch, - setModSearch, - setModFilter, - modView, - setModView, - } = useAppStateContext(); + const { modFilter, modSearch, setModSearch, setModFilter, modView, setModView } = + useAppStateContext(); const mods = [ - { name: "Mod 1", cat: "performance", desc: "Rendering engine optimization for better frame rates", version: "0.6.1", downloads: "38M", installed: true }, - { name: "Mod 2", cat: "performance", desc: "Dynamic lighting and visual enhancement", version: "1.21.11", downloads: "142M", installed: false }, - { name: "Mod 3", cat: "shaders", desc: "Shader pack loader for post-processing effects", version: "1.8.0", downloads: "25M", installed: false }, - { name: "Mod 4", cat: "utility", desc: "Schematic building tools for pasting and moving structures", version: "0.19.0", downloads: "18M", installed: false }, - { name: "Mod 5", cat: "utility", desc: "Real-time mapping with waypoints and minimap", version: "6.0.0", downloads: "52M", installed: true }, - { name: "Mod 6", cat: "gameplay", desc: "Adds new biomes, creatures, and world generation", version: "2.3.0", downloads: "12M", installed: false }, - { name: "Mod 7", cat: "utility", desc: "Inventory sorting and management tools", version: "1.4.2", downloads: "8M", installed: false }, - { name: "Mod 8", cat: "shaders", desc: "Volumetric clouds and atmospheric effects", version: "3.1.0", downloads: "15M", installed: false }, + { + name: "Mod 1", + cat: "performance", + desc: "Rendering engine optimization for better frame rates", + version: "0.6.1", + downloads: "38M", + installed: true, + }, + { + name: "Mod 2", + cat: "performance", + desc: "Dynamic lighting and visual enhancement", + version: "1.21.11", + downloads: "142M", + installed: false, + }, + { + name: "Mod 3", + cat: "shaders", + desc: "Shader pack loader for post-processing effects", + version: "1.8.0", + downloads: "25M", + installed: false, + }, + { + name: "Mod 4", + cat: "utility", + desc: "Schematic building tools for pasting and moving structures", + version: "0.19.0", + downloads: "18M", + installed: false, + }, + { + name: "Mod 5", + cat: "utility", + desc: "Real-time mapping with waypoints and minimap", + version: "6.0.0", + downloads: "52M", + installed: true, + }, + { + name: "Mod 6", + cat: "gameplay", + desc: "Adds new biomes, creatures, and world generation", + version: "2.3.0", + downloads: "12M", + installed: false, + }, + { + name: "Mod 7", + cat: "utility", + desc: "Inventory sorting and management tools", + version: "1.4.2", + downloads: "8M", + installed: false, + }, + { + name: "Mod 8", + cat: "shaders", + desc: "Volumetric clouds and atmospheric effects", + version: "3.1.0", + downloads: "15M", + installed: false, + }, ]; - const filtered = mods.filter((m) => - (modFilter === "all" || m.cat === modFilter) && - m.name.toLowerCase().includes(modSearch.toLowerCase()) + const filtered = mods.filter( + (m) => + (modFilter === "all" || m.cat === modFilter) && + m.name.toLowerCase().includes(modSearch.toLowerCase()), ); return (
@@ -69,7 +119,9 @@ export default function ModsPage() {
{filtered.map((m) => (
-
+
+ +
{m.name} {m.desc} diff --git a/launcher/src/pages/News.tsx b/launcher/src/pages/News.tsx index 05d7cf24..893d2b29 100644 --- a/launcher/src/pages/News.tsx +++ b/launcher/src/pages/News.tsx @@ -1,31 +1,23 @@ import { HiArrowLeft } from "react-icons/hi2"; -import { useAppStateContext } from "../lib/state" +import { useAppStateContext } from "../lib/state"; import { PatchNote } from "../lib/types"; -export default function NewsPage({ openPatchNote }: { - openPatchNote: (note: PatchNote) => Promise +export default function NewsPage({ + openPatchNote, +}: { + openPatchNote: (note: PatchNote) => Promise; }) { - const { - selectedNote, - setSelectedNote, - news, - } = useAppStateContext(); + const { selectedNote, setSelectedNote, news } = useAppStateContext(); return (
{selectedNote ? (
-

{selectedNote.title}

-
+
) : ( <> @@ -43,26 +35,20 @@ export default function NewsPage({ openPatchNote }: { backgroundImage: `url(${item.image_url})`, }} > - - {item.entry_type} - + {item.entry_type}
- - {item.date.replace(/-/g, ".")} - + {item.date.replace(/-/g, ".")}

{item.title}

{item.summary}

{item.version}
))} - {news.length === 0 && ( -

Loading patch notes...

- )} + {news.length === 0 &&

Loading patch notes...

}
)}
- ) + ); } diff --git a/launcher/src/pages/Servers.tsx b/launcher/src/pages/Servers.tsx index ee2bc839..f8261b04 100644 --- a/launcher/src/pages/Servers.tsx +++ b/launcher/src/pages/Servers.tsx @@ -2,32 +2,32 @@ import { HiPlay } from "react-icons/hi2"; export default function ServersPage() { return ( -
-
This is a preview - functionality coming soon
-

SERVERS

-
- {[ - { name: "Hypixel", ip: "mc.hypixel.net", players: "48,231", ping: "32ms", online: true }, - { name: "My SMP", ip: "play.mysmp.com", players: "12", ping: "8ms", online: true }, - { name: "Mineplex", ip: "us.mineplex.com", players: "3,891", ping: "45ms", online: true }, - { name: "Local Server", ip: "localhost:25565", players: "1", ping: "1ms", online: false }, - ].map((s) => ( -
-
-
+
+
This is a preview - functionality coming soon
+

SERVERS

+
+ {[ + { name: "Hypixel", ip: "mc.hypixel.net", players: "48,231", ping: "32ms", online: true }, + { name: "My SMP", ip: "play.mysmp.com", players: "12", ping: "8ms", online: true }, + { name: "Mineplex", ip: "us.mineplex.com", players: "3,891", ping: "45ms", online: true }, + { name: "Local Server", ip: "localhost:25565", players: "1", ping: "1ms", online: false }, + ].map((s) => ( +
+
+
+
+
+ {s.name} + {s.ip} +
+ {s.players} players + {s.ping} +
-
- {s.name} - {s.ip} -
- {s.players} players - {s.ping} - -
- ))} + ))} +
-
- ) + ); } diff --git a/launcher/src/pages/Settings.tsx b/launcher/src/pages/Settings.tsx index bfc48323..bd1ef0c6 100644 --- a/launcher/src/pages/Settings.tsx +++ b/launcher/src/pages/Settings.tsx @@ -1,15 +1,7 @@ -import { useAppStateContext } from "../lib/state" +import {useAppStateContext} from "../lib/state"; export default function SettingsPage() { - const { - keepOpen, - setKeepOpen, - useConsole, - setUseConsole, - launcherSettings, - } = useAppStateContext(); - - console.log("launchWithConsole:", launcherSettings.launchWithConsole); + const {launcherSettings} = useAppStateContext(); return (
@@ -21,41 +13,33 @@ export default function SettingsPage() {
Language - - Display language for the launcher - + Display language for the launcher
- +
- - Keep launcher open - - - Keep the launcher open after the game starts - + Keep launcher open + Keep the launcher open after the game starts
- - Launch with console - + Launch with console Automatically open a window with all output from the client- useful when debugging. @@ -63,13 +47,15 @@ export default function SettingsPage() {
- ) + ); } From 27c0cefe7b1b2c7554cc3c8d92b97beaee30bd01 Mon Sep 17 00:00:00 2001 From: arse09 Date: Tue, 24 Mar 2026 03:54:01 +0100 Subject: [PATCH 4/6] style(storage): formatter fixes --- launcher/src/lib/state.ts | 1 + launcher/src/pages/Settings.tsx | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/launcher/src/lib/state.ts b/launcher/src/lib/state.ts index 6eed5fd0..3d501b52 100644 --- a/launcher/src/lib/state.ts +++ b/launcher/src/lib/state.ts @@ -47,6 +47,7 @@ const useLauncherSettings = () => { setLaunchWithConsole, }; }; + const useAppState = () => { const [page, setPage] = useState("home"); const [accounts, setAccounts] = useState([]); diff --git a/launcher/src/pages/Settings.tsx b/launcher/src/pages/Settings.tsx index bd1ef0c6..ddab74d5 100644 --- a/launcher/src/pages/Settings.tsx +++ b/launcher/src/pages/Settings.tsx @@ -1,7 +1,7 @@ -import {useAppStateContext} from "../lib/state"; +import { useAppStateContext } from "../lib/state"; export default function SettingsPage() { - const {launcherSettings} = useAppStateContext(); + const { launcherSettings } = useAppStateContext(); return (
@@ -32,7 +32,7 @@ export default function SettingsPage() { launcherSettings.setKeepLauncherOpen(!launcherSettings.keepLauncherOpen) } > -
+
@@ -51,7 +51,7 @@ export default function SettingsPage() { launcherSettings.setLaunchWithConsole(!launcherSettings.launchWithConsole) } > -
+
From 170037bc52e399fefd18e7e151a874abf510781d Mon Sep 17 00:00:00 2001 From: arse09 Date: Tue, 24 Mar 2026 14:19:39 +0100 Subject: [PATCH 5/6] fix(storage): cache data_dir with LazyLock instead of recomputing on every call --- launcher/src-tauri/src/storage.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/launcher/src-tauri/src/storage.rs b/launcher/src-tauri/src/storage.rs index c70c0a41..9a92ab47 100644 --- a/launcher/src-tauri/src/storage.rs +++ b/launcher/src-tauri/src/storage.rs @@ -1,4 +1,17 @@ use std::path::{Path, PathBuf}; +use std::sync::LazyLock; + +static DATA_DIR: LazyLock = { + LazyLock::new(|| { + directories::ProjectDirs::from("", "", ".pomc") + .map(|d| d.data_dir().to_path_buf()) + .unwrap_or_else(|| PathBuf::from(".pomc")) + }) +}; + +pub fn data_dir() -> &'static Path { + &DATA_DIR +} fn ensure_file(path: &Path, default: &str) { if !path.exists() { @@ -19,12 +32,6 @@ pub fn ensure_dirs() { ensure_file(&installations_file(), "[]"); } -pub fn data_dir() -> PathBuf { - directories::ProjectDirs::from("", "", ".pomc") - .map(|d| d.data_dir().to_path_buf()) - .unwrap_or_else(|| PathBuf::from(".pomc")) -} - pub fn assets_dir() -> PathBuf { data_dir().join("assets") } From dfed9cb009fc325b164f93b5e5432d59557ba248 Mon Sep 17 00:00:00 2001 From: arse09 Date: Tue, 24 Mar 2026 14:56:51 +0100 Subject: [PATCH 6/6] fix(storage): load settings once into RwLock, async save with tokio::fs --- launcher/src-tauri/src/commands.rs | 9 ++++---- launcher/src-tauri/src/settings.rs | 35 ++++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/launcher/src-tauri/src/commands.rs b/launcher/src-tauri/src/commands.rs index b86b14f5..303ef80a 100644 --- a/launcher/src-tauri/src/commands.rs +++ b/launcher/src-tauri/src/commands.rs @@ -417,20 +417,21 @@ fn find_client_binary() -> Result { #[tauri::command] pub async fn load_launcher_settings() -> LauncherSettings { - LauncherSettings::load() + let settings = LauncherSettings::get().await; + settings.clone() } #[tauri::command] pub async fn set_launcher_language(language: String) -> Result<(), String> { - LauncherSettings::update_settings(|s| s.language = language) + LauncherSettings::update(|s| s.language = language).await } #[tauri::command] pub async fn set_keep_launcher_open(keep: bool) -> Result<(), String> { - LauncherSettings::update_settings(|s| s.keep_launcher_open = keep) + LauncherSettings::update(|s| s.keep_launcher_open = keep).await } #[tauri::command] pub async fn set_launch_with_console(launch: bool) -> Result<(), String> { - LauncherSettings::update_settings(|s| s.launch_with_console = launch) + LauncherSettings::update(|s| s.launch_with_console = launch).await } diff --git a/launcher/src-tauri/src/settings.rs b/launcher/src-tauri/src/settings.rs index 90a4c8c7..37e70e12 100644 --- a/launcher/src-tauri/src/settings.rs +++ b/launcher/src-tauri/src/settings.rs @@ -1,7 +1,12 @@ use crate::storage; use serde::{Deserialize, Serialize}; +use std::sync::LazyLock; +use tokio::sync::{RwLock, RwLockReadGuard}; -#[derive(Serialize, Deserialize, Debug)] +static LAUNCHER_SETTINGS: LazyLock> = + LazyLock::new(|| RwLock::new(LauncherSettings::load())); + +#[derive(Serialize, Deserialize, Debug, Clone)] #[serde(rename_all = "camelCase")] pub struct LauncherSettings { pub language: String, @@ -20,14 +25,16 @@ impl Default for LauncherSettings { } impl LauncherSettings { - pub fn save(&self) -> Result<(), String> { + async fn save(&self) -> Result<(), String> { let path = storage::settings_file(); let json = serde_json::to_string_pretty(self).map_err(|e| e.to_string())?; - std::fs::write(path, json).map_err(|e| e.to_string())?; + tokio::fs::write(path, json) + .await + .map_err(|e| e.to_string())?; Ok(()) } - pub fn load() -> Self { + fn load() -> Self { let path = storage::settings_file(); match std::fs::read_to_string(&path) { @@ -43,16 +50,26 @@ impl LauncherSettings { } let default = LauncherSettings::default(); - let _ = default.save(); + if let Ok(json) = serde_json::to_string_pretty(&default) { + let _ = std::fs::write(&path, json); + } default } - pub fn update_settings(f: F) -> Result<(), String> + pub async fn get() -> RwLockReadGuard<'static, LauncherSettings> { + LAUNCHER_SETTINGS.read().await + } + + pub async fn update(f: F) -> Result<(), String> where F: FnOnce(&mut LauncherSettings), { - let mut settings = LauncherSettings::load(); - f(&mut settings); - settings.save() + let cloned = { + let mut settings = LAUNCHER_SETTINGS.write().await; + f(&mut settings); + settings.clone() + }; + + cloned.save().await } }