From 1775fac5fd112eadb06aa0aa013bced29cd02d7a Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Mon, 7 Jul 2025 22:42:49 +0200 Subject: [PATCH 01/13] Refactor sessions to frequently rotate In order to minimise the window of opportunity to steal a session, automatically rotate it onto a new session on a frequent basis. This makes a session cookie older than the automatic rollover time less likely to grant access and more likely to be detected. Should a stolen session cookie get rotated while the attacker is using it, the user will be notificed that their session has been taken the next time they open the app if the user re-visits the website before the session is discarded. --- docs/admin/config.md | 17 +++++ docs/dev/sessions.md | 13 ++++ nuxt.config.ts | 4 + server/api/admin/database-import.post.ts | 2 +- server/api/admin/user.patch.ts | 19 ++++- server/api/auth/account.delete.ts | 8 +- server/api/auth/account.patch.ts | 4 +- server/api/auth/account.post.ts | 2 +- server/api/auth/session.delete.ts | 7 +- server/api/auth/session.get.ts | 10 +-- server/api/events.ts | 5 +- server/api/schedule.patch.ts | 6 +- server/api/schedule.ts | 4 +- server/api/subscribe.post.ts | 2 +- server/api/unsubscribe.post.ts | 2 +- server/api/users/index.get.ts | 6 +- server/database.ts | 34 ++------- server/utils/session.ts | 96 ++++++++++++++++++++---- 18 files changed, 168 insertions(+), 73 deletions(-) create mode 100644 docs/admin/config.md create mode 100644 docs/dev/sessions.md diff --git a/docs/admin/config.md b/docs/admin/config.md new file mode 100644 index 0000000..1dbc6c8 --- /dev/null +++ b/docs/admin/config.md @@ -0,0 +1,17 @@ + +# Configuration + +## Environment Variables + +### NUXT_SESSION_EXPIRES_TIMEOUT + +Time in seconds before a session is considered expired and need to be rotated over into a new session. When an endpoint using a session is hit after the session expires but before the session is discarded a new session is created as the successor with a new expiry and discard timeout. The old session then considered to have been superceeded and any requests using the old session will result in a 403 Forbidden with the message the session has been taken. + +### NUXT_SESSION_DISCARD_TIMEOUT + +Time in seconds before a session is deleted from the client and server, resulting in the user having to authenticate again if the session wasn't rotated over into a new session before this timeout. + +This should be several times greater that `NUXT_SESSION_EXPIRES_TIMEOUT`. diff --git a/docs/dev/sessions.md b/docs/dev/sessions.md new file mode 100644 index 0000000..6ae7967 --- /dev/null +++ b/docs/dev/sessions.md @@ -0,0 +1,13 @@ + +# Sessions + +When a user creates a new account or logs in to an existing account a session is created on the server and linked to the user's browser via a session cookie. This cookie contains a unique identifier along with a HMAC signature created using the server's cookie secret key. Since this unique identifier stored on the user's device is a technical requirement to securely do what the user is requesting the user's consent to its storage can be assumed. + +Sessions have two future times associated with them: The expiration time is the point in time after the session will be recreated and the cookie reassigned, and the discard time is when the session is deleted from both the client and the server. The expiriation time is short, by default 1 hour, while the discard time is long, by default 2 weeks. + +When a request is made to a session that's past the expiration time a new session is created to replace the existing one, and the session cookie is updated with the new session. The purpose of this is to reduce the time window a stolen session can be used in without being detected. If a request is made using a session that has already been replaced the server responds with a message saying the "session has been taken". + +Sessions are created for a limited timespan, purpose and access level, and expires after the timespan is over, the purpose is fulfilled or the access level changes. For example if the user's account is promoted from regular to crew the session will no longer be valid and will be recreated as a new session with the new access level on the next request. diff --git a/nuxt.config.ts b/nuxt.config.ts index abf656d..71b5233 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -4,6 +4,8 @@ */ // https://nuxt.com/docs/api/configuration/nuxt-config const enableDevtools = !process.env.DISABLE_DEV_TOOLS +const oneHourSeconds = 60 * 60; +const oneDaySeconds = 24 * oneHourSeconds; export default defineNuxtConfig({ experimental: { renderJsonPayloads: true }, compatibilityDate: '2024-11-01', @@ -21,6 +23,8 @@ export default defineNuxtConfig({ }, runtimeConfig: { cookieSecretKeyFile: "", + sessionExpiresTimeout: 1 * oneHourSeconds, + sessionDiscardTimeout: 14 * oneDaySeconds, vapidSubject: "", vapidPrivateKeyFile: "", public: { diff --git a/server/api/admin/database-import.post.ts b/server/api/admin/database-import.post.ts index 3449a84..f4e6019 100644 --- a/server/api/admin/database-import.post.ts +++ b/server/api/admin/database-import.post.ts @@ -40,7 +40,7 @@ export default defineEventHandler(async (event) => { // Only keep sessions that match the account id in both sets to avoid // resurrecting deleted sessions. This will still cause session cross // pollution if a snapshot from another instance is loaded here. - return current && current.account.id === session.account.id; + return current?.accountId !== undefined && current.accountId === session.accountId; })); await writeSubscriptions(snapshot.subscriptions); await writeSchedule(snapshot.schedule); diff --git a/server/api/admin/user.patch.ts b/server/api/admin/user.patch.ts index 0acc771..bdcf099 100644 --- a/server/api/admin/user.patch.ts +++ b/server/api/admin/user.patch.ts @@ -2,7 +2,7 @@ SPDX-FileCopyrightText: © 2025 Hornwitser SPDX-License-Identifier: AGPL-3.0-or-later */ -import { readUsers, writeUsers } from "~/server/database"; +import { readSessions, readUsers, writeSessions, writeUsers } from "~/server/database"; import { apiUserPatchSchema } from "~/shared/types/api"; import { z } from "zod/v4-mini"; import { broadcastEvent } from "~/server/streams"; @@ -29,7 +29,8 @@ export default defineEventHandler(async (event) => { } - if (patch.type) { + let accessChanged = false; + if (patch.type && patch.type !== user.type) { if (patch.type === "anonymous" || user.type === "anonymous") { throw createError({ status: 409, @@ -38,6 +39,7 @@ export default defineEventHandler(async (event) => { }); } user.type = patch.type; + accessChanged = true; } if (patch.name) { if (user.type === "anonymous") { @@ -54,7 +56,18 @@ export default defineEventHandler(async (event) => { broadcastEvent({ type: "user-update", data: serverUserToApi(user), - }) + }); + + // Expire sessions with the user in it if the access changed + if (accessChanged) { + const sessions = await readSessions(); + for (const session of sessions) { + if (session.accountId === user.id) { + session.expiresAtMs = 0; + } + } + await writeSessions(sessions); + } // Update Schedule counts. await updateScheduleInterestedCounts(users); diff --git a/server/api/auth/account.delete.ts b/server/api/auth/account.delete.ts index bf62f7f..7506531 100644 --- a/server/api/auth/account.delete.ts +++ b/server/api/auth/account.delete.ts @@ -9,20 +9,20 @@ import { import { broadcastEvent, cancelAccountStreams } from "~/server/streams"; export default defineEventHandler(async (event) => { - const serverSession = await requireServerSession(event); + const serverSession = await requireServerSessionWithUser(event); let users = await readUsers(); // Remove sessions for this user const removedSessionIds = new Set(); let sessions = await readSessions(); sessions = sessions.filter(session => { - if (session.account.id === serverSession.account.id) { + if (session.accountId === serverSession.accountId) { removedSessionIds.add(session.id); return false; } return true; }); - cancelAccountStreams(serverSession.account.id); + cancelAccountStreams(serverSession.accountId); await writeSessions(sessions); await deleteCookie(event, "session"); @@ -34,7 +34,7 @@ export default defineEventHandler(async (event) => { await writeSubscriptions(subscriptions); // Remove the user - const account = users.find(user => user.id === serverSession.account.id)!; + const account = users.find(user => user.id === serverSession.accountId)!; const now = new Date().toISOString(); account.deleted = true; account.updatedAt = now; diff --git a/server/api/auth/account.patch.ts b/server/api/auth/account.patch.ts index dc228e9..75c65ea 100644 --- a/server/api/auth/account.patch.ts +++ b/server/api/auth/account.patch.ts @@ -9,7 +9,7 @@ import { z } from "zod/v4-mini"; export default defineEventHandler(async (event) => { - const session = await requireServerSession(event); + const session = await requireServerSessionWithUser(event); const { success, error, data: patch } = apiAccountPatchSchema.safeParse(await readBody(event)); if (!success) { throw createError({ @@ -39,7 +39,7 @@ export default defineEventHandler(async (event) => { } const users = await readUsers(); - const account = users.find(user => user.id === session.account.id); + const account = users.find(user => user.id === session.accountId); if (!account) { throw Error("Account does not exist"); } diff --git a/server/api/auth/account.post.ts b/server/api/auth/account.post.ts index d393cfe..527215c 100644 --- a/server/api/auth/account.post.ts +++ b/server/api/auth/account.post.ts @@ -6,7 +6,7 @@ import { readUsers, writeUsers, nextUserId, type ServerUser } from "~/server/dat import { broadcastEvent } from "~/server/streams"; export default defineEventHandler(async (event) => { - let session = await getServerSession(event); + let session = await getServerSession(event, false); if (session) { throw createError({ status: 409, diff --git a/server/api/auth/session.delete.ts b/server/api/auth/session.delete.ts index 29c6756..ca24eaf 100644 --- a/server/api/auth/session.delete.ts +++ b/server/api/auth/session.delete.ts @@ -2,12 +2,15 @@ SPDX-FileCopyrightText: © 2025 Hornwitser SPDX-License-Identifier: AGPL-3.0-or-later */ +import { readUsers } from "~/server/database"; import { cancelSessionStreams } from "~/server/streams"; export default defineEventHandler(async (event) => { - const session = await getServerSession(event); + const session = await getServerSession(event, true); if (session) { - if (session.account.type === "anonymous") { + const users = await readUsers(); + const account = users.find(user => user.id === session.accountId); + if (account?.type === "anonymous") { throw createError({ status: 409, message: "Cannot log out of an anonymous account", diff --git a/server/api/auth/session.get.ts b/server/api/auth/session.get.ts index 99c7107..f63f355 100644 --- a/server/api/auth/session.get.ts +++ b/server/api/auth/session.get.ts @@ -2,23 +2,23 @@ SPDX-FileCopyrightText: © 2025 Hornwitser SPDX-License-Identifier: AGPL-3.0-or-later */ -import { readSubscriptions } from "~/server/database"; +import { readSubscriptions, readUsers } from "~/server/database"; import type { ApiSession } from "~/shared/types/api"; export default defineEventHandler(async (event): Promise => { - const session = await getServerSession(event); + const session = await getServerSession(event, false); if (!session) return; + const users = await readUsers(); + const account = users.find(user => user.id === session.accountId); const subscriptions = await readSubscriptions(); const push = Boolean( subscriptions.find(sub => sub.type === "push" && sub.sessionId === session.id) ); - await refreshServerSession(event, session); - return { id: session.id, - account: session.account, + account, push, }; }) diff --git a/server/api/events.ts b/server/api/events.ts index 92cb35f..140c52e 100644 --- a/server/api/events.ts +++ b/server/api/events.ts @@ -6,8 +6,7 @@ import { pipeline } from "node:stream"; import { addStream, deleteStream } from "~/server/streams"; export default defineEventHandler(async (event) => { - const session = await getServerSession(event); - const accountId = session?.account.id; + const session = await getServerSession(event, false); const encoder = new TextEncoder(); const source = event.headers.get("x-forwarded-for"); @@ -26,7 +25,7 @@ export default defineEventHandler(async (event) => { deleteStream(stream.writable); } }) - addStream(stream.writable, session?.id, accountId); + addStream(stream.writable, session?.id, session?.accountId); // Workaround to properly handle stream errors. See https://github.com/unjs/h3/issues/986 setHeader(event, "Access-Control-Allow-Origin", "*"); diff --git a/server/api/schedule.patch.ts b/server/api/schedule.patch.ts index 364818d..49d365b 100644 --- a/server/api/schedule.patch.ts +++ b/server/api/schedule.patch.ts @@ -9,9 +9,9 @@ import { apiScheduleSchema } from "~/shared/types/api"; import { applyUpdatesToArray } from "~/shared/utils/update"; export default defineEventHandler(async (event) => { - const session = await requireServerSession(event); + const session = await requireServerSessionWithUser(event); - if (session.account.type !== "admin" && session.account.type !== "crew") { + if (session.access !== "admin" && session.access !== "crew") { throw createError({ status: 403, statusMessage: "Forbidden", @@ -45,7 +45,7 @@ export default defineEventHandler(async (event) => { } // Validate edit restrictions for crew - if (session.account.type === "crew") { + if (session.access === "crew") { if (update.locations?.length) { throw createError({ status: 403, diff --git a/server/api/schedule.ts b/server/api/schedule.ts index 4c59437..a9ab848 100644 --- a/server/api/schedule.ts +++ b/server/api/schedule.ts @@ -5,7 +5,7 @@ import { readSchedule } from "~/server/database"; export default defineEventHandler(async (event) => { - const session = await getServerSession(event); + const session = await getServerSession(event, false); const schedule = await readSchedule(); - return canSeeCrew(session?.account.type) ? schedule : filterSchedule(schedule); + return canSeeCrew(session?.access) ? schedule : filterSchedule(schedule); }); diff --git a/server/api/subscribe.post.ts b/server/api/subscribe.post.ts index 1528239..9c4a76a 100644 --- a/server/api/subscribe.post.ts +++ b/server/api/subscribe.post.ts @@ -11,7 +11,7 @@ const subscriptionSchema = z.strictObject({ }); export default defineEventHandler(async (event) => { - const session = await requireServerSession(event); + const session = await requireServerSessionWithUser(event); const { success, error, data: body } = subscriptionSchema.safeParse(await readBody(event)); if (!success) { throw createError({ diff --git a/server/api/unsubscribe.post.ts b/server/api/unsubscribe.post.ts index 415a7c9..61a3d51 100644 --- a/server/api/unsubscribe.post.ts +++ b/server/api/unsubscribe.post.ts @@ -5,7 +5,7 @@ import { readSubscriptions, writeSubscriptions } from "~/server/database"; export default defineEventHandler(async (event) => { - const session = await requireServerSession(event); + const session = await requireServerSessionWithUser(event); const subscriptions = await readSubscriptions(); const existingIndex = subscriptions.findIndex( sub => sub.type === "push" && sub.sessionId === session.id diff --git a/server/api/users/index.get.ts b/server/api/users/index.get.ts index 9cb4ac2..f6365fd 100644 --- a/server/api/users/index.get.ts +++ b/server/api/users/index.get.ts @@ -5,13 +5,13 @@ import { readUsers } from "~/server/database" export default defineEventHandler(async (event) => { - const session = await requireServerSession(event); + const session = await requireServerSessionWithUser(event); const users = await readUsers(); - if (session.account.type === "admin") { + if (session.access === "admin") { return users.map(serverUserToApi); } - if (session.account.type === "crew") { + if (session.access === "crew") { return users.filter(u => u.type === "crew" || u.type === "admin").map(serverUserToApi); } throw createError({ diff --git a/server/database.ts b/server/database.ts index eeae873..b369e24 100644 --- a/server/database.ts +++ b/server/database.ts @@ -7,15 +7,14 @@ import type { ApiSchedule, ApiSubscription, ApiUserType } from "~/shared/types/a import type { Id } from "~/shared/types/common"; export interface ServerSession { - id: number, - account: ServerUser, + id: Id, + access: ApiUserType, + accountId?: number, + expiresAtMs: number, + discardAtMs: number, + successor?: Id, }; -interface StoredSession { - id: number, - accountId: number, -} - export interface ServerUser { id: Id, updatedAt: string, @@ -131,26 +130,9 @@ export async function nextSessionId() { } export async function readSessions() { - const users = await readUsers(); - const sessions: ServerSession[] = []; - for (const stored of await readJson(sessionsPath, [])) { - const user = users.find(user => user.id === stored.accountId); - if (user) { - sessions.push({ - id: stored.id, - account: user, - }); - } - } - return sessions; + return readJson(sessionsPath, []) } export async function writeSessions(sessions: ServerSession[]) { - const stored: StoredSession[] = sessions.map( - session => ({ - id: session.id, - accountId: session.account.id, - }), - ); - await writeFile(sessionsPath, JSON.stringify(stored, undefined, "\t") + "\n", "utf-8"); + await writeFile(sessionsPath, JSON.stringify(sessions, undefined, "\t") + "\n", "utf-8"); } diff --git a/server/utils/session.ts b/server/utils/session.ts index 4575eb9..c33d3c7 100644 --- a/server/utils/session.ts +++ b/server/utils/session.ts @@ -3,9 +3,16 @@ SPDX-License-Identifier: AGPL-3.0-or-later */ import type { H3Event } from "h3"; -import { nextSessionId, readSessions, readSubscriptions, type ServerSession, type ServerUser, writeSessions, writeSubscriptions } from "~/server/database"; - -const oneYearSeconds = 365 * 24 * 60 * 60; +import { + nextSessionId, + readSessions, + readSubscriptions, + readUsers, + type ServerSession, + type ServerUser, + writeSessions, + writeSubscriptions +} from "~/server/database"; async function removeSessionSubscription(sessionId: number) { const subscriptions = await readSubscriptions(); @@ -40,48 +47,105 @@ export async function clearServerSession(event: H3Event) { export async function setServerSession(event: H3Event, account: ServerUser) { const sessions = await readSessions(); + const runtimeConfig = useRuntimeConfig(event); await clearServerSessionInternal(event, sessions); + const now = Date.now(); const newSession: ServerSession = { - account, + accountId: account.id, + access: account.type, + expiresAtMs: now + runtimeConfig.sessionExpiresTimeout * 1000, + discardAtMs: now + runtimeConfig.sessionDiscardTimeout * 1000, id: await nextSessionId(), }; sessions.push(newSession); await writeSessions(sessions); - await setSignedCookie(event, "session", String(newSession.id), oneYearSeconds) + await setSignedCookie(event, "session", String(newSession.id), runtimeConfig.sessionDiscardTimeout) } -export async function refreshServerSession(event: H3Event, session: ServerSession) { - await setSignedCookie(event, "session", String(session.id), oneYearSeconds) +async function rotateSession(event: H3Event, sessions: ServerSession[], session: ServerSession) { + const runtimeConfig = useRuntimeConfig(event); + const users = await readUsers(); + const account = users.find(user => user.id === session.accountId); + const now = Date.now(); + const newSession: ServerSession = { + accountId: account?.id, + access: account?.type ?? "anonymous", + expiresAtMs: now + runtimeConfig.sessionExpiresTimeout * 1000, + discardAtMs: now + runtimeConfig.sessionDiscardTimeout * 1000, + id: await nextSessionId(), + }; + session.successor = newSession.id; + sessions.push(newSession); + await writeSessions(sessions); + await setSignedCookie(event, "session", String(newSession.id), runtimeConfig.sessionDiscardTimeout) + return newSession; } -export async function getServerSession(event: H3Event) { +export async function getServerSession(event: H3Event, ignoreExpired: boolean) { const sessionCookie = await getSignedCookie(event, "session"); if (sessionCookie) { const sessionId = parseInt(sessionCookie, 10); const sessions = await readSessions(); - return sessions.find(session => session.id === sessionId); + const session = sessions.find(session => session.id === sessionId); + if (session) { + if (!ignoreExpired && session.successor !== undefined) { + throw createError({ + statusCode: 403, + statusMessage: "Forbidden", + message: "Session has been taken by another agent.", + }); + } + const now = Date.now(); + if (now >= session?.discardAtMs) { + return undefined; + } + if (!ignoreExpired && now >= session?.expiresAtMs) { + return await rotateSession(event, sessions, session); + } + } + return session; } } -export async function requireServerSession(event: H3Event) { - const session = await getServerSession(event); +export async function requireServerSession(event: H3Event, message: string) { + const session = await getServerSession(event, false); if (!session) throw createError({ - status: 401, - message: "Account session required", + statusCode: 401, + statusMessage: "Unauthorized", + message, }); return session; } +export async function requireServerSessionWithUser(event: H3Event) { + const message = "User session required"; + const session = await requireServerSession(event, message); + const users = await readUsers(); + const account = users.find(user => user.id === session.accountId); + if (session.accountId === undefined || !account) + throw createError({ + statusCode: 401, + statusMessage: "Uauthorized", + message, + }); + return { ...session, accountId: session.accountId }; +} + + export async function requireServerSessionWithAdmin(event: H3Event) { - const session = await requireServerSession(event); - if (session.account.type !== "admin") { + const message = "Admin session required"; + const session = await requireServerSession(event, message); + const users = await readUsers(); + const account = users.find(user => user.id === session.accountId); + if (session.access !== "admin" || account?.type !== "admin") { throw createError({ statusCode: 403, statusMessage: "Forbidden", + message, }); } - return session; + return { ...session, accountId: session.accountId }; } From ce1eab7ede3b9924564f91e59ccb2619bccc90e0 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Mon, 7 Jul 2025 22:51:15 +0200 Subject: [PATCH 02/13] Fix syntax error in .editorconfig --- .editorconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index 24ba2ba..81333b6 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,6 +10,6 @@ indent_style = tab insert_final_newline = true trim_trailing_whitespace = true -*{.yaml,.yml}] +[*{.yaml,.yml}] indent_size = 2 indent_style = space From 2d5af785688ccc9885a8eec852622e7ac23f4726 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Mon, 7 Jul 2025 23:40:27 +0200 Subject: [PATCH 03/13] Update dependencies --- package.json | 22 +- pnpm-lock.yaml | 3191 +++++++++++++++++++++++++----------------------- 2 files changed, 1706 insertions(+), 1507 deletions(-) diff --git a/package.json b/package.json index 27771cf..7f6cd85 100644 --- a/package.json +++ b/package.json @@ -11,14 +11,14 @@ "postinstall": "nuxt prepare" }, "dependencies": { - "@pinia/nuxt": "0.11.0", - "luxon": "^3.5.0", - "nuxt": "^3.17.4", - "pinia": "^3.0.2", - "vue": "latest", - "vue-router": "latest", + "@pinia/nuxt": "^0.11.1", + "luxon": "^3.6.1", + "nuxt": "^3.17.6", + "pinia": "^3.0.3", + "vue": "^3.5.17", + "vue-router": "^4.5.1", "web-push": "^3.6.7", - "zod": "^3.25.30" + "zod": "^3.25.75" }, "packageManager": "pnpm@10.5.2+sha512.da9dc28cd3ff40d0592188235ab25d3202add8a207afbedc682220e4a0029ffbff4562102b9e6e46b4e3f9e8bd53e6d05de48544b0c57d4b0179e22c76d1199b", "pnpm": { @@ -28,11 +28,11 @@ ] }, "devDependencies": { - "@nuxt/test-utils": "^3.19.1", - "@types/luxon": "^3.4.2", + "@nuxt/test-utils": "^3.19.2", + "@types/luxon": "^3.6.2", "@types/web-push": "^3.6.4", "happy-dom": "^17.6.3", - "vitest": "^3.2.3", - "vue-tsc": "^2.2.10" + "vitest": "^3.2.4", + "vue-tsc": "^3.0.1" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f79869d..b1a4ccf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,36 +9,36 @@ importers: .: dependencies: '@pinia/nuxt': - specifier: 0.11.0 - version: 0.11.0(magicast@0.3.5)(pinia@3.0.2(typescript@5.8.2)(vue@3.5.14(typescript@5.8.2))) + specifier: ^0.11.1 + version: 0.11.1(magicast@0.3.5)(pinia@3.0.3(typescript@5.8.3)(vue@3.5.17(typescript@5.8.3))) luxon: - specifier: ^3.5.0 - version: 3.5.0 + specifier: ^3.6.1 + version: 3.6.1 nuxt: - specifier: ^3.17.4 - version: 3.17.4(@parcel/watcher@2.5.1)(@types/node@22.13.8)(db0@0.3.2)(ioredis@5.6.1)(magicast@0.3.5)(rollup@4.41.0)(terser@5.39.0)(typescript@5.8.2)(vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))(vue-tsc@2.2.10(typescript@5.8.2))(yaml@2.7.0) + specifier: ^3.17.6 + version: 3.17.6(@parcel/watcher@2.5.1)(@types/node@24.0.10)(@vue/compiler-sfc@3.5.17)(db0@0.3.2)(ioredis@5.6.1)(magicast@0.3.5)(rollup@4.44.2)(terser@5.43.1)(typescript@5.8.3)(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0))(vue-tsc@3.0.1(typescript@5.8.3))(yaml@2.8.0) pinia: - specifier: ^3.0.2 - version: 3.0.2(typescript@5.8.2)(vue@3.5.14(typescript@5.8.2)) + specifier: ^3.0.3 + version: 3.0.3(typescript@5.8.3)(vue@3.5.17(typescript@5.8.3)) vue: specifier: latest - version: 3.5.14(typescript@5.8.2) + version: 3.5.17(typescript@5.8.3) vue-router: specifier: latest - version: 4.5.1(vue@3.5.14(typescript@5.8.2)) + version: 4.5.1(vue@3.5.17(typescript@5.8.3)) web-push: specifier: ^3.6.7 version: 3.6.7 zod: - specifier: ^3.25.30 - version: 3.25.30 + specifier: ^3.25.75 + version: 3.25.75 devDependencies: '@nuxt/test-utils': - specifier: ^3.19.1 - version: 3.19.1(@types/node@22.13.8)(happy-dom@17.6.3)(jiti@2.4.2)(magicast@0.3.5)(terser@5.39.0)(typescript@5.8.2)(vitest@3.2.3(@types/node@22.13.8)(happy-dom@17.6.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))(yaml@2.7.0) + specifier: ^3.19.2 + version: 3.19.2(happy-dom@17.6.3)(magicast@0.3.5)(typescript@5.8.3)(vitest@3.2.4(@types/node@24.0.10)(happy-dom@17.6.3)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0)) '@types/luxon': - specifier: ^3.4.2 - version: 3.4.2 + specifier: ^3.6.2 + version: 3.6.2 '@types/web-push': specifier: ^3.6.4 version: 3.6.4 @@ -46,11 +46,11 @@ importers: specifier: ^17.6.3 version: 17.6.3 vitest: - specifier: ^3.2.3 - version: 3.2.3(@types/node@22.13.8)(happy-dom@17.6.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) + specifier: ^3.2.4 + version: 3.2.4(@types/node@24.0.10)(happy-dom@17.6.3)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0) vue-tsc: - specifier: ^2.2.10 - version: 2.2.10(typescript@5.8.2) + specifier: ^3.0.1 + version: 3.0.1(typescript@5.8.3) packages: @@ -62,20 +62,20 @@ packages: resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.27.2': - resolution: {integrity: sha512-TUtMJYRPyUb/9aU8f3K0mjmjf6M9N5Woshn2CS6nqJSeJtTtQcpLUXjGt9vbF8ZGff0El99sWkLgzwW3VXnxZQ==} + '@babel/compat-data@7.28.0': + resolution: {integrity: sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==} engines: {node: '>=6.9.0'} - '@babel/core@7.27.1': - resolution: {integrity: sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==} + '@babel/core@7.28.0': + resolution: {integrity: sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==} engines: {node: '>=6.9.0'} - '@babel/generator@7.27.1': - resolution: {integrity: sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w==} + '@babel/generator@7.28.0': + resolution: {integrity: sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==} engines: {node: '>=6.9.0'} - '@babel/helper-annotate-as-pure@7.27.1': - resolution: {integrity: sha512-WnuuDILl9oOBbKnb4L+DyODx7iC47XfzmNCpTttFsSp6hTG7XZxu60+4IO+2/hPfcGOoKbFiwoI/+zwARbNQow==} + '@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.27.2': @@ -88,6 +88,10 @@ packages: 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.27.1': resolution: {integrity: sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==} engines: {node: '>=6.9.0'} @@ -96,8 +100,8 @@ packages: resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.27.1': - resolution: {integrity: sha512-9yHn519/8KvTU5BjTVEEeIM3w9/2yXNKoD82JifINImhpKkARMJKPP59kLo+BafpdN5zgNeIcS4jsGDmd3l58g==} + '@babel/helper-module-transforms@7.27.3': + resolution: {integrity: sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -132,17 +136,17 @@ packages: resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.27.1': - resolution: {integrity: sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==} + '@babel/helpers@7.27.6': + resolution: {integrity: sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==} engines: {node: '>=6.9.0'} - '@babel/parser@7.27.2': - resolution: {integrity: sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==} + '@babel/parser@7.28.0': + resolution: {integrity: sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/plugin-syntax-jsx@7.25.9': - resolution: {integrity: sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==} + '@babel/plugin-syntax-jsx@7.27.1': + resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -153,8 +157,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typescript@7.27.1': - resolution: {integrity: sha512-Q5sT5+O4QUebHdbwKedFBEwRLb02zJ7r4A5Gg2hUoLuU3FjdMcyqcywqUrLCaDsFCxzokf7u9kuy7qz51YUuAg==} + '@babel/plugin-transform-typescript@7.28.0': + resolution: {integrity: sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -163,12 +167,12 @@ packages: resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.27.1': - resolution: {integrity: sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg==} + '@babel/traverse@7.28.0': + resolution: {integrity: sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==} engines: {node: '>=6.9.0'} - '@babel/types@7.27.1': - resolution: {integrity: sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==} + '@babel/types@7.28.0': + resolution: {integrity: sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg==} engines: {node: '>=6.9.0'} '@cloudflare/kv-asset-handler@0.4.0': @@ -186,161 +190,317 @@ packages: resolution: {integrity: sha512-Y6+WUMsTFWE5jb20IFP4YGa5IrGY/+a/FbOSjDF/wz9gepU2hwCYSXRHP/vPwBvwcY3SVMASt4yXxbXNXigmZQ==} engines: {node: '>=18'} - '@emnapi/core@1.4.3': - resolution: {integrity: sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==} + '@emnapi/core@1.4.4': + resolution: {integrity: sha512-A9CnAbC6ARNMKcIcrQwq6HeHCjpcBZ5wSx4U01WXCqEKlrzB9F9315WDNHkrs2xbx7YjjSxbUYxuN6EQzpcY2g==} - '@emnapi/runtime@1.4.3': - resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} + '@emnapi/runtime@1.4.4': + resolution: {integrity: sha512-hHyapA4A3gPaDCNfiqyZUStTMqIkKRshqPIuDOXv1hcBnD4U3l8cP0T1HMCfGRxQ6V64TGCcoswChANyOAwbQg==} - '@emnapi/wasi-threads@1.0.2': - resolution: {integrity: sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==} + '@emnapi/wasi-threads@1.0.3': + resolution: {integrity: sha512-8K5IFFsQqF9wQNJptGbS6FNKgUTsSRYnTqNCG1vPP8jFdjSv18n2mQfJpkt2Oibo9iBEzcDnDxNwKTzC7svlJw==} - '@esbuild/aix-ppc64@0.25.4': - resolution: {integrity: sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==} + '@esbuild/aix-ppc64@0.25.5': + resolution: {integrity: sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.25.4': - resolution: {integrity: sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==} + '@esbuild/aix-ppc64@0.25.6': + resolution: {integrity: sha512-ShbM/3XxwuxjFiuVBHA+d3j5dyac0aEVVq1oluIDf71hUw0aRF59dV/efUsIwFnR6m8JNM2FjZOzmaZ8yG61kw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.25.5': + resolution: {integrity: sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.25.4': - resolution: {integrity: sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==} + '@esbuild/android-arm64@0.25.6': + resolution: {integrity: sha512-hd5zdUarsK6strW+3Wxi5qWws+rJhCCbMiC9QZyzoxfk5uHRIE8T287giQxzVpEvCwuJ9Qjg6bEjcRJcgfLqoA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.5': + resolution: {integrity: sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.25.4': - resolution: {integrity: sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==} + '@esbuild/android-arm@0.25.6': + resolution: {integrity: sha512-S8ToEOVfg++AU/bHwdksHNnyLyVM+eMVAOf6yRKFitnwnbwwPNqKr3srzFRe7nzV69RQKb5DgchIX5pt3L53xg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.5': + resolution: {integrity: sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.25.4': - resolution: {integrity: sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==} + '@esbuild/android-x64@0.25.6': + resolution: {integrity: sha512-0Z7KpHSr3VBIO9A/1wcT3NTy7EB4oNC4upJ5ye3R7taCc2GUdeynSLArnon5G8scPwaU866d3H4BCrE5xLW25A==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.5': + resolution: {integrity: sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.25.4': - resolution: {integrity: sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==} + '@esbuild/darwin-arm64@0.25.6': + resolution: {integrity: sha512-FFCssz3XBavjxcFxKsGy2DYK5VSvJqa6y5HXljKzhRZ87LvEi13brPrf/wdyl/BbpbMKJNOr1Sd0jtW4Ge1pAA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.5': + resolution: {integrity: sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.25.4': - resolution: {integrity: sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==} + '@esbuild/darwin-x64@0.25.6': + resolution: {integrity: sha512-GfXs5kry/TkGM2vKqK2oyiLFygJRqKVhawu3+DOCk7OxLy/6jYkWXhlHwOoTb0WqGnWGAS7sooxbZowy+pK9Yg==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.5': + resolution: {integrity: sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.4': - resolution: {integrity: sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==} + '@esbuild/freebsd-arm64@0.25.6': + resolution: {integrity: sha512-aoLF2c3OvDn2XDTRvn8hN6DRzVVpDlj2B/F66clWd/FHLiHaG3aVZjxQX2DYphA5y/evbdGvC6Us13tvyt4pWg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.5': + resolution: {integrity: sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.25.4': - resolution: {integrity: sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==} + '@esbuild/freebsd-x64@0.25.6': + resolution: {integrity: sha512-2SkqTjTSo2dYi/jzFbU9Plt1vk0+nNg8YC8rOXXea+iA3hfNJWebKYPs3xnOUf9+ZWhKAaxnQNUf2X9LOpeiMQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.25.5': + resolution: {integrity: sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.25.4': - resolution: {integrity: sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==} + '@esbuild/linux-arm64@0.25.6': + resolution: {integrity: sha512-b967hU0gqKd9Drsh/UuAm21Khpoh6mPBSgz8mKRq4P5mVK8bpA+hQzmm/ZwGVULSNBzKdZPQBRT3+WuVavcWsQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.25.5': + resolution: {integrity: sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.25.4': - resolution: {integrity: sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==} + '@esbuild/linux-arm@0.25.6': + resolution: {integrity: sha512-SZHQlzvqv4Du5PrKE2faN0qlbsaW/3QQfUUc6yO2EjFcA83xnwm91UbEEVx4ApZ9Z5oG8Bxz4qPE+HFwtVcfyw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.25.5': + resolution: {integrity: sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.25.4': - resolution: {integrity: sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==} + '@esbuild/linux-ia32@0.25.6': + resolution: {integrity: sha512-aHWdQ2AAltRkLPOsKdi3xv0mZ8fUGPdlKEjIEhxCPm5yKEThcUjHpWB1idN74lfXGnZ5SULQSgtr5Qos5B0bPw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.25.5': + resolution: {integrity: sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.25.4': - resolution: {integrity: sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==} + '@esbuild/linux-loong64@0.25.6': + resolution: {integrity: sha512-VgKCsHdXRSQ7E1+QXGdRPlQ/e08bN6WMQb27/TMfV+vPjjTImuT9PmLXupRlC90S1JeNNW5lzkAEO/McKeJ2yg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.25.5': + resolution: {integrity: sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.25.4': - resolution: {integrity: sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==} + '@esbuild/linux-mips64el@0.25.6': + resolution: {integrity: sha512-WViNlpivRKT9/py3kCmkHnn44GkGXVdXfdc4drNmRl15zVQ2+D2uFwdlGh6IuK5AAnGTo2qPB1Djppj+t78rzw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.5': + resolution: {integrity: sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.25.4': - resolution: {integrity: sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==} + '@esbuild/linux-ppc64@0.25.6': + resolution: {integrity: sha512-wyYKZ9NTdmAMb5730I38lBqVu6cKl4ZfYXIs31Baf8aoOtB4xSGi3THmDYt4BTFHk7/EcVixkOV2uZfwU3Q2Jw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.5': + resolution: {integrity: sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.25.4': - resolution: {integrity: sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==} + '@esbuild/linux-riscv64@0.25.6': + resolution: {integrity: sha512-KZh7bAGGcrinEj4qzilJ4hqTY3Dg2U82c8bv+e1xqNqZCrCyc+TL9AUEn5WGKDzm3CfC5RODE/qc96OcbIe33w==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.25.5': + resolution: {integrity: sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.25.4': - resolution: {integrity: sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==} + '@esbuild/linux-s390x@0.25.6': + resolution: {integrity: sha512-9N1LsTwAuE9oj6lHMyyAM+ucxGiVnEqUdp4v7IaMmrwb06ZTEVCIs3oPPplVsnjPfyjmxwHxHMF8b6vzUVAUGw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.5': + resolution: {integrity: sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.4': - resolution: {integrity: sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==} + '@esbuild/linux-x64@0.25.6': + resolution: {integrity: sha512-A6bJB41b4lKFWRKNrWoP2LHsjVzNiaurf7wyj/XtFNTsnPuxwEBWHLty+ZE0dWBKuSK1fvKgrKaNjBS7qbFKig==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.5': + resolution: {integrity: sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.4': - resolution: {integrity: sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==} + '@esbuild/netbsd-arm64@0.25.6': + resolution: {integrity: sha512-IjA+DcwoVpjEvyxZddDqBY+uJ2Snc6duLpjmkXm/v4xuS3H+3FkLZlDm9ZsAbF9rsfP3zeA0/ArNDORZgrxR/Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.5': + resolution: {integrity: sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.4': - resolution: {integrity: sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==} + '@esbuild/netbsd-x64@0.25.6': + resolution: {integrity: sha512-dUXuZr5WenIDlMHdMkvDc1FAu4xdWixTCRgP7RQLBOkkGgwuuzaGSYcOpW4jFxzpzL1ejb8yF620UxAqnBrR9g==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.5': + resolution: {integrity: sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.4': - resolution: {integrity: sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==} + '@esbuild/openbsd-arm64@0.25.6': + resolution: {integrity: sha512-l8ZCvXP0tbTJ3iaqdNf3pjaOSd5ex/e6/omLIQCVBLmHTlfXW3zAxQ4fnDmPLOB1x9xrcSi/xtCWFwCZRIaEwg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.5': + resolution: {integrity: sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/sunos-x64@0.25.4': - resolution: {integrity: sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==} + '@esbuild/openbsd-x64@0.25.6': + resolution: {integrity: sha512-hKrmDa0aOFOr71KQ/19JC7az1P0GWtCN1t2ahYAf4O007DHZt/dW8ym5+CUdJhQ/qkZmI1HAF8KkJbEFtCL7gw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.25.6': + resolution: {integrity: sha512-+SqBcAWoB1fYKmpWoQP4pGtx+pUUC//RNYhFdbcSA16617cchuryuhOCRpPsjCblKukAckWsV+aQ3UKT/RMPcA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.25.5': + resolution: {integrity: sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.25.4': - resolution: {integrity: sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==} + '@esbuild/sunos-x64@0.25.6': + resolution: {integrity: sha512-dyCGxv1/Br7MiSC42qinGL8KkG4kX0pEsdb0+TKhmJZgCUDBGmyo1/ArCjNGiOLiIAgdbWgmWgib4HoCi5t7kA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.25.5': + resolution: {integrity: sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.25.4': - resolution: {integrity: sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==} + '@esbuild/win32-arm64@0.25.6': + resolution: {integrity: sha512-42QOgcZeZOvXfsCBJF5Afw73t4veOId//XD3i+/9gSkhSV6Gk3VPlWncctI+JcOyERv85FUo7RxuxGy+z8A43Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.25.5': + resolution: {integrity: sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.25.4': - resolution: {integrity: sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==} + '@esbuild/win32-ia32@0.25.6': + resolution: {integrity: sha512-4AWhgXmDuYN7rJI6ORB+uU9DHLq/erBbuMoAuB4VWJTu5KtCgcKYPynF0YI1VkBNuEfjNlLrFr9KZPJzrtLkrQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.25.5': + resolution: {integrity: sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.25.6': + resolution: {integrity: sha512-NgJPHHbEpLQgDH2MjQu90pzW/5vvXIZ7KOnPyNBm92A6WgZ/7b6fJyUBjoumLqeOQQGqY2QjQxRo97ah4Sj0cA==} engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -351,6 +511,14 @@ packages: '@ioredis/commands@1.2.0': resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==} + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} + + '@isaacs/brace-expansion@5.0.0': + resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} + engines: {node: 20 || >=22} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -359,26 +527,21 @@ packages: resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} engines: {node: '>=18.0.0'} - '@jridgewell/gen-mapping@0.3.8': - resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} - engines: {node: '>=6.0.0'} + '@jridgewell/gen-mapping@0.3.12': + resolution: {integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==} '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - '@jridgewell/set-array@1.2.1': - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} + '@jridgewell/source-map@0.3.10': + resolution: {integrity: sha512-0pPkgz9dY+bijgistcTTJ5mR+ocqRXLuhXHYdzoMmmoJ2C9S46RCm2GMUbatPEUK9Yjy26IrAy8D/M00lLkv+Q==} - '@jridgewell/source-map@0.3.6': - resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} + '@jridgewell/sourcemap-codec@1.5.4': + resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==} - '@jridgewell/sourcemap-codec@1.5.0': - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - - '@jridgewell/trace-mapping@0.3.25': - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jridgewell/trace-mapping@0.3.29': + resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==} '@kwsites/file-exists@1.1.1': resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==} @@ -391,8 +554,8 @@ packages: engines: {node: '>=18'} hasBin: true - '@napi-rs/wasm-runtime@0.2.10': - resolution: {integrity: sha512-bCsCyeZEwVErsGmyPNSzwfwFn4OdxBj0mmv6hOFucB/k81Ojdu68RbZdxYsRQUPc9l6SU5F/cG+bXgWs3oUgsQ==} + '@napi-rs/wasm-runtime@0.2.11': + resolution: {integrity: sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA==} '@netlify/binary-info@1.0.0': resolution: {integrity: sha512-4wMPu9iN3/HL97QblBsBay3E1etIciR84izI3U+4iALY+JHCrI+a2jO0qbAZ/nxKoegypYEaiiqWXylm+/zfrw==} @@ -405,8 +568,8 @@ packages: resolution: {integrity: sha512-5XUvZuffe3KetyhbWwd4n2ktd7wraocCYw10tlM+/u/95iAz29GjNiuNxbCD1T6Bn1MyGc4QLVNKOWhzJkVFAw==} engines: {node: ^14.16.0 || >=16.0.0} - '@netlify/functions@3.1.9': - resolution: {integrity: sha512-mbmQIylPzOTDicMFbJF839W3bywJVR0Fm77uvjS6AkDl000VlLwQb+4eO3p0BV7j8+l5IgN/3ltQ/Byi/esTEQ==} + '@netlify/functions@3.1.10': + resolution: {integrity: sha512-sI93kcJ2cUoMgDRPnrEm0lZhuiDVDqM6ngS/UbHTApIH3+eg3yZM5p/0SDFQQq9Bad0/srFmgBmTdXushzY5kg==} engines: {node: '>=14.0.0'} '@netlify/open-api@2.37.0': @@ -421,8 +584,12 @@ packages: resolution: {integrity: sha512-pfCkH50JV06SGMNsNPjn8t17hOcId4fA881HeYQgMBOrewjsw4csaYgHEnCxCEu24Y5x75E2ULbFpqm9CvRCqw==} engines: {node: '>=18.0.0'} - '@netlify/zip-it-and-ship-it@12.1.0': - resolution: {integrity: sha512-+ND2fNnfeOZwnho79aMQ5rreFpI9tu/l4N9/F5H8t9rKYwVHHlv5Zi9o6g/gxZHDLfSbGC9th7Z46CihV8JaZw==} + '@netlify/serverless-functions-api@2.1.3': + resolution: {integrity: sha512-bNlN/hpND8xFQzpjyKxm6vJayD+bPBlOvs4lWihE7WULrphuH1UuFsoVE5386bNNGH8Rs1IH01AFsl7ALQgOlQ==} + engines: {node: '>=18.0.0'} + + '@netlify/zip-it-and-ship-it@12.2.1': + resolution: {integrity: sha512-zAr+8Tg80y/sUbhdUkZsq4Uy1IMzkSB6H/sKRMrDQ2NJx4uPgf5X5jMdg9g2FljNcxzpfJwc1Gg4OXQrjD0Z4A==} engines: {node: '>=18.14.0'} hasBin: true @@ -446,27 +613,27 @@ packages: '@nuxt/devalue@2.0.2': resolution: {integrity: sha512-GBzP8zOc7CGWyFQS6dv1lQz8VVpz5C2yRszbXufwG/9zhStTIH50EtD87NmWbTMwXDvZLNg8GIpb1UFdH93JCA==} - '@nuxt/devtools-kit@2.4.1': - resolution: {integrity: sha512-taA2Nm03JiV3I+SEYS/u1AfjvLm3V9PO8lh0xLsUk/2mlUnL6GZ9xLXrp8VRg11HHt7EPXERGQh8h4iSPU2bSQ==} + '@nuxt/devtools-kit@2.6.2': + resolution: {integrity: sha512-esErdMQ0u3wXXogKQ3IE2m0fxv52w6CzPsfsXF4o5ZVrUQrQaH58ygupDAQTYdlGTgtqmEA6KkHTGG5cM6yxeg==} peerDependencies: vite: '>=6.0' - '@nuxt/devtools-wizard@2.4.1': - resolution: {integrity: sha512-2BaryhfribzQ95UxR7vLLV17Pk1Otxg9ryqH71M1Yp0mybBFs6Z3b0v+RXfCb4BwA10s/tXBhfF13DHSSJF1+A==} + '@nuxt/devtools-wizard@2.6.2': + resolution: {integrity: sha512-s1eYYKi2eZu2ZUPQrf22C0SceWs5/C3c3uow/DVunD304Um/Tj062xM9E4p1B9L8yjaq8t0Gtyu/YvZdo/reyg==} hasBin: true - '@nuxt/devtools@2.4.1': - resolution: {integrity: sha512-2gwjUF1J1Bp/V9ZTsYJe8sS9O3eg80gdf01fT8aEBcilR3wf0PSIxjEyYk+YENtrHPLXcnnUko89jHGq23MHPQ==} + '@nuxt/devtools@2.6.2': + resolution: {integrity: sha512-pqcSDPv1I+8fxa6FvhAxVrfcN/sXYLOBe9scTLbRQOVLTO0pHzryayho678qNKiwWGgj/rcjEDr6IZCgwqOCfA==} hasBin: true peerDependencies: vite: '>=6.0' - '@nuxt/kit@3.17.4': - resolution: {integrity: sha512-l+hY8sy2XFfg3PigZj+PTu6+KIJzmbACTRimn1ew/gtCz+F38f6KTF4sMRTN5CUxiB8TRENgEonASmkAWfpO9Q==} + '@nuxt/kit@3.17.6': + resolution: {integrity: sha512-8PKRwoEF70IXVrpGEJZ4g4V2WtE9RjSMgSZLLa0HZCoyT+QczJcJe3kho/XKnJOnNnHep4WqciTD7p4qRRtBqw==} engines: {node: '>=18.12.0'} - '@nuxt/schema@3.17.4': - resolution: {integrity: sha512-bsfJdWjKNYLkVQt7Ykr9YsAql1u8Tuo6iecSUOltTIhsvAIYsknRFPHoNKNmaiv/L6FgCQgUgQppPTPUAXiJQQ==} + '@nuxt/schema@3.17.6': + resolution: {integrity: sha512-ahm0yz6CrSaZ4pS0iuVod9lVRXNDNIidKWLLBx2naGNM6rW+sdFV9gxjvUS3+rLW+swa4HCKE6J5bjOl//oyqQ==} engines: {node: ^14.18.0 || >=16.10.0} '@nuxt/telemetry@2.6.6': @@ -474,20 +641,20 @@ packages: engines: {node: '>=18.12.0'} hasBin: true - '@nuxt/test-utils@3.19.1': - resolution: {integrity: sha512-qq2ioRgPCM7JwPIeJO2OzzqCWr8NR5eQINoskX2NEXTHzucvb8N9mt2UB2+NUe8OL9yNjGDZA+oA51GUKNhqhg==} - engines: {node: ^18.20.5 || ^20.9.0 || ^22.0.0 || >=23.0.0} + '@nuxt/test-utils@3.19.2': + resolution: {integrity: sha512-jvpCbTNd1e8t2vrGAMpVq8j7N25Jao0NpblRiIYwogXgNXOPrH1XBZxgufyLA701g64SeiplUe+pddtnJnQu/g==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} peerDependencies: '@cucumber/cucumber': ^10.3.1 || ^11.0.0 - '@jest/globals': ^29.5.0 + '@jest/globals': ^29.5.0 || ^30.0.0 '@playwright/test': ^1.43.1 '@testing-library/vue': ^7.0.0 || ^8.0.1 '@vitest/ui': '*' '@vue/test-utils': ^2.4.2 - happy-dom: ^9.10.9 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + happy-dom: ^9.10.9 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 jsdom: ^22.0.0 || ^23.0.0 || ^24.0.0 || ^25.0.0 || ^26.0.0 playwright-core: ^1.43.1 - vitest: ^0.34.6 || ^1.0.0 || ^2.0.0 || ^3.0.0 + vitest: ^3.2.0 peerDependenciesMeta: '@cucumber/cucumber': optional: true @@ -510,97 +677,103 @@ packages: vitest: optional: true - '@nuxt/vite-builder@3.17.4': - resolution: {integrity: sha512-MRcGe02nEDpu+MnRJcmgVfHdzgt9tWvxVdJbhfd6oyX19plw/CANjgHedlpUNUxqeWXC6CQfGvoVJXn3bQlEqA==} + '@nuxt/vite-builder@3.17.6': + resolution: {integrity: sha512-D7bf0BE2nDFj23ryKuSakQFDETt5rpnMTlaoDsRElrApFRvMNzF7pYHuHjvPELsi0UmaqCb8sZn6ki0GALEu2A==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0.0} peerDependencies: vue: ^3.3.4 - '@oxc-parser/binding-darwin-arm64@0.71.0': - resolution: {integrity: sha512-7R7TuHWL2hZ8BbRdxXlVJTE0os7TM6LL2EX2OkIz41B3421JeIU+2YH+IV55spIUy5E5ynesLk0IdpSSPVZ25Q==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-android-arm64@0.75.1': + resolution: {integrity: sha512-hJt8uKPKj0R+3mKCWZLb14lIJ5o2SvVmO/0FwzbBR4Pdrlmp7mWG28Uui1VSIrFVqr47S38dswfCz5StMhGRjA==} + engines: {node: '>=20.0.0'} + cpu: [arm64] + os: [android] + + '@oxc-parser/binding-darwin-arm64@0.75.1': + resolution: {integrity: sha512-uIwpwocl3ot599uPgZMfYC7wpQoL7Cpn6r4jRGss3u2g2och4JVUO8H3BTcne+l/bGGP9FEo58dlKKj27SDzvQ==} + engines: {node: '>=20.0.0'} cpu: [arm64] os: [darwin] - '@oxc-parser/binding-darwin-x64@0.71.0': - resolution: {integrity: sha512-Q7QshRy7cDvpvWAH+qy2U8O9PKo5yEKFqPruD2OSOM8igy/GLIC21dAd6iCcqXRZxaqzN9c4DaXFtEZfq4NWsw==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-darwin-x64@0.75.1': + resolution: {integrity: sha512-Mvt3miySAzXatxPiklsJoPz3yFErNg7sJKnPjBkgn4VCuJjL7Tulbdjkpx/aXGvRA6lPvaxz1hgyeSJ5CU0Arg==} + engines: {node: '>=20.0.0'} cpu: [x64] os: [darwin] - '@oxc-parser/binding-freebsd-x64@0.71.0': - resolution: {integrity: sha512-z8NNBBseLriz2p+eJ8HWC+A8P+MsO8HCtXie9zaVlVcXSiUuBroRWeXopvHN4r+tLzmN2iLXlXprJdNhXNgobQ==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-freebsd-x64@0.75.1': + resolution: {integrity: sha512-sBbrz6EGzKh7u5fzKTxQympWTvmM1u7Xm80OXAVPunZ15+Ky2Q2Xmzys8jlfRsceZwRjeziggS+ysCeT0yhyMA==} + engines: {node: '>=20.0.0'} cpu: [x64] os: [freebsd] - '@oxc-parser/binding-linux-arm-gnueabihf@0.71.0': - resolution: {integrity: sha512-QZQcWMduFRWddqvjgLvsWoeellFjvWqvdI0O1m5hoMEykv2/Ag8d7IZbBwRwFqKBuK4UzpBNt4jZaYzRsv1irg==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-linux-arm-gnueabihf@0.75.1': + resolution: {integrity: sha512-UbzXDqh4IwtF6x1NoxD44esutbe4/+dBzEHle7awCXGFKWPghP/AMGZnA2JYBGHxrxbiQpfueynyvqQThEAYtg==} + engines: {node: '>=20.0.0'} cpu: [arm] os: [linux] - '@oxc-parser/binding-linux-arm-musleabihf@0.71.0': - resolution: {integrity: sha512-lTDc2WCzllVFXugUHQGR904CksA5BiHc35mcH6nJm6h0FCdoyn9zefW8Pelku5ET39JgO1OENEm/AyNvf/FzIw==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-linux-arm-musleabihf@0.75.1': + resolution: {integrity: sha512-cVWiU+UrspdMlp/aMrt1F2l1nxZtrzIkGvIbrKL0hVjOcXvMCp+H2mL07PQ3vnaHo2mt8cPIKv9pd+FoJhgp3w==} + engines: {node: '>=20.0.0'} cpu: [arm] os: [linux] - '@oxc-parser/binding-linux-arm64-gnu@0.71.0': - resolution: {integrity: sha512-mAA6JGS+MB+gbN5y/KuQ095EHYGF7a/FaznM7klk5CaCap/UdiRWCVinVV6xXmejOPZMnrkr6R5Kqi6dHRsm2g==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-linux-arm64-gnu@0.75.1': + resolution: {integrity: sha512-hmCAu+bIq/4b8H07tLZNyIiWL1Prw1ILuTEPPakb1uFV943kg0ZOwEOpV1poBleZrnSjjciWyKRpDRuacBAgyQ==} + engines: {node: '>=20.0.0'} cpu: [arm64] os: [linux] - '@oxc-parser/binding-linux-arm64-musl@0.71.0': - resolution: {integrity: sha512-PaPmIEM0yldXSrO1Icrx6/DwnMXpEOv0bDVa0LFtwy2I+aiTiX7OVRB3pJCg8FEV9P+L48s9XW0Oaz+Dz3o3sQ==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-linux-arm64-musl@0.75.1': + resolution: {integrity: sha512-8ilN7iG7Y4qvXJTuHERPKy5LKcT1ioSGRn7Yyd988tzuR9Cvp4+gJu8azYZnSUJKfNV6SGOEfVnxLabCLRkG/A==} + engines: {node: '>=20.0.0'} cpu: [arm64] os: [linux] - '@oxc-parser/binding-linux-riscv64-gnu@0.71.0': - resolution: {integrity: sha512-+AEGO6gOSSEqWTrCCYayNMMPe/qi83o1czQ5bytEFQtyvWdgLwliqqShpJtgSLj1SNWi94HiA/VOfqqZnGE1AQ==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-linux-riscv64-gnu@0.75.1': + resolution: {integrity: sha512-/JPJXjT/fkG699rlxzLNvQx0URjvzdk7oHln54F159ybgVJKLLWqb8M45Nhw5z6TeaIYyhwIqMNlrA7yb1Rlrw==} + engines: {node: '>=20.0.0'} cpu: [riscv64] os: [linux] - '@oxc-parser/binding-linux-s390x-gnu@0.71.0': - resolution: {integrity: sha512-zqFnheBACFzrRl401ylXufNl1YsOdVa8jwS2iSCwJFx4/JdQhE6Y4YWoEjQ/pzeRZXwI5FX4C607rQe2YdhggQ==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-linux-s390x-gnu@0.75.1': + resolution: {integrity: sha512-t6/E4j+2dT7/4R5hQNX4LBtR1+wxxtJNUVBD89YuiWHPgeEoghqSa0mGMrGyOZPbHMb4V8xdT/CrMMeDpuqRaQ==} + engines: {node: '>=20.0.0'} cpu: [s390x] os: [linux] - '@oxc-parser/binding-linux-x64-gnu@0.71.0': - resolution: {integrity: sha512-steSQTwv3W+/hpES4/9E3vNohou1FXJLNWLDbYHDaBI9gZdYJp6zwALC8EShCz0NoQvCu4THD3IBsTBHvFBNyw==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-linux-x64-gnu@0.75.1': + resolution: {integrity: sha512-zJ2t+d1rV5dcPJHxN3B1Fxc2KDN+gPgdXtlzp0/EH4iO3s5OePpPvTTZA/d1vfPoQFiFOT7VYNmaD9XjHfMQaw==} + engines: {node: '>=20.0.0'} cpu: [x64] os: [linux] - '@oxc-parser/binding-linux-x64-musl@0.71.0': - resolution: {integrity: sha512-mV8j/haQBZRU2QnwZe0UIpnhpPBL9dFk1tgNVSH9tV7cV4xUZPn7pFDqMriAmpD7GLfmxbZMInDkujokd63M7Q==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-linux-x64-musl@0.75.1': + resolution: {integrity: sha512-62hG/1IoOr0hpmGtF2k1MJUzAXLH7DH3fSAttZ1vEvDThhLplqA7jcqOP0IFMIVZ0kt9cA/rW5pF4tnXjiWeSA==} + engines: {node: '>=20.0.0'} cpu: [x64] os: [linux] - '@oxc-parser/binding-wasm32-wasi@0.71.0': - resolution: {integrity: sha512-P8ScINpuihkkBX8BrN/4x4ka2+izncHh7/hHxxuPZDZTVMyNNnL1uSoI80tN9yN7NUtUKoi9aQUaF4h22RQcIA==} + '@oxc-parser/binding-wasm32-wasi@0.75.1': + resolution: {integrity: sha512-txS7vK0EU/1Ey7d1pxGrlp2q/JrxkvLU+r9c3gKxW9mVgvFMQzAxQhuc9tT3ZiS793pkvZ+C1w9GS2DpJi7QYg==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@oxc-parser/binding-win32-arm64-msvc@0.71.0': - resolution: {integrity: sha512-4jrJSdBXHmLYaghi1jvbuJmWu117wxqCpzHHgpEV9xFiRSngtClqZkNqyvcD4907e/VriEwluZ3PO3Mlp0y9cw==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-win32-arm64-msvc@0.75.1': + resolution: {integrity: sha512-/Rw/YLuMaSo8h0QyCniv0UFby5wDTghhswDCcFT2aCCgZaXUVQZrJ+0GJHB8tK72xhe5E6u34etpw/dxxH6E3A==} + engines: {node: '>=20.0.0'} cpu: [arm64] os: [win32] - '@oxc-parser/binding-win32-x64-msvc@0.71.0': - resolution: {integrity: sha512-zF7xF19DOoANym/xwVClYH1tiW3S70W8ZDrMHdrEB7gZiTYLCIKIRMrpLVKaRia6LwEo7X0eduwdBa5QFawxOw==} - engines: {node: '>=14.0.0'} + '@oxc-parser/binding-win32-x64-msvc@0.75.1': + resolution: {integrity: sha512-ThiQUpCG2nYE/bnYM3fjIpcKbxITB/a/cf5VL0VAqtpsGNCzUC7TrwMVUdfBerTBTEZpwxWBf/d1EF1ggrtVfQ==} + engines: {node: '>=20.0.0'} cpu: [x64] os: [win32] - '@oxc-project/types@0.71.0': - resolution: {integrity: sha512-5CwQ4MI+P4MQbjLWXgNurA+igGwu/opNetIE13LBs9+V93R64MLvDKOOLZIXSzEfovU3Zef3q3GjPnMTgJTn2w==} + '@oxc-project/types@0.75.1': + resolution: {integrity: sha512-7ZJy+51qWpZRvynaQUezeYfjCtaSdiXIWFUZIlOuTSfDXpXqnSl/m1IUPLx6XrOy6s0SFv3CLE14vcZy63bz7g==} '@parcel/watcher-android-arm64@2.5.1': resolution: {integrity: sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==} @@ -690,31 +863,29 @@ packages: resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==} engines: {node: '>= 10.0.0'} - '@pinia/nuxt@0.11.0': - resolution: {integrity: sha512-QGFlUAkeVAhPCTXacrtNP4ti24sGEleVzmxcTALY9IkS6U5OUox7vmNL1pkqBeW39oSNq/UC5m40ofDEPHB1fg==} + '@pinia/nuxt@0.11.1': + resolution: {integrity: sha512-tCD8ioWhhIHKwm8Y9VvyhBAV/kK4W5uGBIYbI5iM4N1t7duOqK6ECBUavrMxMolELayqqMLb9+evegrh3S7s2A==} peerDependencies: - pinia: ^3.0.2 + pinia: ^3.0.3 '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@polka/url@1.0.0-next.28': - resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==} + '@polka/url@1.0.0-next.29': + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} - '@poppinss/colors@4.1.4': - resolution: {integrity: sha512-FA+nTU8p6OcSH4tLDY5JilGYr1bVWHpNmcLr7xmMEdbWmKHa+3QZ+DqefrXKmdjO/brHTnQZo20lLSjaO7ydog==} - engines: {node: '>=18.16.0'} + '@poppinss/colors@4.1.5': + resolution: {integrity: sha512-FvdDqtcRCtz6hThExcFOgW0cWX+xwSMWcRuQe5ZEb2m7cVQOAVZOIMt+/v9RxGiD9/OY16qJBXK4CVKWAPalBw==} - '@poppinss/dumper@0.6.3': - resolution: {integrity: sha512-iombbn8ckOixMtuV1p3f8jN6vqhXefNjJttoPaJDMeIk/yIGhkkL3OrHkEjE9SRsgoAx1vBUU2GtgggjvA5hCA==} + '@poppinss/dumper@0.6.4': + resolution: {integrity: sha512-iG0TIdqv8xJ3Lt9O8DrPRxw1MRLjNpoqiSGU03P/wNLP/s0ra0udPJ1J2Tx5M0J3H/cVyEgpbn8xUKRY9j59kQ==} - '@poppinss/exception@1.2.1': - resolution: {integrity: sha512-aQypoot0HPSJa6gDPEPTntc1GT6QINrSbgRlRhadGW2WaYqUK3tK4Bw9SBMZXhmxd3GeAlZjVcODHgiu+THY7A==} - engines: {node: '>=18'} + '@poppinss/exception@1.2.2': + resolution: {integrity: sha512-m7bpKCD4QMlFCjA/nKTs23fuvoVFoA83brRKmObCUNmi/9tVu8Ve3w4YQAnJu4q3Tjf5fr685HYIC/IA2zHRSg==} - '@rolldown/pluginutils@1.0.0-beta.9': - resolution: {integrity: sha512-e9MeMtVWo186sgvFFJOPGy7/d2j2mZhLJIdVW0C/xDluuOvymEATqz6zKsP0ZmXGzQtqlyjz5sC1sYQUoJG98w==} + '@rolldown/pluginutils@1.0.0-beta.24': + resolution: {integrity: sha512-NMiim/enJlffMP16IanVj1ajFNEg8SaMEYyxyYfJoEyt5EiFT3HUH/T2GRdeStNWp+/kg5U8DiJqnQBgLQ8uCw==} '@rollup/plugin-alias@5.1.1': resolution: {integrity: sha512-PR9zDb+rOzkRb2VD+EuKB7UC41vU5DIwZ5qqCpk0KJudcWAyi8rvYOhS7+L5aZCspw1stTViLgN5v6FF1p5cgQ==} @@ -725,8 +896,8 @@ packages: rollup: optional: true - '@rollup/plugin-commonjs@28.0.3': - resolution: {integrity: sha512-pyltgilam1QPdn+Zd9gaCfOLcnjMEJ9gV+bTw6/r73INdvzf1ah9zLIJBm+kW7R6IUFIQ1YO+VqZtYxZNWFPEQ==} + '@rollup/plugin-commonjs@28.0.6': + resolution: {integrity: sha512-XSQB1K7FUU5QP+3lOQmVCE3I0FcbbNvmNT4VJSj93iUjayaARrTQeoRdiYQoftAJBLrR9t2agwAd3ekaTgHNlw==} engines: {node: '>=16.0.0 || 14 >= 14.17'} peerDependencies: rollup: ^2.68.0||^3.0.0||^4.0.0 @@ -779,8 +950,8 @@ packages: rollup: optional: true - '@rollup/pluginutils@5.1.4': - resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==} + '@rollup/pluginutils@5.2.0': + resolution: {integrity: sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 @@ -788,108 +959,108 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.41.0': - resolution: {integrity: sha512-KxN+zCjOYHGwCl4UCtSfZ6jrq/qi88JDUtiEFk8LELEHq2Egfc/FgW+jItZiOLRuQfb/3xJSgFuNPC9jzggX+A==} + '@rollup/rollup-android-arm-eabi@4.44.2': + resolution: {integrity: sha512-g0dF8P1e2QYPOj1gu7s/3LVP6kze9A7m6x0BZ9iTdXK8N5c2V7cpBKHV3/9A4Zd8xxavdhK0t4PnqjkqVmUc9Q==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.41.0': - resolution: {integrity: sha512-yDvqx3lWlcugozax3DItKJI5j05B0d4Kvnjx+5mwiUpWramVvmAByYigMplaoAQ3pvdprGCTCE03eduqE/8mPQ==} + '@rollup/rollup-android-arm64@4.44.2': + resolution: {integrity: sha512-Yt5MKrOosSbSaAK5Y4J+vSiID57sOvpBNBR6K7xAaQvk3MkcNVV0f9fE20T+41WYN8hDn6SGFlFrKudtx4EoxA==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.41.0': - resolution: {integrity: sha512-2KOU574vD3gzcPSjxO0eyR5iWlnxxtmW1F5CkNOHmMlueKNCQkxR6+ekgWyVnz6zaZihpUNkGxjsYrkTJKhkaw==} + '@rollup/rollup-darwin-arm64@4.44.2': + resolution: {integrity: sha512-EsnFot9ZieM35YNA26nhbLTJBHD0jTwWpPwmRVDzjylQT6gkar+zenfb8mHxWpRrbn+WytRRjE0WKsfaxBkVUA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.41.0': - resolution: {integrity: sha512-gE5ACNSxHcEZyP2BA9TuTakfZvULEW4YAOtxl/A/YDbIir/wPKukde0BNPlnBiP88ecaN4BJI2TtAd+HKuZPQQ==} + '@rollup/rollup-darwin-x64@4.44.2': + resolution: {integrity: sha512-dv/t1t1RkCvJdWWxQ2lWOO+b7cMsVw5YFaS04oHpZRWehI1h0fV1gF4wgGCTyQHHjJDfbNpwOi6PXEafRBBezw==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.41.0': - resolution: {integrity: sha512-GSxU6r5HnWij7FoSo7cZg3l5GPg4HFLkzsFFh0N/b16q5buW1NAWuCJ+HMtIdUEi6XF0qH+hN0TEd78laRp7Dg==} + '@rollup/rollup-freebsd-arm64@4.44.2': + resolution: {integrity: sha512-W4tt4BLorKND4qeHElxDoim0+BsprFTwb+vriVQnFFtT/P6v/xO5I99xvYnVzKWrK6j7Hb0yp3x7V5LUbaeOMg==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.41.0': - resolution: {integrity: sha512-KGiGKGDg8qLRyOWmk6IeiHJzsN/OYxO6nSbT0Vj4MwjS2XQy/5emsmtoqLAabqrohbgLWJ5GV3s/ljdrIr8Qjg==} + '@rollup/rollup-freebsd-x64@4.44.2': + resolution: {integrity: sha512-tdT1PHopokkuBVyHjvYehnIe20fxibxFCEhQP/96MDSOcyjM/shlTkZZLOufV3qO6/FQOSiJTBebhVc12JyPTA==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.41.0': - resolution: {integrity: sha512-46OzWeqEVQyX3N2/QdiU/CMXYDH/lSHpgfBkuhl3igpZiaB3ZIfSjKuOnybFVBQzjsLwkus2mjaESy8H41SzvA==} + '@rollup/rollup-linux-arm-gnueabihf@4.44.2': + resolution: {integrity: sha512-+xmiDGGaSfIIOXMzkhJ++Oa0Gwvl9oXUeIiwarsdRXSe27HUIvjbSIpPxvnNsRebsNdUo7uAiQVgBD1hVriwSQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.41.0': - resolution: {integrity: sha512-lfgW3KtQP4YauqdPpcUZHPcqQXmTmH4nYU0cplNeW583CMkAGjtImw4PKli09NFi2iQgChk4e9erkwlfYem6Lg==} + '@rollup/rollup-linux-arm-musleabihf@4.44.2': + resolution: {integrity: sha512-bDHvhzOfORk3wt8yxIra8N4k/N0MnKInCW5OGZaeDYa/hMrdPaJzo7CSkjKZqX4JFUWjUGm88lI6QJLCM7lDrA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.41.0': - resolution: {integrity: sha512-nn8mEyzMbdEJzT7cwxgObuwviMx6kPRxzYiOl6o/o+ChQq23gfdlZcUNnt89lPhhz3BYsZ72rp0rxNqBSfqlqw==} + '@rollup/rollup-linux-arm64-gnu@4.44.2': + resolution: {integrity: sha512-NMsDEsDiYghTbeZWEGnNi4F0hSbGnsuOG+VnNvxkKg0IGDvFh7UVpM/14mnMwxRxUf9AdAVJgHPvKXf6FpMB7A==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.41.0': - resolution: {integrity: sha512-l+QK99je2zUKGd31Gh+45c4pGDAqZSuWQiuRFCdHYC2CSiO47qUWsCcenrI6p22hvHZrDje9QjwSMAFL3iwXwQ==} + '@rollup/rollup-linux-arm64-musl@4.44.2': + resolution: {integrity: sha512-lb5bxXnxXglVq+7imxykIp5xMq+idehfl+wOgiiix0191av84OqbjUED+PRC5OA8eFJYj5xAGcpAZ0pF2MnW+A==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.41.0': - resolution: {integrity: sha512-WbnJaxPv1gPIm6S8O/Wg+wfE/OzGSXlBMbOe4ie+zMyykMOeqmgD1BhPxZQuDqwUN+0T/xOFtL2RUWBspnZj3w==} + '@rollup/rollup-linux-loongarch64-gnu@4.44.2': + resolution: {integrity: sha512-Yl5Rdpf9pIc4GW1PmkUGHdMtbx0fBLE1//SxDmuf3X0dUC57+zMepow2LK0V21661cjXdTn8hO2tXDdAWAqE5g==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.41.0': - resolution: {integrity: sha512-eRDWR5t67/b2g8Q/S8XPi0YdbKcCs4WQ8vklNnUYLaSWF+Cbv2axZsp4jni6/j7eKvMLYCYdcsv8dcU+a6QNFg==} + '@rollup/rollup-linux-powerpc64le-gnu@4.44.2': + resolution: {integrity: sha512-03vUDH+w55s680YYryyr78jsO1RWU9ocRMaeV2vMniJJW/6HhoTBwyyiiTPVHNWLnhsnwcQ0oH3S9JSBEKuyqw==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.41.0': - resolution: {integrity: sha512-TWrZb6GF5jsEKG7T1IHwlLMDRy2f3DPqYldmIhnA2DVqvvhY2Ai184vZGgahRrg8k9UBWoSlHv+suRfTN7Ua4A==} + '@rollup/rollup-linux-riscv64-gnu@4.44.2': + resolution: {integrity: sha512-iYtAqBg5eEMG4dEfVlkqo05xMOk6y/JXIToRca2bAWuqjrJYJlx/I7+Z+4hSrsWU8GdJDFPL4ktV3dy4yBSrzg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.41.0': - resolution: {integrity: sha512-ieQljaZKuJpmWvd8gW87ZmSFwid6AxMDk5bhONJ57U8zT77zpZ/TPKkU9HpnnFrM4zsgr4kiGuzbIbZTGi7u9A==} + '@rollup/rollup-linux-riscv64-musl@4.44.2': + resolution: {integrity: sha512-e6vEbgaaqz2yEHqtkPXa28fFuBGmUJ0N2dOJK8YUfijejInt9gfCSA7YDdJ4nYlv67JfP3+PSWFX4IVw/xRIPg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.41.0': - resolution: {integrity: sha512-/L3pW48SxrWAlVsKCN0dGLB2bi8Nv8pr5S5ocSM+S0XCn5RCVCXqi8GVtHFsOBBCSeR+u9brV2zno5+mg3S4Aw==} + '@rollup/rollup-linux-s390x-gnu@4.44.2': + resolution: {integrity: sha512-evFOtkmVdY3udE+0QKrV5wBx7bKI0iHz5yEVx5WqDJkxp9YQefy4Mpx3RajIVcM6o7jxTvVd/qpC1IXUhGc1Mw==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.41.0': - resolution: {integrity: sha512-XMLeKjyH8NsEDCRptf6LO8lJk23o9wvB+dJwcXMaH6ZQbbkHu2dbGIUindbMtRN6ux1xKi16iXWu6q9mu7gDhQ==} + '@rollup/rollup-linux-x64-gnu@4.44.2': + resolution: {integrity: sha512-/bXb0bEsWMyEkIsUL2Yt5nFB5naLAwyOWMEviQfQY1x3l5WsLKgvZf66TM7UTfED6erckUVUJQ/jJ1FSpm3pRQ==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.41.0': - resolution: {integrity: sha512-m/P7LycHZTvSQeXhFmgmdqEiTqSV80zn6xHaQ1JSqwCtD1YGtwEK515Qmy9DcB2HK4dOUVypQxvhVSy06cJPEg==} + '@rollup/rollup-linux-x64-musl@4.44.2': + resolution: {integrity: sha512-3D3OB1vSSBXmkGEZR27uiMRNiwN08/RVAcBKwhUYPaiZ8bcvdeEwWPvbnXvvXHY+A/7xluzcN+kaiOFNiOZwWg==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.41.0': - resolution: {integrity: sha512-4yodtcOrFHpbomJGVEqZ8fzD4kfBeCbpsUy5Pqk4RluXOdsWdjLnjhiKy2w3qzcASWd04fp52Xz7JKarVJ5BTg==} + '@rollup/rollup-win32-arm64-msvc@4.44.2': + resolution: {integrity: sha512-VfU0fsMK+rwdK8mwODqYeM2hDrF2WiHaSmCBrS7gColkQft95/8tphyzv2EupVxn3iE0FI78wzffoULH1G+dkw==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.41.0': - resolution: {integrity: sha512-tmazCrAsKzdkXssEc65zIE1oC6xPHwfy9d5Ta25SRCDOZS+I6RypVVShWALNuU9bxIfGA0aqrmzlzoM5wO5SPQ==} + '@rollup/rollup-win32-ia32-msvc@4.44.2': + resolution: {integrity: sha512-+qMUrkbUurpE6DVRjiJCNGZBGo9xM4Y0FXU5cjgudWqIBWbcLkjE3XprJUsOFgC6xjBClwVa9k6O3A7K3vxb5Q==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.41.0': - resolution: {integrity: sha512-h1J+Yzjo/X+0EAvR2kIXJDuTuyT7drc+t2ALY0nIcGPbTatNOf0VWdhEA2Z4AAjv6X1NJV7SYo5oCTYRJhSlVA==} + '@rollup/rollup-win32-x64-msvc@4.44.2': + resolution: {integrity: sha512-3+QZROYfJ25PDcxFF66UEk8jGWigHJeecZILvkPkyQN7oc5BvFo4YEXFkOs154j3FTMp9mn9Ky8RCOwastduEA==} cpu: [x64] os: [win32] - '@sindresorhus/is@7.0.1': - resolution: {integrity: sha512-QWLl2P+rsCJeofkDNIT3WFmb6NrRud1SUYW8dIhXK/46XFV8Q/g7Bsvib0Askb0reRLe+WYPeeE+l5cH7SlkuQ==} + '@sindresorhus/is@7.0.2': + resolution: {integrity: sha512-d9xRovfKNz1SKieM0qJdO+PQonjnnIfSNWfHYnBSJ9hkjm0ZPw6HlxscDXYstp3z+7V2GOFHc+J0CYrYTjqCJw==} engines: {node: '>=18'} '@sindresorhus/merge-streams@2.3.0': @@ -912,20 +1083,21 @@ packages: '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} - '@types/estree@1.0.7': - resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - '@types/luxon@3.4.2': - resolution: {integrity: sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA==} + '@types/luxon@3.6.2': + resolution: {integrity: sha512-R/BdP7OxEMc44l2Ex5lSXHoIXTB2JLNa3y2QISIbr58U/YcsffyQrYW//hZSdrfxrjRZj3GcUoxMPGdO8gSYuw==} - '@types/node@22.13.8': - resolution: {integrity: sha512-G3EfaZS+iOGYWLLRCEAXdWK9my08oHNZ+FHluRiggIYJPOXzhOiDgpVCUHaUvyIC5/fj7C/p637jdzC666AOKQ==} + '@types/node@24.0.10': + resolution: {integrity: sha512-ENHwaH+JIRTDIEEbDK6QSQntAYGtbvdDXnMXnZaZ6k13Du1dPMmprkEHIL7ok2Wl2aZevetwTAb5S+7yIF+enA==} '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} - '@types/parse-path@7.0.3': - resolution: {integrity: sha512-LriObC2+KYZD3FzCrgWGv/qufdUy4eXrxcLgQMfYXgPbLIecKIsVBaQgUPmxSSLcjmYbDTQbMgr6qr6l/eb7Bg==} + '@types/parse-path@7.1.0': + resolution: {integrity: sha512-EULJ8LApcVEPbrfND0cRQqutIOdiIgJ1Mgrhpy755r14xMohPTEpkV/k28SJvuOs9bHRFW8x+KeDAEPiGQPB9Q==} + deprecated: This is a stub types definition. parse-path provides its own type definitions, so you do not need this installed. '@types/resolve@1.20.2': resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} @@ -939,27 +1111,39 @@ packages: '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - '@typescript-eslint/types@8.32.1': - resolution: {integrity: sha512-YmybwXUJcgGqgAp6bEsgpPXEg6dcCyPyCSr0CAAueacR/CCBi25G3V8gGQ2kRzQRBNol7VQknxMs9HvVa9Rvfg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/typescript-estree@8.32.1': - resolution: {integrity: sha512-Y3AP9EIfYwBb4kWGb+simvPaqQoT5oJuzzj9m0i6FCY6SPvlomY2Ei4UEMm7+FXtlNJbor80ximyslzaQF6xhg==} + '@typescript-eslint/project-service@8.36.0': + resolution: {integrity: sha512-JAhQFIABkWccQYeLMrHadu/fhpzmSQ1F1KXkpzqiVxA/iYI6UnRt2trqXHt1sYEcw1mxLnB9rKMsOxXPxowN/g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/visitor-keys@8.32.1': - resolution: {integrity: sha512-ar0tjQfObzhSaW3C3QNmTc5ofj0hDoNQ5XWrCy6zDyabdr0TWhCkClp+rywGNj/odAFBVzzJrK4tEq5M4Hmu4w==} + '@typescript-eslint/tsconfig-utils@8.36.0': + resolution: {integrity: sha512-Nhh3TIEgN18mNbdXpd5Q8mSCBnrZQeY9V7Ca3dqYvNDStNIGRmJA6dmrIPMJ0kow3C7gcQbpsG2rPzy1Ks/AnA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/types@8.36.0': + resolution: {integrity: sha512-xGms6l5cTJKQPZOKM75Dl9yBfNdGeLRsIyufewnxT4vZTrjC0ImQT4fj8QmtJK84F58uSh5HVBSANwcfiXxABQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@unhead/vue@2.0.10': - resolution: {integrity: sha512-lV7E1sXX6/te8+IiUwlMysBAyJT/WM5Je47cRnpU5hsvDRziSIGfim9qMWbsTouH+paavRJz1i8gk5hRzjvkcw==} + '@typescript-eslint/typescript-estree@8.36.0': + resolution: {integrity: sha512-JaS8bDVrfVJX4av0jLpe4ye0BpAaUW7+tnS4Y4ETa3q7NoZgzYbN9zDQTJ8kPb5fQ4n0hliAt9tA4Pfs2zA2Hg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/visitor-keys@8.36.0': + resolution: {integrity: sha512-vZrhV2lRPWDuGoxcmrzRZyxAggPL+qp3WzUrlZD+slFueDiYHxeBa34dUXPuC0RmGKzl4lS5kFJYvKCq9cnNDA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@unhead/vue@2.0.12': + resolution: {integrity: sha512-WFaiCVbBd39FK6Bx3GQskhgT9s45Vjx6dRQegYheVwU1AnF+FAfJVgWbrl21p6fRJcLAFp0xDz6wE18JYBM0eQ==} peerDependencies: vue: '>=3.5.13' - '@vercel/nft@0.29.3': - resolution: {integrity: sha512-aVV0E6vJpuvImiMwU1/5QKkw2N96BRFE7mBYGS7FhXUoS6V7SarQ+8tuj33o7ofECz8JtHpmQ9JW+oVzOoB7MA==} + '@vercel/nft@0.29.4': + resolution: {integrity: sha512-6lLqMNX3TuycBPABycx7A9F1bHQR7kiQln6abjFbPrf5C/05qHM9M5E4PeTE59c7z8g6vHnx1Ioihb2AQl7BTA==} engines: {node: '>=18'} hasBin: true @@ -977,11 +1161,11 @@ packages: vite: ^5.0.0 || ^6.0.0 vue: ^3.2.25 - '@vitest/expect@3.2.3': - resolution: {integrity: sha512-W2RH2TPWVHA1o7UmaFKISPvdicFJH+mjykctJFoAkUw+SPTJTGjUNdKscFBrqM7IPnCVu6zihtKYa7TkZS1dkQ==} + '@vitest/expect@3.2.4': + resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} - '@vitest/mocker@3.2.3': - resolution: {integrity: sha512-cP6fIun+Zx8he4rbWvi+Oya6goKQDZK+Yq4hhlggwQBbrlOQ4qtZ+G4nxB6ZnzI9lyIb+JnvyiJnPC2AGbKSPA==} + '@vitest/mocker@3.2.4': + resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} peerDependencies: msw: ^2.4.9 vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 @@ -991,33 +1175,33 @@ packages: vite: optional: true - '@vitest/pretty-format@3.2.3': - resolution: {integrity: sha512-yFglXGkr9hW/yEXngO+IKMhP0jxyFw2/qys/CK4fFUZnSltD+MU7dVYGrH8rvPcK/O6feXQA+EU33gjaBBbAng==} + '@vitest/pretty-format@3.2.4': + resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} - '@vitest/runner@3.2.3': - resolution: {integrity: sha512-83HWYisT3IpMaU9LN+VN+/nLHVBCSIUKJzGxC5RWUOsK1h3USg7ojL+UXQR3b4o4UBIWCYdD2fxuzM7PQQ1u8w==} + '@vitest/runner@3.2.4': + resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} - '@vitest/snapshot@3.2.3': - resolution: {integrity: sha512-9gIVWx2+tysDqUmmM1L0hwadyumqssOL1r8KJipwLx5JVYyxvVRfxvMq7DaWbZZsCqZnu/dZedaZQh4iYTtneA==} + '@vitest/snapshot@3.2.4': + resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} - '@vitest/spy@3.2.3': - resolution: {integrity: sha512-JHu9Wl+7bf6FEejTCREy+DmgWe+rQKbK+y32C/k5f4TBIAlijhJbRBIRIOCEpVevgRsCQR2iHRUH2/qKVM/plw==} + '@vitest/spy@3.2.4': + resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} - '@vitest/utils@3.2.3': - resolution: {integrity: sha512-4zFBCU5Pf+4Z6v+rwnZ1HU1yzOKKvDkMXZrymE2PBlbjKJRlrOxbvpfPSvJTGRIwGoahaOGvp+kbCoxifhzJ1Q==} + '@vitest/utils@3.2.4': + resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} - '@volar/language-core@2.4.14': - resolution: {integrity: sha512-X6beusV0DvuVseaOEy7GoagS4rYHgDHnTrdOj5jeUb49fW5ceQyP9Ej5rBhqgz2wJggl+2fDbbojq1XKaxDi6w==} + '@volar/language-core@2.4.17': + resolution: {integrity: sha512-chmRZMbKmcGpKMoO7Reb70uiLrzo0KWC2CkFttKUuKvrE+VYgi+fL9vWMJ07Fv5ulX0V1TAyyacN9q3nc5/ecA==} - '@volar/source-map@2.4.14': - resolution: {integrity: sha512-5TeKKMh7Sfxo8021cJfmBzcjfY1SsXsPMMjMvjY7ivesdnybqqS+GxGAoXHAOUawQTwtdUxgP65Im+dEmvWtYQ==} + '@volar/source-map@2.4.17': + resolution: {integrity: sha512-QDybtQyO3Ms/NjFqNHTC5tbDN2oK5VH7ZaKrcubtfHBDj63n2pizHC3wlMQ+iT55kQXZUUAbmBX5L1C8CHFeBw==} - '@volar/typescript@2.4.14': - resolution: {integrity: sha512-p8Z6f/bZM3/HyCdRNFZOEEzts51uV8WHeN8Tnfnm2EBv6FDB2TQLzfVx7aJvnl8ofKAOnS64B2O8bImBFaauRw==} + '@volar/typescript@2.4.17': + resolution: {integrity: sha512-3paEFNh4P5DkgNUB2YkTRrfUekN4brAXxd3Ow1syMqdIPtCZHbUy4AW99S5RO/7mzyTWPMdDSo3mqTpB/LPObQ==} - '@vue-macros/common@1.16.1': - resolution: {integrity: sha512-Pn/AWMTjoMYuquepLZP813BIcq8DTZiNCoaceuNlvaYuOTd8DqBZWc5u0uOMQZMInwME1mdSmmBAcTluiV9Jtg==} - engines: {node: '>=16.14.0'} + '@vue-macros/common@3.0.0-beta.15': + resolution: {integrity: sha512-DMgq/rIh1H20WYNWU7krIbEfJRYDDhy7ix64GlT4AVUJZZWCZ5pxiYVJR3A3GmWQPkn7Pg7i3oIiGqu4JGC65w==} + engines: {node: '>=20.18.0'} peerDependencies: vue: ^2.7.0 || ^3.2.25 peerDependenciesMeta: @@ -1040,29 +1224,17 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@vue/compiler-core@3.5.14': - resolution: {integrity: sha512-k7qMHMbKvoCXIxPhquKQVw3Twid3Kg4s7+oYURxLGRd56LiuHJVrvFKI4fm2AM3c8apqODPfVJGoh8nePbXMRA==} + '@vue/compiler-core@3.5.17': + resolution: {integrity: sha512-Xe+AittLbAyV0pabcN7cP7/BenRBNcteM4aSDCtRvGw0d9OL+HG1u/XHLY/kt1q4fyMeZYXyIYrsHuPSiDPosA==} - '@vue/compiler-core@3.5.16': - resolution: {integrity: sha512-AOQS2eaQOaaZQoL1u+2rCJIKDruNXVBZSiUD3chnUrsoX5ZTQMaCvXlWNIfxBJuU15r1o7+mpo5223KVtIhAgQ==} + '@vue/compiler-dom@3.5.17': + resolution: {integrity: sha512-+2UgfLKoaNLhgfhV5Ihnk6wB4ljyW1/7wUIog2puUqajiC29Lp5R/IKDdkebh9jTbTogTbsgB+OY9cEWzG95JQ==} - '@vue/compiler-dom@3.5.14': - resolution: {integrity: sha512-1aOCSqxGOea5I80U2hQJvXYpPm/aXo95xL/m/mMhgyPUsKe9jhjwWpziNAw7tYRnbz1I61rd9Mld4W9KmmRoug==} + '@vue/compiler-sfc@3.5.17': + resolution: {integrity: sha512-rQQxbRJMgTqwRugtjw0cnyQv9cP4/4BxWfTdRBkqsTfLOHWykLzbOc3C4GGzAmdMDxhzU/1Ija5bTjMVrddqww==} - '@vue/compiler-dom@3.5.16': - resolution: {integrity: sha512-SSJIhBr/teipXiXjmWOVWLnxjNGo65Oj/8wTEQz0nqwQeP75jWZ0n4sF24Zxoht1cuJoWopwj0J0exYwCJ0dCQ==} - - '@vue/compiler-sfc@3.5.14': - resolution: {integrity: sha512-9T6m/9mMr81Lj58JpzsiSIjBgv2LiVoWjIVa7kuXHICUi8LiDSIotMpPRXYJsXKqyARrzjT24NAwttrMnMaCXA==} - - '@vue/compiler-sfc@3.5.16': - resolution: {integrity: sha512-rQR6VSFNpiinDy/DVUE0vHoIDUF++6p910cgcZoaAUm3POxgNOOdS/xgoll3rNdKYTYPnnbARDCZOyZ+QSe6Pw==} - - '@vue/compiler-ssr@3.5.14': - resolution: {integrity: sha512-Y0G7PcBxr1yllnHuS/NxNCSPWnRGH4Ogrp0tsLA5QemDZuJLs99YjAKQ7KqkHE0vCg4QTKlQzXLKCMF7WPSl7Q==} - - '@vue/compiler-ssr@3.5.16': - resolution: {integrity: sha512-d2V7kfxbdsjrDSGlJE7my1ZzCXViEcqN6w14DOsDrUCHEA6vbnVCpRFfrc4ryCP/lCKzX2eS1YtnLE/BuC9f/A==} + '@vue/compiler-ssr@3.5.17': + resolution: {integrity: sha512-hkDbA0Q20ZzGgpj5uZjb9rBzQtIHLS78mMilwrlpWk2Ep37DYntUz0PonQ6kr113vfOEdM+zTBuJDaceNIW0tQ==} '@vue/compiler-vue2@2.7.16': resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} @@ -1070,61 +1242,44 @@ packages: '@vue/devtools-api@6.6.4': resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} - '@vue/devtools-api@7.7.6': - resolution: {integrity: sha512-b2Xx0KvXZObePpXPYHvBRRJLDQn5nhKjXh7vUhMEtWxz1AYNFOVIsh5+HLP8xDGL7sy+Q7hXeUxPHB/KgbtsPw==} + '@vue/devtools-api@7.7.7': + resolution: {integrity: sha512-lwOnNBH2e7x1fIIbVT7yF5D+YWhqELm55/4ZKf45R9T8r9dE2AIOy8HKjfqzGsoTHFbWbr337O4E0A0QADnjBg==} - '@vue/devtools-core@7.7.6': - resolution: {integrity: sha512-ghVX3zjKPtSHu94Xs03giRIeIWlb9M+gvDRVpIZ/cRIxKHdW6HE/sm1PT3rUYS3aV92CazirT93ne+7IOvGUWg==} + '@vue/devtools-core@7.7.7': + resolution: {integrity: sha512-9z9TLbfC+AjAi1PQyWX+OErjIaJmdFlbDHcD+cAMYKY6Bh5VlsAtCeGyRMrXwIlMEQPukvnWt3gZBLwTAIMKzQ==} peerDependencies: vue: ^3.0.0 - '@vue/devtools-kit@7.7.6': - resolution: {integrity: sha512-geu7ds7tem2Y7Wz+WgbnbZ6T5eadOvozHZ23Atk/8tksHMFOFylKi1xgGlQlVn0wlkEf4hu+vd5ctj1G4kFtwA==} + '@vue/devtools-kit@7.7.7': + resolution: {integrity: sha512-wgoZtxcTta65cnZ1Q6MbAfePVFxfM+gq0saaeytoph7nEa7yMXoi6sCPy4ufO111B9msnw0VOWjPEFCXuAKRHA==} - '@vue/devtools-shared@7.7.6': - resolution: {integrity: sha512-yFEgJZ/WblEsojQQceuyK6FzpFDx4kqrz2ohInxNj5/DnhoX023upTv4OD6lNPLAA5LLkbwPVb10o/7b+Y4FVA==} + '@vue/devtools-shared@7.7.7': + resolution: {integrity: sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw==} - '@vue/language-core@2.2.10': - resolution: {integrity: sha512-+yNoYx6XIKuAO8Mqh1vGytu8jkFEOH5C8iOv3i8Z/65A7x9iAOXA97Q+PqZ3nlm2lxf5rOJuIGI/wDtx/riNYw==} + '@vue/language-core@3.0.1': + resolution: {integrity: sha512-sq+/Mc1IqIexWEQ+Q2XPiDb5SxSvY5JPqHnMOl/PlF5BekslzduX8dglSkpC17VeiAQB6dpS+4aiwNLJRduCNw==} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true - '@vue/reactivity@3.5.14': - resolution: {integrity: sha512-7cK1Hp343Fu/SUCCO52vCabjvsYu7ZkOqyYu7bXV9P2yyfjUMUXHZafEbq244sP7gf+EZEz+77QixBTuEqkQQw==} + '@vue/reactivity@3.5.17': + resolution: {integrity: sha512-l/rmw2STIscWi7SNJp708FK4Kofs97zc/5aEPQh4bOsReD/8ICuBcEmS7KGwDj5ODQLYWVN2lNibKJL1z5b+Lw==} - '@vue/reactivity@3.5.16': - resolution: {integrity: sha512-FG5Q5ee/kxhIm1p2bykPpPwqiUBV3kFySsHEQha5BJvjXdZTUfmya7wP7zC39dFuZAcf/PD5S4Lni55vGLMhvA==} + '@vue/runtime-core@3.5.17': + resolution: {integrity: sha512-QQLXa20dHg1R0ri4bjKeGFKEkJA7MMBxrKo2G+gJikmumRS7PTD4BOU9FKrDQWMKowz7frJJGqBffYMgQYS96Q==} - '@vue/runtime-core@3.5.14': - resolution: {integrity: sha512-w9JWEANwHXNgieAhxPpEpJa+0V5G0hz3NmjAZwlOebtfKyp2hKxKF0+qSh0Xs6/PhfGihuSdqMprMVcQU/E6ag==} + '@vue/runtime-dom@3.5.17': + resolution: {integrity: sha512-8El0M60TcwZ1QMz4/os2MdlQECgGoVHPuLnQBU3m9h3gdNRW9xRmI8iLS4t/22OQlOE6aJvNNlBiCzPHur4H9g==} - '@vue/runtime-core@3.5.16': - resolution: {integrity: sha512-bw5Ykq6+JFHYxrQa7Tjr+VSzw7Dj4ldR/udyBZbq73fCdJmyy5MPIFR9IX/M5Qs+TtTjuyUTCnmK3lWWwpAcFQ==} - - '@vue/runtime-dom@3.5.14': - resolution: {integrity: sha512-lCfR++IakeI35TVR80QgOelsUIdcKjd65rWAMfdSlCYnaEY5t3hYwru7vvcWaqmrK+LpI7ZDDYiGU5V3xjMacw==} - - '@vue/runtime-dom@3.5.16': - resolution: {integrity: sha512-T1qqYJsG2xMGhImRUV9y/RseB9d0eCYZQ4CWca9ztCuiPj/XWNNN+lkNBuzVbia5z4/cgxdL28NoQCvC0Xcfww==} - - '@vue/server-renderer@3.5.14': - resolution: {integrity: sha512-Rf/ISLqokIvcySIYnv3tNWq40PLpNLDLSJwwVWzG6MNtyIhfbcrAxo5ZL9nARJhqjZyWWa40oRb2IDuejeuv6w==} + '@vue/server-renderer@3.5.17': + resolution: {integrity: sha512-BOHhm8HalujY6lmC3DbqF6uXN/K00uWiEeF22LfEsm9Q93XeJ/plHTepGwf6tqFcF7GA5oGSSAAUock3VvzaCA==} peerDependencies: - vue: 3.5.14 + vue: 3.5.17 - '@vue/server-renderer@3.5.16': - resolution: {integrity: sha512-BrX0qLiv/WugguGsnQUJiYOE0Fe5mZTwi6b7X/ybGB0vfrPH9z0gD/Y6WOR1sGCgX4gc25L1RYS5eYQKDMoNIg==} - peerDependencies: - vue: 3.5.16 - - '@vue/shared@3.5.14': - resolution: {integrity: sha512-oXTwNxVfc9EtP1zzXAlSlgARLXNC84frFYkS0HHz0h3E4WZSP9sywqjqzGCP9Y34M8ipNmd380pVgmMuwELDyQ==} - - '@vue/shared@3.5.16': - resolution: {integrity: sha512-c/0fWy3Jw6Z8L9FmTyYfkpM5zklnqqa9+a6dz3DvONRKW2NEbh46BP0FHuLFSWi2TnQEtp91Z6zOWNrU6QiyPg==} + '@vue/shared@3.5.17': + resolution: {integrity: sha512-CabR+UN630VnsJO/jHWYBC1YVXyMq94KKp6iF5MQgZJs5I8cmjw6oVMO1oDbtBkENSHSSn/UadWlW/OAgdmKrg==} '@whatwg-node/disposablestack@0.0.6': resolution: {integrity: sha512-LOtTn+JgJvX8WfBVJtF08TGrdjuFzGJc4mkP8EdDI8ADbvO7kiexYep1o8dwnt0okb0jYclCDXF13xU7Ge4zSw==} @@ -1146,8 +1301,8 @@ packages: resolution: {integrity: sha512-ueFCcIPaMgtuYDS9u0qlUoEvj6GiSsKrwnOLPp9SshqjtcRaR1IEHRjoReq3sXNydsF5i0ZnmuYgXq9dV53t0g==} engines: {node: '>=18.0.0'} - abbrev@3.0.0: - resolution: {integrity: sha512-+/kfrslGQ7TNV2ecmQwMJj/B65g5KVq1/L3SGVZ3tCYGqlzFuFCGBZJtMP99wH3NpEUyAjn0zPdPUg0D+DwrOA==} + abbrev@3.0.1: + resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} engines: {node: ^18.17.0 || >=20.5.0} abort-controller@3.0.0: @@ -1159,17 +1314,17 @@ packages: peerDependencies: acorn: ^8 - acorn@8.14.1: - resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} engines: {node: '>=0.4.0'} hasBin: true - agent-base@7.1.3: - resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} - alien-signals@1.0.13: - resolution: {integrity: sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==} + alien-signals@2.0.5: + resolution: {integrity: sha512-PdJB6+06nUNAClInE3Dweq7/2xVAYM64vvvS1IHVHSJmgeOtEdrAGyp7Z2oJtYm0B342/Exd2NT0uMJaThcjLQ==} ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} @@ -1187,8 +1342,8 @@ packages: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} - ansis@3.17.0: - resolution: {integrity: sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==} + ansis@4.1.0: + resolution: {integrity: sha512-BGcItUBWSMRgOCe+SVZJ+S7yTRG0eGt9cXAHev72yuGcY23hnLA7Bky5L/xLyPINoSN95geovfBkqoTlNZYa7w==} engines: {node: '>=14'} anymatch@3.1.3: @@ -1210,17 +1365,17 @@ packages: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} - ast-kit@1.4.0: - resolution: {integrity: sha512-BlGeOw73FDsX7z0eZE/wuuafxYoek2yzNJ6l6A1nsb4+z/p87TOPbHaWuN53kFKNuUXiCQa2M+xLF71IqQmRSw==} - engines: {node: '>=16.14.0'} + ast-kit@2.1.1: + resolution: {integrity: sha512-mfh6a7gKXE8pDlxTvqIc/syH/P3RkzbOF6LeHdcKztLEzYe6IMsRCL7N8vI7hqTGWNxpkCuuRTpT21xNWqhRtQ==} + engines: {node: '>=20.18.0'} ast-module-types@6.0.1: resolution: {integrity: sha512-WHw67kLXYbZuHTmcdbIrVArCq5wxo6NEuj3hiYAWr8mwJeC+C2mMCIBIWCiDoCye/OF/xelc+teJ1ERoWmnEIA==} engines: {node: '>=18'} - ast-walker-scope@0.6.2: - resolution: {integrity: sha512-1UWOyC50xI3QZkRuDj6PqDtpm1oHWtYs+NQGwqL/2R11eN3Q81PHAHPM0SWW3BNQm53UDwS//Jv8L4CCVLM1bQ==} - engines: {node: '>=16.14.0'} + ast-walker-scope@0.8.1: + resolution: {integrity: sha512-72XOdbzQCMKERvFrxAykatn2pu7osPNq/sNUzwcHdWzwPvOsNpPqkawfDXVvQbA2RT+ivtsMNjYdojTUZitt1A==} + engines: {node: '>=20.18.0'} async-sema@3.1.1: resolution: {integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==} @@ -1250,24 +1405,24 @@ packages: bindings@1.5.0: resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} - birpc@2.3.0: - resolution: {integrity: sha512-ijbtkn/F3Pvzb6jHypHRyve2QApOCZDR25D/VnkY2G/lBNcXCTsnsCxgY4k4PkVB7zfwzYbY3O9Lcqe3xufS5g==} + birpc@2.4.0: + resolution: {integrity: sha512-5IdNxTyhXHv2UlgnPHQ0h+5ypVmkrYHzL8QT+DwFZ//2N/oNV8Ch+BCRmTJ3x6/z9Axo/cXYBc9eprsUVK/Jsg==} - bn.js@4.12.1: - resolution: {integrity: sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==} + bn.js@4.12.2: + resolution: {integrity: sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==} boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.24.5: - resolution: {integrity: sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==} + browserslist@4.25.1: + resolution: {integrity: sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -1321,8 +1476,8 @@ packages: caniuse-api@3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} - caniuse-lite@1.0.30001718: - resolution: {integrity: sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==} + caniuse-lite@1.0.30001727: + resolution: {integrity: sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==} chai@5.2.0: resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} @@ -1455,8 +1610,8 @@ packages: resolution: {integrity: sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==} engines: {node: '>=12.0.0'} - croner@9.0.0: - resolution: {integrity: sha512-onMB0OkDjkXunhdW9htFjEhqrD54+M94i6ackoUkjHKbRnXdyEyKRelp4nJ1kAz32+s27jP1FsebpJCVl0BsvA==} + croner@9.1.0: + resolution: {integrity: sha512-p9nwwR4qyT5W996vBZhdvBCnMhicY5ytZkR4D1Xj0wuTDEiMnjwR57Q3RXYY/s0EpX6Ay3vgIcfaR+ewGHsi+g==} engines: {node: '>=18.0'} cross-spawn@7.0.6: @@ -1472,8 +1627,8 @@ packages: peerDependencies: postcss: ^8.0.9 - css-select@5.1.0: - resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} css-tree@2.2.1: resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} @@ -1483,8 +1638,8 @@ packages: resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} - css-what@6.1.0: - resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} engines: {node: '>= 6'} cssesc@3.0.0: @@ -1602,8 +1757,8 @@ packages: engines: {node: '>=0.10'} hasBin: true - detect-libc@2.0.3: - resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + detect-libc@2.0.4: + resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} engines: {node: '>=8'} detective-amd@6.0.1: @@ -1652,8 +1807,8 @@ packages: devalue@5.1.1: resolution: {integrity: sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==} - diff@7.0.0: - resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==} + diff@8.0.2: + resolution: {integrity: sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==} engines: {node: '>=0.3.1'} dom-serializer@2.0.0: @@ -1673,8 +1828,8 @@ packages: resolution: {integrity: sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==} engines: {node: '>=18'} - dotenv@16.5.0: - resolution: {integrity: sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==} + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} dunder-proto@1.0.1: @@ -1693,8 +1848,8 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - electron-to-chromium@1.5.157: - resolution: {integrity: sha512-/0ybgsQd1muo8QlnuTpKwtl0oX5YMlUGbm8xyqgDU00motRkKFFbUJySAQBWcY79rVqNLWIWa87BGVGClwAB2w==} + electron-to-chromium@1.5.180: + resolution: {integrity: sha512-ED+GEyEh3kYMwt2faNmgMB0b8O5qtATGgR4RmRsIp4T6p7B8vdMbIedYndnvZfsaXvSzegtpfqRMDNCjjiSduA==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1709,11 +1864,11 @@ packages: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} - end-of-stream@1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - enhanced-resolve@5.18.1: - resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} + enhanced-resolve@5.18.2: + resolution: {integrity: sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==} engines: {node: '>=10.13.0'} entities@4.5.0: @@ -1745,8 +1900,13 @@ packages: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} - esbuild@0.25.4: - resolution: {integrity: sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==} + esbuild@0.25.5: + resolution: {integrity: sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==} + engines: {node: '>=18'} + hasBin: true + + esbuild@0.25.6: + resolution: {integrity: sha512-GVuzuUwtdsghE3ocJ9Bs8PNoF13HNQ5TXbEi2AhvVb8xU1Iwt9Fos9FEamfoee+u/TOsn7GUWc04lz46n2bbTg==} engines: {node: '>=18'} hasBin: true @@ -1766,8 +1926,8 @@ packages: engines: {node: '>=6.0'} hasBin: true - eslint-visitor-keys@4.2.0: - resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} esprima@4.0.1: @@ -1805,12 +1965,12 @@ packages: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} - expect-type@1.2.1: - resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==} + expect-type@1.2.2: + resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} engines: {node: '>=12.0.0'} - exsolve@1.0.5: - resolution: {integrity: sha512-pz5dvkYYKQ1AHVrgOzBKWeP4u4FRb3a6DNK2ucr0OoNwYIU4QWsJ+NM36LLzORT+z845MzKHHhpXiUF5nvQoJg==} + exsolve@1.0.7: + resolution: {integrity: sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==} externality@1.0.2: resolution: {integrity: sha512-LyExtJWKxtgVzmgtEHyQtLFpw1KFhQphF9nTG8TpAIVkiI/xQ3FJh75tRFLYl4hkn7BNIIdLJInuDAavX35pMw==} @@ -1831,8 +1991,8 @@ packages: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} - fast-npm-meta@0.4.3: - resolution: {integrity: sha512-eUzR/uVx61fqlHBjG/eQx5mQs7SQObehMTTdq8FAkdCB4KuZSQ6DiZMIrAq4kcibB3WFLQ9c4dT26Vwkix1RKg==} + fast-npm-meta@0.4.4: + resolution: {integrity: sha512-cq8EVW3jpX1U3dO1AYanz2BJ6n9ITQgCwE1xjNwI5jO2a9erE369OZNO8Wt/Wbw8YHhCD/dimH9BxRsY+6DinA==} fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} @@ -1840,8 +2000,8 @@ packages: fd-slicer@1.1.0: resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} - fdir@6.4.4: - resolution: {integrity: sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==} + fdir@6.4.6: + resolution: {integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==} peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: @@ -1892,9 +2052,6 @@ packages: resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} engines: {node: '>= 0.8'} - fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1942,11 +2099,11 @@ packages: resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==} hasBin: true - git-up@8.0.1: - resolution: {integrity: sha512-2XFu1uNZMSjkyetaF+8rqn6P0XqpMq/C+2ycjI6YwrIKcszZ5/WR4UubxjN0lILOKqLkLaHDaCr2B6fP1cke6g==} + git-up@8.1.1: + resolution: {integrity: sha512-FDenSF3fVqBYSaJoYy1KSc2wosx0gCvKP+c+PRBht7cAaiCeQlBtfBDX9vgnNOHmdePlSFITVcn4pFfcgNvx3g==} - git-url-parse@16.0.1: - resolution: {integrity: sha512-mcD36GrhAzX5JVOsIO52qNpgRyFzYWRbU1VSRFCvJt1IJvqfvH427wWw/CFqkWvjVPtdG5VTx4MKUeC5GeFPDQ==} + git-url-parse@16.1.0: + resolution: {integrity: sha512-cPLz4HuK86wClEW7iDdeAKcCVlWXmrLpb2L+G9goW0Z1dtpNS6BXXSOckUTlJT/LDQViE1QZKstNORzHsLnobw==} glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} @@ -1956,19 +2113,10 @@ packages: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true - glob@8.1.0: - resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} - engines: {node: '>=12'} - deprecated: Glob versions prior to v9 are no longer supported - global-directory@4.0.1: resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} engines: {node: '>=18'} - globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - globby@14.1.0: resolution: {integrity: sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==} engines: {node: '>=18'} @@ -2041,8 +2189,8 @@ packages: ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - ignore@7.0.4: - resolution: {integrity: sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A==} + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} engines: {node: '>= 4'} image-meta@0.2.1: @@ -2055,14 +2203,10 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} - index-to-position@0.1.2: - resolution: {integrity: sha512-MWDKS3AS1bGCHLBA2VLImJz42f7bJh8wQsTGCzI3j519/CASStoDONUBVz2I/VID0MpiX3SGSnbOD2xUalbE5g==} + index-to-position@1.1.0: + resolution: {integrity: sha512-XPdx9Dq4t9Qk1mTMbWONJqU7boCoumEH7fRET37HX5+khDUl3J2W6PdALxhILYlIYx2amlwYcRPp28p0tSiojg==} engines: {node: '>=18'} - inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. - inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -2212,8 +2356,8 @@ packages: resolution: {integrity: sha512-Qush0uP+G8ZScpGMZvHUiRfI0YBWuB3gVBYlI0v0vvOJt5FLicco+IkP0a50LqTTQhmts/m6tP5SWE+USyIvcQ==} engines: {node: '>=12.20'} - jwa@2.0.0: - resolution: {integrity: sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==} + jwa@2.0.1: + resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} jws@4.0.0: resolution: {integrity: sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==} @@ -2293,8 +2437,8 @@ packages: resolution: {integrity: sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==} engines: {node: '>= 12.0.0'} - loupe@3.1.3: - resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} + loupe@3.1.4: + resolution: {integrity: sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg==} lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} @@ -2302,13 +2446,13 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - luxon@3.5.0: - resolution: {integrity: sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==} + luxon@3.6.1: + resolution: {integrity: sha512-tJLxrKJhO2ukZ5z0gyjY1zPh3Rh88Ej9P7jNrZiHMUXHae1yvI2imgOZtL1TO8TW6biMMKfTtAOoEJANgtWBMQ==} engines: {node: '>=12'} - magic-string-ast@0.7.0: - resolution: {integrity: sha512-686fgAHaJY7wLTFEq7nnKqeQrhqmXB19d1HnqT35Ci7BN6hbAYLZUezTQ062uUHM7ggZEQlqJ94Ftls+KDXU8Q==} - engines: {node: '>=16.14.0'} + magic-string-ast@1.0.0: + resolution: {integrity: sha512-8rbuNizut2gW94kv7pqgt0dvk+AHLPVIm0iJtpSgQJ9dx21eWx5SBel8z3jp1xtC0j6/iyK3AWGhAR1H61s7LA==} + engines: {node: '>=20.18.0'} magic-string@0.30.17: resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} @@ -2369,6 +2513,10 @@ packages: minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + minimatch@10.0.3: + resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==} + engines: {node: 20 || >=22} + minimatch@5.1.6: resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} engines: {node: '>=10'} @@ -2384,8 +2532,8 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} - minizlib@3.0.1: - resolution: {integrity: sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==} + minizlib@3.0.2: + resolution: {integrity: sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==} engines: {node: '>= 18'} mitt@3.0.1: @@ -2417,13 +2565,13 @@ packages: muggle-string@0.4.1: resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} - nanoid@3.3.8: - resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - nanoid@5.1.2: - resolution: {integrity: sha512-b+CiXQCNMUGe0Ri64S9SXFcP9hogjAJ2Rd6GdVxhPLRm7mhGaM7VgOvCAJ1ZshfHbqVDI3uqTI5C8/GaKuLI7g==} + nanoid@5.1.5: + resolution: {integrity: sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==} engines: {node: ^18 || >=20} hasBin: true @@ -2434,8 +2582,8 @@ packages: resolution: {integrity: sha512-Nc3loyVASW59W+8fLDZT1lncpG7llffyZ2o0UQLx/Fr20i7P8oP+lE7+TEcFvXj9IUWU6LjB9P3BH+iFGyp+mg==} engines: {node: ^14.16.0 || >=16.0.0} - nitropack@2.11.12: - resolution: {integrity: sha512-e2AdQrEY1IVoNTdyjfEQV93xkqz4SQxAMR0xWF8mZUUHxMLm6S4nPzpscjksmT4OdUxl0N8/DCaGjKQ9ghdodA==} + nitropack@2.11.13: + resolution: {integrity: sha512-xKng/szRZmFEsrB1Z+sFzYDhXL5KUtUkEouPCj9LiBPhJ7qV3jdOv1MSis++8H8zNI6dEurt51ZlK4VRDvedsA==} engines: {node: ^16.11.0 || >=17.0.0} hasBin: true peerDependencies: @@ -2476,8 +2624,8 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-mock-http@1.0.0: - resolution: {integrity: sha512-0uGYQ1WQL1M5kKvGRXWQ3uZCHtLTO8hln3oBjIusM75WoesZ909uQJs/Hb946i2SS+Gsrhkaa6iAO17jRIv6DQ==} + node-mock-http@1.0.1: + resolution: {integrity: sha512-0gJJgENizp4ghds/Ywu2FCmcRsgBTmRQzYPZm61wy+Em2sBarSka0OhQS5huLBg6od1zkNpnWMCZloQDFVvOMQ==} node-releases@2.0.19: resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} @@ -2518,9 +2666,9 @@ packages: nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - nuxt@3.17.4: - resolution: {integrity: sha512-49tkp7/+QVhuEOFoTDVvNV6Pc5+aI7wWjZHXzLUrt3tlWLPFh0yYbNXOc3kaxir1FuhRQHHyHZ7azCPmGukfFg==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0.0} + nuxt@3.17.6: + resolution: {integrity: sha512-kOsoJk7YvlcUChJXhCrVP18zRWKquUdrZSoJX8bCcQ54OhFOr4s2VhsxnbJVP7AtCiBSLbKuQt6ZBO7lE159Aw==} + engines: {node: ^20.9.0 || >=22.0.0} hasBin: true peerDependencies: '@parcel/watcher': ^2.1.0 @@ -2572,9 +2720,9 @@ packages: resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} engines: {node: '>=12'} - oxc-parser@0.71.0: - resolution: {integrity: sha512-RXmu7qi+67RJ8E5UhKZJdliTI+AqD3gncsJecjujcYvjsCZV9KNIfu42fQAnAfLaYZuzOMRdUYh7LzV3F1C0Gw==} - engines: {node: '>=14.0.0'} + oxc-parser@0.75.1: + resolution: {integrity: sha512-yq4gtrBM+kitDyQEtUtskdg9lqH5o1YOcYbJDKV9XGfJTdgbUiMNbYQi7gXsfOZlUGsmwsWEtmjcjYMSjPB1pA==} + engines: {node: '>=20.0.0'} p-event@6.0.1: resolution: {integrity: sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w==} @@ -2610,12 +2758,12 @@ packages: resolution: {integrity: sha512-RmVuCHWsfu0QPNW+mraxh/xjQVw/lhUCUru8Zni3Ctq3AoMhpDTq0OVdKS6iesd6Kqb7viCV3isAL43dciOSog==} engines: {node: '>=14'} - parse-json@8.1.0: - resolution: {integrity: sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==} + parse-json@8.3.0: + resolution: {integrity: sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==} engines: {node: '>=18'} - parse-path@7.0.1: - resolution: {integrity: sha512-6ReLMptznuuOEzLoGEa+I1oWRSj2Zna5jLWC+l6zlfAI4dbbSaIES29ThzuPkbhNahT65dWzfoZEO6cfJw2Ksg==} + parse-path@7.1.0: + resolution: {integrity: sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw==} parse-url@9.2.0: resolution: {integrity: sha512-bCgsFI+GeGWPAvAiUv63ZorMeif3/U0zaXABGJbOWt5OH2KCaPHF6S+0ok4aqM9RuIPGyZdx9tR9l13PsW4AYQ==} @@ -2657,8 +2805,8 @@ packages: pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - pathval@2.0.0: - resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + pathval@2.0.1: + resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} engines: {node: '>= 14.16'} pend@1.2.0: @@ -2678,8 +2826,8 @@ packages: resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} engines: {node: '>=12'} - pinia@3.0.2: - resolution: {integrity: sha512-sH2JK3wNY809JOeiiURUR0wehJ9/gd9qFN2Y828jCbxEzKEmEt0pzCXwqiSTfuRsK9vQsOflSdnbdBOGrhtn+g==} + pinia@3.0.3: + resolution: {integrity: sha512-ttXO/InUULUXkMHpTdp9Fj4hLpD/2AoJdmAbAeW2yu1iy1k+pkFekQXw5VpC0/5p51IOR/jDaDRfRWRnMMsGOA==} peerDependencies: typescript: '>=4.4.4' vue: ^2.7.0 || ^3.5.11 @@ -2690,8 +2838,8 @@ packages: pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} - pkg-types@2.1.0: - resolution: {integrity: sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==} + pkg-types@2.2.0: + resolution: {integrity: sha512-2SM/GZGAEkPp3KWORxQZns4M+WSeXbC2HEvmOIJe3Cmiv6ieAJvdVhDldtHqM5J1Y7MrR1XhkBT/rMlhh9FdqQ==} postcss-calc@10.1.1: resolution: {integrity: sha512-NYEsLHh8DgG/PRH2+G9BTuUdtf9ViS+vdoQ0YA5OQdGsfN4ztiwtDWNtBl9EKeqNMFnIu8IKZ0cLxEQ5r5KVMw==} @@ -2868,8 +3016,8 @@ packages: peerDependencies: postcss: ^8.2.9 - postcss@8.5.3: - resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} precinct@12.2.0: @@ -2895,8 +3043,8 @@ packages: protocols@2.0.2: resolution: {integrity: sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==} - pump@3.0.2: - resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} + pump@3.0.3: + resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} qs@6.14.0: resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} @@ -2988,16 +3136,12 @@ packages: rfdc@1.4.1: resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} - rimraf@5.0.10: - resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} - hasBin: true - - rollup-plugin-visualizer@5.14.0: - resolution: {integrity: sha512-VlDXneTDaKsHIw8yzJAFWtrzguoJ/LnQ+lMpoVfYJ3jJF4Ihe5oYLAqLklIK/35lgUY+1yEzCkHyZ1j4A5w5fA==} + rollup-plugin-visualizer@6.0.3: + resolution: {integrity: sha512-ZU41GwrkDcCpVoffviuM9Clwjy5fcUxlz0oMoTXTYsK+tcIFzbdacnrr2n8TXcHxbGKKXtOdjxM2HUS4HjkwIw==} engines: {node: '>=18'} hasBin: true peerDependencies: - rolldown: 1.x + rolldown: 1.x || ^1.0.0-beta rollup: 2.x || 3.x || 4.x peerDependenciesMeta: rolldown: @@ -3005,8 +3149,8 @@ packages: rollup: optional: true - rollup@4.41.0: - resolution: {integrity: sha512-HqMFpUbWlf/tvcxBFNKnJyzc7Lk+XO3FGc3pbNBLqEbOz0gPLRgcrlS3UF4MfUrVlstOaP/q0kM6GVvi+LrLRg==} + rollup@4.44.2: + resolution: {integrity: sha512-PVoapzTwSEcelaWGth3uR66u7ZRo6qhPHc0f2uRO9fX6XDVNrIiGYS0Pj9+R8yIIYSD/mCx2b16Ws9itljKSPg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -3067,8 +3211,8 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - shell-quote@1.8.2: - resolution: {integrity: sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==} + shell-quote@1.8.3: + resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} engines: {node: '>= 0.4'} side-channel-list@1.0.0: @@ -3094,8 +3238,8 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - simple-git@3.27.0: - resolution: {integrity: sha512-ivHoFS9Yi9GY49ogc6/YAi3Fl9ROnF4VyubNylgCkA+RVqLaKWnDSzXOVzya8csELIaWaYNutsEuAhZrtOjozA==} + simple-git@3.28.0: + resolution: {integrity: sha512-Rs/vQRwsn1ILH1oBUy8NucJlXmnnLeLCfcvbSehkPzbv3wwoFWIdtfd6Ndo6ZPhlPsCZ60CPI4rxurnwAa+a2w==} simple-swizzle@0.2.2: resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} @@ -3158,11 +3302,15 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + std-env@3.9.0: resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} - streamx@2.22.0: - resolution: {integrity: sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==} + streamx@2.22.1: + resolution: {integrity: sha512-znKXEBxfatz2GBNK02kRnCXjV+AA4kjZIUxeWSr3UGirZMJfTE9uiwKHobnbgxWyL/JWro8tTq+vOqAK1/qbSA==} string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} @@ -3223,8 +3371,8 @@ packages: resolution: {integrity: sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA==} engines: {node: '>=18'} - tapable@2.2.1: - resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + tapable@2.2.2: + resolution: {integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==} engines: {node: '>=6'} tar-stream@3.1.7: @@ -3234,8 +3382,8 @@ packages: resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} engines: {node: '>=18'} - terser@5.39.0: - resolution: {integrity: sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==} + terser@5.43.1: + resolution: {integrity: sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==} engines: {node: '>=10'} hasBin: true @@ -3257,16 +3405,12 @@ packages: tinyexec@1.0.1: resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==} - tinyglobby@0.2.13: - resolution: {integrity: sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==} - engines: {node: '>=12.0.0'} - tinyglobby@0.2.14: resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} engines: {node: '>=12.0.0'} - tinypool@1.1.0: - resolution: {integrity: sha512-7CotroY9a8DKsKprEy/a14aCCm8jYVmR7aFy4fpkZM8sdpNJbKkixuNjgM50yCmip2ezc8z4N7k3oe2+rfRJCQ==} + tinypool@1.1.1: + resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} engines: {node: ^18.0.0 || >=20.0.0} tinyrainbow@2.0.0: @@ -3315,12 +3459,12 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - type-fest@4.36.0: - resolution: {integrity: sha512-3T/PUdKTCnkUmhQU6FFJEHsLwadsRegktX3TNHk+2JJB9HlA8gp1/VXblXVDI93kSnXF2rdPx0GMbHtJIV2LPg==} + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} - typescript@5.8.2: - resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} + typescript@5.8.3: + resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} engines: {node: '>=14.17'} hasBin: true @@ -3336,14 +3480,14 @@ packages: unctx@2.4.1: resolution: {integrity: sha512-AbaYw0Nm4mK4qjhns67C+kgxR2YWiwlDBPzxrN8h8C6VtAdCgditAY5Dezu3IJy4XVqAnbrXt9oQJvsn3fyozg==} - undici-types@6.20.0: - resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + undici-types@7.8.0: + resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} - unenv@2.0.0-rc.17: - resolution: {integrity: sha512-B06u0wXkEd+o5gOCMl/ZHl5cfpYbDZKAT+HWTL+Hws6jWu7dCiqBBXXXzMFcFVJb8D4ytAnYmxJA83uwOQRSsg==} + unenv@2.0.0-rc.18: + resolution: {integrity: sha512-O0oVQVJ2X3Q8H4HITJr4e2cWxMYBeZ+p8S25yoKCxVCgDWtIJDcgwWNonYz12tI3ylVQCRyPV/Bdq0KJeXo7AA==} - unhead@2.0.10: - resolution: {integrity: sha512-GT188rzTCeSKt55tYyQlHHKfUTtZvgubrXiwzGeXg6UjcKO3FsagaMzQp6TVDrpDY++3i7Qt0t3pnCc/ebg5yQ==} + unhead@2.0.12: + resolution: {integrity: sha512-5oo0lwz81XDXCmrHGzgmbaNOxM8R9MZ3FkEs2ROHeW8e16xsrv7qXykENlISrcxr3RLPHQEsD1b6js9P2Oj/Ow==} unicorn-magic@0.1.0: resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} @@ -3353,8 +3497,8 @@ packages: resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} engines: {node: '>=18'} - unimport@5.0.1: - resolution: {integrity: sha512-1YWzPj6wYhtwHE+9LxRlyqP4DiRrhGfJxdtH475im8ktyZXO3jHj/3PZ97zDdvkYoovFdi0K4SKl3a7l92v3sQ==} + unimport@5.1.0: + resolution: {integrity: sha512-wMmuG+wkzeHh2KCE6yiDlHmKelN8iE/maxkUYMbmrS6iV8+n6eP1TH3yKKlepuF4hrkepinEGmBXdfo9XZUvAw==} engines: {node: '>=18.12.0'} unixify@1.0.0: @@ -3365,10 +3509,11 @@ packages: resolution: {integrity: sha512-8U/MtpkPkkk3Atewj1+RcKIjb5WBimZ/WSLhhR3w6SsIj8XJuKTacSP8g+2JhfSGw0Cb125Y+2zA/IzJZDVbhA==} engines: {node: '>=18.12.0'} - unplugin-vue-router@0.12.0: - resolution: {integrity: sha512-xjgheKU0MegvXQcy62GVea0LjyOdMxN0/QH+ijN29W62ZlMhG7o7K+0AYqfpprvPwpWtuRjiyC5jnV2SxWye2w==} + unplugin-vue-router@0.14.0: + resolution: {integrity: sha512-ipjunvS5e2aFHBAUFuLbHl2aHKbXXXBhTxGT9wZx66fNVPdEQzVVitF8nODr1plANhTTa3UZ+DQu9uyLngMzoQ==} peerDependencies: - vue-router: ^4.4.0 + '@vue/compiler-sfc': ^3.5.17 + vue-router: ^4.5.1 peerDependenciesMeta: vue-router: optional: true @@ -3377,8 +3522,8 @@ packages: resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==} engines: {node: '>=14.0.0'} - unplugin@2.3.4: - resolution: {integrity: sha512-m4PjxTurwpWfpMomp8AptjD5yj8qEZN5uQjjGM3TAs9MWWD2tXSSNNj6jGR2FoVGod4293ytyV6SwBbertfyJg==} + unplugin@2.3.5: + resolution: {integrity: sha512-RyWSb5AHmGtjjNQ6gIlA67sHOsWpsbWpwDokLwTcejVdOjEkJZh7QKu14J00gDDVSh8kGH4KYC/TNBceXFZhtw==} engines: {node: '>=18.12.0'} unstorage@1.16.0: @@ -3476,23 +3621,18 @@ packages: validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} - vite-dev-rpc@1.0.7: - resolution: {integrity: sha512-FxSTEofDbUi2XXujCA+hdzCDkXFG1PXktMjSk1efq9Qb5lOYaaM9zNSvKvPPF7645Bak79kSp1PTooMW2wktcA==} + vite-dev-rpc@1.1.0: + resolution: {integrity: sha512-pKXZlgoXGoE8sEKiKJSng4hI1sQ4wi5YT24FCrwrLt6opmkjlqPPVmiPWWJn8M8byMxRGzp1CrFuqQs4M/Z39A==} peerDependencies: - vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.1 + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.1 || ^7.0.0-0 - vite-hot-client@2.0.4: - resolution: {integrity: sha512-W9LOGAyGMrbGArYJN4LBCdOC5+Zwh7dHvOHC0KmGKkJhsOzaKbpo/jEjpPKVHIW0/jBWj8RZG0NUxfgA8BxgAg==} + vite-hot-client@2.1.0: + resolution: {integrity: sha512-7SpgZmU7R+dDnSmvXE1mfDtnHLHQSisdySVR7lO8ceAXvM0otZeuQQ6C8LrS5d/aYyP/QZ0hI0L+dIPrm4YlFQ==} peerDependencies: - vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 + vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 - vite-node@3.1.4: - resolution: {integrity: sha512-6enNwYnpyDo4hEgytbmc6mYWHXDHYEn0D1/rw4Q+tnHUGtKTJsn8T1YkX6Q18wI5LCrS8CTYlBaiCqxOy2kvUA==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true - - vite-node@3.2.3: - resolution: {integrity: sha512-gc8aAifGuDIpZHrPjuHyP4dpQmYXqWw7D1GmDnWeNWP654UEXzVfQ5IHPSK5HaHkwB/+p1atpYpSdw/2kOv8iQ==} + 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 @@ -3530,20 +3670,20 @@ packages: vue-tsc: optional: true - vite-plugin-inspect@11.1.0: - resolution: {integrity: sha512-r3Nx8xGQ08bSoNu7gJGfP5H/wNOROHtv0z3tWspplyHZJlABwNoPOdFEmcVh+lVMDyk/Be4yt8oS596ZHoYhOg==} + vite-plugin-inspect@11.3.0: + resolution: {integrity: sha512-vmt7K1WVKQkuiwvsM6e5h3HDJ2pSWTnzoj+JP9Kvu3Sh2G+nFap1F1V7tqpyA4qFxM1GQ84ryffWFGQrwShERQ==} engines: {node: '>=14'} peerDependencies: '@nuxt/kit': '*' - vite: ^6.0.0 + vite: ^6.0.0 || ^7.0.0-0 peerDependenciesMeta: '@nuxt/kit': optional: true - vite-plugin-vue-tracer@0.1.3: - resolution: {integrity: sha512-+fN6oo0//dwZP9Ax9gRKeUroCqpQ43P57qlWgL0ljCIxAs+Rpqn/L4anIPZPgjDPga5dZH+ZJsshbF0PNJbm3Q==} + vite-plugin-vue-tracer@1.0.0: + resolution: {integrity: sha512-a+UB9IwGx5uwS4uG/a9kM6fCMnxONDkOTbgCUbhFpiGhqfxrrC1+9BibV7sWwUnwj1Dg6MnRxG0trLgUZslDXA==} peerDependencies: - vite: ^6.0.0 + vite: ^6.0.0 || ^7.0.0 vue: ^3.5.0 vite@6.3.5: @@ -3586,19 +3726,59 @@ packages: yaml: optional: true + vite@7.0.2: + resolution: {integrity: sha512-hxdyZDY1CM6SNpKI4w4lcUc3Mtkd9ej4ECWVHSMrOdSinVc2zYOAppHeGc/hzmRo3pxM5blMzkuWHOJA/3NiFw==} + 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 + vitest-environment-nuxt@1.0.1: resolution: {integrity: sha512-eBCwtIQriXW5/M49FjqNKfnlJYlG2LWMSNFsRVKomc8CaMqmhQPBS5LZ9DlgYL9T8xIVsiA6RZn2lk7vxov3Ow==} - vitest@3.2.3: - resolution: {integrity: sha512-E6U2ZFXe3N/t4f5BwUaVCKRLHqUpk1CBWeMh78UT4VaTPH/2dyvH6ALl29JTovEPu9dVKr/K/J4PkXgrMbw4Ww==} + vitest@3.2.4: + resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/debug': ^4.1.12 '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - '@vitest/browser': 3.2.3 - '@vitest/ui': 3.2.3 + '@vitest/browser': 3.2.4 + '@vitest/ui': 3.2.4 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -3631,22 +3811,14 @@ packages: peerDependencies: vue: ^3.2.0 - vue-tsc@2.2.10: - resolution: {integrity: sha512-jWZ1xSaNbabEV3whpIDMbjVSVawjAyW+x1n3JeGQo7S0uv2n9F/JMgWW90tGWNFRKya4YwKMZgCtr0vRAM7DeQ==} + vue-tsc@3.0.1: + resolution: {integrity: sha512-UvMLQD0hAGL1g/NfEQelnSVB4H5gtf/gz2lJKjMMwWNOUmSNyWkejwJagAxEbSjtV5CPPJYslOtoSuqJ63mhdg==} hasBin: true peerDependencies: typescript: '>=5.0.0' - vue@3.5.14: - resolution: {integrity: sha512-LbOm50/vZFG6Mhy6KscQYXZMQ0LMCC/y40HDJPPvGFQ+i/lUH+PJHR6C3assgOQiXdl6tAfsXHbXYVBZZu65ew==} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - vue@3.5.16: - resolution: {integrity: sha512-rjOV2ecxMd5SiAmof2xzh2WxntRcigkX/He4YFJ6WdRvVUrbt6DxC1Iujh10XLl8xCDRDtGKMeO3D+pRQ1PP9w==} + vue@3.5.17: + resolution: {integrity: sha512-LbHV3xPN9BeljML+Xctq4lbz2lVHCR6DtbpTf5XIO6gugpXUN49j2QQPcMj086r9+AkJ0FfUT8xjulKKBkkr9g==} peerDependencies: typescript: '*' peerDependenciesMeta: @@ -3717,8 +3889,8 @@ packages: resolution: {integrity: sha512-GmqrO8WJ1NuzJ2DrziEI2o57jKAVIQNf8a18W3nCYU3H7PNWqCCVTeH6/NQE93CIllIgQS98rrmVkYgTX9fFJQ==} engines: {node: ^18.17.0 || >=20.5.0} - ws@8.18.2: - resolution: {integrity: sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==} + ws@8.18.3: + resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -3740,9 +3912,9 @@ packages: resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} engines: {node: '>=18'} - yaml@2.7.0: - resolution: {integrity: sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==} - engines: {node: '>= 14'} + yaml@2.8.0: + resolution: {integrity: sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==} + engines: {node: '>= 14.6'} hasBin: true yargs-parser@21.1.1: @@ -3760,27 +3932,29 @@ packages: resolution: {integrity: sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==} engines: {node: '>=12.20'} - youch-core@0.3.2: - resolution: {integrity: sha512-fusrlIMLeRvTFYLUjJ9KzlGC3N+6MOPJ68HNj/yJv2nz7zq8t4HEviLms2gkdRPUS7F5rZ5n+pYx9r88m6IE1g==} - engines: {node: '>=18'} + youch-core@0.3.3: + resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==} - youch@4.1.0-beta.7: - resolution: {integrity: sha512-HUn0M24AUTMvjdkoMtH8fJz2FEd+k1xvtR9EoTrDUoVUi6o7xl5X+pST/vjk4T3GEQo2mJ9FlAvhWBm8dIdD4g==} + youch@4.1.0-beta.10: + resolution: {integrity: sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==} + + youch@4.1.0-beta.8: + resolution: {integrity: sha512-rY2A2lSF7zC+l7HH9Mq+83D1dLlsPnEvy8jTouzaptDZM6geqZ3aJe/b7ULCwRURPtWV3vbDjA2DDMdoBol0HQ==} engines: {node: '>=18'} zip-stream@6.0.1: resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} engines: {node: '>= 14'} - zod@3.25.30: - resolution: {integrity: sha512-VolhdEtu6TJr/fzGuHA/SZ5ixvXqA6ADOG9VRcQ3rdOKmF5hkmcJbyaQjUH5BgmpA9gej++zYRX7zjSmdReIwA==} + zod@3.25.75: + resolution: {integrity: sha512-OhpzAmVzabPOL6C3A3gpAifqr9MqihV/Msx3gor2b2kviCgcb+HM9SEOpMWwwNp9MRunWnhtAKUoo0AHhjyPPg==} snapshots: '@ampproject/remapping@2.3.0': dependencies: - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/gen-mapping': 0.3.12 + '@jridgewell/trace-mapping': 0.3.29 '@babel/code-frame@7.27.1': dependencies: @@ -3788,20 +3962,20 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.27.2': {} + '@babel/compat-data@7.28.0': {} - '@babel/core@7.27.1': + '@babel/core@7.28.0': dependencies: '@ampproject/remapping': 2.3.0 '@babel/code-frame': 7.27.1 - '@babel/generator': 7.27.1 + '@babel/generator': 7.28.0 '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.27.1(@babel/core@7.27.1) - '@babel/helpers': 7.27.1 - '@babel/parser': 7.27.2 + '@babel/helper-module-transforms': 7.27.3(@babel/core@7.28.0) + '@babel/helpers': 7.27.6 + '@babel/parser': 7.28.0 '@babel/template': 7.27.2 - '@babel/traverse': 7.27.1 - '@babel/types': 7.27.1 + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.0 convert-source-map: 2.0.0 debug: 4.4.1 gensync: 1.0.0-beta.2 @@ -3810,81 +3984,83 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/generator@7.27.1': + '@babel/generator@7.28.0': dependencies: - '@babel/parser': 7.27.2 - '@babel/types': 7.27.1 - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 + '@babel/parser': 7.28.0 + '@babel/types': 7.28.0 + '@jridgewell/gen-mapping': 0.3.12 + '@jridgewell/trace-mapping': 0.3.29 jsesc: 3.1.0 - '@babel/helper-annotate-as-pure@7.27.1': + '@babel/helper-annotate-as-pure@7.27.3': dependencies: - '@babel/types': 7.27.1 + '@babel/types': 7.28.0 '@babel/helper-compilation-targets@7.27.2': dependencies: - '@babel/compat-data': 7.27.2 + '@babel/compat-data': 7.28.0 '@babel/helper-validator-option': 7.27.1 - browserslist: 4.24.5 + browserslist: 4.25.1 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.27.1(@babel/core@7.27.1)': + '@babel/helper-create-class-features-plugin@7.27.1(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.27.1 - '@babel/helper-annotate-as-pure': 7.27.1 + '@babel/core': 7.28.0 + '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-member-expression-to-functions': 7.27.1 '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.27.1) + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.0) '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/traverse': 7.27.1 + '@babel/traverse': 7.28.0 semver: 6.3.1 transitivePeerDependencies: - supports-color + '@babel/helper-globals@7.28.0': {} + '@babel/helper-member-expression-to-functions@7.27.1': dependencies: - '@babel/traverse': 7.27.1 - '@babel/types': 7.27.1 + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.0 transitivePeerDependencies: - supports-color '@babel/helper-module-imports@7.27.1': dependencies: - '@babel/traverse': 7.27.1 - '@babel/types': 7.27.1 + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.0 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.27.1(@babel/core@7.27.1)': + '@babel/helper-module-transforms@7.27.3(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.27.1 + '@babel/core': 7.28.0 '@babel/helper-module-imports': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.27.1 + '@babel/traverse': 7.28.0 transitivePeerDependencies: - supports-color '@babel/helper-optimise-call-expression@7.27.1': dependencies: - '@babel/types': 7.27.1 + '@babel/types': 7.28.0 '@babel/helper-plugin-utils@7.27.1': {} - '@babel/helper-replace-supers@7.27.1(@babel/core@7.27.1)': + '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.27.1 + '@babel/core': 7.28.0 '@babel/helper-member-expression-to-functions': 7.27.1 '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/traverse': 7.27.1 + '@babel/traverse': 7.28.0 transitivePeerDependencies: - supports-color '@babel/helper-skip-transparent-expression-wrappers@7.27.1': dependencies: - '@babel/traverse': 7.27.1 - '@babel/types': 7.27.1 + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.0 transitivePeerDependencies: - supports-color @@ -3894,55 +4070,55 @@ snapshots: '@babel/helper-validator-option@7.27.1': {} - '@babel/helpers@7.27.1': + '@babel/helpers@7.27.6': dependencies: '@babel/template': 7.27.2 - '@babel/types': 7.27.1 + '@babel/types': 7.28.0 - '@babel/parser@7.27.2': + '@babel/parser@7.28.0': dependencies: - '@babel/types': 7.27.1 + '@babel/types': 7.28.0 - '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.27.1)': + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.27.1 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.27.1)': + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.27.1 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-typescript@7.27.1(@babel/core@7.27.1)': + '@babel/plugin-transform-typescript@7.28.0(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.27.1 - '@babel/helper-annotate-as-pure': 7.27.1 - '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.1) + '@babel/core': 7.28.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.28.0) '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.0) transitivePeerDependencies: - supports-color '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 - '@babel/parser': 7.27.2 - '@babel/types': 7.27.1 + '@babel/parser': 7.28.0 + '@babel/types': 7.28.0 - '@babel/traverse@7.27.1': + '@babel/traverse@7.28.0': dependencies: '@babel/code-frame': 7.27.1 - '@babel/generator': 7.27.1 - '@babel/parser': 7.27.2 + '@babel/generator': 7.28.0 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.0 '@babel/template': 7.27.2 - '@babel/types': 7.27.1 + '@babel/types': 7.28.0 debug: 4.4.1 - globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/types@7.27.1': + '@babel/types@7.28.0': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 @@ -3964,101 +4140,185 @@ snapshots: gonzales-pe: 4.3.0 node-source-walk: 7.0.1 - '@emnapi/core@1.4.3': + '@emnapi/core@1.4.4': dependencies: - '@emnapi/wasi-threads': 1.0.2 + '@emnapi/wasi-threads': 1.0.3 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.4.3': + '@emnapi/runtime@1.4.4': dependencies: tslib: 2.8.1 optional: true - '@emnapi/wasi-threads@1.0.2': + '@emnapi/wasi-threads@1.0.3': dependencies: tslib: 2.8.1 optional: true - '@esbuild/aix-ppc64@0.25.4': + '@esbuild/aix-ppc64@0.25.5': optional: true - '@esbuild/android-arm64@0.25.4': + '@esbuild/aix-ppc64@0.25.6': optional: true - '@esbuild/android-arm@0.25.4': + '@esbuild/android-arm64@0.25.5': optional: true - '@esbuild/android-x64@0.25.4': + '@esbuild/android-arm64@0.25.6': optional: true - '@esbuild/darwin-arm64@0.25.4': + '@esbuild/android-arm@0.25.5': optional: true - '@esbuild/darwin-x64@0.25.4': + '@esbuild/android-arm@0.25.6': optional: true - '@esbuild/freebsd-arm64@0.25.4': + '@esbuild/android-x64@0.25.5': optional: true - '@esbuild/freebsd-x64@0.25.4': + '@esbuild/android-x64@0.25.6': optional: true - '@esbuild/linux-arm64@0.25.4': + '@esbuild/darwin-arm64@0.25.5': optional: true - '@esbuild/linux-arm@0.25.4': + '@esbuild/darwin-arm64@0.25.6': optional: true - '@esbuild/linux-ia32@0.25.4': + '@esbuild/darwin-x64@0.25.5': optional: true - '@esbuild/linux-loong64@0.25.4': + '@esbuild/darwin-x64@0.25.6': optional: true - '@esbuild/linux-mips64el@0.25.4': + '@esbuild/freebsd-arm64@0.25.5': optional: true - '@esbuild/linux-ppc64@0.25.4': + '@esbuild/freebsd-arm64@0.25.6': optional: true - '@esbuild/linux-riscv64@0.25.4': + '@esbuild/freebsd-x64@0.25.5': optional: true - '@esbuild/linux-s390x@0.25.4': + '@esbuild/freebsd-x64@0.25.6': optional: true - '@esbuild/linux-x64@0.25.4': + '@esbuild/linux-arm64@0.25.5': optional: true - '@esbuild/netbsd-arm64@0.25.4': + '@esbuild/linux-arm64@0.25.6': optional: true - '@esbuild/netbsd-x64@0.25.4': + '@esbuild/linux-arm@0.25.5': optional: true - '@esbuild/openbsd-arm64@0.25.4': + '@esbuild/linux-arm@0.25.6': optional: true - '@esbuild/openbsd-x64@0.25.4': + '@esbuild/linux-ia32@0.25.5': optional: true - '@esbuild/sunos-x64@0.25.4': + '@esbuild/linux-ia32@0.25.6': optional: true - '@esbuild/win32-arm64@0.25.4': + '@esbuild/linux-loong64@0.25.5': optional: true - '@esbuild/win32-ia32@0.25.4': + '@esbuild/linux-loong64@0.25.6': optional: true - '@esbuild/win32-x64@0.25.4': + '@esbuild/linux-mips64el@0.25.5': + optional: true + + '@esbuild/linux-mips64el@0.25.6': + optional: true + + '@esbuild/linux-ppc64@0.25.5': + optional: true + + '@esbuild/linux-ppc64@0.25.6': + optional: true + + '@esbuild/linux-riscv64@0.25.5': + optional: true + + '@esbuild/linux-riscv64@0.25.6': + optional: true + + '@esbuild/linux-s390x@0.25.5': + optional: true + + '@esbuild/linux-s390x@0.25.6': + optional: true + + '@esbuild/linux-x64@0.25.5': + optional: true + + '@esbuild/linux-x64@0.25.6': + optional: true + + '@esbuild/netbsd-arm64@0.25.5': + optional: true + + '@esbuild/netbsd-arm64@0.25.6': + optional: true + + '@esbuild/netbsd-x64@0.25.5': + optional: true + + '@esbuild/netbsd-x64@0.25.6': + optional: true + + '@esbuild/openbsd-arm64@0.25.5': + optional: true + + '@esbuild/openbsd-arm64@0.25.6': + optional: true + + '@esbuild/openbsd-x64@0.25.5': + optional: true + + '@esbuild/openbsd-x64@0.25.6': + optional: true + + '@esbuild/openharmony-arm64@0.25.6': + optional: true + + '@esbuild/sunos-x64@0.25.5': + optional: true + + '@esbuild/sunos-x64@0.25.6': + optional: true + + '@esbuild/win32-arm64@0.25.5': + optional: true + + '@esbuild/win32-arm64@0.25.6': + optional: true + + '@esbuild/win32-ia32@0.25.5': + optional: true + + '@esbuild/win32-ia32@0.25.6': + optional: true + + '@esbuild/win32-x64@0.25.5': + optional: true + + '@esbuild/win32-x64@0.25.6': optional: true '@fastify/busboy@3.1.1': {} '@ioredis/commands@1.2.0': {} + '@isaacs/balanced-match@4.0.1': {} + + '@isaacs/brace-expansion@5.0.0': + dependencies: + '@isaacs/balanced-match': 4.0.1 + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -4072,27 +4332,24 @@ snapshots: dependencies: minipass: 7.1.2 - '@jridgewell/gen-mapping@0.3.8': + '@jridgewell/gen-mapping@0.3.12': dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/sourcemap-codec': 1.5.4 + '@jridgewell/trace-mapping': 0.3.29 '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/set-array@1.2.1': {} - - '@jridgewell/source-map@0.3.6': + '@jridgewell/source-map@0.3.10': dependencies: - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/gen-mapping': 0.3.12 + '@jridgewell/trace-mapping': 0.3.29 - '@jridgewell/sourcemap-codec@1.5.0': {} + '@jridgewell/sourcemap-codec@1.5.4': {} - '@jridgewell/trace-mapping@0.3.25': + '@jridgewell/trace-mapping@0.3.29': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.4 '@kwsites/file-exists@1.1.1': dependencies: @@ -4105,7 +4362,7 @@ snapshots: '@mapbox/node-pre-gyp@2.0.0': dependencies: consola: 3.4.2 - detect-libc: 2.0.3 + detect-libc: 2.0.4 https-proxy-agent: 7.0.6 node-fetch: 2.7.0 nopt: 8.1.0 @@ -4115,10 +4372,10 @@ snapshots: - encoding - supports-color - '@napi-rs/wasm-runtime@0.2.10': + '@napi-rs/wasm-runtime@0.2.11': dependencies: - '@emnapi/core': 1.4.3 - '@emnapi/runtime': 1.4.3 + '@emnapi/core': 1.4.4 + '@emnapi/runtime': 1.4.4 '@tybys/wasm-util': 0.9.0 optional: true @@ -4143,12 +4400,12 @@ snapshots: uuid: 11.1.0 write-file-atomic: 6.0.0 - '@netlify/functions@3.1.9(rollup@4.41.0)': + '@netlify/functions@3.1.10(rollup@4.44.2)': dependencies: '@netlify/blobs': 9.1.2 '@netlify/dev-utils': 2.2.0 '@netlify/serverless-functions-api': 1.41.2 - '@netlify/zip-it-and-ship-it': 12.1.0(rollup@4.41.0) + '@netlify/zip-it-and-ship-it': 12.2.1(rollup@4.44.2) cron-parser: 4.9.0 decache: 4.6.2 extract-zip: 2.0.1 @@ -4168,23 +4425,24 @@ snapshots: '@netlify/serverless-functions-api@1.41.2': {} - '@netlify/zip-it-and-ship-it@12.1.0(rollup@4.41.0)': + '@netlify/serverless-functions-api@2.1.3': {} + + '@netlify/zip-it-and-ship-it@12.2.1(rollup@4.44.2)': dependencies: - '@babel/parser': 7.27.2 - '@babel/types': 7.27.1 + '@babel/parser': 7.28.0 + '@babel/types': 7.28.0 '@netlify/binary-info': 1.0.0 - '@netlify/serverless-functions-api': 1.41.2 - '@vercel/nft': 0.29.3(rollup@4.41.0) + '@netlify/serverless-functions-api': 2.1.3 + '@vercel/nft': 0.29.4(rollup@4.44.2) archiver: 7.0.1 common-path-prefix: 3.0.0 copy-file: 11.0.0 es-module-lexer: 1.7.0 - esbuild: 0.25.4 + esbuild: 0.25.5 execa: 8.0.1 fast-glob: 3.3.3 filter-obj: 6.1.0 find-up: 7.0.0 - glob: 8.1.0 is-builtin-module: 3.2.1 is-path-inside: 4.0.0 junk: 4.0.1 @@ -4203,7 +4461,7 @@ snapshots: unixify: 1.0.0 urlpattern-polyfill: 8.0.2 yargs: 17.7.2 - zod: 3.25.30 + zod: 3.25.75 transitivePeerDependencies: - encoding - rollup @@ -4240,51 +4498,50 @@ snapshots: ohash: 2.0.11 pathe: 2.0.3 perfect-debounce: 1.0.0 - pkg-types: 2.1.0 + pkg-types: 2.2.0 scule: 1.3.0 semver: 7.7.2 std-env: 3.9.0 tinyexec: 1.0.1 ufo: 1.6.1 - youch: 4.1.0-beta.7 + youch: 4.1.0-beta.10 transitivePeerDependencies: - magicast '@nuxt/devalue@2.0.2': {} - '@nuxt/devtools-kit@2.4.1(magicast@0.3.5)(vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))': + '@nuxt/devtools-kit@2.6.2(magicast@0.3.5)(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0))': dependencies: - '@nuxt/kit': 3.17.4(magicast@0.3.5) - '@nuxt/schema': 3.17.4 + '@nuxt/kit': 3.17.6(magicast@0.3.5) execa: 8.0.1 - vite: 6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) + vite: 6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0) transitivePeerDependencies: - magicast - '@nuxt/devtools-wizard@2.4.1': + '@nuxt/devtools-wizard@2.6.2': dependencies: consola: 3.4.2 - diff: 7.0.0 + diff: 8.0.2 execa: 8.0.1 magicast: 0.3.5 pathe: 2.0.3 - pkg-types: 2.1.0 + pkg-types: 2.2.0 prompts: 2.4.2 semver: 7.7.2 - '@nuxt/devtools@2.4.1(vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))(vue@3.5.14(typescript@5.8.2))': + '@nuxt/devtools@2.6.2(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.17(typescript@5.8.3))': dependencies: - '@nuxt/devtools-kit': 2.4.1(magicast@0.3.5)(vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0)) - '@nuxt/devtools-wizard': 2.4.1 - '@nuxt/kit': 3.17.4(magicast@0.3.5) - '@vue/devtools-core': 7.7.6(vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))(vue@3.5.14(typescript@5.8.2)) - '@vue/devtools-kit': 7.7.6 - birpc: 2.3.0 + '@nuxt/devtools-kit': 2.6.2(magicast@0.3.5)(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0)) + '@nuxt/devtools-wizard': 2.6.2 + '@nuxt/kit': 3.17.6(magicast@0.3.5) + '@vue/devtools-core': 7.7.7(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.17(typescript@5.8.3)) + '@vue/devtools-kit': 7.7.7 + birpc: 2.4.0 consola: 3.4.2 destr: 2.0.5 error-stack-parser-es: 1.0.5 execa: 8.0.1 - fast-npm-meta: 0.4.3 + fast-npm-meta: 0.4.4 get-port-please: 3.1.2 hookable: 5.5.3 image-meta: 0.2.1 @@ -4296,53 +4553,53 @@ snapshots: ohash: 2.0.11 pathe: 2.0.3 perfect-debounce: 1.0.0 - pkg-types: 2.1.0 + pkg-types: 2.2.0 semver: 7.7.2 - simple-git: 3.27.0 + simple-git: 3.28.0 sirv: 3.0.1 structured-clone-es: 1.0.0 - tinyglobby: 0.2.13 - vite: 6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) - vite-plugin-inspect: 11.1.0(@nuxt/kit@3.17.4(magicast@0.3.5))(vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0)) - vite-plugin-vue-tracer: 0.1.3(vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))(vue@3.5.14(typescript@5.8.2)) + tinyglobby: 0.2.14 + vite: 6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0) + vite-plugin-inspect: 11.3.0(@nuxt/kit@3.17.6(magicast@0.3.5))(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0)) + vite-plugin-vue-tracer: 1.0.0(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.17(typescript@5.8.3)) which: 5.0.0 - ws: 8.18.2 + ws: 8.18.3 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - vue - '@nuxt/kit@3.17.4(magicast@0.3.5)': + '@nuxt/kit@3.17.6(magicast@0.3.5)': dependencies: c12: 3.0.4(magicast@0.3.5) consola: 3.4.2 defu: 6.1.4 destr: 2.0.5 errx: 0.1.0 - exsolve: 1.0.5 - ignore: 7.0.4 + exsolve: 1.0.7 + ignore: 7.0.5 jiti: 2.4.2 klona: 2.0.6 knitwork: 1.2.0 mlly: 1.7.4 ohash: 2.0.11 pathe: 2.0.3 - pkg-types: 2.1.0 + pkg-types: 2.2.0 scule: 1.3.0 semver: 7.7.2 std-env: 3.9.0 - tinyglobby: 0.2.13 + tinyglobby: 0.2.14 ufo: 1.6.1 unctx: 2.4.1 - unimport: 5.0.1 + unimport: 5.1.0 untyped: 2.0.0 transitivePeerDependencies: - magicast - '@nuxt/schema@3.17.4': + '@nuxt/schema@3.17.6': dependencies: - '@vue/shared': 3.5.14 + '@vue/shared': 3.5.17 consola: 3.4.2 defu: 6.1.4 pathe: 2.0.3 @@ -4350,12 +4607,12 @@ snapshots: '@nuxt/telemetry@2.6.6(magicast@0.3.5)': dependencies: - '@nuxt/kit': 3.17.4(magicast@0.3.5) + '@nuxt/kit': 3.17.6(magicast@0.3.5) citty: 0.1.6 consola: 3.4.2 destr: 2.0.5 - dotenv: 16.5.0 - git-url-parse: 16.0.1 + dotenv: 16.6.1 + git-url-parse: 16.1.0 is-docker: 3.0.0 ofetch: 1.4.1 package-manager-detector: 1.3.0 @@ -4365,10 +4622,9 @@ snapshots: transitivePeerDependencies: - magicast - '@nuxt/test-utils@3.19.1(@types/node@22.13.8)(happy-dom@17.6.3)(jiti@2.4.2)(magicast@0.3.5)(terser@5.39.0)(typescript@5.8.2)(vitest@3.2.3(@types/node@22.13.8)(happy-dom@17.6.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))(yaml@2.7.0)': + '@nuxt/test-utils@3.19.2(happy-dom@17.6.3)(magicast@0.3.5)(typescript@5.8.3)(vitest@3.2.4(@types/node@24.0.10)(happy-dom@17.6.3)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0))': dependencies: - '@nuxt/kit': 3.17.4(magicast@0.3.5) - '@nuxt/schema': 3.17.4 + '@nuxt/kit': 3.17.6(magicast@0.3.5) c12: 3.0.4(magicast@0.3.5) consola: 3.4.2 defu: 6.1.4 @@ -4380,7 +4636,7 @@ snapshots: local-pkg: 1.1.1 magic-string: 0.30.17 node-fetch-native: 1.6.6 - node-mock-http: 1.0.0 + node-mock-http: 1.0.1 ofetch: 1.4.1 pathe: 2.0.3 perfect-debounce: 1.0.0 @@ -4389,41 +4645,29 @@ snapshots: std-env: 3.9.0 tinyexec: 1.0.1 ufo: 1.6.1 - unplugin: 2.3.4 - vite: 6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) - vitest-environment-nuxt: 1.0.1(@types/node@22.13.8)(happy-dom@17.6.3)(jiti@2.4.2)(magicast@0.3.5)(terser@5.39.0)(typescript@5.8.2)(vitest@3.2.3(@types/node@22.13.8)(happy-dom@17.6.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))(yaml@2.7.0) - vue: 3.5.16(typescript@5.8.2) + unplugin: 2.3.5 + vitest-environment-nuxt: 1.0.1(happy-dom@17.6.3)(magicast@0.3.5)(typescript@5.8.3)(vitest@3.2.4(@types/node@24.0.10)(happy-dom@17.6.3)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0)) + vue: 3.5.17(typescript@5.8.3) optionalDependencies: happy-dom: 17.6.3 - vitest: 3.2.3(@types/node@22.13.8)(happy-dom@17.6.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) + vitest: 3.2.4(@types/node@24.0.10)(happy-dom@17.6.3)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0) transitivePeerDependencies: - - '@types/node' - - jiti - - less - - lightningcss - magicast - - sass - - sass-embedded - - stylus - - sugarss - - terser - - tsx - typescript - - yaml - '@nuxt/vite-builder@3.17.4(@types/node@22.13.8)(magicast@0.3.5)(rollup@4.41.0)(terser@5.39.0)(typescript@5.8.2)(vue-tsc@2.2.10(typescript@5.8.2))(vue@3.5.14(typescript@5.8.2))(yaml@2.7.0)': + '@nuxt/vite-builder@3.17.6(@types/node@24.0.10)(magicast@0.3.5)(rollup@4.44.2)(terser@5.43.1)(typescript@5.8.3)(vue-tsc@3.0.1(typescript@5.8.3))(vue@3.5.17(typescript@5.8.3))(yaml@2.8.0)': dependencies: - '@nuxt/kit': 3.17.4(magicast@0.3.5) - '@rollup/plugin-replace': 6.0.2(rollup@4.41.0) - '@vitejs/plugin-vue': 5.2.4(vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))(vue@3.5.14(typescript@5.8.2)) - '@vitejs/plugin-vue-jsx': 4.2.0(vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))(vue@3.5.14(typescript@5.8.2)) - autoprefixer: 10.4.21(postcss@8.5.3) + '@nuxt/kit': 3.17.6(magicast@0.3.5) + '@rollup/plugin-replace': 6.0.2(rollup@4.44.2) + '@vitejs/plugin-vue': 5.2.4(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.17(typescript@5.8.3)) + '@vitejs/plugin-vue-jsx': 4.2.0(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.17(typescript@5.8.3)) + autoprefixer: 10.4.21(postcss@8.5.6) consola: 3.4.2 - cssnano: 7.0.7(postcss@8.5.3) + cssnano: 7.0.7(postcss@8.5.6) defu: 6.1.4 - esbuild: 0.25.4 + esbuild: 0.25.6 escape-string-regexp: 5.0.0 - exsolve: 1.0.5 + exsolve: 1.0.7 externality: 1.0.2 get-port-please: 3.1.2 h3: 1.15.3 @@ -4435,17 +4679,16 @@ snapshots: ohash: 2.0.11 pathe: 2.0.3 perfect-debounce: 1.0.0 - pkg-types: 2.1.0 - postcss: 8.5.3 - rollup-plugin-visualizer: 5.14.0(rollup@4.41.0) + pkg-types: 2.2.0 + postcss: 8.5.6 + rollup-plugin-visualizer: 6.0.3(rollup@4.44.2) std-env: 3.9.0 ufo: 1.6.1 - unenv: 2.0.0-rc.17 - unplugin: 2.3.4 - vite: 6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) - vite-node: 3.1.4(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) - vite-plugin-checker: 0.9.3(typescript@5.8.2)(vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))(vue-tsc@2.2.10(typescript@5.8.2)) - vue: 3.5.14(typescript@5.8.2) + unenv: 2.0.0-rc.18 + vite: 6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0) + vite-node: 3.2.4(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0) + vite-plugin-checker: 0.9.3(typescript@5.8.3)(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0))(vue-tsc@3.0.1(typescript@5.8.3)) + vue: 3.5.17(typescript@5.8.3) vue-bundle-renderer: 2.1.1 transitivePeerDependencies: - '@biomejs/biome' @@ -4472,51 +4715,54 @@ snapshots: - vue-tsc - yaml - '@oxc-parser/binding-darwin-arm64@0.71.0': + '@oxc-parser/binding-android-arm64@0.75.1': optional: true - '@oxc-parser/binding-darwin-x64@0.71.0': + '@oxc-parser/binding-darwin-arm64@0.75.1': optional: true - '@oxc-parser/binding-freebsd-x64@0.71.0': + '@oxc-parser/binding-darwin-x64@0.75.1': optional: true - '@oxc-parser/binding-linux-arm-gnueabihf@0.71.0': + '@oxc-parser/binding-freebsd-x64@0.75.1': optional: true - '@oxc-parser/binding-linux-arm-musleabihf@0.71.0': + '@oxc-parser/binding-linux-arm-gnueabihf@0.75.1': optional: true - '@oxc-parser/binding-linux-arm64-gnu@0.71.0': + '@oxc-parser/binding-linux-arm-musleabihf@0.75.1': optional: true - '@oxc-parser/binding-linux-arm64-musl@0.71.0': + '@oxc-parser/binding-linux-arm64-gnu@0.75.1': optional: true - '@oxc-parser/binding-linux-riscv64-gnu@0.71.0': + '@oxc-parser/binding-linux-arm64-musl@0.75.1': optional: true - '@oxc-parser/binding-linux-s390x-gnu@0.71.0': + '@oxc-parser/binding-linux-riscv64-gnu@0.75.1': optional: true - '@oxc-parser/binding-linux-x64-gnu@0.71.0': + '@oxc-parser/binding-linux-s390x-gnu@0.75.1': optional: true - '@oxc-parser/binding-linux-x64-musl@0.71.0': + '@oxc-parser/binding-linux-x64-gnu@0.75.1': optional: true - '@oxc-parser/binding-wasm32-wasi@0.71.0': + '@oxc-parser/binding-linux-x64-musl@0.75.1': + optional: true + + '@oxc-parser/binding-wasm32-wasi@0.75.1': dependencies: - '@napi-rs/wasm-runtime': 0.2.10 + '@napi-rs/wasm-runtime': 0.2.11 optional: true - '@oxc-parser/binding-win32-arm64-msvc@0.71.0': + '@oxc-parser/binding-win32-arm64-msvc@0.75.1': optional: true - '@oxc-parser/binding-win32-x64-msvc@0.71.0': + '@oxc-parser/binding-win32-x64-msvc@0.75.1': optional: true - '@oxc-project/types@0.71.0': {} + '@oxc-project/types@0.75.1': {} '@parcel/watcher-android-arm64@2.5.1': optional: true @@ -4583,156 +4829,156 @@ snapshots: '@parcel/watcher-win32-ia32': 2.5.1 '@parcel/watcher-win32-x64': 2.5.1 - '@pinia/nuxt@0.11.0(magicast@0.3.5)(pinia@3.0.2(typescript@5.8.2)(vue@3.5.14(typescript@5.8.2)))': + '@pinia/nuxt@0.11.1(magicast@0.3.5)(pinia@3.0.3(typescript@5.8.3)(vue@3.5.17(typescript@5.8.3)))': dependencies: - '@nuxt/kit': 3.17.4(magicast@0.3.5) - pinia: 3.0.2(typescript@5.8.2)(vue@3.5.14(typescript@5.8.2)) + '@nuxt/kit': 3.17.6(magicast@0.3.5) + pinia: 3.0.3(typescript@5.8.3)(vue@3.5.17(typescript@5.8.3)) transitivePeerDependencies: - magicast '@pkgjs/parseargs@0.11.0': optional: true - '@polka/url@1.0.0-next.28': {} + '@polka/url@1.0.0-next.29': {} - '@poppinss/colors@4.1.4': + '@poppinss/colors@4.1.5': dependencies: kleur: 4.1.5 - '@poppinss/dumper@0.6.3': + '@poppinss/dumper@0.6.4': dependencies: - '@poppinss/colors': 4.1.4 - '@sindresorhus/is': 7.0.1 + '@poppinss/colors': 4.1.5 + '@sindresorhus/is': 7.0.2 supports-color: 10.0.0 - '@poppinss/exception@1.2.1': {} + '@poppinss/exception@1.2.2': {} - '@rolldown/pluginutils@1.0.0-beta.9': {} + '@rolldown/pluginutils@1.0.0-beta.24': {} - '@rollup/plugin-alias@5.1.1(rollup@4.41.0)': + '@rollup/plugin-alias@5.1.1(rollup@4.44.2)': optionalDependencies: - rollup: 4.41.0 + rollup: 4.44.2 - '@rollup/plugin-commonjs@28.0.3(rollup@4.41.0)': + '@rollup/plugin-commonjs@28.0.6(rollup@4.44.2)': dependencies: - '@rollup/pluginutils': 5.1.4(rollup@4.41.0) + '@rollup/pluginutils': 5.2.0(rollup@4.44.2) commondir: 1.0.1 estree-walker: 2.0.2 - fdir: 6.4.4(picomatch@4.0.2) + fdir: 6.4.6(picomatch@4.0.2) is-reference: 1.2.1 magic-string: 0.30.17 picomatch: 4.0.2 optionalDependencies: - rollup: 4.41.0 + rollup: 4.44.2 - '@rollup/plugin-inject@5.0.5(rollup@4.41.0)': + '@rollup/plugin-inject@5.0.5(rollup@4.44.2)': dependencies: - '@rollup/pluginutils': 5.1.4(rollup@4.41.0) + '@rollup/pluginutils': 5.2.0(rollup@4.44.2) estree-walker: 2.0.2 magic-string: 0.30.17 optionalDependencies: - rollup: 4.41.0 + rollup: 4.44.2 - '@rollup/plugin-json@6.1.0(rollup@4.41.0)': + '@rollup/plugin-json@6.1.0(rollup@4.44.2)': dependencies: - '@rollup/pluginutils': 5.1.4(rollup@4.41.0) + '@rollup/pluginutils': 5.2.0(rollup@4.44.2) optionalDependencies: - rollup: 4.41.0 + rollup: 4.44.2 - '@rollup/plugin-node-resolve@16.0.1(rollup@4.41.0)': + '@rollup/plugin-node-resolve@16.0.1(rollup@4.44.2)': dependencies: - '@rollup/pluginutils': 5.1.4(rollup@4.41.0) + '@rollup/pluginutils': 5.2.0(rollup@4.44.2) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 resolve: 1.22.10 optionalDependencies: - rollup: 4.41.0 + rollup: 4.44.2 - '@rollup/plugin-replace@6.0.2(rollup@4.41.0)': + '@rollup/plugin-replace@6.0.2(rollup@4.44.2)': dependencies: - '@rollup/pluginutils': 5.1.4(rollup@4.41.0) + '@rollup/pluginutils': 5.2.0(rollup@4.44.2) magic-string: 0.30.17 optionalDependencies: - rollup: 4.41.0 + rollup: 4.44.2 - '@rollup/plugin-terser@0.4.4(rollup@4.41.0)': + '@rollup/plugin-terser@0.4.4(rollup@4.44.2)': dependencies: serialize-javascript: 6.0.2 smob: 1.5.0 - terser: 5.39.0 + terser: 5.43.1 optionalDependencies: - rollup: 4.41.0 + rollup: 4.44.2 - '@rollup/pluginutils@5.1.4(rollup@4.41.0)': + '@rollup/pluginutils@5.2.0(rollup@4.44.2)': dependencies: - '@types/estree': 1.0.7 + '@types/estree': 1.0.8 estree-walker: 2.0.2 picomatch: 4.0.2 optionalDependencies: - rollup: 4.41.0 + rollup: 4.44.2 - '@rollup/rollup-android-arm-eabi@4.41.0': + '@rollup/rollup-android-arm-eabi@4.44.2': optional: true - '@rollup/rollup-android-arm64@4.41.0': + '@rollup/rollup-android-arm64@4.44.2': optional: true - '@rollup/rollup-darwin-arm64@4.41.0': + '@rollup/rollup-darwin-arm64@4.44.2': optional: true - '@rollup/rollup-darwin-x64@4.41.0': + '@rollup/rollup-darwin-x64@4.44.2': optional: true - '@rollup/rollup-freebsd-arm64@4.41.0': + '@rollup/rollup-freebsd-arm64@4.44.2': optional: true - '@rollup/rollup-freebsd-x64@4.41.0': + '@rollup/rollup-freebsd-x64@4.44.2': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.41.0': + '@rollup/rollup-linux-arm-gnueabihf@4.44.2': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.41.0': + '@rollup/rollup-linux-arm-musleabihf@4.44.2': optional: true - '@rollup/rollup-linux-arm64-gnu@4.41.0': + '@rollup/rollup-linux-arm64-gnu@4.44.2': optional: true - '@rollup/rollup-linux-arm64-musl@4.41.0': + '@rollup/rollup-linux-arm64-musl@4.44.2': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.41.0': + '@rollup/rollup-linux-loongarch64-gnu@4.44.2': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.41.0': + '@rollup/rollup-linux-powerpc64le-gnu@4.44.2': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.41.0': + '@rollup/rollup-linux-riscv64-gnu@4.44.2': optional: true - '@rollup/rollup-linux-riscv64-musl@4.41.0': + '@rollup/rollup-linux-riscv64-musl@4.44.2': optional: true - '@rollup/rollup-linux-s390x-gnu@4.41.0': + '@rollup/rollup-linux-s390x-gnu@4.44.2': optional: true - '@rollup/rollup-linux-x64-gnu@4.41.0': + '@rollup/rollup-linux-x64-gnu@4.44.2': optional: true - '@rollup/rollup-linux-x64-musl@4.41.0': + '@rollup/rollup-linux-x64-musl@4.44.2': optional: true - '@rollup/rollup-win32-arm64-msvc@4.41.0': + '@rollup/rollup-win32-arm64-msvc@4.44.2': optional: true - '@rollup/rollup-win32-ia32-msvc@4.41.0': + '@rollup/rollup-win32-ia32-msvc@4.44.2': optional: true - '@rollup/rollup-win32-x64-msvc@4.41.0': + '@rollup/rollup-win32-x64-msvc@4.44.2': optional: true - '@sindresorhus/is@7.0.1': {} + '@sindresorhus/is@7.0.2': {} '@sindresorhus/merge-streams@2.3.0': {} @@ -4751,17 +4997,19 @@ snapshots: '@types/deep-eql@4.0.2': {} - '@types/estree@1.0.7': {} + '@types/estree@1.0.8': {} - '@types/luxon@3.4.2': {} + '@types/luxon@3.6.2': {} - '@types/node@22.13.8': + '@types/node@24.0.10': dependencies: - undici-types: 6.20.0 + undici-types: 7.8.0 '@types/normalize-package-data@2.4.4': {} - '@types/parse-path@7.0.3': {} + '@types/parse-path@7.1.0': + dependencies: + parse-path: 7.1.0 '@types/resolve@1.20.2': {} @@ -4769,46 +5017,61 @@ snapshots: '@types/web-push@3.6.4': dependencies: - '@types/node': 22.13.8 + '@types/node': 24.0.10 '@types/yauzl@2.10.3': dependencies: - '@types/node': 22.13.8 + '@types/node': 24.0.10 optional: true - '@typescript-eslint/types@8.32.1': {} - - '@typescript-eslint/typescript-estree@8.32.1(typescript@5.8.2)': + '@typescript-eslint/project-service@8.36.0(typescript@5.8.3)': dependencies: - '@typescript-eslint/types': 8.32.1 - '@typescript-eslint/visitor-keys': 8.32.1 + '@typescript-eslint/tsconfig-utils': 8.36.0(typescript@5.8.3) + '@typescript-eslint/types': 8.36.0 + debug: 4.4.1 + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/tsconfig-utils@8.36.0(typescript@5.8.3)': + dependencies: + typescript: 5.8.3 + + '@typescript-eslint/types@8.36.0': {} + + '@typescript-eslint/typescript-estree@8.36.0(typescript@5.8.3)': + dependencies: + '@typescript-eslint/project-service': 8.36.0(typescript@5.8.3) + '@typescript-eslint/tsconfig-utils': 8.36.0(typescript@5.8.3) + '@typescript-eslint/types': 8.36.0 + '@typescript-eslint/visitor-keys': 8.36.0 debug: 4.4.1 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.7.2 - ts-api-utils: 2.1.0(typescript@5.8.2) - typescript: 5.8.2 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.32.1': + '@typescript-eslint/visitor-keys@8.36.0': dependencies: - '@typescript-eslint/types': 8.32.1 - eslint-visitor-keys: 4.2.0 + '@typescript-eslint/types': 8.36.0 + eslint-visitor-keys: 4.2.1 - '@unhead/vue@2.0.10(vue@3.5.14(typescript@5.8.2))': + '@unhead/vue@2.0.12(vue@3.5.17(typescript@5.8.3))': dependencies: hookable: 5.5.3 - unhead: 2.0.10 - vue: 3.5.14(typescript@5.8.2) + unhead: 2.0.12 + vue: 3.5.17(typescript@5.8.3) - '@vercel/nft@0.29.3(rollup@4.41.0)': + '@vercel/nft@0.29.4(rollup@4.44.2)': dependencies: '@mapbox/node-pre-gyp': 2.0.0 - '@rollup/pluginutils': 5.1.4(rollup@4.41.0) - acorn: 8.14.1 - acorn-import-attributes: 1.9.5(acorn@8.14.1) + '@rollup/pluginutils': 5.2.0(rollup@4.44.2) + acorn: 8.15.0 + acorn-import-attributes: 1.9.5(acorn@8.15.0) async-sema: 3.1.1 bindings: 1.5.0 estree-walker: 2.0.2 @@ -4822,175 +5085,144 @@ snapshots: - rollup - supports-color - '@vitejs/plugin-vue-jsx@4.2.0(vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))(vue@3.5.14(typescript@5.8.2))': + '@vitejs/plugin-vue-jsx@4.2.0(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.17(typescript@5.8.3))': dependencies: - '@babel/core': 7.27.1 - '@babel/plugin-transform-typescript': 7.27.1(@babel/core@7.27.1) - '@rolldown/pluginutils': 1.0.0-beta.9 - '@vue/babel-plugin-jsx': 1.4.0(@babel/core@7.27.1) - vite: 6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) - vue: 3.5.14(typescript@5.8.2) + '@babel/core': 7.28.0 + '@babel/plugin-transform-typescript': 7.28.0(@babel/core@7.28.0) + '@rolldown/pluginutils': 1.0.0-beta.24 + '@vue/babel-plugin-jsx': 1.4.0(@babel/core@7.28.0) + vite: 6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0) + vue: 3.5.17(typescript@5.8.3) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue@5.2.4(vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))(vue@3.5.14(typescript@5.8.2))': + '@vitejs/plugin-vue@5.2.4(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.17(typescript@5.8.3))': dependencies: - vite: 6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) - vue: 3.5.14(typescript@5.8.2) + vite: 6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0) + vue: 3.5.17(typescript@5.8.3) - '@vitest/expect@3.2.3': + '@vitest/expect@3.2.4': dependencies: '@types/chai': 5.2.2 - '@vitest/spy': 3.2.3 - '@vitest/utils': 3.2.3 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 chai: 5.2.0 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.3(vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))': + '@vitest/mocker@3.2.4(vite@7.0.2(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0))': dependencies: - '@vitest/spy': 3.2.3 + '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) + vite: 7.0.2(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0) - '@vitest/pretty-format@3.2.3': + '@vitest/pretty-format@3.2.4': dependencies: tinyrainbow: 2.0.0 - '@vitest/runner@3.2.3': + '@vitest/runner@3.2.4': dependencies: - '@vitest/utils': 3.2.3 + '@vitest/utils': 3.2.4 pathe: 2.0.3 strip-literal: 3.0.0 - '@vitest/snapshot@3.2.3': + '@vitest/snapshot@3.2.4': dependencies: - '@vitest/pretty-format': 3.2.3 + '@vitest/pretty-format': 3.2.4 magic-string: 0.30.17 pathe: 2.0.3 - '@vitest/spy@3.2.3': + '@vitest/spy@3.2.4': dependencies: tinyspy: 4.0.3 - '@vitest/utils@3.2.3': + '@vitest/utils@3.2.4': dependencies: - '@vitest/pretty-format': 3.2.3 - loupe: 3.1.3 + '@vitest/pretty-format': 3.2.4 + loupe: 3.1.4 tinyrainbow: 2.0.0 - '@volar/language-core@2.4.14': + '@volar/language-core@2.4.17': dependencies: - '@volar/source-map': 2.4.14 + '@volar/source-map': 2.4.17 - '@volar/source-map@2.4.14': {} + '@volar/source-map@2.4.17': {} - '@volar/typescript@2.4.14': + '@volar/typescript@2.4.17': dependencies: - '@volar/language-core': 2.4.14 + '@volar/language-core': 2.4.17 path-browserify: 1.0.1 vscode-uri: 3.1.0 - '@vue-macros/common@1.16.1(vue@3.5.14(typescript@5.8.2))': + '@vue-macros/common@3.0.0-beta.15(vue@3.5.17(typescript@5.8.3))': dependencies: - '@vue/compiler-sfc': 3.5.14 - ast-kit: 1.4.0 + '@vue/compiler-sfc': 3.5.17 + ast-kit: 2.1.1 local-pkg: 1.1.1 - magic-string-ast: 0.7.0 - pathe: 2.0.3 - picomatch: 4.0.2 + magic-string-ast: 1.0.0 + unplugin-utils: 0.2.4 optionalDependencies: - vue: 3.5.14(typescript@5.8.2) + vue: 3.5.17(typescript@5.8.3) '@vue/babel-helper-vue-transform-on@1.4.0': {} - '@vue/babel-plugin-jsx@1.4.0(@babel/core@7.27.1)': + '@vue/babel-plugin-jsx@1.4.0(@babel/core@7.28.0)': dependencies: '@babel/helper-module-imports': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.27.1) + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.0) '@babel/template': 7.27.2 - '@babel/traverse': 7.27.1 - '@babel/types': 7.27.1 + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.0 '@vue/babel-helper-vue-transform-on': 1.4.0 - '@vue/babel-plugin-resolve-type': 1.4.0(@babel/core@7.27.1) - '@vue/shared': 3.5.14 + '@vue/babel-plugin-resolve-type': 1.4.0(@babel/core@7.28.0) + '@vue/shared': 3.5.17 optionalDependencies: - '@babel/core': 7.27.1 + '@babel/core': 7.28.0 transitivePeerDependencies: - supports-color - '@vue/babel-plugin-resolve-type@1.4.0(@babel/core@7.27.1)': + '@vue/babel-plugin-resolve-type@1.4.0(@babel/core@7.28.0)': dependencies: '@babel/code-frame': 7.27.1 - '@babel/core': 7.27.1 + '@babel/core': 7.28.0 '@babel/helper-module-imports': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 - '@babel/parser': 7.27.2 - '@vue/compiler-sfc': 3.5.14 + '@babel/parser': 7.28.0 + '@vue/compiler-sfc': 3.5.17 transitivePeerDependencies: - supports-color - '@vue/compiler-core@3.5.14': + '@vue/compiler-core@3.5.17': dependencies: - '@babel/parser': 7.27.2 - '@vue/shared': 3.5.14 + '@babel/parser': 7.28.0 + '@vue/shared': 3.5.17 entities: 4.5.0 estree-walker: 2.0.2 source-map-js: 1.2.1 - '@vue/compiler-core@3.5.16': + '@vue/compiler-dom@3.5.17': dependencies: - '@babel/parser': 7.27.2 - '@vue/shared': 3.5.16 - entities: 4.5.0 - estree-walker: 2.0.2 - source-map-js: 1.2.1 + '@vue/compiler-core': 3.5.17 + '@vue/shared': 3.5.17 - '@vue/compiler-dom@3.5.14': + '@vue/compiler-sfc@3.5.17': dependencies: - '@vue/compiler-core': 3.5.14 - '@vue/shared': 3.5.14 - - '@vue/compiler-dom@3.5.16': - dependencies: - '@vue/compiler-core': 3.5.16 - '@vue/shared': 3.5.16 - - '@vue/compiler-sfc@3.5.14': - dependencies: - '@babel/parser': 7.27.2 - '@vue/compiler-core': 3.5.14 - '@vue/compiler-dom': 3.5.14 - '@vue/compiler-ssr': 3.5.14 - '@vue/shared': 3.5.14 + '@babel/parser': 7.28.0 + '@vue/compiler-core': 3.5.17 + '@vue/compiler-dom': 3.5.17 + '@vue/compiler-ssr': 3.5.17 + '@vue/shared': 3.5.17 estree-walker: 2.0.2 magic-string: 0.30.17 - postcss: 8.5.3 + postcss: 8.5.6 source-map-js: 1.2.1 - '@vue/compiler-sfc@3.5.16': + '@vue/compiler-ssr@3.5.17': dependencies: - '@babel/parser': 7.27.2 - '@vue/compiler-core': 3.5.16 - '@vue/compiler-dom': 3.5.16 - '@vue/compiler-ssr': 3.5.16 - '@vue/shared': 3.5.16 - estree-walker: 2.0.2 - magic-string: 0.30.17 - postcss: 8.5.3 - source-map-js: 1.2.1 - - '@vue/compiler-ssr@3.5.14': - dependencies: - '@vue/compiler-dom': 3.5.14 - '@vue/shared': 3.5.14 - - '@vue/compiler-ssr@3.5.16': - dependencies: - '@vue/compiler-dom': 3.5.16 - '@vue/shared': 3.5.16 + '@vue/compiler-dom': 3.5.17 + '@vue/shared': 3.5.17 '@vue/compiler-vue2@2.7.16': dependencies: @@ -4999,96 +5231,72 @@ snapshots: '@vue/devtools-api@6.6.4': {} - '@vue/devtools-api@7.7.6': + '@vue/devtools-api@7.7.7': dependencies: - '@vue/devtools-kit': 7.7.6 + '@vue/devtools-kit': 7.7.7 - '@vue/devtools-core@7.7.6(vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))(vue@3.5.14(typescript@5.8.2))': + '@vue/devtools-core@7.7.7(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.17(typescript@5.8.3))': dependencies: - '@vue/devtools-kit': 7.7.6 - '@vue/devtools-shared': 7.7.6 + '@vue/devtools-kit': 7.7.7 + '@vue/devtools-shared': 7.7.7 mitt: 3.0.1 - nanoid: 5.1.2 + nanoid: 5.1.5 pathe: 2.0.3 - vite-hot-client: 2.0.4(vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0)) - vue: 3.5.14(typescript@5.8.2) + vite-hot-client: 2.1.0(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0)) + vue: 3.5.17(typescript@5.8.3) transitivePeerDependencies: - vite - '@vue/devtools-kit@7.7.6': + '@vue/devtools-kit@7.7.7': dependencies: - '@vue/devtools-shared': 7.7.6 - birpc: 2.3.0 + '@vue/devtools-shared': 7.7.7 + birpc: 2.4.0 hookable: 5.5.3 mitt: 3.0.1 perfect-debounce: 1.0.0 speakingurl: 14.0.1 superjson: 2.2.2 - '@vue/devtools-shared@7.7.6': + '@vue/devtools-shared@7.7.7': dependencies: rfdc: 1.4.1 - '@vue/language-core@2.2.10(typescript@5.8.2)': + '@vue/language-core@3.0.1(typescript@5.8.3)': dependencies: - '@volar/language-core': 2.4.14 - '@vue/compiler-dom': 3.5.16 + '@volar/language-core': 2.4.17 + '@vue/compiler-dom': 3.5.17 '@vue/compiler-vue2': 2.7.16 - '@vue/shared': 3.5.16 - alien-signals: 1.0.13 - minimatch: 9.0.5 + '@vue/shared': 3.5.17 + alien-signals: 2.0.5 + minimatch: 10.0.3 muggle-string: 0.4.1 path-browserify: 1.0.1 optionalDependencies: - typescript: 5.8.2 + typescript: 5.8.3 - '@vue/reactivity@3.5.14': + '@vue/reactivity@3.5.17': dependencies: - '@vue/shared': 3.5.14 + '@vue/shared': 3.5.17 - '@vue/reactivity@3.5.16': + '@vue/runtime-core@3.5.17': dependencies: - '@vue/shared': 3.5.16 + '@vue/reactivity': 3.5.17 + '@vue/shared': 3.5.17 - '@vue/runtime-core@3.5.14': + '@vue/runtime-dom@3.5.17': dependencies: - '@vue/reactivity': 3.5.14 - '@vue/shared': 3.5.14 - - '@vue/runtime-core@3.5.16': - dependencies: - '@vue/reactivity': 3.5.16 - '@vue/shared': 3.5.16 - - '@vue/runtime-dom@3.5.14': - dependencies: - '@vue/reactivity': 3.5.14 - '@vue/runtime-core': 3.5.14 - '@vue/shared': 3.5.14 + '@vue/reactivity': 3.5.17 + '@vue/runtime-core': 3.5.17 + '@vue/shared': 3.5.17 csstype: 3.1.3 - '@vue/runtime-dom@3.5.16': + '@vue/server-renderer@3.5.17(vue@3.5.17(typescript@5.8.3))': dependencies: - '@vue/reactivity': 3.5.16 - '@vue/runtime-core': 3.5.16 - '@vue/shared': 3.5.16 - csstype: 3.1.3 + '@vue/compiler-ssr': 3.5.17 + '@vue/shared': 3.5.17 + vue: 3.5.17(typescript@5.8.3) - '@vue/server-renderer@3.5.14(vue@3.5.14(typescript@5.8.2))': - dependencies: - '@vue/compiler-ssr': 3.5.14 - '@vue/shared': 3.5.14 - vue: 3.5.14(typescript@5.8.2) - - '@vue/server-renderer@3.5.16(vue@3.5.16(typescript@5.8.2))': - dependencies: - '@vue/compiler-ssr': 3.5.16 - '@vue/shared': 3.5.16 - vue: 3.5.16(typescript@5.8.2) - - '@vue/shared@3.5.14': {} - - '@vue/shared@3.5.16': {} + '@vue/shared@3.5.17': {} '@whatwg-node/disposablestack@0.0.6': dependencies: @@ -5118,21 +5326,21 @@ snapshots: '@whatwg-node/promise-helpers': 1.3.2 tslib: 2.8.1 - abbrev@3.0.0: {} + abbrev@3.0.1: {} abort-controller@3.0.0: dependencies: event-target-shim: 5.0.1 - acorn-import-attributes@1.9.5(acorn@8.14.1): + acorn-import-attributes@1.9.5(acorn@8.15.0): dependencies: - acorn: 8.14.1 + acorn: 8.15.0 - acorn@8.14.1: {} + acorn@8.15.0: {} - agent-base@7.1.3: {} + agent-base@7.1.4: {} - alien-signals@1.0.13: {} + alien-signals@2.0.5: {} ansi-regex@5.0.1: {} @@ -5144,7 +5352,7 @@ snapshots: ansi-styles@6.2.1: {} - ansis@3.17.0: {} + ansis@4.1.0: {} anymatch@3.1.3: dependencies: @@ -5173,37 +5381,37 @@ snapshots: asn1.js@5.4.1: dependencies: - bn.js: 4.12.1 + bn.js: 4.12.2 inherits: 2.0.4 minimalistic-assert: 1.0.1 safer-buffer: 2.1.2 assertion-error@2.0.1: {} - ast-kit@1.4.0: + ast-kit@2.1.1: dependencies: - '@babel/parser': 7.27.2 + '@babel/parser': 7.28.0 pathe: 2.0.3 ast-module-types@6.0.1: {} - ast-walker-scope@0.6.2: + ast-walker-scope@0.8.1: dependencies: - '@babel/parser': 7.27.2 - ast-kit: 1.4.0 + '@babel/parser': 7.28.0 + ast-kit: 2.1.1 async-sema@3.1.1: {} async@3.2.6: {} - autoprefixer@10.4.21(postcss@8.5.3): + autoprefixer@10.4.21(postcss@8.5.6): dependencies: - browserslist: 4.24.5 - caniuse-lite: 1.0.30001718 + browserslist: 4.25.1 + caniuse-lite: 1.0.30001727 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 b4a@1.6.7: {} @@ -5219,13 +5427,13 @@ snapshots: dependencies: file-uri-to-path: 1.0.0 - birpc@2.3.0: {} + birpc@2.4.0: {} - bn.js@4.12.1: {} + bn.js@4.12.2: {} boolbase@1.0.0: {} - brace-expansion@2.0.1: + brace-expansion@2.0.2: dependencies: balanced-match: 1.0.2 @@ -5233,12 +5441,12 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.24.5: + browserslist@4.25.1: dependencies: - caniuse-lite: 1.0.30001718 - electron-to-chromium: 1.5.157 + caniuse-lite: 1.0.30001727 + electron-to-chromium: 1.5.180 node-releases: 2.0.19 - update-browserslist-db: 1.1.3(browserslist@4.24.5) + update-browserslist-db: 1.1.3(browserslist@4.25.1) buffer-crc32@0.2.13: {} @@ -5264,14 +5472,14 @@ snapshots: chokidar: 4.0.3 confbox: 0.2.2 defu: 6.1.4 - dotenv: 16.5.0 - exsolve: 1.0.5 + dotenv: 16.6.1 + exsolve: 1.0.7 giget: 2.0.0 jiti: 2.4.2 ohash: 2.0.11 pathe: 2.0.3 perfect-debounce: 1.0.0 - pkg-types: 2.1.0 + pkg-types: 2.2.0 rc9: 2.1.2 optionalDependencies: magicast: 0.3.5 @@ -5292,20 +5500,20 @@ snapshots: caniuse-api@3.0.0: dependencies: - browserslist: 4.24.5 - caniuse-lite: 1.0.30001718 + browserslist: 4.25.1 + caniuse-lite: 1.0.30001727 lodash.memoize: 4.1.2 lodash.uniq: 4.5.0 - caniuse-lite@1.0.30001718: {} + caniuse-lite@1.0.30001727: {} chai@5.2.0: dependencies: assertion-error: 2.0.1 check-error: 2.1.1 deep-eql: 5.0.2 - loupe: 3.1.3 - pathval: 2.0.0 + loupe: 3.1.4 + pathval: 2.0.1 check-error@2.1.1: {} @@ -5418,9 +5626,9 @@ snapshots: cron-parser@4.9.0: dependencies: - luxon: 3.5.0 + luxon: 3.6.1 - croner@9.0.0: {} + croner@9.1.0: {} cross-spawn@7.0.6: dependencies: @@ -5432,14 +5640,14 @@ snapshots: dependencies: uncrypto: 0.1.3 - css-declaration-sorter@7.2.0(postcss@8.5.3): + css-declaration-sorter@7.2.0(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 - css-select@5.1.0: + css-select@5.2.2: dependencies: boolbase: 1.0.0 - css-what: 6.1.0 + css-what: 6.2.2 domhandler: 5.0.3 domutils: 3.2.2 nth-check: 2.1.1 @@ -5454,53 +5662,53 @@ snapshots: mdn-data: 2.0.30 source-map-js: 1.2.1 - css-what@6.1.0: {} + css-what@6.2.2: {} cssesc@3.0.0: {} - cssnano-preset-default@7.0.7(postcss@8.5.3): + cssnano-preset-default@7.0.7(postcss@8.5.6): dependencies: - browserslist: 4.24.5 - css-declaration-sorter: 7.2.0(postcss@8.5.3) - cssnano-utils: 5.0.1(postcss@8.5.3) - postcss: 8.5.3 - postcss-calc: 10.1.1(postcss@8.5.3) - postcss-colormin: 7.0.3(postcss@8.5.3) - postcss-convert-values: 7.0.5(postcss@8.5.3) - postcss-discard-comments: 7.0.4(postcss@8.5.3) - postcss-discard-duplicates: 7.0.2(postcss@8.5.3) - postcss-discard-empty: 7.0.1(postcss@8.5.3) - postcss-discard-overridden: 7.0.1(postcss@8.5.3) - postcss-merge-longhand: 7.0.5(postcss@8.5.3) - postcss-merge-rules: 7.0.5(postcss@8.5.3) - postcss-minify-font-values: 7.0.1(postcss@8.5.3) - postcss-minify-gradients: 7.0.1(postcss@8.5.3) - postcss-minify-params: 7.0.3(postcss@8.5.3) - postcss-minify-selectors: 7.0.5(postcss@8.5.3) - postcss-normalize-charset: 7.0.1(postcss@8.5.3) - postcss-normalize-display-values: 7.0.1(postcss@8.5.3) - postcss-normalize-positions: 7.0.1(postcss@8.5.3) - postcss-normalize-repeat-style: 7.0.1(postcss@8.5.3) - postcss-normalize-string: 7.0.1(postcss@8.5.3) - postcss-normalize-timing-functions: 7.0.1(postcss@8.5.3) - postcss-normalize-unicode: 7.0.3(postcss@8.5.3) - postcss-normalize-url: 7.0.1(postcss@8.5.3) - postcss-normalize-whitespace: 7.0.1(postcss@8.5.3) - postcss-ordered-values: 7.0.2(postcss@8.5.3) - postcss-reduce-initial: 7.0.3(postcss@8.5.3) - postcss-reduce-transforms: 7.0.1(postcss@8.5.3) - postcss-svgo: 7.0.2(postcss@8.5.3) - postcss-unique-selectors: 7.0.4(postcss@8.5.3) + browserslist: 4.25.1 + css-declaration-sorter: 7.2.0(postcss@8.5.6) + cssnano-utils: 5.0.1(postcss@8.5.6) + postcss: 8.5.6 + postcss-calc: 10.1.1(postcss@8.5.6) + postcss-colormin: 7.0.3(postcss@8.5.6) + postcss-convert-values: 7.0.5(postcss@8.5.6) + postcss-discard-comments: 7.0.4(postcss@8.5.6) + postcss-discard-duplicates: 7.0.2(postcss@8.5.6) + postcss-discard-empty: 7.0.1(postcss@8.5.6) + postcss-discard-overridden: 7.0.1(postcss@8.5.6) + postcss-merge-longhand: 7.0.5(postcss@8.5.6) + postcss-merge-rules: 7.0.5(postcss@8.5.6) + postcss-minify-font-values: 7.0.1(postcss@8.5.6) + postcss-minify-gradients: 7.0.1(postcss@8.5.6) + postcss-minify-params: 7.0.3(postcss@8.5.6) + postcss-minify-selectors: 7.0.5(postcss@8.5.6) + postcss-normalize-charset: 7.0.1(postcss@8.5.6) + postcss-normalize-display-values: 7.0.1(postcss@8.5.6) + postcss-normalize-positions: 7.0.1(postcss@8.5.6) + postcss-normalize-repeat-style: 7.0.1(postcss@8.5.6) + postcss-normalize-string: 7.0.1(postcss@8.5.6) + postcss-normalize-timing-functions: 7.0.1(postcss@8.5.6) + postcss-normalize-unicode: 7.0.3(postcss@8.5.6) + postcss-normalize-url: 7.0.1(postcss@8.5.6) + postcss-normalize-whitespace: 7.0.1(postcss@8.5.6) + postcss-ordered-values: 7.0.2(postcss@8.5.6) + postcss-reduce-initial: 7.0.3(postcss@8.5.6) + postcss-reduce-transforms: 7.0.1(postcss@8.5.6) + postcss-svgo: 7.0.2(postcss@8.5.6) + postcss-unique-selectors: 7.0.4(postcss@8.5.6) - cssnano-utils@5.0.1(postcss@8.5.3): + cssnano-utils@5.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 - cssnano@7.0.7(postcss@8.5.3): + cssnano@7.0.7(postcss@8.5.6): dependencies: - cssnano-preset-default: 7.0.7(postcss@8.5.3) + cssnano-preset-default: 7.0.7(postcss@8.5.6) lilconfig: 3.1.3 - postcss: 8.5.3 + postcss: 8.5.6 csso@5.0.5: dependencies: @@ -5547,7 +5755,7 @@ snapshots: detect-libc@1.0.3: {} - detect-libc@2.0.3: {} + detect-libc@2.0.4: {} detective-amd@6.0.1: dependencies: @@ -5565,11 +5773,11 @@ snapshots: dependencies: node-source-walk: 7.0.1 - detective-postcss@7.0.1(postcss@8.5.3): + detective-postcss@7.0.1(postcss@8.5.6): dependencies: is-url: 1.2.4 - postcss: 8.5.3 - postcss-values-parser: 6.0.2(postcss@8.5.3) + postcss: 8.5.6 + postcss-values-parser: 6.0.2(postcss@8.5.6) detective-sass@6.0.1: dependencies: @@ -5583,31 +5791,31 @@ snapshots: detective-stylus@5.0.1: {} - detective-typescript@14.0.0(typescript@5.8.2): + detective-typescript@14.0.0(typescript@5.8.3): dependencies: - '@typescript-eslint/typescript-estree': 8.32.1(typescript@5.8.2) + '@typescript-eslint/typescript-estree': 8.36.0(typescript@5.8.3) ast-module-types: 6.0.1 node-source-walk: 7.0.1 - typescript: 5.8.2 + typescript: 5.8.3 transitivePeerDependencies: - supports-color - detective-vue2@2.2.0(typescript@5.8.2): + detective-vue2@2.2.0(typescript@5.8.3): dependencies: '@dependents/detective-less': 5.0.1 - '@vue/compiler-sfc': 3.5.14 + '@vue/compiler-sfc': 3.5.17 detective-es6: 5.0.1 detective-sass: 6.0.1 detective-scss: 5.0.1 detective-stylus: 5.0.1 - detective-typescript: 14.0.0(typescript@5.8.2) - typescript: 5.8.2 + detective-typescript: 14.0.0(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - supports-color devalue@5.1.1: {} - diff@7.0.0: {} + diff@8.0.2: {} dom-serializer@2.0.0: dependencies: @@ -5629,9 +5837,9 @@ snapshots: dot-prop@9.0.0: dependencies: - type-fest: 4.36.0 + type-fest: 4.41.0 - dotenv@16.5.0: {} + dotenv@16.6.1: {} dunder-proto@1.0.1: dependencies: @@ -5649,7 +5857,7 @@ snapshots: ee-first@1.1.1: {} - electron-to-chromium@1.5.157: {} + electron-to-chromium@1.5.180: {} emoji-regex@8.0.0: {} @@ -5659,14 +5867,14 @@ snapshots: encodeurl@2.0.0: {} - end-of-stream@1.4.4: + end-of-stream@1.4.5: dependencies: once: 1.4.0 - enhanced-resolve@5.18.1: + enhanced-resolve@5.18.2: dependencies: graceful-fs: 4.2.11 - tapable: 2.2.1 + tapable: 2.2.2 entities@4.5.0: {} @@ -5686,33 +5894,62 @@ snapshots: dependencies: es-errors: 1.3.0 - esbuild@0.25.4: + esbuild@0.25.5: optionalDependencies: - '@esbuild/aix-ppc64': 0.25.4 - '@esbuild/android-arm': 0.25.4 - '@esbuild/android-arm64': 0.25.4 - '@esbuild/android-x64': 0.25.4 - '@esbuild/darwin-arm64': 0.25.4 - '@esbuild/darwin-x64': 0.25.4 - '@esbuild/freebsd-arm64': 0.25.4 - '@esbuild/freebsd-x64': 0.25.4 - '@esbuild/linux-arm': 0.25.4 - '@esbuild/linux-arm64': 0.25.4 - '@esbuild/linux-ia32': 0.25.4 - '@esbuild/linux-loong64': 0.25.4 - '@esbuild/linux-mips64el': 0.25.4 - '@esbuild/linux-ppc64': 0.25.4 - '@esbuild/linux-riscv64': 0.25.4 - '@esbuild/linux-s390x': 0.25.4 - '@esbuild/linux-x64': 0.25.4 - '@esbuild/netbsd-arm64': 0.25.4 - '@esbuild/netbsd-x64': 0.25.4 - '@esbuild/openbsd-arm64': 0.25.4 - '@esbuild/openbsd-x64': 0.25.4 - '@esbuild/sunos-x64': 0.25.4 - '@esbuild/win32-arm64': 0.25.4 - '@esbuild/win32-ia32': 0.25.4 - '@esbuild/win32-x64': 0.25.4 + '@esbuild/aix-ppc64': 0.25.5 + '@esbuild/android-arm': 0.25.5 + '@esbuild/android-arm64': 0.25.5 + '@esbuild/android-x64': 0.25.5 + '@esbuild/darwin-arm64': 0.25.5 + '@esbuild/darwin-x64': 0.25.5 + '@esbuild/freebsd-arm64': 0.25.5 + '@esbuild/freebsd-x64': 0.25.5 + '@esbuild/linux-arm': 0.25.5 + '@esbuild/linux-arm64': 0.25.5 + '@esbuild/linux-ia32': 0.25.5 + '@esbuild/linux-loong64': 0.25.5 + '@esbuild/linux-mips64el': 0.25.5 + '@esbuild/linux-ppc64': 0.25.5 + '@esbuild/linux-riscv64': 0.25.5 + '@esbuild/linux-s390x': 0.25.5 + '@esbuild/linux-x64': 0.25.5 + '@esbuild/netbsd-arm64': 0.25.5 + '@esbuild/netbsd-x64': 0.25.5 + '@esbuild/openbsd-arm64': 0.25.5 + '@esbuild/openbsd-x64': 0.25.5 + '@esbuild/sunos-x64': 0.25.5 + '@esbuild/win32-arm64': 0.25.5 + '@esbuild/win32-ia32': 0.25.5 + '@esbuild/win32-x64': 0.25.5 + + esbuild@0.25.6: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.6 + '@esbuild/android-arm': 0.25.6 + '@esbuild/android-arm64': 0.25.6 + '@esbuild/android-x64': 0.25.6 + '@esbuild/darwin-arm64': 0.25.6 + '@esbuild/darwin-x64': 0.25.6 + '@esbuild/freebsd-arm64': 0.25.6 + '@esbuild/freebsd-x64': 0.25.6 + '@esbuild/linux-arm': 0.25.6 + '@esbuild/linux-arm64': 0.25.6 + '@esbuild/linux-ia32': 0.25.6 + '@esbuild/linux-loong64': 0.25.6 + '@esbuild/linux-mips64el': 0.25.6 + '@esbuild/linux-ppc64': 0.25.6 + '@esbuild/linux-riscv64': 0.25.6 + '@esbuild/linux-s390x': 0.25.6 + '@esbuild/linux-x64': 0.25.6 + '@esbuild/netbsd-arm64': 0.25.6 + '@esbuild/netbsd-x64': 0.25.6 + '@esbuild/openbsd-arm64': 0.25.6 + '@esbuild/openbsd-x64': 0.25.6 + '@esbuild/openharmony-arm64': 0.25.6 + '@esbuild/sunos-x64': 0.25.6 + '@esbuild/win32-arm64': 0.25.6 + '@esbuild/win32-ia32': 0.25.6 + '@esbuild/win32-x64': 0.25.6 escalade@3.2.0: {} @@ -5728,7 +5965,7 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-visitor-keys@4.2.0: {} + eslint-visitor-keys@4.2.1: {} esprima@4.0.1: {} @@ -5738,7 +5975,7 @@ snapshots: estree-walker@3.0.3: dependencies: - '@types/estree': 1.0.7 + '@types/estree': 1.0.8 esutils@2.0.3: {} @@ -5760,13 +5997,13 @@ snapshots: signal-exit: 4.1.0 strip-final-newline: 3.0.0 - expect-type@1.2.1: {} + expect-type@1.2.2: {} - exsolve@1.0.5: {} + exsolve@1.0.7: {} externality@1.0.2: dependencies: - enhanced-resolve: 5.18.1 + enhanced-resolve: 5.18.2 mlly: 1.7.4 pathe: 1.1.2 ufo: 1.6.1 @@ -5793,7 +6030,7 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.8 - fast-npm-meta@0.4.3: {} + fast-npm-meta@0.4.4: {} fastq@1.19.1: dependencies: @@ -5803,7 +6040,7 @@ snapshots: dependencies: pend: 1.2.0 - fdir@6.4.4(picomatch@4.0.2): + fdir@6.4.6(picomatch@4.0.2): optionalDependencies: picomatch: 4.0.2 @@ -5845,8 +6082,6 @@ snapshots: fresh@2.0.0: {} - fs.realpath@1.0.0: {} - fsevents@2.3.3: optional: true @@ -5885,7 +6120,7 @@ snapshots: get-stream@5.2.0: dependencies: - pump: 3.0.2 + pump: 3.0.3 get-stream@8.0.1: {} @@ -5898,14 +6133,14 @@ snapshots: nypm: 0.6.0 pathe: 2.0.3 - git-up@8.0.1: + git-up@8.1.1: dependencies: is-ssh: 1.4.1 parse-url: 9.2.0 - git-url-parse@16.0.1: + git-url-parse@16.1.0: dependencies: - git-up: 8.0.1 + git-up: 8.1.1 glob-parent@5.1.2: dependencies: @@ -5920,25 +6155,15 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 1.11.1 - glob@8.1.0: - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 5.1.6 - once: 1.4.0 - global-directory@4.0.1: dependencies: ini: 4.1.1 - globals@11.12.0: {} - globby@14.1.0: dependencies: '@sindresorhus/merge-streams': 2.3.0 fast-glob: 3.3.3 - ignore: 7.0.4 + ignore: 7.0.5 path-type: 6.0.0 slash: 5.1.0 unicorn-magic: 0.3.0 @@ -5962,7 +6187,7 @@ snapshots: defu: 6.1.4 destr: 2.0.5 iron-webcrypto: 1.2.1 - node-mock-http: 1.0.0 + node-mock-http: 1.0.1 radix3: 1.1.2 ufo: 1.6.1 uncrypto: 0.1.3 @@ -6000,7 +6225,7 @@ snapshots: https-proxy-agent@7.0.6: dependencies: - agent-base: 7.1.3 + agent-base: 7.1.4 debug: 4.4.1 transitivePeerDependencies: - supports-color @@ -6011,26 +6236,21 @@ snapshots: ieee754@1.2.1: {} - ignore@7.0.4: {} + ignore@7.0.5: {} image-meta@0.2.1: {} impound@1.0.0: dependencies: - exsolve: 1.0.5 + exsolve: 1.0.7 mocked-exports: 0.1.1 pathe: 2.0.3 - unplugin: 2.3.4 + unplugin: 2.3.5 unplugin-utils: 0.2.4 imurmurhash@0.1.4: {} - index-to-position@0.1.2: {} - - inflight@1.0.6: - dependencies: - once: 1.4.0 - wrappy: 1.0.2 + index-to-position@1.1.0: {} inherits@2.0.4: {} @@ -6093,7 +6313,7 @@ snapshots: is-reference@1.2.1: dependencies: - '@types/estree': 1.0.7 + '@types/estree': 1.0.8 is-ssh@1.4.1: dependencies: @@ -6147,7 +6367,7 @@ snapshots: junk@4.0.1: {} - jwa@2.0.0: + jwa@2.0.1: dependencies: buffer-equal-constant-time: 1.0.1 ecdsa-sig-formatter: 1.0.11 @@ -6155,7 +6375,7 @@ snapshots: jws@4.0.0: dependencies: - jwa: 2.0.0 + jwa: 2.0.1 safe-buffer: 5.2.1 jwt-decode@4.0.0: {} @@ -6173,13 +6393,13 @@ snapshots: lambda-local@2.2.0: dependencies: commander: 10.0.1 - dotenv: 16.5.0 + dotenv: 16.6.1 winston: 3.17.0 launch-editor@2.10.0: dependencies: picocolors: 1.1.1 - shell-quote: 1.8.2 + shell-quote: 1.8.3 lazystream@1.0.1: dependencies: @@ -6211,7 +6431,7 @@ snapshots: local-pkg@1.1.1: dependencies: mlly: 1.7.4 - pkg-types: 2.1.0 + pkg-types: 2.2.0 quansync: 0.2.10 locate-path@7.2.0: @@ -6241,7 +6461,7 @@ snapshots: safe-stable-stringify: 2.5.0 triple-beam: 1.4.1 - loupe@3.1.3: {} + loupe@3.1.4: {} lru-cache@10.4.3: {} @@ -6249,20 +6469,20 @@ snapshots: dependencies: yallist: 3.1.1 - luxon@3.5.0: {} + luxon@3.6.1: {} - magic-string-ast@0.7.0: + magic-string-ast@1.0.0: dependencies: magic-string: 0.30.17 magic-string@0.30.17: dependencies: - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.4 magicast@0.3.5: dependencies: - '@babel/parser': 7.27.2 - '@babel/types': 7.27.1 + '@babel/parser': 7.28.0 + '@babel/types': 7.28.0 source-map-js: 1.2.1 math-intrinsics@1.1.0: {} @@ -6300,22 +6520,25 @@ snapshots: minimalistic-assert@1.0.1: {} + minimatch@10.0.3: + dependencies: + '@isaacs/brace-expansion': 5.0.0 + minimatch@5.1.6: dependencies: - brace-expansion: 2.0.1 + brace-expansion: 2.0.2 minimatch@9.0.5: dependencies: - brace-expansion: 2.0.1 + brace-expansion: 2.0.2 minimist@1.2.8: {} minipass@7.1.2: {} - minizlib@3.0.1: + minizlib@3.0.2: dependencies: minipass: 7.1.2 - rimraf: 5.0.10 mitt@3.0.1: {} @@ -6323,7 +6546,7 @@ snapshots: mlly@1.7.4: dependencies: - acorn: 8.14.1 + acorn: 8.15.0 pathe: 2.0.3 pkg-types: 1.3.1 ufo: 1.6.1 @@ -6341,9 +6564,9 @@ snapshots: muggle-string@0.4.1: {} - nanoid@3.3.8: {} + nanoid@3.3.11: {} - nanoid@5.1.2: {} + nanoid@5.1.5: {} nanotar@0.2.0: {} @@ -6356,18 +6579,18 @@ snapshots: p-wait-for: 5.0.2 qs: 6.14.0 - nitropack@2.11.12: + nitropack@2.11.13: dependencies: '@cloudflare/kv-asset-handler': 0.4.0 - '@netlify/functions': 3.1.9(rollup@4.41.0) - '@rollup/plugin-alias': 5.1.1(rollup@4.41.0) - '@rollup/plugin-commonjs': 28.0.3(rollup@4.41.0) - '@rollup/plugin-inject': 5.0.5(rollup@4.41.0) - '@rollup/plugin-json': 6.1.0(rollup@4.41.0) - '@rollup/plugin-node-resolve': 16.0.1(rollup@4.41.0) - '@rollup/plugin-replace': 6.0.2(rollup@4.41.0) - '@rollup/plugin-terser': 0.4.4(rollup@4.41.0) - '@vercel/nft': 0.29.3(rollup@4.41.0) + '@netlify/functions': 3.1.10(rollup@4.44.2) + '@rollup/plugin-alias': 5.1.1(rollup@4.44.2) + '@rollup/plugin-commonjs': 28.0.6(rollup@4.44.2) + '@rollup/plugin-inject': 5.0.5(rollup@4.44.2) + '@rollup/plugin-json': 6.1.0(rollup@4.44.2) + '@rollup/plugin-node-resolve': 16.0.1(rollup@4.44.2) + '@rollup/plugin-replace': 6.0.2(rollup@4.44.2) + '@rollup/plugin-terser': 0.4.4(rollup@4.44.2) + '@vercel/nft': 0.29.4(rollup@4.44.2) archiver: 7.0.1 c12: 3.0.4(magicast@0.3.5) chokidar: 4.0.3 @@ -6376,16 +6599,16 @@ snapshots: confbox: 0.2.2 consola: 3.4.2 cookie-es: 2.0.0 - croner: 9.0.0 + croner: 9.1.0 crossws: 0.3.5 db0: 0.3.2 defu: 6.1.4 destr: 2.0.5 dot-prop: 9.0.0 - esbuild: 0.25.4 + esbuild: 0.25.6 escape-string-regexp: 5.0.0 etag: 1.8.1 - exsolve: 1.0.5 + exsolve: 1.0.7 globby: 14.1.0 gzip-size: 7.0.0 h3: 1.15.3 @@ -6401,16 +6624,16 @@ snapshots: mime: 4.0.7 mlly: 1.7.4 node-fetch-native: 1.6.6 - node-mock-http: 1.0.0 + node-mock-http: 1.0.1 ofetch: 1.4.1 ohash: 2.0.11 pathe: 2.0.3 perfect-debounce: 1.0.0 - pkg-types: 2.1.0 + pkg-types: 2.2.0 pretty-bytes: 6.1.1 radix3: 1.1.2 - rollup: 4.41.0 - rollup-plugin-visualizer: 5.14.0(rollup@4.41.0) + rollup: 4.44.2 + rollup-plugin-visualizer: 6.0.3(rollup@4.44.2) scule: 1.3.0 semver: 7.7.2 serve-placeholder: 2.0.2 @@ -6421,14 +6644,14 @@ snapshots: ultrahtml: 1.6.0 uncrypto: 0.1.3 unctx: 2.4.1 - unenv: 2.0.0-rc.17 - unimport: 5.0.1 + unenv: 2.0.0-rc.18 + unimport: 5.1.0 unplugin-utils: 0.2.4 unstorage: 1.16.0(db0@0.3.2)(ioredis@5.6.1) untyped: 2.0.0 unwasm: 0.3.9 - youch: 4.1.0-beta.7 - youch-core: 0.3.2 + youch: 4.1.0-beta.8 + youch-core: 0.3.3 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -6476,17 +6699,17 @@ snapshots: node-gyp-build@4.8.4: {} - node-mock-http@1.0.0: {} + node-mock-http@1.0.1: {} node-releases@2.0.19: {} node-source-walk@7.0.1: dependencies: - '@babel/parser': 7.27.2 + '@babel/parser': 7.28.0 nopt@8.1.0: dependencies: - abbrev: 3.0.0 + abbrev: 3.0.1 normalize-package-data@6.0.2: dependencies: @@ -6515,17 +6738,17 @@ snapshots: dependencies: boolbase: 1.0.0 - nuxt@3.17.4(@parcel/watcher@2.5.1)(@types/node@22.13.8)(db0@0.3.2)(ioredis@5.6.1)(magicast@0.3.5)(rollup@4.41.0)(terser@5.39.0)(typescript@5.8.2)(vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))(vue-tsc@2.2.10(typescript@5.8.2))(yaml@2.7.0): + nuxt@3.17.6(@parcel/watcher@2.5.1)(@types/node@24.0.10)(@vue/compiler-sfc@3.5.17)(db0@0.3.2)(ioredis@5.6.1)(magicast@0.3.5)(rollup@4.44.2)(terser@5.43.1)(typescript@5.8.3)(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0))(vue-tsc@3.0.1(typescript@5.8.3))(yaml@2.8.0): dependencies: '@nuxt/cli': 3.25.1(magicast@0.3.5) '@nuxt/devalue': 2.0.2 - '@nuxt/devtools': 2.4.1(vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))(vue@3.5.14(typescript@5.8.2)) - '@nuxt/kit': 3.17.4(magicast@0.3.5) - '@nuxt/schema': 3.17.4 + '@nuxt/devtools': 2.6.2(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.17(typescript@5.8.3)) + '@nuxt/kit': 3.17.6(magicast@0.3.5) + '@nuxt/schema': 3.17.6 '@nuxt/telemetry': 2.6.6(magicast@0.3.5) - '@nuxt/vite-builder': 3.17.4(@types/node@22.13.8)(magicast@0.3.5)(rollup@4.41.0)(terser@5.39.0)(typescript@5.8.2)(vue-tsc@2.2.10(typescript@5.8.2))(vue@3.5.14(typescript@5.8.2))(yaml@2.7.0) - '@unhead/vue': 2.0.10(vue@3.5.14(typescript@5.8.2)) - '@vue/shared': 3.5.14 + '@nuxt/vite-builder': 3.17.6(@types/node@24.0.10)(magicast@0.3.5)(rollup@4.44.2)(terser@5.43.1)(typescript@5.8.3)(vue-tsc@3.0.1(typescript@5.8.3))(vue@3.5.17(typescript@5.8.3))(yaml@2.8.0) + '@unhead/vue': 2.0.12(vue@3.5.17(typescript@5.8.3)) + '@vue/shared': 3.5.17 c12: 3.0.4(magicast@0.3.5) chokidar: 4.0.3 compatx: 0.2.0 @@ -6535,14 +6758,13 @@ snapshots: destr: 2.0.5 devalue: 5.1.1 errx: 0.1.0 - esbuild: 0.25.4 + esbuild: 0.25.6 escape-string-regexp: 5.0.0 estree-walker: 3.0.3 - exsolve: 1.0.5 - globby: 14.1.0 + exsolve: 1.0.7 h3: 1.15.3 hookable: 5.5.3 - ignore: 7.0.4 + ignore: 7.0.5 impound: 1.0.0 jiti: 2.4.2 klona: 2.0.6 @@ -6551,37 +6773,37 @@ snapshots: mlly: 1.7.4 mocked-exports: 0.1.1 nanotar: 0.2.0 - nitropack: 2.11.12 + nitropack: 2.11.13 nypm: 0.6.0 ofetch: 1.4.1 ohash: 2.0.11 on-change: 5.0.1 - oxc-parser: 0.71.0 + oxc-parser: 0.75.1 pathe: 2.0.3 perfect-debounce: 1.0.0 - pkg-types: 2.1.0 + pkg-types: 2.2.0 radix3: 1.1.2 scule: 1.3.0 semver: 7.7.2 std-env: 3.9.0 strip-literal: 3.0.0 - tinyglobby: 0.2.13 + tinyglobby: 0.2.14 ufo: 1.6.1 ultrahtml: 1.6.0 uncrypto: 0.1.3 unctx: 2.4.1 - unimport: 5.0.1 - unplugin: 2.3.4 - unplugin-vue-router: 0.12.0(vue-router@4.5.1(vue@3.5.14(typescript@5.8.2)))(vue@3.5.14(typescript@5.8.2)) + unimport: 5.1.0 + unplugin: 2.3.5 + unplugin-vue-router: 0.14.0(@vue/compiler-sfc@3.5.17)(vue-router@4.5.1(vue@3.5.17(typescript@5.8.3)))(vue@3.5.17(typescript@5.8.3)) unstorage: 1.16.0(db0@0.3.2)(ioredis@5.6.1) untyped: 2.0.0 - vue: 3.5.14(typescript@5.8.2) + vue: 3.5.17(typescript@5.8.3) vue-bundle-renderer: 2.1.1 vue-devtools-stub: 0.1.0 - vue-router: 4.5.1(vue@3.5.14(typescript@5.8.2)) + vue-router: 4.5.1(vue@3.5.17(typescript@5.8.3)) optionalDependencies: '@parcel/watcher': 2.5.1 - '@types/node': 22.13.8 + '@types/node': 24.0.10 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -6599,6 +6821,7 @@ snapshots: - '@upstash/redis' - '@vercel/blob' - '@vercel/kv' + - '@vue/compiler-sfc' - aws4fetch - better-sqlite3 - bufferutil @@ -6640,7 +6863,7 @@ snapshots: citty: 0.1.6 consola: 3.4.2 pathe: 2.0.3 - pkg-types: 2.1.0 + pkg-types: 2.2.0 tinyexec: 0.3.2 object-inspect@1.13.4: {} @@ -6684,24 +6907,25 @@ snapshots: is-docker: 2.2.1 is-wsl: 2.2.0 - oxc-parser@0.71.0: + oxc-parser@0.75.1: dependencies: - '@oxc-project/types': 0.71.0 + '@oxc-project/types': 0.75.1 optionalDependencies: - '@oxc-parser/binding-darwin-arm64': 0.71.0 - '@oxc-parser/binding-darwin-x64': 0.71.0 - '@oxc-parser/binding-freebsd-x64': 0.71.0 - '@oxc-parser/binding-linux-arm-gnueabihf': 0.71.0 - '@oxc-parser/binding-linux-arm-musleabihf': 0.71.0 - '@oxc-parser/binding-linux-arm64-gnu': 0.71.0 - '@oxc-parser/binding-linux-arm64-musl': 0.71.0 - '@oxc-parser/binding-linux-riscv64-gnu': 0.71.0 - '@oxc-parser/binding-linux-s390x-gnu': 0.71.0 - '@oxc-parser/binding-linux-x64-gnu': 0.71.0 - '@oxc-parser/binding-linux-x64-musl': 0.71.0 - '@oxc-parser/binding-wasm32-wasi': 0.71.0 - '@oxc-parser/binding-win32-arm64-msvc': 0.71.0 - '@oxc-parser/binding-win32-x64-msvc': 0.71.0 + '@oxc-parser/binding-android-arm64': 0.75.1 + '@oxc-parser/binding-darwin-arm64': 0.75.1 + '@oxc-parser/binding-darwin-x64': 0.75.1 + '@oxc-parser/binding-freebsd-x64': 0.75.1 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.75.1 + '@oxc-parser/binding-linux-arm-musleabihf': 0.75.1 + '@oxc-parser/binding-linux-arm64-gnu': 0.75.1 + '@oxc-parser/binding-linux-arm64-musl': 0.75.1 + '@oxc-parser/binding-linux-riscv64-gnu': 0.75.1 + '@oxc-parser/binding-linux-s390x-gnu': 0.75.1 + '@oxc-parser/binding-linux-x64-gnu': 0.75.1 + '@oxc-parser/binding-linux-x64-musl': 0.75.1 + '@oxc-parser/binding-wasm32-wasi': 0.75.1 + '@oxc-parser/binding-win32-arm64-msvc': 0.75.1 + '@oxc-parser/binding-win32-x64-msvc': 0.75.1 p-event@6.0.1: dependencies: @@ -6729,20 +6953,20 @@ snapshots: parse-gitignore@2.0.0: {} - parse-json@8.1.0: + parse-json@8.3.0: dependencies: '@babel/code-frame': 7.27.1 - index-to-position: 0.1.2 - type-fest: 4.36.0 + index-to-position: 1.1.0 + type-fest: 4.41.0 - parse-path@7.0.1: + parse-path@7.1.0: dependencies: protocols: 2.0.2 parse-url@9.2.0: dependencies: - '@types/parse-path': 7.0.3 - parse-path: 7.0.1 + '@types/parse-path': 7.1.0 + parse-path: 7.1.0 parseurl@1.3.3: {} @@ -6767,7 +6991,7 @@ snapshots: pathe@2.0.3: {} - pathval@2.0.0: {} + pathval@2.0.1: {} pend@1.2.0: {} @@ -6779,12 +7003,12 @@ snapshots: picomatch@4.0.2: {} - pinia@3.0.2(typescript@5.8.2)(vue@3.5.14(typescript@5.8.2)): + pinia@3.0.3(typescript@5.8.3)(vue@3.5.17(typescript@5.8.3)): dependencies: - '@vue/devtools-api': 7.7.6 - vue: 3.5.14(typescript@5.8.2) + '@vue/devtools-api': 7.7.7 + vue: 3.5.17(typescript@5.8.3) optionalDependencies: - typescript: 5.8.2 + typescript: 5.8.3 pkg-types@1.3.1: dependencies: @@ -6792,148 +7016,148 @@ snapshots: mlly: 1.7.4 pathe: 2.0.3 - pkg-types@2.1.0: + pkg-types@2.2.0: dependencies: confbox: 0.2.2 - exsolve: 1.0.5 + exsolve: 1.0.7 pathe: 2.0.3 - postcss-calc@10.1.1(postcss@8.5.3): + postcss-calc@10.1.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-selector-parser: 7.1.0 postcss-value-parser: 4.2.0 - postcss-colormin@7.0.3(postcss@8.5.3): + postcss-colormin@7.0.3(postcss@8.5.6): dependencies: - browserslist: 4.24.5 + browserslist: 4.25.1 caniuse-api: 3.0.0 colord: 2.9.3 - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-convert-values@7.0.5(postcss@8.5.3): + postcss-convert-values@7.0.5(postcss@8.5.6): dependencies: - browserslist: 4.24.5 - postcss: 8.5.3 + browserslist: 4.25.1 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-discard-comments@7.0.4(postcss@8.5.3): + postcss-discard-comments@7.0.4(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-selector-parser: 7.1.0 - postcss-discard-duplicates@7.0.2(postcss@8.5.3): + postcss-discard-duplicates@7.0.2(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 - postcss-discard-empty@7.0.1(postcss@8.5.3): + postcss-discard-empty@7.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 - postcss-discard-overridden@7.0.1(postcss@8.5.3): + postcss-discard-overridden@7.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 - postcss-merge-longhand@7.0.5(postcss@8.5.3): + postcss-merge-longhand@7.0.5(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - stylehacks: 7.0.5(postcss@8.5.3) + stylehacks: 7.0.5(postcss@8.5.6) - postcss-merge-rules@7.0.5(postcss@8.5.3): + postcss-merge-rules@7.0.5(postcss@8.5.6): dependencies: - browserslist: 4.24.5 + browserslist: 4.25.1 caniuse-api: 3.0.0 - cssnano-utils: 5.0.1(postcss@8.5.3) - postcss: 8.5.3 + cssnano-utils: 5.0.1(postcss@8.5.6) + postcss: 8.5.6 postcss-selector-parser: 7.1.0 - postcss-minify-font-values@7.0.1(postcss@8.5.3): + postcss-minify-font-values@7.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-minify-gradients@7.0.1(postcss@8.5.3): + postcss-minify-gradients@7.0.1(postcss@8.5.6): dependencies: colord: 2.9.3 - cssnano-utils: 5.0.1(postcss@8.5.3) - postcss: 8.5.3 + cssnano-utils: 5.0.1(postcss@8.5.6) + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-minify-params@7.0.3(postcss@8.5.3): + postcss-minify-params@7.0.3(postcss@8.5.6): dependencies: - browserslist: 4.24.5 - cssnano-utils: 5.0.1(postcss@8.5.3) - postcss: 8.5.3 + browserslist: 4.25.1 + cssnano-utils: 5.0.1(postcss@8.5.6) + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-minify-selectors@7.0.5(postcss@8.5.3): + postcss-minify-selectors@7.0.5(postcss@8.5.6): dependencies: cssesc: 3.0.0 - postcss: 8.5.3 + postcss: 8.5.6 postcss-selector-parser: 7.1.0 - postcss-normalize-charset@7.0.1(postcss@8.5.3): + postcss-normalize-charset@7.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 - postcss-normalize-display-values@7.0.1(postcss@8.5.3): + postcss-normalize-display-values@7.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-normalize-positions@7.0.1(postcss@8.5.3): + postcss-normalize-positions@7.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-normalize-repeat-style@7.0.1(postcss@8.5.3): + postcss-normalize-repeat-style@7.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-normalize-string@7.0.1(postcss@8.5.3): + postcss-normalize-string@7.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-normalize-timing-functions@7.0.1(postcss@8.5.3): + postcss-normalize-timing-functions@7.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-normalize-unicode@7.0.3(postcss@8.5.3): + postcss-normalize-unicode@7.0.3(postcss@8.5.6): dependencies: - browserslist: 4.24.5 - postcss: 8.5.3 + browserslist: 4.25.1 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-normalize-url@7.0.1(postcss@8.5.3): + postcss-normalize-url@7.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-normalize-whitespace@7.0.1(postcss@8.5.3): + postcss-normalize-whitespace@7.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-ordered-values@7.0.2(postcss@8.5.3): + postcss-ordered-values@7.0.2(postcss@8.5.6): dependencies: - cssnano-utils: 5.0.1(postcss@8.5.3) - postcss: 8.5.3 + cssnano-utils: 5.0.1(postcss@8.5.6) + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-reduce-initial@7.0.3(postcss@8.5.3): + postcss-reduce-initial@7.0.3(postcss@8.5.6): dependencies: - browserslist: 4.24.5 + browserslist: 4.25.1 caniuse-api: 3.0.0 - postcss: 8.5.3 + postcss: 8.5.6 - postcss-reduce-transforms@7.0.1(postcss@8.5.3): + postcss-reduce-transforms@7.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 postcss-selector-parser@7.1.0: @@ -6941,29 +7165,29 @@ snapshots: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss-svgo@7.0.2(postcss@8.5.3): + postcss-svgo@7.0.2(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 svgo: 3.3.2 - postcss-unique-selectors@7.0.4(postcss@8.5.3): + postcss-unique-selectors@7.0.4(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-selector-parser: 7.1.0 postcss-value-parser@4.2.0: {} - postcss-values-parser@6.0.2(postcss@8.5.3): + postcss-values-parser@6.0.2(postcss@8.5.6): dependencies: color-name: 1.1.4 is-url-superb: 4.0.0 - postcss: 8.5.3 + postcss: 8.5.6 quote-unquote: 1.0.0 - postcss@8.5.3: + postcss@8.5.6: dependencies: - nanoid: 3.3.8 + nanoid: 3.3.11 picocolors: 1.1.1 source-map-js: 1.2.1 @@ -6974,16 +7198,16 @@ snapshots: detective-amd: 6.0.1 detective-cjs: 6.0.1 detective-es6: 5.0.1 - detective-postcss: 7.0.1(postcss@8.5.3) + detective-postcss: 7.0.1(postcss@8.5.6) detective-sass: 6.0.1 detective-scss: 5.0.1 detective-stylus: 5.0.1 - detective-typescript: 14.0.0(typescript@5.8.2) - detective-vue2: 2.2.0(typescript@5.8.2) + detective-typescript: 14.0.0(typescript@5.8.3) + detective-vue2: 2.2.0(typescript@5.8.3) module-definition: 6.0.1 node-source-walk: 7.0.1 - postcss: 8.5.3 - typescript: 5.8.2 + postcss: 8.5.6 + typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -7000,9 +7224,9 @@ snapshots: protocols@2.0.2: {} - pump@3.0.2: + pump@3.0.3: dependencies: - end-of-stream: 1.4.4 + end-of-stream: 1.4.5 once: 1.4.0 qs@6.14.0: @@ -7032,14 +7256,14 @@ snapshots: dependencies: find-up-simple: 1.0.1 read-pkg: 9.0.1 - type-fest: 4.36.0 + type-fest: 4.41.0 read-pkg@9.0.1: dependencies: '@types/normalize-package-data': 2.4.4 normalize-package-data: 6.0.2 - parse-json: 8.1.0 - type-fest: 4.36.0 + parse-json: 8.3.0 + type-fest: 4.41.0 unicorn-magic: 0.1.0 readable-stream@2.3.8: @@ -7102,43 +7326,39 @@ snapshots: rfdc@1.4.1: {} - rimraf@5.0.10: - dependencies: - glob: 10.4.5 - - rollup-plugin-visualizer@5.14.0(rollup@4.41.0): + rollup-plugin-visualizer@6.0.3(rollup@4.44.2): dependencies: open: 8.4.2 picomatch: 4.0.2 source-map: 0.7.4 yargs: 17.7.2 optionalDependencies: - rollup: 4.41.0 + rollup: 4.44.2 - rollup@4.41.0: + rollup@4.44.2: dependencies: - '@types/estree': 1.0.7 + '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.41.0 - '@rollup/rollup-android-arm64': 4.41.0 - '@rollup/rollup-darwin-arm64': 4.41.0 - '@rollup/rollup-darwin-x64': 4.41.0 - '@rollup/rollup-freebsd-arm64': 4.41.0 - '@rollup/rollup-freebsd-x64': 4.41.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.41.0 - '@rollup/rollup-linux-arm-musleabihf': 4.41.0 - '@rollup/rollup-linux-arm64-gnu': 4.41.0 - '@rollup/rollup-linux-arm64-musl': 4.41.0 - '@rollup/rollup-linux-loongarch64-gnu': 4.41.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.41.0 - '@rollup/rollup-linux-riscv64-gnu': 4.41.0 - '@rollup/rollup-linux-riscv64-musl': 4.41.0 - '@rollup/rollup-linux-s390x-gnu': 4.41.0 - '@rollup/rollup-linux-x64-gnu': 4.41.0 - '@rollup/rollup-linux-x64-musl': 4.41.0 - '@rollup/rollup-win32-arm64-msvc': 4.41.0 - '@rollup/rollup-win32-ia32-msvc': 4.41.0 - '@rollup/rollup-win32-x64-msvc': 4.41.0 + '@rollup/rollup-android-arm-eabi': 4.44.2 + '@rollup/rollup-android-arm64': 4.44.2 + '@rollup/rollup-darwin-arm64': 4.44.2 + '@rollup/rollup-darwin-x64': 4.44.2 + '@rollup/rollup-freebsd-arm64': 4.44.2 + '@rollup/rollup-freebsd-x64': 4.44.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.44.2 + '@rollup/rollup-linux-arm-musleabihf': 4.44.2 + '@rollup/rollup-linux-arm64-gnu': 4.44.2 + '@rollup/rollup-linux-arm64-musl': 4.44.2 + '@rollup/rollup-linux-loongarch64-gnu': 4.44.2 + '@rollup/rollup-linux-powerpc64le-gnu': 4.44.2 + '@rollup/rollup-linux-riscv64-gnu': 4.44.2 + '@rollup/rollup-linux-riscv64-musl': 4.44.2 + '@rollup/rollup-linux-s390x-gnu': 4.44.2 + '@rollup/rollup-linux-x64-gnu': 4.44.2 + '@rollup/rollup-linux-x64-musl': 4.44.2 + '@rollup/rollup-win32-arm64-msvc': 4.44.2 + '@rollup/rollup-win32-ia32-msvc': 4.44.2 + '@rollup/rollup-win32-x64-msvc': 4.44.2 fsevents: 2.3.3 run-applescript@7.0.0: {} @@ -7173,7 +7393,7 @@ snapshots: ms: 2.1.3 on-finished: 2.4.1 range-parser: 1.2.1 - statuses: 2.0.1 + statuses: 2.0.2 transitivePeerDependencies: - supports-color @@ -7202,7 +7422,7 @@ snapshots: shebang-regex@3.0.0: {} - shell-quote@1.8.2: {} + shell-quote@1.8.3: {} side-channel-list@1.0.0: dependencies: @@ -7236,7 +7456,7 @@ snapshots: signal-exit@4.1.0: {} - simple-git@3.27.0: + simple-git@3.28.0: dependencies: '@kwsites/file-exists': 1.1.1 '@kwsites/promise-deferred': 1.1.1 @@ -7250,7 +7470,7 @@ snapshots: sirv@3.0.1: dependencies: - '@polka/url': 1.0.0-next.28 + '@polka/url': 1.0.0-next.29 mrmime: 2.0.1 totalist: 3.0.1 @@ -7295,9 +7515,11 @@ snapshots: statuses@2.0.1: {} + statuses@2.0.2: {} + std-env@3.9.0: {} - streamx@2.22.0: + streamx@2.22.1: dependencies: fast-fifo: 1.3.2 text-decoder: 1.2.3 @@ -7340,10 +7562,10 @@ snapshots: structured-clone-es@1.0.0: {} - stylehacks@7.0.5(postcss@8.5.3): + stylehacks@7.0.5(postcss@8.5.6): dependencies: - browserslist: 4.24.5 - postcss: 8.5.3 + browserslist: 4.25.1 + postcss: 8.5.6 postcss-selector-parser: 7.1.0 superjson@2.2.2: @@ -7358,35 +7580,35 @@ snapshots: dependencies: '@trysound/sax': 0.2.0 commander: 7.2.0 - css-select: 5.1.0 + css-select: 5.2.2 css-tree: 2.3.1 - css-what: 6.1.0 + css-what: 6.2.2 csso: 5.0.5 picocolors: 1.1.1 system-architecture@0.1.0: {} - tapable@2.2.1: {} + tapable@2.2.2: {} tar-stream@3.1.7: dependencies: b4a: 1.6.7 fast-fifo: 1.3.2 - streamx: 2.22.0 + streamx: 2.22.1 tar@7.4.3: dependencies: '@isaacs/fs-minipass': 4.0.1 chownr: 3.0.0 minipass: 7.1.2 - minizlib: 3.0.1 + minizlib: 3.0.2 mkdirp: 3.0.1 yallist: 5.0.0 - terser@5.39.0: + terser@5.43.1: dependencies: - '@jridgewell/source-map': 0.3.6 - acorn: 8.14.1 + '@jridgewell/source-map': 0.3.10 + acorn: 8.15.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -7404,17 +7626,12 @@ snapshots: tinyexec@1.0.1: {} - tinyglobby@0.2.13: - dependencies: - fdir: 6.4.4(picomatch@4.0.2) - picomatch: 4.0.2 - tinyglobby@0.2.14: dependencies: - fdir: 6.4.4(picomatch@4.0.2) + fdir: 6.4.6(picomatch@4.0.2) picomatch: 4.0.2 - tinypool@1.1.0: {} + tinypool@1.1.1: {} tinyrainbow@2.0.0: {} @@ -7440,15 +7657,15 @@ snapshots: triple-beam@1.4.1: {} - ts-api-utils@2.1.0(typescript@5.8.2): + ts-api-utils@2.1.0(typescript@5.8.3): dependencies: - typescript: 5.8.2 + typescript: 5.8.3 tslib@2.8.1: {} - type-fest@4.36.0: {} + type-fest@4.41.0: {} - typescript@5.8.2: {} + typescript@5.8.3: {} ufo@1.6.1: {} @@ -7458,22 +7675,22 @@ snapshots: unctx@2.4.1: dependencies: - acorn: 8.14.1 + acorn: 8.15.0 estree-walker: 3.0.3 magic-string: 0.30.17 - unplugin: 2.3.4 + unplugin: 2.3.5 - undici-types@6.20.0: {} + undici-types@7.8.0: {} - unenv@2.0.0-rc.17: + unenv@2.0.0-rc.18: dependencies: defu: 6.1.4 - exsolve: 1.0.5 + exsolve: 1.0.7 ohash: 2.0.11 pathe: 2.0.3 ufo: 1.6.1 - unhead@2.0.10: + unhead@2.0.12: dependencies: hookable: 5.5.3 @@ -7481,9 +7698,9 @@ snapshots: unicorn-magic@0.3.0: {} - unimport@5.0.1: + unimport@5.1.0: dependencies: - acorn: 8.14.1 + acorn: 8.15.0 escape-string-regexp: 5.0.0 estree-walker: 3.0.3 local-pkg: 1.1.1 @@ -7491,11 +7708,11 @@ snapshots: mlly: 1.7.4 pathe: 2.0.3 picomatch: 4.0.2 - pkg-types: 2.1.0 + pkg-types: 2.2.0 scule: 1.3.0 strip-literal: 3.0.0 - tinyglobby: 0.2.13 - unplugin: 2.3.4 + tinyglobby: 0.2.14 + unplugin: 2.3.5 unplugin-utils: 0.2.4 unixify@1.0.0: @@ -7507,36 +7724,36 @@ snapshots: pathe: 2.0.3 picomatch: 4.0.2 - unplugin-vue-router@0.12.0(vue-router@4.5.1(vue@3.5.14(typescript@5.8.2)))(vue@3.5.14(typescript@5.8.2)): + unplugin-vue-router@0.14.0(@vue/compiler-sfc@3.5.17)(vue-router@4.5.1(vue@3.5.17(typescript@5.8.3)))(vue@3.5.17(typescript@5.8.3)): dependencies: - '@babel/types': 7.27.1 - '@vue-macros/common': 1.16.1(vue@3.5.14(typescript@5.8.2)) - ast-walker-scope: 0.6.2 + '@vue-macros/common': 3.0.0-beta.15(vue@3.5.17(typescript@5.8.3)) + '@vue/compiler-sfc': 3.5.17 + ast-walker-scope: 0.8.1 chokidar: 4.0.3 fast-glob: 3.3.3 json5: 2.2.3 local-pkg: 1.1.1 magic-string: 0.30.17 - micromatch: 4.0.8 mlly: 1.7.4 pathe: 2.0.3 + picomatch: 4.0.2 scule: 1.3.0 - unplugin: 2.3.4 + unplugin: 2.3.5 unplugin-utils: 0.2.4 - yaml: 2.7.0 + yaml: 2.8.0 optionalDependencies: - vue-router: 4.5.1(vue@3.5.14(typescript@5.8.2)) + vue-router: 4.5.1(vue@3.5.17(typescript@5.8.3)) transitivePeerDependencies: - vue unplugin@1.16.1: dependencies: - acorn: 8.14.1 + acorn: 8.15.0 webpack-virtual-modules: 0.6.2 - unplugin@2.3.4: + unplugin@2.3.5: dependencies: - acorn: 8.14.1 + acorn: 8.15.0 picomatch: 4.0.2 webpack-virtual-modules: 0.6.2 @@ -7577,9 +7794,9 @@ snapshots: pkg-types: 1.3.1 unplugin: 1.16.1 - update-browserslist-db@1.1.3(browserslist@4.24.5): + update-browserslist-db@1.1.3(browserslist@4.25.1): dependencies: - browserslist: 4.24.5 + browserslist: 4.25.1 escalade: 3.2.0 picocolors: 1.1.1 @@ -7598,23 +7815,23 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 - vite-dev-rpc@1.0.7(vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0)): + vite-dev-rpc@1.1.0(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0)): dependencies: - birpc: 2.3.0 - vite: 6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) - vite-hot-client: 2.0.4(vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0)) + birpc: 2.4.0 + vite: 6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0) + vite-hot-client: 2.1.0(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0)) - vite-hot-client@2.0.4(vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0)): + vite-hot-client@2.1.0(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0)): dependencies: - vite: 6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) + vite: 6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0) - vite-node@3.1.4(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0): + vite-node@3.2.4(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0): dependencies: cac: 6.7.14 debug: 4.4.1 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) + vite: 7.0.2(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0) transitivePeerDependencies: - '@types/node' - jiti @@ -7629,28 +7846,7 @@ snapshots: - tsx - yaml - vite-node@3.2.3(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0): - dependencies: - cac: 6.7.14 - debug: 4.4.1 - es-module-lexer: 1.7.0 - pathe: 2.0.3 - vite: 6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) - transitivePeerDependencies: - - '@types/node' - - jiti - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - - vite-plugin-checker@0.9.3(typescript@5.8.2)(vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))(vue-tsc@2.2.10(typescript@5.8.2)): + vite-plugin-checker@0.9.3(typescript@5.8.3)(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0))(vue-tsc@3.0.1(typescript@5.8.3)): dependencies: '@babel/code-frame': 7.27.1 chokidar: 4.0.3 @@ -7659,16 +7855,16 @@ snapshots: picomatch: 4.0.2 strip-ansi: 7.1.0 tiny-invariant: 1.3.3 - tinyglobby: 0.2.13 - vite: 6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) + tinyglobby: 0.2.14 + vite: 6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0) vscode-uri: 3.1.0 optionalDependencies: - typescript: 5.8.2 - vue-tsc: 2.2.10(typescript@5.8.2) + typescript: 5.8.3 + vue-tsc: 3.0.1(typescript@5.8.3) - vite-plugin-inspect@11.1.0(@nuxt/kit@3.17.4(magicast@0.3.5))(vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0)): + vite-plugin-inspect@11.3.0(@nuxt/kit@3.17.6(magicast@0.3.5))(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0)): dependencies: - ansis: 3.17.0 + ansis: 4.1.0 debug: 4.4.1 error-stack-parser-es: 1.0.5 ohash: 2.0.11 @@ -7676,79 +7872,83 @@ snapshots: perfect-debounce: 1.0.0 sirv: 3.0.1 unplugin-utils: 0.2.4 - vite: 6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) - vite-dev-rpc: 1.0.7(vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0)) + vite: 6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0) + vite-dev-rpc: 1.1.0(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0)) optionalDependencies: - '@nuxt/kit': 3.17.4(magicast@0.3.5) + '@nuxt/kit': 3.17.6(magicast@0.3.5) transitivePeerDependencies: - supports-color - vite-plugin-vue-tracer@0.1.3(vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))(vue@3.5.14(typescript@5.8.2)): + vite-plugin-vue-tracer@1.0.0(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.17(typescript@5.8.3)): dependencies: estree-walker: 3.0.3 - exsolve: 1.0.5 + exsolve: 1.0.7 magic-string: 0.30.17 pathe: 2.0.3 source-map-js: 1.2.1 - vite: 6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) - vue: 3.5.14(typescript@5.8.2) + vite: 6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0) + vue: 3.5.17(typescript@5.8.3) - vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0): + vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0): dependencies: - esbuild: 0.25.4 - fdir: 6.4.4(picomatch@4.0.2) + esbuild: 0.25.6 + fdir: 6.4.6(picomatch@4.0.2) picomatch: 4.0.2 - postcss: 8.5.3 - rollup: 4.41.0 - tinyglobby: 0.2.13 + postcss: 8.5.6 + rollup: 4.44.2 + tinyglobby: 0.2.14 optionalDependencies: - '@types/node': 22.13.8 + '@types/node': 24.0.10 fsevents: 2.3.3 jiti: 2.4.2 - terser: 5.39.0 - yaml: 2.7.0 + terser: 5.43.1 + yaml: 2.8.0 - vitest-environment-nuxt@1.0.1(@types/node@22.13.8)(happy-dom@17.6.3)(jiti@2.4.2)(magicast@0.3.5)(terser@5.39.0)(typescript@5.8.2)(vitest@3.2.3(@types/node@22.13.8)(happy-dom@17.6.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))(yaml@2.7.0): + vite@7.0.2(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0): dependencies: - '@nuxt/test-utils': 3.19.1(@types/node@22.13.8)(happy-dom@17.6.3)(jiti@2.4.2)(magicast@0.3.5)(terser@5.39.0)(typescript@5.8.2)(vitest@3.2.3(@types/node@22.13.8)(happy-dom@17.6.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))(yaml@2.7.0) + esbuild: 0.25.6 + fdir: 6.4.6(picomatch@4.0.2) + picomatch: 4.0.2 + postcss: 8.5.6 + rollup: 4.44.2 + tinyglobby: 0.2.14 + optionalDependencies: + '@types/node': 24.0.10 + fsevents: 2.3.3 + jiti: 2.4.2 + terser: 5.43.1 + yaml: 2.8.0 + + vitest-environment-nuxt@1.0.1(happy-dom@17.6.3)(magicast@0.3.5)(typescript@5.8.3)(vitest@3.2.4(@types/node@24.0.10)(happy-dom@17.6.3)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0)): + dependencies: + '@nuxt/test-utils': 3.19.2(happy-dom@17.6.3)(magicast@0.3.5)(typescript@5.8.3)(vitest@3.2.4(@types/node@24.0.10)(happy-dom@17.6.3)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0)) transitivePeerDependencies: - '@cucumber/cucumber' - '@jest/globals' - '@playwright/test' - '@testing-library/vue' - - '@types/node' - '@vitest/ui' - '@vue/test-utils' - happy-dom - - jiti - jsdom - - less - - lightningcss - magicast - playwright-core - - sass - - sass-embedded - - stylus - - sugarss - - terser - - tsx - typescript - vitest - - yaml - vitest@3.2.3(@types/node@22.13.8)(happy-dom@17.6.3)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0): + vitest@3.2.4(@types/node@24.0.10)(happy-dom@17.6.3)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0): dependencies: '@types/chai': 5.2.2 - '@vitest/expect': 3.2.3 - '@vitest/mocker': 3.2.3(vite@6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0)) - '@vitest/pretty-format': 3.2.3 - '@vitest/runner': 3.2.3 - '@vitest/snapshot': 3.2.3 - '@vitest/spy': 3.2.3 - '@vitest/utils': 3.2.3 + '@vitest/expect': 3.2.4 + '@vitest/mocker': 3.2.4(vite@7.0.2(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0)) + '@vitest/pretty-format': 3.2.4 + '@vitest/runner': 3.2.4 + '@vitest/snapshot': 3.2.4 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 chai: 5.2.0 debug: 4.4.1 - expect-type: 1.2.1 + expect-type: 1.2.2 magic-string: 0.30.17 pathe: 2.0.3 picomatch: 4.0.2 @@ -7756,13 +7956,13 @@ snapshots: tinybench: 2.9.0 tinyexec: 0.3.2 tinyglobby: 0.2.14 - tinypool: 1.1.0 + tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 6.3.5(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) - vite-node: 3.2.3(@types/node@22.13.8)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) + vite: 7.0.2(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0) + vite-node: 3.2.4(@types/node@24.0.10)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 22.13.8 + '@types/node': 24.0.10 happy-dom: 17.6.3 transitivePeerDependencies: - jiti @@ -7786,36 +7986,26 @@ snapshots: vue-devtools-stub@0.1.0: {} - vue-router@4.5.1(vue@3.5.14(typescript@5.8.2)): + vue-router@4.5.1(vue@3.5.17(typescript@5.8.3)): dependencies: '@vue/devtools-api': 6.6.4 - vue: 3.5.14(typescript@5.8.2) + vue: 3.5.17(typescript@5.8.3) - vue-tsc@2.2.10(typescript@5.8.2): + vue-tsc@3.0.1(typescript@5.8.3): dependencies: - '@volar/typescript': 2.4.14 - '@vue/language-core': 2.2.10(typescript@5.8.2) - typescript: 5.8.2 + '@volar/typescript': 2.4.17 + '@vue/language-core': 3.0.1(typescript@5.8.3) + typescript: 5.8.3 - vue@3.5.14(typescript@5.8.2): + vue@3.5.17(typescript@5.8.3): dependencies: - '@vue/compiler-dom': 3.5.14 - '@vue/compiler-sfc': 3.5.14 - '@vue/runtime-dom': 3.5.14 - '@vue/server-renderer': 3.5.14(vue@3.5.14(typescript@5.8.2)) - '@vue/shared': 3.5.14 + '@vue/compiler-dom': 3.5.17 + '@vue/compiler-sfc': 3.5.17 + '@vue/runtime-dom': 3.5.17 + '@vue/server-renderer': 3.5.17(vue@3.5.17(typescript@5.8.3)) + '@vue/shared': 3.5.17 optionalDependencies: - typescript: 5.8.2 - - vue@3.5.16(typescript@5.8.2): - dependencies: - '@vue/compiler-dom': 3.5.16 - '@vue/compiler-sfc': 3.5.16 - '@vue/runtime-dom': 3.5.16 - '@vue/server-renderer': 3.5.16(vue@3.5.16(typescript@5.8.2)) - '@vue/shared': 3.5.16 - optionalDependencies: - typescript: 5.8.2 + typescript: 5.8.3 web-push@3.6.7: dependencies: @@ -7894,7 +8084,7 @@ snapshots: imurmurhash: 0.1.4 signal-exit: 4.1.0 - ws@8.18.2: {} + ws@8.18.3: {} y18n@5.0.8: {} @@ -7902,7 +8092,7 @@ snapshots: yallist@5.0.0: {} - yaml@2.7.0: {} + yaml@2.8.0: {} yargs-parser@21.1.1: {} @@ -7923,17 +8113,26 @@ snapshots: yocto-queue@1.2.1: {} - youch-core@0.3.2: + youch-core@0.3.3: dependencies: - '@poppinss/exception': 1.2.1 + '@poppinss/exception': 1.2.2 error-stack-parser-es: 1.0.5 - youch@4.1.0-beta.7: + youch@4.1.0-beta.10: dependencies: - '@poppinss/dumper': 0.6.3 + '@poppinss/colors': 4.1.5 + '@poppinss/dumper': 0.6.4 '@speed-highlight/core': 1.2.7 cookie: 1.0.2 - youch-core: 0.3.2 + youch-core: 0.3.3 + + youch@4.1.0-beta.8: + dependencies: + '@poppinss/colors': 4.1.5 + '@poppinss/dumper': 0.6.4 + '@speed-highlight/core': 1.2.7 + cookie: 1.0.2 + youch-core: 0.3.3 zip-stream@6.0.1: dependencies: @@ -7941,4 +8140,4 @@ snapshots: compress-commons: 6.0.2 readable-stream: 4.7.0 - zod@3.25.30: {} + zod@3.25.75: {} From 011687b391c12df4c7066c72591995c9329a3c0c Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Tue, 8 Jul 2025 15:43:14 +0200 Subject: [PATCH 04/13] Close event streams for expired sessions When a session expires close any event streams that have been opened with that session. This prevents an attacker with a leaked session cookie from opening a stream and receiving updates indefinitely without being detected. By sending the session the event stream is opened with when the stream is established this closure on session expiry also serves as a way for a user agent to be notified whenever its own access level changes. --- composables/event-source.ts | 5 +++- docs/dev/server-sent-events.md | 13 +++++++++ server/api/admin/user.patch.ts | 4 +++ server/api/auth/account.delete.ts | 29 +++++++++++++------- server/api/auth/session.delete.ts | 3 --- server/api/auth/session.get.ts | 17 ++---------- server/api/events.ts | 4 +-- server/database.ts | 1 + server/streams.ts | 44 ++++++++++++++++++++++++------- server/utils/session.ts | 32 +++++++++++++++++++--- shared/types/api.ts | 12 +++++++++ stores/session.ts | 12 ++++++++- 12 files changed, 132 insertions(+), 44 deletions(-) create mode 100644 docs/dev/server-sent-events.md diff --git a/composables/event-source.ts b/composables/event-source.ts index 379cc07..838b879 100644 --- a/composables/event-source.ts +++ b/composables/event-source.ts @@ -22,8 +22,11 @@ class AppEventSource extends EventTarget { console.log("AppEventSource", event.type, event.data); this.dispatchEvent(new Event(event.type)); } else { - const data = event.data ? JSON.parse(event.data) : undefined; + const data = event.data ? JSON.parse(event.data) as ApiEvent : undefined; console.log("AppEventSource", event.type, data); + if (data?.type === "connected") { + this.#sourceSessionId = data.session?.id; + } this.dispatchEvent(new MessageEvent(event.type, { data, origin: event.origin, diff --git a/docs/dev/server-sent-events.md b/docs/dev/server-sent-events.md new file mode 100644 index 0000000..14c1813 --- /dev/null +++ b/docs/dev/server-sent-events.md @@ -0,0 +1,13 @@ + +# Server-sent events + +To update in real time this application sends a `text/event-source` stream using [Server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events). These streams use the current session if any to filter restricted resources and ends when the session expires, necessitating a reconnect by the user agent. (If there are no session associated with the connection it ends after the session expiry timeout). + +## Events + +Upon connecting a `"connect"` event is emitted with the session the connection was made under. This is the primary mechanism a user agent discovers its own session having been rotated into a new one, which also happens when the access level of the account associated with the session changes. + +After the `"connect"` event the user agent will start to receive updates to resources it has access to that has changed. There is no filtering for what resoucres the user agent receives updates for at the moment as there's not enough events to justify the complexity of server-side subscriptions and filtering. diff --git a/server/api/admin/user.patch.ts b/server/api/admin/user.patch.ts index bdcf099..42b08ad 100644 --- a/server/api/admin/user.patch.ts +++ b/server/api/admin/user.patch.ts @@ -64,6 +64,10 @@ export default defineEventHandler(async (event) => { for (const session of sessions) { if (session.accountId === user.id) { session.expiresAtMs = 0; + broadcastEvent({ + type: "session-expired", + sessionId: session.id, + }); } } await writeSessions(sessions); diff --git a/server/api/auth/account.delete.ts b/server/api/auth/account.delete.ts index 7506531..f75d067 100644 --- a/server/api/auth/account.delete.ts +++ b/server/api/auth/account.delete.ts @@ -12,16 +12,25 @@ export default defineEventHandler(async (event) => { const serverSession = await requireServerSessionWithUser(event); let users = await readUsers(); - // Remove sessions for this user - const removedSessionIds = new Set(); + // Expire sessions for this user + const expiredSessionIds = new Set(); let sessions = await readSessions(); - sessions = sessions.filter(session => { - if (session.accountId === serverSession.accountId) { - removedSessionIds.add(session.id); - return false; + const nowMs = Date.now(); + for (const session of sessions) { + if ( + !session.finished + && session.successor !== undefined + && session.expiresAtMs < nowMs + && session.accountId === serverSession.accountId + ) { + session.expiresAtMs = nowMs; + broadcastEvent({ + type: "session-expired", + sessionId: session.id, + }); + expiredSessionIds.add(session.id); } - return true; - }); + } cancelAccountStreams(serverSession.accountId); await writeSessions(sessions); await deleteCookie(event, "session"); @@ -29,13 +38,13 @@ export default defineEventHandler(async (event) => { // Remove subscriptions for this user let subscriptions = await readSubscriptions(); subscriptions = subscriptions.filter( - subscription => !removedSessionIds.has(subscription.sessionId) + subscription => !expiredSessionIds.has(subscription.sessionId) ); await writeSubscriptions(subscriptions); // Remove the user const account = users.find(user => user.id === serverSession.accountId)!; - const now = new Date().toISOString(); + const now = new Date(nowMs).toISOString(); account.deleted = true; account.updatedAt = now; await writeUsers(users); diff --git a/server/api/auth/session.delete.ts b/server/api/auth/session.delete.ts index ca24eaf..df4bfd9 100644 --- a/server/api/auth/session.delete.ts +++ b/server/api/auth/session.delete.ts @@ -18,8 +18,5 @@ export default defineEventHandler(async (event) => { } } - if (session) { - cancelSessionStreams(session.id); - } await clearServerSession(event); }) diff --git a/server/api/auth/session.get.ts b/server/api/auth/session.get.ts index f63f355..9ad7a5e 100644 --- a/server/api/auth/session.get.ts +++ b/server/api/auth/session.get.ts @@ -2,23 +2,10 @@ SPDX-FileCopyrightText: © 2025 Hornwitser SPDX-License-Identifier: AGPL-3.0-or-later */ -import { readSubscriptions, readUsers } from "~/server/database"; -import type { ApiSession } from "~/shared/types/api"; - -export default defineEventHandler(async (event): Promise => { +export default defineEventHandler(async event => { const session = await getServerSession(event, false); if (!session) return; - const users = await readUsers(); - const account = users.find(user => user.id === session.accountId); - const subscriptions = await readSubscriptions(); - const push = Boolean( - subscriptions.find(sub => sub.type === "push" && sub.sessionId === session.id) - ); - return { - id: session.id, - account, - push, - }; + return await serverSessionToApi(event, session); }) diff --git a/server/api/events.ts b/server/api/events.ts index 140c52e..12e1f3b 100644 --- a/server/api/events.ts +++ b/server/api/events.ts @@ -24,8 +24,8 @@ export default defineEventHandler(async (event) => { console.log(`cancelled event stream for ${source}`); deleteStream(stream.writable); } - }) - addStream(stream.writable, session?.id, session?.accountId); + }); + addStream(event, stream.writable, session); // Workaround to properly handle stream errors. See https://github.com/unjs/h3/issues/986 setHeader(event, "Access-Control-Allow-Origin", "*"); diff --git a/server/database.ts b/server/database.ts index b369e24..24e30a5 100644 --- a/server/database.ts +++ b/server/database.ts @@ -13,6 +13,7 @@ export interface ServerSession { expiresAtMs: number, discardAtMs: number, successor?: Id, + finished: boolean, }; export interface ServerUser { diff --git a/server/streams.ts b/server/streams.ts index a231e85..7298d73 100644 --- a/server/streams.ts +++ b/server/streams.ts @@ -2,8 +2,10 @@ SPDX-FileCopyrightText: © 2025 Hornwitser SPDX-License-Identifier: AGPL-3.0-or-later */ -import { readUsers } from "~/server/database"; +import { readUsers, ServerSession } from "~/server/database"; import type { ApiAccount, ApiEvent } from "~/shared/types/api"; +import { serverSessionToApi } from "./utils/session"; +import { H3Event } from "h3"; function sendMessage( stream: WritableStream, @@ -31,18 +33,30 @@ function sendMessageAndClose( ; } -const streams = new Map, { sessionId?: number, accountId?: number }>(); +const streams = new Map, { sessionId?: number, accountId?: number, expiresAtMs: number }>(); let keepaliveInterval: ReturnType | null = null -export function addStream(stream: WritableStream, sessionId?: number, accountId?: number) { +export async function addStream( + event: H3Event, + stream: WritableStream, + session?: ServerSession, +) { if (streams.size === 0) { console.log("Starting keepalive") keepaliveInterval = setInterval(sendKeepalive, 4000) } - streams.set(stream, { sessionId, accountId }); - // Produce a response immediately to avoid the reply waiting for content. - const message = `data: connected sid:${sessionId ?? '-'} aid:${accountId ?? '-'}\n\n`; - sendMessage(stream, message); + const runtimeConfig = useRuntimeConfig(event); + streams.set(stream, { + sessionId: session?.id, + accountId: session?.accountId, + expiresAtMs: session?.expiresAtMs ?? Date.now() + runtimeConfig.sessionExpiresTimeout * 1000, + }); + // Produce a response immediately to avoid the reply waiting for content. + const update: ApiEvent = { + type: "connected", + session: session ? await serverSessionToApi(event, session) : undefined, + }; + sendMessage(stream, `event: update\ndata: ${JSON.stringify(update)}\n\n`); } export function deleteStream(stream: WritableStream) { streams.delete(stream); @@ -119,6 +133,13 @@ export async function broadcastEvent(event: ApiEvent) { if (!streams.size) { return; } + + // Session expiry events cause the streams belonging to that session to be terminated + if (event.type === "session-expired") { + cancelSessionStreams(event.sessionId); + return; + } + const users = await readUsers(); for (const [stream, streamData] of streams) { // Account events are specially handled and only sent to the user they belong to. @@ -139,7 +160,12 @@ export async function broadcastEvent(event: ApiEvent) { } function sendKeepalive() { - for (const stream of streams.keys()) { - sendMessage(stream, ": keepalive\n"); + const now = Date.now(); + for (const [stream, streamData] of streams) { + if (streamData.expiresAtMs > now) { + sendMessage(stream, ": keepalive\n"); + } else { + sendMessageAndClose(stream, `data: cancelled\n\n`); + } } } diff --git a/server/utils/session.ts b/server/utils/session.ts index c33d3c7..db819e4 100644 --- a/server/utils/session.ts +++ b/server/utils/session.ts @@ -13,6 +13,8 @@ import { writeSessions, writeSubscriptions } from "~/server/database"; +import { broadcastEvent } from "../streams"; +import type { ApiSession } from "~/shared/types/api"; async function removeSessionSubscription(sessionId: number) { const subscriptions = await readSubscriptions(); @@ -27,9 +29,13 @@ async function clearServerSessionInternal(event: H3Event, sessions: ServerSessio const existingSessionCookie = await getSignedCookie(event, "session"); if (existingSessionCookie) { const sessionId = parseInt(existingSessionCookie, 10); - const sessionIndex = sessions.findIndex(session => session.id === sessionId); - if (sessionIndex !== -1) { - sessions.splice(sessionIndex, 1); + const session = sessions.find(session => session.id === sessionId); + if (session) { + session.finished = true; + broadcastEvent({ + type: "session-expired", + sessionId, + }); await removeSessionSubscription(sessionId); return true; } @@ -56,6 +62,7 @@ export async function setServerSession(event: H3Event, account: ServerUser) { access: account.type, expiresAtMs: now + runtimeConfig.sessionExpiresTimeout * 1000, discardAtMs: now + runtimeConfig.sessionDiscardTimeout * 1000, + finished: false, id: await nextSessionId(), }; @@ -74,6 +81,7 @@ async function rotateSession(event: H3Event, sessions: ServerSession[], session: access: account?.type ?? "anonymous", expiresAtMs: now + runtimeConfig.sessionExpiresTimeout * 1000, discardAtMs: now + runtimeConfig.sessionDiscardTimeout * 1000, + finished: false, id: await nextSessionId(), }; session.successor = newSession.id; @@ -90,6 +98,9 @@ export async function getServerSession(event: H3Event, ignoreExpired: boolean) { const sessions = await readSessions(); const session = sessions.find(session => session.id === sessionId); if (session) { + if (session.finished) { + return undefined; + } if (!ignoreExpired && session.successor !== undefined) { throw createError({ statusCode: 403, @@ -149,3 +160,18 @@ export async function requireServerSessionWithAdmin(event: H3Event) { } return { ...session, accountId: session.accountId }; } + +export async function serverSessionToApi(event: H3Event, session: ServerSession): Promise { + const users = await readUsers(); + const account = users.find(user => user.id === session.accountId); + const subscriptions = await readSubscriptions(); + const push = Boolean( + subscriptions.find(sub => sub.type === "push" && sub.sessionId === session.id) + ); + + return { + id: session.id, + account, + push, + }; +} diff --git a/shared/types/api.ts b/shared/types/api.ts index 321ea3c..3f2d421 100644 --- a/shared/types/api.ts +++ b/shared/types/api.ts @@ -149,12 +149,22 @@ export interface ApiAccountUpdate { data: ApiAccount, } +export interface ApiConnected { + type: "connected", + session?: ApiSession, +} + export interface ApiScheduleUpdate { type: "schedule-update", updatedFrom?: string, data: ApiSchedule | ApiTombstone, } +export interface ApiSessionExpired { + type: "session-expired", + sessionId: Id, +} + export interface ApiUserUpdate { type: "user-update", updatedFrom?: string, @@ -163,6 +173,8 @@ export interface ApiUserUpdate { export type ApiEvent = | ApiAccountUpdate + | ApiConnected | ApiScheduleUpdate + | ApiSessionExpired | ApiUserUpdate ; diff --git a/stores/session.ts b/stores/session.ts index 48f5fda..2545c4f 100644 --- a/stores/session.ts +++ b/stores/session.ts @@ -4,7 +4,7 @@ */ import { appendResponseHeader } from "h3"; import type { H3Event } from "h3"; -import type { ApiAccount } from "~/shared/types/api"; +import type { ApiAccount, ApiSession } from "~/shared/types/api"; const fetchSessionWithCookie = async (event?: H3Event) => { // Client side @@ -33,6 +33,9 @@ export const useSessionStore = defineStore("session", () => { const actions = { async fetch(event?: H3Event) { const session = await fetchSessionWithCookie(event) + actions.update(session); + }, + update(session?: ApiSession) { state.account.value = session?.account; state.id.value = session?.id; state.push.value = session?.push ?? false; @@ -58,6 +61,13 @@ export const useSessionStore = defineStore("session", () => { }, }; + appEventSource?.addEventListener("update", (event) => { + if (event.data.type !== "connected") { + return; + } + actions.update(event.data.session); + }); + return { ...state, ...actions, From ebeedff5d016646ab2e1a69c1e21d32cfa0564dd Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Tue, 8 Jul 2025 15:51:50 +0200 Subject: [PATCH 05/13] Add error page for when a session has been taken Describe to the user what it means when a session has been detected as taken and provide a means to abandoned the session and log in again. --- error.vue | 57 ++++++++++++++++++++++++++++++++++------- server/utils/session.ts | 1 + 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/error.vue b/error.vue index fafbcd1..68d0f9d 100644 --- a/error.vue +++ b/error.vue @@ -3,26 +3,65 @@ SPDX-License-Identifier: AGPL-3.0-or-later --> diff --git a/server/utils/session.ts b/server/utils/session.ts index db819e4..194e5c2 100644 --- a/server/utils/session.ts +++ b/server/utils/session.ts @@ -106,6 +106,7 @@ export async function getServerSession(event: H3Event, ignoreExpired: boolean) { statusCode: 403, statusMessage: "Forbidden", message: "Session has been taken by another agent.", + data: { code: "SESSION_TAKEN" }, }); } const now = Date.now(); From f4e4dc9f1143e1e5a29f69ad6de63ac9c3d3c95b Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Tue, 8 Jul 2025 15:53:58 +0200 Subject: [PATCH 06/13] Allow abandoning anonymous taken sessions If an anonymous session is detected as taken the logic preventing the session from being accidentally deleted would also prevent the user from recovering from a taken anonymous session. --- server/api/auth/session.delete.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/api/auth/session.delete.ts b/server/api/auth/session.delete.ts index df4bfd9..4cbfa47 100644 --- a/server/api/auth/session.delete.ts +++ b/server/api/auth/session.delete.ts @@ -10,7 +10,7 @@ export default defineEventHandler(async (event) => { if (session) { const users = await readUsers(); const account = users.find(user => user.id === session.accountId); - if (account?.type === "anonymous") { + if (account?.type === "anonymous" && session.successor === undefined) { throw createError({ status: 409, message: "Cannot log out of an anonymous account", From 352362b9c34a4fcac5a9fb7bca4d2d6e27eaf239 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Tue, 8 Jul 2025 16:23:31 +0200 Subject: [PATCH 07/13] Ignore deleted users when looking up a user After the change to converting users to tombstones instead of removing them from the database several places would accidentally use deleted user accounts instead of ignoring them. --- server/streams.ts | 2 +- server/utils/session.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/server/streams.ts b/server/streams.ts index 7298d73..0f7709f 100644 --- a/server/streams.ts +++ b/server/streams.ts @@ -151,7 +151,7 @@ export async function broadcastEvent(event: ApiEvent) { } else { let userType: ApiAccount["type"] | undefined; if (streamData.accountId !== undefined) { - userType = users.find(a => a.id === streamData.accountId)?.type + userType = users.find(a => !a.deleted && a.id === streamData.accountId)?.type } const data = encodeEvent(event, userType) sendMessage(stream, `id: ${id}\nevent: update\ndata: ${data}\n\n`); diff --git a/server/utils/session.ts b/server/utils/session.ts index 194e5c2..0aeeebe 100644 --- a/server/utils/session.ts +++ b/server/utils/session.ts @@ -74,7 +74,7 @@ export async function setServerSession(event: H3Event, account: ServerUser) { async function rotateSession(event: H3Event, sessions: ServerSession[], session: ServerSession) { const runtimeConfig = useRuntimeConfig(event); const users = await readUsers(); - const account = users.find(user => user.id === session.accountId); + const account = users.find(user => !user.deleted && user.id === session.accountId); const now = Date.now(); const newSession: ServerSession = { accountId: account?.id, @@ -137,7 +137,7 @@ export async function requireServerSessionWithUser(event: H3Event) { const session = await requireServerSession(event, message); const users = await readUsers(); const account = users.find(user => user.id === session.accountId); - if (session.accountId === undefined || !account) + if (session.accountId === undefined || !account || account.deleted) throw createError({ statusCode: 401, statusMessage: "Uauthorized", @@ -164,7 +164,7 @@ export async function requireServerSessionWithAdmin(event: H3Event) { export async function serverSessionToApi(event: H3Event, session: ServerSession): Promise { const users = await readUsers(); - const account = users.find(user => user.id === session.accountId); + const account = users.find(user => !user.deleted && user.id === session.accountId); const subscriptions = await readSubscriptions(); const push = Boolean( subscriptions.find(sub => sub.type === "push" && sub.sessionId === session.id) From 3f492edea20c704aa4a01a193afc11e6a9adf1e5 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Wed, 9 Jul 2025 14:54:54 +0200 Subject: [PATCH 08/13] Separate rotation and expiry of sessions If a session is rotate in the middle of a server side rendering then some random portions of requests made on the server side will fail with a session taken error as the server is not going to update the cookies of the client during these requests. To avoid this pitfall extend the expiry time of sessions to be 10 seconds after the session has been rotated. This is accomplished by introducing a new timestamp on sessions called the rotateAt at time alongside the expiresAt time. Sessions used after rotateAt that haven't been rotated get rotated into a new session and the existing session gets the expiresAt time set to 10 seconds in the future. Sessions that are past the expiredAt time have no access. This makes the logic around session expiry simpler, and also makes it possible to audit when a session got rotated, and to mark sessions as expired without a chance to rotate to a new session without having to resort to a finished flag. --- docs/admin/config.md | 6 ++--- docs/dev/server-sent-events.md | 2 +- docs/dev/sessions.md | 4 ++-- nuxt.config.ts | 2 +- server/api/admin/user.patch.ts | 5 ++-- server/api/auth/account.delete.ts | 5 ++-- server/api/auth/session.delete.ts | 2 +- server/database.ts | 4 ++-- server/streams.ts | 6 ++--- server/utils/session.ts | 39 +++++++++++++++---------------- 10 files changed, 37 insertions(+), 38 deletions(-) diff --git a/docs/admin/config.md b/docs/admin/config.md index 1dbc6c8..8e61c75 100644 --- a/docs/admin/config.md +++ b/docs/admin/config.md @@ -6,12 +6,12 @@ ## Environment Variables -### NUXT_SESSION_EXPIRES_TIMEOUT +### NUXT_SESSION_ROTATES_TIMEOUT -Time in seconds before a session is considered expired and need to be rotated over into a new session. When an endpoint using a session is hit after the session expires but before the session is discarded a new session is created as the successor with a new expiry and discard timeout. The old session then considered to have been superceeded and any requests using the old session will result in a 403 Forbidden with the message the session has been taken. +Time in seconds before a session need to be rotated over into a new session. When an endpoint using a session is hit after the session rotates timeout but before the session is discarded a new session is created as the successor with a new rotates and discard timeout. The old session then marked to expire in 10 seconds any requests using the old session will result in a 403 Forbidden with the message the session has been taken after the expiry. ### NUXT_SESSION_DISCARD_TIMEOUT Time in seconds before a session is deleted from the client and server, resulting in the user having to authenticate again if the session wasn't rotated over into a new session before this timeout. -This should be several times greater that `NUXT_SESSION_EXPIRES_TIMEOUT`. +This should be several times greater that `NUXT_SESSION_ROTATES_TIMEOUT`. diff --git a/docs/dev/server-sent-events.md b/docs/dev/server-sent-events.md index 14c1813..82ff99b 100644 --- a/docs/dev/server-sent-events.md +++ b/docs/dev/server-sent-events.md @@ -4,7 +4,7 @@ --> # Server-sent events -To update in real time this application sends a `text/event-source` stream using [Server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events). These streams use the current session if any to filter restricted resources and ends when the session expires, necessitating a reconnect by the user agent. (If there are no session associated with the connection it ends after the session expiry timeout). +To update in real time this application sends a `text/event-source` stream using [Server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events). These streams use the current session if any to filter restricted resources and ends when the session rotates timeout is hit, necessitating a reconnect by the user agent. (If there are no session associated with the connection it ends after the session rotates timeout). ## Events diff --git a/docs/dev/sessions.md b/docs/dev/sessions.md index 6ae7967..ccf5eb9 100644 --- a/docs/dev/sessions.md +++ b/docs/dev/sessions.md @@ -6,8 +6,8 @@ When a user creates a new account or logs in to an existing account a session is created on the server and linked to the user's browser via a session cookie. This cookie contains a unique identifier along with a HMAC signature created using the server's cookie secret key. Since this unique identifier stored on the user's device is a technical requirement to securely do what the user is requesting the user's consent to its storage can be assumed. -Sessions have two future times associated with them: The expiration time is the point in time after the session will be recreated and the cookie reassigned, and the discard time is when the session is deleted from both the client and the server. The expiriation time is short, by default 1 hour, while the discard time is long, by default 2 weeks. +Sessions have three future times associated with them: The rotates time is the point in time after the session will be recreated and the cookie reassigned, the expiry time is the point in time after which use of the session will be rejected, and the discard time is when the session is deleted from both the client and the server. The rotation time is short, by default 1 hour, while the discard time is long, by default 2 weeks. -When a request is made to a session that's past the expiration time a new session is created to replace the existing one, and the session cookie is updated with the new session. The purpose of this is to reduce the time window a stolen session can be used in without being detected. If a request is made using a session that has already been replaced the server responds with a message saying the "session has been taken". +When a request is made to a session that's past the rotates time a new session is created to replace the existing one, the expiry time is set on the existing session to 10 seconds later, and the session cookie is updated with the new session. The purpose of this is to reduce the time window a stolen session can be used in without being detected. If a request is made using a session that has expired the server responds with a message saying the "session has been taken". The reason for having the session expire 10 seconds after the rotation is to prevent race conditions from triggering the session taken error. Sessions are created for a limited timespan, purpose and access level, and expires after the timespan is over, the purpose is fulfilled or the access level changes. For example if the user's account is promoted from regular to crew the session will no longer be valid and will be recreated as a new session with the new access level on the next request. diff --git a/nuxt.config.ts b/nuxt.config.ts index 71b5233..6ff336a 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -23,7 +23,7 @@ export default defineNuxtConfig({ }, runtimeConfig: { cookieSecretKeyFile: "", - sessionExpiresTimeout: 1 * oneHourSeconds, + sessionRotatesTimeout: 1 * oneHourSeconds, sessionDiscardTimeout: 14 * oneDaySeconds, vapidSubject: "", vapidPrivateKeyFile: "", diff --git a/server/api/admin/user.patch.ts b/server/api/admin/user.patch.ts index 42b08ad..25c559f 100644 --- a/server/api/admin/user.patch.ts +++ b/server/api/admin/user.patch.ts @@ -58,12 +58,13 @@ export default defineEventHandler(async (event) => { data: serverUserToApi(user), }); - // Expire sessions with the user in it if the access changed + // Rotate sessions with the user in it if the access changed if (accessChanged) { const sessions = await readSessions(); + const nowMs = Date.now(); for (const session of sessions) { if (session.accountId === user.id) { - session.expiresAtMs = 0; + session.rotatesAtMs = nowMs; broadcastEvent({ type: "session-expired", sessionId: session.id, diff --git a/server/api/auth/account.delete.ts b/server/api/auth/account.delete.ts index f75d067..2e66d14 100644 --- a/server/api/auth/account.delete.ts +++ b/server/api/auth/account.delete.ts @@ -18,9 +18,8 @@ export default defineEventHandler(async (event) => { const nowMs = Date.now(); for (const session of sessions) { if ( - !session.finished - && session.successor !== undefined - && session.expiresAtMs < nowMs + session.successor !== undefined + && (session.expiresAtMs === undefined || session.expiresAtMs < nowMs) && session.accountId === serverSession.accountId ) { session.expiresAtMs = nowMs; diff --git a/server/api/auth/session.delete.ts b/server/api/auth/session.delete.ts index 4cbfa47..df4bfd9 100644 --- a/server/api/auth/session.delete.ts +++ b/server/api/auth/session.delete.ts @@ -10,7 +10,7 @@ export default defineEventHandler(async (event) => { if (session) { const users = await readUsers(); const account = users.find(user => user.id === session.accountId); - if (account?.type === "anonymous" && session.successor === undefined) { + if (account?.type === "anonymous") { throw createError({ status: 409, message: "Cannot log out of an anonymous account", diff --git a/server/database.ts b/server/database.ts index 24e30a5..e3b5c0b 100644 --- a/server/database.ts +++ b/server/database.ts @@ -10,10 +10,10 @@ export interface ServerSession { id: Id, access: ApiUserType, accountId?: number, - expiresAtMs: number, + rotatesAtMs: number, + expiresAtMs?: number, discardAtMs: number, successor?: Id, - finished: boolean, }; export interface ServerUser { diff --git a/server/streams.ts b/server/streams.ts index 0f7709f..6daf522 100644 --- a/server/streams.ts +++ b/server/streams.ts @@ -33,7 +33,7 @@ function sendMessageAndClose( ; } -const streams = new Map, { sessionId?: number, accountId?: number, expiresAtMs: number }>(); +const streams = new Map, { sessionId?: number, accountId?: number, rotatesAtMs: number }>(); let keepaliveInterval: ReturnType | null = null export async function addStream( @@ -49,7 +49,7 @@ export async function addStream( streams.set(stream, { sessionId: session?.id, accountId: session?.accountId, - expiresAtMs: session?.expiresAtMs ?? Date.now() + runtimeConfig.sessionExpiresTimeout * 1000, + rotatesAtMs: session?.rotatesAtMs ?? Date.now() + runtimeConfig.sessionRotatesTimeout * 1000, }); // Produce a response immediately to avoid the reply waiting for content. const update: ApiEvent = { @@ -162,7 +162,7 @@ export async function broadcastEvent(event: ApiEvent) { function sendKeepalive() { const now = Date.now(); for (const [stream, streamData] of streams) { - if (streamData.expiresAtMs > now) { + if (streamData.rotatesAtMs > now) { sendMessage(stream, ": keepalive\n"); } else { sendMessageAndClose(stream, `data: cancelled\n\n`); diff --git a/server/utils/session.ts b/server/utils/session.ts index 0aeeebe..f89a6b6 100644 --- a/server/utils/session.ts +++ b/server/utils/session.ts @@ -31,7 +31,7 @@ async function clearServerSessionInternal(event: H3Event, sessions: ServerSessio const sessionId = parseInt(existingSessionCookie, 10); const session = sessions.find(session => session.id === sessionId); if (session) { - session.finished = true; + session.expiresAtMs = Date.now(); broadcastEvent({ type: "session-expired", sessionId, @@ -58,11 +58,10 @@ export async function setServerSession(event: H3Event, account: ServerUser) { const now = Date.now(); const newSession: ServerSession = { - accountId: account.id, - access: account.type, - expiresAtMs: now + runtimeConfig.sessionExpiresTimeout * 1000, + access: account?.type ?? "anonymous", + accountId: account?.id, + rotatesAtMs: now + runtimeConfig.sessionRotatesTimeout * 1000, discardAtMs: now + runtimeConfig.sessionDiscardTimeout * 1000, - finished: false, id: await nextSessionId(), }; @@ -79,41 +78,41 @@ async function rotateSession(event: H3Event, sessions: ServerSession[], session: const newSession: ServerSession = { accountId: account?.id, access: account?.type ?? "anonymous", - expiresAtMs: now + runtimeConfig.sessionExpiresTimeout * 1000, + rotatesAtMs: now + runtimeConfig.sessionRotatesTimeout * 1000, discardAtMs: now + runtimeConfig.sessionDiscardTimeout * 1000, - finished: false, id: await nextSessionId(), }; session.successor = newSession.id; + session.expiresAtMs = Date.now() + 10 * 1000; sessions.push(newSession); await writeSessions(sessions); await setSignedCookie(event, "session", String(newSession.id), runtimeConfig.sessionDiscardTimeout) return newSession; } -export async function getServerSession(event: H3Event, ignoreExpired: boolean) { +export async function getServerSession(event: H3Event, ignoreTaken: boolean) { const sessionCookie = await getSignedCookie(event, "session"); if (sessionCookie) { const sessionId = parseInt(sessionCookie, 10); const sessions = await readSessions(); const session = sessions.find(session => session.id === sessionId); if (session) { - if (session.finished) { + const nowMs = Date.now(); + if (nowMs >= session.discardAtMs) { return undefined; } - if (!ignoreExpired && session.successor !== undefined) { - throw createError({ - statusCode: 403, - statusMessage: "Forbidden", - message: "Session has been taken by another agent.", - data: { code: "SESSION_TAKEN" }, - }); - } - const now = Date.now(); - if (now >= session?.discardAtMs) { + if (session.expiresAtMs !== undefined && nowMs >= session.expiresAtMs) { + if (!ignoreTaken && session.successor !== undefined) { + throw createError({ + statusCode: 403, + statusMessage: "Forbidden", + message: "Session has been taken by another agent.", + data: { code: "SESSION_TAKEN" }, + }); + } return undefined; } - if (!ignoreExpired && now >= session?.expiresAtMs) { + if (nowMs >= session.rotatesAtMs && session.successor === undefined) { return await rotateSession(event, sessions, session); } } From 2d6bcebc5a98e947450be734cc7b0f28fde2bfc9 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Wed, 9 Jul 2025 14:59:19 +0200 Subject: [PATCH 09/13] Add note about quoting in configuration guide The way Nuxt handles environment variables is weird. Document this to help others from not falling into its pitfalls. --- docs/admin/config.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/admin/config.md b/docs/admin/config.md index 8e61c75..e273f7d 100644 --- a/docs/admin/config.md +++ b/docs/admin/config.md @@ -4,6 +4,10 @@ --> # Configuration +## Quoting + +Environment variables are parsed using [destr](https://github.com/unjs/destr) which contain arbitrary unspecified and undocumented rules for converting strings to data. If an environment input looks like JSON it'll most likely be parsed as JSON and my cause a type missmatch error to be reported. To avoid strings being converted into other unintended values put the value into `"` marks. Depending on your configuration environment you may have to double up the quotation marks and/or use escapes. + ## Environment Variables ### NUXT_SESSION_ROTATES_TIMEOUT From aaa2faffb16e3357373d38932f9f6ffb0aff5b3b Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Wed, 9 Jul 2025 15:21:39 +0200 Subject: [PATCH 10/13] Implement register and login with Telegram Add the concept of authentication methods that authenticate an account where using the telegram login widget is one such method. If a login is done with an authentication method that's not associated with any account the session ends up with the data from the authentication method in order to allow registering a new account with the authentication method. This has to be stored on the session as otherwise it wouldn't be possible to implement authentication methods such as OAuth2 that takes the user to a third-party site and then redirects the browser back. --- components/Header.vue | 1 + components/LogInTelegram.vue | 61 +++++++++++++ docs/admin/authentication.md | 15 ++++ docs/admin/config.md | 18 ++++ nuxt.config.ts | 3 + pages/login.vue | 3 + pages/register.vue | 57 ++++++++++++ server/api/auth/account.post.ts | 39 +++++++-- server/api/auth/ap/telegram-login.post.ts | 100 ++++++++++++++++++++++ server/database.ts | 27 ++++++ server/utils/session.ts | 15 +++- shared/types/api.ts | 2 + shared/types/telegram.ts | 20 +++++ stores/session.ts | 4 + 14 files changed, 357 insertions(+), 8 deletions(-) create mode 100644 components/LogInTelegram.vue create mode 100644 docs/admin/authentication.md create mode 100644 pages/register.vue create mode 100644 server/api/auth/ap/telegram-login.post.ts create mode 100644 shared/types/telegram.ts diff --git a/components/Header.vue b/components/Header.vue index 0d9e95d..fd79684 100644 --- a/components/Header.vue +++ b/components/Header.vue @@ -33,6 +33,7 @@ diff --git a/components/LogInTelegram.vue b/components/LogInTelegram.vue new file mode 100644 index 0000000..d56fa98 --- /dev/null +++ b/components/LogInTelegram.vue @@ -0,0 +1,61 @@ + + + + diff --git a/docs/admin/authentication.md b/docs/admin/authentication.md new file mode 100644 index 0000000..a1fbc3e --- /dev/null +++ b/docs/admin/authentication.md @@ -0,0 +1,15 @@ + +# Authentication + +It's possible to configure authentication using a third party Authentication Provider (referred to as AP). Currently only Telegram is supported as an AP. + +## Telegram + +In order to use Telegram as an AP you need to be hosting Owltide under a domain name over https, using http will not work. + +You will also need a bot which can be created by messaging [@BotFather](https://t.me/BotFather), with the domain of the bot set using the `/setdomain` command to the domain Owltide is hosted under. + +Once you have the pre-requisites you need to configure `NUXT_TELEGRAM_BOT_TOKEN_FILE` to a path to a file containing the token of the bot with no spaces or new-lines. `NUXT_PUBLIC_TELEGRAM_BOT_USERNAME` to the username of the bot. And finally `NUXT_AUTH_TELEGRAM_ENABLED` to `true` to enable authentication via Telegram. diff --git a/docs/admin/config.md b/docs/admin/config.md index e273f7d..b95e08d 100644 --- a/docs/admin/config.md +++ b/docs/admin/config.md @@ -19,3 +19,21 @@ Time in seconds before a session need to be rotated over into a new session. Whe Time in seconds before a session is deleted from the client and server, resulting in the user having to authenticate again if the session wasn't rotated over into a new session before this timeout. This should be several times greater that `NUXT_SESSION_ROTATES_TIMEOUT`. + +### NUXT_TELEGRAM_BOT_TOKEN_FILE + +Path to a file containing the token for the Telegram bot used for authenticating users via Telegram. + +Does nothing if `NUXT_AUTH_TELEGRAM_ENABLED` is not enabled. + +### NUXT_PUBLIC_TELEGRAM_BOT_USERNAME + +Username of the Telegram bot used for authenticating users via Telegram. + +Does nothing if `NUXT_AUTH_TELEGRAM_ENABLED` is not enabled. + +### NUXT_AUTH_TELEGRAM_ENABLED + +Boolean indicating if authentication via Telegram is enabled or not. Requires `NUXT_PUBLIC_TELEGRAM_BOT_USERNAME` and `NUXT_TELEGRAM_BOT_TOKEN_FILE` to be set in order to work. + +Defaults to `false`. diff --git a/nuxt.config.ts b/nuxt.config.ts index 6ff336a..b970358 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -27,9 +27,12 @@ export default defineNuxtConfig({ sessionDiscardTimeout: 14 * oneDaySeconds, vapidSubject: "", vapidPrivateKeyFile: "", + telegramBotTokenFile: "", public: { defaultTimezone: "Europe/Oslo", defaultLocale: "en-GB", + authTelegramEnabled: false, + telegramBotUsername: "", vapidPublicKey: "", } }, diff --git a/pages/login.vue b/pages/login.vue index cdb04b8..01b233f 100644 --- a/pages/login.vue +++ b/pages/login.vue @@ -9,6 +9,7 @@ +

Create Account

If you don't have an account you may create one

@@ -38,6 +39,8 @@ useHead({ title: "Login", }); +const runtimeConfig = useRuntimeConfig(); +const authTelegramEnabled = runtimeConfig.public.authTelegramEnabled; const sessionStore = useSessionStore(); const { getSubscription, subscribe } = usePushNotification(); diff --git a/pages/register.vue b/pages/register.vue new file mode 100644 index 0000000..f9de244 --- /dev/null +++ b/pages/register.vue @@ -0,0 +1,57 @@ + + + + diff --git a/server/api/auth/account.post.ts b/server/api/auth/account.post.ts index 527215c..2fcbc71 100644 --- a/server/api/auth/account.post.ts +++ b/server/api/auth/account.post.ts @@ -2,20 +2,21 @@ SPDX-FileCopyrightText: © 2025 Hornwitser SPDX-License-Identifier: AGPL-3.0-or-later */ -import { readUsers, writeUsers, nextUserId, type ServerUser } from "~/server/database"; +import { readUsers, writeUsers, nextUserId, type ServerUser, readAuthenticationMethods, nextAuthenticationMethodId, writeAuthenticationMethods } from "~/server/database"; import { broadcastEvent } from "~/server/streams"; +import { ApiSession } from "~/shared/types/api"; -export default defineEventHandler(async (event) => { +export default defineEventHandler(async (event): Promise => { let session = await getServerSession(event, false); - if (session) { + if (session?.accountId !== undefined) { throw createError({ status: 409, - message: "Cannot create account while having an active session." + message: "Cannot create account while logged in to an account." }); } - const formData = await readFormData(event); - const name = formData.get("name"); + const formData = await readBody(event); + const name = formData.name; const users = await readUsers(); let user: ServerUser; @@ -54,11 +55,35 @@ export default defineEventHandler(async (event) => { }); } + if (session?.authenticationProvider) { + const authMethods = await readAuthenticationMethods(); + const method = authMethods.find(method => ( + method.provider === session.authenticationProvider + && method.slug === session.authenticationSlug + )); + if (method) { + throw createError({ + statusCode: 409, + statusMessage: "Conflict", + message: "A user is already associated with the authentication method", + }); + } + authMethods.push({ + id: await nextAuthenticationMethodId(), + userId: user.id, + provider: session.authenticationProvider, + slug: session.authenticationSlug!, + name: session.authenticationName!, + }) + await writeAuthenticationMethods(authMethods); + } + users.push(user); await writeUsers(users); await broadcastEvent({ type: "user-update", data: user, }); - await setServerSession(event, user); + const newSession = await setServerSession(event, user); + return await serverSessionToApi(event, newSession); }) diff --git a/server/api/auth/ap/telegram-login.post.ts b/server/api/auth/ap/telegram-login.post.ts new file mode 100644 index 0000000..d3c69fd --- /dev/null +++ b/server/api/auth/ap/telegram-login.post.ts @@ -0,0 +1,100 @@ +/* + SPDX-FileCopyrightText: © 2025 Hornwitser + SPDX-License-Identifier: AGPL-3.0-or-later +*/ +import * as fs from "node:fs/promises"; +import type { H3Event } from "h3"; +import { string, z } from "zod/v4-mini"; +import { readAuthenticationMethods, readUsers } from "~/server/database"; +import { type TelegramAuthData, telegramAuthDataSchema } from "~/shared/types/telegram"; +import { ApiSession } from "~/shared/types/api"; + +const loginSchema = z.object({ + authData: telegramAuthDataSchema, +}); + +let cachedTelegramConfig: + | undefined + | { enabled: false } + | { enabled: true, botUsername: string, secretKey: CryptoKey } +; +async function useTelegramConfig(event: H3Event) { + if (cachedTelegramConfig) + return cachedTelegramConfig; + + const runtimeConfig = useRuntimeConfig(event); + if (!runtimeConfig.public.authTelegramEnabled) { + return cachedTelegramConfig = { + enabled: false, + }; + } + if (!runtimeConfig.telegramBotTokenFile) throw new Error("NUXT_TELEGRAM_BOT_TOKEN_FILE not configured"); + if (!runtimeConfig.public.telegramBotUsername) throw new Error("NUXT_PUBLIC_TELEGRAM_BOT_USERNAME not configured"); + + const botToken = await fs.readFile(runtimeConfig.telegramBotTokenFile); + const secretKey = await crypto.subtle.importKey( + "raw", + await crypto.subtle.digest("SHA-256", botToken), + { + name: "HMAC", + hash: "SHA-256", + }, + false, + ["verify"], + ); + return cachedTelegramConfig = { + enabled: true, + botUsername: runtimeConfig.public.telegramBotUsername, + secretKey, + } +} + +async function validateTelegramAuthData(authData: TelegramAuthData, key: CryptoKey) { + const { hash, ...checkData } = authData; + const checkString = Object.entries(checkData).map(([key, value]) => `${key}=${value}`).sort().join("\n"); + const signature = Buffer.from(hash, "hex"); + return await crypto.subtle.verify("HMAC", key, signature, Buffer.from(checkString)); +} + +export default defineEventHandler(async (event): Promise => { + const { success, error, data } = loginSchema.safeParse(await readBody(event)); + if (!success) { + throw createError({ + statusCode: 400, + statusMessage: "Bad Request", + message: z.prettifyError(error), + }); + } + + const config = await useTelegramConfig(event); + if (!config.enabled) { + throw createError({ + statusCode: 403, + statusMessage: "Forbidden", + message: "Telegram authentication is disabled", + }); + } + + if (!await validateTelegramAuthData(data.authData, config.secretKey)) { + throw createError({ + statusCode: 403, + statusMessage: "Forbidden", + message: "Validating authentication data failed", + }); + } + + const slug = String(data.authData.id); + const authMethods = await readAuthenticationMethods(); + const method = authMethods.find(method => method.provider === "telegram" && method.slug === slug); + let session; + if (method) { + const users = await readUsers(); + const account = users.find(user => !user.deleted && user.id === method.userId); + session = await setServerSession(event, account); + } else { + const name = data.authData.username ? "@" + data.authData.username : slug; + session = await setServerSession(event, undefined, "telegram", slug, name); + } + + return await serverSessionToApi(event, session); +}) diff --git a/server/database.ts b/server/database.ts index e3b5c0b..da703e5 100644 --- a/server/database.ts +++ b/server/database.ts @@ -10,6 +10,9 @@ export interface ServerSession { id: Id, access: ApiUserType, accountId?: number, + authenticationProvider?: "telegram", + authenticationSlug?: string, + authenticationName?: string, rotatesAtMs: number, expiresAtMs?: number, discardAtMs: number, @@ -28,6 +31,14 @@ export interface ServerUser { locale?: string, } +export interface ServerAuthenticationMethod { + id: Id, + provider: "telegram", + slug: string, + name: string, + userId: Id, +} + // For this demo I'm just storing the runtime data in JSON files. When making // this into proper application this should be replaced with an actual database. @@ -37,6 +48,8 @@ const usersPath = "data/users.json"; const nextUserIdPath = "data/next-user-id.json"; const sessionsPath = "data/sessions.json"; const nextSessionIdPath = "data/next-session-id.json"; +const authMethodPath = "data/auth-method.json"; +const nextAuthenticationMethodIdPath = "data/auth-method-id.json" async function remove(path: string) { try { @@ -137,3 +150,17 @@ export async function readSessions() { export async function writeSessions(sessions: ServerSession[]) { await writeFile(sessionsPath, JSON.stringify(sessions, undefined, "\t") + "\n", "utf-8"); } + +export async function nextAuthenticationMethodId() { + const nextId = await readJson(nextAuthenticationMethodIdPath, 0); + await writeFile(nextAuthenticationMethodIdPath, String(nextId + 1), "utf-8"); + return nextId; +} + +export async function readAuthenticationMethods() { + return readJson(authMethodPath, []) +} + +export async function writeAuthenticationMethods(authMethods: ServerAuthenticationMethod[]) { + await writeFile(authMethodPath, JSON.stringify(authMethods, undefined, "\t") + "\n", "utf-8"); +} diff --git a/server/utils/session.ts b/server/utils/session.ts index f89a6b6..9c824e7 100644 --- a/server/utils/session.ts +++ b/server/utils/session.ts @@ -51,7 +51,13 @@ export async function clearServerSession(event: H3Event) { deleteCookie(event, "session"); } -export async function setServerSession(event: H3Event, account: ServerUser) { +export async function setServerSession( + event: H3Event, + account: ServerUser | undefined, + authenticationProvider?: "telegram", + authenticationSlug?: string, + authenticationName?: string, +) { const sessions = await readSessions(); const runtimeConfig = useRuntimeConfig(event); await clearServerSessionInternal(event, sessions); @@ -60,6 +66,9 @@ export async function setServerSession(event: H3Event, account: ServerUser) { const newSession: ServerSession = { access: account?.type ?? "anonymous", accountId: account?.id, + authenticationProvider, + authenticationSlug, + authenticationName, rotatesAtMs: now + runtimeConfig.sessionRotatesTimeout * 1000, discardAtMs: now + runtimeConfig.sessionDiscardTimeout * 1000, id: await nextSessionId(), @@ -68,6 +77,7 @@ export async function setServerSession(event: H3Event, account: ServerUser) { sessions.push(newSession); await writeSessions(sessions); await setSignedCookie(event, "session", String(newSession.id), runtimeConfig.sessionDiscardTimeout) + return newSession; } async function rotateSession(event: H3Event, sessions: ServerSession[], session: ServerSession) { @@ -78,6 +88,7 @@ async function rotateSession(event: H3Event, sessions: ServerSession[], session: const newSession: ServerSession = { accountId: account?.id, access: account?.type ?? "anonymous", + // Authentication provider is removed to avoid possibility of an infinite delay before using it. rotatesAtMs: now + runtimeConfig.sessionRotatesTimeout * 1000, discardAtMs: now + runtimeConfig.sessionDiscardTimeout * 1000, id: await nextSessionId(), @@ -172,6 +183,8 @@ export async function serverSessionToApi(event: H3Event, session: ServerSession) return { id: session.id, account, + authenticationProvider: session.authenticationProvider, + authenticationName: session.authenticationName, push, }; } diff --git a/shared/types/api.ts b/shared/types/api.ts index 3f2d421..64812ac 100644 --- a/shared/types/api.ts +++ b/shared/types/api.ts @@ -70,6 +70,8 @@ export type ApiSubscription = z.infer; export interface ApiSession { id: Id, account?: ApiAccount, + authenticationProvider?: "telegram", + authenticationName?: string, push: boolean, } diff --git a/shared/types/telegram.ts b/shared/types/telegram.ts new file mode 100644 index 0000000..b7caeb7 --- /dev/null +++ b/shared/types/telegram.ts @@ -0,0 +1,20 @@ +/* + SPDX-FileCopyrightText: © 2025 Hornwitser + SPDX-License-Identifier: AGPL-3.0-or-later +*/ +import { z } from "zod/v4-mini"; + +export const telegramAuthDataSchema = z.catchall( + z.object({ + // These fields are pure speculation as the actual API is undocumented. + auth_date: z.number(), + first_name: z.optional(z.string()), + hash: z.string(), + id: z.number(), + last_name: z.optional(z.string()), + photo_url: z.optional(z.string()), + username: z.optional(z.string()), + }), + z.union([z.string(), z.number()]), +); +export type TelegramAuthData = z.infer; diff --git a/stores/session.ts b/stores/session.ts index 2545c4f..ddba323 100644 --- a/stores/session.ts +++ b/stores/session.ts @@ -26,6 +26,8 @@ const fetchSessionWithCookie = async (event?: H3Event) => { export const useSessionStore = defineStore("session", () => { const state = { account: ref(), + authenticationProvider: ref(), + authenticationName: ref(), id: ref(), push: ref(false), }; @@ -37,6 +39,8 @@ export const useSessionStore = defineStore("session", () => { }, update(session?: ApiSession) { state.account.value = session?.account; + state.authenticationProvider.value = session?.authenticationProvider; + state.authenticationName.value = session?.authenticationName; state.id.value = session?.id; state.push.value = session?.push ?? false; }, From a33c8e9dac063c086ac40ea18565375d6fa5029f Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Wed, 9 Jul 2025 15:35:17 +0200 Subject: [PATCH 11/13] Use SameSite Lax for session cookie When a user browses to a page from another site, for example via a shared link we want the browser to send the session cookie so that the page renders as the user and not confusingly being logged out. This may cause CSRF vulenrabilities, later work to add CSRF tokens should be considered. --- server/utils/signed-cookie.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/utils/signed-cookie.ts b/server/utils/signed-cookie.ts index b7c4129..88b9687 100644 --- a/server/utils/signed-cookie.ts +++ b/server/utils/signed-cookie.ts @@ -25,7 +25,7 @@ export async function setSignedCookie(event: H3Event, name: string, value: strin const secret = await useCookieSecret(event); const signature = await crypto.subtle.sign("HMAC", secret, Buffer.from(`${name}=${value}`)); const cookie = `${value}.${Buffer.from(signature).toString("base64url")}` - setCookie(event, name, cookie, { httpOnly: true, secure: true, sameSite: true, maxAge }); + setCookie(event, name, cookie, { httpOnly: true, secure: true, sameSite: "lax", maxAge }); } export async function getSignedCookie(event: H3Event, name: string) { From 0d0e38e4b64d6c6d3a8a75311d890310eb4ec523 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Wed, 9 Jul 2025 17:57:49 +0200 Subject: [PATCH 12/13] Refactor demo login as an authentication method Use the authentication method system for the demo login and the generated accounts. This makes it possible to toggle it off on production systems as these shouldn't have it enabled at all. --- components/LogIn.vue | 29 ++++++ components/LogInDemo.vue | 41 +++++++++ docs/admin/config.md | 6 ++ nuxt.config.ts | 1 + pages/login.vue | 88 +------------------ pages/register.vue | 71 ++++++++++++--- server/api/admin/database-import-demo.post.ts | 13 ++- server/api/auth/account.post.ts | 15 +++- server/api/auth/ap/demo-login.post.ts | 38 ++++++++ server/api/auth/login.post.ts | 22 ----- server/database.ts | 10 ++- server/utils/session.ts | 4 +- shared/types/api.ts | 7 +- stores/session.ts | 8 -- 14 files changed, 212 insertions(+), 141 deletions(-) create mode 100644 components/LogIn.vue create mode 100644 components/LogInDemo.vue create mode 100644 server/api/auth/ap/demo-login.post.ts delete mode 100644 server/api/auth/login.post.ts diff --git a/components/LogIn.vue b/components/LogIn.vue new file mode 100644 index 0000000..e2d56ca --- /dev/null +++ b/components/LogIn.vue @@ -0,0 +1,29 @@ + + + + + + diff --git a/components/LogInDemo.vue b/components/LogInDemo.vue new file mode 100644 index 0000000..31cdbf8 --- /dev/null +++ b/components/LogInDemo.vue @@ -0,0 +1,41 @@ + + + + + + diff --git a/docs/admin/config.md b/docs/admin/config.md index b95e08d..cf22886 100644 --- a/docs/admin/config.md +++ b/docs/admin/config.md @@ -20,6 +20,12 @@ Time in seconds before a session is deleted from the client and server, resultin This should be several times greater that `NUXT_SESSION_ROTATES_TIMEOUT`. +### NUXT_AUTH_DEMO_ENABLED + +Boolean indicating if the demo authentication provider should be enabled. This allows logging in using only a name with no additional checks or security and should _never_ be enabled on a production system. The purpose of this is to make it easier to demo the system. + +Defaults to `false`. + ### NUXT_TELEGRAM_BOT_TOKEN_FILE Path to a file containing the token for the Telegram bot used for authenticating users via Telegram. diff --git a/nuxt.config.ts b/nuxt.config.ts index b970358..42624ba 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -31,6 +31,7 @@ export default defineNuxtConfig({ public: { defaultTimezone: "Europe/Oslo", defaultLocale: "en-GB", + authDemoEnabled: false, authTelegramEnabled: false, telegramBotUsername: "", vapidPublicKey: "", diff --git a/pages/login.vue b/pages/login.vue index 01b233f..c7b9cdd 100644 --- a/pages/login.vue +++ b/pages/login.vue @@ -5,32 +5,10 @@ @@ -38,66 +16,4 @@ useHead({ title: "Login", }); - -const runtimeConfig = useRuntimeConfig(); -const authTelegramEnabled = runtimeConfig.public.authTelegramEnabled; -const sessionStore = useSessionStore(); -const { getSubscription, subscribe } = usePushNotification(); - -const name = ref(""); -const result = ref("") -async function logIn() { - try { - result.value = await sessionStore.logIn(name.value); - // Resubscribe push notifications if the user was subscribed before. - const subscription = await getSubscription(); - if (subscription) { - await subscribe(); - } - // XXX Remove the need for this. - await sessionStore.fetch(); - - } catch (err: any) { - console.log(err); - console.log(err.data); - result.value = `Server replied: ${err.statusCode} ${err.statusMessage}`; - } -} - -const createName = ref(""); -async function createAccount() { - try { - const res = await $fetch.raw("/api/auth/account", { - method: "POST", - headers: { - "Content-Type": "application/x-www-form-urlencoded", - }, - body: new URLSearchParams({ name: createName.value }) - }); - result.value = `Server replied: ${res.status} ${res.statusText}`; - await sessionStore.fetch(); - - } catch (err: any) { - console.log(err); - console.log(err.data); - result.value = `Server replied: ${err.statusCode} ${err.statusMessage}`; - } -} -async function createAnonymousAccount() { - try { - const res = await $fetch.raw("/api/auth/account", { - method: "POST", - headers: { - "Content-Type": "application/x-www-form-urlencoded", - }, - }); - result.value = `Server replied: ${res.status} ${res.statusText}`; - await sessionStore.fetch(); - - } catch (err: any) { - console.log(err); - console.log(err.data); - result.value = `Server replied: ${err.statusCode} ${err.statusMessage}`; - } -} diff --git a/pages/register.vue b/pages/register.vue index f9de244..7ed2ad6 100644 --- a/pages/register.vue +++ b/pages/register.vue @@ -5,43 +5,74 @@ + + diff --git a/server/api/admin/database-import-demo.post.ts b/server/api/admin/database-import-demo.post.ts index fe85be8..cab0eae 100644 --- a/server/api/admin/database-import-demo.post.ts +++ b/server/api/admin/database-import-demo.post.ts @@ -2,10 +2,19 @@ SPDX-FileCopyrightText: © 2025 Hornwitser SPDX-License-Identifier: AGPL-3.0-or-later */ -import { writeSchedule, writeUsers } from "~/server/database"; +import { nextAuthenticationMethodId, writeAuthenticationMethods, writeNextAuthenticationMethodId, writeSchedule, writeUsers } from "~/server/database"; import { generateDemoSchedule, generateDemoAccounts } from "~/server/generate-demo-schedule"; export default defineEventHandler(async (event) => { await requireServerSessionWithAdmin(event); - await writeUsers(generateDemoAccounts()); + const accounts = generateDemoAccounts(); + await writeUsers(accounts); await writeSchedule(generateDemoSchedule()); + await writeAuthenticationMethods(accounts.map((user, index) => ({ + id: index, + userId: user.id, + provider: "demo", + slug: user.name!, + name: user.name!, + }))); + await writeNextAuthenticationMethodId(Math.max(await nextAuthenticationMethodId(), accounts.length)); }) diff --git a/server/api/auth/account.post.ts b/server/api/auth/account.post.ts index 2fcbc71..1b2d033 100644 --- a/server/api/auth/account.post.ts +++ b/server/api/auth/account.post.ts @@ -15,8 +15,8 @@ export default defineEventHandler(async (event): Promise => { }); } - const formData = await readBody(event); - const name = formData.name; + const body = await readBody(event); + const name = body?.name; const users = await readUsers(); let user: ServerUser; @@ -42,7 +42,7 @@ export default defineEventHandler(async (event): Promise => { name, }; - } else if (name === null) { + } else if (name === undefined) { user = { id: await nextUserId(), updatedAt: new Date().toISOString(), @@ -55,7 +55,14 @@ export default defineEventHandler(async (event): Promise => { }); } - if (session?.authenticationProvider) { + if (user.type !== "anonymous") { + if (!session?.authenticationProvider) { + throw createError({ + statusCode: 409, + statusMessage: "Conflict", + message: "User account need an authentication method associated with it.", + }); + } const authMethods = await readAuthenticationMethods(); const method = authMethods.find(method => ( method.provider === session.authenticationProvider diff --git a/server/api/auth/ap/demo-login.post.ts b/server/api/auth/ap/demo-login.post.ts new file mode 100644 index 0000000..ffd07de --- /dev/null +++ b/server/api/auth/ap/demo-login.post.ts @@ -0,0 +1,38 @@ +/* + SPDX-FileCopyrightText: © 2025 Hornwitser + SPDX-License-Identifier: AGPL-3.0-or-later +*/ +import { readAuthenticationMethods, readUsers } from "~/server/database"; + +export default defineEventHandler(async (event) => { + const runtimeConfig = useRuntimeConfig(event); + if (!runtimeConfig.public.authDemoEnabled) { + throw createError({ + statusCode: 403, + statusMessage: "Forbidden", + message: "Demo authentication is disabled", + }); + } + + const { name: slug } = await readBody(event); + + if (typeof slug !== "string" || !slug) { + throw createError({ + statusCode: 400, + statusMessage: "Bad Request", + message: "Missing name", + }); + } + + const authMethods = await readAuthenticationMethods(); + const method = authMethods.find(method => method.provider === "demo" && method.slug === slug); + let session; + if (method) { + const users = await readUsers(); + const account = users.find(user => !user.deleted && user.id === method.userId); + session = await setServerSession(event, account); + } else { + session = await setServerSession(event, undefined, "demo", slug, slug); + } + return await serverSessionToApi(event, session); +}) diff --git a/server/api/auth/login.post.ts b/server/api/auth/login.post.ts deleted file mode 100644 index c390d1c..0000000 --- a/server/api/auth/login.post.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - SPDX-FileCopyrightText: © 2025 Hornwitser - SPDX-License-Identifier: AGPL-3.0-or-later -*/ -import { readUsers } from "~/server/database"; - -export default defineEventHandler(async (event) => { - const { name } = await readBody(event); - - if (!name) { - return new Response(undefined, { status: 400 }) - } - - const accounts = await readUsers(); - const account = accounts.find(a => a.name === name); - - if (!account) { - return new Response(undefined, { status: 403 }) - } - - await setServerSession(event, account); -}) diff --git a/server/database.ts b/server/database.ts index da703e5..db5226a 100644 --- a/server/database.ts +++ b/server/database.ts @@ -3,14 +3,14 @@ SPDX-License-Identifier: AGPL-3.0-or-later */ import { readFile, unlink, writeFile } from "node:fs/promises"; -import type { ApiSchedule, ApiSubscription, ApiUserType } from "~/shared/types/api"; +import type { ApiAuthenticationProvider, ApiSchedule, ApiSubscription, ApiUserType } from "~/shared/types/api"; import type { Id } from "~/shared/types/common"; export interface ServerSession { id: Id, access: ApiUserType, accountId?: number, - authenticationProvider?: "telegram", + authenticationProvider?: ApiAuthenticationProvider, authenticationSlug?: string, authenticationName?: string, rotatesAtMs: number, @@ -33,7 +33,7 @@ export interface ServerUser { export interface ServerAuthenticationMethod { id: Id, - provider: "telegram", + provider: ApiAuthenticationProvider, slug: string, name: string, userId: Id, @@ -157,6 +157,10 @@ export async function nextAuthenticationMethodId() { return nextId; } +export async function writeNextAuthenticationMethodId(nextId: number) { + await writeFile(nextAuthenticationMethodIdPath, String(nextId), "utf-8"); +} + export async function readAuthenticationMethods() { return readJson(authMethodPath, []) } diff --git a/server/utils/session.ts b/server/utils/session.ts index 9c824e7..f6d9d77 100644 --- a/server/utils/session.ts +++ b/server/utils/session.ts @@ -14,7 +14,7 @@ import { writeSubscriptions } from "~/server/database"; import { broadcastEvent } from "../streams"; -import type { ApiSession } from "~/shared/types/api"; +import type { ApiAuthenticationProvider, ApiSession } from "~/shared/types/api"; async function removeSessionSubscription(sessionId: number) { const subscriptions = await readSubscriptions(); @@ -54,7 +54,7 @@ export async function clearServerSession(event: H3Event) { export async function setServerSession( event: H3Event, account: ServerUser | undefined, - authenticationProvider?: "telegram", + authenticationProvider?: ApiAuthenticationProvider, authenticationSlug?: string, authenticationName?: string, ) { diff --git a/shared/types/api.ts b/shared/types/api.ts index 64812ac..7b82c80 100644 --- a/shared/types/api.ts +++ b/shared/types/api.ts @@ -67,10 +67,15 @@ export const apiSubscriptionSchema = z.object({ }); export type ApiSubscription = z.infer; +export type ApiAuthenticationProvider = + | "demo" + | "telegram" +; + export interface ApiSession { id: Id, account?: ApiAccount, - authenticationProvider?: "telegram", + authenticationProvider?: ApiAuthenticationProvider, authenticationName?: string, push: boolean, } diff --git a/stores/session.ts b/stores/session.ts index ddba323..380390b 100644 --- a/stores/session.ts +++ b/stores/session.ts @@ -44,14 +44,6 @@ export const useSessionStore = defineStore("session", () => { state.id.value = session?.id; state.push.value = session?.push ?? false; }, - async logIn(name: string) { - const res = await $fetch.raw("/api/auth/login", { - method: "POST", - body: { name }, - }); - await actions.fetch(); - return `/api/auth/login replied: ${res.status} ${res.statusText}`; - }, async logOut() { try { await $fetch.raw("/api/auth/session", { From f69381c44ca35d07f0fe7af0c821bffa73547763 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Wed, 9 Jul 2025 18:08:39 +0200 Subject: [PATCH 13/13] Set verbatimModuleSyntax for server code The nuxi typecheck command complains about type only imports that are not declared as such, but the VsCode environment does not. There's probably a missmatch somewhere in the configuration for Nuxt that I'm not going to dig into. Workaround this issue for now by setting the option in the tsconfig.json file for the server. --- server/api/auth/account.post.ts | 2 +- server/api/auth/ap/telegram-login.post.ts | 4 ++-- server/streams.ts | 2 +- server/tsconfig.json | 5 ++++- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/server/api/auth/account.post.ts b/server/api/auth/account.post.ts index 1b2d033..e0b3be8 100644 --- a/server/api/auth/account.post.ts +++ b/server/api/auth/account.post.ts @@ -4,7 +4,7 @@ */ import { readUsers, writeUsers, nextUserId, type ServerUser, readAuthenticationMethods, nextAuthenticationMethodId, writeAuthenticationMethods } from "~/server/database"; import { broadcastEvent } from "~/server/streams"; -import { ApiSession } from "~/shared/types/api"; +import type { ApiSession } from "~/shared/types/api"; export default defineEventHandler(async (event): Promise => { let session = await getServerSession(event, false); diff --git a/server/api/auth/ap/telegram-login.post.ts b/server/api/auth/ap/telegram-login.post.ts index d3c69fd..25a610b 100644 --- a/server/api/auth/ap/telegram-login.post.ts +++ b/server/api/auth/ap/telegram-login.post.ts @@ -4,10 +4,10 @@ */ import * as fs from "node:fs/promises"; import type { H3Event } from "h3"; -import { string, z } from "zod/v4-mini"; +import { z } from "zod/v4-mini"; import { readAuthenticationMethods, readUsers } from "~/server/database"; import { type TelegramAuthData, telegramAuthDataSchema } from "~/shared/types/telegram"; -import { ApiSession } from "~/shared/types/api"; +import type { ApiSession } from "~/shared/types/api"; const loginSchema = z.object({ authData: telegramAuthDataSchema, diff --git a/server/streams.ts b/server/streams.ts index 6daf522..111c9a2 100644 --- a/server/streams.ts +++ b/server/streams.ts @@ -2,7 +2,7 @@ SPDX-FileCopyrightText: © 2025 Hornwitser SPDX-License-Identifier: AGPL-3.0-or-later */ -import { readUsers, ServerSession } from "~/server/database"; +import { readUsers, type ServerSession } from "~/server/database"; import type { ApiAccount, ApiEvent } from "~/shared/types/api"; import { serverSessionToApi } from "./utils/session"; import { H3Event } from "h3"; diff --git a/server/tsconfig.json b/server/tsconfig.json index e3135ac..b677c91 100644 --- a/server/tsconfig.json +++ b/server/tsconfig.json @@ -3,5 +3,8 @@ SPDX-License-Identifier: AGPL-3.0-or-later */ { - "extends": "../.nuxt/tsconfig.server.json" + "extends": "../.nuxt/tsconfig.server.json", + "compilerOptions": { + "verbatimModuleSyntax": true, + }, }