diff --git a/.gitignore b/.gitignore index dcc6dbe..ca1c78b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,27 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +!.vscode/settings.json +.idea .DS_Store -/node_modules/ -*.tsbuildinfo +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? -# React Router -/.react-router/ -/build/ -user_*.json -/dist/ +.react-router diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..24d7cc6 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["tauri-apps.tauri-vscode", "rust-lang.rust-analyzer"] +} diff --git a/.vscode/settings.json b/.vscode/settings.json index b2acb54..f2a2aef 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,16 +1,9 @@ { - "editor.insertSpaces": false, + "files.trimTrailingWhitespace": true, "editor.formatOnSave": true, "editor.tabSize": 2, - "files.insertFinalNewline": true, - "files.trimTrailingWhitespace": true, - "typescript.tsdk": "node_modules/typescript/lib", - "search.exclude": { - "**/node_modules": true, - "**/bower_components": true, - "**/*.code-search": true, - "**/lib": true, - "**/build": true, - "**/dist": true + "editor.insertSpaces": false, + "editor.codeActionsOnSave": { + "source.organizeImports.biome": "explicit" } } diff --git a/README.md b/README.md index c1ca5b3..78b9392 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,35 @@ # ValPal -I've created this project to allow Valorant players to create loadouts which can be randomized when joining a game. It supports agent specific loadouts, player cards, player titles, sprays, buddies, skin levels, and skin chromas. +A desktop app for Valorant players to create and randomize loadouts when joining a game. Supports agent-specific loadouts, player cards, player titles, sprays, buddies, skin levels, and skin chromas. -# Screenshots +## Features -Configurator main screen showing a loadout - -Configurator main screen showing an agent specific loadout - +- **Auto Shuffle** — automatically equips a random loadout when you lock in an agent +- **Agent Detection** — filters loadouts to ones matching your selected agent +- **Non-Pregame Shuffle** — randomizes loadouts for modes without agent select (Deathmatch, Escalation, Team Deathmatch, etc.) +- **Manual Equip** — equip any saved loadout on demand from the app -# Installation +## Installation -1. You can find the latest release [here](https://github.com/zachrip/valpal/releases/latest) - download valpal.exe -2. Create a folder somewhere (desktop or your user directory, or wherever else, you do you) -3. Run the .exe - windows will probably complain, click "more info" then "run anyway" -4. You should see an item added to your system tray - right click on it and click "Open ValPal" - this will open your browser to the configurator -5. Open Valorant (you must run the game for this to work) -6. Add a loadout and configure it with your skins -7. When you join a match, the app will detect when you've locked in as an agent. If you have `Agent specific loadouts` enabled it will configure loadouts for that agent if there are any (otherwise it will fall back to all enabled loadouts). You can disable the loadout shuffling all together if you prefer to equip loadouts by hand in the configurator +1. Download the latest `.msi` installer from [Releases](https://github.com/zachrip/valpal/releases/latest) +2. Run the installer — Windows may complain, click "More info" then "Run anyway" +3. Launch ValPal — it will appear in your system tray +4. Open Valorant +5. Create a loadout and configure it with your skins +6. When you join a match, the app will detect your agent lock-in and equip a random matching loadout -# Architecture +## Architecture -This app is based around [Remix](https://remix.run) and packaged using [pkg](https://github.com/vercel/pkg). It uses the local websocket/http server that Valorant runs to authenticate and detect when matches start. +ValPal is a [Tauri](https://tauri.app) app with a [React Router](https://reactrouter.com) frontend and a Rust backend. The backend connects to Valorant's local WebSocket/HTTP APIs to authenticate, detect game events, and manage loadouts. -# Contribute +- `src/` — React frontend (UI, loadout editor) +- `src-tauri/` — Rust backend (game detection, Valorant API integration, system tray) -1. Clone this repo -2. `npm install` -3. `npm run dev` -4. Run Valorant -5. Open [http://localhost:3000](http://localhost:3000) -6. The configurator code mostly lives in app/ - the rest of the stuff is in server/ (such as the game detection, system tray stuff, etc) +## Development + +Prerequisites: [Node.js](https://nodejs.org), [pnpm](https://pnpm.io), [Rust](https://rustup.rs) + +``` +pnpm install +pnpm tauri dev +``` diff --git a/app/app.css b/app/app.css deleted file mode 100644 index d9f1180..0000000 --- a/app/app.css +++ /dev/null @@ -1,17 +0,0 @@ -@font-face { - font-family: 'GolosUIWebVF'; - src: url('../fonts/golos-ui/golos-ui_vf.woff2') format('woff2'), - url('../fonts/golos-ui/golos-ui_vf.woff') format('woff'); - font-weight: normal; - font-style: normal; -} - -@tailwind base; -@tailwind components; -@tailwind utilities; - -@layer base { - html { - font-family: 'GolosUIWebVF', system-ui, sans-serif; - } -} diff --git a/app/root.tsx b/app/root.tsx deleted file mode 100644 index 11b9ffe..0000000 --- a/app/root.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import { - isRouteErrorResponse, - Links, - Meta, - Outlet, - Scripts, - ScrollRestoration, -} from "react-router"; - -import type { Route } from "./+types/root"; -import stylesheet from "./app.css?url"; - -export const links: Route.LinksFunction = () => [ - { rel: 'stylesheet', href: stylesheet }, - { rel: 'preconnect', href: 'https://fonts.googleapis.com' }, - { - rel: 'preconnect', - href: 'https://fonts.gstatic.com', - crossOrigin: 'anonymous' - }, - { - rel: 'stylesheet', - href: 'https://fonts.googleapis.com/css2?family=Readex+Pro:wght@200;300;400;500;600;700&display=swap', - }, -]; - -export function Layout({ children }: { children: React.ReactNode }) { - return ( - - - - - - - - - {children} - - - - - ); -} - -export default function App() { - return ; -} - -export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) { - let message = "Oops!"; - let details = "An unexpected error occurred."; - let stack: string | undefined; - - if (isRouteErrorResponse(error)) { - message = error.status === 404 ? "404" : "Error"; - details = - error.status === 404 - ? "The requested page could not be found." - : error.statusText || details; - } else if (import.meta.env.DEV && error && error instanceof Error) { - details = error.message; - stack = error.stack; - } - - return ( -
-

{message}

-

{details}

- {stack && ( -
-          {stack}
-        
- )} -
- ); -} diff --git a/app/routes.ts b/app/routes.ts deleted file mode 100644 index 1e3ba6b..0000000 --- a/app/routes.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { - type RouteConfig, - index, - layout, - prefix, - route, -} from '@react-router/dev/routes'; - -export default [ - index('routes/index.tsx'), - route('/login', 'routes/login.tsx'), - ...prefix('loadouts', [ - index('routes/loadouts/index.tsx'), - route(':loadoutId', 'routes/loadouts/$loadoutId.tsx', [ - route( - 'playercards/add', - 'routes/loadouts/$loadoutId/playercards/add.tsx', - ), - route( - 'playertitles/add', - 'routes/loadouts/$loadoutId/playertitles/add.tsx', - ), - ...prefix('expressions', [ - route('top', 'routes/loadouts/$loadoutId/expressions/top.tsx'), - route('bottom', 'routes/loadouts/$loadoutId/expressions/bottom.tsx'), - route('left', 'routes/loadouts/$loadoutId/expressions/left.tsx'), - route('right', 'routes/loadouts/$loadoutId/expressions/right.tsx'), - ]), - ...prefix('weapons/:weaponId', [ - index('routes/loadouts/$loadoutId/weapons/$weaponId/index.tsx'), - ...prefix('templates', [ - route( - 'new', - 'routes/loadouts/$loadoutId/weapons/$weaponId/templates/new.tsx', - ), - route( - ':templateId/edit', - 'routes/loadouts/$loadoutId/weapons/$weaponId/templates/$templateId/edit.tsx', - ), - ]), - ]), - ]), - ]), -] satisfies RouteConfig; diff --git a/app/routes/index.tsx b/app/routes/index.tsx deleted file mode 100644 index d422b69..0000000 --- a/app/routes/index.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { redirect } from 'react-router'; -import { useLoaderData } from 'react-router'; -import { getUser } from '~/utils.server'; - -export async function loader() { - const user = await getUser(); - - if (!user) { - throw redirect('/login'); - } - - throw redirect('/loadouts'); -} - -export default function Index() { - const { userId } = useLoaderData(); - - return
{userId}
; -} diff --git a/app/routes/loadouts/$loadoutId.tsx b/app/routes/loadouts/$loadoutId.tsx deleted file mode 100644 index 27f2b20..0000000 --- a/app/routes/loadouts/$loadoutId.tsx +++ /dev/null @@ -1,572 +0,0 @@ -import type { LoaderFunctionArgs } from 'react-router'; -import { redirect } from 'react-router'; -import { Form, Link, Outlet, useLoaderData, useSubmit } from 'react-router'; -import { zfd } from 'zod-form-data'; -import { z } from 'zod'; - -import type { WeaponCategory } from 'types'; -import { Gallery } from '~/components/Gallery'; - -import { - categoryCanonicalNameMap, - categoryNameMap, - sortedWeapons, -} from '~/utils'; -import { getUser, getUserConfig, saveUserConfig } from '~/utils.server'; - -const updateSchema = zfd.formData({ - name: zfd.text(z.string().optional().default('Loadout')), - agents: z.record(z.string(), zfd.checkbox()).optional(), -}); - -export async function action({ request, params }: LoaderFunctionArgs) { - const user = await getUser(); - - if (!user) { - throw redirect('/login'); - } - - const formData = await request.formData(); - const action = formData.get('action') as string; - - switch (action) { - case 'update': { - const loadoutId = params.loadoutId; - const config = await getUserConfig(user.userId); - const loadout = config.loadouts.find( - (loadout) => loadout.id === loadoutId, - ); - - if (!loadout) { - throw redirect('/loadouts'); - } - - const { name, agents } = updateSchema.parse(formData); - - loadout.name = name; - loadout.agentIds = Object.entries(agents || {}).reduce>( - (acc, next) => { - if (next[1]) { - acc.push(next[0]); - } - return acc; - }, - [], - ); - await saveUserConfig(user.userId, config); - throw redirect(`/loadouts/${loadoutId}`); - } - default: { - throw new Error('Invalid action'); - } - } -} - -export const loader = async ({ params }: LoaderFunctionArgs) => { - const user = await getUser(); - - if (!user) { - throw redirect('/login'); - } - - const { loadoutId } = params; - - const userConfig = await getUserConfig(user.userId); - const loadout = userConfig.loadouts.find( - (loadout) => loadout.id === loadoutId, - ); - - if (!loadout) { - throw redirect('/loadouts'); - } - - const weapons = valorantData.weapons; - - return { - allAgents: valorantData.agents, - loadout: { - id: loadout.id, - name: loadout.name, - agents: loadout.agentIds.map((agentId) => { - const agent = valorantData.agents.find( - (agent) => agent.uuid === agentId, - )!; - return agent; - }), - playerCards: (loadout.playerCardIds.length - ? loadout.playerCardIds - : ['9fb348bc-41a0-91ad-8a3e-818035c4e561'] - ).map((id) => valorantData.playerCards.find((card) => card.uuid === id)!), - playerTitles: (loadout.playerTitleIds.length - ? loadout.playerTitleIds - : ['d13e579c-435e-44d4-cec2-6eae5a3c5ed4'] - ).map( - (id) => valorantData.playerTitles.find((title) => title.uuid === id)!, - ), - expressions: { - top: { - sprayIds: (loadout.expressionIds.top.sprayIds.length || - loadout.expressionIds.top.flexIds.length - ? loadout.expressionIds.top.sprayIds - : ['0a6db78c-48b9-a32d-c47a-82be597584c1'] - ).map( - (sprayId) => - valorantData.sprays.find((spray) => spray.uuid === sprayId)!, - ), - flexIds: loadout.expressionIds.top.flexIds.map( - (flexId) => valorantData.flex.find((flex) => flex.uuid === flexId)!, - ), - }, - right: { - sprayIds: (loadout.expressionIds.right.sprayIds.length || - loadout.expressionIds.right.flexIds.length - ? loadout.expressionIds.right.sprayIds - : ['0a6db78c-48b9-a32d-c47a-82be597584c1'] - ).map( - (sprayId) => - valorantData.sprays.find((spray) => spray.uuid === sprayId)!, - ), - flexIds: loadout.expressionIds.right.flexIds.map( - (flexId) => valorantData.flex.find((flex) => flex.uuid === flexId)!, - ), - }, - bottom: { - sprayIds: (loadout.expressionIds.bottom.sprayIds.length || - loadout.expressionIds.bottom.flexIds.length - ? loadout.expressionIds.bottom.sprayIds - : ['0a6db78c-48b9-a32d-c47a-82be597584c1'] - ).map( - (sprayId) => - valorantData.sprays.find((spray) => spray.uuid === sprayId)!, - ), - flexIds: loadout.expressionIds.bottom.flexIds.map( - (flexId) => valorantData.flex.find((flex) => flex.uuid === flexId)!, - ), - }, - left: { - sprayIds: loadout.expressionIds.left.sprayIds.map( - (sprayId) => - valorantData.sprays.find((spray) => spray.uuid === sprayId)!, - ), - flexIds: (loadout.expressionIds.left.flexIds.length || - loadout.expressionIds.left.sprayIds.length - ? loadout.expressionIds.left.flexIds - : ['af52b5a0-4a4c-03b2-c9d7-8187a08a2675'] - ).map( - (flexId) => valorantData.flex.find((flex) => flex.uuid === flexId)!, - ), - }, - }, - weapons: Object.entries(loadout.weapons).map( - ([weaponId, { templates }]) => { - const weapon = weapons.find((w) => w.uuid === weaponId)!; - - return { - id: weaponId, - displayName: weapon.displayName, - displayIcon: weapon.displayIcon, - category: weapon.category, - uuid: weapon.uuid, - templates: templates.map((template) => { - const skin = weapon.skins.find( - (skin) => skin.uuid === template.skinId, - )!; - const chromas = skin.chromas.filter((chroma) => - template.chromaIds.includes(chroma.uuid), - ); - const buddies = template.buddies.flatMap((buddy) => { - const buddyData = valorantData.buddies.find( - (b) => b.uuid === buddy.id, - )!; - - return buddy.levelIds.flatMap((levelId) => { - return { - id: buddy.id, - levelId, - displayName: buddyData.displayName, - displayIcon: buddyData.displayIcon, - }; - }); - }); - - return { - id: template.id, - skin, - chromas, - buddies, - }; - }), - }; - }, - ), - }, - }; -}; - -export default function Index() { - const { loadout, allAgents } = useLoaderData(); - const categories = loadout.weapons.reduce< - Record - >( - (acc, weapon) => { - const index = sortedWeapons[weapon.category].indexOf( - weapon.displayName.toLowerCase(), - ); - acc[weapon.category][index] = weapon; - return acc; - }, - { - 'EEquippableCategory::Sidearm': [], - 'EEquippableCategory::SMG': [], - 'EEquippableCategory::Rifle': [], - 'EEquippableCategory::Sniper': [], - 'EEquippableCategory::Shotgun': [], - 'EEquippableCategory::Heavy': [], - 'EEquippableCategory::Melee': [], - }, - ); - - const submit = useSubmit(); - - return ( - <> -
- - - - - Loadouts - -
{ - submit(e.currentTarget, { - replace: true, - }); - }} - > - -
-

- Loadout Name -

-
- -
-
-
-

Agents

-
- {allAgents.map((agent) => ( -
- a.uuid === agent.uuid, - )} - /> - -
- ))} -
-
-
- - - ); -} diff --git a/app/routes/loadouts/$loadoutId/expressions/bottom.tsx b/app/routes/loadouts/$loadoutId/expressions/bottom.tsx deleted file mode 100644 index a53b83f..0000000 --- a/app/routes/loadouts/$loadoutId/expressions/bottom.tsx +++ /dev/null @@ -1,271 +0,0 @@ -import { - Form, - useLoaderData, - useNavigate, - useParams, - useSubmit, -} from 'react-router'; -import * as DialogPrimitive from '@radix-ui/react-dialog'; -import * as TabsPrimitive from '@radix-ui/react-tabs'; -import type { Loadout } from '~/utils'; -import type { ActionFunctionArgs, LoaderFunctionArgs } from 'react-router'; -import { redirect } from 'react-router'; -import { getUser, getUserConfig, saveUserConfig } from '~/utils.server'; -import { zfd } from 'zod-form-data'; -import { z } from 'zod'; - -const schema = zfd.formData({ - tab: z.enum(['sprays', 'flex']), - sprays: z.record(z.string(), zfd.checkbox()).optional(), - flex: z.record(z.string(), zfd.checkbox()).optional(), -}); - -export async function action({ request, params }: ActionFunctionArgs) { - const user = await getUser(); - if (!user) { - throw redirect('/login'); - } - - const { loadoutId } = params; - - const userConfig = await getUserConfig(user.userId); - const loadout = userConfig.loadouts.find( - (loadout) => loadout.id === loadoutId, - ); - - if (!loadout) { - throw redirect('/loadouts'); - } - - const formData = await request.formData(); - - const out = schema.parse(formData); - - const newLoadout: Loadout = { - ...loadout, - expressionIds: { - ...loadout.expressionIds, - bottom: { - ...loadout.expressionIds.bottom, - ...(out.tab === 'sprays' - ? { - sprayIds: Object.entries(out.sprays || {}).reduce>( - (acc, next) => { - if (next[1]) { - acc.push(next[0]); - } - return acc; - }, - [], - ), - flexIds: loadout.expressionIds.bottom.flexIds, - } - : { - flexIds: Object.entries(out.flex || {}).reduce>( - (acc, next) => { - if (next[1]) { - acc.push(next[0]); - } - return acc; - }, - [], - ), - sprayIds: loadout.expressionIds.bottom.sprayIds, - }), - }, - }, - }; - - await saveUserConfig(user.userId, { - loadouts: [ - ...userConfig.loadouts.filter((l) => l.id !== loadoutId), - newLoadout, - ], - }); - - return { - success: true, - }; -} - -export async function loader({ params }: LoaderFunctionArgs) { - const user = await getUser(); - - if (!user) { - throw redirect('/login'); - } - - const { loadoutId } = params; - - const userConfig = await getUserConfig(user.userId); - const loadout = userConfig.loadouts.find( - (loadout) => loadout.id === loadoutId, - ); - - if (!loadout) { - throw redirect('/loadouts'); - } - - const entitlements = await user.getEntitlements(); - - const selectedSprays = loadout.expressionIds.bottom.sprayIds; - const ownedSprays = valorantData.sprays - .filter((spray) => - entitlements.spray.some( - (entitlement) => entitlement.ItemID === spray.uuid, - ), - ) - .sort((a, b) => a.displayName.localeCompare(b.displayName)); - - const selectedFlex = loadout.expressionIds.bottom.flexIds; - const ownedFlex = valorantData.flex - .filter((flex) => - entitlements.flex.some((entitlement) => entitlement.ItemID === flex.uuid), - ) - .sort((a, b) => a.displayName.localeCompare(b.displayName)); - - return { - selectedSprays, - ownedSprays, - selectedFlex, - ownedFlex, - }; -} - -export default function AddBottomSpray() { - const { ownedSprays, selectedSprays, ownedFlex, selectedFlex } = - useLoaderData(); - const navigate = useNavigate(); - const params = useParams(); - const submit = useSubmit(); - - return ( - navigate(`/loadouts/${params.loadoutId}`)} - > - - - -
- - Select Bottom Slot Expressions - - - - - - -
- - - - Sprays - - - Flex - - -
{ - submit(e.currentTarget, { - replace: true, - }); - }} - className="flex-auto overflow-y-auto scrollbar-thin scrollbar-thumb-white scrollbar-track-transparent scrollbar-thumb-rounded-full px-4 mr-4 mb-4 mt-4" - > - - -
- {ownedSprays.map((spray) => ( -
- - -
- ))} -
-
- - -
- {ownedFlex.map((flex) => ( -
- - -
- ))} -
-
-
-
-
-
-
-
- ); -} diff --git a/app/routes/loadouts/$loadoutId/expressions/left.tsx b/app/routes/loadouts/$loadoutId/expressions/left.tsx deleted file mode 100644 index 8b5277b..0000000 --- a/app/routes/loadouts/$loadoutId/expressions/left.tsx +++ /dev/null @@ -1,271 +0,0 @@ -import { - Form, - useLoaderData, - useNavigate, - useParams, - useSubmit, -} from 'react-router'; -import * as DialogPrimitive from '@radix-ui/react-dialog'; -import * as TabsPrimitive from '@radix-ui/react-tabs'; -import type { Loadout } from '~/utils'; -import type { ActionFunctionArgs, LoaderFunctionArgs } from 'react-router'; -import { redirect } from 'react-router'; -import { getUser, getUserConfig, saveUserConfig } from '~/utils.server'; -import { zfd } from 'zod-form-data'; -import { z } from 'zod'; - -const schema = zfd.formData({ - tab: z.enum(['sprays', 'flex']), - sprays: z.record(z.string(), zfd.checkbox()).optional(), - flex: z.record(z.string(), zfd.checkbox()).optional(), -}); - -export async function action({ request, params }: ActionFunctionArgs) { - const user = await getUser(); - if (!user) { - throw redirect('/login'); - } - - const { loadoutId } = params; - - const userConfig = await getUserConfig(user.userId); - const loadout = userConfig.loadouts.find( - (loadout) => loadout.id === loadoutId, - ); - - if (!loadout) { - throw redirect('/loadouts'); - } - - const formData = await request.formData(); - - const out = schema.parse(formData); - - const newLoadout: Loadout = { - ...loadout, - expressionIds: { - ...loadout.expressionIds, - left: { - ...loadout.expressionIds.left, - ...(out.tab === 'sprays' - ? { - sprayIds: Object.entries(out.sprays || {}).reduce>( - (acc, next) => { - if (next[1]) { - acc.push(next[0]); - } - return acc; - }, - [], - ), - flexIds: loadout.expressionIds.left.flexIds, - } - : { - flexIds: Object.entries(out.flex || {}).reduce>( - (acc, next) => { - if (next[1]) { - acc.push(next[0]); - } - return acc; - }, - [], - ), - sprayIds: loadout.expressionIds.left.sprayIds, - }), - }, - }, - }; - - await saveUserConfig(user.userId, { - loadouts: [ - ...userConfig.loadouts.filter((l) => l.id !== loadoutId), - newLoadout, - ], - }); - - return { - success: true, - }; -} - -export async function loader({ params }: LoaderFunctionArgs) { - const user = await getUser(); - - if (!user) { - throw redirect('/login'); - } - - const { loadoutId } = params; - - const userConfig = await getUserConfig(user.userId); - const loadout = userConfig.loadouts.find( - (loadout) => loadout.id === loadoutId, - ); - - if (!loadout) { - throw redirect('/loadouts'); - } - - const entitlements = await user.getEntitlements(); - - const selectedSprays = loadout.expressionIds.left.sprayIds; - const ownedSprays = valorantData.sprays - .filter((spray) => - entitlements.spray.some( - (entitlement) => entitlement.ItemID === spray.uuid, - ), - ) - .sort((a, b) => a.displayName.localeCompare(b.displayName)); - - const selectedFlex = loadout.expressionIds.left.flexIds; - const ownedFlex = valorantData.flex - .filter((flex) => - entitlements.flex.some((entitlement) => entitlement.ItemID === flex.uuid), - ) - .sort((a, b) => a.displayName.localeCompare(b.displayName)); - - return { - selectedSprays, - ownedSprays, - selectedFlex, - ownedFlex, - }; -} - -export default function AddLeftSpray() { - const { ownedSprays, selectedSprays, ownedFlex, selectedFlex } = - useLoaderData(); - const navigate = useNavigate(); - const params = useParams(); - const submit = useSubmit(); - - return ( - navigate(`/loadouts/${params.loadoutId}`)} - > - - - -
- - Select Left Slot Expressions - - - - - - -
- - - - Sprays - - - Flex - - -
{ - submit(e.currentTarget, { - replace: true, - }); - }} - className="flex-auto overflow-y-auto scrollbar-thin scrollbar-thumb-white scrollbar-track-transparent scrollbar-thumb-rounded-full px-4 mr-4 mb-4 mt-4" - > - - -
- {ownedSprays.map((spray) => ( -
- - -
- ))} -
-
- - -
- {ownedFlex.map((flex) => ( -
- - -
- ))} -
-
-
-
-
-
-
-
- ); -} diff --git a/app/routes/loadouts/$loadoutId/expressions/right.tsx b/app/routes/loadouts/$loadoutId/expressions/right.tsx deleted file mode 100644 index e2d8c1f..0000000 --- a/app/routes/loadouts/$loadoutId/expressions/right.tsx +++ /dev/null @@ -1,271 +0,0 @@ -import { - Form, - useLoaderData, - useNavigate, - useParams, - useSubmit, -} from 'react-router'; -import * as DialogPrimitive from '@radix-ui/react-dialog'; -import * as TabsPrimitive from '@radix-ui/react-tabs'; -import type { Loadout } from '~/utils'; -import type { ActionFunctionArgs, LoaderFunctionArgs } from 'react-router'; -import { redirect } from 'react-router'; -import { getUser, getUserConfig, saveUserConfig } from '~/utils.server'; -import { zfd } from 'zod-form-data'; -import { z } from 'zod'; - -const schema = zfd.formData({ - tab: z.enum(['sprays', 'flex']), - sprays: z.record(z.string(), zfd.checkbox()).optional(), - flex: z.record(z.string(), zfd.checkbox()).optional(), -}); - -export async function action({ request, params }: ActionFunctionArgs) { - const user = await getUser(); - if (!user) { - throw redirect('/login'); - } - - const { loadoutId } = params; - - const userConfig = await getUserConfig(user.userId); - const loadout = userConfig.loadouts.find( - (loadout) => loadout.id === loadoutId, - ); - - if (!loadout) { - throw redirect('/loadouts'); - } - - const formData = await request.formData(); - - const out = schema.parse(formData); - - const newLoadout: Loadout = { - ...loadout, - expressionIds: { - ...loadout.expressionIds, - right: { - ...loadout.expressionIds.right, - ...(out.tab === 'sprays' - ? { - sprayIds: Object.entries(out.sprays || {}).reduce>( - (acc, next) => { - if (next[1]) { - acc.push(next[0]); - } - return acc; - }, - [], - ), - flexIds: loadout.expressionIds.right.flexIds, - } - : { - flexIds: Object.entries(out.flex || {}).reduce>( - (acc, next) => { - if (next[1]) { - acc.push(next[0]); - } - return acc; - }, - [], - ), - sprayIds: loadout.expressionIds.right.sprayIds, - }), - }, - }, - }; - - await saveUserConfig(user.userId, { - loadouts: [ - ...userConfig.loadouts.filter((l) => l.id !== loadoutId), - newLoadout, - ], - }); - - return { - success: true, - }; -} - -export async function loader({ params }: LoaderFunctionArgs) { - const user = await getUser(); - - if (!user) { - throw redirect('/login'); - } - - const { loadoutId } = params; - - const userConfig = await getUserConfig(user.userId); - const loadout = userConfig.loadouts.find( - (loadout) => loadout.id === loadoutId, - ); - - if (!loadout) { - throw redirect('/loadouts'); - } - - const entitlements = await user.getEntitlements(); - - const selectedSprays = loadout.expressionIds.right.sprayIds; - const ownedSprays = valorantData.sprays - .filter((spray) => - entitlements.spray.some( - (entitlement) => entitlement.ItemID === spray.uuid, - ), - ) - .sort((a, b) => a.displayName.localeCompare(b.displayName)); - - const selectedFlex = loadout.expressionIds.right.flexIds; - const ownedFlex = valorantData.flex - .filter((flex) => - entitlements.flex.some((entitlement) => entitlement.ItemID === flex.uuid), - ) - .sort((a, b) => a.displayName.localeCompare(b.displayName)); - - return { - selectedSprays, - ownedSprays, - selectedFlex, - ownedFlex, - }; -} - -export default function AddRightSpray() { - const { ownedSprays, selectedSprays, ownedFlex, selectedFlex } = - useLoaderData(); - const navigate = useNavigate(); - const params = useParams(); - const submit = useSubmit(); - - return ( - navigate(`/loadouts/${params.loadoutId}`)} - > - - - -
- - Select Right Slot Expressions - - - - - - -
- - - - Sprays - - - Flex - - -
{ - submit(e.currentTarget, { - replace: true, - }); - }} - className="flex-auto overflow-y-auto scrollbar-thin scrollbar-thumb-white scrollbar-track-transparent scrollbar-thumb-rounded-full px-4 mr-4 mb-4 mt-4" - > - - -
- {ownedSprays.map((spray) => ( -
- - -
- ))} -
-
- - -
- {ownedFlex.map((flex) => ( -
- - -
- ))} -
-
-
-
-
-
-
-
- ); -} diff --git a/app/routes/loadouts/$loadoutId/expressions/top.tsx b/app/routes/loadouts/$loadoutId/expressions/top.tsx deleted file mode 100644 index e31ee2e..0000000 --- a/app/routes/loadouts/$loadoutId/expressions/top.tsx +++ /dev/null @@ -1,271 +0,0 @@ -import { - Form, - useLoaderData, - useNavigate, - useParams, - useSubmit, -} from 'react-router'; -import * as DialogPrimitive from '@radix-ui/react-dialog'; -import * as TabsPrimitive from '@radix-ui/react-tabs'; -import type { Loadout } from '~/utils'; -import type { ActionFunctionArgs, LoaderFunctionArgs } from 'react-router'; -import { redirect } from 'react-router'; -import { getUser, getUserConfig, saveUserConfig } from '~/utils.server'; -import { zfd } from 'zod-form-data'; -import { z } from 'zod'; - -const schema = zfd.formData({ - tab: z.enum(['sprays', 'flex']), - sprays: z.record(z.string(), zfd.checkbox()).optional(), - flex: z.record(z.string(), zfd.checkbox()).optional(), -}); - -export async function action({ request, params }: ActionFunctionArgs) { - const user = await getUser(); - if (!user) { - throw redirect('/login'); - } - - const { loadoutId } = params; - - const userConfig = await getUserConfig(user.userId); - const loadout = userConfig.loadouts.find( - (loadout) => loadout.id === loadoutId, - ); - - if (!loadout) { - throw redirect('/loadouts'); - } - - const formData = await request.formData(); - - const out = schema.parse(formData); - - const newLoadout: Loadout = { - ...loadout, - expressionIds: { - ...loadout.expressionIds, - top: { - ...loadout.expressionIds.top, - ...(out.tab === 'sprays' - ? { - sprayIds: Object.entries(out.sprays || {}).reduce>( - (acc, next) => { - if (next[1]) { - acc.push(next[0]); - } - return acc; - }, - [], - ), - flexIds: loadout.expressionIds.top.flexIds, - } - : { - flexIds: Object.entries(out.flex || {}).reduce>( - (acc, next) => { - if (next[1]) { - acc.push(next[0]); - } - return acc; - }, - [], - ), - sprayIds: loadout.expressionIds.top.sprayIds, - }), - }, - }, - }; - - await saveUserConfig(user.userId, { - loadouts: [ - ...userConfig.loadouts.filter((l) => l.id !== loadoutId), - newLoadout, - ], - }); - - return { - success: true, - }; -} - -export async function loader({ params }: LoaderFunctionArgs) { - const user = await getUser(); - - if (!user) { - throw redirect('/login'); - } - - const { loadoutId } = params; - - const userConfig = await getUserConfig(user.userId); - const loadout = userConfig.loadouts.find( - (loadout) => loadout.id === loadoutId, - ); - - if (!loadout) { - throw redirect('/loadouts'); - } - - const entitlements = await user.getEntitlements(); - - const selectedSprays = loadout.expressionIds.top.sprayIds; - const ownedSprays = valorantData.sprays - .filter((spray) => - entitlements.spray.some( - (entitlement) => entitlement.ItemID === spray.uuid, - ), - ) - .sort((a, b) => a.displayName.localeCompare(b.displayName)); - - const selectedFlex = loadout.expressionIds.top.flexIds; - const ownedFlex = valorantData.flex - .filter((flex) => - entitlements.flex.some((entitlement) => entitlement.ItemID === flex.uuid), - ) - .sort((a, b) => a.displayName.localeCompare(b.displayName)); - - return { - selectedSprays, - ownedSprays, - selectedFlex, - ownedFlex, - }; -} - -export default function AddTopSpray() { - const { ownedSprays, selectedSprays, ownedFlex, selectedFlex } = - useLoaderData(); - const navigate = useNavigate(); - const params = useParams(); - const submit = useSubmit(); - - return ( - navigate(`/loadouts/${params.loadoutId}`)} - > - - - -
- - Select Top Slot Expressions - - - - - - -
- - - - Sprays - - - Flex - - -
{ - submit(e.currentTarget, { - replace: true, - }); - }} - className="flex-auto overflow-y-auto scrollbar-thin scrollbar-thumb-white scrollbar-track-transparent scrollbar-thumb-rounded-full px-4 mr-4 mb-4 mt-4" - > - - -
- {ownedSprays.map((spray) => ( -
- - -
- ))} -
-
- - -
- {ownedFlex.map((flex) => ( -
- - -
- ))} -
-
-
-
-
-
-
-
- ); -} diff --git a/app/routes/loadouts/$loadoutId/playercards/add.tsx b/app/routes/loadouts/$loadoutId/playercards/add.tsx deleted file mode 100644 index 4293f3c..0000000 --- a/app/routes/loadouts/$loadoutId/playercards/add.tsx +++ /dev/null @@ -1,183 +0,0 @@ -import { - Form, - useLoaderData, - useNavigate, - useParams, - useSubmit, -} from 'react-router'; -import * as DialogPrimitive from '@radix-ui/react-dialog'; -import type { Loadout } from '~/utils'; -import type { ActionFunctionArgs, LoaderFunctionArgs } from 'react-router'; -import { redirect } from 'react-router'; -import { getUser, getUserConfig, saveUserConfig } from '~/utils.server'; -import { zfd } from 'zod-form-data'; -import { z } from 'zod'; - -const schema = zfd.formData({ - playerCards: z.record(z.string(), zfd.checkbox()).optional(), -}); - -export async function action({ request, params }: ActionFunctionArgs) { - const user = await getUser(); - if (!user) { - throw redirect('/login'); - } - - const { loadoutId } = params; - - const userConfig = await getUserConfig(user.userId); - const loadout = userConfig.loadouts.find( - (loadout) => loadout.id === loadoutId, - ); - - if (!loadout) { - throw redirect('/loadouts'); - } - - const formData = await request.formData(); - - const out = schema.parse(formData); - - const newLoadout: Loadout = { - ...loadout, - playerCardIds: Object.entries(out.playerCards || {}).reduce>( - (acc, next) => { - if (next[1]) { - acc.push(next[0]); - } - return acc; - }, - [], - ), - }; - - await saveUserConfig(user.userId, { - loadouts: [ - ...userConfig.loadouts.filter((l) => l.id !== loadoutId), - newLoadout, - ], - }); - - return { - success: true, - }; -} - -export async function loader({ params }: LoaderFunctionArgs) { - const user = await getUser(); - - if (!user) { - throw redirect('/login'); - } - - const { loadoutId } = params; - - const userConfig = await getUserConfig(user.userId); - const loadout = userConfig.loadouts.find( - (loadout) => loadout.id === loadoutId, - ); - - if (!loadout) { - throw redirect('/loadouts'); - } - - const entitlements = await user.getEntitlements(); - - const selectedPlayerCards = loadout.playerCardIds; - const ownedPlayerCards = valorantData.playerCards - .filter((playerCard) => - entitlements.player_card.some( - (entitlement) => entitlement.ItemID === playerCard.uuid, - ), - ) - .sort((a, b) => a.displayName.localeCompare(b.displayName)); - - return { - selectedPlayerCards, - ownedPlayerCards, - }; -} - -export default function AddPlayerCard() { - const { ownedPlayerCards, selectedPlayerCards } = - useLoaderData(); - const navigate = useNavigate(); - const params = useParams(); - const submit = useSubmit(); - - return ( - navigate(`/loadouts/${params.loadoutId}`)} - > - - - -
- - Select Player Cards - - - - - - -
-
{ - submit(e.currentTarget, { - replace: true, - }); - }} - className="flex-auto overflow-y-auto scrollbar-thin scrollbar-thumb-white scrollbar-track-transparent scrollbar-thumb-rounded-full px-4 mr-4 mb-4 mt-4" - > -
- {ownedPlayerCards.map((playerCard) => ( -
- - -
- ))} -
-
-
-
-
-
- ); -} diff --git a/app/routes/loadouts/$loadoutId/playertitles/add.tsx b/app/routes/loadouts/$loadoutId/playertitles/add.tsx deleted file mode 100644 index f3cea3e..0000000 --- a/app/routes/loadouts/$loadoutId/playertitles/add.tsx +++ /dev/null @@ -1,174 +0,0 @@ -import { - Form, - useLoaderData, - useNavigate, - useParams, - useSubmit, -} from 'react-router'; -import * as DialogPrimitive from '@radix-ui/react-dialog'; -import type { Loadout } from '~/utils'; -import type { ActionFunctionArgs, LoaderFunctionArgs } from 'react-router'; -import { redirect } from 'react-router'; -import { getUser, getUserConfig, saveUserConfig } from '~/utils.server'; -import { zfd } from 'zod-form-data'; -import { z } from 'zod'; - -const schema = zfd.formData({ - playerTitles: z.record(z.string(), zfd.checkbox()).optional(), -}); - -export async function action({ request, params }: ActionFunctionArgs) { - const user = await getUser(); - if (!user) { - throw redirect('/login'); - } - - const { loadoutId } = params; - - const userConfig = await getUserConfig(user.userId); - const loadout = userConfig.loadouts.find( - (loadout) => loadout.id === loadoutId, - ); - - if (!loadout) { - throw redirect('/loadouts'); - } - - const formData = await request.formData(); - - const out = schema.parse(formData); - - const newLoadout: Loadout = { - ...loadout, - playerTitleIds: Object.entries(out.playerTitles || {}).reduce< - Array - >((acc, next) => { - if (next[1]) { - acc.push(next[0]); - } - return acc; - }, []), - }; - - await saveUserConfig(user.userId, { - loadouts: [ - ...userConfig.loadouts.filter((l) => l.id !== loadoutId), - newLoadout, - ], - }); - - return { - success: true, - }; -} - -export async function loader({ params }: LoaderFunctionArgs) { - const user = await getUser(); - - if (!user) { - throw redirect('/login'); - } - - const { loadoutId } = params; - - const userConfig = await getUserConfig(user.userId); - const loadout = userConfig.loadouts.find( - (loadout) => loadout.id === loadoutId, - ); - - if (!loadout) { - throw redirect('/loadouts'); - } - - const entitlements = await user.getEntitlements(); - - const selectedPlayerTitles = loadout.playerTitleIds; - const ownedPlayerTitles = valorantData.playerTitles - .filter((playerTitle) => - entitlements.player_title.some( - (entitlement) => entitlement.ItemID === playerTitle.uuid, - ), - ) - .sort((a, b) => - (a.titleText || 'default').localeCompare(b.titleText || 'Default'), - ); - - return { - selectedPlayerTitles, - ownedPlayerTitles, - }; -} - -export default function AddPlayerTitle() { - const { ownedPlayerTitles, selectedPlayerTitles } = - useLoaderData(); - const navigate = useNavigate(); - const params = useParams(); - const submit = useSubmit(); - - return ( - navigate(`/loadouts/${params.loadoutId}`)} - > - - - -
- - Select Player Titles - - - - - - -
-
{ - submit(e.currentTarget, { - replace: true, - }); - }} - className="flex-auto overflow-y-auto scrollbar-thin scrollbar-thumb-white scrollbar-track-transparent scrollbar-thumb-rounded-full px-4 mr-4 mb-4 mt-4" - > -
- {ownedPlayerTitles.map((playerTitle) => ( -
- - -
- ))} -
-
-
-
-
-
- ); -} diff --git a/app/routes/loadouts/$loadoutId/weapons/$weaponId/index.tsx b/app/routes/loadouts/$loadoutId/weapons/$weaponId/index.tsx deleted file mode 100644 index 2dd8e75..0000000 --- a/app/routes/loadouts/$loadoutId/weapons/$weaponId/index.tsx +++ /dev/null @@ -1,253 +0,0 @@ -import { - Form, - Link, - useLoaderData, - useNavigate, - useParams, -} from 'react-router'; -import * as DialogPrimitive from '@radix-ui/react-dialog'; -import type { ActionFunctionArgs, LoaderFunctionArgs } from 'react-router'; -import { redirect } from 'react-router'; -import { getUser, getUserConfig, saveUserConfig } from '~/utils.server'; -import { SwitchImage } from '~/components/SwitchImage'; -import type { Loadout } from '~/utils'; - -export async function action({ request, params }: ActionFunctionArgs) { - const user = await getUser(); - - if (!user) { - throw redirect('/login'); - } - - const { loadoutId, weaponId } = params; - const formData = await request.formData(); - const action = formData.get('action'); - - const userConfig = await getUserConfig(user.userId); - const loadout = userConfig.loadouts.find( - (loadout) => loadout.id === loadoutId, - ); - - if (!loadout) { - throw redirect('/loadouts'); - } - - switch (action) { - case 'deleteTemplate': { - const templateId = formData.get('templateId'); - const existingWeapon = loadout.weapons[weaponId!]; - - if (!existingWeapon) { - throw new Error('Weapon not found in loadout'); - } - - const newTemplates = existingWeapon.templates.filter( - (template) => template.id !== templateId, - ); - - const newWeapon: Loadout['weapons'][number] = { - ...existingWeapon, - templates: newTemplates, - }; - - const newLoadout: Loadout = { - ...loadout, - weapons: { - ...loadout.weapons, - [weaponId!]: newWeapon, - }, - }; - - await saveUserConfig(user.userId, { - loadouts: [ - ...userConfig.loadouts.filter((l) => l.id !== loadoutId), - newLoadout, - ], - }); - - return { - success: true, - }; - } - default: { - return new Response(null, { - headers: { - 'Content-Type': 'application/json', - }, - status: 400, - }); - } - } -} - -export async function loader({ params }: LoaderFunctionArgs) { - const user = await getUser(); - - if (!user) { - throw redirect('/login'); - } - - const { loadoutId, weaponId } = params; - - const userConfig = await getUserConfig(user.userId); - const loadout = userConfig.loadouts.find( - (loadout) => loadout.id === loadoutId, - ); - - if (!loadout) { - throw redirect('/loadouts'); - } - - const weapons = valorantData.weapons; - - const weapon = weapons.find((weapon) => weapon.uuid === weaponId)!; - const templates = loadout.weapons[weaponId!].templates; - - return { - weapon, - templates: templates.map((template) => { - const skin = weapon.skins.find((skin) => skin.uuid === template.skinId)!; - const chromas = skin.chromas.filter((chroma) => - template.chromaIds.includes(chroma.uuid), - ); - - return { - id: template.id, - skin, - chromas, - }; - }), - }; -} - -export default function EditWeapon() { - const params = useParams(); - const { weapon, templates } = useLoaderData(); - const navigate = useNavigate(); - - return ( - navigate(`/loadouts/${params.loadoutId}`)} - > - - - -
- - {weapon.displayName} - - - - - - -
-
- {templates.map((template) => { - return ( -
-
-
- ({ - src: chroma.fullRender, - alt: chroma.displayName, - }))} - /> -
-

- {template.skin.displayName - .split(' ') - .slice(0, -1) - .join(' ')} -

-
-
-
- - - -
- - - - - - -
-
- ); - })} - - + - -
-
-
-
-
- ); -} diff --git a/app/routes/loadouts/$loadoutId/weapons/$weaponId/templates/$templateId/edit.tsx b/app/routes/loadouts/$loadoutId/weapons/$weaponId/templates/$templateId/edit.tsx deleted file mode 100644 index 7e3cb61..0000000 --- a/app/routes/loadouts/$loadoutId/weapons/$weaponId/templates/$templateId/edit.tsx +++ /dev/null @@ -1,314 +0,0 @@ -import { Form, useLoaderData, useNavigate, useParams } from 'react-router'; -import * as DialogPrimitive from '@radix-ui/react-dialog'; -import type { Loadout } from '~/utils'; -import { getOwnedChromas, getOwnedLevels } from '~/utils'; -import type { ActionFunctionArgs, LoaderFunctionArgs } from 'react-router'; -import { redirect } from 'react-router'; -import { getUser, getUserConfig, saveUserConfig } from '~/utils.server'; -import { zfd } from 'zod-form-data'; -import { z } from 'zod'; - -const schema = zfd.formData({ - skinId: z.string(), - chromas: z.record(z.string(), zfd.checkbox()).optional(), - levels: z.record(z.string(), zfd.checkbox()).optional(), - buddies: z - .record(z.string(), z.record(z.string(), zfd.checkbox())) - .optional(), -}); - -export async function action({ request, params }: ActionFunctionArgs) { - const user = await getUser(); - if (!user) { - throw redirect('/login'); - } - - const { loadoutId, weaponId } = params; - - const userConfig = await getUserConfig(user.userId); - const loadout = userConfig.loadouts.find( - (loadout) => loadout.id === loadoutId, - ); - - if (!loadout) { - throw redirect('/loadouts'); - } - - const formData = await request.formData(); - - const out = schema.parse(formData); - - const existingWeapon = loadout.weapons[weaponId!]; - - if (!existingWeapon) { - throw new Error('Weapon not found in loadout'); - } - - const existingTemplate = existingWeapon.templates.find( - (template) => template.id === params.templateId, - ); - - if (!existingTemplate) { - throw new Error('Template not found in weapon'); - } - - const skin = valorantData.weapons - .find((weapon) => weapon.uuid === weaponId) - ?.skins.find((skin) => skin.uuid === existingTemplate.skinId)!; - const defaultChroma = skin.chromas[skin.chromas.length - 1].uuid; - const defaultLevel = skin.levels[skin.levels.length - 1].uuid; - - const newTemplate = { - ...existingTemplate, - chromaIds: out.chromas - ? Object.keys(out.chromas).filter((key) => out.chromas![key]) - : [defaultChroma], - levelIds: out.levels - ? Object.keys(out.levels).filter((key) => out.levels![key]) - : [defaultLevel], - buddies: Object.keys(out.buddies || {}).map((buddyId) => ({ - id: buddyId, - levelIds: Object.keys(out.buddies![buddyId]).filter( - (key) => out.buddies![buddyId][key], - ), - })), - }; - - const newTemplates = [...loadout.weapons[weaponId!].templates!]; - newTemplates.splice( - newTemplates.findIndex((t) => t.id === params.templateId), - 1, - newTemplate, - ); - - const newWeapon: Loadout['weapons'][number] = { - ...existingWeapon, - templates: newTemplates, - }; - - const newLoadout: Loadout = { - ...loadout, - weapons: { - ...loadout.weapons, - [weaponId!]: newWeapon, - }, - }; - - await saveUserConfig(user.userId, { - loadouts: [ - ...userConfig.loadouts.filter((l) => l.id !== loadoutId), - newLoadout, - ], - }); - - throw redirect(`/loadouts/${loadoutId}/weapons/${weaponId}`); -} - -export async function loader({ params }: LoaderFunctionArgs) { - const user = await getUser(); - - if (!user) { - throw redirect('/login'); - } - - const { loadoutId, weaponId } = params; - - const userConfig = await getUserConfig(user.userId); - const loadout = userConfig.loadouts.find( - (loadout) => loadout.id === loadoutId, - ); - - if (!loadout) { - throw redirect('/loadouts'); - } - - const weapons = valorantData.weapons; - - const weapon = weapons.find((weapon) => weapon.uuid === weaponId)!; - const entitlements = await user.getEntitlements(); - const templates = loadout.weapons[weaponId!].templates; - - const template = templates.find( - (template) => template.id === params.templateId, - )!; - - const skin = weapon.skins.find((skin) => skin.uuid === template.skinId)!; - - const ownedBuddies = valorantData.buddies - .flatMap((buddy) => - buddy.levels - .map((level) => ({ - buddyId: buddy.uuid, - levelId: level.uuid, - displayName: buddy.displayName, - displayIcon: level.displayIcon, - })) - .filter((buddy) => - entitlements.buddy.some( - (entitlement) => entitlement.ItemID === buddy.levelId, - ), - ), - ) - .sort((a, b) => a.displayName.localeCompare(b.displayName)); - - return { - weapon, - skin: { - ...skin, - ownedChromas: getOwnedChromas(skin, entitlements), - ownedLevels: getOwnedLevels(skin, entitlements), - }, - ownedBuddies, - template, - }; -} - -export default function EditSkin() { - const { skin, template, ownedBuddies, weapon } = - useLoaderData(); - const navigate = useNavigate(); - const params = useParams(); - - return ( - - navigate(`/loadouts/${params.loadoutId}/weapons/${params.weaponId}`) - } - > - - - -
- - {skin.displayName} - - - - - - -
-
-
- -
- {skin.displayName} -
-

Chromas

-
- {skin.ownedChromas.map((chroma) => ( -
- - -
- ))} -
-

Levels

-
- {skin.ownedLevels.map((level, index) => ( -
- - -
- ))} -
- {weapon.uuid !== '2f59173c-4bed-b6c3-2191-dea9b58be9c7' && ( - <> -

Buddies

-
- {ownedBuddies.map((buddy) => ( -
- - b.id === buddy.buddyId && - b.levelIds.includes(buddy.levelId), - )} - /> - -
- ))} -
- - )} -
-
- - - Cancel - -
-
-
-
-
-
- ); -} diff --git a/app/routes/loadouts/$loadoutId/weapons/$weaponId/templates/new.tsx b/app/routes/loadouts/$loadoutId/weapons/$weaponId/templates/new.tsx deleted file mode 100644 index 1b9d67d..0000000 --- a/app/routes/loadouts/$loadoutId/weapons/$weaponId/templates/new.tsx +++ /dev/null @@ -1,401 +0,0 @@ -import { Form, useLoaderData, useNavigate, useParams } from 'react-router'; -import * as DialogPrimitive from '@radix-ui/react-dialog'; -import { useReducer } from 'react'; -import type { Loadout, ResolvedWeapon } from '~/utils'; -import type { ActionFunctionArgs, LoaderFunctionArgs } from 'react-router'; -import { redirect } from 'react-router'; -import { - getUser, - getUserConfig, - randomUUID, - saveUserConfig, -} from '~/utils.server'; -import { zfd } from 'zod-form-data'; -import { z } from 'zod'; - -const schema = zfd.formData({ - skinId: z.string(), - chromas: z.record(z.string(), zfd.checkbox()).optional(), - levels: z.record(z.string(), zfd.checkbox()).optional(), - buddies: z - .record(z.string(), z.record(z.string(), zfd.checkbox())) - .optional(), -}); - -export async function action({ request, params }: ActionFunctionArgs) { - const user = await getUser(); - if (!user) { - throw redirect('/login'); - } - - const { loadoutId, weaponId } = params; - - const userConfig = await getUserConfig(user.userId); - const loadout = userConfig.loadouts.find( - (loadout) => loadout.id === loadoutId, - ); - - if (!loadout) { - throw redirect('/loadouts'); - } - - const formData = await request.formData(); - - const out = schema.parse(formData); - - const existingWeapon = loadout.weapons[weaponId!]; - - if (!existingWeapon) { - throw new Error('Weapon not found in loadout'); - } - - const skin = valorantData.weapons - .find((weapon) => weapon.uuid === weaponId) - ?.skins.find((skin) => skin.uuid === out.skinId)!; - const defaultChroma = skin.chromas[skin.chromas.length - 1].uuid; - const defaultLevel = skin.levels[skin.levels.length - 1].uuid; - - const newWeapon: Loadout['weapons'][number] = { - ...existingWeapon, - templates: [ - ...(loadout.weapons[weaponId!].templates || []), - { - id: randomUUID(), - skinId: out.skinId, - chromaIds: out.chromas - ? Object.keys(out.chromas).filter((key) => out.chromas![key]) - : [defaultChroma], - levelIds: out.levels - ? Object.keys(out.levels).filter((key) => out.levels![key]) - : [defaultLevel], - buddies: Object.keys(out.buddies || {}).map((buddyId) => ({ - id: buddyId, - levelIds: Object.keys(out.buddies![buddyId]).filter( - (key) => out.buddies![buddyId][key], - ), - })), - }, - ], - }; - - const newLoadout: Loadout = { - ...loadout, - weapons: { - ...loadout.weapons, - [weaponId!]: newWeapon, - }, - }; - - await saveUserConfig(user.userId, { - loadouts: [ - ...userConfig.loadouts.filter((l) => l.id !== loadoutId), - newLoadout, - ], - }); - - throw redirect(`/loadouts/${loadoutId}/weapons/${weaponId}`); -} - -export async function loader({ params }: LoaderFunctionArgs) { - const user = await getUser(); - - if (!user) { - throw redirect('/login'); - } - - const { loadoutId, weaponId } = params; - - const userConfig = await getUserConfig(user.userId); - const loadout = userConfig.loadouts.find( - (loadout) => loadout.id === loadoutId, - ); - - if (!loadout) { - throw redirect('/loadouts'); - } - - const weapons = valorantData.weapons; - const entitlements = await user.getEntitlements(); - - const weapon = weapons.find((weapon) => weapon.uuid === weaponId)!; - - const ownedSkins = weapon.skins.reduce< - Array<{ - id: string; - name: string; - displayIcon: string; - chromas: Array; - levels: Array; - }> - >((acc, next) => { - const chromas = next.chromas.filter((chroma) => - entitlements.skin_chroma.find( - (entitlement) => entitlement.ItemID === chroma.uuid, - ), - ); - - const levels = next.levels.filter((level) => - entitlements.skin_level.find( - (entitlement) => entitlement.ItemID === level.uuid, - ), - ); - - if (chromas.length === 0 && levels.length === 0) { - return acc; - } - - return [ - ...acc, - { - id: next.uuid, - name: next.displayName, - displayIcon: next.displayIcon, - chromas: [next.chromas[0], ...chromas], - levels, - }, - ]; - }, []); - - const ownedBuddies = valorantData.buddies - .flatMap((buddy) => - buddy.levels - .map((level) => ({ - buddyId: buddy.uuid, - levelId: level.uuid, - displayName: buddy.displayName, - displayIcon: level.displayIcon, - })) - .filter((buddy) => - entitlements.buddy.some( - (entitlement) => entitlement.ItemID === buddy.levelId, - ), - ), - ) - .sort((a, b) => a.displayName.localeCompare(b.displayName)); - - return { - weapon: { - uuid: weapon.uuid, - displayName: weapon.displayName, - defaultSkinIcon: weapon.displayIcon, - category: weapon.category, - ownedSkins, - }, - ownedBuddies, - }; -} - -export default function NewSkin() { - const { weapon, ownedBuddies } = useLoaderData(); - const navigate = useNavigate(); - const params = useParams(); - - type NewSkinAction = { - type: 'SET_SELECTED_SKIN'; - payload: ResolvedWeapon['ownedSkins'][number]; - }; - - type NewSkinState = - | { - mode: 'select_skin'; - title: string; - } - | { - mode: 'select_chroma'; - title: string; - selectedSkin: ResolvedWeapon['ownedSkins'][number]; - }; - - const [state, dispatch] = useReducer( - (_state, action) => { - switch (action.type) { - case 'SET_SELECTED_SKIN': { - return { - mode: 'select_chroma', - title: action.payload.name, - selectedSkin: action.payload, - }; - } - } - }, - { - mode: 'select_skin', - title: `Select a skin`, - }, - ); - - return ( - - navigate(`/loadouts/${params.loadoutId}/weapons/${params.weaponId}`) - } - > - - - -
- - {state.title} - - - - - - -
- {state.mode === 'select_skin' && ( -
- {[...weapon.ownedSkins] - .sort((a, b) => { - return a.name.localeCompare(b.name); - }) - .map((skin) => ( - - ))} -
- )} - {state.mode === 'select_chroma' && ( -
-
- -
- {state.title} -
-

Chromas

-
- {state.selectedSkin.chromas.map((chroma) => ( -
- - -
- ))} -
-

Levels

-
- {state.selectedSkin.levels.map((level, index, arr) => ( -
- - -
- ))} -
- {weapon.uuid !== '2f59173c-4bed-b6c3-2191-dea9b58be9c7' && ( - <> -

Buddies

-
- {ownedBuddies.map((buddy) => ( -
- - -
- ))} -
- - )} -
-
- - - Cancel - -
-
- )} -
-
-
-
- ); -} diff --git a/app/routes/loadouts/index.tsx b/app/routes/loadouts/index.tsx deleted file mode 100644 index d07737e..0000000 --- a/app/routes/loadouts/index.tsx +++ /dev/null @@ -1,592 +0,0 @@ -import type { ActionFunctionArgs } from 'react-router'; -import { redirect } from 'react-router'; -import { Form, Link, useLoaderData } from 'react-router'; -import { entitlementTypeToIdMap } from 'types'; -import { Gallery } from '~/components/Gallery'; - -import { SwitchImage } from '~/components/SwitchImage'; -import { Loadout, weaponUuidToIndex } from '~/utils'; -import { - getDefaultLoadout, - getUser, - getUserConfig, - randomUUID, - saveUserConfig, -} from '~/utils.server'; - -export const action = async ({ request }: ActionFunctionArgs) => { - const user = await getUser(); - - if (!user) { - throw redirect('/login'); - } - - const formData = await request.formData(); - const action = formData.get('action') as string; - - switch (action) { - case 'create': { - const newLoadout = { - ...getDefaultLoadout(), - name: 'New Loadout', - }; - const config = await getUserConfig(user.userId); - - if (config.loadouts.find((loadout) => loadout.id === newLoadout.id)) { - throw new Error('Loadout already exists'); - } - - config.loadouts.push(newLoadout); - - await saveUserConfig(user.userId, config); - throw redirect(`/loadouts/${newLoadout.id}`); - } - case 'equip': { - const loadoutId = formData.get('loadoutId') as string; - const config = await getUserConfig(user.userId); - const loadout = config.loadouts.find( - (loadout) => loadout.id === loadoutId, - ); - - if (!loadout) { - throw redirect('/loadouts'); - } - - await appManager.equipLoadout(user, loadout); - - return { success: true }; - } - case 'enable': - case 'disable': { - const loadoutId = formData.get('loadoutId') as string; - const config = await getUserConfig(user.userId); - const loadout = config.loadouts.find( - (loadout) => loadout.id === loadoutId, - ); - - if (!loadout) { - throw redirect('/loadouts'); - } - - loadout.enabled = action === 'enable'; - - await saveUserConfig(user.userId, config); - - return { success: true }; - } - case 'duplicate': { - const loadoutId = formData.get('loadoutId') as string; - const config = await getUserConfig(user.userId); - const loadout = config.loadouts.find( - (loadout) => loadout.id === loadoutId, - ); - - if (!loadout) { - throw redirect('/loadouts'); - } - - const newLoadout = { - ...loadout, - id: randomUUID(), - name: `${loadout.name} (Copy)`, - }; - - config.loadouts.push(newLoadout); - - await saveUserConfig(user.userId, config); - - throw redirect(`/loadouts/${newLoadout.id}`); - } - case 'delete': { - const loadoutId = formData.get('loadoutId') as string; - - const config = await getUserConfig(user.userId); - const loadoutIndex = config.loadouts.findIndex( - (loadout) => loadout.id === loadoutId, - ); - - if (loadoutIndex === -1) { - throw redirect('/loadouts'); - } - - config.loadouts.splice(loadoutIndex, 1); - - await saveUserConfig(user.userId, config); - - return { success: true }; - } - case 'save-in-game': { - const currentInGameLoadout = await user.getLoadout(); - const config = await getUserConfig(user.userId); - - const [top, right, bottom, left] = currentInGameLoadout.ActiveExpressions; - - const newLoadout: Loadout = { - ...getDefaultLoadout(), - name: 'In-Game Loadout', - enabled: true, - id: randomUUID(), - weapons: Object.fromEntries( - currentInGameLoadout.Guns.map((gun) => [ - gun.ID, - { - templates: [ - { - id: gun.ID, - skinId: gun.SkinID, - buddies: gun.CharmID - ? [ - { - id: gun.CharmID, - levelIds: gun.CharmLevelID ? [gun.CharmLevelID] : [], - }, - ] - : [], - chromaIds: [gun.ChromaID], - levelIds: [gun.SkinLevelID], - }, - ], - }, - ]), - ), - expressionIds: { - top: { - sprayIds: - top.TypeID === entitlementTypeToIdMap.spray ? [top.AssetID] : [], - flexIds: - top.TypeID === entitlementTypeToIdMap.flex ? [top.AssetID] : [], - }, - right: { - sprayIds: - right.TypeID === entitlementTypeToIdMap.spray - ? [right.AssetID] - : [], - flexIds: - right.TypeID === entitlementTypeToIdMap.flex - ? [right.AssetID] - : [], - }, - bottom: { - sprayIds: - bottom.TypeID === entitlementTypeToIdMap.spray - ? [bottom.AssetID] - : [], - flexIds: - bottom.TypeID === entitlementTypeToIdMap.flex - ? [bottom.AssetID] - : [], - }, - left: { - sprayIds: - left.TypeID === entitlementTypeToIdMap.spray - ? [left.AssetID] - : [], - flexIds: - left.TypeID === entitlementTypeToIdMap.flex ? [left.AssetID] : [], - }, - }, - playerCardIds: [currentInGameLoadout.Identity.PlayerCardID], - playerTitleIds: [currentInGameLoadout.Identity.PlayerTitleID], - }; - - config.loadouts.push(newLoadout); - - await saveUserConfig(user.userId, config); - - throw redirect(`/loadouts/${newLoadout.id}`); - } - default: { - throw new Error('Invalid action'); - } - } -}; - -export const loader = async () => { - const user = await getUser(); - - if (!user) { - throw redirect('/login'); - } - - const userConfig = await getUserConfig(user.userId); - - const weapons = valorantData.weapons; - - const loadouts = userConfig.loadouts - .sort((a, b) => { - if (a.enabled === b.enabled) { - return a.name.localeCompare(b.name); - } - - return a.enabled ? -1 : 1; - }) - .map((loadout) => { - return { - id: loadout.id, - name: loadout.name, - enabled: loadout.enabled, - agents: loadout.agentIds.map( - (id) => valorantData.agents.find((a) => a.uuid === id)!, - ), - playerCards: (loadout.playerCardIds.length - ? loadout.playerCardIds - : ['9fb348bc-41a0-91ad-8a3e-818035c4e561'] - ).map((id) => valorantData.playerCards.find((c) => c.uuid === id)!), - playerTitles: (loadout.playerTitleIds.length - ? loadout.playerTitleIds - : ['d13e579c-435e-44d4-cec2-6eae5a3c5ed4'] - ).map( - (id) => valorantData.playerTitles.find((title) => title.uuid === id)!, - ), - expressions: { - top: { - sprayIds: (loadout.expressionIds.top.sprayIds.length || - loadout.expressionIds.top.flexIds.length - ? loadout.expressionIds.top.sprayIds - : ['0a6db78c-48b9-a32d-c47a-82be597584c1'] - ).map( - (sprayId) => - valorantData.sprays.find((spray) => spray.uuid === sprayId)!, - ), - flexIds: loadout.expressionIds.top.flexIds.map( - (flexId) => - valorantData.flex.find((flex) => flex.uuid === flexId)!, - ), - }, - right: { - sprayIds: (loadout.expressionIds.right.sprayIds.length || - loadout.expressionIds.right.flexIds.length - ? loadout.expressionIds.right.sprayIds - : ['0a6db78c-48b9-a32d-c47a-82be597584c1'] - ).map( - (sprayId) => - valorantData.sprays.find((spray) => spray.uuid === sprayId)!, - ), - flexIds: loadout.expressionIds.right.flexIds.map( - (flexId) => - valorantData.flex.find((flex) => flex.uuid === flexId)!, - ), - }, - bottom: { - sprayIds: (loadout.expressionIds.bottom.sprayIds.length || - loadout.expressionIds.bottom.flexIds.length - ? loadout.expressionIds.bottom.sprayIds - : ['0a6db78c-48b9-a32d-c47a-82be597584c1'] - ).map( - (sprayId) => - valorantData.sprays.find((spray) => spray.uuid === sprayId)!, - ), - flexIds: loadout.expressionIds.bottom.flexIds.map( - (flexId) => - valorantData.flex.find((flex) => flex.uuid === flexId)!, - ), - }, - left: { - sprayIds: loadout.expressionIds.left.sprayIds.map( - (sprayId) => - valorantData.sprays.find((spray) => spray.uuid === sprayId)!, - ), - flexIds: (loadout.expressionIds.left.flexIds.length || - loadout.expressionIds.left.sprayIds.length - ? loadout.expressionIds.left.flexIds - : ['af52b5a0-4a4c-03b2-c9d7-8187a08a2675'] - ).map( - (flexId) => - valorantData.flex.find((flex) => flex.uuid === flexId)!, - ), - }, - }, - weapons: Object.entries(loadout.weapons) - .sort((a, b) => { - const indexA = weaponUuidToIndex[a[0]]; - const indexB = weaponUuidToIndex[b[0]]; - - return indexA - indexB; - }) - .map(([weaponId, { templates }]) => { - const weapon = weapons.find((w) => w.uuid === weaponId)!; - - return { - id: weaponId, - displayName: weapon.displayName, - displayIcon: weapon.displayIcon, - category: weapon.category, - uuid: weapon.uuid, - templates: templates.map((template) => { - const skin = weapon.skins.find( - (skin) => skin.uuid === template.skinId, - )!; - const chromas = skin.chromas.filter((chroma) => - template.chromaIds.includes(chroma.uuid), - ); - const buddies = template.buddies.flatMap((buddy) => { - const buddyData = valorantData.buddies.find( - (b) => b.uuid === buddy.id, - )!; - - return buddy.levelIds.flatMap((levelId) => { - return { - id: buddy.id, - levelId, - displayName: buddyData.displayName, - displayIcon: buddyData.displayIcon, - }; - }); - }); - - return { - id: template.id, - skin, - chromas, - buddies, - }; - }), - }; - }), - }; - }); - - return { - loadouts, - }; -}; - -const buttonStyles = - 'cursor-pointer text-white px-2 py-1 border-2 border-white rounded-md hover:bg-white hover:text-slate-800'; - -export default function Index() { - const { loadouts } = useLoaderData(); - - return ( -
-
-

Loadouts

-
- - -
-
-
- {loadouts.map((loadout) => { - return ( -
-

- {loadout.name} - {!loadout.enabled && ( - <> - {' '} - (Disabled) - - )} -
- {loadout.agents.map((agent) => ( -
- {agent.displayName} -
- ))} -
-

-
-
-
- ({ - src: c.largeArt, - alt: c.displayName, - }))} - /> -
- ({ - ...t, - duration: 1000, - }))} - render={(title) => ( -

- {title.titleText || 'Default'} -

- )} - /> -
- {Object.entries(loadout.expressions).map( - ([key, sprays]) => { - return ( -
- ({ - src: - spray.animationGif || - spray.fullTransparentIcon || - spray.displayIcon, - alt: spray.displayName, - })), - ...sprays.flexIds.map((flex) => ({ - src: flex.displayIcon, - alt: flex.displayName, - })), - ]} - /> -
- ); - }, - )} -
-
-
- {loadout.weapons.map((weapon) => { - return ( -
- { - return template.chromas.flatMap<{ - chroma: { - icon: string; - name: string; - }; - buddy: { - icon: string; - name: string; - } | null; - duration: number; - }>((chroma) => { - if (template.buddies.length === 0) { - return [ - { - chroma: { - icon: - chroma.fullRender || - chroma.displayIcon, - name: chroma.displayName, - }, - buddy: null, - duration: 1000, - }, - ]; - } - - return template.buddies.map((buddy) => { - return { - chroma: { - icon: - chroma.fullRender || - chroma.displayIcon, - name: chroma.displayName, - }, - buddy: { - icon: buddy.displayIcon, - name: buddy.displayName, - }, - duration: 1000, - }; - }); - }); - }) - : [ - { - buddy: null, - chroma: { - icon: weapon.displayIcon, - name: weapon.displayName, - }, - duration: 1000, - }, - ] - } - render={(item) => ( - <> - {item.chroma.name} - {item.buddy && ( - {item.buddy.name} - )} - - )} - /> -
- ); - })} -
-
-
-
- - - -
-
- - - -
-
- - - -
- - Edit - -
- - - -
-
-
- ); - })} -
-
- ); -} diff --git a/app/routes/login.tsx b/app/routes/login.tsx deleted file mode 100644 index 25a8641..0000000 --- a/app/routes/login.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import type { MetaFunction } from 'react-router'; -import { redirect } from 'react-router'; - -import { getUser } from '~/utils.server'; - -export async function loader() { - const user = await getUser(); - - if (user) { - throw redirect('/'); - } - - return null; -} - -export const meta: MetaFunction = () => [ - { - httpEquiv: 'refresh', - content: '5', - }, -]; - -export default function Index() { - return ( -
- Please open Valorant to continue -
- ); -} diff --git a/app/utils.server.ts b/app/utils.server.ts deleted file mode 100644 index c237725..0000000 --- a/app/utils.server.ts +++ /dev/null @@ -1,348 +0,0 @@ -import axios, { isAxiosError } from 'axios'; -import fsPromise from 'fs/promises'; -import path from 'path'; -import https from 'https'; - -import type { - Loadout, - UserConfig, - UserConfigV1, - UserConfigV2, - UserConfigV3, -} from '~/utils'; -import { generateRequestHeaders, User } from 'server/userman'; -import { Regions, Shards } from 'types'; - -async function exists(filename: string) { - try { - await fsPromise.access(filename); - return true; - } catch { - return false; - } -} - -export async function getLockfile() { - const lockfilePath = path.resolve( - process.env.LOCALAPPDATA!, - 'Riot Games', - 'Riot Client', - 'Config', - 'lockfile', - ); - - if (!(await exists(lockfilePath))) { - return; - } - - const lockfile = await fsPromise.readFile(lockfilePath, 'utf8'); - const [name, pid, port, password] = lockfile.split(':'); - - return { - name, - pid, - port, - password, - }; -} - -function readTextFile(filename: string) { - return fsPromise.readFile(filename, 'utf-8'); -} - -function writeTextFile(filename: string, content: string) { - return fsPromise.writeFile(filename, content); -} - -export function randomUUID() { - return crypto.randomUUID(); -} - -export function randomItem(array: T[]) { - const index = Math.floor(Math.random() * array.length); - return array[index]; -} - -export function getDefaultLoadout(): Loadout { - return { - id: randomUUID(), - name: 'Default Loadout', - enabled: true, - agentIds: [], - weapons: { - '63e6c2b6-4a8e-869c-3d4c-e38355226584': { templates: [] }, - '55d8a0f4-4274-ca67-fe2c-06ab45efdf58': { templates: [] }, - '9c82e19d-4575-0200-1a81-3eacf00cf872': { templates: [] }, - 'ae3de142-4d85-2547-dd26-4e90bed35cf7': { templates: [] }, - 'ee8e8d15-496b-07ac-e5f6-8fae5d4c7b1a': { templates: [] }, - 'ec845bf4-4f79-ddda-a3da-0db3774b2794': { templates: [] }, - '910be174-449b-c412-ab22-d0873436b21b': { templates: [] }, - '44d4e95c-4157-0037-81b2-17841bf2e8e3': { templates: [] }, - '29a0cfab-485b-f5d5-779a-b59f85e204a8': { templates: [] }, - '1baa85b4-4c70-1284-64bb-6481dfc3bb4e': { templates: [] }, - 'e336c6b8-418d-9340-d77f-7a9e4cfe0702': { templates: [] }, - '42da8ccc-40d5-affc-beec-15aa47b42eda': { templates: [] }, - 'a03b24d3-4319-996d-0f8c-94bbfba1dfc7': { templates: [] }, - '4ade7faa-4cf1-8376-95ef-39884480959b': { templates: [] }, - 'c4883e50-4494-202c-3ec3-6b8a9284f00b': { templates: [] }, - '462080d1-4035-2937-7c09-27aa2a5c27a7': { templates: [] }, - 'f7e1b454-4ad4-1063-ec0a-159e56b58941': { templates: [] }, - '2f59173c-4bed-b6c3-2191-dea9b58be9c7': { templates: [] }, - '5f0aaf7a-4289-3998-d5ff-eb9a5cf7ef5c': { templates: [] }, - }, - playerCardIds: [], - playerTitleIds: [], - expressionIds: { - top: { - sprayIds: [], - flexIds: [], - }, - right: { - sprayIds: [], - flexIds: [], - }, - bottom: { - sprayIds: [], - flexIds: [], - }, - left: { - sprayIds: [], - flexIds: [], - }, - }, - }; -} - -const CONFIG_VERSION = 3; - -const migratePipeline = [ - { - version: 2, - migrate(old: UserConfigV1): UserConfigV2 { - return { - ...old, - loadouts: old.loadouts.map((loadout) => ({ - ...loadout, - sprayIds: { - top: loadout.sprayIds.midRound, - right: loadout.sprayIds.postRound, - bottom: [], - left: loadout.sprayIds.preRound, - }, - })), - version: 2, - }; - }, - }, - { - version: 3, - migrate(old: UserConfigV2): UserConfigV3 { - return { - ...old, - version: 3, - loadouts: old.loadouts.map((loadout) => ({ - ...loadout, - expressionIds: { - top: { - sprayIds: loadout.sprayIds.top, - flexIds: [], - }, - right: { - sprayIds: loadout.sprayIds.right, - flexIds: [], - }, - bottom: { - sprayIds: loadout.sprayIds.bottom, - flexIds: [], - }, - left: { - sprayIds: loadout.sprayIds.left, - flexIds: [], - }, - }, - })), - }; - }, - }, -] as const; - -function migrateConfig(config: any) { - const configVersion = 'version' in config ? config.version : 1; - - if (configVersion === CONFIG_VERSION) { - return config; - } - - const pipeline = migratePipeline.filter( - ({ version }) => version > configVersion, - ); - - if (!pipeline.length) { - throw new Error( - `No migration pipeline for config version ${configVersion}`, - ); - } - - return pipeline.reduce((acc, { migrate }) => migrate(acc), config); -} - -export async function getUserConfig(userId: string): Promise { - const userFileName = `user_${userId}.json`; - const userFilenamePath = path.resolve(process.cwd(), userFileName); - - if (!(await exists(userFilenamePath))) { - const newConfig: UserConfig = { - loadouts: [getDefaultLoadout()], - version: CONFIG_VERSION, - }; - - await writeTextFile(userFilenamePath, JSON.stringify(newConfig)); - } - - return migrateConfig(JSON.parse(await readTextFile(userFilenamePath))); -} - -export async function saveUserConfig( - userId: string, - config: Omit, -) { - const userFileName = `user_${userId}.json`; - const userFilenamePath = path.resolve(process.cwd(), userFileName); - - await writeTextFile( - userFilenamePath, - JSON.stringify({ - ...config, - version: CONFIG_VERSION, - }), - ); -} - -const httpClient = axios.create({ - httpsAgent: new https.Agent({ - rejectUnauthorized: false, - }), -}); - -declare global { - var userShardRegionCache: Map; -} - -global.userShardRegionCache = - global.userShardRegionCache || - new Map(); - -export async function getUser() { - try { - const lockfile = await getLockfile(); - - if (!lockfile) { - return null; - } - - const { port, password } = lockfile; - - const tokens = ( - await httpClient.get<{ - accessToken: string; - entitlements: unknown[]; - issuer: string; - subject: string; - token: string; - }>(`https://127.0.0.1:${port}/entitlements/v1/token`, { - headers: { - Authorization: `Basic ${Buffer.from(`riot:${password}`).toString( - 'base64', - )}`, - }, - }) - ).data; - - const shardRegionMap = [ - [Shards.NorthAmerica, Regions.NorthAmerica], - [Shards.NorthAmerica, Regions.LatinAmerica], - [Shards.NorthAmerica, Regions.Brazil], - [Shards.PBE, Regions.NorthAmerica], - [Shards.Europe, Regions.Europe], - [Shards.AsiaPacific, Regions.AsiaPacific], - [Shards.Korea, Regions.Korea], - ] as const; - - const res = - global.userShardRegionCache.get(tokens.subject) || - (await (async function findRegionAndShard(attempts = 0): Promise<{ - region: Regions; - shard: Shards; - } | null> { - for (const [shard, region] of shardRegionMap) { - try { - const response = await httpClient.get( - `https://glz-${region}-1.${shard}.a.pvp.net/parties/v1/players/${tokens.subject}`, - { - headers: generateRequestHeaders({ - accessToken: tokens.accessToken, - entitlementsToken: tokens.token, - riotClientVersion: - global.valorantData.version.riotClientVersion, - }), - }, - ); - - if (!response.data.Subject) { - continue; - } - - return { - region, - shard, - }; - } catch (e) { - if (isAxiosError(e)) { - switch (e.response?.status) { - case 404: { - console.log('tried', region, shard, 'got 404, continuing'); - break; - } - default: { - console.warn( - 'Caught error trying to get user for region/shard detection', - region, - shard, - e, - ); - break; - } - } - } - } - } - - if (attempts < 5) { - console.log('Failed to find user region and shard, retrying in 2.5s'); - await new Promise((resolve) => setTimeout(resolve, 2500)); - return findRegionAndShard(attempts + 1); - } - - return null; - })()); - - if (!res) { - return null; - } - - console.log('Found user region and shard', res); - userShardRegionCache.set(tokens.subject, res); - - return new User({ - riotClientVersion: global.valorantData.version.riotClientVersion, - accessToken: tokens.accessToken, - entitlementsToken: tokens.token, - region: res.region, - shard: res.shard, - userId: tokens.subject, - }); - } catch (e) { - console.warn('Caught error trying to get user', e); - return null; - } -} diff --git a/app/utils.ts b/app/utils.ts deleted file mode 100644 index b390d89..0000000 --- a/app/utils.ts +++ /dev/null @@ -1,266 +0,0 @@ -import type { EntitlementsByCategory, Weapon, WeaponCategory } from 'types'; - -export type LoadoutV1 = { - id: string; - name: string; - enabled: boolean; - agentIds: Array; - weapons: Record< - string, - { - templates: Array<{ - id: string; - skinId: string; - levelIds: Array; - chromaIds: Array; - buddies: Array<{ - id: string; - levelIds: Array; - }>; - }>; - } - >; - playerCardIds: Array; - playerTitleIds: Array; - sprayIds: { - preRound: Array; - midRound: Array; - postRound: Array; - }; -}; - -export type LoadoutV2 = { - id: string; - name: string; - enabled: boolean; - agentIds: Array; - weapons: Record< - string, - { - templates: Array<{ - id: string; - skinId: string; - levelIds: Array; - chromaIds: Array; - buddies: Array<{ - id: string; - levelIds: Array; - }>; - }>; - } - >; - playerCardIds: Array; - playerTitleIds: Array; - sprayIds: { - top: Array; - right: Array; - bottom: Array; - left: Array; - }; -}; - -export type Loadout = { - id: string; - name: string; - enabled: boolean; - agentIds: Array; - weapons: Record< - string, - { - templates: Array<{ - id: string; - skinId: string; - levelIds: Array; - chromaIds: Array; - buddies: Array<{ - id: string; - levelIds: Array; - }>; - }>; - } - >; - playerCardIds: Array; - playerTitleIds: Array; - expressionIds: { - top: { - sprayIds: Array; - flexIds: Array; - }; - right: { - sprayIds: Array; - flexIds: Array; - }; - bottom: { - sprayIds: Array; - flexIds: Array; - }; - left: { - sprayIds: Array; - flexIds: Array; - }; - }; -}; - -export type UserConfigV1 = { - loadouts: Array; -}; - -export type UserConfigV2 = { - version: 2; - loadouts: Array; -}; - -export type UserConfigV3 = { - version: 3; - loadouts: Array; -}; - -export { type UserConfigV3 as UserConfig }; - -export const categoryNameMap: Record = { - 'EEquippableCategory::Sidearm': 'sidearms', - 'EEquippableCategory::SMG': 'smgs', - 'EEquippableCategory::Rifle': 'rifles', - 'EEquippableCategory::Sniper': 'sniper rifles', - 'EEquippableCategory::Shotgun': 'shotguns', - 'EEquippableCategory::Heavy': 'machine guns', - 'EEquippableCategory::Melee': 'melee', -}; - -export const categoryCanonicalNameMap: Record = { - 'EEquippableCategory::Sidearm': 'sidearm', - 'EEquippableCategory::SMG': 'smg', - 'EEquippableCategory::Rifle': 'rifle', - 'EEquippableCategory::Sniper': 'sniper', - 'EEquippableCategory::Shotgun': 'shotgun', - 'EEquippableCategory::Heavy': 'heavy', - 'EEquippableCategory::Melee': 'melee', -}; - -export const sortedWeapons: Record = { - 'EEquippableCategory::Sidearm': [ - 'classic', - 'shorty', - 'frenzy', - 'ghost', - 'sheriff', - ], - 'EEquippableCategory::SMG': ['stinger', 'spectre'], - 'EEquippableCategory::Rifle': ['bulldog', 'guardian', 'phantom', 'vandal'], - 'EEquippableCategory::Sniper': ['marshal', 'outlaw', 'operator'], - 'EEquippableCategory::Shotgun': ['bucky', 'judge'], - 'EEquippableCategory::Heavy': ['ares', 'odin'], - 'EEquippableCategory::Melee': ['melee'], -}; - -export const weaponUUIDCanonicalNameMap: Record = { - '63e6c2b6-4a8e-869c-3d4c-e38355226584': 'odin', - '55d8a0f4-4274-ca67-fe2c-06ab45efdf58': 'ares', - '9c82e19d-4575-0200-1a81-3eacf00cf872': 'vandal', - 'ae3de142-4d85-2547-dd26-4e90bed35cf7': 'bulldog', - 'ee8e8d15-496b-07ac-e5f6-8fae5d4c7b1a': 'phantom', - 'ec845bf4-4f79-ddda-a3da-0db3774b2794': 'judge', - '910be174-449b-c412-ab22-d0873436b21b': 'bucky', - '44d4e95c-4157-0037-81b2-17841bf2e8e3': 'frenzy', - '29a0cfab-485b-f5d5-779a-b59f85e204a8': 'classic', - '1baa85b4-4c70-1284-64bb-6481dfc3bb4e': 'ghost', - 'e336c6b8-418d-9340-d77f-7a9e4cfe0702': 'sheriff', - '42da8ccc-40d5-affc-beec-15aa47b42eda': 'shorty', - 'a03b24d3-4319-996d-0f8c-94bbfba1dfc7': 'operator', - '4ade7faa-4cf1-8376-95ef-39884480959b': 'guardian', - 'c4883e50-4494-202c-3ec3-6b8a9284f00b': 'marshal', - '5f0aaf7a-4289-3998-d5ff-eb9a5cf7ef5c': 'outlaw', - '462080d1-4035-2937-7c09-27aa2a5c27a7': 'spectre', - 'f7e1b454-4ad4-1063-ec0a-159e56b58941': 'stinger', - '2f59173c-4bed-b6c3-2191-dea9b58be9c7': 'melee', -}; - -export const weaponCanonicalNameUUIDMap: Record = - Object.entries(weaponUUIDCanonicalNameMap).reduce( - (acc, [key, value]) => { - acc[value] = key; - return acc; - }, - {} as Record, - ); - -export const nameToIndex = Object.entries(sortedWeapons).reduce( - (acc, [_category, weapons]) => { - const totalAcc = Object.keys(acc).length; - weapons.forEach((weapon, index) => { - acc[weapon] = index + totalAcc; - }); - return acc; - }, - {} as Record, -); - -export const weaponUuidToIndex = Object.entries(sortedWeapons).reduce( - (acc, [_category, weapons]) => { - const totalAcc = Object.keys(acc).length; - weapons.forEach((weapon, index) => { - acc[weaponCanonicalNameUUIDMap[weapon]] = index + totalAcc; - }); - return acc; - }, - {} as Record, -); - -export type ResolvedWeapon = { - uuid: string; - displayName: string; - category: WeaponCategory; - defaultSkinIcon: string; - resolvedSkins: Array<{ - id: string; - name: string; - skinIcon: string; - buddyIcon: string; - }>; - ownedSkins: Array<{ - id: string; - name: string; - displayIcon: string; - chromas: Array<{ - uuid: string; - displayName: string; - displayIcon: string; - fullRender: string; - swatch: string; - streamedVideo: string; - assetPath: string; - }>; - levels: Array<{ - uuid: string; - displayName: string; - levelItem: string | null; - displayIcon: string | null; - streamedVideo: string; - assetPath: string; - }>; - }>; -}; - -export function getOwnedChromas( - skin: Weapon['skins'][number], - entitlements: EntitlementsByCategory, -) { - return skin.chromas.filter( - (chroma, index) => - index === 0 || - entitlements.skin_chroma.some( - (entitlement) => entitlement.ItemID === chroma.uuid, - ), - ); -} - -export function getOwnedLevels( - skin: Weapon['skins'][number], - entitlements: EntitlementsByCategory, -) { - return skin.levels.filter((level) => - entitlements.skin_level.some( - (entitlement) => entitlement.ItemID === level.uuid, - ), - ); -} diff --git a/biome.json b/biome.json index dd007aa..af099af 100644 --- a/biome.json +++ b/biome.json @@ -1,28 +1,39 @@ { - "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", + "$schema": "https://biomejs.dev/schemas/2.4.2/schema.json", + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + }, + "files": { + "ignoreUnknown": false + }, "formatter": { "enabled": true, - "formatWithErrors": false, - "indentStyle": "tab", - "indentWidth": 2, - "lineEnding": "lf", - "lineWidth": 80, - "attributePosition": "auto", - "bracketSpacing": true + "indentStyle": "tab" + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true + } }, - "organizeImports": { "enabled": true }, - "linter": { "enabled": true, "rules": { "recommended": false } }, "javascript": { "formatter": { - "jsxQuoteStyle": "double", - "quoteProperties": "asNeeded", - "trailingCommas": "all", - "semicolons": "always", - "arrowParentheses": "always", - "bracketSameLine": false, - "quoteStyle": "single", - "attributePosition": "auto", - "bracketSpacing": true + "quoteStyle": "double" + } + }, + "css": { + "parser": { + "tailwindDirectives": true + } + }, + "assist": { + "enabled": true, + "actions": { + "source": { + "organizeImports": "on" + } } } -} +} \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..ff93803 --- /dev/null +++ b/index.html @@ -0,0 +1,14 @@ + + + + + + + Tauri + React + Typescript + + + +
+ + + diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 04c7048..0000000 --- a/package-lock.json +++ /dev/null @@ -1,7624 +0,0 @@ -{ - "name": "valpal", - "version": "0.0.10", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "valpal", - "version": "0.0.10", - "dependencies": { - "@radix-ui/react-dialog": "^1.1.4", - "@radix-ui/react-tabs": "^1.1.2", - "@react-router/express": "^7.1.1", - "@react-router/node": "^7.1.1", - "axios": "^1.7.9", - "compression": "^1.7.5", - "express": "^4.21.1", - "isbot": "^5.1.17", - "morgan": "^1.10.0", - "not-the-systray": "^0.3.1", - "react": "^19.0.0", - "react-dom": "^19.0.0", - "react-router": "^7.1.1", - "ws": "^8.18.0", - "zod-form-data": "^2.0.5" - }, - "devDependencies": { - "@biomejs/biome": "1.9.4", - "@react-router/dev": "^7.1.1", - "@types/compression": "^1.7.5", - "@types/express": "^5.0.0", - "@types/express-serve-static-core": "^5.0.1", - "@types/morgan": "^1.9.9", - "@types/node": "^20", - "@types/react": "^19.0.1", - "@types/react-dom": "^19.0.1", - "@types/ws": "^8.5.13", - "@yao-pkg/pkg": "^6.2.0", - "autoprefixer": "^10.4.20", - "cross-env": "^7.0.3", - "esbuild": "^0.24.2", - "postcss": "^8.4.49", - "tailwind-scrollbar": "^3.1.0", - "tailwindcss": "^3.4.16", - "typescript": "^5.7.2", - "vite": "^5.4.11", - "vite-tsconfig-paths": "^5.1.4" - } - }, - "node_modules/@alloc/quick-lru": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", - "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", - "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.25.9", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.3.tgz", - "integrity": "sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", - "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.26.0", - "@babel/generator": "^7.26.0", - "@babel/helper-compilation-targets": "^7.25.9", - "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.0", - "@babel/parser": "^7.26.0", - "@babel/template": "^7.25.9", - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.26.0", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", - "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.26.3", - "@babel/types": "^7.26.3", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^3.0.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", - "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", - "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.25.9", - "@babel/helper-validator-option": "^7.25.9", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", - "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.25.9", - "@babel/helper-member-expression-to-functions": "^7.25.9", - "@babel/helper-optimise-call-expression": "^7.25.9", - "@babel/helper-replace-supers": "^7.25.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", - "@babel/traverse": "^7.25.9", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", - "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", - "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", - "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9", - "@babel/traverse": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", - "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", - "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz", - "integrity": "sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.25.9", - "@babel/helper-optimise-call-expression": "^7.25.9", - "@babel/traverse": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", - "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", - "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", - "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", - "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", - "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.25.9", - "@babel/types": "^7.26.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz", - "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.26.3" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-syntax-decorators": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.25.9.tgz", - "integrity": "sha512-ryzI0McXUPJnRCvMo4lumIKZUzhYUO/ScI+Mz4YVaTLt04DHNSjEUjKVvbzQjZFLuod/cYEc07mJWhzl6v4DPg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz", - "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz", - "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", - "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.26.0", - "@babel/helper-plugin-utils": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typescript": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.26.3.tgz", - "integrity": "sha512-6+5hpdr6mETwSKjmJUdYw0EIkATiQhnELWlE3kJFBwSg/BGIVwVaVbX+gOXBCdc7Ln1RXZxyWGecIXhUfnl7oA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.25.9", - "@babel/helper-create-class-features-plugin": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", - "@babel/plugin-syntax-typescript": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-typescript": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.26.0.tgz", - "integrity": "sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-validator-option": "^7.25.9", - "@babel/plugin-syntax-jsx": "^7.25.9", - "@babel/plugin-transform-modules-commonjs": "^7.25.9", - "@babel/plugin-transform-typescript": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/template": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", - "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.25.9", - "@babel/parser": "^7.25.9", - "@babel/types": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.26.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz", - "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.3", - "@babel/parser": "^7.26.3", - "@babel/template": "^7.25.9", - "@babel/types": "^7.26.3", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", - "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@biomejs/biome": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.9.4.tgz", - "integrity": "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==", - "dev": true, - "hasInstallScript": true, - "license": "MIT OR Apache-2.0", - "bin": { - "biome": "bin/biome" - }, - "engines": { - "node": ">=14.21.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/biome" - }, - "optionalDependencies": { - "@biomejs/cli-darwin-arm64": "1.9.4", - "@biomejs/cli-darwin-x64": "1.9.4", - "@biomejs/cli-linux-arm64": "1.9.4", - "@biomejs/cli-linux-arm64-musl": "1.9.4", - "@biomejs/cli-linux-x64": "1.9.4", - "@biomejs/cli-linux-x64-musl": "1.9.4", - "@biomejs/cli-win32-arm64": "1.9.4", - "@biomejs/cli-win32-x64": "1.9.4" - } - }, - "node_modules/@biomejs/cli-darwin-arm64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.4.tgz", - "integrity": "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-darwin-x64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.4.tgz", - "integrity": "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-linux-arm64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.4.tgz", - "integrity": "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-linux-arm64-musl": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.4.tgz", - "integrity": "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-linux-x64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.4.tgz", - "integrity": "sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-linux-x64-musl": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.9.4.tgz", - "integrity": "sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-win32-arm64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.4.tgz", - "integrity": "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-win32-x64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.4.tgz", - "integrity": "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", - "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz", - "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", - "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz", - "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", - "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", - "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", - "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", - "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", - "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", - "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", - "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", - "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", - "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", - "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", - "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", - "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", - "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz", - "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", - "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", - "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", - "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", - "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", - "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", - "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", - "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/fs-minipass": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", - "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.4" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", - "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@mjackson/node-fetch-server": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@mjackson/node-fetch-server/-/node-fetch-server-0.2.0.tgz", - "integrity": "sha512-EMlH1e30yzmTpGLQjlFmaDAjyOeZhng1/XCd7DExR8PNAnG/G1tyruZxEoUe11ClnwGhGrtsdnyyUx1frSzjng==", - "license": "MIT" - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@npmcli/git": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-4.1.0.tgz", - "integrity": "sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "@npmcli/promise-spawn": "^6.0.0", - "lru-cache": "^7.4.4", - "npm-pick-manifest": "^8.0.0", - "proc-log": "^3.0.0", - "promise-inflight": "^1.0.1", - "promise-retry": "^2.0.1", - "semver": "^7.3.5", - "which": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/git/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/@npmcli/package-json": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-4.0.1.tgz", - "integrity": "sha512-lRCEGdHZomFsURroh522YvA/2cVb9oPIJrjHanCJZkiasz1BzcnLr3tBJhlV7S86MBJBuAQ33is2D60YitZL2Q==", - "dev": true, - "license": "ISC", - "dependencies": { - "@npmcli/git": "^4.1.0", - "glob": "^10.2.2", - "hosted-git-info": "^6.1.1", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^5.0.0", - "proc-log": "^3.0.0", - "semver": "^7.5.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/promise-spawn": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-6.0.2.tgz", - "integrity": "sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==", - "dev": true, - "license": "ISC", - "dependencies": { - "which": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@radix-ui/primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz", - "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==", - "license": "MIT" - }, - "node_modules/@radix-ui/react-collection": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.1.tgz", - "integrity": "sha512-LwT3pSho9Dljg+wY2KN2mrrh6y3qELfftINERIzBUO9e0N+t0oMTyn3k9iv+ZqgrwGkRnLpNJrsMv9BZlt2yuA==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-slot": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz", - "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-context": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", - "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dialog": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.4.tgz", - "integrity": "sha512-Ur7EV1IwQGCyaAuyDRiOLA5JIUZxELJljF+MbM/2NC0BYwfuRrbpS30BiQBJrVruscgUkieKkqXYDOoByaxIoA==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.1", - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.3", - "@radix-ui/react-focus-guards": "1.1.1", - "@radix-ui/react-focus-scope": "1.1.1", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-portal": "1.1.3", - "@radix-ui/react-presence": "1.1.2", - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-slot": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.1.0", - "aria-hidden": "^1.1.1", - "react-remove-scroll": "^2.6.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-direction": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz", - "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.3.tgz", - "integrity": "sha512-onrWn/72lQoEucDmJnr8uczSNTujT0vJnA/X5+3AkChVPowr8n1yvIKIabhWyMQeMvvmdpsvcyDqx3X1LEXCPg==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.1", - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-escape-keydown": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-focus-guards": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz", - "integrity": "sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-focus-scope": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.1.tgz", - "integrity": "sha512-01omzJAYRxXdG2/he/+xy+c8a8gCydoQ1yOxnWNcRhrrBW5W+RQJ22EK1SaO8tb3WoUsuEw7mJjBozPzihDFjA==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-callback-ref": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-id": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz", - "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-portal": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.3.tgz", - "integrity": "sha512-NciRqhXnGojhT93RPyDaMPfLH3ZSl4jjIFbZQ1b/vxvZEdHsBZ49wP9w8L3HzUQwep01LcWtkUvm0OVB5JAHTw==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-presence": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz", - "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-primitive": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", - "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-slot": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-roving-focus": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.1.tgz", - "integrity": "sha512-QE1RoxPGJ/Nm8Qmk0PxP8ojmoaS67i0s7hVssS7KuI2FQoc/uzVlZsqKfQvxPE6D8hICCPHJ4D88zNhT3OOmkw==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.1", - "@radix-ui/react-collection": "1.1.1", - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-direction": "1.1.0", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-controllable-state": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-slot": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.1.tgz", - "integrity": "sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-tabs": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.2.tgz", - "integrity": "sha512-9u/tQJMcC2aGq7KXpGivMm1mgq7oRJKXphDwdypPd/j21j/2znamPU8WkXgnhUaTrSFNIt8XhOyCAupg8/GbwQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.1", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-direction": "1.1.0", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-presence": "1.1.2", - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-roving-focus": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-callback-ref": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", - "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-controllable-state": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", - "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-use-callback-ref": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-escape-keydown": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz", - "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-use-callback-ref": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-layout-effect": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", - "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@react-router/dev": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@react-router/dev/-/dev-7.1.1.tgz", - "integrity": "sha512-+UCrQZBAmdRcC7Bx1ho89T/DeP+FzEErkzrTvdBCpstr8AzOQ6mKlaglXGty15o3fgihBSFF4/J67jGveYIR8Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.21.8", - "@babel/generator": "^7.21.5", - "@babel/parser": "^7.21.8", - "@babel/plugin-syntax-decorators": "^7.22.10", - "@babel/plugin-syntax-jsx": "^7.21.4", - "@babel/preset-typescript": "^7.21.5", - "@babel/traverse": "^7.23.2", - "@babel/types": "^7.22.5", - "@npmcli/package-json": "^4.0.1", - "@react-router/node": "7.1.1", - "arg": "^5.0.1", - "babel-dead-code-elimination": "^1.0.6", - "chokidar": "^4.0.0", - "dedent": "^1.5.3", - "es-module-lexer": "^1.3.1", - "exit-hook": "2.2.1", - "fs-extra": "^10.0.0", - "gunzip-maybe": "^1.4.2", - "jsesc": "3.0.2", - "lodash": "^4.17.21", - "pathe": "^1.1.2", - "picocolors": "^1.1.1", - "picomatch": "^2.3.1", - "prettier": "^2.7.1", - "react-refresh": "^0.14.0", - "semver": "^7.3.7", - "set-cookie-parser": "^2.6.0", - "valibot": "^0.41.0", - "vite-node": "3.0.0-beta.2" - }, - "bin": { - "react-router": "bin.js" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "@react-router/serve": "^7.1.1", - "react-router": "^7.1.1", - "typescript": "^5.1.0", - "vite": "^5.1.0 || ^6.0.0", - "wrangler": "^3.28.2" - }, - "peerDependenciesMeta": { - "@react-router/serve": { - "optional": true - }, - "typescript": { - "optional": true - }, - "wrangler": { - "optional": true - } - } - }, - "node_modules/@react-router/express": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@react-router/express/-/express-7.1.1.tgz", - "integrity": "sha512-oiL2ADor3byuh7piajLTPr6007GmVPZ1Gh4HiN0uuZlz3vQ1rd0xZMSD9LnSrXhsrKEbPFaeCk8E2O67ZoABsg==", - "license": "MIT", - "dependencies": { - "@react-router/node": "7.1.1" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "express": "^4.17.1", - "react-router": "7.1.1", - "typescript": "^5.1.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@react-router/node": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@react-router/node/-/node-7.1.1.tgz", - "integrity": "sha512-5X79SfJ1IEEsttt0oo9rhO9kgxXyBTKdVBsz3h0WHTkRzbRk0VEpVpBW3PQ1RpkgEaAHwJ8obVl4k4brdDSExA==", - "license": "MIT", - "dependencies": { - "@mjackson/node-fetch-server": "^0.2.0", - "source-map-support": "^0.5.21", - "stream-slice": "^0.1.2", - "undici": "^6.19.2" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "react-router": "7.1.1", - "typescript": "^5.1.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.30.1.tgz", - "integrity": "sha512-pSWY+EVt3rJ9fQ3IqlrEUtXh3cGqGtPDH1FQlNZehO2yYxCHEX1SPsz1M//NXwYfbTlcKr9WObLnJX9FsS9K1Q==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.30.1.tgz", - "integrity": "sha512-/NA2qXxE3D/BRjOJM8wQblmArQq1YoBVJjrjoTSBS09jgUisq7bqxNHJ8kjCHeV21W/9WDGwJEWSN0KQ2mtD/w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.30.1.tgz", - "integrity": "sha512-r7FQIXD7gB0WJ5mokTUgUWPl0eYIH0wnxqeSAhuIwvnnpjdVB8cRRClyKLQr7lgzjctkbp5KmswWszlwYln03Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.30.1.tgz", - "integrity": "sha512-x78BavIwSH6sqfP2xeI1hd1GpHL8J4W2BXcVM/5KYKoAD3nNsfitQhvWSw+TFtQTLZ9OmlF+FEInEHyubut2OA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.30.1.tgz", - "integrity": "sha512-HYTlUAjbO1z8ywxsDFWADfTRfTIIy/oUlfIDmlHYmjUP2QRDTzBuWXc9O4CXM+bo9qfiCclmHk1x4ogBjOUpUQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.30.1.tgz", - "integrity": "sha512-1MEdGqogQLccphhX5myCJqeGNYTNcmTyaic9S7CG3JhwuIByJ7J05vGbZxsizQthP1xpVx7kd3o31eOogfEirw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.30.1.tgz", - "integrity": "sha512-PaMRNBSqCx7K3Wc9QZkFx5+CX27WFpAMxJNiYGAXfmMIKC7jstlr32UhTgK6T07OtqR+wYlWm9IxzennjnvdJg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.30.1.tgz", - "integrity": "sha512-B8Rcyj9AV7ZlEFqvB5BubG5iO6ANDsRKlhIxySXcF1axXYUyqwBok+XZPgIYGBgs7LDXfWfifxhw0Ik57T0Yug==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.30.1.tgz", - "integrity": "sha512-hqVyueGxAj3cBKrAI4aFHLV+h0Lv5VgWZs9CUGqr1z0fZtlADVV1YPOij6AhcK5An33EXaxnDLmJdQikcn5NEw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.30.1.tgz", - "integrity": "sha512-i4Ab2vnvS1AE1PyOIGp2kXni69gU2DAUVt6FSXeIqUCPIR3ZlheMW3oP2JkukDfu3PsexYRbOiJrY+yVNSk9oA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.30.1.tgz", - "integrity": "sha512-fARcF5g296snX0oLGkVxPmysetwUk2zmHcca+e9ObOovBR++9ZPOhqFUM61UUZ2EYpXVPN1redgqVoBB34nTpQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.30.1.tgz", - "integrity": "sha512-GLrZraoO3wVT4uFXh67ElpwQY0DIygxdv0BNW9Hkm3X34wu+BkqrDrkcsIapAY+N2ATEbvak0XQ9gxZtCIA5Rw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.30.1.tgz", - "integrity": "sha512-0WKLaAUUHKBtll0wvOmh6yh3S0wSU9+yas923JIChfxOaaBarmb/lBKPF0w/+jTVozFnOXJeRGZ8NvOxvk/jcw==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.30.1.tgz", - "integrity": "sha512-GWFs97Ruxo5Bt+cvVTQkOJ6TIx0xJDD/bMAOXWJg8TCSTEK8RnFeOeiFTxKniTc4vMIaWvCplMAFBt9miGxgkA==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.30.1.tgz", - "integrity": "sha512-UtgGb7QGgXDIO+tqqJ5oZRGHsDLO8SlpE4MhqpY9Llpzi5rJMvrK6ZGhsRCST2abZdBqIBeXW6WPD5fGK5SDwg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.30.1.tgz", - "integrity": "sha512-V9U8Ey2UqmQsBT+xTOeMzPzwDzyXmnAoO4edZhL7INkwQcaW1Ckv3WJX3qrrp/VHaDkEWIBWhRwP47r8cdrOow==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.30.1.tgz", - "integrity": "sha512-WabtHWiPaFF47W3PkHnjbmWawnX/aE57K47ZDT1BXTS5GgrBUEpvOzq0FI0V/UYzQJgdb8XlhVNH8/fwV8xDjw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.30.1.tgz", - "integrity": "sha512-pxHAU+Zv39hLUTdQQHUVHf4P+0C47y/ZloorHpzs2SXMRqeAWmGghzAhfOlzFHHwjvgokdFAhC4V+6kC1lRRfw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.30.1.tgz", - "integrity": "sha512-D6qjsXGcvhTjv0kI4fU8tUuBDF/Ueee4SVX79VfNDXZa64TfCW1Slkb6Z7O1p7vflqZjcmOVdZlqf8gvJxc6og==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/compression": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/@types/compression/-/compression-1.7.5.tgz", - "integrity": "sha512-AAQvK5pxMpaT+nDvhHrsBhLSYG5yQdtkaJE1WYieSNY2mVFKAgmU4ks65rkZD5oqnGCFLyQpUr1CqI4DmUMyDg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", - "license": "MIT" - }, - "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/express": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.0.tgz", - "integrity": "sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^5.0.0", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.4.tgz", - "integrity": "sha512-5kz9ScmzBdzTgB/3susoCgfqNDzBjvLL4taparufgSvlwjdLy6UyUy9T/tCpYd2GIdIilCatC4iSQS0QSYHt0w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/morgan": { - "version": "1.9.9", - "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.9.tgz", - "integrity": "sha512-iRYSDKVaC6FkGSpEVVIvrRGw0DfJMiQzIn3qr2G5B3C//AWkulhXgaBd7tS9/J79GWSYMTHGs7PfI5b3Y8m+RQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/node": { - "version": "20.17.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.12.tgz", - "integrity": "sha512-vo/wmBgMIiEA23A/knMfn/cf37VnuF52nZh5ZoW0GWt4e4sxNquibrMRJ7UQsA06+MBx9r/H1jsI9grYjQCQlw==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.19.2" - } - }, - "node_modules/@types/qs": { - "version": "6.9.17", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.17.tgz", - "integrity": "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/react": { - "version": "19.0.4", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.4.tgz", - "integrity": "sha512-3O4QisJDYr1uTUMZHA2YswiQZRq+Pd8D+GdVFYikTutYsTz+QZgWkAPnP7rx9txoI6EXKcPiluMqWPFV3tT9Wg==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-dom": { - "version": "19.0.2", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.0.2.tgz", - "integrity": "sha512-c1s+7TKFaDRRxr1TxccIX2u7sfCnc3RxkVyBIUA2lCpyqCF+QoAwQ/CBg7bsMdVwP120HEH143VQezKtef5nCg==", - "devOptional": true, - "license": "MIT", - "peerDependencies": { - "@types/react": "^19.0.0" - } - }, - "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.7", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", - "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" - } - }, - "node_modules/@types/ws": { - "version": "8.5.13", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", - "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@yao-pkg/pkg": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@yao-pkg/pkg/-/pkg-6.2.0.tgz", - "integrity": "sha512-kq1aDs9aa+fEtKQQ2AsxcL4Z82LsYw9ZQIwD3Q/wDq8ZPN69wCf2+OQp271lnqMybYInXwwBJ3swIb/nvaXS/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/generator": "^7.23.0", - "@babel/parser": "^7.23.0", - "@babel/types": "^7.23.0", - "@yao-pkg/pkg-fetch": "3.5.18", - "into-stream": "^6.0.0", - "minimist": "^1.2.6", - "multistream": "^4.1.0", - "picocolors": "^1.1.0", - "picomatch": "^4.0.2", - "prebuild-install": "^7.1.1", - "resolve": "^1.22.0", - "stream-meter": "^1.0.4", - "tar": "^7.4.3", - "tinyglobby": "^0.2.9", - "unzipper": "^0.12.3" - }, - "bin": { - "pkg": "lib-es5/bin.js" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@yao-pkg/pkg-fetch": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/@yao-pkg/pkg-fetch/-/pkg-fetch-3.5.18.tgz", - "integrity": "sha512-tdUT7zS2lyXeJwkA8lDI4aVxHwauAc5lKj6Xui3/BtDe6vDsQ8KP+f66u07AI28DuTzKxjRJKNNXVdyGv2Ndsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "https-proxy-agent": "^5.0.0", - "node-fetch": "^2.6.6", - "picocolors": "^1.1.0", - "progress": "^2.0.3", - "semver": "^7.3.5", - "tar-fs": "^2.1.1", - "yargs": "^16.2.0" - }, - "bin": { - "pkg-fetch": "lib-es5/bin.js" - } - }, - "node_modules/@yao-pkg/pkg/node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "license": "MIT", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/accepts/node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true, - "license": "MIT" - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "dev": true, - "license": "MIT" - }, - "node_modules/aria-hidden": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", - "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", - "license": "MIT", - "dependencies": { - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "license": "MIT" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT" - }, - "node_modules/autoprefixer": { - "version": "10.4.20", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", - "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.3", - "caniuse-lite": "^1.0.30001646", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.1", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/axios": { - "version": "1.7.9", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", - "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/babel-dead-code-elimination": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/babel-dead-code-elimination/-/babel-dead-code-elimination-1.0.8.tgz", - "integrity": "sha512-og6HQERk0Cmm+nTT4Od2wbPtgABXFMPaHACjbKLulZIFMkYyXZLkUGuAxdgpMJBrxyt/XFpSz++lNzjbcMnPkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.23.7", - "@babel/parser": "^7.23.6", - "@babel/traverse": "^7.23.7", - "@babel/types": "^7.23.6" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/basic-auth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", - "license": "MIT", - "dependencies": { - "safe-buffer": "5.1.2" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/basic-auth/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "license": "MIT" - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/bl/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true, - "license": "MIT" - }, - "node_modules/body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserify-zlib": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", - "integrity": "sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "pako": "~0.2.0" - } - }, - "node_modules/browserslist": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", - "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001688", - "electron-to-chromium": "^1.5.73", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.1" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "license": "MIT" - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", - "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/call-bound": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", - "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "get-intrinsic": "^1.2.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/camelcase-css": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001692", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001692.tgz", - "integrity": "sha512-A95VKan0kdtrsnMubMKxEKUKImOPSuCpYgxSQBo036P5YYgVIcOYJEgt/txJWqObiRQeISNCfef9nvlQ0vbV7A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/chownr": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", - "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "license": "MIT", - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compression": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.5.tgz", - "integrity": "sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "compressible": "~2.0.18", - "debug": "2.6.9", - "negotiator": "~0.6.4", - "on-headers": "~1.0.2", - "safe-buffer": "5.2.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" - }, - "node_modules/cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "license": "MIT" - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/cross-env": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "bin": { - "cross-env": "src/bin/cross-env.js", - "cross-env-shell": "src/bin/cross-env-shell.js" - }, - "engines": { - "node": ">=10.14", - "npm": ">=6", - "yarn": ">=1" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cross-spawn/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true, - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "devOptional": true, - "license": "MIT" - }, - "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/dedent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", - "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "babel-plugin-macros": "^3.1.0" - }, - "peerDependenciesMeta": { - "babel-plugin-macros": { - "optional": true - } - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "license": "MIT", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/detect-libc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "node_modules/detect-node-es": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", - "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", - "license": "MIT" - }, - "node_modules/didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true, - "license": "MIT" - }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "readable-stream": "^2.0.2" - } - }, - "node_modules/duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true, - "license": "MIT" - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "license": "MIT" - }, - "node_modules/electron-to-chromium": { - "version": "1.5.79", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.79.tgz", - "integrity": "sha512-nYOxJNxQ9Om4EC88BE4pPoNI8xwSFf8pU/BAeOl4Hh/b/i6V4biTAzwV7pXi3ARKeoYO5JZKMIXTryXSVer5RA==", - "dev": true, - "license": "ISC" - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/err-code": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "dev": true, - "license": "MIT" - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-module-lexer": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", - "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/esbuild": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", - "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.24.2", - "@esbuild/android-arm": "0.24.2", - "@esbuild/android-arm64": "0.24.2", - "@esbuild/android-x64": "0.24.2", - "@esbuild/darwin-arm64": "0.24.2", - "@esbuild/darwin-x64": "0.24.2", - "@esbuild/freebsd-arm64": "0.24.2", - "@esbuild/freebsd-x64": "0.24.2", - "@esbuild/linux-arm": "0.24.2", - "@esbuild/linux-arm64": "0.24.2", - "@esbuild/linux-ia32": "0.24.2", - "@esbuild/linux-loong64": "0.24.2", - "@esbuild/linux-mips64el": "0.24.2", - "@esbuild/linux-ppc64": "0.24.2", - "@esbuild/linux-riscv64": "0.24.2", - "@esbuild/linux-s390x": "0.24.2", - "@esbuild/linux-x64": "0.24.2", - "@esbuild/netbsd-arm64": "0.24.2", - "@esbuild/netbsd-x64": "0.24.2", - "@esbuild/openbsd-arm64": "0.24.2", - "@esbuild/openbsd-x64": "0.24.2", - "@esbuild/sunos-x64": "0.24.2", - "@esbuild/win32-arm64": "0.24.2", - "@esbuild/win32-ia32": "0.24.2", - "@esbuild/win32-x64": "0.24.2" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "license": "MIT" - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/exit-hook": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-2.2.1.tgz", - "integrity": "sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "dev": true, - "license": "(MIT OR WTFPL)", - "engines": { - "node": ">=6" - } - }, - "node_modules/express": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", - "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", - "license": "MIT", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.3", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.7.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.3.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.12", - "proxy-addr": "~2.0.7", - "qs": "6.13.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.2", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fastq": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", - "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/foreground-child": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", - "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/form-data": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", - "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - }, - "funding": { - "type": "patreon", - "url": "https://github.com/sponsors/rawify" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true, - "license": "MIT" - }, - "node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", - "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "function-bind": "^1.1.2", - "get-proto": "^1.0.0", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-nonce": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", - "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", - "dev": true, - "license": "MIT" - }, - "node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/globrex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", - "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", - "dev": true, - "license": "MIT" - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/gunzip-maybe": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/gunzip-maybe/-/gunzip-maybe-1.4.2.tgz", - "integrity": "sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==", - "dev": true, - "license": "MIT", - "dependencies": { - "browserify-zlib": "^0.1.4", - "is-deflate": "^1.0.0", - "is-gzip": "^1.0.0", - "peek-stream": "^1.1.0", - "pumpify": "^1.3.3", - "through2": "^2.0.3" - }, - "bin": { - "gunzip-maybe": "bin.js" - } - }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hosted-git-info": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.3.tgz", - "integrity": "sha512-HVJyzUrLIL1c0QmviVh5E8VGyUS7xCFPS6yydaVd1UegW+ibV/CohqTH9MkOLDp5o+rb82DMo77PTuc9F/8GKw==", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^7.5.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/hosted-git-info/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "license": "MIT", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true, - "license": "ISC" - }, - "node_modules/into-stream": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-6.0.0.tgz", - "integrity": "sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "from2": "^2.3.0", - "p-is-promise": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-deflate": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-deflate/-/is-deflate-1.0.0.tgz", - "integrity": "sha512-YDoFpuZWu1VRXlsnlYMzKyVRITXj7Ej/V9gXQ2/pAe7X1J7M/RNOqaIYi6qUn+B7nGyB9pDXrv02dsB58d2ZAQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-gzip": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-gzip/-/is-gzip-1.0.0.tgz", - "integrity": "sha512-rcfALRIb1YewtnksfRIHGcIY93QnK8BIQ/2c9yDYcG/Y6+vRoJuTWBmmSEbyLLYtXm7q35pHOHbZFQBaLrhlWQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/isbot": { - "version": "5.1.21", - "resolved": "https://registry.npmjs.org/isbot/-/isbot-5.1.21.tgz", - "integrity": "sha512-0q3naRVpENL0ReKHeNcwn/G7BDynp0DqZUckKyFtM9+hmpnPqgm8+8wbjiVZ0XNhq1wPQV28/Pb8Snh5adeUHA==", - "license": "Unlicense", - "engines": { - "node": ">=18" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/jiti": { - "version": "1.21.7", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", - "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", - "dev": true, - "license": "MIT", - "bin": { - "jiti": "bin/jiti.js" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/jsesc": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", - "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/json-parse-even-better-errors": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", - "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/lilconfig": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", - "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true, - "license": "MIT" - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.53.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz", - "integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/minizlib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.1.tgz", - "integrity": "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "minipass": "^7.0.4", - "rimraf": "^5.0.5" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/mkdirp": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", - "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", - "dev": true, - "license": "MIT", - "bin": { - "mkdirp": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true, - "license": "MIT" - }, - "node_modules/morgan": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", - "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", - "license": "MIT", - "dependencies": { - "basic-auth": "~2.0.1", - "debug": "2.6.9", - "depd": "~2.0.0", - "on-finished": "~2.3.0", - "on-headers": "~1.0.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/morgan/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/morgan/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/morgan/node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/multistream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/multistream/-/multistream-4.1.0.tgz", - "integrity": "sha512-J1XDiAmmNpRCBfIWJv+n0ymC4ABcf/Pl+5YvC5B/D2f/2+8PtHvCNxMPKiQcZyi922Hq69J2YOpb1pTywfifyw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "once": "^1.4.0", - "readable-stream": "^3.6.0" - } - }, - "node_modules/multistream/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "node_modules/nanoid": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", - "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/napi-build-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", - "dev": true, - "license": "MIT" - }, - "node_modules/negotiator": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", - "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/node-abi": { - "version": "3.71.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.71.0.tgz", - "integrity": "sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", - "dev": true, - "license": "MIT" - }, - "node_modules/normalize-package-data": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz", - "integrity": "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^6.0.0", - "is-core-module": "^2.8.1", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/not-the-systray": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/not-the-systray/-/not-the-systray-0.3.1.tgz", - "integrity": "sha512-AO+jt6bO8tfZWtKUMHa8pgRktWAIZvHJ4PKPKwsrxaiGunLSppawJt0EM2uFtYO+tWgq6sRgPL7QPfNmT/UQFA==", - "hasInstallScript": true, - "license": "MIT", - "os": [ - "win32" - ], - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/npm-install-checks": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.3.0.tgz", - "integrity": "sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "semver": "^7.1.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm-normalize-package-bin": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", - "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm-package-arg": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-10.1.0.tgz", - "integrity": "sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==", - "dev": true, - "license": "ISC", - "dependencies": { - "hosted-git-info": "^6.0.0", - "proc-log": "^3.0.0", - "semver": "^7.3.5", - "validate-npm-package-name": "^5.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm-pick-manifest": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-8.0.2.tgz", - "integrity": "sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg==", - "dev": true, - "license": "ISC", - "dependencies": { - "npm-install-checks": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "npm-package-arg": "^10.0.0", - "semver": "^7.3.5" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/object-inspect": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", - "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/p-is-promise": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", - "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true, - "license": "BlueOak-1.0.0" - }, - "node_modules/pako": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", - "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==", - "dev": true, - "license": "MIT" - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, - "license": "MIT" - }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/path-to-regexp": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", - "license": "MIT" - }, - "node_modules/pathe": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", - "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/peek-stream": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/peek-stream/-/peek-stream-1.1.3.tgz", - "integrity": "sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "duplexify": "^3.5.0", - "through2": "^2.0.3" - } - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/postcss": { - "version": "8.4.49", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", - "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-import": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", - "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "dev": true, - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "postcss": "^8.0.0" - } - }, - "node_modules/postcss-js": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", - "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", - "dev": true, - "license": "MIT", - "dependencies": { - "camelcase-css": "^2.0.1" - }, - "engines": { - "node": "^12 || ^14 || >= 16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.4.21" - } - }, - "node_modules/postcss-load-config": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", - "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "lilconfig": "^3.0.0", - "yaml": "^2.3.4" - }, - "engines": { - "node": ">= 14" - }, - "peerDependencies": { - "postcss": ">=8.0.9", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "postcss": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "node_modules/postcss-nested": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", - "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.1.1" - }, - "engines": { - "node": ">=12.0" - }, - "peerDependencies": { - "postcss": "^8.2.14" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/prebuild-install": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", - "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/prebuild-install/node_modules/pump": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", - "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/proc-log": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz", - "integrity": "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, - "license": "MIT" - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", - "dev": true, - "license": "ISC" - }, - "node_modules/promise-retry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", - "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" - }, - "node_modules/pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - } - }, - "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/react": { - "version": "19.0.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz", - "integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "19.0.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz", - "integrity": "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==", - "license": "MIT", - "dependencies": { - "scheduler": "^0.25.0" - }, - "peerDependencies": { - "react": "^19.0.0" - } - }, - "node_modules/react-refresh": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", - "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-remove-scroll": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.2.tgz", - "integrity": "sha512-KmONPx5fnlXYJQqC62Q+lwIeAk64ws/cUw6omIumRzMRPqgnYqhSSti99nbj0Ry13bv7dF+BKn7NB+OqkdZGTw==", - "license": "MIT", - "dependencies": { - "react-remove-scroll-bar": "^2.3.7", - "react-style-singleton": "^2.2.1", - "tslib": "^2.1.0", - "use-callback-ref": "^1.3.3", - "use-sidecar": "^1.1.2" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/react-remove-scroll-bar": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", - "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", - "license": "MIT", - "dependencies": { - "react-style-singleton": "^2.2.2", - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/react-router": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.1.1.tgz", - "integrity": "sha512-39sXJkftkKWRZ2oJtHhCxmoCrBCULr/HAH4IT5DHlgu/Q0FCPV0S4Lx+abjDTx/74xoZzNYDYbOZWlJjruyuDQ==", - "license": "MIT", - "dependencies": { - "@types/cookie": "^0.6.0", - "cookie": "^1.0.1", - "set-cookie-parser": "^2.6.0", - "turbo-stream": "2.4.0" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "react": ">=18", - "react-dom": ">=18" - }, - "peerDependenciesMeta": { - "react-dom": { - "optional": true - } - } - }, - "node_modules/react-router/node_modules/cookie": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", - "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/react-style-singleton": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", - "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", - "license": "MIT", - "dependencies": { - "get-nonce": "^1.0.0", - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pify": "^2.3.0" - } - }, - "node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "license": "MIT" - }, - "node_modules/readdirp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", - "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.16.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", - "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^10.3.7" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rollup": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.30.1.tgz", - "integrity": "sha512-mlJ4glW020fPuLi7DkM/lN97mYEZGWeqBnrljzN0gs7GLctqX3lNWxKQ7Gl712UAX+6fog/L3jh4gb7R6aVi3w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.6" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.30.1", - "@rollup/rollup-android-arm64": "4.30.1", - "@rollup/rollup-darwin-arm64": "4.30.1", - "@rollup/rollup-darwin-x64": "4.30.1", - "@rollup/rollup-freebsd-arm64": "4.30.1", - "@rollup/rollup-freebsd-x64": "4.30.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.30.1", - "@rollup/rollup-linux-arm-musleabihf": "4.30.1", - "@rollup/rollup-linux-arm64-gnu": "4.30.1", - "@rollup/rollup-linux-arm64-musl": "4.30.1", - "@rollup/rollup-linux-loongarch64-gnu": "4.30.1", - "@rollup/rollup-linux-powerpc64le-gnu": "4.30.1", - "@rollup/rollup-linux-riscv64-gnu": "4.30.1", - "@rollup/rollup-linux-s390x-gnu": "4.30.1", - "@rollup/rollup-linux-x64-gnu": "4.30.1", - "@rollup/rollup-linux-x64-musl": "4.30.1", - "@rollup/rollup-win32-arm64-msvc": "4.30.1", - "@rollup/rollup-win32-ia32-msvc": "4.30.1", - "@rollup/rollup-win32-x64-msvc": "4.30.1", - "fsevents": "~2.3.2" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" - }, - "node_modules/scheduler": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0.tgz", - "integrity": "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==", - "license": "MIT" - }, - "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/send": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/send/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/serve-static": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", - "license": "MIT", - "dependencies": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.19.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/set-cookie-parser": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", - "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", - "license": "MIT" - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "license": "ISC" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true, - "license": "CC-BY-3.0" - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.20", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", - "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/stream-meter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/stream-meter/-/stream-meter-1.0.4.tgz", - "integrity": "sha512-4sOEtrbgFotXwnEuzzsQBYEV1elAeFSO8rSGeTwabuX1RRn/kEq9JVH7I0MRBhKVRR0sJkr0M0QCH7yOLf9fhQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "^2.1.4" - } - }, - "node_modules/stream-shift": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", - "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/stream-slice": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/stream-slice/-/stream-slice-0.1.2.tgz", - "integrity": "sha512-QzQxpoacatkreL6jsxnVb7X5R/pGw9OUv2qWTYWnmLpg4NdN31snPy/f3TdQE1ZUXaThRvj1Zw4/OGg0ZkaLMA==", - "license": "MIT" - }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "license": "MIT" - }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sucrase": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", - "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "glob": "^10.3.10", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "ts-interface-checker": "^0.1.9" - }, - "bin": { - "sucrase": "bin/sucrase", - "sucrase-node": "bin/sucrase-node" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/tailwind-scrollbar": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tailwind-scrollbar/-/tailwind-scrollbar-3.1.0.tgz", - "integrity": "sha512-pmrtDIZeHyu2idTejfV59SbaJyvp1VRjYxAjZBH0jnyrPRo6HL1kD5Glz8VPagasqr6oAx6M05+Tuw429Z8jxg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.13.0" - }, - "peerDependencies": { - "tailwindcss": "3.x" - } - }, - "node_modules/tailwindcss": { - "version": "3.4.17", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", - "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", - "dev": true, - "license": "MIT", - "dependencies": { - "@alloc/quick-lru": "^5.2.0", - "arg": "^5.0.2", - "chokidar": "^3.6.0", - "didyoumean": "^1.2.2", - "dlv": "^1.1.3", - "fast-glob": "^3.3.2", - "glob-parent": "^6.0.2", - "is-glob": "^4.0.3", - "jiti": "^1.21.6", - "lilconfig": "^3.1.3", - "micromatch": "^4.0.8", - "normalize-path": "^3.0.0", - "object-hash": "^3.0.0", - "picocolors": "^1.1.1", - "postcss": "^8.4.47", - "postcss-import": "^15.1.0", - "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.2", - "postcss-nested": "^6.2.0", - "postcss-selector-parser": "^6.1.2", - "resolve": "^1.22.8", - "sucrase": "^3.35.0" - }, - "bin": { - "tailwind": "lib/cli.js", - "tailwindcss": "lib/cli.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tailwindcss/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/tailwindcss/node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/tailwindcss/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/tar": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", - "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", - "dev": true, - "license": "ISC", - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.0.1", - "mkdirp": "^3.0.1", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "dev": true, - "license": "MIT", - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/tar-fs/node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true, - "license": "ISC" - }, - "node_modules/tar-fs/node_modules/pump": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", - "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tar-stream/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/tar/node_modules/yallist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/tinyglobby": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.10.tgz", - "integrity": "sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==", - "dev": true, - "license": "MIT", - "dependencies": { - "fdir": "^6.4.2", - "picomatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/tinyglobby/node_modules/fdir": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.2.tgz", - "integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true, - "license": "MIT" - }, - "node_modules/ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/tsconfck": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.4.tgz", - "integrity": "sha512-kdqWFGVJqe+KGYvlSO9NIaWn9jT1Ny4oKVzAJsKii5eoE9snzTJzL4+MMVOMn+fikWGFmKEylcXL710V/kIPJQ==", - "dev": true, - "license": "MIT", - "bin": { - "tsconfck": "bin/tsconfck.js" - }, - "engines": { - "node": "^18 || >=20" - }, - "peerDependencies": { - "typescript": "^5.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/turbo-stream": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.4.0.tgz", - "integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==", - "license": "ISC" - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "license": "MIT", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typescript": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", - "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", - "devOptional": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.0.tgz", - "integrity": "sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw==", - "license": "MIT", - "engines": { - "node": ">=18.17" - } - }, - "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "license": "MIT" - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/unzipper": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.12.3.tgz", - "integrity": "sha512-PZ8hTS+AqcGxsaQntl3IRBw65QrBI6lxzqDEL7IAo/XCEqRTKGfOX56Vea5TH9SZczRVxuzk1re04z/YjuYCJA==", - "dev": true, - "license": "MIT", - "dependencies": { - "bluebird": "~3.7.2", - "duplexer2": "~0.1.4", - "fs-extra": "^11.2.0", - "graceful-fs": "^4.2.2", - "node-int64": "^0.4.0" - } - }, - "node_modules/unzipper/node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", - "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/use-callback-ref": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", - "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", - "license": "MIT", - "dependencies": { - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/use-sidecar": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", - "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", - "license": "MIT", - "dependencies": { - "detect-node-es": "^1.1.0", - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, - "license": "MIT" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/valibot": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/valibot/-/valibot-0.41.0.tgz", - "integrity": "sha512-igDBb8CTYr8YTQlOKgaN9nSS0Be7z+WRuaeYqGf3Cjz3aKmSnqEmYnkfVjzIuumGqfHpa3fLIvMEAfhrpqN8ng==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "typescript": ">=5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/validate-npm-package-name": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", - "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/vite": { - "version": "5.4.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", - "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vite-node": { - "version": "3.0.0-beta.2", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.0-beta.2.tgz", - "integrity": "sha512-ofTf6cfRdL30Wbl9n/BX81EyIR5s4PReLmSurrxQ+koLaWUNOEo8E0lCM53OJkb8vpa2URM2nSrxZsIFyvY1rg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.4.0", - "es-module-lexer": "^1.5.4", - "pathe": "^1.1.2", - "vite": "^5.0.0 || ^6.0.0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/vite-tsconfig-paths": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-5.1.4.tgz", - "integrity": "sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.1.1", - "globrex": "^0.1.2", - "tsconfck": "^3.0.3" - }, - "peerDependencies": { - "vite": "*" - }, - "peerDependenciesMeta": { - "vite": { - "optional": true - } - } - }, - "node_modules/vite/node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/which": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", - "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, - "license": "ISC" - }, - "node_modules/yaml": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", - "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", - "dev": true, - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/zod": { - "version": "3.24.1", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz", - "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==", - "license": "MIT", - "peer": true, - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zod-form-data": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/zod-form-data/-/zod-form-data-2.0.5.tgz", - "integrity": "sha512-T7dV6lTBCwkd8PyvJVCnjXKpgXomU8gEm/TcvEZY7qNdRhIo9T17HrdlHIK68PzTAYaV2HxR9rgwpTSWv0L+QQ==", - "license": "MIT", - "peerDependencies": { - "zod": ">= 3.11.0" - } - } - } -} diff --git a/package.json b/package.json index 01fe664..2c0d092 100644 --- a/package.json +++ b/package.json @@ -1,54 +1,36 @@ { - "name": "valpal", - "version": "0.0.10", - "private": true, - "type": "module", - "scripts": { - "build": "npm run build:react-router && npm run build:server && npm run pkg", - "build:react-router": "react-router build", - "build:server": "esbuild --platform=node --format=cjs ./server.ts --bundle --outfile=build/server.js --define:process.env.NODE_ENV=\\\"production\\\" --external:not-the-systray", - "dev": "cross-env NODE_ENV=development node --experimental-strip-types --experimental-transform-types --watch-path=./server.ts server.ts", - "start": "node --experimental-strip-types --experimental-transform-types server.ts", - "typecheck": "react-router typegen && tsc -b", - "pkg": "pkg -c pkg.json build/server.js --output dist/valpal.exe && editbin.exe /subsystem:windows dist/valpal.exe" - }, - "dependencies": { - "@radix-ui/react-dialog": "^1.1.4", - "@radix-ui/react-tabs": "^1.1.2", - "@react-router/express": "^7.1.1", - "@react-router/node": "^7.1.1", - "axios": "^1.7.9", - "compression": "^1.7.5", - "express": "^4.21.1", - "isbot": "^5.1.17", - "morgan": "^1.10.0", - "not-the-systray": "^0.3.1", - "react": "^19.0.0", - "react-dom": "^19.0.0", - "react-router": "^7.1.1", - "ws": "^8.18.0", - "zod-form-data": "^2.0.5" - }, - "devDependencies": { - "@biomejs/biome": "1.9.4", - "@react-router/dev": "^7.1.1", - "@types/compression": "^1.7.5", - "@types/express": "^5.0.0", - "@types/express-serve-static-core": "^5.0.1", - "@types/morgan": "^1.9.9", - "@types/node": "^20", - "@types/react": "^19.0.1", - "@types/react-dom": "^19.0.1", - "@types/ws": "^8.5.13", - "@yao-pkg/pkg": "^6.2.0", - "autoprefixer": "^10.4.20", - "cross-env": "^7.0.3", - "esbuild": "^0.24.2", - "postcss": "^8.4.49", - "tailwind-scrollbar": "^3.1.0", - "tailwindcss": "^3.4.16", - "typescript": "^5.7.2", - "vite": "^5.4.11", - "vite-tsconfig-paths": "^5.1.4" - } -} + "name": "valpal", + "private": true, + "version": "0.1.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "set \"RUSTFLAGS=--remap-path-prefix=%USERPROFILE%\\=/user/\" && tauri build", + "build:frontend": "tsc && react-router build", + "preview": "vite preview", + "tauri": "tauri" + }, + "dependencies": { + "@react-router/node": "^7.13.0", + "@tauri-apps/api": "^2", + "@tauri-apps/plugin-opener": "^2", + "isbot": "^5", + "react": "^19.1.0", + "react-aria-components": "^1.15.1", + "react-dom": "^19.1.0", + "react-router": "^7.13.0", + "tiny-invariant": "^1.3.3" + }, + "devDependencies": { + "@biomejs/biome": "2.4.2", + "@react-router/dev": "^7.13.0", + "@tailwindcss/vite": "^4.2.0", + "@tauri-apps/cli": "^2", + "@types/react": "^19.1.8", + "@types/react-dom": "^19.1.6", + "tailwindcss": "^4.2.0", + "typescript": "~5.8.3", + "vite": "^7.0.4", + "vite-tsconfig-paths": "^6.1.1" + } +} \ No newline at end of file diff --git a/pkg.json b/pkg.json deleted file mode 100644 index 03de5ba..0000000 --- a/pkg.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "assets": ["build/**/*"], - "targets": ["win"] -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..6b48c32 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,3964 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@react-router/node': + specifier: ^7.13.0 + version: 7.13.0(react-router@7.13.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.8.3) + '@tauri-apps/api': + specifier: ^2 + version: 2.10.1 + '@tauri-apps/plugin-opener': + specifier: ^2 + version: 2.5.3 + isbot: + specifier: ^5 + version: 5.1.35 + react: + specifier: ^19.1.0 + version: 19.2.4 + react-aria-components: + specifier: ^1.15.1 + version: 1.15.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react-dom: + specifier: ^19.1.0 + version: 19.2.4(react@19.2.4) + react-router: + specifier: ^7.13.0 + version: 7.13.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + tiny-invariant: + specifier: ^1.3.3 + version: 1.3.3 + devDependencies: + '@biomejs/biome': + specifier: 2.4.2 + version: 2.4.2 + '@react-router/dev': + specifier: ^7.13.0 + version: 7.13.0(jiti@2.6.1)(lightningcss@1.31.1)(react-router@7.13.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.8.3)(vite@7.3.1(jiti@2.6.1)(lightningcss@1.31.1)) + '@tailwindcss/vite': + specifier: ^4.2.0 + version: 4.2.0(vite@7.3.1(jiti@2.6.1)(lightningcss@1.31.1)) + '@tauri-apps/cli': + specifier: ^2 + version: 2.10.0 + '@types/react': + specifier: ^19.1.8 + version: 19.2.14 + '@types/react-dom': + specifier: ^19.1.6 + version: 19.2.3(@types/react@19.2.14) + tailwindcss: + specifier: ^4.2.0 + version: 4.2.0 + typescript: + specifier: ~5.8.3 + version: 5.8.3 + vite: + specifier: ^7.0.4 + version: 7.3.1(jiti@2.6.1)(lightningcss@1.31.1) + vite-tsconfig-paths: + specifier: ^6.1.1 + version: 6.1.1(typescript@5.8.3)(vite@7.3.1(jiti@2.6.1)(lightningcss@1.31.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-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + 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-create-class-features-plugin@7.28.6': + resolution: {integrity: sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.28.5': + resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} + 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-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + engines: {node: '>=6.9.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-replace-supers@7.28.6': + resolution: {integrity: sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + 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.28.6': + resolution: {integrity: sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.0': + resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-syntax-jsx@7.28.6': + resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.28.6': + resolution: {integrity: sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-commonjs@7.28.6': + resolution: {integrity: sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.28.6': + resolution: {integrity: sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-typescript@7.28.5': + resolution: {integrity: sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==} + 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'} + + '@biomejs/biome@2.4.2': + resolution: {integrity: sha512-vVE/FqLxNLbvYnFDYg3Xfrh1UdFhmPT5i+yPT9GE2nTUgI4rkqo5krw5wK19YHBd7aE7J6r91RRmb8RWwkjy6w==} + engines: {node: '>=14.21.3'} + hasBin: true + + '@biomejs/cli-darwin-arm64@2.4.2': + resolution: {integrity: sha512-3pEcKCP/1POKyaZZhXcxFl3+d9njmeAihZ17k8lL/1vk+6e0Cbf0yPzKItFiT+5Yh6TQA4uKvnlqe0oVZwRxCA==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + + '@biomejs/cli-darwin-x64@2.4.2': + resolution: {integrity: sha512-P7hK1jLVny+0R9UwyGcECxO6sjETxfPyBm/1dmFjnDOHgdDPjPqozByunrwh4xPKld8sxOr5eAsSqal5uKgeBg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + + '@biomejs/cli-linux-arm64-musl@2.4.2': + resolution: {integrity: sha512-/x04YK9+7erw6tYEcJv9WXoBHcULI/wMOvNdAyE9S3JStZZ9yJyV67sWAI+90UHuDo/BDhq0d96LDqGlSVv7WA==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-arm64@2.4.2': + resolution: {integrity: sha512-DI3Mi7GT2zYNgUTDEbSjl3e1KhoP76OjQdm8JpvZYZWtVDRyLd3w8llSr2TWk1z+U3P44kUBWY3X7H9MD1/DGQ==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-x64-musl@2.4.2': + resolution: {integrity: sha512-wbBmTkeAoAYbOQ33f6sfKG7pcRSydQiF+dTYOBjJsnXO2mWEOQHllKlC2YVnedqZFERp2WZhFUoO7TNRwnwEHQ==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-linux-x64@2.4.2': + resolution: {integrity: sha512-GK2ErnrKpWFigYP68cXiCHK4RTL4IUWhK92AFS3U28X/nuAL5+hTuy6hyobc8JZRSt+upXt1nXChK+tuHHx4mA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-win32-arm64@2.4.2': + resolution: {integrity: sha512-k2uqwLYrNNxnaoiW3RJxoMGnbKda8FuCmtYG3cOtVljs3CzWxaTR+AoXwKGHscC9thax9R4kOrtWqWN0+KdPTw==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@2.4.2': + resolution: {integrity: sha512-9ma7C4g8Sq3cBlRJD2yrsHXB1mnnEBdpy7PhvFrylQWQb4PoyCmPucdX7frvsSBQuFtIiKCrolPl/8tCZrKvgQ==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + + '@esbuild/aix-ppc64@0.27.3': + resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.27.3': + resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.27.3': + resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.27.3': + resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.27.3': + resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.3': + resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.27.3': + resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.3': + resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.27.3': + resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.27.3': + resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.27.3': + resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.27.3': + resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.27.3': + resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.27.3': + resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.3': + resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.27.3': + resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.27.3': + resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.27.3': + resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.3': + resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.27.3': + resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.3': + resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.3': + resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.27.3': + resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.27.3': + resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.27.3': + resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.27.3': + resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@formatjs/ecma402-abstract@2.3.6': + resolution: {integrity: sha512-HJnTFeRM2kVFVr5gr5kH1XP6K0JcJtE7Lzvtr3FS/so5f1kpsqqqxy5JF+FRaO6H2qmcMfAUIox7AJteieRtVw==} + + '@formatjs/fast-memoize@2.2.7': + resolution: {integrity: sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ==} + + '@formatjs/icu-messageformat-parser@2.11.4': + resolution: {integrity: sha512-7kR78cRrPNB4fjGFZg3Rmj5aah8rQj9KPzuLsmcSn4ipLXQvC04keycTI1F7kJYDwIXtT2+7IDEto842CfZBtw==} + + '@formatjs/icu-skeleton-parser@1.8.16': + resolution: {integrity: sha512-H13E9Xl+PxBd8D5/6TVUluSpxGNvFSlN/b3coUp0e0JpuWXXnQDiavIpY3NnvSp4xhEMoXyyBvVfdFX8jglOHQ==} + + '@formatjs/intl-localematcher@0.6.2': + resolution: {integrity: sha512-XOMO2Hupl0wdd172Y06h6kLpBz6Dv+J4okPLl4LPtzbr8f66WbIoy4ev98EBuZ6ZK4h5ydTN6XneT4QVpD7cdA==} + + '@internationalized/date@3.11.0': + resolution: {integrity: sha512-BOx5huLAWhicM9/ZFs84CzP+V3gBW6vlpM02yzsdYC7TGlZJX1OJiEEHcSayF00Z+3jLlm4w79amvSt6RqKN3Q==} + + '@internationalized/message@3.1.8': + resolution: {integrity: sha512-Rwk3j/TlYZhn3HQ6PyXUV0XP9Uv42jqZGNegt0BXlxjE6G3+LwHjbQZAGHhCnCPdaA6Tvd3ma/7QzLlLkJxAWA==} + + '@internationalized/number@3.6.5': + resolution: {integrity: sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g==} + + '@internationalized/string@3.2.7': + resolution: {integrity: sha512-D4OHBjrinH+PFZPvfCXvG28n2LSykWcJ7GIioQL+ok0LON15SdfoUssoHzzOUmVZLbRoREsQXVzA6r8JKsbP6A==} + + '@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==} + + '@mjackson/node-fetch-server@0.2.0': + resolution: {integrity: sha512-EMlH1e30yzmTpGLQjlFmaDAjyOeZhng1/XCd7DExR8PNAnG/G1tyruZxEoUe11ClnwGhGrtsdnyyUx1frSzjng==} + + '@react-aria/autocomplete@3.0.0-rc.5': + resolution: {integrity: sha512-qcGr/ZlSJxw78QtXB29MnvCwGZKlJ5FGfSICjaX/KIg4ONGFR/u4QjP/axA+vhlPa9Ik7BNeikWQriTcYrkbhw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/breadcrumbs@3.5.31': + resolution: {integrity: sha512-j8F2NMHFGT/n3alfFKdO4bvrY/ymtdL04GdclY7Vc6zOmCnWoEZ2UA0sFuV7Rk9dOL8fAtYV1kMD1ZRO/EMcGA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/button@3.14.4': + resolution: {integrity: sha512-6mTPiSSQhELnWlnYJ1Tm1B0VL1GGKAs2PGAY3ZGbPGQPPDc6Wu82yIhuAO8TTFJrXkwAiqjQawgDLil/yB0V7Q==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/calendar@3.9.4': + resolution: {integrity: sha512-0BvU8cj6uHn622Vp8Xd21XxXtvp3Bh4Yk1pHloqDNmUvvdBN+ol3Xsm5gG3XKKkZ+6CCEi6asCbLaEg3SZSbyg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/checkbox@3.16.4': + resolution: {integrity: sha512-FcZj6/f27mNp2+G5yxyOMRZbZQjJ1cuWvo0PPnnZ4ybSPUmSzI4uUZBk1wvsJVP9F9n+J2hZuYVCaN8pyzLweA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/collections@3.0.2': + resolution: {integrity: sha512-5GV0fj1bvfdztHozlZQ1nzdmcZOAOdZ5BhwrSyuHbK5ptmQrpAoWUK+VTQlxkAfyn5i6niaaN/llP1v3RgEemw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/color@3.1.4': + resolution: {integrity: sha512-LNFo0A9EEn2HZ8O/hASschH++M+krfezcp01XPv0/2ZQJ5b5u7VvJlUOEXtPsD4i9+BzvkSAEoVUXdlJie9V2Q==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/combobox@3.14.2': + resolution: {integrity: sha512-qwBeb8cMgK3xwrvXYHPtcphduD/k+oTcU18JHPvEO2kmR32knB33H81C2/Zoh4x86zTDJXaEtPscXBWuQ/M7AQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/datepicker@3.16.0': + resolution: {integrity: sha512-QynYHIHE+wvuGopl/k05tphmDpykpfZ3l3eKnUfGrqvAYJEeCOyS0qoMlw7Vq3NscMLFbJI6ajqBmlmtgFNiSA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/dialog@3.5.33': + resolution: {integrity: sha512-C5FpLAMJU6gQU8gztWKlEJ2A0k/JKl0YijNOv3Lizk+vUdF5njROSrmFs16bY5Hd6ycmsK9x/Pqkq3m/OpNFXA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/disclosure@3.1.2': + resolution: {integrity: sha512-UQ/CmWcdcROfRTMtvfsnYHrEsPPNbwZifZ/UErQpbvU4kzal2N+PpuP3+kpdf4G7TeMt+uJ8S9dLzyFVijOj9A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/dnd@3.11.5': + resolution: {integrity: sha512-3IGrABfK8Cf6/b/uEmGEDGeubWKMUK3umWunF/tdkWBnIaxpdj4gRkWFMw7siWQYnqir6AN567nrWXtHFcLKsA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/focus@3.21.4': + resolution: {integrity: sha512-6gz+j9ip0/vFRTKJMl3R30MHopn4i19HqqLfSQfElxJD+r9hBnYG1Q6Wd/kl/WRR1+CALn2F+rn06jUnf5sT8Q==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/form@3.1.4': + resolution: {integrity: sha512-GjPS85cE/34zal3vs6MOi7FxUsXwbxN4y6l1LFor2g92UK97gVobp238f3xdMW2T8IuaWGcnHeYFg+cjiZ51pQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/grid@3.14.7': + resolution: {integrity: sha512-8eaJThNHUs75Xf4+FQC2NKQtTOVYkkDdA8VbfbqG06oYDAn7ETb1yhbwoqh1jOv7MezCNkYjyFe4ADsz2rBVcw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/gridlist@3.14.3': + resolution: {integrity: sha512-t3nr29nU5jRG9MdWe9aiMd02V8o0pmidLU/7c4muWAu7hEH+IYdeDthGDdXL9tXAom/oQ+6yt6sOfLxpsVNmGA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/i18n@3.12.15': + resolution: {integrity: sha512-3CrAN7ORVHrckvTmbPq76jFZabqq+rScosGT5+ElircJ5rF5+JcdT99Hp5Xg6R10jk74e8G3xiqdYsUd+7iJMA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/interactions@3.27.0': + resolution: {integrity: sha512-D27pOy+0jIfHK60BB26AgqjjRFOYdvVSkwC31b2LicIzRCSPOSP06V4gMHuGmkhNTF4+YWDi1HHYjxIvMeiSlA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/label@3.7.24': + resolution: {integrity: sha512-lcJbUy6xyicWKNgzfrXksrJ2CeCST2rDxGAvHOmUxSbFOm26kK710DjaFvtO4tICWh/TKW5mC3sm77soNcVUGA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/landmark@3.0.9': + resolution: {integrity: sha512-YYyluDBCXupnMh91ccE5g27fczjYmzPebHqTkVYjH4B6k45pOoqsMmWBCMnOTl0qOCeioI+daT8W0MamAZzoSw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/link@3.8.8': + resolution: {integrity: sha512-hxQEvo5rrn2C0GOSwB/tROe+y//dyhmyXGbm8arDy6WF5Mj0wcjjrAu0/dhGYBqoltJa16iIEvs52xgzOC+f+Q==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/listbox@3.15.2': + resolution: {integrity: sha512-xcrgSediV8MaVmsuDrDPmWywF82/HOv+H+Y/dgr6GLCWl0XDj5Q7PyAhDzUsYdZNIne3B9muGh6IQc3HdkgWqg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/live-announcer@3.4.4': + resolution: {integrity: sha512-PTTBIjNRnrdJOIRTDGNifY2d//kA7GUAwRFJNOEwSNG4FW+Bq9awqLiflw0JkpyB0VNIwou6lqKPHZVLsGWOXA==} + + '@react-aria/menu@3.20.0': + resolution: {integrity: sha512-BAsHuf7kTVmawNUkTUd5RB3ZvL6DQQT7hgZ2cYKd/1ZwYq4KO2wWGYdzyTOtK1qimZL0eyHyQwDYv4dNKBH4gw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/meter@3.4.29': + resolution: {integrity: sha512-XAhJf8LlYQl+QQXqtpWvzjlrT8MZKEG6c8N3apC5DONgSKlCwfmDm4laGEJPqtuz3QGiOopsfSfyTFYHjWsfZw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/numberfield@3.12.4': + resolution: {integrity: sha512-TgKBjKOjyURzbqNR2wF4tSFmQKNK5DqE4QZSlQxpYYo1T6zuztkh+oTOUZ4IWCJymL5qLtuPfGHCZbR7B+DN2w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/overlays@3.31.1': + resolution: {integrity: sha512-U5BedzcXU97U5PWm4kIPnNoVpAs9KjTYfbkGx33vapmTVpGYhQyYW9eg6zW2E8ZKsyFJtQ/jkQnbWGen97aHSQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/progress@3.4.29': + resolution: {integrity: sha512-orSaaFLX5LdD9UyxgBrmP1J/ivyEFX+5v4ENPQM5RH5+Hl+0OJa+8ozI0AfVKBqCYc89BOZfG7kzi7wFHACZcQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/radio@3.12.4': + resolution: {integrity: sha512-2sjBAE8++EtAAfjwPdrqEVswbzR4Mvcy4n8SvwUxTo02yESa9nolBzCSdAUFUmhrNj3MiMA+zLxQ+KACfUjJOg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/searchfield@3.8.11': + resolution: {integrity: sha512-5R0prEC+jRFwPeJsK6G4RN8QG3V/+EaIuw9p79G1gFD+1dY81ZakiZIIJaLWRyO7AzYBGyC/QFHtz0m3KGQT/Q==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/select@3.17.2': + resolution: {integrity: sha512-oMpHStyMluRf67qxrzH5Qfcvw6ETQgZT1Qw2xvAxQVRd5IBb0PfzZS7TGiULOcMLqXAUOC28O/ycUGrGRKLarg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/selection@3.27.1': + resolution: {integrity: sha512-8WQ4AtWiBnk9UEeYkqpH12dd8KQW2aFbNZvM4sDfLtz7K7HWyY/MkqMe/snk9IcoSa7t4zr0bnoZJcWSGgn2PQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/separator@3.4.15': + resolution: {integrity: sha512-A1aPQhCaE8XeelNJYPjHtA2uh921ROh8PNiZI4o62x80wcziRoctN5PAtNHJAx7VKvX66A8ZVGbOqb7iqS3J5Q==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/slider@3.8.4': + resolution: {integrity: sha512-/FYCgK1qVqaz2VCDfR2x4BjyJ8lmWg1v8//+WIwKdIu4cz0KUs+U3yx0w1vp676RoERp3OEvkT3tb+/jHQ1hjA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/spinbutton@3.7.1': + resolution: {integrity: sha512-Nisah6yzxOC6983u/5ck0w+OQoa3sRKmpDvWpTEX0g2+ZIABOl8ttdSd65XKtxXmXHdK8X1zmrfeGOBfBR3sKA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/ssr@3.9.10': + resolution: {integrity: sha512-hvTm77Pf+pMBhuBm760Li0BVIO38jv1IBws1xFm1NoL26PU+fe+FMW5+VZWyANR6nYL65joaJKZqOdTQMkO9IQ==} + engines: {node: '>= 12'} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/switch@3.7.10': + resolution: {integrity: sha512-j7nrYnqX6H9J8GuqD0kdMECUozeqxeG19A2nsvfaTx3//Q7RhgIR9fqhQdVHW/wgraTlEHNH6AhDzmomBg0TNw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/table@3.17.10': + resolution: {integrity: sha512-xdEeyOzuETkOfAHhZrX7HOIwMUsCUr4rbPvHqdcNqg7Ngla2ck9iulZNAyvOPfFwELuBEd2rz1I9TYRQ2OzSQQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/tabs@3.11.0': + resolution: {integrity: sha512-9Gwo118GHrMXSyteCZL1L/LHLVlGSYkhGgiTL3e/UgnYjHfEfDJVTkV2JikuE2O/4uig52gQRlq5E99axLeE9Q==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/tag@3.8.0': + resolution: {integrity: sha512-sTV6uRKFIFU1aljKb0QjM6fPPnzBuitrbkkCUZCJ0w0RIX1JinZPh96NknNtjFwWmqoROjVNCq51EUd0Hh2SQw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/textfield@3.18.4': + resolution: {integrity: sha512-ts3Vdy2qNOzjCVeO+4RH8FSgTYN2USAMcYFeGbHOriCukVOrvgRsqcDniW7xaT60LgFdlWMJsCusvltSIyo6xw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/toast@3.0.10': + resolution: {integrity: sha512-irW5Cr4msbPo4A4ysjT70MDJbpGCe1h9SkFgdYXBPA4Xbi4jRT7TiEZeIS1I7Hsvp6shAK1Ld/m6NBS0b/gyzg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/toggle@3.12.4': + resolution: {integrity: sha512-yVcl8kEFLsV47aCA22EMPcd/KWoYqPIPSzoKjRD/iWmxcP6iGzSxDjdUgMQojNGY8Q6wL8lUxfRqKBjvl/uezQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/toolbar@3.0.0-beta.23': + resolution: {integrity: sha512-FzvNf2hWtjEwk8F2MBf4qSs6AAR/p2WFSws6kJ4f0SrWXl4wR9VDEwBEUQcIPbWCK2aUsyOjubCh55Cl4t3MoQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/tooltip@3.9.1': + resolution: {integrity: sha512-mvEhqpvF4v/wj9zw3a8bsAEnySutGbxKXXt39s6WvF6dkVfaXfsmV9ahuMCHH//UGh/yidZGLrXX4YVdrgS8lA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/tree@3.1.6': + resolution: {integrity: sha512-igLX+OQrbXCBLrtPWgUevU0iDrgTSAJh1ncHoPzfD/YDcyTDLqKdy2nZhNbJ/IdHCwTyzIknhFJ700K20Ymw9A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/utils@3.33.0': + resolution: {integrity: sha512-yvz7CMH8d2VjwbSa5nGXqjU031tYhD8ddax95VzJsHSPyqHDEGfxul8RkhGV6oO7bVqZxVs6xY66NIgae+FHjw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/virtualizer@4.1.12': + resolution: {integrity: sha512-va0VAD28nq7rk1vHZvnkq591EbWuDKBwh2NzAEn+zz9JjMtpg4utcihNXECJ1DwMRkpaT6q+KpOE7dSdzTxPBQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/visually-hidden@3.8.30': + resolution: {integrity: sha512-iY44USEU8sJy0NOJ/sTDn3YlspbhHuVG3nx2YYrzfmxbS3i+lNwkCfG8kJ77dtmbuDLIdBGKENjGkbcwz3kiJg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-router/dev@7.13.0': + resolution: {integrity: sha512-0vRfTrS6wIXr9j0STu614Cv2ytMr21evnv1r+DXPv5cJ4q0V2x2kBAXC8TAqEXkpN5vdhbXBlbGQ821zwOfhvg==} + engines: {node: '>=20.0.0'} + hasBin: true + peerDependencies: + '@react-router/serve': ^7.13.0 + '@vitejs/plugin-rsc': ~0.5.7 + react-router: ^7.13.0 + react-server-dom-webpack: ^19.2.3 + typescript: ^5.1.0 + vite: ^5.1.0 || ^6.0.0 || ^7.0.0 + wrangler: ^3.28.2 || ^4.0.0 + peerDependenciesMeta: + '@react-router/serve': + optional: true + '@vitejs/plugin-rsc': + optional: true + react-server-dom-webpack: + optional: true + typescript: + optional: true + wrangler: + optional: true + + '@react-router/node@7.13.0': + resolution: {integrity: sha512-Mhr3fAou19oc/S93tKMIBHwCPfqLpWyWM/m0NWd3pJh/wZin8/9KhAdjwxhYbXw1TrTBZBLDENa35uZ+Y7oh3A==} + engines: {node: '>=20.0.0'} + peerDependencies: + react-router: 7.13.0 + typescript: ^5.1.0 + peerDependenciesMeta: + typescript: + optional: true + + '@react-stately/autocomplete@3.0.0-beta.4': + resolution: {integrity: sha512-K2Uy7XEdseFvgwRQ8CyrYEHMupjVKEszddOapP8deNz4hntYvT1aRm0m+sKa5Kl/4kvg9c/3NZpQcrky/vRZIg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/calendar@3.9.2': + resolution: {integrity: sha512-AQj8/izwb7eY+KFqKcMLI2ygvnbAIwLuQG5KPHgJsMygFqnN4yzXKz5orGqVJnxEXLKiLPteVztx7b5EQobrtw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/checkbox@3.7.4': + resolution: {integrity: sha512-oXHMkK22CWLcmNlunDuu4p52QXYmkpx6es9AjWx/xlh3XLZdJzo/5SANioOH1QvBtwPA/c2KQy+ZBqC21NtMHw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/collections@3.12.9': + resolution: {integrity: sha512-2jywPMhVgMOh0XtutxPqIxFCIiLOnL/GXIrRKoBEo8M3Q24NoMRBavUrn9RTvjqNnec1i/8w1/8sq8cmCKEohA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/color@3.9.4': + resolution: {integrity: sha512-SprAP5STMg6K0jq+A3UoimsvvTCIGItUtWurS/lDRoQJYajFR8IUdz+mekU/GaXzvFhMN32dijOtFcfxnA4cfA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/combobox@3.12.2': + resolution: {integrity: sha512-h4YRmzA+s3aMwUrXm6jyWLN0BWWXUNiodArB1wC24xNdeI7S8O3mxz6G2r3Ne8AE02FXmZXs9SD30Mx5vVVuqQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/data@3.15.1': + resolution: {integrity: sha512-lchubLxCWg1Yswpe9yRYJAjmzP0eTYZe+AQyFJQRIT6axRi9Gs92RIZ7zhwLXxI0vcWpnAWADB9kD4bsos7xww==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/datepicker@3.16.0': + resolution: {integrity: sha512-mYtzKXufFVivrHjmxys3ryJFMPIQNhVqaSItmGnWv3ehxw+0HKBrROf3BFiEN4zP20euoP149ZaR4uNx90kMYw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/disclosure@3.0.10': + resolution: {integrity: sha512-nUistLYMjBDy+yaS5H0y0Dwfcjr12zpIh7vjhQXF4wxIh3D08NRvV1NCQ0LV+IsMej/qoPJvKS4EnXHxBI3GmQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/dnd@3.7.3': + resolution: {integrity: sha512-yBtzAimyYvJWnzP80Scx7l559+43TVSyjaMpUR6/s2IjqD3XoPKgPsv7KaFUmygBTkCBGBFJn404rYgMCOsu3g==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/flags@3.1.2': + resolution: {integrity: sha512-2HjFcZx1MyQXoPqcBGALwWWmgFVUk2TuKVIQxCbRq7fPyWXIl6VHcakCLurdtYC2Iks7zizvz0Idv48MQ38DWg==} + + '@react-stately/form@3.2.3': + resolution: {integrity: sha512-NPvjJtns1Pq9uvqeRJCf8HIdVmOm2ARLYQ2F/sqXj1w5IChJ4oWL4Xzvj29/zBitgE1vVjDhnrnwSfNlHZGX0g==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/grid@3.11.8': + resolution: {integrity: sha512-tCabR5U7ype+uEElS5Chv5n6ntUv3drXa9DwebjO05cFevUmjTkEfYPJWixpgX4UlCCvjdUFgzeQlJF+gCiozg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/layout@4.5.3': + resolution: {integrity: sha512-BDYnvO2AKzvWfxxVM96kif3qCynsA+XcNoQC+T77exH+LLT8zlK9oOdarZXTlok/eZmjs6+5wmjq51PeL6eM5w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/list@3.13.3': + resolution: {integrity: sha512-xN0v7rzhIKshhcshOzx+ZgVngXnGCtMPRdhoDLGaHzQy5YfxvKBMNLCnr5Lm4T1U/kIvHbyzxmr5uwmH8WxoIg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/menu@3.9.10': + resolution: {integrity: sha512-dY9FzjQ+6iNInVujZPyMklDGoSbaoO0yguUnALAY+yfkPAyStEElfm4aXZgRfNKOTNHe9E34oV7qefSYsclvTg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/numberfield@3.10.4': + resolution: {integrity: sha512-EniHHwXOw/Ta0x5j61OvldDAvLoi/8xOo//bzrqwnDvf2/1IKGFMD9CHs7HYhQw+9oNl3Q2V1meOTNPc4PvoMQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/overlays@3.6.22': + resolution: {integrity: sha512-sWBnuy5dqVp8d+1e+ABTRVB3YBcOW86/90pF5PWY44au3bUFXVSUBO2QMdR/6JtojDoPRmrjufonI19/Zs/20w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/radio@3.11.4': + resolution: {integrity: sha512-3svsW5VxJA5/p1vO+Qlxv+7Jq9g7f4rqX9Rbqdfd+pH7ykHaV0CUKkSRMaWfcY8Vgaf2xmcc6dvusPRqKX8T1A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/searchfield@3.5.18': + resolution: {integrity: sha512-C3/1wOON5oK0QBljj0vSbHm/IWgd29NxB+7zT1JjZcxtbcFxCj4HOxKdnPCT/d8Pojb0YS26QgKzatLZ0NnhgQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/select@3.9.1': + resolution: {integrity: sha512-CJQRqv8Dg+0RRvcig3a2YfY6POJIscDINvidRF31yK6J72rsP01dY3ria9aJjizNDHR9Q5dWFp/z+ii0cOTWIQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/selection@3.20.8': + resolution: {integrity: sha512-V1kRN1NLW+i/3Xv+Q0pN9OzuM0zFEW9mdXOOOq7l+YL6hFjqIjttT2/q4KoyiNV3W0hfoRFSTQ7XCgqnqtwEng==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/slider@3.7.4': + resolution: {integrity: sha512-cSOYSx2nsOQejMg6Ql0+GUpqAiPwRA5teYXUghNvuBDtVxnd4l2rnXs54Ww48tU43xf2+L3kkmMofThjABoEPw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/table@3.15.3': + resolution: {integrity: sha512-W1wR0O/PmdD8hCUFIAelHICjUX/Ii6ZldPlH6EILr9olyGpoCaY7XmnyG7kii1aANuQGBeskjJdXvS6LX/gyDw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/tabs@3.8.8': + resolution: {integrity: sha512-BZImWT+pHZitImRQkoL7jVhTtpGPSra1Rhh4pi8epzwogeqseEIEpuWpQebjQP74r1kfNi/iT2p5Qb31eWfh1Q==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/toast@3.1.3': + resolution: {integrity: sha512-mT9QJKmD523lqFpOp0VWZ6QHZENFK7HrodnNJDVc7g616s5GNmemdlkITV43fSY3tHeThCVvPu+Uzh7RvQ9mpQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/toggle@3.9.4': + resolution: {integrity: sha512-tjWsshRJtHC+PI5NYMlnDlV/BTo1eWq6fmR6x1mXlQfKuKGTJRzhgJyaQ2mc5K+LkifD7fchOhfapHCrRlzwMg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/tooltip@3.5.10': + resolution: {integrity: sha512-GauUdc6Of08Np2iUw4xx/DdgpvszS9CxJWYcRnNyAAGPLQrmniVrpJvb0EUKQTP9sUSci1SlmpvJh4SNZx26Bw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/tree@3.9.5': + resolution: {integrity: sha512-UpvBlzL/MpFdOepDg+cohI/zvw8DEVM8cXY/OZ8tKUXWpew1HpUglwnAI3ivm0L2k9laUIB9siW0g04ZWiH9Lg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/utils@3.11.0': + resolution: {integrity: sha512-8LZpYowJ9eZmmYLpudbo/eclIRnbhWIJZ994ncmlKlouNzKohtM8qTC6B1w1pwUbiwGdUoyzLuQbeaIor5Dvcw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/virtualizer@4.4.5': + resolution: {integrity: sha512-MP33zys3nRYTk/+3BPchxlil9GrwbMksc3XuvNACeZqYEA/oEidsHffgPL+LY0iitKCmQE6pg49MI5HvBuOd2w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/autocomplete@3.0.0-alpha.37': + resolution: {integrity: sha512-9KkL/UEUHIqp4OD4PffeZPiRV93ZBKq84sBrzTbTIPN+os+N+Lfz45Mg67NM2RumR/KQSVE0gZp7OA0eOvxPYA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/breadcrumbs@3.7.18': + resolution: {integrity: sha512-zwltqx2XSELBRQeuCraxrdfT4fpIOVu6eQXsZ4RhWlsT7DLhzj3pUGkxdPDAMfYaVdyNBqc+nhiAnCwz6tUJ8A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/button@3.15.0': + resolution: {integrity: sha512-X/K2/Oeuq7Hi8nMIzx4/YlZuvWFiSOHZt27p4HmThCnNO/9IDFPmvPrpkYjWN5eN9Nuk+P5vZUb4A7QJgYpvGA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/calendar@3.8.2': + resolution: {integrity: sha512-QbPFhvBQfrsz3x1Nnatr5SL+8XtbxvP4obESFuDrKmsqaaAv+jG5vwLiPTKp6Z3L+MWkCvKavBPuW+byhq+69A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/checkbox@3.10.3': + resolution: {integrity: sha512-Xw4jHG7uK352Wc18XXzdzmtr3Xjg8d2tPoBGNgsw39f92EY2UpoDAPHxYR0BaDe04lGfAn6YwVivI4OGVbjXIg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/color@3.1.3': + resolution: {integrity: sha512-XM0x8iZpAf036w9qceD2RFroehLxKRwkVer7EvdJNs8K8iUN8TuhCagzsomiSJtyYh5MFysEVQ2ir85toiAFyw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/combobox@3.13.11': + resolution: {integrity: sha512-5/tdmTAvqPpiWzEeaV7uLLSbSTkkoQ1mVz6NfKMPuw4ZBkY3lPc9JDkkQjY/JrquZao+KY4Dx8ZIoS0NqkrFrw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/datepicker@3.13.4': + resolution: {integrity: sha512-B5sAPoYZfluDBpgVK3ADlHbXBKRkFCQFO18Bs091IvRRwqzfoO/uf+/9UpXMw+BEF4pciLf0/kdiVQTvI3MzlA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/dialog@3.5.23': + resolution: {integrity: sha512-3tMzweYuaDOaufF5tZPMgXSA0pPFJNgdg89YRITh0wMXMG0pm+tAKVQJL1TSLLhOiLCEL08V8M/AK67dBdr2IA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/form@3.7.17': + resolution: {integrity: sha512-wBFRJ3jehHw2X2Td/KwUNxFWOqXCK7OTGG9A+W3ZI3nDGyflHQpIjqKCKV1jRySs6sv7huiPckJ7ScDleCKf7w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/grid@3.3.7': + resolution: {integrity: sha512-riET3xeKPTcRWQy6hYCMxdbdL3yubPY5Ow66b2GA2rEqoYvmDBniYXAM2Oh+q9s+YgnAP7qJK++ym8NljvHiLA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/link@3.6.6': + resolution: {integrity: sha512-M6WXxUJFmiF6GNu7xUH0uHj0jsorFBN6npkfSCNM4puStC8NbUT2+ZPySQyZXCoHMQ89g6qZ6vCc8QduVkTE7Q==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/listbox@3.7.5': + resolution: {integrity: sha512-Cn+yNip+YZBaGzu+z5xPNgmfSupnLl+li7uG5hRc+EArkk8/G42myRXz6M8wPrLM1bFAq3r85tAbyoXVmKG5Jw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/menu@3.10.6': + resolution: {integrity: sha512-OJTznQ4xE/VddBJU+HO4x5tceSOdyQhiHA1bREE1aHl+PcgHOUZLdMjXp1zFaGF16HhItHJaxpifJ4hzf4hWQA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/meter@3.4.14': + resolution: {integrity: sha512-rNw0Do2AM3zLGZ0pSWweViuddg1uW99PWzE6RQXE8nsTHTeiwDZt9SYGdObEnjd+nJ3YzemqekG0Kqt93iNBcA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/numberfield@3.8.17': + resolution: {integrity: sha512-Q9n24OaSMXrebMowbtowmHLNclknN3XkcBIaYMwA2BIGIl+fZFnI8MERM0pG87W+wki6FepDExsDW9YxQF4pnw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/overlays@3.9.3': + resolution: {integrity: sha512-LzetThNNk8T26pQRbs1I7+isuFhdFYREy7wJCsZmbB0FnZgCukGTfOtThZWv+ry11veyVJiX68jfl4SV6ACTWA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/progress@3.5.17': + resolution: {integrity: sha512-JtiGlek6QS04bFrRj1WfChjPNr7+3/+pd6yZayXGUkQUPHt1Z/cFnv3QZ/tSQTdUt1XXmjnCak9ZH9JQBqe64Q==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/radio@3.9.3': + resolution: {integrity: sha512-w2BrMGIiZxYXPCnnB2NQyifwE/rRFMIW87MyawrKO9zPSbnDkqLIHAAtqmlNk2zkz1ZEWjk9opNsuztjP7D4sA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/searchfield@3.6.7': + resolution: {integrity: sha512-POo3spZcYD14aqo0f4eNbymJ8w9EKrlu0pOOjYYWI2P0GUSRmib9cBA9xZFhvRGHuNlHo3ePjeFitYQI7L3g1g==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/select@3.12.1': + resolution: {integrity: sha512-PtIUymvQNIIzgr+piJtK/8gbH7akWtbswIbfoADPSxtZEd1/vfUIO0s8c750s3XYNlmx/4DrhugQsLYwgC35yg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/shared@3.33.0': + resolution: {integrity: sha512-xuUpP6MyuPmJtzNOqF5pzFUIHH2YogyOQfUQHag54PRmWB7AbjuGWBUv0l1UDmz6+AbzAYGmDVAzcRDOu2PFpw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/slider@3.8.3': + resolution: {integrity: sha512-HCDegYiUA27CcJKvFwgpR8ktFKf2nAirXqQEgVPV4uxk6JIeiRx41yqM/xPJGfmaqa7BARYARLT41yN2V8Kadg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/switch@3.5.16': + resolution: {integrity: sha512-6fynclkyg0wGHo3f1bwk4Z+gZZEg0Z63iP5TFhgHWdZ8W+Uq6F3u7V4IgQpuJ2NleL1c2jy2/CKdS9v06ac2Og==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/table@3.13.5': + resolution: {integrity: sha512-4/CixlNmXSuJuX2IKuUlgNd/dEgNh3WvfE/bdwuI1t5JBdShP9tHIzSkgZbrzE2xX46NeA2xq4vXNO5kBv+QDA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/tabs@3.3.21': + resolution: {integrity: sha512-Dq9bKI62rHoI4LGGcBGlZ5s0aSwB0G4Y8o0r7hQZvf1eZWc9fmqdAdTTaGG/RUyhMIGRYWl5RRUBUuC5RmaO6w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/textfield@3.12.7': + resolution: {integrity: sha512-ddiacsS6sLFtAn2/fym7lR8nbdsLgPfelNDcsDqHiu6XUHh5TCNe8ItXHFaIiyfnKTH8uJqZrSli4wfAYNfMsw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/tooltip@3.5.1': + resolution: {integrity: sha512-h6xOAWbWUJKs9CzcCyzSPATLHq7W5dS866HkXLrtCrRDShLuzQnojZnctD2tKtNt17990hjnOhl36GUBuO5kyw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@remix-run/node-fetch-server@0.13.0': + resolution: {integrity: sha512-1EsNo0ZpgXu/90AWoRZf/oE3RVTUS80tiTUpt+hv5pjtAkw7icN4WskDwz/KdAw5ARbJLMhZBrO1NqThmy/McA==} + + '@rollup/rollup-android-arm-eabi@4.57.1': + resolution: {integrity: sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.57.1': + resolution: {integrity: sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.57.1': + resolution: {integrity: sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.57.1': + resolution: {integrity: sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.57.1': + resolution: {integrity: sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.57.1': + resolution: {integrity: sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.57.1': + resolution: {integrity: sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.57.1': + resolution: {integrity: sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.57.1': + resolution: {integrity: sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.57.1': + resolution: {integrity: sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.57.1': + resolution: {integrity: sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-loong64-musl@4.57.1': + resolution: {integrity: sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.57.1': + resolution: {integrity: sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-ppc64-musl@4.57.1': + resolution: {integrity: sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.57.1': + resolution: {integrity: sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.57.1': + resolution: {integrity: sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.57.1': + resolution: {integrity: sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.57.1': + resolution: {integrity: sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.57.1': + resolution: {integrity: sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openbsd-x64@4.57.1': + resolution: {integrity: sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.57.1': + resolution: {integrity: sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.57.1': + resolution: {integrity: sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.57.1': + resolution: {integrity: sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.57.1': + resolution: {integrity: sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.57.1': + resolution: {integrity: sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==} + cpu: [x64] + os: [win32] + + '@swc/helpers@0.5.18': + resolution: {integrity: sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ==} + + '@tailwindcss/node@4.2.0': + resolution: {integrity: sha512-Yv+fn/o2OmL5fh/Ir62VXItdShnUxfpkMA4Y7jdeC8O81WPB8Kf6TT6GSHvnqgSwDzlB5iT7kDpeXxLsUS0T6Q==} + + '@tailwindcss/oxide-android-arm64@4.2.0': + resolution: {integrity: sha512-F0QkHAVaW/JNBWl4CEKWdZ9PMb0khw5DCELAOnu+RtjAfx5Zgw+gqCHFvqg3AirU1IAd181fwOtJQ5I8Yx5wtw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.2.0': + resolution: {integrity: sha512-I0QylkXsBsJMZ4nkUNSR04p6+UptjcwhcVo3Zu828ikiEqHjVmQL9RuQ6uT/cVIiKpvtVA25msu/eRV97JeNSA==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.2.0': + resolution: {integrity: sha512-6TmQIn4p09PBrmnkvbYQ0wbZhLtbaksCDx7Y7R3FYYx0yxNA7xg5KP7dowmQ3d2JVdabIHvs3Hx4K3d5uCf8xg==} + engines: {node: '>= 20'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.2.0': + resolution: {integrity: sha512-qBudxDvAa2QwGlq9y7VIzhTvp2mLJ6nD/G8/tI70DCDoneaUeLWBJaPcbfzqRIWraj+o969aDQKvKW9dvkUizw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.0': + resolution: {integrity: sha512-7XKkitpy5NIjFZNUQPeUyNJNJn1CJeV7rmMR+exHfTuOsg8rxIO9eNV5TSEnqRcaOK77zQpsyUkBWmPy8FgdSg==} + engines: {node: '>= 20'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.2.0': + resolution: {integrity: sha512-Mff5a5Q3WoQR01pGU1gr29hHM1N93xYrKkGXfPw/aRtK4bOc331Ho4Tgfsm5WDGvpevqMpdlkCojT3qlCQbCpA==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-musl@4.2.0': + resolution: {integrity: sha512-XKcSStleEVnbH6W/9DHzZv1YhjE4eSS6zOu2eRtYAIh7aV4o3vIBs+t/B15xlqoxt6ef/0uiqJVB6hkHjWD/0A==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-gnu@4.2.0': + resolution: {integrity: sha512-/hlXCBqn9K6fi7eAM0RsobHwJYa5V/xzWspVTzxnX+Ft9v6n+30Pz8+RxCn7sQL/vRHHLS30iQPrHQunu6/vJA==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-musl@4.2.0': + resolution: {integrity: sha512-lKUaygq4G7sWkhQbfdRRBkaq4LY39IriqBQ+Gk6l5nKq6Ay2M2ZZb1tlIyRNgZKS8cbErTwuYSor0IIULC0SHw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-wasm32-wasi@4.2.0': + resolution: {integrity: sha512-xuDjhAsFdUuFP5W9Ze4k/o4AskUtI8bcAGU4puTYprr89QaYFmhYOPfP+d1pH+k9ets6RoE23BXZM1X1jJqoyw==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.2.0': + resolution: {integrity: sha512-2UU/15y1sWDEDNJXxEIrfWKC2Yb4YgIW5Xz2fKFqGzFWfoMHWFlfa1EJlGO2Xzjkq/tvSarh9ZTjvbxqWvLLXA==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.2.0': + resolution: {integrity: sha512-CrFadmFoc+z76EV6LPG1jx6XceDsaCG3lFhyLNo/bV9ByPrE+FnBPckXQVP4XRkN76h3Fjt/a+5Er/oA/nCBvQ==} + engines: {node: '>= 20'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.2.0': + resolution: {integrity: sha512-AZqQzADaj742oqn2xjl5JbIOzZB/DGCYF/7bpvhA8KvjUj9HJkag6bBuwZvH1ps6dfgxNHyuJVlzSr2VpMgdTQ==} + engines: {node: '>= 20'} + + '@tailwindcss/vite@4.2.0': + resolution: {integrity: sha512-da9mFCaHpoOgtQiWtDGIikTrSpUFBtIZCG3jy/u2BGV+l/X1/pbxzmIUxNt6JWm19N3WtGi4KlJdSH/Si83WOA==} + peerDependencies: + vite: ^5.2.0 || ^6 || ^7 + + '@tauri-apps/api@2.10.1': + resolution: {integrity: sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw==} + + '@tauri-apps/cli-darwin-arm64@2.10.0': + resolution: {integrity: sha512-avqHD4HRjrMamE/7R/kzJPcAJnZs0IIS+1nkDP5b+TNBn3py7N2aIo9LIpy+VQq0AkN8G5dDpZtOOBkmWt/zjA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@tauri-apps/cli-darwin-x64@2.10.0': + resolution: {integrity: sha512-keDmlvJRStzVFjZTd0xYkBONLtgBC9eMTpmXnBXzsHuawV2q9PvDo2x6D5mhuoMVrJ9QWjgaPKBBCFks4dK71Q==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@tauri-apps/cli-linux-arm-gnueabihf@2.10.0': + resolution: {integrity: sha512-e5u0VfLZsMAC9iHaOEANumgl6lfnJx0Dtjkd8IJpysZ8jp0tJ6wrIkto2OzQgzcYyRCKgX72aKE0PFgZputA8g==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@tauri-apps/cli-linux-arm64-gnu@2.10.0': + resolution: {integrity: sha512-YrYYk2dfmBs5m+OIMCrb+JH/oo+4FtlpcrTCgiFYc7vcs6m3QDd1TTyWu0u01ewsCtK2kOdluhr/zKku+KP7HA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tauri-apps/cli-linux-arm64-musl@2.10.0': + resolution: {integrity: sha512-GUoPdVJmrJRIXFfW3Rkt+eGK9ygOdyISACZfC/bCSfOnGt8kNdQIQr5WRH9QUaTVFIwxMlQyV3m+yXYP+xhSVA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tauri-apps/cli-linux-riscv64-gnu@2.10.0': + resolution: {integrity: sha512-JO7s3TlSxshwsoKNCDkyvsx5gw2QAs/Y2GbR5UE2d5kkU138ATKoPOtxn8G1fFT1aDW4LH0rYAAfBpGkDyJJnw==} + engines: {node: '>= 10'} + cpu: [riscv64] + os: [linux] + + '@tauri-apps/cli-linux-x64-gnu@2.10.0': + resolution: {integrity: sha512-Uvh4SUUp4A6DVRSMWjelww0GnZI3PlVy7VS+DRF5napKuIehVjGl9XD0uKoCoxwAQBLctvipyEK+pDXpJeoHng==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tauri-apps/cli-linux-x64-musl@2.10.0': + resolution: {integrity: sha512-AP0KRK6bJuTpQ8kMNWvhIpKUkQJfcPFeba7QshOQZjJ8wOS6emwTN4K5g/d3AbCMo0RRdnZWwu67MlmtJyxC1Q==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tauri-apps/cli-win32-arm64-msvc@2.10.0': + resolution: {integrity: sha512-97DXVU3dJystrq7W41IX+82JEorLNY+3+ECYxvXWqkq7DBN6FsA08x/EFGE8N/b0LTOui9X2dvpGGoeZKKV08g==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@tauri-apps/cli-win32-ia32-msvc@2.10.0': + resolution: {integrity: sha512-EHyQ1iwrWy1CwMalEm9z2a6L5isQ121pe7FcA2xe4VWMJp+GHSDDGvbTv/OPdkt2Lyr7DAZBpZHM6nvlHXEc4A==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + + '@tauri-apps/cli-win32-x64-msvc@2.10.0': + resolution: {integrity: sha512-NTpyQxkpzGmU6ceWBTY2xRIEaS0ZLbVx1HE1zTA3TY/pV3+cPoPPOs+7YScr4IMzXMtOw7tLw5LEXo5oIG3qaQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@tauri-apps/cli@2.10.0': + resolution: {integrity: sha512-ZwT0T+7bw4+DPCSWzmviwq5XbXlM0cNoleDKOYPFYqcZqeKY31KlpoMW/MOON/tOFBPgi31a2v3w9gliqwL2+Q==} + engines: {node: '>= 10'} + hasBin: true + + '@tauri-apps/plugin-opener@2.5.3': + resolution: {integrity: sha512-CCcUltXMOfUEArbf3db3kCE7Ggy1ExBEBl51Ko2ODJ6GDYHRp1nSNlQm5uNCFY5k7/ufaK5Ib3Du/Zir19IYQQ==} + + '@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==} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + babel-dead-code-elimination@1.0.12: + resolution: {integrity: sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig==} + + baseline-browser-mapping@2.9.19: + resolution: {integrity: sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==} + hasBin: true + + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + caniuse-lite@1.0.30001770: + resolution: {integrity: sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + confbox@0.2.4: + resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie@1.1.1: + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} + engines: {node: '>=18'} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decimal.js@10.6.0: + resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + + dedent@1.7.1: + resolution: {integrity: sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + electron-to-chromium@1.5.286: + resolution: {integrity: sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==} + + enhanced-resolve@5.19.0: + resolution: {integrity: sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==} + engines: {node: '>=10.13.0'} + + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + + esbuild@0.27.3: + resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + exit-hook@2.2.1: + resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} + engines: {node: '>=6'} + + exsolve@1.0.8: + resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fsevents@2.3.3: + 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'} + + globrex@0.1.2: + resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + intl-messageformat@10.7.18: + resolution: {integrity: sha512-m3Ofv/X/tV8Y3tHXLohcuVuhWKo7BBq62cqY15etqmLxg2DZ34AGGgQDeR+SCta2+zICb1NX83af0GJmbQ1++g==} + + isbot@5.1.35: + resolution: {integrity: sha512-waFfC72ZNfwLLuJ2iLaoVaqcNo+CAaLR7xCpAn0Y5WfGzkNHv7ZN39Vbi1y+kb+Zs46XHOX3tZNExroFUPX+Kg==} + engines: {node: '>=18'} + + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + lightningcss-android-arm64@1.31.1: + resolution: {integrity: sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.31.1: + resolution: {integrity: sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.31.1: + resolution: {integrity: sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.31.1: + resolution: {integrity: sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.31.1: + resolution: {integrity: sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.31.1: + resolution: {integrity: sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.31.1: + resolution: {integrity: sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.31.1: + resolution: {integrity: sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.31.1: + resolution: {integrity: sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.31.1: + resolution: {integrity: sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.31.1: + resolution: {integrity: sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.31.1: + resolution: {integrity: sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==} + engines: {node: '>= 12.0.0'} + + lodash@4.17.23: + resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + ms@2.1.3: + 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} + hasBin: true + + node-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + + p-map@7.0.4: + resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==} + engines: {node: '>=18'} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + pkg-types@2.3.0: + resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} + + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + + prettier@3.8.1: + resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} + engines: {node: '>=14'} + hasBin: true + + react-aria-components@1.15.1: + resolution: {integrity: sha512-irGhZ+vBvoY9xJHf/qzPLLwFZ8cBUrYwPERGhgjE62dy/RXMUiEW+1DeTHz0OvtjbvFbhNp/I7XM9IaBvmLALg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + react-aria@3.46.0: + resolution: {integrity: sha512-We0diSsMK35jw53JFjgF9w8obBjehAUI/TRiynnzSrjRd9eoHYQcecHlptke/HEFxvya/Gcm+LA21Im1+qnIeQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + react-dom@19.2.4: + resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} + peerDependencies: + react: ^19.2.4 + + react-refresh@0.14.2: + resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} + engines: {node: '>=0.10.0'} + + react-router@7.13.0: + resolution: {integrity: sha512-PZgus8ETambRT17BUm/LL8lX3Of+oiLaPuVTRH3l1eLvSPpKO3AvhAEb5N7ihAFZQrYDqkvvWfFh9p0z9VsjLw==} + engines: {node: '>=20.0.0'} + peerDependencies: + react: '>=18' + react-dom: '>=18' + peerDependenciesMeta: + react-dom: + optional: true + + react-stately@3.44.0: + resolution: {integrity: sha512-Il3trIp2Mo1SSa9PhQFraqOpC74zEFmwuMAlu5Fj3qdtihJOKOFqoyDl7ALRrVfnvCkau6rui155d/NMKvd+RQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + react@19.2.4: + resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} + engines: {node: '>=0.10.0'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + rollup@4.57.1: + resolution: {integrity: sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==} + 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==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + set-cookie-parser@2.7.2: + resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + tailwindcss@4.2.0: + resolution: {integrity: sha512-yYzTZ4++b7fNYxFfpnberEEKu43w44aqDMNM9MHMmcKuCH7lL8jJ4yJ7LGHv7rSwiqM0nkiobF9I6cLlpS2P7Q==} + + tapable@2.3.0: + resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} + engines: {node: '>=6'} + + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + tsconfck@3.1.6: + resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} + engines: {node: ^18 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + typescript@5.8.3: + resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} + engines: {node: '>=14.17'} + hasBin: true + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + use-sync-external-store@1.6.0: + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + valibot@1.2.0: + resolution: {integrity: sha512-mm1rxUsmOxzrwnX5arGS+U4T25RdvpPjPN4yR0u9pUBov9+zGVtO84tif1eY4r6zWxVxu3KzIyknJy3rxfRZZg==} + peerDependencies: + typescript: '>=5' + peerDependenciesMeta: + typescript: + optional: true + + vite-node@3.2.4: + resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + + vite-tsconfig-paths@6.1.1: + resolution: {integrity: sha512-2cihq7zliibCCZ8P9cKJrQBkfgdvcFkOOc3Y02o3GWUDLgqjWsZudaoiuOwO/gzTzy17cS5F7ZPo4bsnS4DGkg==} + peerDependencies: + vite: '*' + + vite@7.3.1: + resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + +snapshots: + + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@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.28.6 + '@babel/parser': 7.29.0 + '@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 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.29.0 + + '@babel/helper-compilation-targets@7.28.6': + dependencies: + '@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-create-class-features-plugin@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.29.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-member-expression-to-functions@7.28.5': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.28.6': + dependencies: + '@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)': + 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 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.29.0 + + '@babel/helper-plugin-utils@7.28.6': {} + + '@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.28.6': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + + '@babel/parser@7.29.0': + dependencies: + '@babel/types': 7.29.0 + + '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/preset-typescript@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.0 + '@babel/types': 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.0 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@biomejs/biome@2.4.2': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 2.4.2 + '@biomejs/cli-darwin-x64': 2.4.2 + '@biomejs/cli-linux-arm64': 2.4.2 + '@biomejs/cli-linux-arm64-musl': 2.4.2 + '@biomejs/cli-linux-x64': 2.4.2 + '@biomejs/cli-linux-x64-musl': 2.4.2 + '@biomejs/cli-win32-arm64': 2.4.2 + '@biomejs/cli-win32-x64': 2.4.2 + + '@biomejs/cli-darwin-arm64@2.4.2': + optional: true + + '@biomejs/cli-darwin-x64@2.4.2': + optional: true + + '@biomejs/cli-linux-arm64-musl@2.4.2': + optional: true + + '@biomejs/cli-linux-arm64@2.4.2': + optional: true + + '@biomejs/cli-linux-x64-musl@2.4.2': + optional: true + + '@biomejs/cli-linux-x64@2.4.2': + optional: true + + '@biomejs/cli-win32-arm64@2.4.2': + optional: true + + '@biomejs/cli-win32-x64@2.4.2': + optional: true + + '@esbuild/aix-ppc64@0.27.3': + optional: true + + '@esbuild/android-arm64@0.27.3': + optional: true + + '@esbuild/android-arm@0.27.3': + optional: true + + '@esbuild/android-x64@0.27.3': + optional: true + + '@esbuild/darwin-arm64@0.27.3': + optional: true + + '@esbuild/darwin-x64@0.27.3': + optional: true + + '@esbuild/freebsd-arm64@0.27.3': + optional: true + + '@esbuild/freebsd-x64@0.27.3': + optional: true + + '@esbuild/linux-arm64@0.27.3': + optional: true + + '@esbuild/linux-arm@0.27.3': + optional: true + + '@esbuild/linux-ia32@0.27.3': + optional: true + + '@esbuild/linux-loong64@0.27.3': + optional: true + + '@esbuild/linux-mips64el@0.27.3': + optional: true + + '@esbuild/linux-ppc64@0.27.3': + optional: true + + '@esbuild/linux-riscv64@0.27.3': + optional: true + + '@esbuild/linux-s390x@0.27.3': + optional: true + + '@esbuild/linux-x64@0.27.3': + optional: true + + '@esbuild/netbsd-arm64@0.27.3': + optional: true + + '@esbuild/netbsd-x64@0.27.3': + optional: true + + '@esbuild/openbsd-arm64@0.27.3': + optional: true + + '@esbuild/openbsd-x64@0.27.3': + optional: true + + '@esbuild/openharmony-arm64@0.27.3': + optional: true + + '@esbuild/sunos-x64@0.27.3': + optional: true + + '@esbuild/win32-arm64@0.27.3': + optional: true + + '@esbuild/win32-ia32@0.27.3': + optional: true + + '@esbuild/win32-x64@0.27.3': + optional: true + + '@formatjs/ecma402-abstract@2.3.6': + dependencies: + '@formatjs/fast-memoize': 2.2.7 + '@formatjs/intl-localematcher': 0.6.2 + decimal.js: 10.6.0 + tslib: 2.8.1 + + '@formatjs/fast-memoize@2.2.7': + dependencies: + tslib: 2.8.1 + + '@formatjs/icu-messageformat-parser@2.11.4': + dependencies: + '@formatjs/ecma402-abstract': 2.3.6 + '@formatjs/icu-skeleton-parser': 1.8.16 + tslib: 2.8.1 + + '@formatjs/icu-skeleton-parser@1.8.16': + dependencies: + '@formatjs/ecma402-abstract': 2.3.6 + tslib: 2.8.1 + + '@formatjs/intl-localematcher@0.6.2': + dependencies: + tslib: 2.8.1 + + '@internationalized/date@3.11.0': + dependencies: + '@swc/helpers': 0.5.18 + + '@internationalized/message@3.1.8': + dependencies: + '@swc/helpers': 0.5.18 + intl-messageformat: 10.7.18 + + '@internationalized/number@3.6.5': + dependencies: + '@swc/helpers': 0.5.18 + + '@internationalized/string@3.2.7': + dependencies: + '@swc/helpers': 0.5.18 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@mjackson/node-fetch-server@0.2.0': {} + + '@react-aria/autocomplete@3.0.0-rc.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/combobox': 3.14.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/focus': 3.21.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/listbox': 3.15.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/searchfield': 3.8.11(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/textfield': 3.18.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/autocomplete': 3.0.0-beta.4(react@19.2.4) + '@react-stately/combobox': 3.12.2(react@19.2.4) + '@react-types/autocomplete': 3.0.0-alpha.37(react@19.2.4) + '@react-types/button': 3.15.0(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/breadcrumbs@3.5.31(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/link': 3.8.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/breadcrumbs': 3.7.18(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/button@3.14.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/toolbar': 3.0.0-beta.23(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/toggle': 3.9.4(react@19.2.4) + '@react-types/button': 3.15.0(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/calendar@3.9.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@internationalized/date': 3.11.0 + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/live-announcer': 3.4.4 + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/calendar': 3.9.2(react@19.2.4) + '@react-types/button': 3.15.0(react@19.2.4) + '@react-types/calendar': 3.8.2(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/checkbox@3.16.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/form': 3.1.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/label': 3.7.24(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/toggle': 3.12.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/checkbox': 3.7.4(react@19.2.4) + '@react-stately/form': 3.2.3(react@19.2.4) + '@react-stately/toggle': 3.9.4(react@19.2.4) + '@react-types/checkbox': 3.10.3(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/collections@3.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/ssr': 3.9.10(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + use-sync-external-store: 1.6.0(react@19.2.4) + + '@react-aria/color@3.1.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/numberfield': 3.12.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/slider': 3.8.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/spinbutton': 3.7.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/textfield': 3.18.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/visually-hidden': 3.8.30(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/color': 3.9.4(react@19.2.4) + '@react-stately/form': 3.2.3(react@19.2.4) + '@react-types/color': 3.1.3(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/combobox@3.14.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/focus': 3.21.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/listbox': 3.15.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/live-announcer': 3.4.4 + '@react-aria/menu': 3.20.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/overlays': 3.31.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/selection': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/textfield': 3.18.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/collections': 3.12.9(react@19.2.4) + '@react-stately/combobox': 3.12.2(react@19.2.4) + '@react-stately/form': 3.2.3(react@19.2.4) + '@react-types/button': 3.15.0(react@19.2.4) + '@react-types/combobox': 3.13.11(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/datepicker@3.16.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@internationalized/date': 3.11.0 + '@internationalized/number': 3.6.5 + '@internationalized/string': 3.2.7 + '@react-aria/focus': 3.21.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/form': 3.1.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/label': 3.7.24(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/spinbutton': 3.7.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/datepicker': 3.16.0(react@19.2.4) + '@react-stately/form': 3.2.3(react@19.2.4) + '@react-types/button': 3.15.0(react@19.2.4) + '@react-types/calendar': 3.8.2(react@19.2.4) + '@react-types/datepicker': 3.13.4(react@19.2.4) + '@react-types/dialog': 3.5.23(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/dialog@3.5.33(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/overlays': 3.31.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/dialog': 3.5.23(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/disclosure@3.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/ssr': 3.9.10(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/disclosure': 3.0.10(react@19.2.4) + '@react-types/button': 3.15.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/dnd@3.11.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@internationalized/string': 3.2.7 + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/live-announcer': 3.4.4 + '@react-aria/overlays': 3.31.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/collections': 3.12.9(react@19.2.4) + '@react-stately/dnd': 3.7.3(react@19.2.4) + '@react-types/button': 3.15.0(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/focus@3.21.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + clsx: 2.1.1 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/form@3.1.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/form': 3.2.3(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/grid@3.14.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/focus': 3.21.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/live-announcer': 3.4.4 + '@react-aria/selection': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/collections': 3.12.9(react@19.2.4) + '@react-stately/grid': 3.11.8(react@19.2.4) + '@react-stately/selection': 3.20.8(react@19.2.4) + '@react-types/checkbox': 3.10.3(react@19.2.4) + '@react-types/grid': 3.3.7(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/gridlist@3.14.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/focus': 3.21.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/grid': 3.14.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/selection': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/list': 3.13.3(react@19.2.4) + '@react-stately/tree': 3.9.5(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/i18n@3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@internationalized/date': 3.11.0 + '@internationalized/message': 3.1.8 + '@internationalized/number': 3.6.5 + '@internationalized/string': 3.2.7 + '@react-aria/ssr': 3.9.10(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/interactions@3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/ssr': 3.9.10(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/flags': 3.1.2 + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/label@3.7.24(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/landmark@3.0.9(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + use-sync-external-store: 1.6.0(react@19.2.4) + + '@react-aria/link@3.8.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/link': 3.6.6(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/listbox@3.15.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/label': 3.7.24(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/selection': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/collections': 3.12.9(react@19.2.4) + '@react-stately/list': 3.13.3(react@19.2.4) + '@react-types/listbox': 3.7.5(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/live-announcer@3.4.4': + dependencies: + '@swc/helpers': 0.5.18 + + '@react-aria/menu@3.20.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/focus': 3.21.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/overlays': 3.31.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/selection': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/collections': 3.12.9(react@19.2.4) + '@react-stately/menu': 3.9.10(react@19.2.4) + '@react-stately/selection': 3.20.8(react@19.2.4) + '@react-stately/tree': 3.9.5(react@19.2.4) + '@react-types/button': 3.15.0(react@19.2.4) + '@react-types/menu': 3.10.6(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/meter@3.4.29(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/progress': 3.4.29(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/meter': 3.4.14(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/numberfield@3.12.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/spinbutton': 3.7.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/textfield': 3.18.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/form': 3.2.3(react@19.2.4) + '@react-stately/numberfield': 3.10.4(react@19.2.4) + '@react-types/button': 3.15.0(react@19.2.4) + '@react-types/numberfield': 3.8.17(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/overlays@3.31.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/focus': 3.21.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/ssr': 3.9.10(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/visually-hidden': 3.8.30(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/overlays': 3.6.22(react@19.2.4) + '@react-types/button': 3.15.0(react@19.2.4) + '@react-types/overlays': 3.9.3(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/progress@3.4.29(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/label': 3.7.24(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/progress': 3.5.17(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/radio@3.12.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/focus': 3.21.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/form': 3.1.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/label': 3.7.24(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/radio': 3.11.4(react@19.2.4) + '@react-types/radio': 3.9.3(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/searchfield@3.8.11(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/textfield': 3.18.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/searchfield': 3.5.18(react@19.2.4) + '@react-types/button': 3.15.0(react@19.2.4) + '@react-types/searchfield': 3.6.7(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/select@3.17.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/form': 3.1.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/label': 3.7.24(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/listbox': 3.15.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/menu': 3.20.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/selection': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/visually-hidden': 3.8.30(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/select': 3.9.1(react@19.2.4) + '@react-types/button': 3.15.0(react@19.2.4) + '@react-types/select': 3.12.1(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/selection@3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/focus': 3.21.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/selection': 3.20.8(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/separator@3.4.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/slider@3.8.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/label': 3.7.24(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/slider': 3.7.4(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@react-types/slider': 3.8.3(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/spinbutton@3.7.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/live-announcer': 3.4.4 + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/button': 3.15.0(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/ssr@3.9.10(react@19.2.4)': + dependencies: + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-aria/switch@3.7.10(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/toggle': 3.12.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/toggle': 3.9.4(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@react-types/switch': 3.5.16(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/table@3.17.10(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/focus': 3.21.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/grid': 3.14.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/live-announcer': 3.4.4 + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/visually-hidden': 3.8.30(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/collections': 3.12.9(react@19.2.4) + '@react-stately/flags': 3.1.2 + '@react-stately/table': 3.15.3(react@19.2.4) + '@react-types/checkbox': 3.10.3(react@19.2.4) + '@react-types/grid': 3.3.7(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@react-types/table': 3.13.5(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/tabs@3.11.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/focus': 3.21.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/selection': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/tabs': 3.8.8(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@react-types/tabs': 3.3.21(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/tag@3.8.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/gridlist': 3.14.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/label': 3.7.24(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/selection': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/list': 3.13.3(react@19.2.4) + '@react-types/button': 3.15.0(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/textfield@3.18.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/form': 3.1.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/label': 3.7.24(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/form': 3.2.3(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@react-types/textfield': 3.12.7(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/toast@3.0.10(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/landmark': 3.0.9(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/toast': 3.1.3(react@19.2.4) + '@react-types/button': 3.15.0(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/toggle@3.12.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/toggle': 3.9.4(react@19.2.4) + '@react-types/checkbox': 3.10.3(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/toolbar@3.0.0-beta.23(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/focus': 3.21.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/tooltip@3.9.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/tooltip': 3.5.10(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@react-types/tooltip': 3.5.1(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/tree@3.1.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/gridlist': 3.14.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/selection': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/tree': 3.9.5(react@19.2.4) + '@react-types/button': 3.15.0(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/utils@3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/ssr': 3.9.10(react@19.2.4) + '@react-stately/flags': 3.1.2 + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + clsx: 2.1.1 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/virtualizer@4.1.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/virtualizer': 4.4.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-aria/visually-hidden@3.8.30(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-router/dev@7.13.0(jiti@2.6.1)(lightningcss@1.31.1)(react-router@7.13.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.8.3)(vite@7.3.1(jiti@2.6.1)(lightningcss@1.31.1))': + dependencies: + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/parser': 7.29.0 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@react-router/node': 7.13.0(react-router@7.13.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.8.3) + '@remix-run/node-fetch-server': 0.13.0 + arg: 5.0.2 + babel-dead-code-elimination: 1.0.12 + chokidar: 4.0.3 + dedent: 1.7.1 + es-module-lexer: 1.7.0 + exit-hook: 2.2.1 + isbot: 5.1.35 + jsesc: 3.0.2 + lodash: 4.17.23 + p-map: 7.0.4 + pathe: 1.1.2 + picocolors: 1.1.1 + pkg-types: 2.3.0 + prettier: 3.8.1 + react-refresh: 0.14.2 + react-router: 7.13.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + semver: 7.7.4 + tinyglobby: 0.2.15 + valibot: 1.2.0(typescript@5.8.3) + vite: 7.3.1(jiti@2.6.1)(lightningcss@1.31.1) + vite-node: 3.2.4(jiti@2.6.1)(lightningcss@1.31.1) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + '@react-router/node@7.13.0(react-router@7.13.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.8.3)': + dependencies: + '@mjackson/node-fetch-server': 0.2.0 + react-router: 7.13.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + optionalDependencies: + typescript: 5.8.3 + + '@react-stately/autocomplete@3.0.0-beta.4(react@19.2.4)': + dependencies: + '@react-stately/utils': 3.11.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/calendar@3.9.2(react@19.2.4)': + dependencies: + '@internationalized/date': 3.11.0 + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/calendar': 3.8.2(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/checkbox@3.7.4(react@19.2.4)': + dependencies: + '@react-stately/form': 3.2.3(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/checkbox': 3.10.3(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/collections@3.12.9(react@19.2.4)': + dependencies: + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/color@3.9.4(react@19.2.4)': + dependencies: + '@internationalized/number': 3.6.5 + '@internationalized/string': 3.2.7 + '@react-stately/form': 3.2.3(react@19.2.4) + '@react-stately/numberfield': 3.10.4(react@19.2.4) + '@react-stately/slider': 3.7.4(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/color': 3.1.3(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/combobox@3.12.2(react@19.2.4)': + dependencies: + '@react-stately/collections': 3.12.9(react@19.2.4) + '@react-stately/form': 3.2.3(react@19.2.4) + '@react-stately/list': 3.13.3(react@19.2.4) + '@react-stately/overlays': 3.6.22(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/combobox': 3.13.11(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/data@3.15.1(react@19.2.4)': + dependencies: + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/datepicker@3.16.0(react@19.2.4)': + dependencies: + '@internationalized/date': 3.11.0 + '@internationalized/number': 3.6.5 + '@internationalized/string': 3.2.7 + '@react-stately/form': 3.2.3(react@19.2.4) + '@react-stately/overlays': 3.6.22(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/datepicker': 3.13.4(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/disclosure@3.0.10(react@19.2.4)': + dependencies: + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/dnd@3.7.3(react@19.2.4)': + dependencies: + '@react-stately/selection': 3.20.8(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/flags@3.1.2': + dependencies: + '@swc/helpers': 0.5.18 + + '@react-stately/form@3.2.3(react@19.2.4)': + dependencies: + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/grid@3.11.8(react@19.2.4)': + dependencies: + '@react-stately/collections': 3.12.9(react@19.2.4) + '@react-stately/selection': 3.20.8(react@19.2.4) + '@react-types/grid': 3.3.7(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/layout@4.5.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-stately/collections': 3.12.9(react@19.2.4) + '@react-stately/table': 3.15.3(react@19.2.4) + '@react-stately/virtualizer': 4.4.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/grid': 3.3.7(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@react-types/table': 3.13.5(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-stately/list@3.13.3(react@19.2.4)': + dependencies: + '@react-stately/collections': 3.12.9(react@19.2.4) + '@react-stately/selection': 3.20.8(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/menu@3.9.10(react@19.2.4)': + dependencies: + '@react-stately/overlays': 3.6.22(react@19.2.4) + '@react-types/menu': 3.10.6(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/numberfield@3.10.4(react@19.2.4)': + dependencies: + '@internationalized/number': 3.6.5 + '@react-stately/form': 3.2.3(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/numberfield': 3.8.17(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/overlays@3.6.22(react@19.2.4)': + dependencies: + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/overlays': 3.9.3(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/radio@3.11.4(react@19.2.4)': + dependencies: + '@react-stately/form': 3.2.3(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/radio': 3.9.3(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/searchfield@3.5.18(react@19.2.4)': + dependencies: + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/searchfield': 3.6.7(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/select@3.9.1(react@19.2.4)': + dependencies: + '@react-stately/form': 3.2.3(react@19.2.4) + '@react-stately/list': 3.13.3(react@19.2.4) + '@react-stately/overlays': 3.6.22(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/select': 3.12.1(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/selection@3.20.8(react@19.2.4)': + dependencies: + '@react-stately/collections': 3.12.9(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/slider@3.7.4(react@19.2.4)': + dependencies: + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@react-types/slider': 3.8.3(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/table@3.15.3(react@19.2.4)': + dependencies: + '@react-stately/collections': 3.12.9(react@19.2.4) + '@react-stately/flags': 3.1.2 + '@react-stately/grid': 3.11.8(react@19.2.4) + '@react-stately/selection': 3.20.8(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/grid': 3.3.7(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@react-types/table': 3.13.5(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/tabs@3.8.8(react@19.2.4)': + dependencies: + '@react-stately/list': 3.13.3(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@react-types/tabs': 3.3.21(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/toast@3.1.3(react@19.2.4)': + dependencies: + '@swc/helpers': 0.5.18 + react: 19.2.4 + use-sync-external-store: 1.6.0(react@19.2.4) + + '@react-stately/toggle@3.9.4(react@19.2.4)': + dependencies: + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/checkbox': 3.10.3(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/tooltip@3.5.10(react@19.2.4)': + dependencies: + '@react-stately/overlays': 3.6.22(react@19.2.4) + '@react-types/tooltip': 3.5.1(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/tree@3.9.5(react@19.2.4)': + dependencies: + '@react-stately/collections': 3.12.9(react@19.2.4) + '@react-stately/selection': 3.20.8(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/utils@3.11.0(react@19.2.4)': + dependencies: + '@swc/helpers': 0.5.18 + react: 19.2.4 + + '@react-stately/virtualizer@4.4.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-types/shared': 3.33.0(react@19.2.4) + '@swc/helpers': 0.5.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-types/autocomplete@3.0.0-alpha.37(react@19.2.4)': + dependencies: + '@react-types/combobox': 3.13.11(react@19.2.4) + '@react-types/searchfield': 3.6.7(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + + '@react-types/breadcrumbs@3.7.18(react@19.2.4)': + dependencies: + '@react-types/link': 3.6.6(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + + '@react-types/button@3.15.0(react@19.2.4)': + dependencies: + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + + '@react-types/calendar@3.8.2(react@19.2.4)': + dependencies: + '@internationalized/date': 3.11.0 + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + + '@react-types/checkbox@3.10.3(react@19.2.4)': + dependencies: + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + + '@react-types/color@3.1.3(react@19.2.4)': + dependencies: + '@react-types/shared': 3.33.0(react@19.2.4) + '@react-types/slider': 3.8.3(react@19.2.4) + react: 19.2.4 + + '@react-types/combobox@3.13.11(react@19.2.4)': + dependencies: + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + + '@react-types/datepicker@3.13.4(react@19.2.4)': + dependencies: + '@internationalized/date': 3.11.0 + '@react-types/calendar': 3.8.2(react@19.2.4) + '@react-types/overlays': 3.9.3(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + + '@react-types/dialog@3.5.23(react@19.2.4)': + dependencies: + '@react-types/overlays': 3.9.3(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + + '@react-types/form@3.7.17(react@19.2.4)': + dependencies: + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + + '@react-types/grid@3.3.7(react@19.2.4)': + dependencies: + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + + '@react-types/link@3.6.6(react@19.2.4)': + dependencies: + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + + '@react-types/listbox@3.7.5(react@19.2.4)': + dependencies: + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + + '@react-types/menu@3.10.6(react@19.2.4)': + dependencies: + '@react-types/overlays': 3.9.3(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + + '@react-types/meter@3.4.14(react@19.2.4)': + dependencies: + '@react-types/progress': 3.5.17(react@19.2.4) + react: 19.2.4 + + '@react-types/numberfield@3.8.17(react@19.2.4)': + dependencies: + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + + '@react-types/overlays@3.9.3(react@19.2.4)': + dependencies: + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + + '@react-types/progress@3.5.17(react@19.2.4)': + dependencies: + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + + '@react-types/radio@3.9.3(react@19.2.4)': + dependencies: + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + + '@react-types/searchfield@3.6.7(react@19.2.4)': + dependencies: + '@react-types/shared': 3.33.0(react@19.2.4) + '@react-types/textfield': 3.12.7(react@19.2.4) + react: 19.2.4 + + '@react-types/select@3.12.1(react@19.2.4)': + dependencies: + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + + '@react-types/shared@3.33.0(react@19.2.4)': + dependencies: + react: 19.2.4 + + '@react-types/slider@3.8.3(react@19.2.4)': + dependencies: + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + + '@react-types/switch@3.5.16(react@19.2.4)': + dependencies: + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + + '@react-types/table@3.13.5(react@19.2.4)': + dependencies: + '@react-types/grid': 3.3.7(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + + '@react-types/tabs@3.3.21(react@19.2.4)': + dependencies: + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + + '@react-types/textfield@3.12.7(react@19.2.4)': + dependencies: + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + + '@react-types/tooltip@3.5.1(react@19.2.4)': + dependencies: + '@react-types/overlays': 3.9.3(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + + '@remix-run/node-fetch-server@0.13.0': {} + + '@rollup/rollup-android-arm-eabi@4.57.1': + optional: true + + '@rollup/rollup-android-arm64@4.57.1': + optional: true + + '@rollup/rollup-darwin-arm64@4.57.1': + optional: true + + '@rollup/rollup-darwin-x64@4.57.1': + optional: true + + '@rollup/rollup-freebsd-arm64@4.57.1': + optional: true + + '@rollup/rollup-freebsd-x64@4.57.1': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.57.1': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.57.1': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.57.1': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.57.1': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.57.1': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.57.1': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.57.1': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.57.1': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.57.1': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.57.1': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.57.1': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.57.1': + optional: true + + '@rollup/rollup-linux-x64-musl@4.57.1': + optional: true + + '@rollup/rollup-openbsd-x64@4.57.1': + optional: true + + '@rollup/rollup-openharmony-arm64@4.57.1': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.57.1': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.57.1': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.57.1': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.57.1': + optional: true + + '@swc/helpers@0.5.18': + dependencies: + tslib: 2.8.1 + + '@tailwindcss/node@4.2.0': + dependencies: + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.19.0 + jiti: 2.6.1 + lightningcss: 1.31.1 + magic-string: 0.30.21 + source-map-js: 1.2.1 + tailwindcss: 4.2.0 + + '@tailwindcss/oxide-android-arm64@4.2.0': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.2.0': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.2.0': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.2.0': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.0': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.2.0': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.2.0': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.2.0': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.2.0': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.2.0': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.2.0': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.2.0': + optional: true + + '@tailwindcss/oxide@4.2.0': + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.2.0 + '@tailwindcss/oxide-darwin-arm64': 4.2.0 + '@tailwindcss/oxide-darwin-x64': 4.2.0 + '@tailwindcss/oxide-freebsd-x64': 4.2.0 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.0 + '@tailwindcss/oxide-linux-arm64-gnu': 4.2.0 + '@tailwindcss/oxide-linux-arm64-musl': 4.2.0 + '@tailwindcss/oxide-linux-x64-gnu': 4.2.0 + '@tailwindcss/oxide-linux-x64-musl': 4.2.0 + '@tailwindcss/oxide-wasm32-wasi': 4.2.0 + '@tailwindcss/oxide-win32-arm64-msvc': 4.2.0 + '@tailwindcss/oxide-win32-x64-msvc': 4.2.0 + + '@tailwindcss/vite@4.2.0(vite@7.3.1(jiti@2.6.1)(lightningcss@1.31.1))': + dependencies: + '@tailwindcss/node': 4.2.0 + '@tailwindcss/oxide': 4.2.0 + tailwindcss: 4.2.0 + vite: 7.3.1(jiti@2.6.1)(lightningcss@1.31.1) + + '@tauri-apps/api@2.10.1': {} + + '@tauri-apps/cli-darwin-arm64@2.10.0': + optional: true + + '@tauri-apps/cli-darwin-x64@2.10.0': + optional: true + + '@tauri-apps/cli-linux-arm-gnueabihf@2.10.0': + optional: true + + '@tauri-apps/cli-linux-arm64-gnu@2.10.0': + optional: true + + '@tauri-apps/cli-linux-arm64-musl@2.10.0': + optional: true + + '@tauri-apps/cli-linux-riscv64-gnu@2.10.0': + optional: true + + '@tauri-apps/cli-linux-x64-gnu@2.10.0': + optional: true + + '@tauri-apps/cli-linux-x64-musl@2.10.0': + optional: true + + '@tauri-apps/cli-win32-arm64-msvc@2.10.0': + optional: true + + '@tauri-apps/cli-win32-ia32-msvc@2.10.0': + optional: true + + '@tauri-apps/cli-win32-x64-msvc@2.10.0': + optional: true + + '@tauri-apps/cli@2.10.0': + optionalDependencies: + '@tauri-apps/cli-darwin-arm64': 2.10.0 + '@tauri-apps/cli-darwin-x64': 2.10.0 + '@tauri-apps/cli-linux-arm-gnueabihf': 2.10.0 + '@tauri-apps/cli-linux-arm64-gnu': 2.10.0 + '@tauri-apps/cli-linux-arm64-musl': 2.10.0 + '@tauri-apps/cli-linux-riscv64-gnu': 2.10.0 + '@tauri-apps/cli-linux-x64-gnu': 2.10.0 + '@tauri-apps/cli-linux-x64-musl': 2.10.0 + '@tauri-apps/cli-win32-arm64-msvc': 2.10.0 + '@tauri-apps/cli-win32-ia32-msvc': 2.10.0 + '@tauri-apps/cli-win32-x64-msvc': 2.10.0 + + '@tauri-apps/plugin-opener@2.5.3': + dependencies: + '@tauri-apps/api': 2.10.1 + + '@types/estree@1.0.8': {} + + '@types/react-dom@19.2.3(@types/react@19.2.14)': + dependencies: + '@types/react': 19.2.14 + + '@types/react@19.2.14': + dependencies: + csstype: 3.2.3 + + arg@5.0.2: {} + + babel-dead-code-elimination@1.0.12: + dependencies: + '@babel/core': 7.29.0 + '@babel/parser': 7.29.0 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + baseline-browser-mapping@2.9.19: {} + + browserslist@4.28.1: + dependencies: + baseline-browser-mapping: 2.9.19 + caniuse-lite: 1.0.30001770 + electron-to-chromium: 1.5.286 + node-releases: 2.0.27 + update-browserslist-db: 1.2.3(browserslist@4.28.1) + + cac@6.7.14: {} + + caniuse-lite@1.0.30001770: {} + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + client-only@0.0.1: {} + + clsx@2.1.1: {} + + confbox@0.2.4: {} + + convert-source-map@2.0.0: {} + + cookie@1.1.1: {} + + csstype@3.2.3: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decimal.js@10.6.0: {} + + dedent@1.7.1: {} + + detect-libc@2.1.2: {} + + electron-to-chromium@1.5.286: {} + + enhanced-resolve@5.19.0: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.0 + + es-module-lexer@1.7.0: {} + + esbuild@0.27.3: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.3 + '@esbuild/android-arm': 0.27.3 + '@esbuild/android-arm64': 0.27.3 + '@esbuild/android-x64': 0.27.3 + '@esbuild/darwin-arm64': 0.27.3 + '@esbuild/darwin-x64': 0.27.3 + '@esbuild/freebsd-arm64': 0.27.3 + '@esbuild/freebsd-x64': 0.27.3 + '@esbuild/linux-arm': 0.27.3 + '@esbuild/linux-arm64': 0.27.3 + '@esbuild/linux-ia32': 0.27.3 + '@esbuild/linux-loong64': 0.27.3 + '@esbuild/linux-mips64el': 0.27.3 + '@esbuild/linux-ppc64': 0.27.3 + '@esbuild/linux-riscv64': 0.27.3 + '@esbuild/linux-s390x': 0.27.3 + '@esbuild/linux-x64': 0.27.3 + '@esbuild/netbsd-arm64': 0.27.3 + '@esbuild/netbsd-x64': 0.27.3 + '@esbuild/openbsd-arm64': 0.27.3 + '@esbuild/openbsd-x64': 0.27.3 + '@esbuild/openharmony-arm64': 0.27.3 + '@esbuild/sunos-x64': 0.27.3 + '@esbuild/win32-arm64': 0.27.3 + '@esbuild/win32-ia32': 0.27.3 + '@esbuild/win32-x64': 0.27.3 + + escalade@3.2.0: {} + + exit-hook@2.2.1: {} + + exsolve@1.0.8: {} + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + fsevents@2.3.3: + optional: true + + gensync@1.0.0-beta.2: {} + + globrex@0.1.2: {} + + graceful-fs@4.2.11: {} + + intl-messageformat@10.7.18: + dependencies: + '@formatjs/ecma402-abstract': 2.3.6 + '@formatjs/fast-memoize': 2.2.7 + '@formatjs/icu-messageformat-parser': 2.11.4 + tslib: 2.8.1 + + isbot@5.1.35: {} + + jiti@2.6.1: {} + + js-tokens@4.0.0: {} + + jsesc@3.0.2: {} + + jsesc@3.1.0: {} + + json5@2.2.3: {} + + lightningcss-android-arm64@1.31.1: + optional: true + + lightningcss-darwin-arm64@1.31.1: + optional: true + + lightningcss-darwin-x64@1.31.1: + optional: true + + lightningcss-freebsd-x64@1.31.1: + optional: true + + lightningcss-linux-arm-gnueabihf@1.31.1: + optional: true + + lightningcss-linux-arm64-gnu@1.31.1: + optional: true + + lightningcss-linux-arm64-musl@1.31.1: + optional: true + + lightningcss-linux-x64-gnu@1.31.1: + optional: true + + lightningcss-linux-x64-musl@1.31.1: + optional: true + + lightningcss-win32-arm64-msvc@1.31.1: + optional: true + + lightningcss-win32-x64-msvc@1.31.1: + optional: true + + lightningcss@1.31.1: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.31.1 + lightningcss-darwin-arm64: 1.31.1 + lightningcss-darwin-x64: 1.31.1 + lightningcss-freebsd-x64: 1.31.1 + lightningcss-linux-arm-gnueabihf: 1.31.1 + lightningcss-linux-arm64-gnu: 1.31.1 + lightningcss-linux-arm64-musl: 1.31.1 + lightningcss-linux-x64-gnu: 1.31.1 + lightningcss-linux-x64-musl: 1.31.1 + lightningcss-win32-arm64-msvc: 1.31.1 + lightningcss-win32-x64-msvc: 1.31.1 + + lodash@4.17.23: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + ms@2.1.3: {} + + nanoid@3.3.11: {} + + node-releases@2.0.27: {} + + p-map@7.0.4: {} + + pathe@1.1.2: {} + + pathe@2.0.3: {} + + picocolors@1.1.1: {} + + picomatch@4.0.3: {} + + pkg-types@2.3.0: + dependencies: + confbox: 0.2.4 + exsolve: 1.0.8 + pathe: 2.0.3 + + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prettier@3.8.1: {} + + react-aria-components@1.15.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + '@internationalized/date': 3.11.0 + '@internationalized/string': 3.2.7 + '@react-aria/autocomplete': 3.0.0-rc.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/collections': 3.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/dnd': 3.11.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/focus': 3.21.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/live-announcer': 3.4.4 + '@react-aria/overlays': 3.31.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/ssr': 3.9.10(react@19.2.4) + '@react-aria/textfield': 3.18.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/toolbar': 3.0.0-beta.23(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/virtualizer': 4.1.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/autocomplete': 3.0.0-beta.4(react@19.2.4) + '@react-stately/layout': 4.5.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-stately/selection': 3.20.8(react@19.2.4) + '@react-stately/table': 3.15.3(react@19.2.4) + '@react-stately/utils': 3.11.0(react@19.2.4) + '@react-stately/virtualizer': 4.4.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/form': 3.7.17(react@19.2.4) + '@react-types/grid': 3.3.7(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + '@react-types/table': 3.13.5(react@19.2.4) + '@swc/helpers': 0.5.18 + client-only: 0.0.1 + react: 19.2.4 + react-aria: 3.46.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react-dom: 19.2.4(react@19.2.4) + react-stately: 3.44.0(react@19.2.4) + use-sync-external-store: 1.6.0(react@19.2.4) + + react-aria@3.46.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + '@internationalized/string': 3.2.7 + '@react-aria/breadcrumbs': 3.5.31(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/button': 3.14.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/calendar': 3.9.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/checkbox': 3.16.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/color': 3.1.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/combobox': 3.14.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/datepicker': 3.16.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/dialog': 3.5.33(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/disclosure': 3.1.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/dnd': 3.11.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/focus': 3.21.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/gridlist': 3.14.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/i18n': 3.12.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/interactions': 3.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/label': 3.7.24(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/landmark': 3.0.9(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/link': 3.8.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/listbox': 3.15.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/menu': 3.20.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/meter': 3.4.29(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/numberfield': 3.12.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/overlays': 3.31.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/progress': 3.4.29(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/radio': 3.12.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/searchfield': 3.8.11(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/select': 3.17.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/selection': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/separator': 3.4.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/slider': 3.8.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/ssr': 3.9.10(react@19.2.4) + '@react-aria/switch': 3.7.10(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/table': 3.17.10(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/tabs': 3.11.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/tag': 3.8.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/textfield': 3.18.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/toast': 3.0.10(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/tooltip': 3.9.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/tree': 3.1.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/utils': 3.33.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-aria/visually-hidden': 3.8.30(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + react-dom@19.2.4(react@19.2.4): + dependencies: + react: 19.2.4 + scheduler: 0.27.0 + + react-refresh@0.14.2: {} + + react-router@7.13.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + cookie: 1.1.1 + react: 19.2.4 + set-cookie-parser: 2.7.2 + optionalDependencies: + react-dom: 19.2.4(react@19.2.4) + + react-stately@3.44.0(react@19.2.4): + dependencies: + '@react-stately/calendar': 3.9.2(react@19.2.4) + '@react-stately/checkbox': 3.7.4(react@19.2.4) + '@react-stately/collections': 3.12.9(react@19.2.4) + '@react-stately/color': 3.9.4(react@19.2.4) + '@react-stately/combobox': 3.12.2(react@19.2.4) + '@react-stately/data': 3.15.1(react@19.2.4) + '@react-stately/datepicker': 3.16.0(react@19.2.4) + '@react-stately/disclosure': 3.0.10(react@19.2.4) + '@react-stately/dnd': 3.7.3(react@19.2.4) + '@react-stately/form': 3.2.3(react@19.2.4) + '@react-stately/list': 3.13.3(react@19.2.4) + '@react-stately/menu': 3.9.10(react@19.2.4) + '@react-stately/numberfield': 3.10.4(react@19.2.4) + '@react-stately/overlays': 3.6.22(react@19.2.4) + '@react-stately/radio': 3.11.4(react@19.2.4) + '@react-stately/searchfield': 3.5.18(react@19.2.4) + '@react-stately/select': 3.9.1(react@19.2.4) + '@react-stately/selection': 3.20.8(react@19.2.4) + '@react-stately/slider': 3.7.4(react@19.2.4) + '@react-stately/table': 3.15.3(react@19.2.4) + '@react-stately/tabs': 3.8.8(react@19.2.4) + '@react-stately/toast': 3.1.3(react@19.2.4) + '@react-stately/toggle': 3.9.4(react@19.2.4) + '@react-stately/tooltip': 3.5.10(react@19.2.4) + '@react-stately/tree': 3.9.5(react@19.2.4) + '@react-types/shared': 3.33.0(react@19.2.4) + react: 19.2.4 + + react@19.2.4: {} + + readdirp@4.1.2: {} + + rollup@4.57.1: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.57.1 + '@rollup/rollup-android-arm64': 4.57.1 + '@rollup/rollup-darwin-arm64': 4.57.1 + '@rollup/rollup-darwin-x64': 4.57.1 + '@rollup/rollup-freebsd-arm64': 4.57.1 + '@rollup/rollup-freebsd-x64': 4.57.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.57.1 + '@rollup/rollup-linux-arm-musleabihf': 4.57.1 + '@rollup/rollup-linux-arm64-gnu': 4.57.1 + '@rollup/rollup-linux-arm64-musl': 4.57.1 + '@rollup/rollup-linux-loong64-gnu': 4.57.1 + '@rollup/rollup-linux-loong64-musl': 4.57.1 + '@rollup/rollup-linux-ppc64-gnu': 4.57.1 + '@rollup/rollup-linux-ppc64-musl': 4.57.1 + '@rollup/rollup-linux-riscv64-gnu': 4.57.1 + '@rollup/rollup-linux-riscv64-musl': 4.57.1 + '@rollup/rollup-linux-s390x-gnu': 4.57.1 + '@rollup/rollup-linux-x64-gnu': 4.57.1 + '@rollup/rollup-linux-x64-musl': 4.57.1 + '@rollup/rollup-openbsd-x64': 4.57.1 + '@rollup/rollup-openharmony-arm64': 4.57.1 + '@rollup/rollup-win32-arm64-msvc': 4.57.1 + '@rollup/rollup-win32-ia32-msvc': 4.57.1 + '@rollup/rollup-win32-x64-gnu': 4.57.1 + '@rollup/rollup-win32-x64-msvc': 4.57.1 + fsevents: 2.3.3 + + scheduler@0.27.0: {} + + semver@6.3.1: {} + + semver@7.7.4: {} + + set-cookie-parser@2.7.2: {} + + source-map-js@1.2.1: {} + + tailwindcss@4.2.0: {} + + tapable@2.3.0: {} + + tiny-invariant@1.3.3: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + tsconfck@3.1.6(typescript@5.8.3): + optionalDependencies: + typescript: 5.8.3 + + tslib@2.8.1: {} + + typescript@5.8.3: {} + + update-browserslist-db@1.2.3(browserslist@4.28.1): + dependencies: + browserslist: 4.28.1 + escalade: 3.2.0 + picocolors: 1.1.1 + + use-sync-external-store@1.6.0(react@19.2.4): + dependencies: + react: 19.2.4 + + valibot@1.2.0(typescript@5.8.3): + optionalDependencies: + typescript: 5.8.3 + + vite-node@3.2.4(jiti@2.6.1)(lightningcss@1.31.1): + dependencies: + cac: 6.7.14 + debug: 4.4.3 + es-module-lexer: 1.7.0 + pathe: 2.0.3 + vite: 7.3.1(jiti@2.6.1)(lightningcss@1.31.1) + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + vite-tsconfig-paths@6.1.1(typescript@5.8.3)(vite@7.3.1(jiti@2.6.1)(lightningcss@1.31.1)): + dependencies: + debug: 4.4.3 + globrex: 0.1.2 + tsconfck: 3.1.6(typescript@5.8.3) + vite: 7.3.1(jiti@2.6.1)(lightningcss@1.31.1) + transitivePeerDependencies: + - supports-color + - typescript + + vite@7.3.1(jiti@2.6.1)(lightningcss@1.31.1): + dependencies: + esbuild: 0.27.3 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.57.1 + tinyglobby: 0.2.15 + optionalDependencies: + fsevents: 2.3.3 + jiti: 2.6.1 + lightningcss: 1.31.1 + + yallist@3.1.1: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..efc037a --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +onlyBuiltDependencies: + - esbuild diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index 5dbdfcd..0000000 Binary files a/public/favicon.ico and /dev/null differ diff --git a/public/fonts/golos-ui/Golos-UI_VF.css b/public/fonts/golos-ui/Golos-UI_VF.css deleted file mode 100644 index 3cefc01..0000000 --- a/public/fonts/golos-ui/Golos-UI_VF.css +++ /dev/null @@ -1,10 +0,0 @@ -/* Generated by ParaType (http://www.paratype.com)*/ -/* Font Golos UI: Copyright ? ParaType, 2018. All rights reserved.*/ - -@font-face { - font-family: 'GolosUIWebVF'; - src: url('Golos%20UI_VF.woff2') format('woff2'), - url('Golos%20UI_VF.woff') format('woff'); - font-weight: normal; - font-style: normal; -} diff --git a/public/fonts/golos-ui/Golos-UI_VF.html b/public/fonts/golos-ui/Golos-UI_VF.html deleted file mode 100644 index 21ef602..0000000 --- a/public/fonts/golos-ui/Golos-UI_VF.html +++ /dev/null @@ -1,160 +0,0 @@ - - - - - - - - - Font Face Demo - - - - - -
-

-Font:
- - -Golos UI VF

- -

-Sample Text:

-

-Jelly-like above the high wire, six quaking pachyderms kept the climax of the extravaganza in a dazzling state of flux.
Юный директор целиком сжевал весь объём продукции фундука (товара дефицитного и деликатесного), идя энергично через хрустящий камыш.

- -

-

-
-
- Character Set:            

-
-

- ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~   ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ ı Œ œ Š š Ÿ Ž ž ƒ ȷ ʼ ˆ ˇ ˙ ˚ ˜ ˝ Ё Ђ Ѓ Є Ѕ І Ї Ј Љ Њ Ћ Ќ Ў Џ А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я а б в г д е ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ы ь э ю я ё ђ ѓ є ѕ і ї ј љ њ ћ ќ ў џ Ґ ґ Ғ ғ Ҕ ҕ Җ җ Ҙ ҙ Қ қ Ҝ ҝ Ҡ ҡ Ң ң Ҥ ҥ Ҫ ҫ Ү ү Ұ ұ Ҳ ҳ Ҷ ҷ Ҹ ҹ Һ һ Ӏ Ӄ ӄ Ӈ ӈ Ӌ ӌ ӏ Ӑ ӑ Ӓ ӓ Ӕ ӕ Ӗ ӗ Ә ә Ӛ ӛ Ӝ ӝ Ӟ ӟ Ӣ ӣ Ӥ ӥ Ӧ ӧ Ө ө Ӫ ӫ Ӯ ӯ Ӱ ӱ Ӳ ӳ Ӵ ӵ Ӹ ӹ Ԓ ԓ ẞ   ‐ ‑ ‒ – — ‘ ’ ‚ “ ” „ † ‡ • …   ‰ ‹ › ⁄ ⁴ € ₴ ₸ ₽ № ™ ← ↑ → ↓ ↖ ↗ ↘ ↙ − ∕                           -

-
-
-

OpenType features:

-
-
- -

-© ParaType, 2013. All rights reserved.
All trademarks mentioned in this document are the trademarks or registered trademarks of their respective holders. You may reproduce and
distribute this document as long as you do not remove ParaType copyright information and do not make any changes in the document.
Русская панграмма из книги В. В. Шахиджаняна «Соло на клавиатуре»

- - - \ No newline at end of file diff --git a/public/fonts/golos-ui/golos-ui_vf.woff b/public/fonts/golos-ui/golos-ui_vf.woff deleted file mode 100644 index b1713be..0000000 Binary files a/public/fonts/golos-ui/golos-ui_vf.woff and /dev/null differ diff --git a/public/fonts/golos-ui/golos-ui_vf.woff2 b/public/fonts/golos-ui/golos-ui_vf.woff2 deleted file mode 100644 index 105549a..0000000 Binary files a/public/fonts/golos-ui/golos-ui_vf.woff2 and /dev/null differ diff --git a/public/tauri.svg b/public/tauri.svg new file mode 100644 index 0000000..31b62c9 --- /dev/null +++ b/public/tauri.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/vite.svg b/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/react-router.config.ts b/react-router.config.ts index 6ff16f9..72a4d21 100644 --- a/react-router.config.ts +++ b/react-router.config.ts @@ -1,7 +1,9 @@ import type { Config } from "@react-router/dev/config"; export default { - // Config options... - // Server-side render by default, to enable SPA mode set this to `false` - ssr: true, + // Config options... + // Server-side render by default, to enable SPA mode set this to `false` + ssr: false, + appDirectory: "src", + buildDirectory: "dist", } satisfies Config; diff --git a/server.ts b/server.ts deleted file mode 100644 index e1ba41c..0000000 --- a/server.ts +++ /dev/null @@ -1,57 +0,0 @@ -import compression from 'compression'; -import express from 'express'; -import { readdirSync } from 'fs'; -import morgan from 'morgan'; -import path from 'path'; - -(async () => { - const PORT = Number.parseInt(process.env.PORT || '3000'); - - const app = express(); - - app.use(compression()); - app.disable('x-powered-by'); - - if (process.env.NODE_ENV === 'development') { - console.log('Starting development server'); - const viteDevServer = await import('vite').then((vite) => - vite.createServer({ - server: { middlewareMode: true }, - }), - ); - app.use(viteDevServer.middlewares); - app.use(async (req, res, next) => { - try { - const source = await viteDevServer.ssrLoadModule('./server/app.ts'); - const server = await source.init(); - return await server(req, res, next); - } catch (error) { - if (typeof error === 'object' && error instanceof Error) { - viteDevServer.ssrFixStacktrace(error); - } - next(error); - } - }); - } else { - console.log('Starting production server'); - app.use( - '/assets', - express.static(path.join(__dirname, '../build/client/assets'), { - immutable: true, - maxAge: '1y', - }), - ); - app.use( - express.static(path.join(__dirname, '../build/client'), { maxAge: '1h' }), - ); - // @ts-ignore - const server = await import('./build/server/index.js'); - app.use(await server.init()); - } - - app.use(morgan('tiny')); - - app.listen(PORT, () => { - console.log(`Server is running on http://localhost:${PORT}`); - }); -})(); diff --git a/server/app.ts b/server/app.ts deleted file mode 100644 index 94da0fe..0000000 --- a/server/app.ts +++ /dev/null @@ -1,61 +0,0 @@ -import 'react-router'; -import { createRequestHandler } from '@react-router/express'; -import express from 'express'; - -declare module 'react-router' { - interface AppLoadContext { - VALUE_FROM_EXPRESS: string; - } -} - -import { AppManager } from './appman'; -import { initSkinData } from './valorantApi'; - -import packageJson from '../package.json'; -import axios from 'axios'; - -declare global { - var appManager: AppManager; -} - -export async function init() { - await initSkinData(); - - global.appManager = new AppManager(); - - if (process.env.NODE_ENV === 'production') { - try { - const { data } = await axios.get( - `https://api.github.com/repos/zachrip/valpal/releases/latest`, - ); - - if (data.tag_name !== packageJson.version) { - global.appManager.notify( - 'Update Available', - `There's a new version of ValPal available! Please update at: ${data.html_url}`, - ); - } - } catch (e) { - global.appManager.notify( - 'Update Check Failed', - 'Failed to check for updates. ' + e, - ); - } - } - - const app = express(); - - app.use( - createRequestHandler({ - // @ts-expect-error - virtual module provided by React Router at build time - build: () => import('virtual:react-router/server-build'), - getLoadContext() { - return { - VALUE_FROM_EXPRESS: 'Hello from Express', - }; - }, - }), - ); - - return app; -} diff --git a/server/appman.ts b/server/appman.ts deleted file mode 100644 index 1bf7a6f..0000000 --- a/server/appman.ts +++ /dev/null @@ -1,414 +0,0 @@ -import { NotifyIcon, Icon, Menu } from 'not-the-systray'; -import { - entitlementTypeToIdMap, - type Agent, - type ValorantLoadout, -} from 'types'; -import type { Loadout } from '~/utils'; -import { - getLockfile, - getUser, - getUserConfig, - randomItem, -} from '~/utils.server'; -import type { User } from './userman'; -import { exec } from 'child_process'; -import WebSocket from 'ws'; - -function open(url: string) { - exec(`start ${url}`); -} - -function tryParseJson(json: string): T | null { - try { - return JSON.parse(json); - } catch (e) { - return null; - } -} - -const notificationIcon = Icon.load(Icon.ids.info, Icon.large); - -const loadoutShufflingItemId = 1; -const agentDetectionItemId = 2; -const openItemId = 3; -const quitItemId = 4; - -export class AppManager { - private isAutoShuffleEnabled = true; - private isAgentDetectionEnabled = true; - - private appIcon = new NotifyIcon({ - icon: Icon.load(Icon.ids.app, Icon.small), - tooltip: 'ValPal', - onSelect: ({ mouseX, mouseY }) => { - this.handleMenu(mouseX, mouseY); - }, - }); - - private menu = new Menu([ - { - id: openItemId, - text: 'Open ValPal', - }, - { - id: loadoutShufflingItemId, - text: 'Loadout shuffling', - checked: true, - }, - { - id: agentDetectionItemId, - text: 'Agent specific loadouts', - checked: true, - }, - { - id: quitItemId, - text: 'Quit', - }, - ]); - - constructor() { - this.connect(); - } - - notify(title: string, text: string) { - this.appIcon.update({ - notification: { - icon: notificationIcon, - title, - text, - }, - }); - } - - private handleMenu = (x: number, y: number) => { - const id = this.menu.showSync(x, y); - switch (id) { - case null: { - break; - } - case openItemId: { - open('http://localhost:3000'); - break; - } - case loadoutShufflingItemId: { - const { checked } = this.menu.get(loadoutShufflingItemId); - this.menu.update(loadoutShufflingItemId, { checked: !checked }); - this.isAutoShuffleEnabled = !checked; - break; - } - case agentDetectionItemId: { - const { checked } = this.menu.get(agentDetectionItemId); - this.menu.update(agentDetectionItemId, { checked: !checked }); - this.isAgentDetectionEnabled = !checked; - break; - } - case quitItemId: { - this.appIcon.remove(); - process.exit(0); - break; - } - } - }; - - async connect() { - try { - console.log('Attempting to connect to websocket'); - - const lockfile = await getLockfile(); - - if (!lockfile) { - console.log('Lockfile not found'); - setTimeout(() => { - this.connect(); - }, 5000); - return; - } - - const { port, password } = lockfile; - const ws = new WebSocket(`wss://riot:${password}@127.0.0.1:${port}`, { - rejectUnauthorized: false, - }); - - const matchCharacterSelectionStates = new Map(); - - ws.addEventListener('open', async () => { - try { - console.log('Connected to websocket'); - ws.send(JSON.stringify([5, 'OnJsonApiEvent'])); - } catch (e) { - console.warn('Caught error in websocket open handler', e); - } - }); - - let abortController: AbortController = new AbortController(); - - ws.addEventListener('message', async ({ data }) => { - try { - const parsed = tryParseJson<[number, string, object]>( - data.toString(), - ); - - if (!parsed) { - return; - } - - const [type, event, payload] = parsed; - - if (type !== 8 || event !== 'OnJsonApiEvent') { - return; - } - - const { uri, eventType } = payload as { - uri: string; - eventType: string; - data: object; - }; - - const uriMatch = uri.match(/\/pregame\/v1\/matches\/(.*)/); - if (eventType === 'Create' && uriMatch && uriMatch[1]) { - const matchId = uriMatch[1]; - console.log('Match found:', matchId); - - const existingState = matchCharacterSelectionStates.get(matchId); - - if (existingState === 'locked') { - console.log('Match already locked, no need to process'); - return; - } - - const user = await getUser(); - - if (!user) { - console.log('User not found'); - return; - } - - const match = await user.getPregame(); - - const player = match.AllyTeam.Players.find( - (player) => player.Subject === user.userId, - ); - - const newState = player?.CharacterSelectionState; - - if ( - newState && - newState !== matchCharacterSelectionStates.get(matchId) - ) { - if (newState === 'locked' && this.isAutoShuffleEnabled) { - this.equip( - user, - this.isAgentDetectionEnabled ? player.CharacterID : undefined, - ); - } - - matchCharacterSelectionStates.set(matchId, newState); - } - } - } catch (e) { - console.warn('Caught error in websocket message handler:', e); - } - }); - - ws.addEventListener('close', () => { - try { - abortController?.abort(); - console.log('Disconnected from websocket'); - setTimeout(() => { - this.connect(); - }, 5000); - } catch (e) { - console.warn('Caught error in websocket close handler:', e); - } - }); - - ws.addEventListener('error', (err) => { - console.warn('WS error:', err); - // this.notify('Websocket Error', err.message); - }); - } catch (e) { - console.warn('Caught error in connect method:', e); - } - } - - equip = async (user: User, agentId?: string) => { - const config = await getUserConfig(user.userId); - - const agent: Agent | undefined = valorantData.agents.find( - (a) => a.uuid === agentId, - )!; - - const loadoutsToConsider = (function ( - loadouts: Loadout[], - agentId?: string, - ) { - if (!agentId) { - console.log('No agent specified, considering all loadouts.'); - return loadouts; - } - - const agentSpecificLoadouts = loadouts.filter((l) => - l.agentIds.includes(agentId), - ); - - if (agentSpecificLoadouts.length === 0) { - console.log( - 'No loadouts for', - agentId, - `(${agent.displayName})`, - 'falling back to all loadouts.', - ); - return loadouts; - } - - console.log( - 'Only considering loadouts for', - agentId, - `(${agent.displayName})`, - ); - return agentSpecificLoadouts; - })( - config.loadouts.filter((loadout) => loadout.enabled), - agentId, - ); - - if (loadoutsToConsider.length === 0) { - console.log('No loadouts, not equipping.'); - return; - } - - const loadout = randomItem(loadoutsToConsider); - this.equipLoadout(user, loadout); - }; - - async equipLoadout(user: User, loadout: Loadout) { - const weapons = valorantData.weapons; - - const [existingLoadout, entitlements] = await Promise.all([ - user.getLoadout(), - user.getEntitlements(), - ]); - - const buddyEntitlements = entitlements.buddy.reduce((acc, buddy) => { - const existing = acc.get(buddy.ItemID) || []; - existing.push(buddy.InstanceID); - - acc.set(buddy.ItemID, existing); - return acc; - }, new Map()); - - const loadoutToEquip: ValorantLoadout = { - ...existingLoadout, - Identity: { - ...existingLoadout.Identity, - PlayerCardID: - randomItem(loadout.playerCardIds) || - '9fb348bc-41a0-91ad-8a3e-818035c4e561', - }, - ActiveExpressions: [ - randomItem([ - ...loadout.expressionIds.top.sprayIds.map((id) => ({ - TypeID: entitlementTypeToIdMap.spray, - AssetID: id, - })), - ...loadout.expressionIds.top.flexIds.map((id) => ({ - TypeID: entitlementTypeToIdMap.flex, - AssetID: id, - })), - ]) || { - TypeID: entitlementTypeToIdMap.spray, - AssetID: '0a6db78c-48b9-a32d-c47a-82be597584c1', - }, - randomItem([ - ...loadout.expressionIds.right.sprayIds.map((id) => ({ - TypeID: entitlementTypeToIdMap.spray, - AssetID: id, - })), - ...loadout.expressionIds.right.flexIds.map((id) => ({ - TypeID: entitlementTypeToIdMap.flex, - AssetID: id, - })), - ]) || { - TypeID: entitlementTypeToIdMap.spray, - AssetID: '0a6db78c-48b9-a32d-c47a-82be597584c1', - }, - randomItem([ - ...loadout.expressionIds.bottom.sprayIds.map((id) => ({ - TypeID: entitlementTypeToIdMap.spray, - AssetID: id, - })), - ...loadout.expressionIds.bottom.flexIds.map((id) => ({ - TypeID: entitlementTypeToIdMap.flex, - AssetID: id, - })), - ]) || { - TypeID: entitlementTypeToIdMap.spray, - AssetID: '0a6db78c-48b9-a32d-c47a-82be597584c1', - }, - randomItem([ - ...loadout.expressionIds.left.sprayIds.map((id) => ({ - TypeID: entitlementTypeToIdMap.spray, - AssetID: id, - })), - ...loadout.expressionIds.left.flexIds.map((id) => ({ - TypeID: entitlementTypeToIdMap.flex, - AssetID: id, - })), - ]) || { - TypeID: entitlementTypeToIdMap.flex, - AssetID: 'af52b5a0-4a4c-03b2-c9d7-8187a08a2675', - }, - ], - Guns: Object.entries(loadout.weapons).map(([weaponId, { templates }]) => { - if (!templates.length) { - const weapon = weapons.find((w) => w.uuid === weaponId)!; - const skin = weapon.skins.find( - (s) => s.uuid === weapon.defaultSkinUuid, - )!; - - return { - ID: weaponId, - SkinID: skin.uuid, - ChromaID: skin.chromas[0].uuid, - SkinLevelID: skin.levels[0].uuid, - Attachments: [], - }; - } - - const template = randomItem(templates); - - const buddyData = (() => { - const buddy = randomItem(template.buddies); - if (!buddy) return null; - - const buddyLevelId = randomItem(buddy.levelIds); - - const consumedBuddy = ( - buddyEntitlements.get(buddyLevelId) || [] - ).shift(); - - if (!consumedBuddy) return null; - - return { - CharmInstanceID: consumedBuddy, - CharmID: buddy.id, - CharmLevelID: buddyLevelId, - }; - })(); - - return { - ID: weaponId, - SkinID: template.skinId, - ChromaID: randomItem(template.chromaIds), - SkinLevelID: randomItem(template.levelIds), - Attachments: [], - ...buddyData, - }; - }), - }; - - console.log('Equipping loadout', loadoutToEquip); - await user.equipLoadout(loadoutToEquip); - } -} diff --git a/server/userman.ts b/server/userman.ts deleted file mode 100644 index 9e6d1c2..0000000 --- a/server/userman.ts +++ /dev/null @@ -1,249 +0,0 @@ -import https from 'https'; - -import axios from 'axios'; -import type { - EntitlementsByCategory, - EntitlementsByType, - Gun, - Identity, - Session, - ValorantLoadout, - Shards, - PregamePlayer, - PregameMatch, - Regions, - ActiveExpression, -} from 'types'; -import { entitlementIdToTypeMap } from 'types'; - -const agent = new https.Agent({ - ciphers: [ - 'TLS_CHACHA20_POLY1305_SHA256', - 'TLS_AES_128_GCM_SHA256', - 'TLS_AES_256_GCM_SHA384', - 'TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256', - ].join(':'), - honorCipherOrder: true, - minVersion: 'TLSv1.2', -}); - -const httpClient = axios.create({ - httpsAgent: agent, -}); - -function getPlayerDataServiceUrl(region: Regions) { - return `https://pd.${region}.a.pvp.net`; -} - -function getPartyServiceUrl(region: Regions, shard: Shards) { - return `https://glz-${region}-1.${shard}.a.pvp.net`; -} - -export function generateRequestHeaders( - args: { - accessToken: string; - entitlementsToken: string; - riotClientVersion: string; - }, - extraHeaders: Record = {}, -) { - const defaultHeaders = { - Authorization: `Bearer ${args.accessToken}`, - 'X-Riot-Entitlements-JWT': args.entitlementsToken, - 'X-Riot-ClientVersion': args.riotClientVersion, - 'X-Riot-ClientPlatform': btoa( - JSON.stringify({ - platformType: 'PC', - platformOS: 'Windows', - platformOSVersion: '10.0.19042.1.256.64bit', - platformChipset: 'Unknown', - }), - ), - }; - - // merge in extra headers - return { - ...defaultHeaders, - ...extraHeaders, - }; -} - -export class User { - private accessToken: string; - private entitlementsToken: string; - public userId: string; - public region: Regions; - public shard: Shards; - - private requestHeaders: Record; - - constructor(args: { - accessToken: string; - entitlementsToken: string; - riotClientVersion: string; - userId: string; - region: Regions; - shard: Shards; - }) { - this.accessToken = args.accessToken; - this.entitlementsToken = args.entitlementsToken; - this.userId = args.userId; - this.region = args.region; - this.shard = args.shard; - this.requestHeaders = generateRequestHeaders({ - riotClientVersion: args.riotClientVersion, - accessToken: this.accessToken, - entitlementsToken: this.entitlementsToken, - }); - } - - getTokens() { - return { - accessToken: this.accessToken, - entitlementsToken: this.entitlementsToken, - }; - } - - async getLoadout() { - const { data } = await httpClient.get<{ - Subject: string; - Version: number; - Guns: Gun[]; - ActiveExpressions: ActiveExpression[]; - Identity: Identity; - Incognito: boolean; - }>( - `${getPlayerDataServiceUrl(this.region)}/personalization/v3/players/${ - this.userId - }/playerloadout`, - { - headers: this.requestHeaders, - }, - ); - - return data; - } - - async getEntitlements() { - const { data } = await httpClient.get<{ - EntitlementsByTypes: EntitlementsByType[]; - }>( - `${getPlayerDataServiceUrl(this.region)}/store/v1/entitlements/${ - this.userId - }`, - { - headers: this.requestHeaders, - }, - ); - - return data.EntitlementsByTypes.reduce( - (acc, curr) => { - const entitlementType = entitlementIdToTypeMap[curr.ItemTypeID]; - if (!entitlementType) { - return acc; - } - - acc[entitlementType].push(...curr.Entitlements); - return acc; - }, - { - skin_level: [], - skin_chroma: [], - agent: [], - contract_definition: [], - buddy: [], - spray: [], - flex: [ - { - ItemID: 'af52b5a0-4a4c-03b2-c9d7-8187a08a2675', - TypeID: '03a572de-4234-31ed-d344-ababa488f981', - InstanceID: 'af52b5a0-4a4c-03b2-c9d7-8187a08a2675', - }, - ], - player_card: [], - player_title: [], - } as EntitlementsByCategory, - ); - } - - async getPlayer() { - const { data } = await httpClient.put< - Array<{ - DisplayName: string; - Subject: string; - GameName: string; - TagLine: string; - }> - >( - `${getPlayerDataServiceUrl(this.region)}/name-service/v2/players`, - [this.userId], - { - headers: this.requestHeaders, - }, - ); - - return data[0]; - } - - async getSession() { - const { data } = await httpClient.get( - `${getPartyServiceUrl(this.region, this.shard)}/session/v1/sessions/${ - this.userId - }`, - { - headers: this.requestHeaders, - }, - ); - - return data; - } - - async getParty() { - const { data } = await httpClient.get( - `${getPartyServiceUrl(this.region, this.shard)}/parties/v1/players/${ - this.userId - }`, - { - headers: this.requestHeaders, - }, - ); - - return data; - } - - async getPregame() { - const { data } = await httpClient.get( - `${getPartyServiceUrl(this.region, this.shard)}/pregame/v1/players/${ - this.userId - }`, - { - headers: this.requestHeaders, - }, - ); - - const { data: pregameData } = await httpClient.get( - `${getPartyServiceUrl(this.region, this.shard)}/pregame/v1/matches/${ - data.MatchID - }`, - { - headers: this.requestHeaders, - }, - ); - - return pregameData; - } - - async equipLoadout(loadout: ValorantLoadout) { - const { data } = await httpClient.put( - `${getPlayerDataServiceUrl(this.region)}/personalization/v3/players/${ - this.userId - }/playerloadout`, - loadout, - { - headers: this.requestHeaders, - }, - ); - - return data; - } -} diff --git a/server/valorantApi.ts b/server/valorantApi.ts deleted file mode 100644 index 03cde22..0000000 --- a/server/valorantApi.ts +++ /dev/null @@ -1,132 +0,0 @@ -import axios from 'axios'; -import type { - Buddy, - PlayerCard, - Weapon, - Spray, - Flex, - Agent, - PlayerTitle, -} from 'types'; - -const httpClient = axios.create(); - -async function getWeapons() { - const { data } = await httpClient.get<{ - status: number; - data: Weapon[]; - }>('https://valorant-api.com/v1/weapons'); - - return data.data; -} - -async function getBuddies() { - const { data } = await httpClient.get<{ - status: number; - data: Buddy[]; - }>('https://valorant-api.com/v1/buddies'); - - return data.data; -} - -async function getSprays() { - const { data } = await httpClient.get<{ - status: number; - data: Spray[]; - }>('https://valorant-api.com/v1/sprays'); - - return data.data; -} - -async function getFlexes() { - const { data } = await httpClient.get<{ - status: number; - data: Flex[]; - }>('https://valorant-api.com/v1/flex'); - - return data.data; -} - -async function getPlayerCards() { - const { data } = await httpClient.get<{ - status: number; - data: PlayerCard[]; - }>('https://valorant-api.com/v1/playercards'); - - return data.data; -} - -async function getPlayerTitles() { - const { data } = await httpClient.get<{ - status: number; - data: PlayerTitle[]; - }>('https://valorant-api.com/v1/playertitles'); - - return data.data; -} - -async function getAgents() { - const { data } = await httpClient.get<{ - status: number; - data: Agent[]; - }>('https://valorant-api.com/v1/agents'); - - return data.data.filter((agent) => agent.isPlayableCharacter); -} - -async function getVersion() { - const { data } = await httpClient.get<{ - status: number; - data: { riotClientVersion: string }; - }>('https://valorant-api.com/v1/version'); - - return data.data; -} - -export async function initSkinData() { - const [ - weapons, - buddies, - sprays, - flex, - playerCards, - playerTitles, - agents, - version, - ] = await Promise.all([ - getWeapons(), - getBuddies(), - getSprays(), - getFlexes(), - getPlayerCards(), - getPlayerTitles(), - getAgents(), - getVersion(), - ]); - - global.valorantData = { - weapons, - buddies, - sprays, - flex, - playerCards, - playerTitles, - agents, - version, - }; -} - -declare global { - var valorantData: { - weapons: Weapon[]; - buddies: Buddy[]; - sprays: Spray[]; - flex: Flex[]; - playerCards: PlayerCard[]; - playerTitles: PlayerTitle[]; - agents: Agent[]; - version: { - riotClientVersion: string; - }; - }; -} diff --git a/src-tauri/.gitignore b/src-tauri/.gitignore new file mode 100644 index 0000000..b21bd68 --- /dev/null +++ b/src-tauri/.gitignore @@ -0,0 +1,7 @@ +# Generated by Cargo +# will have compiled files and executables +/target/ + +# Generated by Tauri +# will have schema files for capabilities auto-completion +/gen/schemas diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock new file mode 100644 index 0000000..f54554f --- /dev/null +++ b/src-tauri/Cargo.lock @@ -0,0 +1,5734 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea" + +[[package]] +name = "async-broadcast" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" +dependencies = [ + "event-listener", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-channel" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c96bf972d85afc50bf5ab8fe2d54d1586b4e0b46c97c50a0c9e71e2f7bcd812a" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "pin-project-lite", + "slab", +] + +[[package]] +name = "async-io" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" +dependencies = [ + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix", + "slab", + "windows-sys 0.61.2", +] + +[[package]] +name = "async-lock" +version = "3.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" +dependencies = [ + "event-listener", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-process" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" +dependencies = [ + "async-channel", + "async-io", + "async-lock", + "async-signal", + "async-task", + "blocking", + "cfg-if", + "event-listener", + "futures-lite", + "rustix", +] + +[[package]] +name = "async-recursion" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "async-signal" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c" +dependencies = [ + "async-io", + "async-lock", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix", + "signal-hook-registry", + "slab", + "windows-sys 0.61.2", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "atk" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241b621213072e993be4f6f3a9e4b45f65b7e6faad43001be957184b7bb1824b" +dependencies = [ + "atk-sys", + "glib", + "libc", +] + +[[package]] +name = "atk-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e48b684b0ca77d2bbadeef17424c2ea3c897d44d566a1617e7e8f30614d086" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +dependencies = [ + "serde_core", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" +dependencies = [ + "objc2", +] + +[[package]] +name = "blocking" +version = "1.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" +dependencies = [ + "async-channel", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + +[[package]] +name = "brotli" +version = "8.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bumpalo" +version = "3.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6f81257d10a0f602a294ae4182251151ff97dbb504ef9afcdda4a64b24d9b4" + +[[package]] +name = "bytemuck" +version = "1.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +dependencies = [ + "serde", +] + +[[package]] +name = "cairo-rs" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" +dependencies = [ + "bitflags 2.11.0", + "cairo-sys-rs", + "glib", + "libc", + "once_cell", + "thiserror 1.0.69", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685c9fa8e590b8b3d678873528d83411db17242a73fccaed827770ea0fedda51" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "camino" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" +dependencies = [ + "serde_core", +] + +[[package]] +name = "cargo-platform" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror 2.0.18", +] + +[[package]] +name = "cargo_toml" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77" +dependencies = [ + "serde", + "toml 0.9.12+spec-1.1.0", +] + +[[package]] +name = "cc" +version = "1.2.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfb" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" +dependencies = [ + "byteorder", + "fnv", + "uuid", +] + +[[package]] +name = "cfg-expr" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +dependencies = [ + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chrono" +version = "0.4.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-link 0.2.1", +] + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "time", + "version_check", +] + +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core-graphics" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1" +dependencies = [ + "bitflags 2.11.0", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" +dependencies = [ + "bitflags 2.11.0", + "core-foundation", + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "cssparser" +version = "0.29.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93d03419cb5950ccfd3daf3ff1c7a36ace64609a1a8746d493df1ca0afde0fa" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa", + "matches", + "phf 0.10.1", + "proc-macro2", + "quote", + "smallvec", + "syn 1.0.109", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" +dependencies = [ + "quote", + "syn 2.0.116", +] + +[[package]] +name = "ctor" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" +dependencies = [ + "quote", + "syn 2.0.116", +] + +[[package]] +name = "darling" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.116", +] + +[[package]] +name = "darling_macro" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "data-encoding" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" + +[[package]] +name = "deranged" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc3dc5ad92c2e2d1c193bbbbdf2ea477cb81331de4f3103f267ca18368b988c4" +dependencies = [ + "powerfmt", + "serde_core", +] + +[[package]] +name = "derive_more" +version = "0.99.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.116", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dirs" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.61.2", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dispatch2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" +dependencies = [ + "bitflags 2.11.0", + "objc2", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "dlopen2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e2c5bd4158e66d1e215c49b837e11d62f3267b30c92f1d171c4d3105e3dc4d4" +dependencies = [ + "dlopen2_derive", + "libc", + "once_cell", + "winapi", +] + +[[package]] +name = "dlopen2_derive" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fbbb781877580993a8707ec48672673ec7b81eeba04cfd2310bd28c08e47c8f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "dpi" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" +dependencies = [ + "serde", +] + +[[package]] +name = "dtoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c3cf4824e2d5f025c7b531afcb2325364084a16806f6d47fbc1f5fbd9960590" + +[[package]] +name = "dtoa-short" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" +dependencies = [ + "dtoa", +] + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + +[[package]] +name = "embed-resource" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55a075fc573c64510038d7ee9abc7990635863992f83ebc52c8b433b8411a02e" +dependencies = [ + "cc", + "memchr", + "rustc_version", + "toml 0.9.12+spec-1.1.0", + "vswhom", + "winreg", +] + +[[package]] +name = "embed_plist" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" + +[[package]] +name = "endi" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099" + +[[package]] +name = "enumflags2" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" +dependencies = [ + "enumflags2_derive", + "serde", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "erased-serde" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89e8918065695684b2b0702da20382d5ae6065cf3327bc2d6436bd49a71ce9f3" +dependencies = [ + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "event-listener" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +dependencies = [ + "event-listener", + "pin-project-lite", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "fdeflate" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset", + "rustc_version", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" +dependencies = [ + "mac", + "new_debug_unreachable", +] + +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-executor" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + +[[package]] +name = "futures-lite" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "gdk" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9f245958c627ac99d8e529166f9823fb3b838d1d41fd2b297af3075093c2691" +dependencies = [ + "cairo-rs", + "gdk-pixbuf", + "gdk-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50e1f5f1b0bfb830d6ccc8066d18db35c487b1b2b1e8589b5dfe9f07e8defaec" +dependencies = [ + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", + "once_cell", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9839ea644ed9c97a34d129ad56d38a25e6756f99f3a88e15cd39c20629caf7" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gdk-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c2d13f38594ac1e66619e188c6d5a1adb98d11b2fcf7894fc416ad76aa2f3f7" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gdkwayland-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "140071d506d223f7572b9f09b5e155afbd77428cd5cc7af8f2694c41d98dfe69" +dependencies = [ + "gdk-sys", + "glib-sys", + "gobject-sys", + "libc", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gdkx11" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3caa00e14351bebbc8183b3c36690327eb77c49abc2268dd4bd36b856db3fbfe" +dependencies = [ + "gdk", + "gdkx11-sys", + "gio", + "glib", + "libc", + "x11", +] + +[[package]] +name = "gdkx11-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e7445fe01ac26f11601db260dd8608fe172514eb63b3b5e261ea6b0f4428d" +dependencies = [ + "gdk-sys", + "glib-sys", + "libc", + "system-deps", + "x11", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi", + "wasip2", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", + "wasip3", +] + +[[package]] +name = "gio" +version = "0.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fc8f532f87b79cbc51a79748f16a6828fb784be93145a322fa14d06d354c73" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys", + "glib", + "libc", + "once_cell", + "pin-project-lite", + "smallvec", + "thiserror 1.0.69", +] + +[[package]] +name = "gio-sys" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37566df850baf5e4cb0dfb78af2e4b9898d817ed9263d1090a2df958c64737d2" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "winapi", +] + +[[package]] +name = "glib" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5" +dependencies = [ + "bitflags 2.11.0", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "memchr", + "once_cell", + "smallvec", + "thiserror 1.0.69", +] + +[[package]] +name = "glib-macros" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc" +dependencies = [ + "heck 0.4.1", + "proc-macro-crate 2.0.2", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "glib-sys" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063ce2eb6a8d0ea93d2bf8ba1957e78dbab6be1c2220dd3daca57d5a9d869898" +dependencies = [ + "libc", + "system-deps", +] + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "gobject-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gtk" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd56fb197bfc42bd5d2751f4f017d44ff59fbb58140c6b49f9b3b2bdab08506a" +dependencies = [ + "atk", + "cairo-rs", + "field-offset", + "futures-channel", + "gdk", + "gdk-pixbuf", + "gio", + "glib", + "gtk-sys", + "gtk3-macros", + "libc", + "pango", + "pkg-config", +] + +[[package]] +name = "gtk-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f29a1c21c59553eb7dd40e918be54dccd60c52b049b75119d5d96ce6b624414" +dependencies = [ + "atk-sys", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "gtk3-macros" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ff3c5b21f14f0736fed6dcfc0bfb4225ebf5725f3c0209edeec181e4d73e9d" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "html5ever" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b7410cae13cbc75623c98ac4cbfd1f0bedddf3227afc24f370cf0f50a44a11c" +dependencies = [ + "log", + "mac", + "markup5ever", + "match_token", +] + +[[package]] +name = "http" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "hyper" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core 0.62.2", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ico" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e795dff5605e0f04bff85ca41b51a96b83e80b281e96231bcaaf1ac35103371" +dependencies = [ + "byteorder", + "png", +] + +[[package]] +name = "icu_collections" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" + +[[package]] +name = "icu_properties" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" + +[[package]] +name = "icu_provider" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +dependencies = [ + "equivalent", + "hashbrown 0.16.1", + "serde", + "serde_core", +] + +[[package]] +name = "infer" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7" +dependencies = [ + "cfb", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "is-docker" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" +dependencies = [ + "once_cell", +] + +[[package]] +name = "is-wsl" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" +dependencies = [ + "is-docker", + "once_cell", +] + +[[package]] +name = "itoa" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" + +[[package]] +name = "javascriptcore-rs" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca5671e9ffce8ffba57afc24070e906da7fc4b1ba66f2cabebf61bf2ea257fcc" +dependencies = [ + "bitflags 1.3.2", + "glib", + "javascriptcore-rs-sys", +] + +[[package]] +name = "javascriptcore-rs-sys" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1be78d14ffa4b75b66df31840478fef72b51f8c2465d4ca7c194da9f7a5124" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror 1.0.69", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "js-sys" +version = "0.3.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "json-patch" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "863726d7afb6bc2590eeff7135d923545e5e964f004c2ccf8716c25e70a86f08" +dependencies = [ + "jsonptr", + "serde", + "serde_json", + "thiserror 1.0.69", +] + +[[package]] +name = "jsonptr" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dea2b27dd239b2556ed7a25ba842fe47fd602e7fc7433c2a8d6106d4d9edd70" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "keyboard-types" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" +dependencies = [ + "bitflags 2.11.0", + "serde", + "unicode-segmentation", +] + +[[package]] +name = "kuchikiki" +version = "0.8.8-speedreader" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02cb977175687f33fa4afa0c95c112b987ea1443e5a51c8f8ff27dc618270cc2" +dependencies = [ + "cssparser", + "html5ever", + "indexmap 2.13.0", + "selectors", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + +[[package]] +name = "libappindicator" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03589b9607c868cc7ae54c0b2a22c8dc03dd41692d48f2d7df73615c6a95dc0a" +dependencies = [ + "glib", + "gtk", + "gtk-sys", + "libappindicator-sys", + "log", +] + +[[package]] +name = "libappindicator-sys" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e9ec52138abedcc58dc17a7c6c0c00a2bdb4f3427c7f63fa97fd0d859155caf" +dependencies = [ + "gtk-sys", + "libloading", + "once_cell", +] + +[[package]] +name = "libc" +version = "0.2.182" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libredox" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" +dependencies = [ + "bitflags 2.11.0", + "libc", +] + +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + +[[package]] +name = "litemap" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" + +[[package]] +name = "markup5ever" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7a7213d12e1864c0f002f52c2923d4556935a43dec5e71355c2760e0f6e7a18" +dependencies = [ + "log", + "phf 0.11.3", + "phf_codegen 0.11.3", + "string_cache", + "string_cache_codegen", + "tendril", +] + +[[package]] +name = "match_token" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "memchr" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +dependencies = [ + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.61.2", +] + +[[package]] +name = "muda" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01c1738382f66ed56b3b9c8119e794a2e23148ac8ea214eda86622d4cb9d415a" +dependencies = [ + "crossbeam-channel", + "dpi", + "gtk", + "keyboard-types", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", + "once_cell", + "png", + "serde", + "thiserror 2.0.18", + "windows-sys 0.60.2", +] + +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.11.0", + "jni-sys", + "log", + "ndk-sys", + "num_enum", + "raw-window-handle", + "thiserror 1.0.69", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "num-conv" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" +dependencies = [ + "proc-macro-crate 3.4.0", + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "objc2" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" +dependencies = [ + "objc2-encode", + "objc2-exception-helper", +] + +[[package]] +name = "objc2-app-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" +dependencies = [ + "bitflags 2.11.0", + "block2", + "libc", + "objc2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-core-image", + "objc2-core-text", + "objc2-core-video", + "objc2-foundation", + "objc2-quartz-core", +] + +[[package]] +name = "objc2-cloud-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" +dependencies = [ + "bitflags 2.11.0", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-data" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa" +dependencies = [ + "bitflags 2.11.0", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" +dependencies = [ + "bitflags 2.11.0", + "dispatch2", + "objc2", +] + +[[package]] +name = "objc2-core-graphics" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" +dependencies = [ + "bitflags 2.11.0", + "dispatch2", + "objc2", + "objc2-core-foundation", + "objc2-io-surface", +] + +[[package]] +name = "objc2-core-image" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-text" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" +dependencies = [ + "bitflags 2.11.0", + "objc2", + "objc2-core-foundation", + "objc2-core-graphics", +] + +[[package]] +name = "objc2-core-video" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d425caf1df73233f29fd8a5c3e5edbc30d2d4307870f802d18f00d83dc5141a6" +dependencies = [ + "bitflags 2.11.0", + "objc2", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-io-surface", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "objc2-exception-helper" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7a1c5fbb72d7735b076bb47b578523aedc40f3c439bea6dfd595c089d79d98a" +dependencies = [ + "cc", +] + +[[package]] +name = "objc2-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" +dependencies = [ + "bitflags 2.11.0", + "block2", + "libc", + "objc2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-io-surface" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" +dependencies = [ + "bitflags 2.11.0", + "objc2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-javascript-core" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a1e6550c4caed348956ce3370c9ffeca70bb1dbed4fa96112e7c6170e074586" +dependencies = [ + "objc2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" +dependencies = [ + "bitflags 2.11.0", + "objc2", + "objc2-core-foundation", + "objc2-foundation", +] + +[[package]] +name = "objc2-security" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709fe137109bd1e8b5a99390f77a7d8b2961dafc1a1c5db8f2e60329ad6d895a" +dependencies = [ + "bitflags 2.11.0", + "objc2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" +dependencies = [ + "bitflags 2.11.0", + "objc2", + "objc2-core-foundation", + "objc2-foundation", +] + +[[package]] +name = "objc2-web-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2e5aaab980c433cf470df9d7af96a7b46a9d892d521a2cbbb2f8a4c16751e7f" +dependencies = [ + "bitflags 2.11.0", + "block2", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", + "objc2-javascript-core", + "objc2-security", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "open" +version = "5.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43bb73a7fa3799b198970490a51174027ba0d4ec504b03cd08caf513d40024bc" +dependencies = [ + "dunce", + "is-wsl", + "libc", + "pathdiff", +] + +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "ordered-stream" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" +dependencies = [ + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "pango" +version = "0.18.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ca27ec1eb0457ab26f3036ea52229edbdb74dee1edd29063f5b9b010e7ebee4" +dependencies = [ + "gio", + "glib", + "libc", + "once_cell", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436737e391a843e5933d6d9aa102cb126d501e815b83601365a948a518555dc5" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link 0.2.1", +] + +[[package]] +name = "pathdiff" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "phf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_shared 0.8.0", +] + +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_macros 0.10.0", + "phf_shared 0.10.0", + "proc-macro-hack", +] + +[[package]] +name = "phf" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +dependencies = [ + "phf_macros 0.11.3", + "phf_shared 0.11.3", +] + +[[package]] +name = "phf_codegen" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", +] + +[[package]] +name = "phf_codegen" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" +dependencies = [ + "phf_generator 0.11.3", + "phf_shared 0.11.3", +] + +[[package]] +name = "phf_generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +dependencies = [ + "phf_shared 0.8.0", + "rand 0.7.3", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared 0.10.0", + "rand 0.8.5", +] + +[[package]] +name = "phf_generator" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +dependencies = [ + "phf_shared 0.11.3", + "rand 0.8.5", +] + +[[package]] +name = "phf_macros" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "phf_macros" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" +dependencies = [ + "phf_generator 0.11.3", + "phf_shared 0.11.3", + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher 0.3.11", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher 0.3.11", +] + +[[package]] +name = "phf_shared" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +dependencies = [ + "siphasher 1.0.2", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "piper" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "plist" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "740ebea15c5d1428f910cd1a5f52cebf8d25006245ed8ade92702f4943d91e07" +dependencies = [ + "base64 0.22.1", + "indexmap 2.13.0", + "quick-xml", + "serde", + "time", +] + +[[package]] +name = "png" +version = "0.17.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "polling" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix", + "windows-sys 0.61.2", +] + +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn 2.0.116", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" +dependencies = [ + "toml_datetime 0.6.3", + "toml_edit 0.20.2", +] + +[[package]] +name = "proc-macro-crate" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +dependencies = [ + "toml_edit 0.23.10+spec-1.0.0", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quick-xml" +version = "0.38.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66c2058c55a409d601666cffe35f04333cf1013010882cec174a7467cd4e21c" +dependencies = [ + "memchr", +] + +[[package]] +name = "quinn" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror 2.0.18", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" +dependencies = [ + "bytes", + "getrandom 0.3.4", + "lru-slab", + "rand 0.9.2", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.18", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.60.2", +] + +[[package]] +name = "quote" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.17", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.11.0", +] + +[[package]] +name = "redox_users" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" +dependencies = [ + "getrandom 0.2.17", + "libredox", + "thiserror 2.0.18", +] + +[[package]] +name = "ref-cast" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "regex" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" + +[[package]] +name = "reqwest" +version = "0.12.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-core", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", +] + +[[package]] +name = "reqwest" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "sync_wrapper", + "tokio", + "tokio-util", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +dependencies = [ + "bitflags 2.11.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls" +version = "0.23.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pki-types" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "schemars" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" +dependencies = [ + "dyn-clone", + "indexmap 1.9.3", + "schemars_derive", + "serde", + "serde_json", + "url", + "uuid", +] + +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.116", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "security-framework" +version = "3.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d17b898a6d6948c3a8ee4372c17cb384f90d2e6e912ef00895b14fd7ab54ec38" +dependencies = [ + "bitflags 2.11.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "321c8673b092a9a42605034a9879d73cb79101ed5fd117bc9a597b89b4e9e61a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "selectors" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c37578180969d00692904465fb7f6b3d50b9a2b952b87c23d0e2e5cb5013416" +dependencies = [ + "bitflags 1.3.2", + "cssparser", + "derive_more", + "fxhash", + "log", + "phf 0.8.0", + "phf_codegen 0.8.0", + "precomputed-hash", + "servo_arc", + "smallvec", +] + +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde-untagged" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9faf48a4a2d2693be24c6289dbe26552776eb7737074e6722891fadbe6c5058" +dependencies = [ + "erased-serde", + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "serde_derive_internals" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "serde_json" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_repr" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_spanned" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "3.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fa237f2807440d238e0364a218270b98f767a00d3dada77b1c53ae88940e2e7" +dependencies = [ + "base64 0.22.1", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.13.0", + "schemars 0.9.0", + "schemars 1.2.1", + "serde_core", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52a8e3ca0ca629121f70ab50f95249e5a6f925cc0f6ffe8256c45b728875706c" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "serialize-to-javascript" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04f3666a07a197cdb77cdf306c32be9b7f598d7060d50cfd4d5aa04bfd92f6c5" +dependencies = [ + "serde", + "serde_json", + "serialize-to-javascript-impl", +] + +[[package]] +name = "serialize-to-javascript-impl" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "772ee033c0916d670af7860b6e1ef7d658a4629a6d0b4c8c3e67f09b3765b75d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "servo_arc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52aa42f8fdf0fed91e5ce7f23d8138441002fa31dca008acf47e6fd4721f741" +dependencies = [ + "nodrop", + "stable_deref_trait", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "siphasher" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[package]] +name = "softbuffer" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aac18da81ebbf05109ab275b157c22a653bb3c12cf884450179942f81bcbf6c3" +dependencies = [ + "bytemuck", + "js-sys", + "ndk", + "objc2", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation", + "objc2-quartz-core", + "raw-window-handle", + "redox_syscall", + "tracing", + "wasm-bindgen", + "web-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "soup3" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "471f924a40f31251afc77450e781cb26d55c0b650842efafc9c6cbd2f7cc4f9f" +dependencies = [ + "futures-channel", + "gio", + "glib", + "libc", + "soup3-sys", +] + +[[package]] +name = "soup3-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebe8950a680a12f24f15ebe1bf70db7af98ad242d9db43596ad3108aab86c27" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "string_cache" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" +dependencies = [ + "new_debug_unreachable", + "parking_lot", + "phf_shared 0.11.3", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0" +dependencies = [ + "phf_generator 0.11.3", + "phf_shared 0.11.3", + "proc-macro2", + "quote", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "swift-rs" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4057c98e2e852d51fdcfca832aac7b571f6b351ad159f9eda5db1655f8d0c4d7" +dependencies = [ + "base64 0.21.7", + "serde", + "serde_json", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.116" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3df424c70518695237746f84cede799c9c58fcb37450d7b23716568cc8bc69cb" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "system-deps" +version = "6.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" +dependencies = [ + "cfg-expr", + "heck 0.5.0", + "pkg-config", + "toml 0.8.2", + "version-compare", +] + +[[package]] +name = "tao" +version = "0.34.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a753bdc39c07b192151523a3f77cd0394aa75413802c883a0f6f6a0e5ee2e7" +dependencies = [ + "bitflags 2.11.0", + "block2", + "core-foundation", + "core-graphics", + "crossbeam-channel", + "dispatch", + "dlopen2", + "dpi", + "gdkwayland-sys", + "gdkx11-sys", + "gtk", + "jni", + "lazy_static", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "once_cell", + "parking_lot", + "raw-window-handle", + "scopeguard", + "tao-macros", + "unicode-segmentation", + "url", + "windows", + "windows-core 0.61.2", + "windows-version", + "x11-dl", +] + +[[package]] +name = "tao-macros" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "target-lexicon" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + +[[package]] +name = "tauri" +version = "2.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "463ae8677aa6d0f063a900b9c41ecd4ac2b7ca82f0b058cc4491540e55b20129" +dependencies = [ + "anyhow", + "bytes", + "cookie", + "dirs", + "dunce", + "embed_plist", + "getrandom 0.3.4", + "glob", + "gtk", + "heck 0.5.0", + "http", + "jni", + "libc", + "log", + "mime", + "muda", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "objc2-ui-kit", + "objc2-web-kit", + "percent-encoding", + "plist", + "raw-window-handle", + "reqwest 0.13.2", + "serde", + "serde_json", + "serde_repr", + "serialize-to-javascript", + "swift-rs", + "tauri-build", + "tauri-macros", + "tauri-runtime", + "tauri-runtime-wry", + "tauri-utils", + "thiserror 2.0.18", + "tokio", + "tray-icon", + "url", + "webkit2gtk", + "webview2-com", + "window-vibrancy", + "windows", +] + +[[package]] +name = "tauri-build" +version = "2.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca7bd893329425df750813e95bd2b643d5369d929438da96d5bbb7cc2c918f74" +dependencies = [ + "anyhow", + "cargo_toml", + "dirs", + "glob", + "heck 0.5.0", + "json-patch", + "schemars 0.8.22", + "semver", + "serde", + "serde_json", + "tauri-utils", + "tauri-winres", + "toml 0.9.12+spec-1.1.0", + "walkdir", +] + +[[package]] +name = "tauri-codegen" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aac423e5859d9f9ccdd32e3cf6a5866a15bedbf25aa6630bcb2acde9468f6ae3" +dependencies = [ + "base64 0.22.1", + "brotli", + "ico", + "json-patch", + "plist", + "png", + "proc-macro2", + "quote", + "semver", + "serde", + "serde_json", + "sha2", + "syn 2.0.116", + "tauri-utils", + "thiserror 2.0.18", + "time", + "url", + "uuid", + "walkdir", +] + +[[package]] +name = "tauri-macros" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b6a1bd2861ff0c8766b1d38b32a6a410f6dc6532d4ef534c47cfb2236092f59" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.116", + "tauri-codegen", + "tauri-utils", +] + +[[package]] +name = "tauri-plugin" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692a77abd8b8773e107a42ec0e05b767b8d2b7ece76ab36c6c3947e34df9f53f" +dependencies = [ + "anyhow", + "glob", + "plist", + "schemars 0.8.22", + "serde", + "serde_json", + "tauri-utils", + "toml 0.9.12+spec-1.1.0", + "walkdir", +] + +[[package]] +name = "tauri-plugin-opener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc624469b06f59f5a29f874bbc61a2ed737c0f9c23ef09855a292c389c42e83f" +dependencies = [ + "dunce", + "glob", + "objc2-app-kit", + "objc2-foundation", + "open", + "schemars 0.8.22", + "serde", + "serde_json", + "tauri", + "tauri-plugin", + "thiserror 2.0.18", + "url", + "windows", + "zbus", +] + +[[package]] +name = "tauri-runtime" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b885ffeac82b00f1f6fd292b6e5aabfa7435d537cef57d11e38a489956535651" +dependencies = [ + "cookie", + "dpi", + "gtk", + "http", + "jni", + "objc2", + "objc2-ui-kit", + "objc2-web-kit", + "raw-window-handle", + "serde", + "serde_json", + "tauri-utils", + "thiserror 2.0.18", + "url", + "webkit2gtk", + "webview2-com", + "windows", +] + +[[package]] +name = "tauri-runtime-wry" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5204682391625e867d16584fedc83fc292fb998814c9f7918605c789cd876314" +dependencies = [ + "gtk", + "http", + "jni", + "log", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "once_cell", + "percent-encoding", + "raw-window-handle", + "softbuffer", + "tao", + "tauri-runtime", + "tauri-utils", + "url", + "webkit2gtk", + "webview2-com", + "windows", + "wry", +] + +[[package]] +name = "tauri-utils" +version = "2.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcd169fccdff05eff2c1033210b9b94acd07a47e6fa9a3431cf09cfd4f01c87e" +dependencies = [ + "anyhow", + "brotli", + "cargo_metadata", + "ctor", + "dunce", + "glob", + "html5ever", + "http", + "infer", + "json-patch", + "kuchikiki", + "log", + "memchr", + "phf 0.11.3", + "proc-macro2", + "quote", + "regex", + "schemars 0.8.22", + "semver", + "serde", + "serde-untagged", + "serde_json", + "serde_with", + "swift-rs", + "thiserror 2.0.18", + "toml 0.9.12+spec-1.1.0", + "url", + "urlpattern", + "uuid", + "walkdir", +] + +[[package]] +name = "tauri-winres" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1087b111fe2b005e42dbdc1990fc18593234238d47453b0c99b7de1c9ab2c1e0" +dependencies = [ + "dunce", + "embed-resource", + "toml 0.9.12+spec-1.1.0", +] + +[[package]] +name = "tempfile" +version = "3.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0136791f7c95b1f6dd99f9cc786b91bb81c3800b639b3478e561ddb7be95e5f1" +dependencies = [ + "fastrand", + "getrandom 0.4.1", + "once_cell", + "rustix", + "windows-sys 0.61.2", +] + +[[package]] +name = "tendril" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" +dependencies = [ + "futf", + "mac", + "utf-8", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl 2.0.18", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "time" +version = "0.3.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde_core", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" + +[[package]] +name = "time-macros" +version = "0.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinystr" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.49.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +dependencies = [ + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-macros" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9" +dependencies = [ + "futures-util", + "log", + "rustls", + "rustls-native-certs", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tungstenite", +] + +[[package]] +name = "tokio-util" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +dependencies = [ + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.3", + "toml_edit 0.20.2", +] + +[[package]] +name = "toml" +version = "0.9.12+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" +dependencies = [ + "indexmap 2.13.0", + "serde_core", + "serde_spanned 1.0.4", + "toml_datetime 0.7.5+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 0.7.14", +] + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.13.0", + "toml_datetime 0.6.3", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +dependencies = [ + "indexmap 2.13.0", + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.3", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.23.10+spec-1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" +dependencies = [ + "indexmap 2.13.0", + "toml_datetime 0.7.5+spec-1.1.0", + "toml_parser", + "winnow 0.7.14", +] + +[[package]] +name = "toml_parser" +version = "1.0.9+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4" +dependencies = [ + "winnow 0.7.14", +] + +[[package]] +name = "toml_writer" +version = "1.0.6+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +dependencies = [ + "bitflags 2.11.0", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "tray-icon" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e85aa143ceb072062fc4d6356c1b520a51d636e7bc8e77ec94be3608e5e80c" +dependencies = [ + "crossbeam-channel", + "dirs", + "libappindicator", + "muda", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation", + "once_cell", + "png", + "serde", + "thiserror 2.0.18", + "windows-sys 0.60.2", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "tungstenite" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand 0.8.5", + "rustls", + "rustls-pki-types", + "sha1", + "thiserror 1.0.69", + "utf-8", +] + +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + +[[package]] +name = "typenum" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + +[[package]] +name = "uds_windows" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" +dependencies = [ + "memoffset", + "tempfile", + "winapi", +] + +[[package]] +name = "unic-char-property" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" +dependencies = [ + "unic-char-range", +] + +[[package]] +name = "unic-char-range" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" + +[[package]] +name = "unic-common" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" + +[[package]] +name = "unic-ucd-ident" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e230a37c0381caa9219d67cf063aa3a375ffed5bf541a452db16e744bdab6987" +dependencies = [ + "unic-char-property", + "unic-char-range", + "unic-ucd-version", +] + +[[package]] +name = "unic-ucd-version" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" +dependencies = [ + "unic-common", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", + "serde_derive", +] + +[[package]] +name = "urlpattern" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70acd30e3aa1450bc2eece896ce2ad0d178e9c079493819301573dae3c37ba6d" +dependencies = [ + "regex", + "serde", + "unic-ucd-ident", + "url", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "uuid" +version = "1.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b672338555252d43fd2240c714dc444b8c6fb0a5c5335e65a07bba7742735ddb" +dependencies = [ + "getrandom 0.4.1", + "js-sys", + "serde_core", + "wasm-bindgen", +] + +[[package]] +name = "valpal" +version = "0.1.0" +dependencies = [ + "base64 0.22.1", + "chrono", + "futures-util", + "http", + "rand 0.9.2", + "reqwest 0.12.28", + "rustls", + "serde", + "serde_json", + "tauri", + "tauri-build", + "tauri-plugin-opener", + "tokio", + "tokio-tungstenite", + "uuid", +] + +[[package]] +name = "version-compare" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c2856837ef78f57382f06b2b8563a2f512f7185d732608fd9176cb3b8edf0e" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "vswhom" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b" +dependencies = [ + "libc", + "vswhom-sys", +] + +[[package]] +name = "vswhom-sys" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb067e4cbd1ff067d1df46c9194b5de0e98efd2810bbc95c5d5e5f25a3231150" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.2+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" +dependencies = [ + "cfg-if", + "futures-util", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.116", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap 2.13.0", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasm-streams" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags 2.11.0", + "hashbrown 0.15.5", + "indexmap 2.13.0", + "semver", +] + +[[package]] +name = "web-sys" +version = "0.3.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webkit2gtk" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1027150013530fb2eaf806408df88461ae4815a45c541c8975e61d6f2fc4793" +dependencies = [ + "bitflags 1.3.2", + "cairo-rs", + "gdk", + "gdk-sys", + "gio", + "gio-sys", + "glib", + "glib-sys", + "gobject-sys", + "gtk", + "gtk-sys", + "javascriptcore-rs", + "libc", + "once_cell", + "soup3", + "webkit2gtk-sys", +] + +[[package]] +name = "webkit2gtk-sys" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "916a5f65c2ef0dfe12fff695960a2ec3d4565359fdbb2e9943c974e06c734ea5" +dependencies = [ + "bitflags 1.3.2", + "cairo-sys-rs", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "gtk-sys", + "javascriptcore-rs-sys", + "libc", + "pkg-config", + "soup3-sys", + "system-deps", +] + +[[package]] +name = "webpki-roots" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "webview2-com" +version = "0.38.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7130243a7a5b33c54a444e54842e6a9e133de08b5ad7b5861cd8ed9a6a5bc96a" +dependencies = [ + "webview2-com-macros", + "webview2-com-sys", + "windows", + "windows-core 0.61.2", + "windows-implement", + "windows-interface", +] + +[[package]] +name = "webview2-com-macros" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a921c1b6914c367b2b823cd4cde6f96beec77d30a939c8199bb377cf9b9b54" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "webview2-com-sys" +version = "0.38.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "381336cfffd772377d291702245447a5251a2ffa5bad679c99e61bc48bacbf9c" +dependencies = [ + "thiserror 2.0.18", + "windows", + "windows-core 0.61.2", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "window-vibrancy" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9bec5a31f3f9362f2258fd0e9c9dd61a9ca432e7306cc78c444258f0dce9a9c" +dependencies = [ + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", + "raw-window-handle", + "windows-sys 0.59.0", + "windows-version", +] + +[[package]] +name = "windows" +version = "0.61.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" +dependencies = [ + "windows-collections", + "windows-core 0.61.2", + "windows-future", + "windows-link 0.1.3", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" +dependencies = [ + "windows-core 0.61.2", +] + +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", +] + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + +[[package]] +name = "windows-future" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" +dependencies = [ + "windows-core 0.61.2", + "windows-link 0.1.3", + "windows-threading", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-numerics" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" +dependencies = [ + "windows-core 0.61.2", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link 0.2.1", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", +] + +[[package]] +name = "windows-threading" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-version" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4060a1da109b9d0326b7262c8e12c84df67cc0dbc9e33cf49e01ccc2eb63631" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.55.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb5a765337c50e9ec252c2069be9bf91c7df47afb103b642ba3a53bf8101be97" +dependencies = [ + "cfg-if", + "windows-sys 0.59.0", +] + +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck 0.5.0", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck 0.5.0", + "indexmap 2.13.0", + "prettyplease", + "syn 2.0.116", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.116", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags 2.11.0", + "indexmap 2.13.0", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap 2.13.0", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] + +[[package]] +name = "writeable" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" + +[[package]] +name = "wry" +version = "0.54.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb26159b420aa77684589a744ae9a9461a95395b848764ad12290a14d960a11a" +dependencies = [ + "base64 0.22.1", + "block2", + "cookie", + "crossbeam-channel", + "dirs", + "dpi", + "dunce", + "gdkx11", + "gtk", + "html5ever", + "http", + "javascriptcore-rs", + "jni", + "kuchikiki", + "libc", + "ndk", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", + "objc2-ui-kit", + "objc2-web-kit", + "once_cell", + "percent-encoding", + "raw-window-handle", + "sha2", + "soup3", + "tao-macros", + "thiserror 2.0.18", + "url", + "webkit2gtk", + "webkit2gtk-sys", + "webview2-com", + "windows", + "windows-core 0.61.2", + "windows-version", + "x11-dl", +] + +[[package]] +name = "x11" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "yoke" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", + "synstructure", +] + +[[package]] +name = "zbus" +version = "5.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfeff997a0aaa3eb20c4652baf788d2dfa6d2839a0ead0b3ff69ce2f9c4bdd1" +dependencies = [ + "async-broadcast", + "async-executor", + "async-io", + "async-lock", + "async-process", + "async-recursion", + "async-task", + "async-trait", + "blocking", + "enumflags2", + "event-listener", + "futures-core", + "futures-lite", + "hex", + "libc", + "ordered-stream", + "rustix", + "serde", + "serde_repr", + "tracing", + "uds_windows", + "uuid", + "windows-sys 0.61.2", + "winnow 0.7.14", + "zbus_macros", + "zbus_names", + "zvariant", +] + +[[package]] +name = "zbus_macros" +version = "5.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bbd5a90dbe8feee5b13def448427ae314ccd26a49cac47905cafefb9ff846f1" +dependencies = [ + "proc-macro-crate 3.4.0", + "proc-macro2", + "quote", + "syn 2.0.116", + "zbus_names", + "zvariant", + "zvariant_utils", +] + +[[package]] +name = "zbus_names" +version = "4.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffd8af6d5b78619bab301ff3c560a5bd22426150253db278f164d6cf3b72c50f" +dependencies = [ + "serde", + "winnow 0.7.14", + "zvariant", +] + +[[package]] +name = "zerocopy" +version = "0.8.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + +[[package]] +name = "zerotrie" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.116", +] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" + +[[package]] +name = "zvariant" +version = "5.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b64ef4f40c7951337ddc7023dd03528a57a3ce3408ee9da5e948bd29b232c4" +dependencies = [ + "endi", + "enumflags2", + "serde", + "winnow 0.7.14", + "zvariant_derive", + "zvariant_utils", +] + +[[package]] +name = "zvariant_derive" +version = "5.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "484d5d975eb7afb52cc6b929c13d3719a20ad650fea4120e6310de3fc55e415c" +dependencies = [ + "proc-macro-crate 3.4.0", + "proc-macro2", + "quote", + "syn 2.0.116", + "zvariant_utils", +] + +[[package]] +name = "zvariant_utils" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f75c23a64ef8f40f13a6989991e643554d9bef1d682a281160cf0c1bc389c5e9" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "syn 2.0.116", + "winnow 0.7.14", +] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml new file mode 100644 index 0000000..dd24449 --- /dev/null +++ b/src-tauri/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "valpal" +version = "0.1.0" +description = "A Tauri App" +authors = ["you"] +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +# The `_lib` suffix may seem redundant but it is necessary +# to make the lib name unique and wouldn't conflict with the bin name. +# This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519 +name = "valpal_lib" +crate-type = ["staticlib", "cdylib", "rlib"] + +[build-dependencies] +tauri-build = { version = "2", features = [] } + +[dependencies] +tauri = { version = "2", features = ["tray-icon", "devtools"] } +tauri-plugin-opener = "2" +serde = { version = "1", features = ["derive"] } +serde_json = "1" +tokio = { version = "1", features = ["full"] } +tokio-tungstenite = { version = "0.24", features = ["rustls-tls-native-roots"] } +futures-util = "0.3" +reqwest = { version = "0.12", features = ["json", "rustls-tls"], default-features = false } +base64 = "0.22" +uuid = { version = "1", features = ["v4"] } +rand = "0.9" +rustls = { version = "0.23", default-features = false, features = ["ring", "std"] } +http = "1.0" +chrono = "0.4" + diff --git a/src-tauri/build.rs b/src-tauri/build.rs new file mode 100644 index 0000000..d860e1e --- /dev/null +++ b/src-tauri/build.rs @@ -0,0 +1,3 @@ +fn main() { + tauri_build::build() +} diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json new file mode 100644 index 0000000..4cdbf49 --- /dev/null +++ b/src-tauri/capabilities/default.json @@ -0,0 +1,10 @@ +{ + "$schema": "../gen/schemas/desktop-schema.json", + "identifier": "default", + "description": "Capability for the main window", + "windows": ["main"], + "permissions": [ + "core:default", + "opener:default" + ] +} diff --git a/src-tauri/icons/128x128.png b/src-tauri/icons/128x128.png new file mode 100644 index 0000000..6be5e50 Binary files /dev/null and b/src-tauri/icons/128x128.png differ diff --git a/src-tauri/icons/128x128@2x.png b/src-tauri/icons/128x128@2x.png new file mode 100644 index 0000000..e81bece Binary files /dev/null and b/src-tauri/icons/128x128@2x.png differ diff --git a/src-tauri/icons/32x32.png b/src-tauri/icons/32x32.png new file mode 100644 index 0000000..a437dd5 Binary files /dev/null and b/src-tauri/icons/32x32.png differ diff --git a/src-tauri/icons/Square107x107Logo.png b/src-tauri/icons/Square107x107Logo.png new file mode 100644 index 0000000..0ca4f27 Binary files /dev/null and b/src-tauri/icons/Square107x107Logo.png differ diff --git a/src-tauri/icons/Square142x142Logo.png b/src-tauri/icons/Square142x142Logo.png new file mode 100644 index 0000000..b81f820 Binary files /dev/null and b/src-tauri/icons/Square142x142Logo.png differ diff --git a/src-tauri/icons/Square150x150Logo.png b/src-tauri/icons/Square150x150Logo.png new file mode 100644 index 0000000..624c7bf Binary files /dev/null and b/src-tauri/icons/Square150x150Logo.png differ diff --git a/src-tauri/icons/Square284x284Logo.png b/src-tauri/icons/Square284x284Logo.png new file mode 100644 index 0000000..c021d2b Binary files /dev/null and b/src-tauri/icons/Square284x284Logo.png differ diff --git a/src-tauri/icons/Square30x30Logo.png b/src-tauri/icons/Square30x30Logo.png new file mode 100644 index 0000000..6219700 Binary files /dev/null and b/src-tauri/icons/Square30x30Logo.png differ diff --git a/src-tauri/icons/Square310x310Logo.png b/src-tauri/icons/Square310x310Logo.png new file mode 100644 index 0000000..f9bc048 Binary files /dev/null and b/src-tauri/icons/Square310x310Logo.png differ diff --git a/src-tauri/icons/Square44x44Logo.png b/src-tauri/icons/Square44x44Logo.png new file mode 100644 index 0000000..d5fbfb2 Binary files /dev/null and b/src-tauri/icons/Square44x44Logo.png differ diff --git a/src-tauri/icons/Square71x71Logo.png b/src-tauri/icons/Square71x71Logo.png new file mode 100644 index 0000000..63440d7 Binary files /dev/null and b/src-tauri/icons/Square71x71Logo.png differ diff --git a/src-tauri/icons/Square89x89Logo.png b/src-tauri/icons/Square89x89Logo.png new file mode 100644 index 0000000..f3f705a Binary files /dev/null and b/src-tauri/icons/Square89x89Logo.png differ diff --git a/src-tauri/icons/StoreLogo.png b/src-tauri/icons/StoreLogo.png new file mode 100644 index 0000000..4556388 Binary files /dev/null and b/src-tauri/icons/StoreLogo.png differ diff --git a/src-tauri/icons/icon.icns b/src-tauri/icons/icon.icns new file mode 100644 index 0000000..12a5bce Binary files /dev/null and b/src-tauri/icons/icon.icns differ diff --git a/src-tauri/icons/icon.ico b/src-tauri/icons/icon.ico new file mode 100644 index 0000000..b3636e4 Binary files /dev/null and b/src-tauri/icons/icon.ico differ diff --git a/src-tauri/icons/icon.png b/src-tauri/icons/icon.png new file mode 100644 index 0000000..e1cd261 Binary files /dev/null and b/src-tauri/icons/icon.png differ diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs new file mode 100644 index 0000000..69405d1 --- /dev/null +++ b/src-tauri/src/commands.rs @@ -0,0 +1,416 @@ +use crate::config::{self, Loadout, UserConfig}; +use crate::valorant::{self, EntitlementsResponse, UserData, ValorantLoadout}; +use crate::valorant_data; +use crate::{AppState, ShuffleSettingsPayload, TrayMenuState}; +use std::sync::atomic::Ordering; +use tauri::{Emitter, State}; + +fn is_token_expired_error(err: &str) -> bool { + err.contains("BAD_CLAIMS") +} + +async fn get_user_or_err(state: &AppState) -> Result { + valorant::get_user(&state.region_cache, &state.user_cache) + .await? + .ok_or_else(|| "No user logged in.".to_string()) +} + +async fn refresh_user(state: &AppState) -> Result { + valorant::invalidate_user_cache(&state.user_cache).await; + get_user_or_err(state).await +} + +#[tauri::command] +pub async fn get_user( + state: State<'_, AppState>, +) -> Result, String> { + let t = std::time::Instant::now(); + let result = valorant::get_user(&state.region_cache, &state.user_cache).await; + println!("[CMD] get_user: {:?}", t.elapsed()); + result +} + +#[tauri::command] +pub async fn get_loadout( + state: State<'_, AppState>, +) -> Result { + let t = std::time::Instant::now(); + let user = get_user_or_err(&state).await?; + println!("[CMD] get_loadout: get_user took {:?}", t.elapsed()); + let t2 = std::time::Instant::now(); + match valorant::get_loadout(&user).await { + Ok(v) => { + println!("[CMD] get_loadout: get_loadout took {:?}, total {:?}", t2.elapsed(), t.elapsed()); + Ok(v) + } + Err(e) if is_token_expired_error(&e) => { + println!("[CMD] get_loadout: token expired, refreshing..."); + let user = refresh_user(&state).await?; + valorant::get_loadout(&user).await + } + Err(e) => Err(e), + } +} + +#[tauri::command] +pub async fn get_entitlements( + state: State<'_, AppState>, +) -> Result { + let t = std::time::Instant::now(); + let user = get_user_or_err(&state).await?; + match valorant::get_entitlements(&user).await { + Ok(v) => { + println!("[CMD] get_entitlements: {:?}", t.elapsed()); + Ok(v) + } + Err(e) if is_token_expired_error(&e) => { + println!("[CMD] get_entitlements: token expired, refreshing..."); + let user = refresh_user(&state).await?; + valorant::get_entitlements(&user).await + } + Err(e) => Err(e), + } +} + +#[tauri::command] +pub async fn equip_loadout( + state: State<'_, AppState>, + loadout: ValorantLoadout, +) -> Result { + let t = std::time::Instant::now(); + let user = get_user_or_err(&state).await?; + match valorant::equip_loadout(&user, loadout.clone()).await { + Ok(()) => { + println!("[CMD] equip_loadout: {:?}", t.elapsed()); + Ok(true) + } + Err(e) if is_token_expired_error(&e) => { + println!("[CMD] equip_loadout: token expired, refreshing..."); + let user = refresh_user(&state).await?; + valorant::equip_loadout(&user, loadout).await?; + Ok(true) + } + Err(e) => Err(e), + } +} + +#[tauri::command] +pub async fn get_user_config( + state: State<'_, AppState>, +) -> Result { + let t = std::time::Instant::now(); + let user = get_user_or_err(&state).await?; + let result = config::get_user_config(&state.config_dir, &user.user_id).await; + println!("[CMD] get_user_config: {:?}", t.elapsed()); + result +} + +#[tauri::command] +pub async fn save_user_config( + state: State<'_, AppState>, + config: UserConfig, +) -> Result { + let user = get_user_or_err(&state).await?; + config::save_user_config(&state.config_dir, &user.user_id, &config).await?; + Ok(config) +} + +#[tauri::command] +pub async fn create_loadout( + state: State<'_, AppState>, + loadout: Loadout, +) -> Result { + let user = get_user_or_err(&state).await?; + let mut user_config = config::get_user_config(&state.config_dir, &user.user_id).await?; + user_config.loadouts.push(loadout.clone()); + config::save_user_config(&state.config_dir, &user.user_id, &user_config).await?; + Ok(loadout) +} + +#[tauri::command] +pub async fn update_loadout( + state: State<'_, AppState>, + loadout: Loadout, +) -> Result { + let user = get_user_or_err(&state).await?; + let mut user_config = config::get_user_config(&state.config_dir, &user.user_id).await?; + let existing = user_config + .loadouts + .iter_mut() + .find(|l| l.id == loadout.id) + .ok_or_else(|| "Loadout not found.".to_string())?; + *existing = loadout.clone(); + config::save_user_config(&state.config_dir, &user.user_id, &user_config).await?; + Ok(loadout) +} + +#[tauri::command] +pub async fn delete_loadout( + state: State<'_, AppState>, + loadout_id: String, +) -> Result { + let t = std::time::Instant::now(); + let user = get_user_or_err(&state).await?; + println!("[CMD] delete_loadout: get_user took {:?}", t.elapsed()); + let mut user_config = config::get_user_config(&state.config_dir, &user.user_id).await?; + let original_len = user_config.loadouts.len(); + user_config.loadouts.retain(|l| l.id != loadout_id); + if user_config.loadouts.len() < original_len { + config::save_user_config(&state.config_dir, &user.user_id, &user_config).await?; + println!("[CMD] delete_loadout: total {:?}", t.elapsed()); + Ok(loadout_id) + } else { + Err("Loadout not found.".to_string()) + } +} + +#[tauri::command] +pub async fn save_in_game_loadout( + state: State<'_, AppState>, + name: String, +) -> Result { + let t = std::time::Instant::now(); + let mut user = get_user_or_err(&state).await?; + println!("[CMD] save_in_game_loadout: get_user took {:?}", t.elapsed()); + let t2 = std::time::Instant::now(); + let in_game_loadout = match valorant::get_loadout(&user).await { + Ok(v) => v, + Err(e) if is_token_expired_error(&e) => { + println!("[CMD] save_in_game_loadout: token expired, refreshing..."); + user = refresh_user(&state).await?; + valorant::get_loadout(&user).await? + } + Err(e) => return Err(e), + }; + println!("[CMD] save_in_game_loadout: get_loadout took {:?}", t2.elapsed()); + let t3 = std::time::Instant::now(); + let val_data = valorant_data::get_valorant_data(&state.valorant_data_cache).await?; + println!("[CMD] save_in_game_loadout: get_valorant_data took {:?}", t3.elapsed()); + let default_skin_ids: Vec = val_data + .weapons + .iter() + .map(|w| w.default_skin_uuid.clone()) + .collect(); + let mut user_config = config::get_user_config(&state.config_dir, &user.user_id).await?; + let loadout = convert_valorant_loadout_to_config(&in_game_loadout, &name, &default_skin_ids); + user_config.loadouts.push(loadout.clone()); + config::save_user_config(&state.config_dir, &user.user_id, &user_config).await?; + println!("[CMD] save_in_game_loadout: total {:?}", t.elapsed()); + Ok(loadout) +} + +#[tauri::command] +pub async fn get_valorant_data( + state: State<'_, AppState>, +) -> Result { + valorant_data::get_valorant_data(&state.valorant_data_cache).await +} + +#[tauri::command] +pub fn get_valorant_status(state: State<'_, AppState>) -> bool { + state.valorant_connected.load(Ordering::SeqCst) +} + +#[tauri::command] +pub fn get_shuffle_settings(state: State<'_, AppState>) -> ShuffleSettingsPayload { + ShuffleSettingsPayload { + auto_shuffle_enabled: state.shuffle_settings.is_auto_shuffle_enabled(), + agent_detection_enabled: state.shuffle_settings.is_agent_detection_enabled(), + non_pregame_shuffle_enabled: state.shuffle_settings.is_non_pregame_shuffle_enabled(), + } +} + +#[tauri::command] +pub fn set_auto_shuffle_enabled( + app_handle: tauri::AppHandle, + state: State<'_, AppState>, + tray_state: State<'_, TrayMenuState>, + enabled: bool, +) -> Result<(), String> { + state.shuffle_settings.set_auto_shuffle_enabled(enabled); + tray_state + .auto_shuffle_item + .set_checked(enabled) + .map_err(|e| e.to_string())?; + let _ = tray_state.agent_detection_item.set_enabled(enabled); + let _ = tray_state.non_pregame_shuffle_item.set_enabled(enabled); + let _ = app_handle.emit( + "shuffle-settings-changed", + ShuffleSettingsPayload { + auto_shuffle_enabled: enabled, + agent_detection_enabled: state.shuffle_settings.is_agent_detection_enabled(), + non_pregame_shuffle_enabled: state.shuffle_settings.is_non_pregame_shuffle_enabled(), + }, + ); + Ok(()) +} + +#[tauri::command] +pub fn set_agent_detection_enabled( + app_handle: tauri::AppHandle, + state: State<'_, AppState>, + tray_state: State<'_, TrayMenuState>, + enabled: bool, +) -> Result<(), String> { + state.shuffle_settings.set_agent_detection_enabled(enabled); + tray_state + .agent_detection_item + .set_checked(enabled) + .map_err(|e| e.to_string())?; + let _ = app_handle.emit( + "shuffle-settings-changed", + ShuffleSettingsPayload { + auto_shuffle_enabled: state.shuffle_settings.is_auto_shuffle_enabled(), + agent_detection_enabled: enabled, + non_pregame_shuffle_enabled: state.shuffle_settings.is_non_pregame_shuffle_enabled(), + }, + ); + Ok(()) +} + +#[tauri::command] +pub fn set_non_pregame_shuffle_enabled( + app_handle: tauri::AppHandle, + state: State<'_, AppState>, + tray_state: State<'_, TrayMenuState>, + enabled: bool, +) -> Result<(), String> { + state.shuffle_settings.set_non_pregame_shuffle_enabled(enabled); + tray_state + .non_pregame_shuffle_item + .set_checked(enabled) + .map_err(|e| e.to_string())?; + let _ = app_handle.emit( + "shuffle-settings-changed", + ShuffleSettingsPayload { + auto_shuffle_enabled: state.shuffle_settings.is_auto_shuffle_enabled(), + agent_detection_enabled: state.shuffle_settings.is_agent_detection_enabled(), + non_pregame_shuffle_enabled: enabled, + }, + ); + Ok(()) +} + +#[tauri::command] +pub async fn equip_loadout_by_id( + state: State<'_, AppState>, + loadout_id: String, +) -> Result { + let t = std::time::Instant::now(); + let user = get_user_or_err(&state).await?; + let user_config = config::get_user_config(&state.config_dir, &user.user_id).await?; + let loadout = user_config + .loadouts + .iter() + .find(|l| l.id == loadout_id) + .ok_or_else(|| "Loadout not found.".to_string())? + .clone(); + + let existing = match valorant::get_loadout(&user).await { + Ok(v) => v, + Err(e) if is_token_expired_error(&e) => { + let user = refresh_user(&state).await?; + valorant::get_loadout(&user).await? + } + Err(e) => return Err(e), + }; + + let entitlements = match valorant::get_entitlements(&user).await { + Ok(v) => v, + Err(e) if is_token_expired_error(&e) => { + let user = refresh_user(&state).await?; + valorant::get_entitlements(&user).await? + } + Err(e) => return Err(e), + }; + + let valorant_loadout = + crate::game_detection::build_valorant_loadout(&loadout, &existing, &entitlements); + + let equip_user = get_user_or_err(&state).await?; + match valorant::equip_loadout(&equip_user, valorant_loadout.clone()).await { + Ok(()) => { + println!("[CMD] equip_loadout_by_id: {:?}", t.elapsed()); + Ok(true) + } + Err(e) if is_token_expired_error(&e) => { + let user = refresh_user(&state).await?; + valorant::equip_loadout(&user, valorant_loadout).await?; + Ok(true) + } + Err(e) => Err(e), + } +} + +fn convert_valorant_loadout_to_config(loadout: &ValorantLoadout, name: &str, default_skin_ids: &[String]) -> Loadout { + use crate::config::{BuddyTemplate, ExpressionIds, ExpressionSlot, WeaponConfig, WeaponTemplate}; + use std::collections::HashMap; + + let spray_type_id = "d5f120f8-ff8c-4aac-92ea-f2b5acbe9475"; + let flex_type_id = "03a572de-4234-31ed-d344-ababa488f981"; + + let mut expression_ids = ExpressionIds { + top: ExpressionSlot { spray_ids: vec![], flex_ids: vec![] }, + right: ExpressionSlot { spray_ids: vec![], flex_ids: vec![] }, + bottom: ExpressionSlot { spray_ids: vec![], flex_ids: vec![] }, + left: ExpressionSlot { spray_ids: vec![], flex_ids: vec![] }, + }; + + let slots = [ + &mut expression_ids.top, + &mut expression_ids.right, + &mut expression_ids.bottom, + &mut expression_ids.left, + ]; + for (i, slot) in slots.into_iter().enumerate() { + if let Some(expr) = loadout.active_expressions.get(i) { + if expr.type_id == spray_type_id { + slot.spray_ids.push(expr.asset_id.clone()); + } else if expr.type_id == flex_type_id { + slot.flex_ids.push(expr.asset_id.clone()); + } + } + } + + let weapons: HashMap = loadout + .guns + .iter() + .filter(|gun| !default_skin_ids.contains(&gun.skin_id)) + .map(|gun| { + let buddies = if let (Some(charm_id), Some(charm_level_id)) = + (&gun.charm_id, &gun.charm_level_id) + { + vec![BuddyTemplate { + id: charm_id.clone(), + level_ids: vec![charm_level_id.clone()], + }] + } else { + vec![] + }; + + ( + gun.id.clone(), + WeaponConfig { + templates: vec![WeaponTemplate { + id: gun.id.clone(), + skin_id: gun.skin_id.clone(), + level_ids: vec![gun.skin_level_id.clone()], + chroma_ids: vec![gun.chroma_id.clone()], + buddies, + }], + }, + ) + }) + .collect(); + + Loadout { + id: uuid::Uuid::new_v4().to_string(), + name: name.to_string(), + enabled: true, + agent_ids: vec![], + weapons, + player_card_ids: vec![loadout.identity.player_card_id.clone()], + player_title_ids: vec![loadout.identity.player_title_id.clone()], + expression_ids, + } +} diff --git a/src-tauri/src/config.rs b/src-tauri/src/config.rs new file mode 100644 index 0000000..c500503 --- /dev/null +++ b/src-tauri/src/config.rs @@ -0,0 +1,292 @@ +use serde::{Deserialize, Serialize}; +use serde_json::Value; +use std::collections::HashMap; +use std::path::{Path, PathBuf}; +use tokio::fs; + +const CONFIG_VERSION: u32 = 3; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct WeaponTemplate { + pub id: String, + #[serde(rename = "skinId")] + pub skin_id: String, + #[serde(rename = "levelIds")] + pub level_ids: Vec, + #[serde(rename = "chromaIds")] + pub chroma_ids: Vec, + pub buddies: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct BuddyTemplate { + pub id: String, + #[serde(rename = "levelIds")] + pub level_ids: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct WeaponConfig { + pub templates: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ExpressionSlot { + #[serde(rename = "sprayIds")] + pub spray_ids: Vec, + #[serde(rename = "flexIds")] + pub flex_ids: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ExpressionIds { + pub top: ExpressionSlot, + pub right: ExpressionSlot, + pub bottom: ExpressionSlot, + pub left: ExpressionSlot, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Loadout { + pub id: String, + pub name: String, + pub enabled: bool, + #[serde(rename = "agentIds")] + pub agent_ids: Vec, + pub weapons: HashMap, + #[serde(rename = "playerCardIds")] + pub player_card_ids: Vec, + #[serde(rename = "playerTitleIds")] + pub player_title_ids: Vec, + #[serde(rename = "expressionIds")] + pub expression_ids: ExpressionIds, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct UserConfig { + pub version: u32, + pub loadouts: Vec, +} + +impl Default for UserConfig { + fn default() -> Self { + Self { + version: CONFIG_VERSION, + loadouts: vec![create_default_loadout()], + } + } +} + +pub fn create_default_loadout() -> Loadout { + let weapon_ids = vec![ + "63e6c2b6-4a8e-869c-3d4c-e38355226584", + "55d8a0f4-4274-ca67-fe2c-06ab45efdf58", + "9c82e19d-4575-0200-1a81-3eacf00cf872", + "ae3de142-4d85-2547-dd26-4e90bed35cf7", + "ee8e8d15-496b-07ac-e5f6-8fae5d4c7b1a", + "ec845bf4-4f79-ddda-a3da-0db3774b2794", + "910be174-449b-c412-ab22-d0873436b21b", + "44d4e95c-4157-0037-81b2-17841bf2e8e3", + "29a0cfab-485b-f5d5-779a-b59f85e204a8", + "1baa85b4-4c70-1284-64bb-6481dfc3bb4e", + "e336c6b8-418d-9340-d77f-7a9e4cfe0702", + "42da8ccc-40d5-affc-beec-15aa47b42eda", + "a03b24d3-4319-996d-0f8c-94bbfba1dfc7", + "4ade7faa-4cf1-8376-95ef-39884480959b", + "c4883e50-4494-202c-3ec3-6b8a9284f00b", + "462080d1-4035-2937-7c09-27aa2a5c27a7", + "f7e1b454-4ad4-1063-ec0a-159e56b58941", + "2f59173c-4bed-b6c3-2191-dea9b58be9c7", + "5f0aaf7a-4289-3998-d5ff-eb9a5cf7ef5c", + ]; + + let weapons: HashMap = weapon_ids + .into_iter() + .map(|id| (id.to_string(), WeaponConfig { templates: vec![] })) + .collect(); + + Loadout { + id: uuid::Uuid::new_v4().to_string(), + name: "Default Loadout".to_string(), + enabled: true, + agent_ids: vec![], + weapons, + player_card_ids: vec![], + player_title_ids: vec![], + expression_ids: ExpressionIds { + top: ExpressionSlot { + spray_ids: vec![], + flex_ids: vec![], + }, + right: ExpressionSlot { + spray_ids: vec![], + flex_ids: vec![], + }, + bottom: ExpressionSlot { + spray_ids: vec![], + flex_ids: vec![], + }, + left: ExpressionSlot { + spray_ids: vec![], + flex_ids: vec![], + }, + }, + } +} + +fn get_config_path(base_dir: &Path, user_id: &str) -> PathBuf { + base_dir.join(format!("user_{}.json", user_id)) +} + +fn migrate_v1_to_v2(config: &mut Value) { + if let Some(loadouts) = config.get_mut("loadouts").and_then(|v| v.as_array_mut()) { + for loadout in loadouts.iter_mut() { + if let Some(spray_ids) = loadout.get("sprayIds").cloned() { + let pre_round = spray_ids + .get("preRound") + .and_then(|v| v.as_array()) + .cloned() + .unwrap_or_default(); + let mid_round = spray_ids + .get("midRound") + .and_then(|v| v.as_array()) + .cloned() + .unwrap_or_default(); + let post_round = spray_ids + .get("postRound") + .and_then(|v| v.as_array()) + .cloned() + .unwrap_or_default(); + + let new_spray_ids = serde_json::json!({ + "top": mid_round, + "right": post_round, + "bottom": [], + "left": pre_round + }); + + loadout["sprayIds"] = new_spray_ids; + } + } + } + config["version"] = serde_json::json!(2); +} + +fn migrate_v2_to_v3(config: &mut Value) { + if let Some(loadouts) = config.get_mut("loadouts").and_then(|v| v.as_array_mut()) { + for loadout in loadouts.iter_mut() { + if let Some(spray_ids) = loadout.get("sprayIds").cloned() { + let top = spray_ids + .get("top") + .and_then(|v| v.as_array()) + .cloned() + .unwrap_or_default(); + let right = spray_ids + .get("right") + .and_then(|v| v.as_array()) + .cloned() + .unwrap_or_default(); + let bottom = spray_ids + .get("bottom") + .and_then(|v| v.as_array()) + .cloned() + .unwrap_or_default(); + let left = spray_ids + .get("left") + .and_then(|v| v.as_array()) + .cloned() + .unwrap_or_default(); + + let expression_ids = serde_json::json!({ + "top": { "sprayIds": top, "flexIds": [] }, + "right": { "sprayIds": right, "flexIds": [] }, + "bottom": { "sprayIds": bottom, "flexIds": [] }, + "left": { "sprayIds": left, "flexIds": [] } + }); + + loadout["expressionIds"] = expression_ids; + loadout.as_object_mut().map(|o| o.remove("sprayIds")); + } + } + } + config["version"] = serde_json::json!(3); +} + +fn migrate_config(content: &str) -> Result<(UserConfig, bool), String> { + let mut config: Value = + serde_json::from_str(content).map_err(|e| format!("Failed to parse config: {}", e))?; + + let original_version = config.get("version").and_then(|v| v.as_u64()).unwrap_or(1) as u32; + let mut migrated = original_version != CONFIG_VERSION; + + if original_version < 2 { + println!("Migrating config from v1 to v2..."); + migrate_v1_to_v2(&mut config); + } + + let version = config.get("version").and_then(|v| v.as_u64()).unwrap_or(2) as u32; + + if version < 3 { + println!("Migrating config from v2 to v3..."); + migrate_v2_to_v3(&mut config); + } + + if config.get("version").is_none() { + config["version"] = serde_json::json!(CONFIG_VERSION); + migrated = true; + } + + let user_config = serde_json::from_value(config) + .map_err(|e| format!("Failed to parse migrated config: {}", e))?; + Ok((user_config, migrated)) +} + +pub async fn get_user_config(base_dir: &Path, user_id: &str) -> Result { + let path = get_config_path(base_dir, user_id); + + if !path.exists() { + let config = UserConfig::default(); + save_user_config(base_dir, user_id, &config).await?; + return Ok(config); + } + + let content = fs::read_to_string(&path) + .await + .map_err(|e| format!("Failed to read config: {}", e))?; + + let (config, migrated) = migrate_config(&content)?; + + if migrated { + save_user_config(base_dir, user_id, &config).await?; + } + + Ok(config) +} + +pub async fn save_user_config( + base_dir: &Path, + user_id: &str, + config: &UserConfig, +) -> Result<(), String> { + let path = get_config_path(base_dir, user_id); + + if let Some(parent) = path.parent() { + fs::create_dir_all(parent) + .await + .map_err(|e| format!("Failed to create config directory: {}", e))?; + } + + let config_to_save = UserConfig { + version: CONFIG_VERSION, + loadouts: config.loadouts.clone(), + }; + + let content = serde_json::to_string_pretty(&config_to_save) + .map_err(|e| format!("Failed to serialize: {}", e))?; + + fs::write(&path, content) + .await + .map_err(|e| format!("Failed to write config: {}", e))?; + + Ok(()) +} diff --git a/src-tauri/src/game_detection.rs b/src-tauri/src/game_detection.rs new file mode 100644 index 0000000..fa40360 --- /dev/null +++ b/src-tauri/src/game_detection.rs @@ -0,0 +1,1010 @@ +use crate::config::{self, Loadout}; +use crate::valorant::{self, EntitlementsResponse, RegionShardCache, UserData, UserDataCache, ValorantLoadout}; +use base64::{engine::general_purpose, Engine as _}; +use futures_util::{SinkExt, StreamExt}; +use rand::prelude::IndexedRandom; +use serde::Deserialize; +use std::collections::HashMap; +use std::path::PathBuf; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Arc; +use tauri::Emitter; +use tokio::io::AsyncWriteExt; +use tokio::sync::{Mutex, RwLock}; +use tokio_tungstenite::{connect_async_tls_with_config, Connector}; + +#[derive(Debug, Clone, Default)] +pub struct ShuffleSettings { + pub auto_shuffle_enabled: Arc, + pub agent_detection_enabled: Arc, + pub non_pregame_shuffle_enabled: Arc, +} + +impl ShuffleSettings { + pub fn new() -> Self { + Self { + auto_shuffle_enabled: Arc::new(AtomicBool::new(true)), + agent_detection_enabled: Arc::new(AtomicBool::new(true)), + non_pregame_shuffle_enabled: Arc::new(AtomicBool::new(true)), + } + } + + pub fn is_auto_shuffle_enabled(&self) -> bool { + self.auto_shuffle_enabled.load(Ordering::SeqCst) + } + + pub fn is_agent_detection_enabled(&self) -> bool { + self.agent_detection_enabled.load(Ordering::SeqCst) + } + + pub fn is_non_pregame_shuffle_enabled(&self) -> bool { + self.non_pregame_shuffle_enabled.load(Ordering::SeqCst) + } + + pub fn set_auto_shuffle_enabled(&self, enabled: bool) { + self.auto_shuffle_enabled.store(enabled, Ordering::SeqCst); + } + + pub fn set_agent_detection_enabled(&self, enabled: bool) { + self.agent_detection_enabled.store(enabled, Ordering::SeqCst); + } + + pub fn set_non_pregame_shuffle_enabled(&self, enabled: bool) { + self.non_pregame_shuffle_enabled.store(enabled, Ordering::SeqCst); + } +} + +#[derive(Debug, Deserialize)] +struct PartyResponse { + #[serde(rename = "ID")] + id: String, + #[serde(rename = "State")] + state: String, + #[serde(rename = "Members")] + members: Vec, + #[serde(rename = "MatchmakingData")] + matchmaking_data: MatchmakingData, + #[serde(rename = "QueueEntryTime")] + queue_entry_time: String, +} + +#[derive(Debug, Deserialize)] +struct PartyMember { + #[serde(rename = "Subject")] + subject: String, + #[serde(rename = "IsReady")] + is_ready: bool, + #[serde(rename = "IsOwner")] + is_owner: Option, +} + +#[derive(Debug, Deserialize)] +struct MatchmakingData { + #[serde(rename = "QueueID")] + queue_id: String, +} + +#[derive(Debug, Deserialize)] +struct PregameMatchResponse { + #[serde(rename = "AllyTeam")] + ally_team: AllyTeam, +} + +#[derive(Debug, Deserialize)] +struct AllyTeam { + #[serde(rename = "Players")] + players: Vec, +} + +#[derive(Debug, Deserialize)] +struct Player { + #[serde(rename = "Subject")] + subject: String, + #[serde(rename = "CharacterID")] + character_id: String, + #[serde(rename = "CharacterSelectionState")] + character_selection_state: String, +} + +// Queue IDs for modes with SkipPregame/AssignRandomAgents: +// deathmatch = Deathmatch +// ggteam = Escalation +// snowball = Snowball Fight +// hurm = Team Deathmatch +// valaram = All Random One Site (AROS) +// skirmish2v2 = Skirmish +// +// Full queue ID mapping: +// competitive = Competitive +// unrated = Unrated +// swiftplay = Swiftplay +// spikerush = Spike Rush +// onefa = Replication +// newmap = New Map +// custom = Custom +const NON_PREGAME_QUEUES: &[&str] = &[ + "deathmatch", + "ggteam", + "snowball", + "hurm", + "valaram", + "skirmish2v2", +]; + +pub struct GameDetector { + region_cache: RegionShardCache, + user_cache: UserDataCache, + settings: ShuffleSettings, + config_dir: PathBuf, + match_states: Arc>>, + party_states: Arc>>, + app_handle: tauri::AppHandle, + connected: Arc, + ws_log: Arc>>, +} + +impl GameDetector { + pub fn new( + region_cache: RegionShardCache, + user_cache: UserDataCache, + settings: ShuffleSettings, + config_dir: PathBuf, + app_handle: tauri::AppHandle, + connected: Arc, + ) -> Self { + Self { + region_cache, + user_cache, + settings, + config_dir, + match_states: Arc::new(RwLock::new(HashMap::new())), + party_states: Arc::new(RwLock::new(HashMap::new())), + app_handle, + connected, + ws_log: Arc::new(Mutex::new(None)), + } + } + + fn set_connected(&self, status: bool) { + let prev = self.connected.swap(status, Ordering::SeqCst); + if prev != status { + let _ = self.app_handle.emit("valorant-status", status); + } + } + + async fn log(&self, msg: &str) { + println!("{}", msg); + self.log_to_file(msg).await; + } + + async fn log_to_file(&self, msg: &str) { + let mut guard = self.ws_log.lock().await; + if let Some(file) = guard.as_mut() { + let timestamp = chrono::Local::now().format("%H:%M:%S%.3f"); + let line = format!("[{}] {}\n", timestamp, msg); + let _ = file.write_all(line.as_bytes()).await; + let _ = file.flush().await; + } + } + + pub async fn run(&self) { + self.log("[GameDetector] Starting game detection loop...").await; + loop { + self.log("[GameDetector] Attempting to connect to Riot Client...").await; + match self.connect_and_listen().await { + Ok(()) => { + self.log("[GameDetector] Connection closed normally").await; + } + Err(e) => { + self.log(&format!("[GameDetector] Error: {}", e)).await; + } + } + self.set_connected(false); + self.log("[GameDetector] Will retry in 5 seconds...").await; + tokio::time::sleep(tokio::time::Duration::from_secs(5)).await; + } + } + + async fn connect_and_listen(&self) -> Result<(), Box> { + { + let log_path = self.config_dir.join("debug.log"); + match tokio::fs::File::create(&log_path).await { + Ok(file) => { + *self.ws_log.lock().await = Some(file); + self.log(&format!("[GameDetector] Opened log: {}", log_path.display())).await; + } + Err(e) => { + eprintln!("[GameDetector] Failed to create log: {}", e); + } + } + } + + let lockfile = match valorant::get_lockfile().await? { + Some(lf) => { + self.log(&format!("[GameDetector] Found lockfile: port={}", lf.port)).await; + lf + } + None => { + return Err("Lockfile not found (Riot Client not running?)".into()); + } + }; + + let url = format!("wss://127.0.0.1:{}/", lockfile.port); + + let auth = format!("riot:{}", lockfile.password); + let auth_header = format!("Basic {}", general_purpose::STANDARD.encode(&auth)); + + let connector = Connector::Rustls(Arc::new( + rustls::ClientConfig::builder() + .dangerous() + .with_custom_certificate_verifier(Arc::new(NoVerifier)) + .with_no_client_auth(), + )); + + let request = http::Request::builder() + .uri(&url) + .header("Authorization", auth_header) + .header("Host", format!("127.0.0.1:{}", lockfile.port)) + .header("Upgrade", "websocket") + .header("Connection", "Upgrade") + .header( + "Sec-WebSocket-Key", + tokio_tungstenite::tungstenite::handshake::client::generate_key(), + ) + .header("Sec-WebSocket-Version", "13") + .body(()) + .map_err(|e| format!("Failed to build request: {}", e))?; + + let (ws_stream, _) = connect_async_tls_with_config(request, None, false, Some(connector)) + .await + .map_err(|e| format!("Failed to connect to Riot WebSocket: {}", e))?; + + self.log(&format!("[GameDetector] Connected to Riot Client WebSocket on port {}", lockfile.port)).await; + + { + let mut cached = self.user_cache.write().await; + *cached = None; + self.log("[GameDetector] Cleared user cache on new connection").await; + } + + self.set_connected(true); + + let (mut write, mut read) = ws_stream.split(); + + self.log("[GameDetector] Subscribing to OnJsonApiEvent...").await; + write + .send(tokio_tungstenite::tungstenite::Message::Text( + r#"[5, "OnJsonApiEvent"]"#.to_string().into(), + )) + .await?; + self.log("[GameDetector] Subscription sent, waiting for events...").await; + + while let Some(msg) = read.next().await { + match msg { + Ok(tokio_tungstenite::tungstenite::Message::Text(text)) => { + if text.is_empty() { + continue; + } + + self.log_to_file(&format!("[WS] {}", text)).await; + + let preview = if text.len() > 200 { + format!("{}... ({} bytes total)", &text[..200], text.len()) + } else { + text.to_string() + }; + self.log(&format!("[GameDetector] Received message: {}", preview)).await; + + if let Err(e) = self.handle_riot_message(&text).await { + self.log(&format!("[GameDetector] Error handling message: {}", e)).await; + } + } + Ok(tokio_tungstenite::tungstenite::Message::Close(frame)) => { + self.log(&format!("[GameDetector] WebSocket closed: {:?}", frame)).await; + break; + } + Err(e) => { + self.log(&format!("[GameDetector] WebSocket error: {}", e)).await; + break; + } + _ => {} + } + } + + self.log("[GameDetector] WebSocket loop ended").await; + + Ok(()) + } + + async fn handle_riot_message( + &self, + text: &str, + ) -> Result<(), Box> { + let parsed: serde_json::Value = serde_json::from_str(text)?; + + let arr = match parsed.as_array() { + Some(a) => a, + None => return Ok(()), + }; + + if arr.len() < 3 { + return Ok(()); + } + + let msg_type = arr[0].as_u64().unwrap_or(0); + let event = arr[1].as_str().unwrap_or(""); + + if msg_type != 8 || event != "OnJsonApiEvent" { + return Ok(()); + } + + let payload = &arr[2]; + let uri = payload["uri"].as_str().unwrap_or(""); + let event_type = payload["eventType"].as_str().unwrap_or(""); + + self.log(&format!("[GameDetector] Event: uri={}, type={}", uri, event_type)).await; + + if let Some(party_id) = uri + .strip_prefix("/riot-messaging-service/v1/message/ares-parties/parties/v1/parties/") + { + if event_type == "Create" { + self.handle_party_event(party_id).await; + } + return Ok(()); + } + + let match_id = if let Some(caps) = uri.strip_prefix("/pregame/v1/matches/") { + caps.to_string() + } else { + return Ok(()); + }; + + self.log(&format!("[GameDetector] Pregame event: match_id={}, event_type={}", match_id, event_type)).await; + + if event_type != "Create" { + self.log(&format!("[GameDetector] Ignoring non-Create event type: '{}'", event_type)).await; + return Ok(()); + } + + self.log(&format!("[GameDetector] Pregame match found: {}", match_id)).await; + + { + let states = self.match_states.read().await; + self.log(&format!("[GameDetector] Current tracked match states: {:?}", states.keys().collect::>())).await; + if states.get(&match_id) == Some(&"locked".to_string()) { + self.log(&format!("[GameDetector] Match {} already locked, skipping", match_id)).await; + return Ok(()); + } + } + + self.log("[GameDetector] Fetching user data...").await; + let mut user = match valorant::get_user(&self.region_cache, &self.user_cache).await? { + Some(u) => { + self.log(&format!("[GameDetector] Got user: id={}, region={:?}, shard={:?}", u.user_id, u.region, u.shard)).await; + u + } + None => { + self.log("[GameDetector] No user data available, aborting").await; + return Ok(()); + } + }; + + self.log("[GameDetector] Fetching pregame data...").await; + let pregame = match self.get_pregame(&user).await { + Ok(p) => { + self.log("[GameDetector] Pregame data retrieved successfully").await; + p + } + Err(e) if e.contains("BAD_CLAIMS") => { + self.log("[GameDetector] Token expired during pregame, refreshing...").await; + valorant::invalidate_user_cache(&self.user_cache).await; + user = match valorant::get_user(&self.region_cache, &self.user_cache).await? { + Some(u) => { + self.log(&format!("[GameDetector] Refreshed user: id={}", u.user_id)).await; + u + } + None => { + self.log("[GameDetector] No user data after refresh, aborting").await; + return Ok(()); + } + }; + match self.get_pregame(&user).await { + Ok(p) => { + self.log("[GameDetector] Pregame data retrieved after token refresh").await; + p + } + Err(e) => { + self.log(&format!("[GameDetector] Failed to get pregame after refresh: {}", e)).await; + return Err(e.into()); + } + } + } + Err(e) => { + self.log(&format!("[GameDetector] Failed to get pregame: {}", e)).await; + return Err(e.into()); + } + }; + + self.log(&format!("[GameDetector] Pregame ally team has {} players", pregame.ally_team.players.len())).await; + for p in &pregame.ally_team.players { + self.log(&format!("[GameDetector] Player: subject={}, character={}, state={}", p.subject, p.character_id, p.character_selection_state)).await; + } + + let player = pregame + .ally_team + .players + .iter() + .find(|p| p.subject == user.user_id); + + if let Some(player) = player { + self.log(&format!("[GameDetector] Found our player: character={}, state={}", player.character_id, player.character_selection_state)).await; + + let new_state = &player.character_selection_state; + let mut states = self.match_states.write().await; + let old_state = states.get(&match_id).cloned(); + + self.log(&format!("[GameDetector] State comparison: old={:?}, new={}", old_state, new_state)).await; + + if old_state.as_deref() != Some(new_state) { + self.log("[GameDetector] State changed! Evaluating actions...").await; + + let auto_shuffle = self.settings.is_auto_shuffle_enabled(); + let agent_detection = self.settings.is_agent_detection_enabled(); + self.log(&format!("[GameDetector] Settings: auto_shuffle={}, agent_detection={}", auto_shuffle, agent_detection)).await; + + if new_state == "locked" && auto_shuffle { + self.log("[GameDetector] Agent locked and auto-shuffle enabled, triggering loadout equip").await; + + let agent_id = if agent_detection { + self.log(&format!("[GameDetector] Agent detection enabled, using agent_id={}", player.character_id)).await; + Some(player.character_id.clone()) + } else { + self.log("[GameDetector] Agent detection disabled, no agent filter").await; + None + }; + + match self.equip_random_loadout(&user, agent_id.as_deref()).await { + Ok(()) => self.log("[GameDetector] Loadout equip completed successfully").await, + Err(e) => self.log(&format!("[GameDetector] Failed to equip loadout: {}", e)).await, + } + } else if new_state != "locked" { + self.log(&format!("[GameDetector] State is '{}', not 'locked' — skipping loadout equip", new_state)).await; + } else { + self.log("[GameDetector] Auto-shuffle is disabled, skipping loadout equip").await; + } + + states.insert(match_id.clone(), new_state.clone()); + self.log(&format!("[GameDetector] Updated match {} state to '{}'", match_id, new_state)).await; + } else { + self.log(&format!("[GameDetector] State unchanged ({}), no action needed", new_state)).await; + } + } else { + self.log(&format!("[GameDetector] Our player (id={}) not found in pregame ally team", user.user_id)).await; + } + + Ok(()) + } + + async fn handle_party_event(&self, party_id: &str) { + self.log(&format!("[GameDetector] Party event detected: party_id={}", party_id)).await; + + let user = match valorant::get_user(&self.region_cache, &self.user_cache).await { + Ok(Some(u)) => u, + Ok(None) => { + self.log("[GameDetector] No user data for party lookup").await; + return; + } + Err(e) => { + self.log(&format!("[GameDetector] Failed to get user for party lookup: {}", e)).await; + return; + } + }; + + let party = match self.get_party(&user, party_id).await { + Ok(p) => p, + Err(e) => { + self.log(&format!("[GameDetector] Failed to get party {}: {}", party_id, e)).await; + return; + } + }; + + self.log("[GameDetector] === Party State ===").await; + self.log(&format!("[GameDetector] Party ID: {}", party.id)).await; + self.log(&format!("[GameDetector] State: {}", party.state)).await; + self.log(&format!("[GameDetector] Queue ID: {}", party.matchmaking_data.queue_id)).await; + self.log(&format!("[GameDetector] Queue Entry Time: {}", party.queue_entry_time)).await; + self.log(&format!("[GameDetector] Members: {}", party.members.len())).await; + for member in &party.members { + self.log(&format!("[GameDetector] - {} (ready={}, owner={})", member.subject, member.is_ready, member.is_owner.unwrap_or(false))).await; + } + self.log("[GameDetector] ===================").await; + + let party_key = format!("{}:{}", party_id, party.queue_entry_time); + let mut states = self.party_states.write().await; + let old_state = states.get(&party_key).cloned(); + + self.log(&format!("[GameDetector] Party key={}, old_state={:?}, new_state={}", party_key, old_state, party.state)).await; + + if old_state.as_deref() == Some(&party.state) { + return; + } + + states.insert(party_key, party.state.clone()); + drop(states); + + if party.state != "MATCHMAKING" { + return; + } + + let queue_id = party.matchmaking_data.queue_id.to_lowercase(); + let is_non_pregame = NON_PREGAME_QUEUES.iter().any(|q| queue_id == *q); + + if !is_non_pregame { + self.log(&format!("[GameDetector] Queue '{}' has pregame, skipping non-pregame shuffle", queue_id)).await; + return; + } + + let auto_shuffle = self.settings.is_auto_shuffle_enabled(); + let non_pregame = self.settings.is_non_pregame_shuffle_enabled(); + self.log(&format!("[GameDetector] Non-pregame queue detected: auto_shuffle={}, non_pregame_shuffle={}", auto_shuffle, non_pregame)).await; + + if !auto_shuffle || !non_pregame { + self.log("[GameDetector] Shuffle disabled for non-pregame modes, skipping").await; + return; + } + + self.log(&format!("[GameDetector] Triggering loadout equip for non-pregame queue '{}'", queue_id)).await; + match self.equip_random_loadout(&user, None).await { + Ok(()) => self.log("[GameDetector] Non-pregame loadout equip completed successfully").await, + Err(e) => self.log(&format!("[GameDetector] Non-pregame loadout equip failed: {}", e)).await, + } + } + + async fn get_party(&self, user: &UserData, party_id: &str) -> Result { + let client = reqwest::Client::builder() + .use_rustls_tls() + .build() + .map_err(|e| e.to_string())?; + + let url = format!( + "https://glz-{}-1.{}.a.pvp.net/parties/v1/parties/{}", + user.region.as_str(), + user.shard.as_str(), + party_id + ); + + self.log(&format!("[GameDetector] GET {}", url)).await; + + let response = client + .get(&url) + .header("Authorization", format!("Bearer {}", user.access_token)) + .header("X-Riot-Entitlements-JWT", &user.entitlements_token) + .header("X-Riot-ClientVersion", &user.riot_client_version) + .header("X-Riot-ClientPlatform", valorant::create_client_platform_header()) + .send() + .await + .map_err(|e| format!("Party request failed: {}", e))?; + + let status = response.status(); + self.log(&format!("[GameDetector] Party endpoint responded: {}", status)).await; + + let body = response.text().await.unwrap_or_default(); + self.log(&format!("[GameDetector] Party response ({}): {}", status, body)).await; + + if !status.is_success() { + return Err(format!("Party request failed ({}): {}", status, body)); + } + + let party: PartyResponse = serde_json::from_str(&body) + .map_err(|e| format!("Failed to parse party response: {}", e))?; + + Ok(party) + } + + async fn get_pregame(&self, user: &UserData) -> Result { + let client = reqwest::Client::builder() + .use_rustls_tls() + .build() + .map_err(|e| e.to_string())?; + + let url = format!( + "https://glz-{}-1.{}.a.pvp.net/pregame/v1/players/{}", + user.region.as_str(), + user.shard.as_str(), + user.user_id + ); + + self.log(&format!("[GameDetector] GET {}", url)).await; + + #[derive(Deserialize)] + struct PlayerResponse { + #[serde(rename = "MatchID")] + match_id: String, + } + + let response = client + .get(&url) + .header("Authorization", format!("Bearer {}", user.access_token)) + .header("X-Riot-Entitlements-JWT", &user.entitlements_token) + .header("X-Riot-ClientVersion", &user.riot_client_version) + .header("X-Riot-ClientPlatform", valorant::create_client_platform_header()) + .send() + .await + .map_err(|e| format!("Request failed: {}", e))?; + + let status = response.status(); + self.log(&format!("[GameDetector] Player endpoint responded: {}", status)).await; + if !status.is_success() { + let body = response.text().await.unwrap_or_default(); + return Err(format!("Player request failed ({}): {}", status, body)); + } + + let player_response: PlayerResponse = response + .json() + .await + .map_err(|e| format!("Failed to parse player response: {}", e))?; + + self.log(&format!("[GameDetector] Player response match_id: {}", player_response.match_id)).await; + + let match_url = format!( + "https://glz-{}-1.{}.a.pvp.net/pregame/v1/matches/{}", + user.region.as_str(), + user.shard.as_str(), + player_response.match_id + ); + + self.log(&format!("[GameDetector] GET {}", match_url)).await; + + let match_response_raw = client + .get(&match_url) + .header("Authorization", format!("Bearer {}", user.access_token)) + .header("X-Riot-Entitlements-JWT", &user.entitlements_token) + .header("X-Riot-ClientVersion", &user.riot_client_version) + .header("X-Riot-ClientPlatform", valorant::create_client_platform_header()) + .send() + .await + .map_err(|e| format!("Match request failed: {}", e))?; + + let match_status = match_response_raw.status(); + self.log(&format!("[GameDetector] Match endpoint responded: {}", match_status)).await; + if !match_status.is_success() { + let body = match_response_raw.text().await.unwrap_or_default(); + return Err(format!("Match request failed ({}): {}", match_status, body)); + } + + let match_response: PregameMatchResponse = match_response_raw + .json() + .await + .map_err(|e| format!("Failed to parse match response: {}", e))?; + + self.log(&format!("[GameDetector] Pregame match parsed: {} players in ally team", match_response.ally_team.players.len())).await; + + Ok(match_response) + } + + async fn equip_random_loadout( + &self, + user: &UserData, + agent_id: Option<&str>, + ) -> Result<(), String> { + self.log(&format!("[GameDetector] equip_random_loadout called: user={}, agent_id={:?}", user.user_id, agent_id)).await; + + let user_config = config::get_user_config(&self.config_dir, &user.user_id).await?; + + self.log(&format!("[GameDetector] User config loaded: {} total loadouts", user_config.loadouts.len())).await; + + let enabled_loadouts: Vec<&Loadout> = + user_config.loadouts.iter().filter(|l| l.enabled).collect(); + + self.log(&format!("[GameDetector] Enabled loadouts: {} (names: [{}])", enabled_loadouts.len(), enabled_loadouts.iter().map(|l| l.name.as_str()).collect::>().join(", "))).await; + + if enabled_loadouts.is_empty() { + self.log("[GameDetector] No enabled loadouts, nothing to equip").await; + return Ok(()); + } + + let loadouts_to_consider: Vec<&Loadout> = if let Some(agent) = agent_id { + let agent_specific: Vec<&Loadout> = enabled_loadouts + .iter() + .filter(|l| l.agent_ids.contains(&agent.to_string())) + .copied() + .collect(); + + self.log(&format!("[GameDetector] Agent filter '{}': {} agent-specific loadouts found (names: [{}])", agent, agent_specific.len(), agent_specific.iter().map(|l| l.name.as_str()).collect::>().join(", "))).await; + + if agent_specific.is_empty() { + self.log(&format!("[GameDetector] No agent-specific loadouts, falling back to all {} enabled loadouts", enabled_loadouts.len())).await; + enabled_loadouts + } else { + agent_specific + } + } else { + self.log(&format!("[GameDetector] No agent filter, using all {} enabled loadouts", enabled_loadouts.len())).await; + enabled_loadouts + }; + + let loadout = { + let mut rng = rand::rng(); + loadouts_to_consider.choose(&mut rng).cloned().cloned() + }; + let loadout = match loadout { + Some(l) => { + self.log(&format!("[GameDetector] Randomly selected loadout: {} (id: {})", l.name, l.id)).await; + l + } + None => return Ok(()), + }; + + self.log("[GameDetector] Fetching existing loadout and entitlements...").await; + let (existing_loadout, entitlements) = + tokio::join!(valorant::get_loadout(user), valorant::get_entitlements(user)); + + let (existing_loadout, entitlements, user_refreshed) = + match (&existing_loadout, &entitlements) { + (Err(e), _) | (_, Err(e)) if e.contains("BAD_CLAIMS") => { + self.log("[GameDetector] Token expired in equip_random_loadout, refreshing...").await; + valorant::invalidate_user_cache(&self.user_cache).await; + let fresh_user = + match valorant::get_user(&self.region_cache, &self.user_cache).await? { + Some(u) => u, + None => return Err("No user after refresh".to_string()), + }; + let (el, ent) = tokio::join!( + valorant::get_loadout(&fresh_user), + valorant::get_entitlements(&fresh_user) + ); + (el?, ent?, Some(fresh_user)) + } + _ => (existing_loadout?, entitlements?, None), + }; + + self.log("[GameDetector] Existing loadout and entitlements retrieved").await; + + let equip_user = user_refreshed.as_ref().unwrap_or(user); + + self.log(&format!("[GameDetector] Building valorant loadout from '{}'...", loadout.name)).await; + let valorant_loadout = + build_valorant_loadout(&loadout, &existing_loadout, &entitlements); + + self.log(&format!("[GameDetector] Built loadout: {} guns, {} expressions, card={}, title={}", valorant_loadout.guns.len(), valorant_loadout.active_expressions.len(), valorant_loadout.identity.player_card_id, valorant_loadout.identity.player_title_id)).await; + + self.log("[GameDetector] Sending equip request to Valorant API...").await; + valorant::equip_loadout(equip_user, valorant_loadout).await?; + + self.log(&format!("[GameDetector] Loadout '{}' equipped successfully!", loadout.name)).await; + + Ok(()) + } +} + +pub fn build_valorant_loadout( + loadout: &Loadout, + existing: &ValorantLoadout, + entitlements: &EntitlementsResponse, +) -> ValorantLoadout { + use rand::prelude::IndexedRandom; + + let mut rng = rand::rng(); + + let buddy_type_id = "dd3bf334-87f3-40bd-b043-682a57a8dc3a"; + let spray_type_id = "d5f120f8-ff8c-4aac-92ea-f2b5acbe9475"; + let flex_type_id = "03a572de-4234-31ed-d344-ababa488f981"; + + let buddy_entitlements: HashMap> = entitlements + .entitlements_by_types + .iter() + .find(|e| e.item_type_id == buddy_type_id) + .map(|e| { + let mut map: HashMap> = HashMap::new(); + for ent in &e.entitlements { + if let Some(instance_id) = &ent.instance_id { + map.entry(ent.item_id.clone()) + .or_default() + .push(instance_id.clone()); + } + } + map + }) + .unwrap_or_default(); + + let mut used_buddies: HashMap = HashMap::new(); + + let guns: Vec = loadout + .weapons + .iter() + .map(|(weapon_id, config)| { + if config.templates.is_empty() { + if let Some(existing_gun) = existing.guns.iter().find(|g| g.id == *weapon_id) { + return valorant::Gun { + id: weapon_id.clone(), + skin_id: existing_gun.skin_id.clone(), + skin_level_id: existing_gun.skin_level_id.clone(), + chroma_id: existing_gun.chroma_id.clone(), + charm_instance_id: None, + charm_id: None, + charm_level_id: None, + attachments: vec![], + }; + } + + return valorant::Gun { + id: weapon_id.clone(), + skin_id: String::new(), + skin_level_id: String::new(), + chroma_id: String::new(), + charm_instance_id: None, + charm_id: None, + charm_level_id: None, + attachments: vec![], + }; + } + + let template = config.templates.choose(&mut rng).unwrap(); + + let chroma_id = template + .chroma_ids + .choose(&mut rng) + .cloned() + .unwrap_or_default(); + let level_id = template + .level_ids + .choose(&mut rng) + .cloned() + .unwrap_or_default(); + + let buddy_data = if !template.buddies.is_empty() { + if let Some(buddy) = template.buddies.choose(&mut rng) { + if let Some(level_id) = buddy.level_ids.choose(&mut rng) { + let used_count = used_buddies.entry(level_id.clone()).or_insert(0); + if let Some(instances) = buddy_entitlements.get(level_id) { + if *used_count < instances.len() { + let instance = instances[*used_count].clone(); + *used_count += 1; + Some((instance, buddy.id.clone(), level_id.clone())) + } else { + None + } + } else { + None + } + } else { + None + } + } else { + None + } + } else { + None + }; + + valorant::Gun { + id: weapon_id.clone(), + skin_id: template.skin_id.clone(), + skin_level_id: level_id, + chroma_id, + charm_instance_id: buddy_data.as_ref().map(|(i, _, _)| i.clone()), + charm_id: buddy_data.as_ref().map(|(_, c, _)| c.clone()), + charm_level_id: buddy_data.map(|(_, _, l)| l), + attachments: vec![], + } + }) + .collect(); + + let mut build_expression = + |slot: &config::ExpressionSlot, default_spray: &str, default_flex: &str| { + let options: Vec = slot + .spray_ids + .iter() + .map(|id| valorant::ActiveExpression { + type_id: spray_type_id.to_string(), + asset_id: id.clone(), + }) + .chain(slot.flex_ids.iter().map(|id| valorant::ActiveExpression { + type_id: flex_type_id.to_string(), + asset_id: id.clone(), + })) + .collect(); + + if options.is_empty() { + if !default_spray.is_empty() { + valorant::ActiveExpression { + type_id: spray_type_id.to_string(), + asset_id: default_spray.to_string(), + } + } else { + valorant::ActiveExpression { + type_id: flex_type_id.to_string(), + asset_id: default_flex.to_string(), + } + } + } else { + options.choose(&mut rng).unwrap().clone() + } + }; + + let default_spray = "0a6db78c-48b9-a32d-c47a-82be597584c1"; + let default_flex = "af52b5a0-4a4c-03b2-c9d7-8187a08a2675"; + + let active_expressions = vec![ + build_expression(&loadout.expression_ids.top, default_spray, ""), + build_expression(&loadout.expression_ids.right, default_spray, ""), + build_expression(&loadout.expression_ids.bottom, default_spray, ""), + build_expression(&loadout.expression_ids.left, "", default_flex), + ]; + + let player_card_id = loadout + .player_card_ids + .choose(&mut rng) + .cloned() + .unwrap_or_else(|| "9fb348bc-41a0-91ad-8a3e-818035c4e561".to_string()); + + let player_title_id = loadout + .player_title_ids + .choose(&mut rng) + .cloned() + .unwrap_or_else(|| existing.identity.player_title_id.clone()); + + ValorantLoadout { + subject: existing.subject.clone(), + version: existing.version, + guns, + active_expressions, + identity: valorant::Identity { + player_card_id, + player_title_id, + account_level: existing.identity.account_level, + preferred_level_border_id: existing.identity.preferred_level_border_id.clone(), + hide_account_level: existing.identity.hide_account_level, + }, + incognito: existing.incognito, + } +} + +#[derive(Debug)] +struct NoVerifier; + +impl rustls::client::danger::ServerCertVerifier for NoVerifier { + fn verify_server_cert( + &self, + _end_entity: &rustls::pki_types::CertificateDer<'_>, + _intermediates: &[rustls::pki_types::CertificateDer<'_>], + _server_name: &rustls::pki_types::ServerName<'_>, + _ocsp_response: &[u8], + _now: rustls::pki_types::UnixTime, + ) -> Result { + Ok(rustls::client::danger::ServerCertVerified::assertion()) + } + + fn verify_tls12_signature( + &self, + _message: &[u8], + _cert: &rustls::pki_types::CertificateDer<'_>, + _dss: &rustls::DigitallySignedStruct, + ) -> Result { + Ok(rustls::client::danger::HandshakeSignatureValid::assertion()) + } + + fn verify_tls13_signature( + &self, + _message: &[u8], + _cert: &rustls::pki_types::CertificateDer<'_>, + _dss: &rustls::DigitallySignedStruct, + ) -> Result { + Ok(rustls::client::danger::HandshakeSignatureValid::assertion()) + } + + fn supported_verify_schemes(&self) -> Vec { + vec![ + rustls::SignatureScheme::RSA_PKCS1_SHA256, + rustls::SignatureScheme::ECDSA_NISTP256_SHA256, + rustls::SignatureScheme::RSA_PKCS1_SHA384, + rustls::SignatureScheme::ECDSA_NISTP384_SHA384, + rustls::SignatureScheme::RSA_PKCS1_SHA512, + rustls::SignatureScheme::ECDSA_NISTP521_SHA512, + rustls::SignatureScheme::RSA_PSS_SHA256, + rustls::SignatureScheme::RSA_PSS_SHA384, + rustls::SignatureScheme::RSA_PSS_SHA512, + rustls::SignatureScheme::ED25519, + ] + } +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs new file mode 100644 index 0000000..bbfcac4 --- /dev/null +++ b/src-tauri/src/lib.rs @@ -0,0 +1,246 @@ +mod commands; +mod config; +mod game_detection; +mod valorant; +mod valorant_data; + +use game_detection::ShuffleSettings; +use std::path::PathBuf; +use std::sync::atomic::AtomicBool; +use std::sync::Arc; +use tauri::menu::{CheckMenuItem, Menu, MenuItem, PredefinedMenuItem}; +use tauri::tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent}; +use tauri::{Emitter, Manager}; +use tokio::sync::RwLock; +use valorant::{RegionShardCache, UserDataCache}; +use valorant_data::ValorantDataCache; + +pub struct AppState { + pub region_cache: RegionShardCache, + pub user_cache: UserDataCache, + pub config_dir: PathBuf, + pub valorant_data_cache: ValorantDataCache, + pub valorant_connected: Arc, + pub shuffle_settings: ShuffleSettings, +} + +pub struct TrayMenuState { + pub auto_shuffle_item: CheckMenuItem, + pub agent_detection_item: CheckMenuItem, + pub non_pregame_shuffle_item: CheckMenuItem, +} + +#[cfg_attr(mobile, tauri::mobile_entry_point)] +pub fn run() { + tauri::Builder::default() + .plugin(tauri_plugin_opener::init()) + .setup(|app| { + let config_dir = app + .path() + .app_data_dir() + .expect("failed to resolve app data dir"); + + let region_cache: RegionShardCache = + Arc::new(RwLock::new(std::collections::HashMap::new())); + + let valorant_data_cache: ValorantDataCache = Arc::new(RwLock::new(None)); + let user_cache: UserDataCache = Arc::new(RwLock::new(None)); + let valorant_connected = Arc::new(AtomicBool::new(false)); + let shuffle_settings = ShuffleSettings::new(); + + let state = AppState { + region_cache: Arc::clone(®ion_cache), + user_cache: Arc::clone(&user_cache), + config_dir: config_dir.clone(), + valorant_data_cache, + valorant_connected: Arc::clone(&valorant_connected), + shuffle_settings: shuffle_settings.clone(), + }; + + app.manage(state); + + let auto_shuffle_item = CheckMenuItem::with_id( + app, + "auto_shuffle", + "Auto Shuffle", + true, + true, + None::<&str>, + )?; + let agent_detection_item = CheckMenuItem::with_id( + app, + "agent_detection", + "Agent Detection", + true, + true, + None::<&str>, + )?; + let non_pregame_shuffle_item = CheckMenuItem::with_id( + app, + "non_pregame_shuffle", + "Shuffle in Non-Pregame Modes", + true, + true, + None::<&str>, + )?; + let separator = PredefinedMenuItem::separator(app)?; + let show_item = MenuItem::with_id(app, "show", "Show", true, None::<&str>)?; + let quit_item = MenuItem::with_id(app, "quit", "Quit", true, None::<&str>)?; + + let menu = Menu::with_items( + app, + &[ + &auto_shuffle_item, + &agent_detection_item, + &non_pregame_shuffle_item, + &separator, + &show_item, + &quit_item, + ], + )?; + + let settings_for_tray = shuffle_settings.clone(); + let auto_shuffle_clone = auto_shuffle_item.clone(); + let agent_detection_clone = agent_detection_item.clone(); + let non_pregame_shuffle_clone = non_pregame_shuffle_item.clone(); + + TrayIconBuilder::new() + .icon(app.default_window_icon().unwrap().clone()) + .tooltip("valpal") + .menu(&menu) + .show_menu_on_left_click(false) + .on_menu_event(move |app, event| { + match event.id.as_ref() { + "auto_shuffle" => { + if let Ok(checked) = auto_shuffle_clone.is_checked() { + settings_for_tray.set_auto_shuffle_enabled(checked); + let _ = agent_detection_clone.set_enabled(checked); + let _ = non_pregame_shuffle_clone.set_enabled(checked); + let _ = app.emit( + "shuffle-settings-changed", + ShuffleSettingsPayload { + auto_shuffle_enabled: checked, + agent_detection_enabled: settings_for_tray + .is_agent_detection_enabled(), + non_pregame_shuffle_enabled: settings_for_tray + .is_non_pregame_shuffle_enabled(), + }, + ); + } + } + "agent_detection" => { + if let Ok(checked) = agent_detection_clone.is_checked() { + settings_for_tray.set_agent_detection_enabled(checked); + let _ = app.emit( + "shuffle-settings-changed", + ShuffleSettingsPayload { + auto_shuffle_enabled: settings_for_tray + .is_auto_shuffle_enabled(), + agent_detection_enabled: checked, + non_pregame_shuffle_enabled: settings_for_tray + .is_non_pregame_shuffle_enabled(), + }, + ); + } + } + "non_pregame_shuffle" => { + if let Ok(checked) = non_pregame_shuffle_clone.is_checked() { + settings_for_tray.set_non_pregame_shuffle_enabled(checked); + let _ = app.emit( + "shuffle-settings-changed", + ShuffleSettingsPayload { + auto_shuffle_enabled: settings_for_tray + .is_auto_shuffle_enabled(), + agent_detection_enabled: settings_for_tray + .is_agent_detection_enabled(), + non_pregame_shuffle_enabled: checked, + }, + ); + } + } + "show" => { + if let Some(window) = app.get_webview_window("main") { + let _ = window.show(); + let _ = window.set_focus(); + } + } + "quit" => { + app.exit(0); + } + _ => {} + } + }) + .on_tray_icon_event(|tray, event| { + if let TrayIconEvent::Click { + button: MouseButton::Left, + button_state: MouseButtonState::Up, + .. + } = event + { + let app = tray.app_handle(); + if let Some(window) = app.get_webview_window("main") { + let _ = window.show(); + let _ = window.set_focus(); + } + } + }) + .build(app)?; + + app.manage(TrayMenuState { + auto_shuffle_item, + agent_detection_item, + non_pregame_shuffle_item, + }); + + let app_handle = app.handle().clone(); + let detector = game_detection::GameDetector::new( + region_cache, + user_cache, + shuffle_settings, + config_dir, + app_handle, + valorant_connected, + ); + + tauri::async_runtime::spawn(async move { + detector.run().await; + }); + + Ok(()) + }) + .on_window_event(|window, event| { + if let tauri::WindowEvent::CloseRequested { api, .. } = event { + api.prevent_close(); + let _ = window.hide(); + } + }) + .invoke_handler(tauri::generate_handler![ + commands::get_user, + commands::get_loadout, + commands::get_entitlements, + commands::equip_loadout, + commands::get_user_config, + commands::save_user_config, + commands::create_loadout, + commands::update_loadout, + commands::delete_loadout, + commands::save_in_game_loadout, + commands::get_valorant_data, + commands::get_valorant_status, + commands::get_shuffle_settings, + commands::set_auto_shuffle_enabled, + commands::set_agent_detection_enabled, + commands::set_non_pregame_shuffle_enabled, + commands::equip_loadout_by_id, + ]) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} + +#[derive(Clone, serde::Serialize)] +#[serde(rename_all = "camelCase")] +pub struct ShuffleSettingsPayload { + pub auto_shuffle_enabled: bool, + pub agent_detection_enabled: bool, + pub non_pregame_shuffle_enabled: bool, +} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs new file mode 100644 index 0000000..8a2a27e --- /dev/null +++ b/src-tauri/src/main.rs @@ -0,0 +1,6 @@ +// Prevents additional console window on Windows in release, DO NOT REMOVE!! +#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] + +fn main() { + valpal_lib::run() +} diff --git a/src-tauri/src/valorant.rs b/src-tauri/src/valorant.rs new file mode 100644 index 0000000..61cbd71 --- /dev/null +++ b/src-tauri/src/valorant.rs @@ -0,0 +1,723 @@ +use base64::{engine::general_purpose, Engine as _}; +use reqwest::Client; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use std::collections::HashMap; +use std::sync::Arc; +use tokio::sync::RwLock; + +fn log_response_preview(body: &str, max_len: usize) -> String { + if body.len() > max_len { + format!("{}... ({} bytes total)", &body[..max_len], body.len()) + } else { + body.to_string() + } +} + +async fn parse_json_response( + response: reqwest::Response, + context: &str, +) -> Result { + let status = response.status(); + let url = response.url().to_string(); + + let body = response.text().await.map_err(|e| { + eprintln!("[API] Failed to read response body from {}: {}", url, e); + format!("Failed to read response body: {}", e) + })?; + + println!( + "[API] {} response ({}): {}", + context, + status, + log_response_preview(&body, 500) + ); + + if !status.is_success() { + eprintln!( + "[API] {} failed with status {}: {}", + context, + status, + log_response_preview(&body, 1000) + ); + return Err(format!( + "{} failed ({}): {}", + context, + status, + log_response_preview(&body, 200) + )); + } + + serde_json::from_str(&body).map_err(|e| { + eprintln!("[API] {} JSON parse error: {}", context, e); + eprintln!( + "[API] {} raw body was: {}", + context, + log_response_preview(&body, 2000) + ); + format!( + "JSON parse error for {}: {} (body: {})", + context, + e, + log_response_preview(&body, 200) + ) + }) +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +pub enum Region { + AP, + EU, + KO, + NA, + LATAM, + BR, +} + +impl Region { + pub fn as_str(&self) -> &str { + match self { + Region::AP => "ap", + Region::EU => "eu", + Region::KO => "ko", + Region::NA => "na", + Region::LATAM => "latam", + Region::BR => "br", + } + } +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +pub enum Shard { + NA, + EU, + AP, + KR, + PBE, +} + +impl Shard { + pub fn as_str(&self) -> &str { + match self { + Shard::NA => "na", + Shard::EU => "eu", + Shard::AP => "ap", + Shard::KR => "kr", + Shard::PBE => "pbe", + } + } +} + +#[derive(Debug, Clone)] +pub struct Lockfile { + pub port: String, + pub password: String, +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct PlayerInfo { + pub display_name: String, + pub game_name: String, + pub tag_line: String, +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct UserData { + pub access_token: String, + pub entitlements_token: String, + pub user_id: String, + pub region: Region, + pub shard: Shard, + pub riot_client_version: String, + pub player_info: PlayerInfo, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct Gun { + #[serde(rename = "ID")] + pub id: String, + #[serde(rename = "SkinID")] + pub skin_id: String, + #[serde(rename = "SkinLevelID")] + pub skin_level_id: String, + #[serde(rename = "ChromaID")] + pub chroma_id: String, + #[serde(rename = "CharmInstanceID")] + pub charm_instance_id: Option, + #[serde(rename = "CharmID")] + pub charm_id: Option, + #[serde(rename = "CharmLevelID")] + pub charm_level_id: Option, + pub attachments: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct ActiveExpression { + #[serde(rename = "TypeID")] + pub type_id: String, + #[serde(rename = "AssetID")] + pub asset_id: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct Identity { + #[serde(rename = "PlayerCardID")] + pub player_card_id: String, + #[serde(rename = "PlayerTitleID")] + pub player_title_id: String, + pub account_level: u32, + #[serde(rename = "PreferredLevelBorderID")] + pub preferred_level_border_id: String, + pub hide_account_level: bool, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct ValorantLoadout { + pub subject: String, + pub version: u32, + pub guns: Vec, + pub active_expressions: Vec, + pub identity: Identity, + pub incognito: bool, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Entitlement { + #[serde(rename = "TypeID")] + pub type_id: String, + #[serde(rename = "ItemID")] + pub item_id: String, + #[serde(rename = "InstanceID")] + #[serde(default)] + pub instance_id: Option, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct EntitlementsByType { + #[serde(rename = "ItemTypeID")] + pub item_type_id: String, + #[serde(rename = "Entitlements")] + pub entitlements: Vec, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct EntitlementsResponse { + #[serde(rename = "EntitlementsByTypes")] + pub entitlements_by_types: Vec, +} + +pub type RegionShardCache = Arc>>; + +const USER_CACHE_TTL: std::time::Duration = std::time::Duration::from_secs(55 * 60); + +pub type UserDataCache = Arc>>; + +fn get_player_data_service_url(region: &Region) -> String { + format!("https://pd.{}.a.pvp.net", region.as_str()) +} + +pub fn create_client_platform_header() -> String { + let platform_info = serde_json::json!({ + "platformType": "PC", + "platformOS": "Windows", + "platformOSVersion": "10.0.19042.1.256.64bit", + "platformChipset": "Unknown" + }); + general_purpose::STANDARD.encode(platform_info.to_string()) +} + +fn create_http_client() -> Result { + Client::builder() + .use_rustls_tls() + .min_tls_version(reqwest::tls::Version::TLS_1_2) + .build() +} + +fn create_local_http_client() -> Result { + Client::builder() + .danger_accept_invalid_certs(true) + .use_rustls_tls() + .build() +} + +pub async fn get_lockfile() -> Result, String> { + let local_appdata = std::env::var("LOCALAPPDATA").map_err(|_| "LOCALAPPDATA not set")?; + + let lockfile_path = std::path::Path::new(&local_appdata) + .join("Riot Games") + .join("Riot Client") + .join("Config") + .join("lockfile"); + + if !lockfile_path.exists() { + return Ok(None); + } + + let content = tokio::fs::read_to_string(&lockfile_path) + .await + .map_err(|e| e.to_string())?; + + let parts: Vec<&str> = content.split(':').collect(); + if parts.len() < 4 { + return Err("Invalid lockfile format".to_string()); + } + + Ok(Some(Lockfile { + port: parts[2].to_string(), + password: parts[3].to_string(), + })) +} + +pub async fn get_riot_client_version() -> Result { + let client = reqwest::Client::new(); + + #[derive(Deserialize)] + struct VersionData { + data: RiotClientVersionData, + } + + #[derive(Deserialize)] + #[serde(rename_all = "camelCase")] + struct RiotClientVersionData { + riot_client_version: String, + } + + let url = "https://valorant-api.com/v1/version"; + println!("[API] GET {}", url); + + let response = client.get(url).send().await.map_err(|e| { + eprintln!("[API] get_riot_client_version request failed: {}", e); + e.to_string() + })?; + + let version_data: VersionData = + parse_json_response(response, "get_riot_client_version").await?; + println!( + "[API] Got riot client version: {}", + version_data.data.riot_client_version + ); + Ok(version_data.data.riot_client_version) +} + +#[derive(Deserialize)] +struct LocalTokenResponse { + #[serde(rename = "accessToken")] + access_token: String, + token: String, + subject: String, +} + +#[derive(Deserialize)] +struct PlayerResponse { + #[serde(rename = "DisplayName")] + display_name: String, + #[serde(rename = "GameName")] + game_name: String, + #[serde(rename = "TagLine")] + tag_line: String, +} + +#[derive(Deserialize)] +struct IdTokenResponse { + token: String, +} + +#[derive(Deserialize)] +struct RiotGeoResponse { + affinities: RiotGeoAffinities, +} + +#[derive(Deserialize)] +struct RiotGeoAffinities { + live: String, +} + +async fn get_id_token(lockfile: &Lockfile) -> Result { + let client = create_local_http_client().map_err(|e| e.to_string())?; + let auth = format!("riot:{}", lockfile.password); + let auth_header = format!("Basic {}", general_purpose::STANDARD.encode(&auth)); + + let url = format!( + "https://127.0.0.1:{}/rso-auth/v1/authorization/id-token", + lockfile.port + ); + println!("[API] GET {}", url); + + let response = client + .get(&url) + .header("Authorization", auth_header) + .send() + .await + .map_err(|e| { + eprintln!("[API] get_id_token request failed: {}", e); + format!("get_id_token request failed: {}", e) + })?; + + let token_response: IdTokenResponse = + parse_json_response(response, "get_id_token").await?; + Ok(token_response.token) +} + +async fn detect_region_shard( + user_id: &str, + access_token: &str, + id_token: &str, + cache: &RegionShardCache, +) -> Result, String> { + { + let cache_lock = cache.read().await; + if let Some(cached) = cache_lock.get(user_id) { + println!( + "[API] Region/shard cache hit for {}: {:?}/{:?}", + user_id, cached.0, cached.1 + ); + return Ok(Some(cached.clone())); + } + } + + println!("[API] Detecting region via Riot Geo for user {}...", user_id); + + let client = create_http_client().map_err(|e| e.to_string())?; + + let url = "https://riot-geo.pas.si.riotgames.com/pas/v1/product/valorant"; + println!("[API] PUT {}", url); + + let response = client + .put(url) + .header("Authorization", format!("Bearer {}", access_token)) + .json(&serde_json::json!({ "id_token": id_token })) + .send() + .await + .map_err(|e| { + eprintln!("[API] Riot Geo request failed: {}", e); + format!("Riot Geo request failed: {}", e) + })?; + + let geo: RiotGeoResponse = parse_json_response(response, "riot_geo").await?; + + println!("[API] Riot Geo affinity: live={}", geo.affinities.live); + + let result = match geo.affinities.live.as_str() { + "na" => (Region::NA, Shard::NA), + "eu" => (Region::EU, Shard::EU), + "ap" => (Region::AP, Shard::AP), + "kr" => (Region::KO, Shard::KR), + "latam" => (Region::LATAM, Shard::NA), + "br" => (Region::BR, Shard::NA), + other => return Err(format!("Unknown region affinity: {}", other)), + }; + + println!("[API] Mapped to region {:?}, shard {:?}", result.0, result.1); + + let mut cache_lock = cache.write().await; + cache_lock.insert(user_id.to_string(), result.clone()); + + Ok(Some(result)) +} + +async fn get_player_info( + user_id: &str, + access_token: &str, + entitlements_token: &str, + riot_client_version: &str, + region: &Region, +) -> Result { + let client = create_http_client().map_err(|e| e.to_string())?; + + let url = format!( + "{}/name-service/v2/players", + get_player_data_service_url(region) + ); + + println!("[API] PUT {} (get_player_info)", url); + + let response = client + .put(&url) + .header("Authorization", format!("Bearer {}", access_token)) + .header("X-Riot-Entitlements-JWT", entitlements_token) + .header("X-Riot-ClientVersion", riot_client_version) + .header("X-Riot-ClientPlatform", create_client_platform_header()) + .json(&vec![user_id]) + .send() + .await + .map_err(|e| { + eprintln!("[API] get_player_info request failed: {}", e); + e.to_string() + })?; + + let players: Vec = parse_json_response(response, "get_player_info").await?; + + let player = players.into_iter().next().ok_or_else(|| { + eprintln!("[API] get_player_info returned empty array"); + "No player data returned".to_string() + })?; + + println!( + "[API] Got player info: {}#{}", + player.game_name, player.tag_line + ); + + Ok(PlayerInfo { + display_name: player.display_name, + game_name: player.game_name, + tag_line: player.tag_line, + }) +} + +pub async fn invalidate_user_cache(user_cache: &UserDataCache) { + let mut cached = user_cache.write().await; + *cached = None; +} + +pub async fn get_user( + region_cache: &RegionShardCache, + user_cache: &UserDataCache, +) -> Result, String> { + { + let cached = user_cache.read().await; + if let Some((ref data, ref cached_at)) = *cached { + if cached_at.elapsed() < USER_CACHE_TTL { + println!("[API] get_user: cache hit for {}#{} (age: {:?})", data.player_info.game_name, data.player_info.tag_line, cached_at.elapsed()); + return Ok(Some(data.clone())); + } + println!("[API] get_user: cache expired for {}#{} (age: {:?})", data.player_info.game_name, data.player_info.tag_line, cached_at.elapsed()); + } + } + + let total_start = std::time::Instant::now(); + println!("[API] get_user: cache miss, fetching..."); + + let t = std::time::Instant::now(); + let lockfile = match get_lockfile().await? { + Some(lf) => { + println!("[API] get_user: Found lockfile on port {} ({:?})", lf.port, t.elapsed()); + lf + } + None => { + println!("[API] get_user: No lockfile found ({:?})", t.elapsed()); + return Ok(None); + } + }; + + let t = std::time::Instant::now(); + let riot_client_version = get_riot_client_version().await?; + println!("[API] get_user: got riot_client_version ({:?})", t.elapsed()); + + let client = create_local_http_client().map_err(|e| e.to_string())?; + + let auth = format!("riot:{}", lockfile.password); + let auth_header = format!("Basic {}", general_purpose::STANDARD.encode(&auth)); + + let url = format!("https://127.0.0.1:{}/entitlements/v1/token", lockfile.port); + + let t = std::time::Instant::now(); + let response = match client + .get(&url) + .header("Authorization", auth_header) + .send() + .await + { + Ok(resp) => resp, + Err(e) => { + eprintln!("[API] get_user local token request failed: {}", e); + return Ok(None); + } + }; + + if response.status() == reqwest::StatusCode::NOT_FOUND { + println!("[API] get_user: local token endpoint returned 404 (Valorant not running)"); + return Ok(None); + } + + let tokens: LocalTokenResponse = + parse_json_response(response, "get_user (local token)").await?; + println!("[API] get_user: Got tokens for user {} ({:?})", tokens.subject, t.elapsed()); + + let t = std::time::Instant::now(); + let id_token = get_id_token(&lockfile).await?; + println!("[API] get_user: got id_token ({:?})", t.elapsed()); + + let t = std::time::Instant::now(); + let region_shard = match detect_region_shard( + &tokens.subject, + &tokens.access_token, + &id_token, + region_cache, + ) + .await? + { + Some(rs) => { + println!("[API] get_user: detect_region_shard ({:?})", t.elapsed()); + rs + } + None => { + println!("[API] get_user: Could not detect region/shard ({:?})", t.elapsed()); + return Ok(None); + } + }; + + let t = std::time::Instant::now(); + let player_info = get_player_info( + &tokens.subject, + &tokens.access_token, + &tokens.token, + &riot_client_version, + ®ion_shard.0, + ) + .await?; + println!("[API] get_user: get_player_info ({:?})", t.elapsed()); + + let user_data = UserData { + access_token: tokens.access_token, + entitlements_token: tokens.token, + user_id: tokens.subject, + region: region_shard.0, + shard: region_shard.1, + riot_client_version, + player_info, + }; + + println!( + "[API] get_user: TOTAL {:?} for {}#{}", + total_start.elapsed(), user_data.player_info.game_name, user_data.player_info.tag_line + ); + + { + let mut cached = user_cache.write().await; + *cached = Some((user_data.clone(), std::time::Instant::now())); + } + + Ok(Some(user_data)) +} + +pub async fn get_loadout(user: &UserData) -> Result { + let client = create_http_client().map_err(|e| e.to_string())?; + + let url = format!( + "{}/personalization/v3/players/{}/playerloadout", + get_player_data_service_url(&user.region), + user.user_id + ); + + println!("[API] GET {} (get_loadout)", url); + + let response = client + .get(&url) + .header("Authorization", format!("Bearer {}", user.access_token)) + .header("X-Riot-Entitlements-JWT", &user.entitlements_token) + .header("X-Riot-ClientVersion", &user.riot_client_version) + .header("X-Riot-ClientPlatform", create_client_platform_header()) + .send() + .await + .map_err(|e| { + eprintln!("[API] get_loadout request failed: {}", e); + e.to_string() + })?; + + let loadout: ValorantLoadout = parse_json_response(response, "get_loadout").await?; + println!( + "[API] get_loadout: Got loadout with {} guns", + loadout.guns.len() + ); + Ok(loadout) +} + +pub async fn get_entitlements(user: &UserData) -> Result { + let client = create_http_client().map_err(|e| e.to_string())?; + + let url = format!( + "{}/store/v1/entitlements/{}", + get_player_data_service_url(&user.region), + user.user_id + ); + + println!("[API] GET {} (get_entitlements)", url); + + let response = client + .get(&url) + .header("Authorization", format!("Bearer {}", user.access_token)) + .header("X-Riot-Entitlements-JWT", &user.entitlements_token) + .header("X-Riot-ClientVersion", &user.riot_client_version) + .header("X-Riot-ClientPlatform", create_client_platform_header()) + .send() + .await + .map_err(|e| { + eprintln!("[API] get_entitlements request failed: {}", e); + e.to_string() + })?; + + let entitlements: EntitlementsResponse = + parse_json_response(response, "get_entitlements").await?; + + let total_items: usize = entitlements + .entitlements_by_types + .iter() + .map(|t| t.entitlements.len()) + .sum(); + println!( + "[API] get_entitlements: Got {} types with {} total items", + entitlements.entitlements_by_types.len(), + total_items + ); + + Ok(entitlements) +} + +pub async fn equip_loadout(user: &UserData, loadout: ValorantLoadout) -> Result<(), String> { + let client = create_http_client().map_err(|e| e.to_string())?; + + let url = format!( + "{}/personalization/v3/players/{}/playerloadout", + get_player_data_service_url(&user.region), + user.user_id + ); + + println!("[API] PUT {} (equip_loadout)", url); + + let request_body = serde_json::to_string(&loadout).unwrap_or_else(|e| { + eprintln!("[API] equip_loadout: Failed to serialize loadout: {}", e); + "{}".to_string() + }); + println!( + "[API] equip_loadout request body: {}", + log_response_preview(&request_body, 500) + ); + + let response = client + .put(&url) + .header("Authorization", format!("Bearer {}", user.access_token)) + .header("X-Riot-Entitlements-JWT", &user.entitlements_token) + .header("X-Riot-ClientVersion", &user.riot_client_version) + .header("X-Riot-ClientPlatform", create_client_platform_header()) + .json(&loadout) + .send() + .await + .map_err(|e| { + eprintln!("[API] equip_loadout request failed: {}", e); + e.to_string() + })?; + + let status = response.status(); + let body = response.text().await.unwrap_or_default(); + + println!( + "[API] equip_loadout response ({}): {}", + status, + log_response_preview(&body, 500) + ); + + if !status.is_success() { + eprintln!("[API] equip_loadout failed ({}): {}", status, body); + return Err(format!( + "Failed to equip loadout ({}): {}", + status, + log_response_preview(&body, 200) + )); + } + + println!("[API] equip_loadout: Success!"); + Ok(()) +} diff --git a/src-tauri/src/valorant_data.rs b/src-tauri/src/valorant_data.rs new file mode 100644 index 0000000..ebf7109 --- /dev/null +++ b/src-tauri/src/valorant_data.rs @@ -0,0 +1,271 @@ +use reqwest::Client; +use serde::{Deserialize, Serialize}; +use std::sync::Arc; +use tokio::sync::RwLock; + +const BASE_URL: &str = "https://valorant-api.com/v1"; + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SkinChroma { + pub uuid: String, + pub display_name: String, + pub display_icon: Option, + pub full_render: String, + pub swatch: Option, + pub streamed_video: Option, + pub asset_path: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SkinLevel { + pub uuid: String, + pub display_name: String, + pub level_item: Option, + pub display_icon: Option, + pub streamed_video: Option, + pub asset_path: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Skin { + pub uuid: String, + pub display_name: String, + pub theme_uuid: Option, + pub content_tier_uuid: Option, + pub display_icon: Option, + pub wallpaper: Option, + pub asset_path: String, + pub chromas: Vec, + pub levels: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Weapon { + pub uuid: String, + pub display_name: String, + pub category: String, + pub default_skin_uuid: String, + pub display_icon: String, + pub kill_stream_icon: String, + pub asset_path: String, + pub skins: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct BuddyLevel { + pub uuid: String, + pub charm_level: u32, + pub display_name: String, + pub display_icon: String, + pub asset_path: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Buddy { + pub uuid: String, + pub display_name: String, + pub is_hidden_if_not_owned: bool, + pub theme_uuid: Option, + pub display_icon: String, + pub asset_path: String, + pub levels: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PlayerCard { + pub uuid: String, + pub display_name: String, + pub is_hidden_if_not_owned: bool, + pub theme_uuid: Option, + pub display_icon: String, + pub small_art: String, + pub wide_art: String, + pub large_art: Option, + pub asset_path: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SprayLevel { + pub uuid: String, + pub spray_level: u32, + pub display_name: String, + pub display_icon: Option, + pub asset_path: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Spray { + pub uuid: String, + pub display_name: String, + pub category: Option, + pub theme_uuid: Option, + pub display_icon: String, + pub full_icon: Option, + pub full_transparent_icon: Option, + pub animation_png: Option, + pub animation_gif: Option, + pub asset_path: String, + pub levels: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Flex { + pub uuid: String, + pub display_name: String, + pub display_icon: String, + pub asset_path: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PlayerTitle { + pub uuid: String, + pub display_name: Option, + pub title_text: Option, + pub is_hidden_if_not_owned: bool, + pub asset_path: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Role { + pub uuid: String, + pub display_name: String, + pub description: String, + pub display_icon: String, + pub asset_path: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Ability { + pub slot: String, + pub display_name: String, + pub description: String, + pub display_icon: Option, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Agent { + pub uuid: String, + pub display_name: String, + pub description: String, + pub developer_name: String, + pub character_tags: Option>, + pub display_icon: String, + pub display_icon_small: String, + pub bust_portrait: String, + pub full_portrait: String, + pub full_portrait_v2: String, + pub killfeed_portrait: String, + pub background: String, + pub background_gradient_colors: Option>, + pub asset_path: String, + pub is_full_portrait_right_facing: bool, + pub is_playable_character: bool, + pub is_available_for_test: bool, + pub is_base_content: bool, + pub role: Option, + pub abilities: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ValorantData { + pub weapons: Vec, + pub buddies: Vec, + #[serde(rename = "playerCards")] + pub player_cards: Vec, + pub sprays: Vec, + #[serde(rename = "playerTitles")] + pub player_titles: Vec, + pub agents: Vec, + pub flex: Vec, +} + +pub type ValorantDataCache = Arc>>; + +#[derive(Deserialize)] +struct ApiResponse { + data: T, +} + +fn json_context_at(body: &str, column: usize) -> String { + let start = column.saturating_sub(120); + let end = (column + 60).min(body.len()); + let snippet = &body[start..end]; + let pointer = column - start; + format!("...{}...\n {}^", snippet, " ".repeat(pointer)) +} + +async fn fetch_data( + client: &Client, + endpoint: &str, +) -> Result { + let url = format!("{}{}", BASE_URL, endpoint); + let resp = client + .get(&url) + .send() + .await + .map_err(|e| format!("Failed to fetch {}: {}", endpoint, e))?; + + let body = resp + .text() + .await + .map_err(|e| format!("Failed to read body from {}: {}", endpoint, e))?; + + let api_resp: ApiResponse = serde_json::from_str(&body).map_err(|e| { + let context = json_context_at(&body, e.column().saturating_sub(1)); + format!( + "Failed to parse {}: {}\n\nContext:\n{}", + endpoint, e, context + ) + })?; + + Ok(api_resp.data) +} + +pub async fn get_valorant_data(cache: &ValorantDataCache) -> Result { + { + let read = cache.read().await; + if let Some(data) = read.as_ref() { + return Ok(data.clone()); + } + } + + let client = Client::new(); + let (weapons, buddies, player_cards, sprays, player_titles, agents, flex) = tokio::try_join!( + fetch_data::>(&client, "/weapons"), + fetch_data::>(&client, "/buddies"), + fetch_data::>(&client, "/playercards"), + fetch_data::>(&client, "/sprays"), + fetch_data::>(&client, "/playertitles"), + fetch_data::>(&client, "/agents?isPlayableCharacter=true"), + fetch_data::>(&client, "/flex"), + )?; + + let data = ValorantData { + weapons, + buddies, + player_cards, + sprays, + player_titles, + agents, + flex, + }; + + let mut write = cache.write().await; + *write = Some(data.clone()); + + Ok(data) +} diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json new file mode 100644 index 0000000..a6c2a42 --- /dev/null +++ b/src-tauri/tauri.conf.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://schema.tauri.app/config/2", + "productName": "valpal", + "version": "0.1.0", + "identifier": "net.zachrip.valpal", + "build": { + "beforeDevCommand": "pnpm dev", + "devUrl": "http://localhost:1420", + "beforeBuildCommand": "pnpm build:frontend", + "frontendDist": "../dist/client" + }, + "app": { + "windows": [ + { + "title": "valpal", + "width": 800, + "height": 600 + } + ], + "security": { + "csp": null + } + }, + "bundle": { + "active": true, + "targets": "msi", + "icon": [ + "icons/32x32.png", + "icons/128x128.png", + "icons/128x128@2x.png", + "icons/icon.icns", + "icons/icon.ico" + ] + } +} \ No newline at end of file diff --git a/src/apiClient.ts b/src/apiClient.ts new file mode 100644 index 0000000..b4c1cf5 --- /dev/null +++ b/src/apiClient.ts @@ -0,0 +1,187 @@ +import { invoke } from "@tauri-apps/api/core"; + +export type Region = "AP" | "EU" | "KO" | "NA" | "LATAM" | "BR"; +export type Shard = "NA" | "EU" | "AP" | "KR" | "PBE"; + +export interface Gun { + ID: string; + SkinID: string; + SkinLevelID: string; + ChromaID: string; + CharmInstanceID?: string; + CharmID?: string; + CharmLevelID?: string; + Attachments: unknown[]; +} + +export interface ActiveExpression { + TypeID: string; + AssetID: string; +} + +export interface Identity { + PlayerCardID: string; + PlayerTitleID: string; + AccountLevel: number; + PreferredLevelBorderID: string; + HideAccountLevel: boolean; +} + +export interface ValorantLoadout { + Subject: string; + Version: number; + Guns: Gun[]; + ActiveExpressions: ActiveExpression[]; + Identity: Identity; + Incognito: boolean; +} + +export interface PlayerInfo { + display_name: string; + game_name: string; + tag_line: string; +} + +export interface UserData { + access_token: string; + entitlements_token: string; + user_id: string; + region: Region; + shard: Shard; + riot_client_version: string; + player_info: PlayerInfo; +} + +export interface Entitlement { + TypeID: string; + ItemID: string; + InstanceID?: string; +} + +export interface EntitlementsByType { + ItemTypeID: string; + Entitlements: Entitlement[]; +} + +export interface EntitlementsResponse { + EntitlementsByTypes: EntitlementsByType[]; +} + +export interface BuddyTemplate { + id: string; + levelIds: string[]; +} + +export interface WeaponTemplate { + id: string; + skinId: string; + levelIds: string[]; + chromaIds: string[]; + buddies: BuddyTemplate[]; +} + +export interface WeaponConfig { + templates: WeaponTemplate[]; +} + +export interface ExpressionSlot { + sprayIds: string[]; + flexIds: string[]; +} + +export interface ExpressionIds { + top: ExpressionSlot; + right: ExpressionSlot; + bottom: ExpressionSlot; + left: ExpressionSlot; +} + +export interface Loadout { + id: string; + name: string; + enabled: boolean; + agentIds: string[]; + weapons: Record; + playerCardIds: string[]; + playerTitleIds: string[]; + expressionIds: ExpressionIds; +} + +export interface UserConfig { + version: number; + loadouts: Loadout[]; +} + +export async function getUser(): Promise { + return invoke("get_user"); +} + +export async function getLoadout(): Promise { + return invoke("get_loadout"); +} + +export async function getEntitlements(): Promise { + return invoke("get_entitlements"); +} + +export async function equipLoadout(loadout: ValorantLoadout): Promise { + return invoke("equip_loadout", { loadout }); +} + +export async function getUserConfig(): Promise { + return invoke("get_user_config"); +} + +export async function saveUserConfig(config: UserConfig): Promise { + return invoke("save_user_config", { config }); +} + +export async function createLoadout(loadout: Loadout): Promise { + return invoke("create_loadout", { loadout }); +} + +export async function updateLoadout(loadout: Loadout): Promise { + return invoke("update_loadout", { loadout }); +} + +export async function deleteLoadout(loadoutId: string): Promise { + return invoke("delete_loadout", { loadoutId }); +} + +export async function saveInGameLoadout(name: string): Promise { + return invoke("save_in_game_loadout", { name }); +} + +export async function getValorantStatus(): Promise { + return invoke("get_valorant_status"); +} + +export interface ShuffleSettings { + autoShuffleEnabled: boolean; + agentDetectionEnabled: boolean; + nonPregameShuffleEnabled: boolean; +} + +export async function getShuffleSettings(): Promise { + return invoke("get_shuffle_settings"); +} + +export async function setAutoShuffleEnabled(enabled: boolean): Promise { + return invoke("set_auto_shuffle_enabled", { enabled }); +} + +export async function setAgentDetectionEnabled( + enabled: boolean, +): Promise { + return invoke("set_agent_detection_enabled", { enabled }); +} + +export async function setNonPregameShuffleEnabled( + enabled: boolean, +): Promise { + return invoke("set_non_pregame_shuffle_enabled", { enabled }); +} + +export async function equipLoadoutById(loadoutId: string): Promise { + return invoke("equip_loadout_by_id", { loadoutId }); +} diff --git a/src/app.css b/src/app.css new file mode 100644 index 0000000..a194a81 --- /dev/null +++ b/src/app.css @@ -0,0 +1,12 @@ +@import "tailwindcss"; + +@theme { + --font-sans: "Inter", ui-sans-serif, system-ui, sans-serif, + "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; +} + +html, +body { + @apply bg-slate-800; + color-scheme: dark; +} diff --git a/app/components/Gallery.tsx b/src/components/Gallery.tsx similarity index 78% rename from app/components/Gallery.tsx rename to src/components/Gallery.tsx index 5f05065..52d7c51 100644 --- a/app/components/Gallery.tsx +++ b/src/components/Gallery.tsx @@ -1,12 +1,11 @@ -import type { ReactNode } from 'react'; -import { useEffect, useState } from 'react'; +import { useEffect, useState } from "react"; export const Gallery = >({ items, render, }: { items: T; - render: (data: T[number]) => JSX.Element; + render: (data: T[number]) => React.ReactNode; }) => { const [selectedElement, setSelectedElement] = useState(0); diff --git a/app/components/SwitchImage.tsx b/src/components/SwitchImage.tsx similarity index 87% rename from app/components/SwitchImage.tsx rename to src/components/SwitchImage.tsx index 58ef50b..a98f6c8 100644 --- a/app/components/SwitchImage.tsx +++ b/src/components/SwitchImage.tsx @@ -1,5 +1,5 @@ -import type { FunctionComponent } from 'react'; -import { useEffect, useState } from 'react'; +import type { FunctionComponent } from "react"; +import { useEffect, useState } from "react"; export const SwitchImage: FunctionComponent< { diff --git a/src/root.tsx b/src/root.tsx new file mode 100644 index 0000000..ca4f7df --- /dev/null +++ b/src/root.tsx @@ -0,0 +1,77 @@ +import { + isRouteErrorResponse, + Links, + Meta, + Outlet, + Scripts, + ScrollRestoration, +} from "react-router"; + +import type { Route } from "./+types/root"; +import "./app.css"; + +export const links: Route.LinksFunction = () => [ + { rel: "preconnect", href: "https://fonts.googleapis.com" }, + { + rel: "preconnect", + href: "https://fonts.gstatic.com", + crossOrigin: "anonymous", + }, + { + rel: "stylesheet", + href: "https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap", + }, +]; + +export function Layout({ children }: { children: React.ReactNode }) { + return ( + + + + + + + + + {children} + + + + + ); +} + +export default function App() { + return ; +} + +export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) { + let message = "Oops!"; + let details = "An unexpected error occurred."; + let stack: string | undefined; + + console.error(error); + + if (isRouteErrorResponse(error)) { + message = error.status === 404 ? "404" : "Error"; + details = + error.status === 404 + ? "The requested page could not be found." + : error.statusText || details; + } else if (import.meta.env.DEV && error && error instanceof Error) { + details = error.message; + stack = error.stack; + } + + return ( +
+

{message}

+

{details}

+ {stack && ( +
+					{stack}
+				
+ )} +
+ ); +} diff --git a/src/routes.ts b/src/routes.ts new file mode 100644 index 0000000..0c9e093 --- /dev/null +++ b/src/routes.ts @@ -0,0 +1,24 @@ +import { + index, + layout, + type RouteConfig, + route, +} from "@react-router/dev/routes"; + +export default [ + layout("routes/app/layout.tsx", [ + index("routes/app/index.tsx"), + route("loadouts", "routes/app/loadouts/layout.tsx", [ + index("routes/app/loadouts/index.tsx"), + route("new", "routes/app/loadouts/new.tsx"), + route(":loadoutId", "routes/app/loadouts/detail.tsx", [ + route("weapons/:weaponId", "routes/app/loadouts/weapon.tsx", [ + route("new", "routes/app/loadouts/weapon-new.tsx"), + ]), + route("playercards", "routes/app/loadouts/playercards.tsx"), + route("playertitles", "routes/app/loadouts/playertitles.tsx"), + route("expressions/:slot", "routes/app/loadouts/expressions.tsx"), + ]), + ]), + ]), +] satisfies RouteConfig; diff --git a/src/routes/app/index.tsx b/src/routes/app/index.tsx new file mode 100644 index 0000000..2df4524 --- /dev/null +++ b/src/routes/app/index.tsx @@ -0,0 +1,560 @@ +import { listen } from "@tauri-apps/api/event"; +import { useEffect } from "react"; +import { Form, Link, redirect, useFetcher, useRevalidator } from "react-router"; +import type { ShuffleSettings } from "~/apiClient"; +import * as api from "~/apiClient"; +import { Gallery } from "~/components/Gallery"; +import { SwitchImage } from "~/components/SwitchImage"; +import { weaponUuidToIndex } from "~/types"; +import { getValorantData } from "~/valorant-data"; +import valpalLogo from "~/valpal.png"; +import type { Route } from "./+types/index"; + +export async function clientLoader() { + const [valorantData, user, shuffleSettings] = await Promise.all([ + getValorantData(), + api.getUser(), + api.getShuffleSettings(), + ]); + + if (!user) { + return { user: null, currentLoadout: null, loadouts: [], shuffleSettings }; + } + + let userConfig: api.UserConfig; + let inGameLoadout: api.ValorantLoadout; + try { + [userConfig, inGameLoadout] = await Promise.all([ + api.getUserConfig(), + api.getLoadout(), + ]); + } catch { + return { user: null, currentLoadout: null, loadouts: [], shuffleSettings }; + } + + const currentLoadout = { + playerCard: valorantData.playerCards.find( + (c) => c.uuid === inGameLoadout.Identity.PlayerCardID, + ), + playerTitle: valorantData.playerTitles.find( + (t) => t.uuid === inGameLoadout.Identity.PlayerTitleID, + ), + weapons: inGameLoadout.Guns.map((gun) => { + const weapon = valorantData.weapons.find((w) => w.uuid === gun.ID); + const skin = weapon?.skins.find((s) => s.uuid === gun.SkinID); + const chroma = skin?.chromas.find((c) => c.uuid === gun.ChromaID); + return { + weapon, + templates: chroma ? [{ skin, chromas: [chroma] }] : [], + }; + }).sort((a, b) => { + const indexA = weaponUuidToIndex[a.weapon?.uuid ?? ""] ?? 999; + const indexB = weaponUuidToIndex[b.weapon?.uuid ?? ""] ?? 999; + return indexA - indexB; + }), + }; + + const loadouts = userConfig.loadouts + .sort((a, b) => { + if (a.enabled === b.enabled) { + return a.name.localeCompare(b.name); + } + return a.enabled ? -1 : 1; + }) + .map((loadout) => { + const defaultSpray = "0a6db78c-48b9-a32d-c47a-82be597584c1"; + const defaultFlex = "af52b5a0-4a4c-03b2-c9d7-8187a08a2675"; + + const findSprays = (ids: string[]) => + ids.flatMap((id) => { + const s = valorantData.sprays.find((spray) => spray.uuid === id); + return s ? [s] : []; + }); + const findFlex = (ids: string[]) => + ids.flatMap((id) => { + const f = valorantData.flex.find((flex) => flex.uuid === id); + return f ? [f] : []; + }); + const resolveSlotSprays = (slot: api.ExpressionSlot) => + findSprays( + slot.sprayIds.length || slot.flexIds.length + ? slot.sprayIds + : [defaultSpray], + ); + const resolveSlotFlex = (slot: api.ExpressionSlot) => + findFlex( + slot.flexIds.length || slot.sprayIds.length + ? slot.flexIds + : [defaultFlex], + ); + + return { + ...loadout, + agents: loadout.agentIds + .map((id) => valorantData.agents.find((a) => a.uuid === id)) + .filter((a) => a !== undefined) + .sort((a, b) => + (a.displayName ?? "").localeCompare(b.displayName ?? ""), + ), + playerCards: (loadout.playerCardIds.length + ? loadout.playerCardIds + : ["9fb348bc-41a0-91ad-8a3e-818035c4e561"] + ) + .map((id) => valorantData.playerCards.find((c) => c.uuid === id)) + .filter(Boolean), + playerTitles: (loadout.playerTitleIds.length + ? loadout.playerTitleIds + : ["d13e579c-435e-44d4-cec2-6eae5a3c5ed4"] + ) + .map((id) => valorantData.playerTitles.find((t) => t.uuid === id)) + .filter(Boolean), + expressions: { + top: { + sprays: resolveSlotSprays(loadout.expressionIds.top), + flexes: findFlex(loadout.expressionIds.top.flexIds), + }, + right: { + sprays: resolveSlotSprays(loadout.expressionIds.right), + flexes: findFlex(loadout.expressionIds.right.flexIds), + }, + bottom: { + sprays: resolveSlotSprays(loadout.expressionIds.bottom), + flexes: findFlex(loadout.expressionIds.bottom.flexIds), + }, + left: { + sprays: findSprays(loadout.expressionIds.left.sprayIds), + flexes: resolveSlotFlex(loadout.expressionIds.left), + }, + }, + weapons: valorantData.weapons + .slice() + .sort((a, b) => { + const indexA = weaponUuidToIndex[a.uuid] ?? 999; + const indexB = weaponUuidToIndex[b.uuid] ?? 999; + return indexA - indexB; + }) + .map((weapon) => { + const config = loadout.weapons[weapon.uuid]; + const templates = (config?.templates || []).map((template) => { + const skin = weapon.skins.find((s) => s.uuid === template.skinId); + const chromas = + skin?.chromas.filter((c) => + template.chromaIds.includes(c.uuid), + ) || []; + return { skin, chromas }; + }); + + return { weapon, templates }; + }), + }; + }); + + return { user, currentLoadout, loadouts, shuffleSettings }; +} + +export async function clientAction({ request }: Route.ClientActionArgs) { + const formData = await request.formData(); + const intent = formData.get("intent"); + + if (intent === "delete") { + const loadoutId = formData.get("loadoutId") as string; + await api.deleteLoadout(loadoutId); + return redirect("/"); + } + + if (intent === "saveInGame") { + await api.saveInGameLoadout("In-Game Loadout"); + return redirect("/"); + } + + if (intent === "setAutoShuffle") { + await api.setAutoShuffleEnabled(formData.get("enabled") === "true"); + return { ok: true }; + } + + if (intent === "setAgentDetection") { + await api.setAgentDetectionEnabled(formData.get("enabled") === "true"); + return { ok: true }; + } + + if (intent === "setNonPregameShuffle") { + await api.setNonPregameShuffleEnabled(formData.get("enabled") === "true"); + return { ok: true }; + } + + if (intent === "equip") { + const loadoutId = formData.get("loadoutId") as string; + await api.equipLoadoutById(loadoutId); + return { ok: true }; + } + + throw new Error(`Unknown intent: ${intent}`); +} + +const buttonStyles = + "cursor-pointer text-white px-3 py-2 border-2 border-white rounded-md hover:bg-white hover:text-slate-800 transition-colors"; + +function Toggle({ + fetcher, + checked, + intent, + label, + disabled, +}: { + fetcher: ReturnType; + checked: boolean; + intent: string; + label: string; + disabled?: boolean; +}) { + const optimistic = fetcher.formData + ? fetcher.formData.get("enabled") === "true" + : checked; + + return ( + + + + + + ); +} + +export default function Index({ loaderData }: Route.ComponentProps) { + const { user, currentLoadout, loadouts, shuffleSettings } = loaderData; + + const autoShuffleFetcher = useFetcher(); + const agentDetectionFetcher = useFetcher(); + const nonPregameShuffleFetcher = useFetcher(); + const revalidator = useRevalidator(); + + const autoShuffleOn = autoShuffleFetcher.formData + ? autoShuffleFetcher.formData.get("enabled") === "true" + : shuffleSettings.autoShuffleEnabled; + + useEffect(() => { + const unlistenShuffle = listen("shuffle-settings-changed", () => { + revalidator.revalidate(); + }); + const unlistenStatus = listen("valorant-status", () => { + revalidator.revalidate(); + }); + + return () => { + unlistenShuffle.then((fn) => fn()); + unlistenStatus.then((fn) => fn()); + }; + }, [revalidator]); + + if (!user) { + return ( +
+
+ ValPal Logo +
+

+ Waiting for Valorant... +

+
+ ); + } + + return ( +
+
+

+ {user?.player_info.game_name} + + #{user?.player_info.tag_line} + +

+
+ + New Loadout + + + +
+
+
+ + + +
+
+

+ Currently Equipped + + (In-Game) + +

+ +
+
+
+ {currentLoadout.playerCard && ( + {currentLoadout.playerCard.displayName + )} +
+

+ {currentLoadout.playerTitle?.titleText || "Default"} +

+
+
+ {currentLoadout.weapons.map((weapon) => ( +
+ {weapon?.templates?.[0]?.chromas?.[0] ? ( + {weapon.templates[0].skin?.displayName + ) : ( + {weapon?.weapon?.displayName + )} + + {weapon?.weapon?.displayName} + +
+ ))} +
+
+
+ + +
+
+
+

+ Saved Loadouts +

+
+
+
+ {loadouts.map((loadout) => ( +
+

+ {loadout.name} + {!loadout.enabled && ( + (Disabled) + )} +
+ {loadout.agents.map((agent) => ( +
+ {agent?.displayName +
+ ))} +
+

+
+
+
+ ({ + src: c?.largeArt ?? "", + alt: c?.displayName ?? "", + }))} + /> +
+ ({ + ...t, + duration: 1000, + }))} + render={(title) => ( +

+ {title?.titleText || "Default"} +

+ )} + /> +
+ {Object.entries(loadout.expressions).map(([key, exps]) => ( +
+ ({ + icon: + spray.animationGif ?? + spray.fullTransparentIcon ?? + spray.displayIcon ?? + "", + displayName: spray.displayName ?? "", + duration: 1000, + })), + ...exps.flexes.map((flex) => ({ + icon: flex.displayIcon ?? "", + displayName: flex.displayName ?? "", + duration: 1000, + })), + ]} + render={(expression) => ( + {expression.displayName + )} + /> +
+ ))} +
+
+
+ {loadout.weapons.map((weapon) => ( +
+ {weapon?.templates?.[0]?.chromas?.[0] ? ( + {weapon.templates[0].skin?.displayName + ) : ( + {weapon?.weapon?.displayName + )} + + {weapon?.weapon?.displayName} + +
+ ))} +
+
+
+
+ + + +
+ + Edit + +
{ + if ( + !confirm("Are you sure you want to delete this loadout?") + ) { + e.preventDefault(); + } + }} + > + + + +
+
+
+ ))} + {loadouts.length === 0 && ( +
+

No loadouts yet.

+

+ Create a new loadout or save your current in-game loadout to get + started. +

+
+ )} +
+
+ ); +} diff --git a/src/routes/app/layout.tsx b/src/routes/app/layout.tsx new file mode 100644 index 0000000..e919ab1 --- /dev/null +++ b/src/routes/app/layout.tsx @@ -0,0 +1,40 @@ +import { listen } from "@tauri-apps/api/event"; +import { useEffect, useState } from "react"; +import { Outlet, useRevalidator } from "react-router"; +import * as api from "~/apiClient"; +import valpalLogo from "~/valpal.png"; + +export default function Layout() { + const [connected, setConnected] = useState(null); + const revalidator = useRevalidator(); + + useEffect(() => { + api.getValorantStatus().then(setConnected); + + const unlisten = listen("valorant-status", (event) => { + setConnected(event.payload); + if (event.payload) { + revalidator.revalidate(); + } + }); + + return () => { + unlisten.then((fn) => fn()); + }; + }, [revalidator]); + + if (!connected) { + return ( +
+
+ ValPal Logo +
+

+ Waiting for Valorant... +

+
+ ); + } + + return ; +} diff --git a/src/routes/app/loadouts/detail.tsx b/src/routes/app/loadouts/detail.tsx new file mode 100644 index 0000000..441f0a7 --- /dev/null +++ b/src/routes/app/loadouts/detail.tsx @@ -0,0 +1,443 @@ +import { useEffect, useState } from "react"; +import { Link, Outlet } from "react-router"; +import type { Loadout } from "~/apiClient"; +import * as api from "~/apiClient"; +import { Gallery } from "~/components/Gallery"; +import { weaponUuidToIndex } from "~/types"; +import { getValorantData } from "~/valorant-data"; +import type { Route } from "./+types/detail"; + +type WeaponGalleryItem = { + chroma: { icon: string; name: string }; + buddy: { icon: string; name: string } | null; + duration: number; +}; + +export async function clientLoader({ params }: Route.ClientLoaderArgs) { + const [valorantData, userConfig] = await Promise.all([ + getValorantData(), + api.getUserConfig(), + ]); + + const loadout = userConfig.loadouts.find((l) => l.id === params.loadoutId); + if (!loadout) { + throw new Error("Loadout not found"); + } + + return { valorantData, loadout }; +} + +export default function LoadoutDetailComponent({ + loaderData, +}: Route.ComponentProps) { + const { valorantData, loadout: initialLoadout } = loaderData; + const [loadout, setLoadout] = useState(initialLoadout); + + useEffect(() => { + setLoadout(initialLoadout); + }, [initialLoadout]); + + const toggleAgent = (agentId: string) => { + const newLoadout = { + ...loadout, + agentIds: loadout.agentIds.includes(agentId) + ? loadout.agentIds.filter((id) => id !== agentId) + : [...loadout.agentIds, agentId], + }; + setLoadout(newLoadout); + api.updateLoadout(newLoadout); + }; + + const findCards = (ids: string[]) => + ids.flatMap((id) => { + const c = valorantData.playerCards.find((card) => card.uuid === id); + return c ? [c] : []; + }); + const findTitles = (ids: string[]) => + ids.flatMap((id) => { + const t = valorantData.playerTitles.find((title) => title.uuid === id); + return t ? [t] : []; + }); + const findSprays = (ids: string[]) => + ids.flatMap((id) => { + const s = valorantData.sprays.find((spray) => spray.uuid === id); + return s ? [s] : []; + }); + const findFlex = (ids: string[]) => + ids.flatMap((id) => { + const f = valorantData.flex.find((flex) => flex.uuid === id); + return f ? [f] : []; + }); + + const playerCards = findCards( + loadout.playerCardIds.length + ? loadout.playerCardIds + : ["9fb348bc-41a0-91ad-8a3e-818035c4e561"], + ); + + const playerTitles = findTitles( + loadout.playerTitleIds.length + ? loadout.playerTitleIds + : ["d13e579c-435e-44d4-cec2-6eae5a3c5ed4"], + ); + + const resolveSlotSprays = ( + slot: api.ExpressionSlot, + defaultSprayId: string, + ) => + findSprays( + slot.sprayIds.length || slot.flexIds.length + ? slot.sprayIds + : [defaultSprayId], + ); + const resolveSlotFlex = (slot: api.ExpressionSlot, defaultFlexId: string) => + findFlex( + slot.flexIds.length || slot.sprayIds.length + ? slot.flexIds + : [defaultFlexId], + ); + + const defaultSpray = "0a6db78c-48b9-a32d-c47a-82be597584c1"; + const defaultFlex = "af52b5a0-4a4c-03b2-c9d7-8187a08a2675"; + + const expressions = { + top: { + sprays: resolveSlotSprays(loadout.expressionIds.top, defaultSpray), + flexes: findFlex(loadout.expressionIds.top.flexIds), + }, + right: { + sprays: resolveSlotSprays(loadout.expressionIds.right, defaultSpray), + flexes: findFlex(loadout.expressionIds.right.flexIds), + }, + bottom: { + sprays: resolveSlotSprays(loadout.expressionIds.bottom, defaultSpray), + flexes: findFlex(loadout.expressionIds.bottom.flexIds), + }, + left: { + sprays: findSprays(loadout.expressionIds.left.sprayIds), + flexes: resolveSlotFlex(loadout.expressionIds.left, defaultFlex), + }, + }; + + return ( + <> +
+ + + Loadouts + + +
+
+

+ Loadout Name +

+
+ { + setLoadout({ ...loadout, name: e.target.value }); + }} + onBlur={() => api.updateLoadout(loadout)} + /> +
+
+
+

Agents

+
+ {valorantData.agents.slice().sort((a, b) => (a.displayName ?? "").localeCompare(b.displayName ?? "")).map((agent) => ( + + ))} +
+
+
+ +
+
+
+

+ Player Cards +

+
+ + ({ + ...card, + duration: 1000, + }))} + render={(card) => ( +
+
+ {card.displayName +
+

+ {(card.displayName ?? "").slice(0, -5)} +

+
+ )} + /> +
+ Edit +
+ +
+
+ +
+

+ Player Titles +

+
+ + ({ ...t, duration: 1000 }))} + render={(title) => ( +

+ {title.titleText || "Default"} +

+ )} + /> +
+ Edit +
+ +
+
+ +
+

+ Expressions +

+
+ {( + Object.entries(expressions) as [ + string, + { + sprays: typeof valorantData.sprays; + flexes: typeof valorantData.flex; + }, + ][] + ).map(([key, exps]) => ( + + ({ + icon: + spray.animationGif ?? + spray.fullTransparentIcon ?? + spray.displayIcon ?? + "", + displayName: spray.displayName ?? "", + duration: 1000, + })), + ...exps.flexes.map((flex) => ({ + icon: flex.displayIcon ?? "", + displayName: flex.displayName ?? "", + duration: 1000, + })), + ]} + render={(expression) => ( + {expression.displayName + )} + /> +
+ {key} +
+ + ))} +
+
+
+ +
+ {valorantData.weapons + .slice() + .sort((a, b) => { + const indexA = weaponUuidToIndex[a.uuid] ?? 999; + const indexB = weaponUuidToIndex[b.uuid] ?? 999; + return indexA - indexB; + }) + .map((weapon) => { + const config = loadout.weapons[weapon.uuid]; + const templates = config?.templates || []; + + const galleryItems: WeaponGalleryItem[] = + templates.length > 0 + ? templates.flatMap((template) => { + const skin = weapon.skins.find( + (s) => s.uuid === template.skinId, + ); + if (!skin) return []; + + const chromas = skin.chromas.filter((c) => + template.chromaIds.includes(c.uuid), + ); + const buddies = template.buddies.flatMap((buddy) => { + const buddyData = valorantData.buddies.find( + (b) => b.uuid === buddy.id, + ); + if (!buddyData) return []; + return buddy.levelIds.map((levelId) => ({ + id: buddy.id, + levelId, + displayName: buddyData.displayName, + displayIcon: buddyData.displayIcon, + })); + }); + + if (chromas.length === 0) return []; + + return chromas.flatMap( + (chroma): WeaponGalleryItem[] => { + if (buddies.length === 0) { + return [ + { + chroma: { + icon: + chroma.fullRender ?? + chroma.displayIcon ?? + "", + name: chroma.displayName ?? "", + }, + buddy: null, + duration: 1000, + }, + ]; + } + return buddies.map((buddy) => ({ + chroma: { + icon: + chroma.fullRender ?? + chroma.displayIcon ?? + "", + name: chroma.displayName ?? "", + }, + buddy: { + icon: buddy.displayIcon ?? "", + name: buddy.displayName ?? "", + }, + duration: 1000, + })); + }, + ); + }) + : [ + { + chroma: { + icon: weapon.displayIcon ?? "", + name: weapon.displayName ?? "", + }, + buddy: null, + duration: 1000, + }, + ]; + + return ( + + ( + <> + {item.chroma.name} + {item.buddy && ( + {item.buddy.name} + )} + + )} + /> + + {weapon.displayName} + +
+ Edit +
+ + ); + })} +
+
+
+ + + ); +} diff --git a/src/routes/app/loadouts/expressions.tsx b/src/routes/app/loadouts/expressions.tsx new file mode 100644 index 0000000..ffb10c3 --- /dev/null +++ b/src/routes/app/loadouts/expressions.tsx @@ -0,0 +1,265 @@ +import { useState } from "react"; +import { + Dialog, + DialogTrigger, + Heading, + Modal, + ModalOverlay, +} from "react-aria-components"; +import { useNavigate, useRevalidator } from "react-router"; +import type { ExpressionSlot, Loadout } from "~/apiClient"; +import * as api from "~/apiClient"; +import { + type Entitlement, + entitlementTypeToIdMap, + type Flex, + type Spray, +} from "~/types"; +import { getValorantData } from "~/valorant-data"; +import type { Route } from "./+types/expressions"; + +type SlotName = "top" | "right" | "bottom" | "left"; + +export async function clientLoader({ params }: Route.ClientLoaderArgs) { + const slot = params.slot as SlotName; + if (!["top", "right", "bottom", "left"].includes(slot)) { + throw new Error("Invalid slot"); + } + + const [valorantData, userConfig, entitlementsData] = await Promise.all([ + getValorantData(), + api.getUserConfig(), + api.getEntitlements(), + ]); + + const loadout = userConfig.loadouts.find( + (l: Loadout) => l.id === params.loadoutId, + ); + if (!loadout) { + throw new Error("Loadout not found"); + } + + const sprayType = entitlementsData.EntitlementsByTypes.find( + (e: { ItemTypeID: string }) => + e.ItemTypeID === entitlementTypeToIdMap.spray, + ); + const flexType = entitlementsData.EntitlementsByTypes.find( + (e: { ItemTypeID: string }) => e.ItemTypeID === entitlementTypeToIdMap.flex, + ); + + const sprayEntitlements: Entitlement[] = sprayType?.Entitlements || []; + const flexEntitlements: Entitlement[] = flexType?.Entitlements || []; + + const ownedSprays = valorantData.sprays + .filter((spray: Spray) => + sprayEntitlements.some((e: Entitlement) => e.ItemID === spray.uuid), + ) + .sort((a: Spray, b: Spray) => + (a.displayName ?? "").localeCompare(b.displayName ?? ""), + ); + + const ownedFlex = valorantData.flex + .filter((flex: Flex) => + flexEntitlements.some((e: Entitlement) => e.ItemID === flex.uuid), + ) + .sort((a: Flex, b: Flex) => + (a.displayName ?? "").localeCompare(b.displayName ?? ""), + ); + + return { + slot, + loadout, + selectedSprays: loadout.expressionIds[slot].sprayIds, + selectedFlex: loadout.expressionIds[slot].flexIds, + ownedSprays, + ownedFlex, + }; +} + +export default function ExpressionPickerModal({ + loaderData, + params, +}: Route.ComponentProps) { + const { + slot, + loadout, + selectedSprays: initialSprays, + selectedFlex: initialFlex, + ownedSprays, + ownedFlex, + } = loaderData; + const navigate = useNavigate(); + const revalidator = useRevalidator(); + const [selectedSprays, setSelectedSprays] = useState(initialSprays); + const [selectedFlex, setSelectedFlex] = useState(initialFlex); + const [currentTab, setCurrentTab] = useState<"sprays" | "flex">("sprays"); + + const toggleSpray = async (sprayId: string) => { + const newSelected = selectedSprays.includes(sprayId) + ? selectedSprays.filter((id) => id !== sprayId) + : [...selectedSprays, sprayId]; + + setSelectedSprays(newSelected); + + const newExpressionSlot: ExpressionSlot = { + sprayIds: newSelected, + flexIds: selectedFlex, + }; + + const newLoadout: Loadout = { + ...loadout, + expressionIds: { + ...loadout.expressionIds, + [slot]: newExpressionSlot, + }, + }; + + await api.updateLoadout(newLoadout); + revalidator.revalidate(); + }; + + const toggleFlex = async (flexId: string) => { + const newSelected = selectedFlex.includes(flexId) + ? selectedFlex.filter((id) => id !== flexId) + : [...selectedFlex, flexId]; + + setSelectedFlex(newSelected); + + const newExpressionSlot: ExpressionSlot = { + sprayIds: selectedSprays, + flexIds: newSelected, + }; + + const newLoadout: Loadout = { + ...loadout, + expressionIds: { + ...loadout.expressionIds, + [slot]: newExpressionSlot, + }, + }; + + await api.updateLoadout(newLoadout); + revalidator.revalidate(); + }; + + const slotTitle = slot.charAt(0).toUpperCase() + slot.slice(1); + + return ( + { + if (!open) navigate(`/loadouts/${params.loadoutId}`); + }} + > + + + +
+ + Select {slotTitle} Slot Expressions + + +
+
+ + +
+
+ {currentTab === "sprays" && ( +
+ {ownedSprays.map((spray: Spray) => ( + + ))} +
+ )} + {currentTab === "flex" && ( +
+ {ownedFlex.map((flex: Flex) => ( + + ))} +
+ )} +
+
+
+
+
+ ); +} diff --git a/src/routes/app/loadouts/index.tsx b/src/routes/app/loadouts/index.tsx new file mode 100644 index 0000000..95feb6e --- /dev/null +++ b/src/routes/app/loadouts/index.tsx @@ -0,0 +1,5 @@ +import { redirect } from "react-router"; + +export function clientLoader() { + return redirect("/"); +} diff --git a/src/routes/app/loadouts/layout.tsx b/src/routes/app/loadouts/layout.tsx new file mode 100644 index 0000000..ccc4e34 --- /dev/null +++ b/src/routes/app/loadouts/layout.tsx @@ -0,0 +1,5 @@ +import { Outlet } from "react-router"; + +export default function LoadoutsLayout() { + return ; +} diff --git a/src/routes/app/loadouts/new.tsx b/src/routes/app/loadouts/new.tsx new file mode 100644 index 0000000..2955db3 --- /dev/null +++ b/src/routes/app/loadouts/new.tsx @@ -0,0 +1,51 @@ +import { redirect } from "react-router"; +import type { Loadout } from "~/apiClient"; +import * as api from "~/apiClient"; + +const weaponIds = [ + "63e6c2b6-4a8e-869c-3d4c-e38355226584", + "55d8a0f4-4274-ca67-fe2c-06ab45efdf58", + "9c82e19d-4575-0200-1a81-3eacf00cf872", + "ae3de142-4d85-2547-dd26-4e90bed35cf7", + "ee8e8d15-496b-07ac-e5f6-8fae5d4c7b1a", + "ec845bf4-4f79-ddda-a3da-0db3774b2794", + "910be174-449b-c412-ab22-d0873436b21b", + "44d4e95c-4157-0037-81b2-17841bf2e8e3", + "29a0cfab-485b-f5d5-779a-b59f85e204a8", + "1baa85b4-4c70-1284-64bb-6481dfc3bb4e", + "e336c6b8-418d-9340-d77f-7a9e4cfe0702", + "42da8ccc-40d5-affc-beec-15aa47b42eda", + "a03b24d3-4319-996d-0f8c-94bbfba1dfc7", + "4ade7faa-4cf1-8376-95ef-39884480959b", + "c4883e50-4494-202c-3ec3-6b8a9284f00b", + "462080d1-4035-2937-7c09-27aa2a5c27a7", + "f7e1b454-4ad4-1063-ec0a-159e56b58941", + "2f59173c-4bed-b6c3-2191-dea9b58be9c7", + "5f0aaf7a-4289-3998-d5ff-eb9a5cf7ef5c", + "410b2e0b-4ceb-1321-1727-20858f7f3477", +]; + +export async function clientLoader() { + const newLoadout: Loadout = { + id: crypto.randomUUID(), + name: "New Loadout", + enabled: true, + agentIds: [], + weapons: Object.fromEntries(weaponIds.map((id) => [id, { templates: [] }])), + playerCardIds: [], + playerTitleIds: [], + expressionIds: { + top: { sprayIds: [], flexIds: [] }, + right: { sprayIds: [], flexIds: [] }, + bottom: { sprayIds: [], flexIds: [] }, + left: { sprayIds: [], flexIds: [] }, + }, + }; + + await api.createLoadout(newLoadout); + return redirect(`/loadouts/${newLoadout.id}`); +} + +export default function NewLoadoutComponent() { + return null; +} diff --git a/src/routes/app/loadouts/playercards.tsx b/src/routes/app/loadouts/playercards.tsx new file mode 100644 index 0000000..af80e48 --- /dev/null +++ b/src/routes/app/loadouts/playercards.tsx @@ -0,0 +1,152 @@ +import { useState } from "react"; +import { + Dialog, + DialogTrigger, + Heading, + Modal, + ModalOverlay, +} from "react-aria-components"; +import { useNavigate, useRevalidator } from "react-router"; +import type { Loadout } from "~/apiClient"; +import * as api from "~/apiClient"; +import { + type Entitlement, + entitlementTypeToIdMap, + type PlayerCard, +} from "~/types"; +import { getValorantData } from "~/valorant-data"; +import type { Route } from "./+types/playercards"; + +export async function clientLoader({ params }: Route.ClientLoaderArgs) { + const [valorantData, userConfig, entitlementsData] = await Promise.all([ + getValorantData(), + api.getUserConfig(), + api.getEntitlements(), + ]); + + const loadout = userConfig.loadouts.find( + (l: Loadout) => l.id === params.loadoutId, + ); + if (!loadout) { + throw new Error("Loadout not found"); + } + + const playerCardType = entitlementsData.EntitlementsByTypes.find( + (e: { ItemTypeID: string }) => + e.ItemTypeID === entitlementTypeToIdMap.player_card, + ); + const playerCardEntitlements: Entitlement[] = + playerCardType?.Entitlements || []; + + const ownedPlayerCards = valorantData.playerCards + .filter((card: PlayerCard) => + playerCardEntitlements.some((e: Entitlement) => e.ItemID === card.uuid), + ) + .sort((a: PlayerCard, b: PlayerCard) => + (a.displayName ?? "").localeCompare(b.displayName ?? ""), + ); + + return { + loadout, + selectedPlayerCards: loadout.playerCardIds, + ownedPlayerCards, + }; +} + +export default function PlayerCardsModal({ + loaderData, + params, +}: Route.ComponentProps) { + const { + loadout, + selectedPlayerCards: initialSelected, + ownedPlayerCards, + } = loaderData; + const navigate = useNavigate(); + const revalidator = useRevalidator(); + const [selectedCards, setSelectedCards] = useState(initialSelected); + + const toggleCard = async (cardId: string) => { + const newSelected = selectedCards.includes(cardId) + ? selectedCards.filter((id) => id !== cardId) + : [...selectedCards, cardId]; + + setSelectedCards(newSelected); + + const newLoadout: Loadout = { + ...loadout, + playerCardIds: newSelected, + }; + + await api.updateLoadout(newLoadout); + revalidator.revalidate(); + }; + + return ( + { + if (!open) navigate(`/loadouts/${params.loadoutId}`); + }} + > + + + +
+ + Select Player Cards + + +
+
+
+ {ownedPlayerCards.map((playerCard: PlayerCard) => ( + + ))} +
+
+
+
+
+
+ ); +} diff --git a/src/routes/app/loadouts/playertitles.tsx b/src/routes/app/loadouts/playertitles.tsx new file mode 100644 index 0000000..516ac74 --- /dev/null +++ b/src/routes/app/loadouts/playertitles.tsx @@ -0,0 +1,147 @@ +import { useState } from "react"; +import { + Dialog, + DialogTrigger, + Heading, + Modal, + ModalOverlay, +} from "react-aria-components"; +import { useNavigate, useRevalidator } from "react-router"; +import type { Loadout } from "~/apiClient"; +import * as api from "~/apiClient"; +import { + type Entitlement, + entitlementTypeToIdMap, + type PlayerTitle, +} from "~/types"; +import { getValorantData } from "~/valorant-data"; +import type { Route } from "./+types/playertitles"; + +export async function clientLoader({ params }: Route.ClientLoaderArgs) { + const [valorantData, userConfig, entitlementsData] = await Promise.all([ + getValorantData(), + api.getUserConfig(), + api.getEntitlements(), + ]); + + const loadout = userConfig.loadouts.find( + (l: Loadout) => l.id === params.loadoutId, + ); + if (!loadout) { + throw new Error("Loadout not found"); + } + + const playerTitleType = entitlementsData.EntitlementsByTypes.find( + (e: { ItemTypeID: string }) => + e.ItemTypeID === entitlementTypeToIdMap.player_title, + ); + const playerTitleEntitlements: Entitlement[] = + playerTitleType?.Entitlements || []; + + const ownedPlayerTitles = valorantData.playerTitles + .filter((title: PlayerTitle) => + playerTitleEntitlements.some((e: Entitlement) => e.ItemID === title.uuid), + ) + .sort((a: PlayerTitle, b: PlayerTitle) => + (a.displayName ?? "").localeCompare(b.displayName ?? ""), + ); + + return { + loadout, + selectedPlayerTitles: loadout.playerTitleIds, + ownedPlayerTitles, + }; +} + +export default function PlayerTitlesModal({ + loaderData, + params, +}: Route.ComponentProps) { + const { + loadout, + selectedPlayerTitles: initialSelected, + ownedPlayerTitles, + } = loaderData; + const navigate = useNavigate(); + const revalidator = useRevalidator(); + const [selectedTitles, setSelectedTitles] = + useState(initialSelected); + + const toggleTitle = async (titleId: string) => { + const newSelected = selectedTitles.includes(titleId) + ? selectedTitles.filter((id) => id !== titleId) + : [...selectedTitles, titleId]; + + setSelectedTitles(newSelected); + + const newLoadout: Loadout = { + ...loadout, + playerTitleIds: newSelected, + }; + + await api.updateLoadout(newLoadout); + revalidator.revalidate(); + }; + + return ( + { + if (!open) navigate(`/loadouts/${params.loadoutId}`); + }} + > + + + +
+ + Select Player Titles + + +
+
+
+ {ownedPlayerTitles.map((title: PlayerTitle) => ( + + ))} +
+
+
+
+
+
+ ); +} diff --git a/src/routes/app/loadouts/weapon-new.tsx b/src/routes/app/loadouts/weapon-new.tsx new file mode 100644 index 0000000..8cb3a6f --- /dev/null +++ b/src/routes/app/loadouts/weapon-new.tsx @@ -0,0 +1,454 @@ +import { useReducer } from "react"; +import { + Dialog, + DialogTrigger, + Heading, + Modal, + ModalOverlay, +} from "react-aria-components"; +import { redirect, useNavigate } from "react-router"; +import invariant from "tiny-invariant"; +import type { Loadout } from "~/apiClient"; +import * as api from "~/apiClient"; +import { + type Buddy, + type BuddyLevel, + type Entitlement, + entitlementTypeToIdMap, + type Skin, + type SkinChroma, + type SkinLevel, +} from "~/types"; +import { getValorantData } from "~/valorant-data"; +import type { Route } from "./+types/weapon-new"; + +interface OwnedSkin { + id: string; + name: string; + displayIcon: string; + chromas: Array<{ + uuid: string; + displayName: string; + displayIcon: string; + fullRender: string; + }>; + levels: Array<{ + uuid: string; + displayName: string; + displayIcon: string; + }>; +} + +type OwnedBuddy = { + buddyId: string; + levelId: string; + displayName: string; + displayIcon: string; +}; + +export async function clientLoader({ params }: Route.ClientLoaderArgs) { + const { loadoutId, weaponId } = params; + if (!loadoutId || !weaponId) throw new Error("Missing params"); + + const [valorantData, userConfig, entitlementsData] = await Promise.all([ + getValorantData(), + api.getUserConfig(), + api.getEntitlements(), + ]); + + const loadout = userConfig.loadouts.find((l: Loadout) => l.id === loadoutId); + if (!loadout) { + throw new Error("Loadout not found"); + } + + const weapon = valorantData.weapons.find( + (w: { uuid: string }) => w.uuid === weaponId, + ); + if (!weapon) { + throw new Error("Weapon not found"); + } + + const skinChromaType = entitlementsData.EntitlementsByTypes.find( + (e: { ItemTypeID: string }) => + e.ItemTypeID === entitlementTypeToIdMap.skin_chroma, + ); + const skinLevelType = entitlementsData.EntitlementsByTypes.find( + (e: { ItemTypeID: string }) => + e.ItemTypeID === entitlementTypeToIdMap.skin_level, + ); + const buddyType = entitlementsData.EntitlementsByTypes.find( + (e: { ItemTypeID: string }) => + e.ItemTypeID === entitlementTypeToIdMap.buddy, + ); + + const skinChromaEntitlements: Entitlement[] = + skinChromaType?.Entitlements || []; + const skinLevelEntitlements: Entitlement[] = + skinLevelType?.Entitlements || []; + const buddyEntitlements: Entitlement[] = buddyType?.Entitlements || []; + + const ownedSkins = weapon.skins.reduce( + (acc: OwnedSkin[], skin: Skin) => { + const chromas = skin.chromas.filter((chroma: SkinChroma) => + skinChromaEntitlements.some( + (e: Entitlement) => e.ItemID === chroma.uuid, + ), + ); + + const levels = skin.levels.filter((level: SkinLevel) => + skinLevelEntitlements.some((e: Entitlement) => e.ItemID === level.uuid), + ); + + if (chromas.length === 0 && levels.length === 0) { + return acc; + } + + acc.push({ + id: skin.uuid, + name: skin.displayName ?? "", + displayIcon: skin.displayIcon ?? "", + chromas: [skin.chromas[0], ...chromas].map((c) => ({ + uuid: c.uuid, + displayName: c.displayName ?? "", + displayIcon: c.displayIcon ?? "", + fullRender: c.fullRender ?? "", + })), + levels: levels.map((l) => ({ + uuid: l.uuid, + displayName: l.displayName ?? "", + displayIcon: l.displayIcon ?? "", + })), + }); + + return acc; + }, + [], + ); + + const ownedBuddies: OwnedBuddy[] = valorantData.buddies + .flatMap((buddy: Buddy) => + buddy.levels + .map((level: BuddyLevel) => ({ + buddyId: buddy.uuid, + levelId: level.uuid, + displayName: buddy.displayName ?? "", + displayIcon: level.displayIcon ?? "", + })) + .filter((b: OwnedBuddy) => + buddyEntitlements.some((e: Entitlement) => e.ItemID === b.levelId), + ), + ) + .sort((a: OwnedBuddy, b: OwnedBuddy) => + (a.displayName ?? "").localeCompare(b.displayName ?? ""), + ); + + return { weapon, loadout, ownedSkins, ownedBuddies }; +} + +export async function clientAction({ + request, + params, +}: Route.ClientActionArgs) { + const { loadoutId, weaponId } = params; + if (!loadoutId || !weaponId) throw new Error("Missing params"); + + const formData = await request.formData(); + const skinId = formData.get("skinId") as string; + const loadoutJson = formData.get("loadout") as string; + const loadout: Loadout = JSON.parse(loadoutJson); + + const chromaIds: string[] = []; + const levelIds: string[] = []; + const buddies: Record = {}; + + formData.forEach((value, key) => { + if (key.startsWith("chromas[") && value === "on") { + chromaIds.push(key.slice(8, -1)); + } + if (key.startsWith("levels[") && value === "on") { + levelIds.push(key.slice(7, -1)); + } + if (key.startsWith("buddies[") && value === "on") { + const match = key.match(/buddies\[(.+?)\]\[(.+?)\]/); + if (match) { + const [, buddyId, levelId] = match; + if (!buddies[buddyId]) buddies[buddyId] = []; + buddies[buddyId].push(levelId); + } + } + }); + + const ownedSkins: OwnedSkin[] = JSON.parse( + formData.get("ownedSkins") as string, + ); + const skin = ownedSkins.find((s) => s.id === skinId); + invariant(skin, "Skin not found"); + const defaultChroma = skin.chromas[skin.chromas.length - 1].uuid; + const defaultLevel = skin.levels[skin.levels.length - 1]?.uuid; + + const existingWeapon = loadout.weapons[weaponId]; + + const newLoadout: Loadout = { + ...loadout, + weapons: { + ...loadout.weapons, + [weaponId]: { + ...existingWeapon, + templates: [ + ...(existingWeapon?.templates || []), + { + id: crypto.randomUUID(), + skinId, + chromaIds: chromaIds.length ? chromaIds : [defaultChroma], + levelIds: levelIds.length + ? levelIds + : defaultLevel + ? [defaultLevel] + : [], + buddies: Object.entries(buddies).map(([id, lvlIds]) => ({ + id, + levelIds: lvlIds, + })), + }, + ], + }, + }, + }; + + await api.updateLoadout(newLoadout); + return redirect(`/loadouts/${loadoutId}/weapons/${weaponId}`); +} + +type NewSkinAction = { + type: "SET_SELECTED_SKIN"; + payload: OwnedSkin; +}; + +type NewSkinState = + | { mode: "select_skin"; title: string } + | { mode: "select_chroma"; title: string; selectedSkin: OwnedSkin }; + +export default function NewSkinTemplateModal({ + loaderData, + params, +}: Route.ComponentProps) { + const { weapon, loadout, ownedSkins, ownedBuddies } = loaderData; + const loadoutId = params.loadoutId; + const weaponId = params.weaponId; + const navigate = useNavigate(); + + const [state, dispatch] = useReducer( + (_state, action) => { + switch (action.type) { + case "SET_SELECTED_SKIN": + return { + mode: "select_chroma", + title: action.payload.name, + selectedSkin: action.payload, + }; + } + }, + { mode: "select_skin", title: "Select a skin" }, + ); + + const closeUrl = `/loadouts/${loadoutId}/weapons/${weaponId}`; + + return ( + { + if (!open) navigate(closeUrl); + }} + > + + + +
+ + {state.title} + + +
+ {state.mode === "select_skin" && ( +
+ {[...ownedSkins] + .sort((a, b) => (a.name ?? "").localeCompare(b.name ?? "")) + .map((skin) => ( + + ))} +
+ )} + {state.mode === "select_chroma" && ( +
+ + + +
+
+ {state.title +
+

Chromas

+
+ {state.selectedSkin.chromas.map((chroma) => ( +
+ + +
+ ))} +
+

Levels

+
+ {state.selectedSkin.levels.map((level, index, arr) => ( +
+ + +
+ ))} +
+ {weapon.uuid !== "2f59173c-4bed-b6c3-2191-dea9b58be9c7" && ( + <> +

Buddies

+
+ {ownedBuddies.map((buddy: OwnedBuddy) => ( +
+ + +
+ ))} +
+ + )} +
+
+ + +
+
+ )} +
+
+
+
+ ); +} diff --git a/src/routes/app/loadouts/weapon.tsx b/src/routes/app/loadouts/weapon.tsx new file mode 100644 index 0000000..60581ce --- /dev/null +++ b/src/routes/app/loadouts/weapon.tsx @@ -0,0 +1,196 @@ +import { + Dialog, + DialogTrigger, + Heading, + Modal, + ModalOverlay, +} from "react-aria-components"; +import { Link, Outlet, useNavigate, useRevalidator } from "react-router"; +import type { Loadout } from "~/apiClient"; +import * as api from "~/apiClient"; +import { SwitchImage } from "~/components/SwitchImage"; +import type { Skin, SkinChroma } from "~/types"; +import { getValorantData } from "~/valorant-data"; +import type { Route } from "./+types/weapon"; + +export async function clientLoader({ params }: Route.ClientLoaderArgs) { + const { loadoutId, weaponId } = params; + if (!loadoutId || !weaponId) throw new Error("Missing params"); + + const [valorantData, userConfig] = await Promise.all([ + getValorantData(), + api.getUserConfig(), + ]); + + const loadout = userConfig.loadouts.find((l) => l.id === loadoutId); + if (!loadout) { + throw new Error("Loadout not found"); + } + + const weapon = valorantData.weapons.find((w) => w.uuid === weaponId); + if (!weapon) { + throw new Error("Weapon not found"); + } + + const templates = loadout.weapons[weaponId]?.templates || []; + + return { + weaponId, + weapon, + loadout, + templates: templates.map( + (template: { id: string; skinId: string; chromaIds: string[] }) => { + const skin = weapon.skins.find((s: Skin) => s.uuid === template.skinId); + const chromas = + skin?.chromas.filter((c: SkinChroma) => + template.chromaIds.includes(c.uuid), + ) || []; + + return { id: template.id, skin, chromas }; + }, + ), + }; +} + +export default function WeaponTemplatesModal({ + loaderData, + params, +}: Route.ComponentProps) { + const { weaponId, weapon, templates, loadout } = loaderData; + const loadoutId = params.loadoutId; + const navigate = useNavigate(); + const revalidator = useRevalidator(); + + const handleDeleteTemplate = async (templateId: string) => { + const existingWeapon = loadout.weapons[weaponId]; + if (!existingWeapon) return; + + const newTemplates = existingWeapon.templates.filter( + (t: { id: string }) => t.id !== templateId, + ); + + const newLoadout: Loadout = { + ...loadout, + weapons: { + ...loadout.weapons, + [weaponId]: { + ...existingWeapon, + templates: newTemplates, + }, + }, + }; + + await api.updateLoadout(newLoadout); + revalidator.revalidate(); + }; + + return ( + <> + { + if (!open) navigate(`/loadouts/${loadoutId}`); + }} + > + + + +
+ + {weapon.displayName ?? ""} + + +
+
+ {templates.map( + (template: { + id: string; + skin: Skin | undefined; + chromas: SkinChroma[]; + }) => ( +
+
+
+ ({ + src: + (chroma.fullRender ?? "") || + (chroma.displayIcon ?? ""), + alt: chroma.displayName ?? "", + }), + )} + /> +
+

+ {(template.skin?.displayName ?? "") + .split(" ") + .slice(0, -1) + .join(" ")} +

+
+
+ +
+
+ ), + )} + + + + +
+
+
+
+
+ + + ); +} diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..674ddf8 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,276 @@ +export type WeaponCategory = + | "EEquippableCategory::Sidearm" + | "EEquippableCategory::SMG" + | "EEquippableCategory::Rifle" + | "EEquippableCategory::Sniper" + | "EEquippableCategory::Shotgun" + | "EEquippableCategory::Heavy" + | "EEquippableCategory::Melee"; + +export interface SkinChroma { + uuid: string; + displayName: string; + displayIcon: string | null; + fullRender: string; + swatch: string | null; + streamedVideo: string | null; + assetPath: string; +} + +export interface SkinLevel { + uuid: string; + displayName: string; + levelItem: string | null; + displayIcon: string | null; + streamedVideo: string | null; + assetPath: string; +} + +export interface Skin { + uuid: string; + displayName: string; + themeUuid: string | null; + contentTierUuid: string | null; + displayIcon: string | null; + wallpaper: string | null; + assetPath: string; + chromas: SkinChroma[]; + levels: SkinLevel[]; +} + +export interface Weapon { + uuid: string; + displayName: string; + category: WeaponCategory; + defaultSkinUuid: string; + displayIcon: string; + killStreamIcon: string; + assetPath: string; + skins: Skin[]; +} + +export interface BuddyLevel { + uuid: string; + charmLevel: number; + displayName: string; + displayIcon: string; + assetPath: string; +} + +export interface Buddy { + uuid: string; + displayName: string; + isHiddenIfNotOwned: boolean; + themeUuid: string | null; + displayIcon: string; + assetPath: string; + levels: BuddyLevel[]; +} + +export interface PlayerCard { + uuid: string; + displayName: string; + isHiddenIfNotOwned: boolean; + themeUuid: string | null; + displayIcon: string; + smallArt: string; + wideArt: string; + largeArt: string | null; + assetPath: string; +} + +export interface SprayLevel { + uuid: string; + sprayLevel: number; + displayName: string; + displayIcon: string | null; + assetPath: string; +} + +export interface Spray { + uuid: string; + displayName: string; + category: string | null; + themeUuid: string | null; + displayIcon: string; + fullIcon: string | null; + fullTransparentIcon: string | null; + animationPng: string | null; + animationGif: string | null; + assetPath: string; + levels: SprayLevel[]; +} + +export interface Flex { + uuid: string; + displayName: string; + displayIcon: string; + assetPath: string; +} + +export interface PlayerTitle { + uuid: string; + displayName: string | null; + titleText: string | null; + isHiddenIfNotOwned: boolean; + assetPath: string; +} + +export interface Role { + uuid: string; + displayName: string; + description: string; + displayIcon: string; + assetPath: string; +} + +export interface Ability { + slot: string; + displayName: string; + description: string; + displayIcon: string | null; +} + +export interface Agent { + uuid: string; + displayName: string; + description: string; + developerName: string; + characterTags: string[] | null; + displayIcon: string; + displayIconSmall: string; + bustPortrait: string; + fullPortrait: string; + fullPortraitV2: string; + killfeedPortrait: string; + background: string; + backgroundGradientColors: string[] | null; + assetPath: string; + isFullPortraitRightFacing: boolean; + isPlayableCharacter: boolean; + isAvailableForTest: boolean; + isBaseContent: boolean; + role: Role | null; + abilities: Ability[]; +} + +export type EntitlementTypes = + | "skin_level" + | "skin_chroma" + | "agent" + | "contract_definition" + | "buddy" + | "spray" + | "flex" + | "player_card" + | "player_title"; + +export interface Entitlement { + TypeID: string; + ItemID: string; + InstanceID?: string; +} + +export const entitlementIdToTypeMap: Record = { + "e7c63390-eda7-46e0-bb7a-a6abdacd2433": "skin_level", + "3ad1b2b2-acdb-4524-852f-954a76ddae0a": "skin_chroma", + "01bb38e1-da47-4e6a-9b3d-945fe4655707": "agent", + "f85cb6f7-33e5-4dc8-b609-ec7212301948": "contract_definition", + "dd3bf334-87f3-40bd-b043-682a57a8dc3a": "buddy", + "d5f120f8-ff8c-4aac-92ea-f2b5acbe9475": "spray", + "03a572de-4234-31ed-d344-ababa488f981": "flex", + "3f296c07-64c3-494c-923b-fe692a4fa1bd": "player_card", + "de7caa6b-adf7-4588-bbd1-143831e786c6": "player_title", +}; + +export const entitlementTypeToIdMap: Record = { + skin_level: "e7c63390-eda7-46e0-bb7a-a6abdacd2433", + skin_chroma: "3ad1b2b2-acdb-4524-852f-954a76ddae0a", + agent: "01bb38e1-da47-4e6a-9b3d-945fe4655707", + contract_definition: "f85cb6f7-33e5-4dc8-b609-ec7212301948", + buddy: "dd3bf334-87f3-40bd-b043-682a57a8dc3a", + spray: "d5f120f8-ff8c-4aac-92ea-f2b5acbe9475", + flex: "03a572de-4234-31ed-d344-ababa488f981", + player_card: "3f296c07-64c3-494c-923b-fe692a4fa1bd", + player_title: "de7caa6b-adf7-4588-bbd1-143831e786c6", +}; + +export const categoryNameMap: Record = { + "EEquippableCategory::Sidearm": "sidearms", + "EEquippableCategory::SMG": "smgs", + "EEquippableCategory::Rifle": "rifles", + "EEquippableCategory::Sniper": "sniper rifles", + "EEquippableCategory::Shotgun": "shotguns", + "EEquippableCategory::Heavy": "machine guns", + "EEquippableCategory::Melee": "melee", +}; + +export const categoryCanonicalNameMap: Record = { + "EEquippableCategory::Sidearm": "sidearm", + "EEquippableCategory::SMG": "smg", + "EEquippableCategory::Rifle": "rifle", + "EEquippableCategory::Sniper": "sniper", + "EEquippableCategory::Shotgun": "shotgun", + "EEquippableCategory::Heavy": "heavy", + "EEquippableCategory::Melee": "melee", +}; + +export const sortedWeapons: Record = { + "EEquippableCategory::Sidearm": [ + "classic", + "shorty", + "frenzy", + "ghost", + "bandit", + "sheriff", + ], + "EEquippableCategory::SMG": ["stinger", "spectre"], + "EEquippableCategory::Rifle": ["bulldog", "guardian", "phantom", "vandal"], + "EEquippableCategory::Sniper": ["marshal", "outlaw", "operator"], + "EEquippableCategory::Shotgun": ["bucky", "judge"], + "EEquippableCategory::Heavy": ["ares", "odin"], + "EEquippableCategory::Melee": ["melee"], +}; + +export const weaponUUIDCanonicalNameMap: Record = { + "63e6c2b6-4a8e-869c-3d4c-e38355226584": "odin", + "55d8a0f4-4274-ca67-fe2c-06ab45efdf58": "ares", + "9c82e19d-4575-0200-1a81-3eacf00cf872": "vandal", + "ae3de142-4d85-2547-dd26-4e90bed35cf7": "bulldog", + "ee8e8d15-496b-07ac-e5f6-8fae5d4c7b1a": "phantom", + "ec845bf4-4f79-ddda-a3da-0db3774b2794": "judge", + "910be174-449b-c412-ab22-d0873436b21b": "bucky", + "44d4e95c-4157-0037-81b2-17841bf2e8e3": "frenzy", + "29a0cfab-485b-f5d5-779a-b59f85e204a8": "classic", + "1baa85b4-4c70-1284-64bb-6481dfc3bb4e": "ghost", + "410b2e0b-4ceb-1321-1727-20858f7f3477": "bandit", + "e336c6b8-418d-9340-d77f-7a9e4cfe0702": "sheriff", + "42da8ccc-40d5-affc-beec-15aa47b42eda": "shorty", + "a03b24d3-4319-996d-0f8c-94bbfba1dfc7": "operator", + "4ade7faa-4cf1-8376-95ef-39884480959b": "guardian", + "c4883e50-4494-202c-3ec3-6b8a9284f00b": "marshal", + "5f0aaf7a-4289-3998-d5ff-eb9a5cf7ef5c": "outlaw", + "462080d1-4035-2937-7c09-27aa2a5c27a7": "spectre", + "f7e1b454-4ad4-1063-ec0a-159e56b58941": "stinger", + "2f59173c-4bed-b6c3-2191-dea9b58be9c7": "melee", +}; + +export const weaponCanonicalNameUUIDMap: Record = + Object.entries(weaponUUIDCanonicalNameMap).reduce( + (acc, [key, value]) => { + acc[value] = key; + return acc; + }, + {} as Record, + ); + +export const weaponUuidToIndex = Object.entries(sortedWeapons).reduce( + (acc, [_category, weapons]) => { + const totalAcc = Object.keys(acc).length; + weapons.forEach((weapon, index) => { + acc[weaponCanonicalNameUUIDMap[weapon]] = index + totalAcc; + }); + return acc; + }, + {} as Record, +); diff --git a/src/valorant-data.ts b/src/valorant-data.ts new file mode 100644 index 0000000..46d0923 --- /dev/null +++ b/src/valorant-data.ts @@ -0,0 +1,24 @@ +import { invoke } from "@tauri-apps/api/core"; +import type { + Agent, + Buddy, + Flex, + PlayerCard, + PlayerTitle, + Spray, + Weapon, +} from "./types"; + +export interface ValorantData { + weapons: Weapon[]; + buddies: Buddy[]; + playerCards: PlayerCard[]; + sprays: Spray[]; + playerTitles: PlayerTitle[]; + agents: Agent[]; + flex: Flex[]; +} + +export async function getValorantData(): Promise { + return invoke("get_valorant_data"); +} diff --git a/src/valpal.png b/src/valpal.png new file mode 100644 index 0000000..4836ab2 Binary files /dev/null and b/src/valpal.png differ diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/tailwind.config.ts b/tailwind.config.ts deleted file mode 100644 index 421f823..0000000 --- a/tailwind.config.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { Config } from 'tailwindcss'; - -export default { - content: ['./app/**/{**,.client,.server}/**/*.{js,jsx,ts,tsx}'], - theme: {}, - plugins: [ - require('tailwind-scrollbar')({ - preferredStrategy: 'pseudoelements', - nocompatible: true, - }), - ], -} satisfies Config; diff --git a/tsconfig.json b/tsconfig.json index cea27d4..ff96009 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,14 +1,31 @@ { - "files": [], - "references": [ - { "path": "./tsconfig.node.json" }, - { "path": "./tsconfig.vite.json" } - ], - "compilerOptions": { - "checkJs": true, - "verbatimModuleSyntax": true, - "skipLibCheck": true, - "strict": true, - "noEmit": true - } + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + "rootDirs": [".", "./.react-router/types"], + "baseUrl": ".", + "paths": { + "~/*": ["./src/*"] + }, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] } diff --git a/tsconfig.node.json b/tsconfig.node.json index 4cf0b2e..42872c5 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -1,13 +1,10 @@ { - "extends": "./tsconfig.json", - "include": ["server.ts", "tailwind.config.ts", "vite.config.ts"], "compilerOptions": { "composite": true, - "strict": true, - "types": ["node"], - "lib": ["ES2022"], - "target": "ES2022", - "module": "ES2022", - "moduleResolution": "bundler" - } + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] } diff --git a/tsconfig.vite.json b/tsconfig.vite.json deleted file mode 100644 index 2675918..0000000 --- a/tsconfig.vite.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "include": [ - ".react-router/types/**/*", - "app/**/*", - "app/**/.server/**/*", - "app/**/.client/**/*", - "server/**/*", - "types.ts" - ], - "compilerOptions": { - "composite": true, - "strict": true, - "lib": ["DOM", "DOM.Iterable", "ES2022"], - "types": ["vite/client"], - "target": "ES2022", - "module": "ES2022", - "moduleResolution": "bundler", - "jsx": "react-jsx", - "baseUrl": ".", - "rootDirs": [".", "./.react-router/types"], - "paths": { - "~/*": ["./app/*"] - }, - "esModuleInterop": true, - "resolveJsonModule": true - } -} diff --git a/types.ts b/types.ts deleted file mode 100644 index d09ecd7..0000000 --- a/types.ts +++ /dev/null @@ -1,521 +0,0 @@ -export enum Regions { - AsiaPacific = 'AP', - Europe = 'EU', - Korea = 'KO', - NorthAmerica = 'NA', - LatinAmerica = 'LATAM', - Brazil = 'BR', -} - -export enum Shards { - NorthAmerica = 'NA', - Europe = 'EU', - AsiaPacific = 'AP', - Korea = 'KR', - PBE = 'PBE', -} - -export const regionToShard: Record = { - [Regions.AsiaPacific]: Shards.AsiaPacific, - [Regions.Europe]: Shards.Europe, - [Regions.Korea]: Shards.Korea, - [Regions.NorthAmerica]: Shards.NorthAmerica, - [Regions.LatinAmerica]: Shards.NorthAmerica, - [Regions.Brazil]: Shards.NorthAmerica, -}; - -export interface AdsStats { - zoomMultiplier: number; - fireRate: number; - runSpeedMultiplier: number; - burstCount: number; - firstBulletAccuracy: number; -} - -export interface DamageRange { - rangeStartMeters: number; - rangeEndMeters: number; - headDamage: number; - bodyDamage: number; - legDamage: number; -} - -export interface WeaponStats { - fireRate: number; - magazineSize: number; - runSpeedMultiplier: number; - equipTimeSeconds: number; - reloadTimeSeconds: number; - firstBulletAccuracy: number; - shotgunPelletCount: number; - wallPenetration: string; - feature: string; - fireMode?: any; - altFireType: string; - adsStats: AdsStats; - altShotgunStats?: any; - airBurstStats?: any; - damageRanges: DamageRange[]; -} - -export interface GridPosition { - row: number; - column: number; -} - -export interface ShopData { - cost: number; - category: string; - categoryText: string; - gridPosition: GridPosition; - canBeTrashed: boolean; - image?: any; - newImage: string; - newImage2?: any; - assetPath: string; -} - -export interface SkinChroma { - uuid: string; - displayName: string; - displayIcon: string; - fullRender: string; - swatch: string; - streamedVideo: string; - assetPath: string; -} - -export interface SkinLevel { - uuid: string; - displayName: string; - levelItem: string; - displayIcon: string; - streamedVideo: string; - assetPath: string; -} - -export interface Skin { - uuid: string; - displayName: string; - themeUuid: string; - contentTierUuid: string; - displayIcon: string; - wallpaper: string; - assetPath: string; - chromas: SkinChroma[]; - levels: SkinLevel[]; -} - -export interface Weapon { - uuid: string; - displayName: string; - category: WeaponCategory; - defaultSkinUuid: string; - displayIcon: string; - killStreamIcon: string; - assetPath: string; - weaponStats: WeaponStats; - shopData: ShopData; - skins: Skin[]; -} - -export interface Entitlement { - TypeID: string; - ItemID: string; - InstanceID: string; -} - -export type WeaponCategory = - | 'EEquippableCategory::Sidearm' - | 'EEquippableCategory::SMG' - | 'EEquippableCategory::Rifle' - | 'EEquippableCategory::Sniper' - | 'EEquippableCategory::Shotgun' - | 'EEquippableCategory::Heavy' - | 'EEquippableCategory::Melee'; - -export interface BuddyLevel { - uuid: string; - charmLevel: number; - displayName: string; - displayIcon: string; - assetPath: string; -} - -export interface Buddy { - uuid: string; - displayName: string; - isHiddenIfNotOwned: boolean; - themeUuid: string; - displayIcon: string; - assetPath: string; - levels: BuddyLevel[]; -} - -export interface Gun { - ID: string; - SkinID: string; - SkinLevelID: string; - ChromaID: string; - CharmInstanceID?: string; - CharmID?: string; - CharmLevelID?: string; - Attachments: any[]; -} - -export interface ActiveExpression { - TypeID: string; - AssetID: string; -} - -export interface Identity { - PlayerCardID: string; - PlayerTitleID: string; - AccountLevel: number; - PreferredLevelBorderID: string; - HideAccountLevel: boolean; -} - -export interface AdsStats { - zoomMultiplier: number; - fireRate: number; - runSpeedMultiplier: number; - burstCount: number; - firstBulletAccuracy: number; -} - -export interface DamageRange { - rangeStartMeters: number; - rangeEndMeters: number; - headDamage: number; - bodyDamage: number; - legDamage: number; -} - -export interface WeaponStats { - fireRate: number; - magazineSize: number; - runSpeedMultiplier: number; - equipTimeSeconds: number; - reloadTimeSeconds: number; - firstBulletAccuracy: number; - shotgunPelletCount: number; - wallPenetration: string; - feature: string; - fireMode?: any; - altFireType: string; - adsStats: AdsStats; - altShotgunStats?: any; - airBurstStats?: any; - damageRanges: DamageRange[]; -} - -export interface GridPosition { - row: number; - column: number; -} - -export interface Entitlement { - TypeID: string; - ItemID: string; - InstanceID: string; -} - -export interface EntitlementsByType { - ItemTypeID: string; - Entitlements: Entitlement[]; -} - -type EntitlementTypes = - | 'skin_level' - | 'skin_chroma' - | 'agent' - | 'contract_definition' - | 'buddy' - | 'spray' - | 'flex' - | 'player_card' - | 'player_title'; - -export const entitlementIdToTypeMap: Record = { - 'e7c63390-eda7-46e0-bb7a-a6abdacd2433': 'skin_level', - '3ad1b2b2-acdb-4524-852f-954a76ddae0a': 'skin_chroma', - '01bb38e1-da47-4e6a-9b3d-945fe4655707': 'agent', - 'f85cb6f7-33e5-4dc8-b609-ec7212301948': 'contract_definition', - 'dd3bf334-87f3-40bd-b043-682a57a8dc3a': 'buddy', - 'd5f120f8-ff8c-4aac-92ea-f2b5acbe9475': 'spray', - '03a572de-4234-31ed-d344-ababa488f981': 'flex', - '3f296c07-64c3-494c-923b-fe692a4fa1bd': 'player_card', - 'de7caa6b-adf7-4588-bbd1-143831e786c6': 'player_title', -}; - -export const entitlementTypeToIdMap: Record = { - skin_level: 'e7c63390-eda7-46e0-bb7a-a6abdacd2433', - skin_chroma: '3ad1b2b2-acdb-4524-852f-954a76ddae0a', - agent: '01bb38e1-da47-4e6a-9b3d-945fe4655707', - contract_definition: 'f85cb6f7-33e5-4dc8-b609-ec7212301948', - buddy: 'dd3bf334-87f3-40bd-b043-682a57a8dc3a', - spray: 'd5f120f8-ff8c-4aac-92ea-f2b5acbe9475', - flex: '03a572de-4234-31ed-d344-ababa488f981', - player_card: '3f296c07-64c3-494c-923b-fe692a4fa1bd', - player_title: 'de7caa6b-adf7-4588-bbd1-143831e786c6', -}; - -export interface ClientPlatformInfo { - platformType: string; - platformOS: string; - platformOSVersion: string; - platformChipset: string; -} - -export interface Session { - subject: string; - cxnState: string; - clientID: string; - clientVersion: string; - loopState: string; - loopStateMetadata: string; - version: number; - lastHeartbeatTime: Date; - expiredTime: Date; - heartbeatIntervalMillis: number; - playtimeNotification: string; - playtimeMinutes: number; - isRestricted: boolean; - userinfoValidTime: Date; - restrictionType: string; - clientPlatformInfo: ClientPlatformInfo; -} - -export interface PregamePlayer { - Subject: string; - MatchID: string; - Version: number; -} - -export interface PlayerIdentity { - Subject: string; - PlayerCardID: string; - PlayerTitleID: string; - AccountLevel: number; - PreferredLevelBorderID: string; - Incognito: boolean; - HideAccountLevel: boolean; -} - -export interface SeasonalBadgeInfo { - SeasonID: string; - NumberOfWins: number; - WinsByTier?: any; - Rank: number; - LeaderboardRank: number; -} - -export interface Player { - Subject: string; - CharacterID: string; - CharacterSelectionState: string; - PregamePlayerState: string; - CompetitiveTier: number; - PlayerIdentity: PlayerIdentity; - SeasonalBadgeInfo: SeasonalBadgeInfo; - IsCaptain: boolean; -} - -export interface Team { - TeamID: string; - Players: Player[]; -} - -export interface PlayerIdentity2 { - Subject: string; - PlayerCardID: string; - PlayerTitleID: string; - AccountLevel: number; - PreferredLevelBorderID: string; - Incognito: boolean; - HideAccountLevel: boolean; -} - -export interface SeasonalBadgeInfo2 { - SeasonID: string; - NumberOfWins: number; - WinsByTier?: any; - Rank: number; - LeaderboardRank: number; -} - -export interface Player2 { - Subject: string; - CharacterID: string; - CharacterSelectionState: string; - PregamePlayerState: string; - CompetitiveTier: number; - PlayerIdentity: PlayerIdentity2; - SeasonalBadgeInfo: SeasonalBadgeInfo2; - IsCaptain: boolean; -} - -export interface AllyTeam { - TeamID: string; - Players: Player2[]; -} - -export interface CastedVotes {} - -export interface PregameMatch { - ID: string; - Version: number; - Teams: Team[]; - AllyTeam: AllyTeam; - EnemyTeam?: any; - ObserverSubjects: any[]; - MatchCoaches: any[]; - EnemyTeamSize: number; - EnemyTeamLockCount: number; - PregameState: string; - LastUpdated: Date; - MapID: string; - MapSelectPool: any[]; - BannedMapIDs: any[]; - CastedVotes: CastedVotes; - MapSelectSteps: any[]; - MapSelectStep: number; - Team1: string; - GamePodID: string; - Mode: string; - VoiceSessionID: string; - MUCName: string; - QueueID: string; - ProvisioningFlowID: string; - IsRanked: boolean; - PhaseTimeRemainingNS: number; - StepTimeRemainingNS: number; - altModesFlagADA: boolean; - TournamentMetadata?: any; - RosterMetadata?: any; -} - -export type EntitlementsByCategory = Record; - -export type ValorantLoadout = { - Guns: Array<{ - ID: string; - SkinID: string; - SkinLevelID: string; - ChromaID: string; - Attachments: Array; - }>; - ActiveExpressions: Array<{ - TypeID: string; - AssetID: string; - }>; - Identity: { - PlayerCardID: string; - PlayerTitleID: string; - AccountLevel: number; - PreferredLevelBorderID: string; - HideAccountLevel: boolean; - }; - Incognito: boolean; -}; - -export type PlayerCard = { - uuid: string; - displayName: string; - isHiddenIfNotOwned: boolean; - themeUuid: string; - displayIcon: string; - smallArt: string; - wideArt: string; - largeArt: string; - assetPath: string; -}; - -export type SprayLevel = { - uuid: string; - sprayLevel: number; - displayName: string; - displayIcon: string; - assetPath: string; -}; - -export type Spray = { - uuid: string; - displayName: string; - category: string; - themeUuid: string; - displayIcon: string; - fullIcon: string; - fullTransparentIcon: string; - animationPng: string; - animationGif: string; - assetPath: string; - levels: SprayLevel[]; -}; - -export type Flex = { - uuid: string; - displayName: string; - displayIcon: string; - assetPath: string; -}; - -export type PlayerTitle = { - uuid: string; - displayName: string; - titleText: string; - isHiddenIfNotOwned: boolean; - assetPath: string; -}; - -export type Role = { - uuid: string; - displayName: string; - description: string; - displayIcon: string; - assetPath: string; -}; - -export type Ability = { - slot: string; - displayName: string; - description: string; - displayIcon: string; -}; - -export type MediaList = { - id: number; - wwise: string; - wave: string; -}; - -export type VoiceLine = { - minDuration: number; - maxDuration: number; - mediaList: MediaList[]; -}; - -export type Agent = { - uuid: string; - displayName: string; - description: string; - developerName: string; - characterTags: string[]; - displayIcon: string; - displayIconSmall: string; - bustPortrait: string; - fullPortrait: string; - fullPortraitV2: string; - killfeedPortrait: string; - background: string; - backgroundGradientColors: string[]; - assetPath: string; - isFullPortraitRightFacing: boolean; - isPlayableCharacter: boolean; - isAvailableForTest: boolean; - isBaseContent: boolean; - role: Role; - abilities: Ability[]; - voiceLine: VoiceLine; -}; diff --git a/vite.config.ts b/vite.config.ts index b1adcd5..85695e3 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,21 +1,34 @@ import { reactRouter } from "@react-router/dev/vite"; -import autoprefixer from "autoprefixer"; -import tailwindcss from "tailwindcss"; +import tailwindcss from "@tailwindcss/vite"; import { defineConfig } from "vite"; import tsconfigPaths from "vite-tsconfig-paths"; -export default defineConfig(({ isSsrBuild }) => ({ - build: { - rollupOptions: isSsrBuild - ? { - input: "./server/app.ts", - } - : undefined, - }, - css: { - postcss: { - plugins: [tailwindcss, autoprefixer], - }, - }, - plugins: [reactRouter(), tsconfigPaths()], +// @ts-expect-error process is a nodejs global +const host = process.env.TAURI_DEV_HOST; + +// https://vite.dev/config/ +export default defineConfig(async () => ({ + plugins: [tailwindcss(), reactRouter(), tsconfigPaths()], + + // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build` + // + // 1. prevent Vite from obscuring rust errors + clearScreen: false, + // 2. tauri expects a fixed port, fail if that port is not available + server: { + port: 1420, + strictPort: true, + host: host || false, + hmr: host + ? { + protocol: "ws", + host, + port: 1421, + } + : undefined, + watch: { + // 3. tell Vite to ignore watching `src-tauri` + ignored: ["**/src-tauri/**"], + }, + }, }));