diff --git a/backend/package.json b/backend/package.json index 2b286280a42a..e5fa53e7b362 100644 --- a/backend/package.json +++ b/backend/package.json @@ -85,7 +85,7 @@ "readline-sync": "1.4.10", "supertest": "7.1.4", "testcontainers": "11.11.0", - "tsx": "4.16.2", + "tsx": "4.21.0", "typescript": "6.0.0-beta", "vitest": "4.0.15" }, diff --git a/frontend/__tests__/components/common/Button.spec.tsx b/frontend/__tests__/components/common/Button.spec.tsx index b926e8a459f1..b753e0cea454 100644 --- a/frontend/__tests__/components/common/Button.spec.tsx +++ b/frontend/__tests__/components/common/Button.spec.tsx @@ -141,21 +141,6 @@ describe("Button component", () => { expect(button).not.toHaveClass("button"); }); - it("applies textButton class when type is text", () => { - const { container } = render(() => ( - - - - -
-
All-Time English Leaderboards
-
-
15 seconds
-
-
-
-
-
-
-
60 seconds
-
-
-
-
-
-
-
-
-
-
15 seconds
-
-
-
-
-
-
-
-
-
30 seconds
-
-
-
-
-
-
-
-
-
60 seconds
-
-
-
-
-
-
-
-
-
120 seconds
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
10 words
-
-
-
-
-
-
-
-
-
25 words
-
-
-
-
-
-
-
-
-
50 words
-
-
-
-
-
-
-
-
-
100 words
-
-
-
-
-
-
-
-
- -
-
-
- - - - - - + - + + + ); +} diff --git a/frontend/src/ts/components/pages/profile/UserProfile.tsx b/frontend/src/ts/components/pages/profile/UserProfile.tsx new file mode 100644 index 000000000000..2527e845825c --- /dev/null +++ b/frontend/src/ts/components/pages/profile/UserProfile.tsx @@ -0,0 +1,178 @@ +import { PersonalBest, PersonalBests } from "@monkeytype/schemas/shared"; +import { + RankAndCount, + UserProfile as UserProfileType, +} from "@monkeytype/schemas/users"; +import { formatDate } from "date-fns/format"; +import { createMemo, For, JSXElement, Show } from "solid-js"; + +import * as PbTablesModal from "../../../modals/pb-tables"; +import { getConfig } from "../../../signals/config"; +import { Formatting } from "../../../utils/format"; +import { formatTopPercentage } from "../../../utils/misc"; +import { Button } from "../../common/Button"; +import { ActivityCalendar } from "./ActivityCalendar"; +import { UserDetails } from "./UserDetails"; + +export function UserProfile(props: { + profile: UserProfileType; + isAccountPage?: true; +}): JSXElement { + return ( +
+ + + + +
+ + +
+ + + Note: This account has opted out of the leaderboards, meaning their + results aren't verified by the anticheat system and may not be + legitimate. + + + + +
+ ); +} + +function LeaderboardPosition(props: { + top15?: RankAndCount; + top60?: RankAndCount; +}): JSXElement { + const format = createMemo(() => new Formatting(getConfig)); + + return ( +
+ + All-Time English Leaderboards + + +
+
15 seconds
+
+ {format().rank(props.top15?.rank)} +
+
+ {formatTopPercentage(props.top15)} +
+
+
+ +
+
60 seconds
+
+ {format().rank(props.top60?.rank)} +
+
+ {formatTopPercentage(props.top60)} +
+
+
+
+ ); +} + +function PbTable(props: { + mode: M; + mode2: string[]; + pbs: PersonalBests[M]; + isAccountPage?: true; +}): JSXElement { + const format = createMemo(() => new Formatting(getConfig)); + + const bests = createMemo(() => + props.mode2.map((mode) => { + const pbArray = props.pbs[mode] ?? []; + + const best = pbArray.reduce( + (max, current) => (current.wpm > (max?.wpm ?? 0) ? current : max), + undefined, + ); + + return { + mode2: mode, + pb: best, + }; + }), + ); + + return ( +
+
+ + {(item) => ( +
+
+
+ {item.mode2} {props.mode === "time" ? "seconds" : "words"} +
+
+ {format().typingSpeed(item.pb?.wpm, { + showDecimalPlaces: false, + })} +
+
+ {format().accuracy(item.pb?.acc, { + showDecimalPlaces: false, + })} +
+
+ +
+
+ {item.mode2} {props.mode === "time" ? "seconds" : "words"} +
+
+ {format().typingSpeed(item.pb?.wpm)}{" "} + {format().typingSpeedUnit} +
+
{format().typingSpeed(item.pb?.raw)} raw
+
{format().accuracy(item.pb?.acc)} acc
+
{format().percentage(item.pb?.consistency)} con
+
+ {formatDate(item.pb?.timestamp ?? 0, "dd MMM yyyy")} +
+
+
+
+ )} +
+
+ +
+
+
+
+ ); +} diff --git a/frontend/src/ts/components/ui/ValidatedInput.tsx b/frontend/src/ts/components/ui/ValidatedInput.tsx index 05865863b52c..0e75561fc93b 100644 --- a/frontend/src/ts/components/ui/ValidatedInput.tsx +++ b/frontend/src/ts/components/ui/ValidatedInput.tsx @@ -38,7 +38,6 @@ export function ValidatedInput( element, others as ValidationOptions, ); - validatedInput.setValue(props.value ?? null); }); diff --git a/frontend/src/ts/controllers/page-controller.ts b/frontend/src/ts/controllers/page-controller.ts index 112179c62dd3..99e6b51e487c 100644 --- a/frontend/src/ts/controllers/page-controller.ts +++ b/frontend/src/ts/controllers/page-controller.ts @@ -1,13 +1,15 @@ import * as Misc from "../utils/misc"; import * as Strings from "../utils/strings"; -import { getActivePage, setActivePage } from "../signals/core"; +import { + getActivePage, + setActivePage, + setSelectedProfileName, +} from "../signals/core"; import * as Settings from "../pages/settings"; import * as Account from "../pages/account"; import * as PageTest from "../pages/test"; import * as PageLogin from "../pages/login"; import * as PageLoading from "../pages/loading"; -import * as PageProfile from "../pages/profile"; -import * as PageProfileSearch from "../pages/profile-search"; import * as Friends from "../pages/friends"; import * as Page404 from "../pages/404"; import * as PageLeaderboards from "../pages/leaderboards"; @@ -15,7 +17,7 @@ import * as PageAccountSettings from "../pages/account-settings"; import * as PageTransition from "../states/page-transition"; import * as AdController from "../controllers/ad-controller"; import * as Focus from "../test/focus"; -import Page, { PageName, LoadingOptions } from "../pages/page"; +import Page, { PageName, LoadingOptions, PageProperties } from "../pages/page"; import { onDOMReady, qsa, qsr } from "../utils/dom"; import * as Skeleton from "../utils/skeleton"; @@ -33,8 +35,12 @@ const pages = { about: solidPage("about"), account: Account.page, login: PageLogin.page, - profile: PageProfile.page, - profileSearch: PageProfileSearch.page, + profile: solidPage("profile", { + beforeShow: async (options) => { + setSelectedProfileName(options.params?.["uidOrName"]); + }, + }), + profileSearch: solidPage("profileSearch"), friends: Friends.page, 404: Page404.page, accountSettings: PageAccountSettings.page, @@ -295,7 +301,13 @@ export async function change( return true; } -function solidPage(id: PageName, props?: { path?: string }): Page { +function solidPage( + id: PageName, + props?: { + path?: string; + beforeShow?: PageProperties["beforeShow"]; + }, +): Page { const path = props?.path ?? `/${id}`; const internalId = `page${Strings.capitalizeFirstLetter(id)}`; onDOMReady(() => Skeleton.save(internalId)); @@ -303,8 +315,9 @@ function solidPage(id: PageName, props?: { path?: string }): Page { id, path, element: qsr(`#${internalId}`), - beforeShow: async () => { + beforeShow: async (options) => { Skeleton.append(internalId, "main"); + await props?.beforeShow?.(options); }, afterHide: async () => { Skeleton.remove(internalId); diff --git a/frontend/src/ts/db.ts b/frontend/src/ts/db.ts index 02f1d9da4e8f..4a83b325bb72 100644 --- a/frontend/src/ts/db.ts +++ b/frontend/src/ts/db.ts @@ -32,6 +32,10 @@ import { get as getServerConfiguration, } from "./ape/server-configuration"; import { Connection } from "@monkeytype/schemas/connections"; +import { + setLastResult, + setSnapshot as setSolidSnapshot, +} from "./stores/snapshot"; let dbSnapshot: Snapshot | undefined; const firstDayOfTheWeek = getFirstDayOfTheWeek(); @@ -77,6 +81,8 @@ export function setSnapshot( if (options?.dispatchEvent !== false) { AuthEvent.dispatch({ type: "snapshotUpdated", data: { isInitial: false } }); } + + setSolidSnapshot(newSnapshot); } export async function initSnapshot(): Promise { @@ -248,6 +254,8 @@ export async function initSnapshot(): Promise { } catch (e) { dbSnapshot = getDefaultSnapshot(); throw e; + } finally { + setSolidSnapshot(dbSnapshot); } } @@ -302,6 +310,8 @@ export async function getUserResults(offset?: number): Promise { } else { dbSnapshot.results = results; } + + setLastResult(results[0]); return true; } @@ -958,6 +968,7 @@ export function saveLocalResult(data: SaveLocalResultData): void { if (snapshot?.results !== undefined) { snapshot.results.unshift(data.result); } + setLastResult(data.result); if (snapshot.testActivity !== undefined) { snapshot.testActivity.increment(new Date(data.result.timestamp)); } diff --git a/frontend/src/ts/elements/account-settings/blocked-user-table.ts b/frontend/src/ts/elements/account-settings/blocked-user-table.ts index 819ed1b77748..b8494b79a5ba 100644 --- a/frontend/src/ts/elements/account-settings/blocked-user-table.ts +++ b/frontend/src/ts/elements/account-settings/blocked-user-table.ts @@ -58,9 +58,7 @@ function refreshList(): void { const content = blockedUsers.map( (blocked) => ` -
${blocked.initiatorName} + ${blocked.initiatorName} ${format(new Date(blocked.lastModified), "dd MMM yyyy HH:mm")} `; - - const htmlToShow = isProfile ? "" : showAllButton; - - targetElement?.qs(".pbsWords")?.setHtml(` -
-
-
10 words
-
-
-
-
-
-
-
-
-
25 words
-
-
-
-
-
-
-
-
-
50 words
-
-
-
-
-
-
-
-
-
100 words
-
-
-
-
-
-
- ${htmlToShow} - `); - - targetElement?.qs(".pbsTime")?.setHtml(` -
-
-
15 seconds
-
-
-
-
-
-
-
-
-
30 seconds
-
-
-
-
-
-
-
-
-
60 seconds
-
-
-
-
-
-
-
-
-
120 seconds
-
-
-
-
-
-
- ${htmlToShow} - `); -} - -export function update(personalBests?: PersonalBests, isProfile = false): void { - clearTables(isProfile); - const targetElement = isProfile - ? qs(".pageProfile .profile") - : qs(".pageAccount .profile"); - - if (personalBests === undefined) return; - let text = ""; - - targetElement?.qs(".pbsTime")?.setHtml(""); - targetElement?.qs(".pbsWords")?.setHtml(""); - - const timeMode2s: Mode2<"time">[] = ["15", "30", "60", "120"]; - const wordMode2s: Mode2<"words">[] = ["10", "25", "50", "100"]; - - timeMode2s.forEach((mode2) => { - text += buildPbHtml(personalBests, "time", mode2); - }); - - const showAllButton = isProfile - ? "" - : `
`; - - targetElement?.qs(".pbsTime")?.appendHtml(text + showAllButton); - - text = ""; - wordMode2s.forEach((mode2) => { - text += buildPbHtml(personalBests, "words", mode2); - }); - - targetElement?.qs(".pbsWords")?.appendHtml(text + showAllButton); -} - -function buildPbHtml( - pbs: PersonalBests, - mode: "time" | "words", - mode2: StringNumber, -): string { - let retval = ""; - let dateText = ""; - const modeString = `${mode2} ${mode === "time" ? "seconds" : "words"}`; - const speedUnit = Config.typingSpeedUnit; - try { - const pbData = (pbs[mode][mode2] ?? []).sort((a, b) => b.wpm - a.wpm)[0]; - - if (pbData === undefined) throw new Error("No PB data found"); - - const date = new Date(pbData.timestamp); - if (pbData.timestamp !== undefined && pbData.timestamp > 0) { - dateText = dateFormat(date, "dd MMM yyyy"); - } - - retval = `
-
${modeString}
-
${Format.typingSpeed(pbData.wpm, { - showDecimalPlaces: false, - })}
-
${Format.accuracy(pbData.acc, { - showDecimalPlaces: false, - })}
-
-
-
${modeString}
-
${Format.typingSpeed(pbData.wpm, { - suffix: ` ${speedUnit}`, - })}
-
${Format.typingSpeed(pbData.raw, { suffix: " raw" })}
-
${Format.accuracy(pbData.acc, { suffix: " acc" })}
-
${Format.percentage(pbData.consistency, { suffix: " con" })}
-
${dateText}
-
`; - } catch (e) { - retval = `
-
${modeString}
-
-
-
-
-
`; - } - return ` -
- ${retval} -
- `; -} diff --git a/frontend/src/ts/elements/alerts.ts b/frontend/src/ts/elements/alerts.ts index 0fe861804130..ccefc55d75c4 100644 --- a/frontend/src/ts/elements/alerts.ts +++ b/frontend/src/ts/elements/alerts.ts @@ -12,11 +12,9 @@ import { promiseAnimate, } from "../utils/misc"; import AnimatedModal from "../utils/animated-modal"; -import { updateXp as accountPageUpdateProfile } from "./profile"; import { MonkeyMail } from "@monkeytype/schemas/users"; import * as XPBar from "../elements/xp-bar"; import * as AuthEvent from "../observables/auth-event"; -import { getActivePage } from "../signals/core"; import { animate } from "animejs"; import { qs, qsr } from "../utils/dom"; @@ -116,11 +114,6 @@ function hide(): void { const snapxp = DB.getSnapshot()?.xp ?? 0; void XPBar.update(snapxp, totalXpClaimed); - const activePage = getActivePage(); - if (activePage === "account" || activePage === "profile") { - accountPageUpdateProfile(activePage, snapxp + totalXpClaimed, true); - } - DB.addXp(totalXpClaimed); } }, diff --git a/frontend/src/ts/elements/input-validation.ts b/frontend/src/ts/elements/input-validation.ts index 73bc3e48c9f5..f8255d7e3235 100644 --- a/frontend/src/ts/elements/input-validation.ts +++ b/frontend/src/ts/elements/input-validation.ts @@ -10,10 +10,16 @@ import Config, { setConfig } from "../config"; import * as Notifications from "../elements/notifications"; import { ElementWithUtils } from "../utils/dom"; -export type ValidationResult = { - status: "checking" | "success" | "failed" | "warning"; - errorMessage?: string; -}; +export type ValidationResult = + | { + status: "checking" | "failed" | "warning"; + errorMessage?: string; + success: false; + } + | { + status: "success"; + success: true; + }; export type IsValidResponse = true | string | { warning: string }; @@ -77,17 +83,19 @@ export function createInputEventHandler( } if (result === true) { - callback({ status: "success" }); + callback({ status: "success", success: true }); } else { if (typeof result === "object" && "warning" in result) { callback({ status: "warning", errorMessage: result.warning, + success: false, }); } else { callback({ status: "failed", errorMessage: result, + success: false, }); } } @@ -104,24 +112,30 @@ export function createInputEventHandler( checkValue = inputValueConvert(currentValue); } - callback({ status: "checking" }); + callback({ status: "checking", success: false }); if (validation.schema !== undefined) { const schemaResult = validation.schema.safeParse(checkValue); if (!schemaResult.success) { callback({ + success: false, status: "failed", errorMessage: - schemaResult.error.errors.map((err) => err.message).join(", ") + - ".", + schemaResult.error.errors + .map((err) => + err.message.at(-1) === "." + ? err.message.slice(0, -1) + : err.message, + ) + .join(", ") + ".", }); return; } } if (callIsValid === undefined) { - callback({ status: "success" }); + callback({ status: "success", success: true }); //call original handler if defined originalInput.oninput?.(e as InputEvent); return; @@ -149,6 +163,7 @@ export class ValidatedHtmlInputElement< private indicator: InputIndicator; private currentStatus: ValidationResult = { status: "checking", + success: false, }; constructor( @@ -207,7 +222,7 @@ export class ValidatedHtmlInputElement< override setValue(val: string | null): this { if (val === null) { this.indicator.hide(); - this.currentStatus = { status: "checking" }; + this.currentStatus = { status: "checking", success: false }; } else { super.setValue(val); this.dispatch("input"); diff --git a/frontend/src/ts/elements/profile.ts b/frontend/src/ts/elements/profile.ts deleted file mode 100644 index bac7915cd4ee..000000000000 --- a/frontend/src/ts/elements/profile.ts +++ /dev/null @@ -1,472 +0,0 @@ -import * as DB from "../db"; -import { format as dateFormat } from "date-fns/format"; -import { differenceInDays } from "date-fns/differenceInDays"; -import * as Misc from "../utils/misc"; -import * as Numbers from "@monkeytype/util/numbers"; -import * as Levels from "../utils/levels"; -import * as DateTime from "@monkeytype/util/date-and-time"; -import { getHTMLById } from "../controllers/badge-controller"; -import { throttle } from "throttle-debounce"; -import { getActivePage } from "../signals/core"; -import { formatDistanceToNowStrict } from "date-fns/formatDistanceToNowStrict"; -import { getHtmlByUserFlags } from "../controllers/user-flag-controller"; -import Format from "../utils/format"; -import { UserProfile } from "@monkeytype/schemas/users"; -import { convertRemToPixels } from "../utils/numbers"; -import { secondsToString } from "../utils/date-and-time"; -import { getAuthenticatedUser } from "../firebase"; -import { Snapshot } from "../constants/default-snapshot"; -import { getAvatarElement } from "../utils/discord-avatar"; -import { formatXp } from "../utils/levels"; -import { formatTopPercentage } from "../utils/misc"; -import { get as getServerConfiguration } from "../ape/server-configuration"; -import { qs } from "../utils/dom"; - -type ProfileViewPaths = "profile" | "account"; -type UserProfileOrSnapshot = UserProfile | Snapshot; - -//this is probably the dirtiest code ive ever written - -export async function update( - where: ProfileViewPaths, - profile: UserProfileOrSnapshot, -): Promise { - const elementClass = where.charAt(0).toUpperCase() + where.slice(1); - const profileElement = qs(`.page${elementClass} .profile`); - const details = qs(`.page${elementClass} .profile .details`); - - profileElement?.setAttribute("uid", profile.uid ?? ""); - profileElement?.setAttribute("name", profile.name ?? ""); - - // ============================================================================ - // DO FREAKING NOT USE .HTML OR .APPEND HERE - USER INPUT!!!!!! - // ============================================================================ - - const banned = profile.banned === true; - - if ( - details === undefined || - profile === undefined || - profile.name === undefined || - profile.addedAt === undefined - ) { - return; - } - - const avatar = details?.qs(".avatarAndName .avatar"); - avatar?.replaceWith(getAvatarElement(profile, { size: 256 })); - - let badgeMainHtml = ""; - let badgeRestHtml = ""; - if (profile.inventory?.badges && !banned) { - for (const badge of profile.inventory.badges) { - if (badge.selected === true) { - badgeMainHtml = getHTMLById(badge.id); - } else { - badgeRestHtml += getHTMLById(badge.id, true); - } - } - } - details?.qs(".badges")?.empty().appendHtml(badgeMainHtml); - details?.qs(".allBadges")?.empty().appendHtml(badgeRestHtml); - - details?.qs(".name")?.setText(profile.name); - details - ?.qs(".userFlags") - ?.setHtml( - getHtmlByUserFlags({ ...profile, isFriend: DB.isFriend(profile.uid) }), - ); - - if (profile.lbOptOut === true) { - if (where === "profile") { - profileElement - ?.qs(".lbOptOutReminder") - ?.show() - ?.setText( - "Note: This account has opted out of the leaderboards, meaning their results aren't verified by the anticheat system and may not be legitimate.", - ); - } else { - profileElement?.qs(".lbOptOutReminder")?.hide(); - } - } - - setTimeout(() => { - updateNameFontSize(where); - }, 10); - - const joinedText = - "Joined " + dateFormat(profile.addedAt ?? 0, "dd MMM yyyy"); - const creationDate = new Date(profile.addedAt); - const diffDays = differenceInDays(new Date(), creationDate); - const balloonText = `${diffDays} day${diffDays !== 1 ? "s" : ""} ago`; - details - ?.qs(".joined") - ?.setText(joinedText) - .setAttribute("aria-label", balloonText); - - let hoverText = ""; - - if (profile.streak && profile?.streak > 1) { - details - ?.qs(".streak") - ?.setText( - `Current streak: ${profile.streak} ${ - profile.streak === 1 ? "day" : "days" - }`, - ); - hoverText = `Longest streak: ${profile.maxStreak} ${ - profile.maxStreak === 1 ? "day" : "days" - }`; - } else { - details?.qs(".streak")?.setText(""); - hoverText = ""; - } - - if (where === "account") { - const results = DB.getSnapshot()?.results; - const lastResult = results?.[0]; - - const streakOffset = (profile as Snapshot).streakHourOffset; - - const dayInMilis = 1000 * 60 * 60 * 24; - - let target = DateTime.getCurrentDayTimestamp(streakOffset) + dayInMilis; - if (target < Date.now()) { - target += dayInMilis; - } - const timeDif = formatDistanceToNowStrict(target); - - console.debug("Streak hour offset"); - console.debug("date.now()", Date.now(), new Date(Date.now())); - console.debug("dayInMilis", dayInMilis); - console.debug( - "difTarget", - new Date(DateTime.getCurrentDayTimestamp(streakOffset) + dayInMilis), - ); - console.debug("timeDif", timeDif); - console.debug( - "DateTime.getCurrentDayTimestamp()", - DateTime.getCurrentDayTimestamp(), - new Date(DateTime.getCurrentDayTimestamp()), - ); - console.debug("profile.streakHourOffset", streakOffset); - - if (lastResult !== undefined) { - //check if the last result is from today - const isToday = DateTime.isToday(lastResult.timestamp, streakOffset); - const isYesterday = DateTime.isYesterday( - lastResult.timestamp, - streakOffset, - ); - - console.debug( - "lastResult.timestamp", - lastResult.timestamp, - new Date(lastResult.timestamp), - ); - console.debug("isToday", isToday); - console.debug("isYesterday", isYesterday); - - const offsetString = Numbers.isSafeNumber(streakOffset) - ? `(${streakOffset > 0 ? "+" : ""}${streakOffset} offset)` - : ""; - - if (isToday) { - hoverText += `\nClaimed today: yes`; - hoverText += `\nCome back in: ${timeDif} ${offsetString}`; - } else if (isYesterday) { - hoverText += `\nClaimed today: no`; - hoverText += `\nStreak lost in: ${timeDif} ${offsetString}`; - } else { - hoverText += `\nStreak lost ${timeDif} ${offsetString} ago`; - hoverText += `\nIt will be removed from your profile on the next result save`; - } - - console.debug(hoverText); - - if (streakOffset === undefined) { - hoverText += `\n\nIf the streak reset time doesn't line up with your timezone, you can change it in Account Settings > Account > Set streak hour offset.`; - } - } - } - - details - ?.qs(".streak") - ?.setAttribute("aria-label", hoverText) - ?.setAttribute("data-balloon-break", ""); - - const { completedPercentage, restartRatio } = Misc.formatTypingStatsRatio( - profile.typingStats, - ); - - const typingStatsEl = details?.qs(".typingStats"); - typingStatsEl - ?.qs(".started .value") - ?.setText(`${profile.typingStats?.startedTests ?? 0}`); - typingStatsEl - ?.qs(".completed .value") - ?.setText(`${profile.typingStats?.completedTests ?? 0}`) - .setAttribute("data-balloon-pos", "up") - .setAttribute( - "aria-label", - `${completedPercentage}% (${restartRatio} restarts per completed test)`, - ); - typingStatsEl - ?.qs(".timeTyping .value") - ?.setText( - secondsToString( - Math.round(profile.typingStats?.timeTyping ?? 0), - true, - true, - ), - ); - - let bio = false; - let keyboard = false; - let socials = false; - - if (!banned) { - bio = !!(profile.details?.bio ?? ""); - details?.qs(".bio .value")?.setText(profile.details?.bio ?? ""); - - keyboard = !!(profile.details?.keyboard ?? ""); - details?.qs(".keyboard .value")?.setText(profile.details?.keyboard ?? ""); - - if ( - (profile.details?.socialProfiles?.github !== undefined && - profile.details?.socialProfiles?.github !== "") || - (profile.details?.socialProfiles?.twitter !== undefined && - profile.details?.socialProfiles?.twitter !== "") || - (profile.details?.socialProfiles?.website !== undefined && - profile.details?.socialProfiles?.website !== "") - ) { - socials = true; - const socialsEl = details?.qs(".socials .value"); - socialsEl?.empty(); - - const git = profile.details?.socialProfiles.github ?? ""; - if (git) { - socialsEl?.appendHtml( - ``, - ); - } - - const twitter = profile.details?.socialProfiles.twitter ?? ""; - if (twitter) { - socialsEl?.appendHtml( - ``, - ); - } - - const website = profile.details?.socialProfiles.website ?? ""; - - //regular expression to get website name from url - const regex = /^https?:\/\/(?:www\.)?([^/]+)/; - const websiteName = regex.exec(website)?.[1] ?? website; - - if (website) { - socialsEl?.appendHtml( - ``, - ); - } - } - } - - updateXp(where, profile.xp ?? 0); - //lbs - - if (banned) { - profileElement?.qs(".leaderboardsPositions")?.hide(); - } else { - profileElement?.qs(".leaderboardsPositions")?.show(); - - const t15 = profile.allTimeLbs?.time?.["15"]?.["english"] ?? null; - const t60 = profile.allTimeLbs?.time?.["60"]?.["english"] ?? null; - - if (t15 === null && t60 === null) { - profileElement?.qs(".leaderboardsPositions")?.hide(); - } else { - if (t15 !== null) { - profileElement - ?.qs(".leaderboardsPositions .group.t15 .pos") - ?.setText(Format.rank(t15?.rank)); - profileElement - ?.qs(".leaderboardsPositions .group.t15 .topPercentage") - ?.setText(formatTopPercentage(t15)); - } - - if (t60 !== null) { - profileElement - ?.qs(".leaderboardsPositions .group.t60 .pos") - ?.setText(Format.rank(t60?.rank)); - - profileElement - ?.qs(".leaderboardsPositions .group.t60 .topPercentage") - ?.setText(formatTopPercentage(t60)); - } - } - } - - if (profile.uid === getAuthenticatedUser()?.uid) { - profileElement?.qs(".userReportButton")?.hide(); - } else { - profileElement?.qs(".userReportButton")?.show(); - } - - const bioAndKey = bio || keyboard; - - if (!bio) { - details?.qs(".bio")?.hide(); - } else { - details?.qs(".bio")?.show(); - } - - if (!keyboard) { - details?.qs(".keyboard")?.hide(); - } else { - details?.qs(".keyboard")?.show(); - } - - if (!bioAndKey) { - details?.qs(".bioAndKeyboard")?.hide(); - details?.qs(".sep2")?.hide(); - } else { - details?.qs(".bioAndKeyboard")?.show(); - details?.qs(".sep2")?.show(); - } - - if (!socials) { - details?.qs(".socials")?.hide(); - details?.qs(".sep3")?.hide(); - } else { - details?.qs(".socials")?.show(); - details?.qs(".sep3")?.show(); - } - - details?.removeClass("none"); - details?.removeClass("bioAndKey"); - details?.removeClass("soc"); - details?.removeClass("both"); - if (!socials && !bioAndKey) { - details?.addClass("none"); - } else if (socials && !bioAndKey) { - details?.addClass("soc"); - } else if (!socials && bioAndKey) { - details?.addClass("bioAndKey"); - } else if (socials && bioAndKey) { - details?.addClass("both"); - } - - updateFriendRequestButton(); -} - -export function updateXp( - where: ProfileViewPaths, - xp: number, - sameUserCheck = false, -): void { - const elementClass = where.charAt(0).toUpperCase() + where.slice(1); - const profileElement = qs(`.page${elementClass} .profile`); - const details = qs(`.page${elementClass} .profile .details .levelAndBar`); - - if (details === undefined || details === null) return; - - if (sameUserCheck && where === "profile") { - const authedUserUid = getAuthenticatedUser()?.uid; - if (authedUserUid !== profileElement?.getAttribute("uid")) return; - } - - const xpDetails = Levels.getXpDetails(xp); - const xpForLevel = xpDetails.levelMaxXp; - const xpToDisplay = xpDetails.levelCurrentXp; - details - ?.qs(".level") - ?.setText(`${xpDetails.level}`) - ?.setAttribute("aria-label", `${formatXp(xp)} total xp`); - details - ?.qs(".xp") - ?.setText(`${formatXp(xpToDisplay)}/${formatXp(xpForLevel)}`) - ?.setAttribute( - "aria-label", - `${formatXp(xpForLevel - xpToDisplay)} xp until next level`, - ); - details - ?.qs(".xpBar .bar") - ?.setStyle({ width: `${(xpToDisplay / xpForLevel) * 100}%` }); - details - ?.qs(".xpBar") - ?.setAttribute( - "aria-label", - `${((xpToDisplay / xpForLevel) * 100).toFixed(2)}%`, - ); -} - -export function updateNameFontSize(where: ProfileViewPaths): void { - //dont run this function in safari because OH MY GOD IT IS SO SLOW - const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); - if (isSafari) return; - - let details; - if (where === "account") { - details = qs(".pageAccount .profile .details"); - } else if (where === "profile") { - details = qs(".pageProfile .profile .details"); - } - if (!details) return; - const nameField = details?.qs(".user"); - const nameFieldParent = nameField?.getParent(); - const upperLimit = convertRemToPixels(2); - - if (!nameField || !nameFieldParent) return; - - nameField.native.style.fontSize = `10px`; - const parentWidth = nameFieldParent.native.clientWidth; - const widthAt10 = nameField.native.clientWidth; - const ratioAt10 = parentWidth / widthAt10; - const fittedFontSize = ratioAt10 * 10; - const finalFontSize = Math.min(Math.max(fittedFontSize, 10), upperLimit); - nameField.native.style.fontSize = `${finalFontSize}px`; -} - -export function updateFriendRequestButton(): void { - const myUid = getAuthenticatedUser()?.uid; - const profileUid = document - .querySelector(".profile") - ?.getAttribute("uid") as string; - const button = document.querySelector(".profile .addFriendButton"); - - const myProfile = myUid === profileUid; - const hasRequest = DB.getSnapshot()?.connections[profileUid] !== undefined; - const featureEnabled = getServerConfiguration()?.connections.enabled; - - if (!featureEnabled || myUid === undefined || myProfile) { - button?.classList.add("hidden"); - } else if (hasRequest) { - button?.classList.add("disabled"); - } else { - button?.classList.remove("disabled"); - button?.classList.remove("hidden"); - } -} -const throttledEvent = throttle(1000, () => { - const activePage = getActivePage(); - if (activePage && ["account", "profile"].includes(activePage)) { - updateNameFontSize(activePage as ProfileViewPaths); - } -}); - -window.addEventListener("resize", () => { - throttledEvent(); -}); diff --git a/frontend/src/ts/elements/test-activity.ts b/frontend/src/ts/elements/test-activity.ts index 1793bf67fafb..3ddd9cd08faf 100644 --- a/frontend/src/ts/elements/test-activity.ts +++ b/frontend/src/ts/elements/test-activity.ts @@ -1,20 +1,11 @@ -import SlimSelect from "slim-select"; -import { DataObjectPartial } from "slim-select/store"; -import { getTestActivityCalendar } from "../db"; -import * as ServerConfiguration from "../ape/server-configuration"; -import * as DB from "../db"; import { TestActivityCalendar, TestActivityMonth, } from "./test-activity-calendar"; -import { safeNumber } from "@monkeytype/util/numbers"; - -let yearSelector: SlimSelect | undefined = undefined; export function init( element: HTMLElement, calendar?: TestActivityCalendar, - userSignUpDate?: Date, ): void { if (calendar === undefined) { clear(element); @@ -22,14 +13,6 @@ export function init( } element.classList.remove("hidden"); - if (element.querySelector(".yearSelect") !== null) { - yearSelector = getYearSelector(element); - initYearSelector( - element, - "current", - safeNumber(userSignUpDate?.getFullYear()) ?? 2022, - ); - } updateLabels(element, calendar.firstDayOfWeek); update(element, calendar); } @@ -39,7 +22,10 @@ export function clear(element?: HTMLElement): void { element?.querySelector(".activity")?.replaceChildren(); } -function update(element: HTMLElement, calendar?: TestActivityCalendar): void { +export function update( + element: HTMLElement, + calendar?: TestActivityCalendar, +): void { const container = element.querySelector(".activity"); if (container === null) { @@ -76,40 +62,6 @@ function update(element: HTMLElement, calendar?: TestActivityCalendar): void { } } -export function initYearSelector( - element: HTMLElement, - selectedYear: number | "current", - startYear: number, -): void { - const currentYear = new Date().getFullYear(); - const years: DataObjectPartial[] = [ - { - text: "last 12 months", - value: "current", - selected: selectedYear === "current", - }, - ]; - for (let year = currentYear; year >= startYear; year--) { - if ( - years.length < 2 || - (ServerConfiguration.get()?.users.premium.enabled && - DB.getSnapshot()?.isPremium) - ) { - years.push({ - text: year.toString(), - value: year.toString(), - selected: year === selectedYear, - }); - } - } - - const yearSelect = getYearSelector(element); - // oxlint-disable-next-line no-unsafe-argument - yearSelect.setData(years); - // oxlint-disable-next-line no-unsafe-call - years.length > 1 ? yearSelect.enable() : yearSelect.disable(); -} - function updateMonths(months: TestActivityMonth[]): void { const element = document.querySelector(".testActivity .months"); @@ -125,31 +77,6 @@ function updateMonths(months: TestActivityMonth[]): void { .join(""); } -function getYearSelector(element: HTMLElement): SlimSelect { - if (yearSelector !== undefined) return yearSelector; - yearSelector = new SlimSelect({ - select: element.querySelector(".yearSelect") as Element, - settings: { - showSearch: false, - }, - events: { - afterChange: async (newVal): Promise => { - // oxlint-disable-next-line no-unsafe-call - yearSelector?.disable(); - const selected = newVal[0]?.value as string; - const activity = await getTestActivityCalendar(selected); - update(element, activity); - // oxlint-disable-next-line no-unsafe-call - if ((yearSelector?.getData() ?? []).length > 1) { - // oxlint-disable-next-line no-unsafe-call - yearSelector?.enable(); - } - }, - }, - }); - return yearSelector; -} - const daysDisplay = [ "sunday", "monday", diff --git a/frontend/src/ts/event-handlers/global.ts b/frontend/src/ts/event-handlers/global.ts index 471c0aa00c4d..7ac60fc47b57 100644 --- a/frontend/src/ts/event-handlers/global.ts +++ b/frontend/src/ts/event-handlers/global.ts @@ -103,6 +103,7 @@ window.onerror = function (message, url, line, column, error): void { duration: 5, important: true, }); + console.error({ message, url, line, column, error }); } }; diff --git a/frontend/src/ts/modals/edit-profile.ts b/frontend/src/ts/modals/edit-profile.ts index d373940b525e..36cee234323b 100644 --- a/frontend/src/ts/modals/edit-profile.ts +++ b/frontend/src/ts/modals/edit-profile.ts @@ -5,7 +5,6 @@ import * as DB from "../db"; import { showLoaderBar, hideLoaderBar } from "../signals/loader-bar"; import * as Notifications from "../elements/notifications"; import AnimatedModal from "../utils/animated-modal"; -import * as Profile from "../elements/profile"; import { CharacterCounter } from "../elements/character-counter"; import { Badge, @@ -27,13 +26,7 @@ export function show(): void { } function hide(): void { - void modal.hide({ - afterAnimation: async () => { - const snapshot = DB.getSnapshot(); - if (!snapshot) return; - void Profile.update("account", snapshot); - }, - }); + void modal.hide(); } const bioInput = qsr("#editProfileModal .bio"); @@ -190,6 +183,8 @@ async function updateProfile(): Promise { } }); + DB.setSnapshot(snapshot); + Notifications.add("Profile updated", 1); hide(); diff --git a/frontend/src/ts/pages/account.ts b/frontend/src/ts/pages/account.ts index 7486d48b8a2c..f6487d1b275c 100644 --- a/frontend/src/ts/pages/account.ts +++ b/frontend/src/ts/pages/account.ts @@ -3,7 +3,6 @@ import * as ResultFilters from "../elements/account/result-filters"; import * as ChartController from "../controllers/chart-controller"; import Config, { setConfig } from "../config"; import * as MiniResultChartModal from "../modals/mini-result-chart"; -import * as PbTables from "../elements/account/pb-tables"; import * as Focus from "../test/focus"; import * as TodayTracker from "../test/today-tracker"; import * as Notifications from "../elements/notifications"; @@ -13,7 +12,6 @@ import * as Misc from "../utils/misc"; import * as Arrays from "../utils/arrays"; import * as Numbers from "@monkeytype/util/numbers"; import { get as getTypingSpeedUnit } from "../utils/typing-speed-units"; -import * as Profile from "../elements/profile"; import { format } from "date-fns/format"; import * as Skeleton from "../utils/skeleton"; import type { ScaleChartOptions, LinearScaleOptions } from "chart.js"; @@ -24,7 +22,6 @@ import { getAuthenticatedUser } from "../firebase"; import { showLoaderBar, hideLoaderBar } from "../signals/loader-bar"; import * as ResultBatches from "../elements/result-batches"; import Format from "../utils/format"; -import * as TestActivity from "../elements/test-activity"; import { ChartData } from "@monkeytype/schemas/results"; import { Mode, Mode2, Mode2Custom } from "@monkeytype/schemas/shared"; import { ResultFiltersGroupItem } from "@monkeytype/schemas/users"; @@ -48,7 +45,6 @@ export function toggleFilterDebug(): void { let filteredResults: SnapshotResult[] = []; let visibleTableLines = 0; -let testActivityEl: HTMLElement | null; let historyTable: SortedTableWithLimit>; function loadMoreLines(lineIndex?: number): void { @@ -210,14 +206,6 @@ async function fillContent(): Promise { const snapshot = DB.getSnapshot(); if (!snapshot) return; - PbTables.update(snapshot.personalBests); - void Profile.update("account", snapshot); - - TestActivity.init( - testActivityEl as HTMLElement, - snapshot.testActivity, - new Date(snapshot.addedAt), - ); void ResultBatches.update(); chartData = []; @@ -964,9 +952,6 @@ async function fillContent(): Promise { ChartController.accountHistogram.update(); Focus.set(false); qs(".page.pageAccount")?.setStyle({ height: "unset" }); //weird safari fix - setTimeout(() => { - Profile.updateNameFontSize("account"); - }, 0); } export async function downloadResults(offset?: number): Promise { @@ -1162,22 +1147,6 @@ qs(".pageAccount .content .group.aboveHistory .exportCSV")?.on("click", () => { void Misc.downloadResultsCSV(filteredResults); }); -qs(".pageAccount .profile")?.onChild("click", ".details .copyLink", () => { - const snapshot = DB.getSnapshot(); - if (!snapshot) return; - const { name } = snapshot; - const url = `${location.origin}/profile/${name}`; - - navigator.clipboard.writeText(url).then( - function () { - Notifications.add("URL Copied to clipboard", 0); - }, - function () { - alert("Failed to copy using the Clipboard API. Here's the link: " + url); - }, - ); -}); - qs(".pageAccount button.loadMoreResults")?.on("click", async () => { const offset = DB.getSnapshot()?.results?.length ?? 0; @@ -1236,21 +1205,10 @@ export const page = new Page({ }, beforeShow: async (): Promise => { Skeleton.append("pageAccount", "main"); - const snapshot = DB.getSnapshot(); await ResultFilters.appendDropdowns(update); ResultFilters.updateActive(); await Misc.sleep(0); - testActivityEl = document.querySelector( - ".page.pageAccount .testActivity", - ) as HTMLElement; - - TestActivity.initYearSelector( - testActivityEl, - "current", - snapshot !== undefined ? new Date(snapshot.addedAt).getFullYear() : 2020, - ); - historyTable ??= new SortedTableWithLimit>({ limit: 10, table: qsr(".pageAccount .content .history table"), diff --git a/frontend/src/ts/pages/friends.ts b/frontend/src/ts/pages/friends.ts index 2597b894d1a2..6386ca7ed6b2 100644 --- a/frontend/src/ts/pages/friends.ts +++ b/frontend/src/ts/pages/friends.ts @@ -167,9 +167,7 @@ function updatePendingConnections(): void { (item) => ` - ${item.initiatorName} + ${item.initiatorName}
- ${ + ${ entry.name }
${getHtmlByUserFlags(entry)} diff --git a/frontend/src/ts/pages/leaderboards.ts b/frontend/src/ts/pages/leaderboards.ts index 182e819c1ad6..fcac61fcb67c 100644 --- a/frontend/src/ts/pages/leaderboards.ts +++ b/frontend/src/ts/pages/leaderboards.ts @@ -449,8 +449,8 @@ function buildTableRow(entry: LeaderboardEntry, me = false): HTMLElement {
${entry.name} + entry.name + }" class="entryName" uid=${entry.uid} router-link>${entry.name}
${getHtmlByUserFlags({ ...entry, diff --git a/frontend/src/ts/pages/page.ts b/frontend/src/ts/pages/page.ts index 44032b6cc3f6..77eceecf9cef 100644 --- a/frontend/src/ts/pages/page.ts +++ b/frontend/src/ts/pages/page.ts @@ -67,7 +67,7 @@ export type LoadingOptions = { } ); -type PageProperties = { +export type PageProperties = { id: PageName; display?: string; element: ElementWithUtils; diff --git a/frontend/src/ts/pages/profile-search.ts b/frontend/src/ts/pages/profile-search.ts deleted file mode 100644 index 20941fa608d9..000000000000 --- a/frontend/src/ts/pages/profile-search.ts +++ /dev/null @@ -1,74 +0,0 @@ -import Page from "./page"; -import * as Skeleton from "../utils/skeleton"; -import Ape from "../ape"; -import { ValidatedHtmlInputElement } from "../elements/input-validation"; -import { UserNameSchema, UserProfile } from "@monkeytype/schemas/users"; -import { remoteValidation } from "../utils/remote-validation"; -import * as NavigationEvent from "../observables/navigation-event"; -import { qs, qsr, onDOMReady } from "../utils/dom"; - -let nameInputEl: ValidatedHtmlInputElement | null = null; -let lastProfile: UserProfile | null = null; - -function enableButton(): void { - qs('.page.pageProfileSearch button[type="submit"]')?.enable(); -} - -function disableButton(): void { - qs('.page.pageProfileSearch button[type="submit"]')?.disable(); -} - -export const page = new Page({ - id: "profileSearch", - element: qsr(".page.pageProfileSearch"), - path: "/profile", - afterHide: async (): Promise => { - Skeleton.remove("pageProfileSearch"); - }, - beforeShow: async (): Promise => { - Skeleton.append("pageProfileSearch", "main"); - - nameInputEl ??= new ValidatedHtmlInputElement( - qsr(".page.pageProfileSearch input"), - { - schema: UserNameSchema, - isValid: remoteValidation( - async (name) => Ape.users.getProfile({ params: { uidOrName: name } }), - { - check: (data) => { - lastProfile = data; - return true; - }, - on4xx: () => "Unknown user", - }, - ), - callback: (result) => { - if (result.status === "success") { - enableButton(); - } else { - disableButton(); - lastProfile = null; - } - }, - }, - ); - - nameInputEl.setValue(null); - disableButton(); - }, - afterShow: async (): Promise => { - qs(".page.pageProfileSearch input")?.focus(); - }, -}); - -qs(".page.pageProfileSearch form")?.on("submit", (e) => { - e.preventDefault(); - if (lastProfile === null) return; - NavigationEvent.dispatch(`/profile/${lastProfile.name}`, { - data: lastProfile, - }); -}); - -onDOMReady(() => { - Skeleton.save("pageProfileSearch"); -}); diff --git a/frontend/src/ts/pages/profile.ts b/frontend/src/ts/pages/profile.ts deleted file mode 100644 index abe923649a42..000000000000 --- a/frontend/src/ts/pages/profile.ts +++ /dev/null @@ -1,298 +0,0 @@ -import Ape from "../ape"; -import Page from "./page"; -import * as Profile from "../elements/profile"; -import * as PbTables from "../elements/account/pb-tables"; -import * as Notifications from "../elements/notifications"; -import { checkIfGetParameterExists } from "../utils/misc"; -import * as UserReportModal from "../modals/user-report"; -import * as Skeleton from "../utils/skeleton"; -import { UserProfile } from "@monkeytype/schemas/users"; -import { PersonalBests } from "@monkeytype/schemas/shared"; -import * as TestActivity from "../elements/test-activity"; -import { TestActivityCalendar } from "../elements/test-activity-calendar"; -import { getFirstDayOfTheWeek } from "../utils/date-and-time"; -import { addFriend } from "./friends"; -import { onDOMReady, qs, qsr } from "../utils/dom"; - -const firstDayOfTheWeek = getFirstDayOfTheWeek(); - -function reset(): void { - qs(".page.pageProfile .error")?.hide(); - qs(".page.pageProfile .preloader")?.show(); - qs(".page.pageProfile .profile")?.setHtml(` -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/-
-
-
-
-
-
-
tests started
-
-
-
-
-
tests completed
-
-
-
-
-
time typing
-
-
-
-
- - - - - - -
- - -
-
-
-
All-Time English Leaderboards
-
-
15 seconds
-
-
-
-
-
-
-
60 seconds
-
-
-
-
-
-
-
-
-
-
10 words
-
-
-
-
-
-
-
-
-
25 words
-
-
-
-
-
-
-
-
-
50 words
-
-
-
-
-
-
-
-
-
100 words
-
-
-
-
-
-
-
-
-
-
-
15 seconds
-
-
-
-
-
-
-
-
-
30 seconds
-
-
-
-
-
-
-
-
-
60 seconds
-
-
-
-
-
-
-
-
-
120 seconds
-
-
-
-
-
-
-
- `); - - const testActivityEl = document.querySelector( - ".page.pageProfile .testActivity", - ); - if (testActivityEl !== null) { - TestActivity.clear(testActivityEl as HTMLElement); - } -} - -type UpdateOptions = { - uidOrName?: string; - data?: undefined | UserProfile; -}; - -async function update(options: UpdateOptions): Promise { - const getParamExists = checkIfGetParameterExists("isUid"); - if (options.data) { - qs(".page.pageProfile .preloader")?.hide(); - await Profile.update("profile", options.data); - PbTables.update( - // this cast is fine because pb tables can handle the partial data inside user profiles - options.data.personalBests as unknown as PersonalBests, - true, - ); - } else if (options.uidOrName !== undefined && options.uidOrName !== "") { - const response = await Ape.users.getProfile({ - params: { uidOrName: options.uidOrName }, - query: { isUid: getParamExists }, - }); - - qs(".page.pageProfile .preloader")?.hide(); - - if (response.status === 404) { - const message = getParamExists - ? "User not found" - : `User ${options.uidOrName} not found`; - qs(".page.pageProfile .preloader")?.hide(); - qs(".page.pageProfile .error")?.show(); - qs(".page.pageProfile .error .message")?.setText(message); - } else if (response.status === 200) { - const profile = response.body.data; - window.history.replaceState(null, "", `/profile/${profile.name}`); - await Profile.update("profile", profile); - // this cast is fine because pb tables can handle the partial data inside user profiles - PbTables.update(profile.personalBests as unknown as PersonalBests, true); - - const testActivity = document.querySelector( - ".page.pageProfile .testActivity", - ) as HTMLElement; - - if (profile.testActivity !== undefined) { - const calendar = new TestActivityCalendar( - profile.testActivity.testsByDays, - new Date(profile.testActivity.lastDay), - firstDayOfTheWeek, - ); - TestActivity.init(testActivity, calendar); - const title = testActivity.querySelector(".top .title") as HTMLElement; - title.innerHTML = title?.innerHTML + " in last 12 months"; - } else { - TestActivity.clear(testActivity); - } - } else { - // qs(".page.pageProfile .failedToLoad")?.show(); - Notifications.add("Failed to load profile: " + response.body.message, -1); - return; - } - } else { - Notifications.add("Missing update parameter!", -1); - } -} - -qs(".page.pageProfile")?.onChild("click", ".profile .userReportButton", () => { - const uid = qs(".page.pageProfile .profile")?.getAttribute("uid") ?? ""; - const name = qs(".page.pageProfile .profile")?.getAttribute("name") ?? ""; - const lbOptOut = - (qs(".page.pageProfile .profile")?.getAttribute("lbOptOut") ?? "false") === - "true"; - - void UserReportModal.show({ uid, name, lbOptOut }); -}); - -qs(".page.pageProfile")?.onChild( - "click", - ".profile .addFriendButton", - async () => { - const friendName = - qs(".page.pageProfile .profile")?.getAttribute("name") ?? ""; - - const result = await addFriend(friendName); - - if (result === true) { - Notifications.add(`Request sent to ${friendName}`); - qs(".profile .details .addFriendButton")?.disable(); - } else { - Notifications.add(result, -1); - } - }, -); - -export const page = new Page({ - id: "profile", - element: qsr(".page.pageProfile"), - path: "/profile", - afterHide: async (): Promise => { - Skeleton.remove("pageProfile"); - reset(); - }, - beforeShow: async (options): Promise => { - Skeleton.append("pageProfile", "main"); - const uidOrName = options?.params?.["uidOrName"] ?? ""; - if (uidOrName) { - qs(".page.pageProfile .preloader")?.show(); - qs(".page.pageProfile .search")?.hide(); - qs(".page.pageProfile .content")?.show(); - reset(); - void update({ - uidOrName, - data: options?.data, - }); - } else { - qs(".page.pageProfile .preloader")?.hide(); - qs(".page.pageProfile .search")?.show(); - qs(".page.pageProfile .content")?.hide(); - } - }, -}); - -onDOMReady(() => { - Skeleton.save("pageProfile"); -}); diff --git a/frontend/src/ts/queries/profile.ts b/frontend/src/ts/queries/profile.ts new file mode 100644 index 000000000000..6cfb3c35e4e3 --- /dev/null +++ b/frontend/src/ts/queries/profile.ts @@ -0,0 +1,31 @@ +import { queryOptions } from "@tanstack/solid-query"; +import { baseKey } from "./utils/keys"; +import Ape from "../ape"; + +const queryKeys = { + root: () => baseKey("profiles"), + profile: (username: string) => [...queryKeys.root(), username], +}; + +const staleTime = 1000 * 60 * 60; + +// oxlint-disable-next-line typescript/explicit-function-return-type +export const getUserProfile = (username: string) => + queryOptions({ + queryKey: queryKeys.profile(username), + queryFn: async () => { + const response = await Ape.users.getProfile({ + params: { uidOrName: username }, + query: { isUid: false }, + }); + if (response.status !== 200) { + throw new Error(`Could not fetch profile: ${response.body.message}`); + } + return response.body.data; + }, + staleTime, + retry: (failureCount, error) => { + if (error.message.includes("User not found")) return false; + return failureCount < 3; + }, + }); diff --git a/frontend/src/ts/signals/core.ts b/frontend/src/ts/signals/core.ts index 175691f4316d..ef007615eee5 100644 --- a/frontend/src/ts/signals/core.ts +++ b/frontend/src/ts/signals/core.ts @@ -32,3 +32,7 @@ export const [getIsScreenshotting, setIsScreenshotting] = createSignal(false); export const [getUserId, setUserId] = createSignal(null); export const isLoggedIn = () => getUserId() !== null; + +export const [getSelectedProfileName, setSelectedProfileName] = createSignal< + string | undefined +>(undefined); diff --git a/frontend/src/ts/stores/snapshot.ts b/frontend/src/ts/stores/snapshot.ts new file mode 100644 index 000000000000..8a6c187137f0 --- /dev/null +++ b/frontend/src/ts/stores/snapshot.ts @@ -0,0 +1,31 @@ +import { createStore, reconcile } from "solid-js/store"; +import { Snapshot, SnapshotResult } from "../constants/default-snapshot"; +import { createSignal } from "solid-js"; +import { Mode } from "@monkeytype/schemas/shared"; + +type MiniSnapshot = Omit< + Snapshot, + "results" | "tags" | "presets" | "filterPresets" +>; +const [snapshot, updateSnapshot] = createStore<{ + value: MiniSnapshot | undefined; +}>({ value: undefined }); + +export function setSnapshot(newValue: MiniSnapshot | undefined) { + if (newValue === undefined) { + updateSnapshot("value", undefined); + } else { + updateSnapshot( + "value", + reconcile(structuredClone(newValue), { merge: true }), + ); + } +} + +export function getSnapshot() { + return snapshot.value; +} + +export const [getLastResult, setLastResult] = createSignal< + SnapshotResult | undefined +>(undefined); diff --git a/frontend/src/ts/utils/format.ts b/frontend/src/ts/utils/format.ts index 33eec36832d6..bf50d649b47a 100644 --- a/frontend/src/ts/utils/format.ts +++ b/frontend/src/ts/utils/format.ts @@ -1,6 +1,9 @@ import { get as getTypingSpeedUnit } from "../utils/typing-speed-units"; import * as Numbers from "@monkeytype/util/numbers"; -import { Config as ConfigType } from "@monkeytype/schemas/configs"; +import { + Config as ConfigType, + TypingSpeedUnit, +} from "@monkeytype/schemas/configs"; import Config from "../config"; export type FormatOptions = { @@ -20,9 +23,15 @@ export type FallbackOptions = { fallback?: string; }; +type FormatConfig = Pick< + ConfigType, + "typingSpeedUnit" | "alwaysShowDecimalPlaces" +>; + export class Formatting { - private config: ConfigType; - constructor(config: ConfigType) { + private config: FormatConfig; + + constructor(config: FormatConfig) { this.config = config; } @@ -66,6 +75,10 @@ export class Formatting { return this.number(value, options); } + get typingSpeedUnit(): TypingSpeedUnit { + return this.config.typingSpeedUnit; + } + private number( value: number | null | undefined, formatOptions: FormatOptions, diff --git a/frontend/src/ts/utils/levels.ts b/frontend/src/ts/utils/levels.ts index 1ce16972f002..794b4b18cae7 100644 --- a/frontend/src/ts/utils/levels.ts +++ b/frontend/src/ts/utils/levels.ts @@ -33,7 +33,7 @@ function getTotalXpToReachLevel(level: number): number { return (49 * Math.pow(level, 2) + 53 * level - 102) / 2; } -type XPDetails = { +export type XPDetails = { level: number; levelCurrentXp: number; levelMaxXp: number; diff --git a/frontend/src/ts/utils/misc.ts b/frontend/src/ts/utils/misc.ts index c780b792f6d2..df2143b9783f 100644 --- a/frontend/src/ts/utils/misc.ts +++ b/frontend/src/ts/utils/misc.ts @@ -739,7 +739,8 @@ export function scrollToCenterOrTop(el: HTMLElement | null): void { }); } -export function formatTopPercentage(lbRank: RankAndCount): string { +export function formatTopPercentage(lbRank?: RankAndCount): string { + if (lbRank === undefined) return ""; if (lbRank.rank === undefined) return "-"; if (lbRank.rank === 1) return "GOAT"; return "Top " + roundTo2((lbRank.rank / lbRank.count) * 100) + "%"; diff --git a/frontend/src/ts/utils/skeleton.ts b/frontend/src/ts/utils/skeleton.ts index 3abeeec595fc..bdf6a4875748 100644 --- a/frontend/src/ts/utils/skeleton.ts +++ b/frontend/src/ts/utils/skeleton.ts @@ -7,6 +7,11 @@ export function save(id: string, removeAfter = true): void { if (removeAfter) remove(id); } +export function add(id: string): void { + if (!has(id)) { + save(id); + } +} export function remove(id: string): void { const popup = skeletons.get(id); if (popup) { diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 7875bcf167ae..0e654131cbb3 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -284,10 +284,7 @@ function getCssOptions({ return { devSourcemap: true, postcss: { - plugins: [ - // @ts-expect-error this is fine - autoprefixer({}), - ], + plugins: [autoprefixer({})], }, preprocessorOptions: { scss: { diff --git a/monkeytype.code-workspace b/monkeytype.code-workspace index a7d3a6f28b54..3ddff0b55d9b 100644 --- a/monkeytype.code-workspace +++ b/monkeytype.code-workspace @@ -100,6 +100,7 @@ "dbaeumer.vscode-eslint", "oxc.oxc-vscode", "bradlc.vscode-tailwindcss", + "csstools.postcss", ], }, } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 05e1f32de689..8c39eccefdf9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,7 +19,7 @@ importers: version: link:packages/release '@vitest/coverage-v8': specifier: 4.0.15 - version: 4.0.15(vitest@4.0.15(@types/node@20.5.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1)) + version: 4.0.15(vitest@4.0.15(@types/node@20.5.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)) conventional-changelog: specifier: 6.0.0 version: 6.0.0(conventional-commits-filter@5.0.0) @@ -52,7 +52,7 @@ importers: version: 2.7.5 vitest: specifier: 4.0.15 - version: 4.0.15(@types/node@20.5.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1) + version: 4.0.15(@types/node@20.5.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) backend: dependencies: @@ -224,7 +224,7 @@ importers: version: 10.0.0 '@vitest/coverage-v8': specifier: 4.0.15 - version: 4.0.15(vitest@4.0.15(@types/node@24.9.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1)) + version: 4.0.15(vitest@4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)) concurrently: specifier: 8.2.2 version: 8.2.2 @@ -247,14 +247,14 @@ importers: specifier: 11.11.0 version: 11.11.0 tsx: - specifier: 4.16.2 - version: 4.16.2 + specifier: 4.21.0 + version: 4.21.0 typescript: specifier: 6.0.0-beta version: 6.0.0-beta vitest: specifier: 4.0.15 - version: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1) + version: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) frontend: dependencies: @@ -262,8 +262,8 @@ importers: specifier: 1.2.0 version: 1.2.0 '@leonabcd123/modern-caps-lock': - specifier: 2.0.3 - version: 2.0.3 + specifier: 2.2.2 + version: 2.2.2 '@monkeytype/contracts': specifier: workspace:* version: link:../packages/contracts @@ -383,8 +383,8 @@ importers: version: 0.0.16(zod@3.23.8) devDependencies: '@eslint/json': - specifier: 0.14.0 - version: 0.14.0 + specifier: 1.0.1 + version: 1.0.1 '@fortawesome/fontawesome-free': specifier: 5.15.4 version: 5.15.4 @@ -398,8 +398,8 @@ importers: specifier: 0.8.10 version: 0.8.10(solid-js@1.9.10) '@tailwindcss/vite': - specifier: 4.1.18 - version: 4.1.18(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1)) + specifier: 4.2.1 + version: 4.2.1(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)) '@tanstack/eslint-plugin-query': specifier: 5.91.4 version: 5.91.4(eslint@9.39.1(jiti@2.6.1))(typescript@6.0.0-beta) @@ -438,10 +438,10 @@ importers: version: 5.0.2 '@vitest/coverage-v8': specifier: 4.0.15 - version: 4.0.15(vitest@4.0.15(@types/node@24.9.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1)) + version: 4.0.15(vitest@4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)) autoprefixer: - specifier: 10.4.20 - version: 10.4.20(postcss@8.4.31) + specifier: 10.4.27 + version: 10.4.27(postcss@8.5.6) concurrently: specifier: 8.2.2 version: 8.2.2 @@ -449,8 +449,8 @@ importers: specifier: 9.39.1 version: 9.39.1(jiti@2.6.1) eslint-plugin-compat: - specifier: 6.0.2 - version: 6.0.2(eslint@9.39.1(jiti@2.6.1)) + specifier: 7.0.0 + version: 7.0.0(eslint@9.39.1(jiti@2.6.1)) eslint-plugin-solid: specifier: 0.14.5 version: 0.14.5(eslint@9.39.1(jiti@2.6.1))(typescript@6.0.0-beta) @@ -482,8 +482,8 @@ importers: specifier: 0.14.2 version: 0.14.2 postcss: - specifier: 8.4.31 - version: 8.4.31 + specifier: 8.5.6 + version: 8.5.6 sass: specifier: 1.70.0 version: 1.70.0 @@ -497,8 +497,8 @@ importers: specifier: 4.1.18 version: 4.1.18 tsx: - specifier: 4.16.2 - version: 4.16.2 + specifier: 4.21.0 + version: 4.21.0 typescript: specifier: 6.0.0-beta version: 6.0.0-beta @@ -507,7 +507,7 @@ importers: version: 3.0.0 vite: specifier: 7.1.12 - version: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1) + version: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) vite-bundle-visualizer: specifier: 1.2.1 version: 1.2.1(rollup@2.79.2) @@ -519,19 +519,19 @@ importers: version: 1.1.2 vite-plugin-inspect: specifier: 11.3.3 - version: 11.3.3(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1)) + version: 11.3.3(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)) vite-plugin-minify: specifier: 2.1.0 - version: 2.1.0(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1)) + version: 2.1.0(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)) vite-plugin-pwa: specifier: 1.1.0 - version: 1.1.0(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1))(workbox-build@7.1.1(@types/babel__core@7.20.5))(workbox-window@7.1.0) + version: 1.1.0(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))(workbox-build@7.1.1(@types/babel__core@7.20.5))(workbox-window@7.1.0) vite-plugin-solid: specifier: 2.11.10 - version: 2.11.10(@testing-library/jest-dom@6.9.1)(solid-js@1.9.10)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1)) + version: 2.11.10(@testing-library/jest-dom@6.9.1)(solid-js@1.9.10)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)) vitest: specifier: 4.0.15 - version: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1) + version: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) packages/contracts: dependencies: @@ -562,13 +562,13 @@ importers: version: 0.14.2 tsup: specifier: 8.4.0 - version: 8.4.0(jiti@2.6.1)(postcss@8.5.6)(tsx@4.16.2)(typescript@6.0.0-beta)(yaml@2.8.1) + version: 8.4.0(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(typescript@6.0.0-beta)(yaml@2.8.1) typescript: specifier: 6.0.0-beta version: 6.0.0-beta vitest: specifier: 4.0.15 - version: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1) + version: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) packages/funbox: dependencies: @@ -596,13 +596,13 @@ importers: version: 0.14.2 tsup: specifier: 8.4.0 - version: 8.4.0(jiti@2.6.1)(postcss@8.5.6)(tsx@4.16.2)(typescript@6.0.0-beta)(yaml@2.8.1) + version: 8.4.0(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(typescript@6.0.0-beta)(yaml@2.8.1) typescript: specifier: 6.0.0-beta version: 6.0.0-beta vitest: specifier: 4.0.15 - version: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1) + version: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) packages/oxlint-config: devDependencies: @@ -655,19 +655,19 @@ importers: version: 0.14.2 tsup: specifier: 8.4.0 - version: 8.4.0(jiti@2.6.1)(postcss@8.5.6)(tsx@4.16.2)(typescript@6.0.0-beta)(yaml@2.8.1) + version: 8.4.0(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(typescript@6.0.0-beta)(yaml@2.8.1) typescript: specifier: 6.0.0-beta version: 6.0.0-beta vitest: specifier: 4.0.15 - version: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1) + version: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) packages/tsup-config: dependencies: tsup: specifier: 8.4.0 - version: 8.4.0(jiti@2.6.1)(postcss@8.5.6)(tsx@4.16.2)(typescript@6.0.0-beta)(yaml@2.8.1) + version: 8.4.0(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(typescript@6.0.0-beta)(yaml@2.8.1) devDependencies: '@monkeytype/typescript-config': specifier: workspace:* @@ -703,13 +703,13 @@ importers: version: 0.14.2 tsup: specifier: 8.4.0 - version: 8.4.0(jiti@2.6.1)(postcss@8.5.6)(tsx@4.16.2)(typescript@6.0.0-beta)(yaml@2.8.1) + version: 8.4.0(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(typescript@6.0.0-beta)(yaml@2.8.1) typescript: specifier: 6.0.0-beta version: 6.0.0-beta vitest: specifier: 4.0.15 - version: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1) + version: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) zod: specifier: 3.23.8 version: 3.23.8 @@ -1524,12 +1524,6 @@ packages: engines: {node: '>=4'} deprecated: Support for this package will stop 2025-12-31 - '@esbuild/aix-ppc64@0.21.5': - resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - '@esbuild/aix-ppc64@0.25.0': resolution: {integrity: sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==} engines: {node: '>=18'} @@ -1542,11 +1536,11 @@ packages: cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.21.5': - resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] + '@esbuild/aix-ppc64@0.27.3': + resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] '@esbuild/android-arm64@0.25.0': resolution: {integrity: sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==} @@ -1560,10 +1554,10 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm@0.21.5': - resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} - engines: {node: '>=12'} - cpu: [arm] + '@esbuild/android-arm64@0.27.3': + resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==} + engines: {node: '>=18'} + cpu: [arm64] os: [android] '@esbuild/android-arm@0.25.0': @@ -1578,10 +1572,10 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-x64@0.21.5': - resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} - engines: {node: '>=12'} - cpu: [x64] + '@esbuild/android-arm@0.27.3': + resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==} + engines: {node: '>=18'} + cpu: [arm] os: [android] '@esbuild/android-x64@0.25.0': @@ -1596,11 +1590,11 @@ packages: cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.21.5': - resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] + '@esbuild/android-x64@0.27.3': + resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] '@esbuild/darwin-arm64@0.25.0': resolution: {integrity: sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==} @@ -1614,10 +1608,10 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.21.5': - resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} - engines: {node: '>=12'} - cpu: [x64] + '@esbuild/darwin-arm64@0.27.3': + resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==} + engines: {node: '>=18'} + cpu: [arm64] os: [darwin] '@esbuild/darwin-x64@0.25.0': @@ -1632,11 +1626,11 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.21.5': - resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] + '@esbuild/darwin-x64@0.27.3': + resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] '@esbuild/freebsd-arm64@0.25.0': resolution: {integrity: sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==} @@ -1650,10 +1644,10 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.21.5': - resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} - engines: {node: '>=12'} - cpu: [x64] + '@esbuild/freebsd-arm64@0.27.3': + resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==} + engines: {node: '>=18'} + cpu: [arm64] os: [freebsd] '@esbuild/freebsd-x64@0.25.0': @@ -1668,11 +1662,11 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.21.5': - resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] + '@esbuild/freebsd-x64@0.27.3': + resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] '@esbuild/linux-arm64@0.25.0': resolution: {integrity: sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==} @@ -1686,10 +1680,10 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.21.5': - resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} - engines: {node: '>=12'} - cpu: [arm] + '@esbuild/linux-arm64@0.27.3': + resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==} + engines: {node: '>=18'} + cpu: [arm64] os: [linux] '@esbuild/linux-arm@0.25.0': @@ -1704,10 +1698,10 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.21.5': - resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} - engines: {node: '>=12'} - cpu: [ia32] + '@esbuild/linux-arm@0.27.3': + resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==} + engines: {node: '>=18'} + cpu: [arm] os: [linux] '@esbuild/linux-ia32@0.25.0': @@ -1722,10 +1716,10 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.21.5': - resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} - engines: {node: '>=12'} - cpu: [loong64] + '@esbuild/linux-ia32@0.27.3': + resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==} + engines: {node: '>=18'} + cpu: [ia32] os: [linux] '@esbuild/linux-loong64@0.25.0': @@ -1740,10 +1734,10 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.21.5': - resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} - engines: {node: '>=12'} - cpu: [mips64el] + '@esbuild/linux-loong64@0.27.3': + resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==} + engines: {node: '>=18'} + cpu: [loong64] os: [linux] '@esbuild/linux-mips64el@0.25.0': @@ -1758,10 +1752,10 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.21.5': - resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} - engines: {node: '>=12'} - cpu: [ppc64] + '@esbuild/linux-mips64el@0.27.3': + resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==} + engines: {node: '>=18'} + cpu: [mips64el] os: [linux] '@esbuild/linux-ppc64@0.25.0': @@ -1776,10 +1770,10 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.21.5': - resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} - engines: {node: '>=12'} - cpu: [riscv64] + '@esbuild/linux-ppc64@0.27.3': + resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==} + engines: {node: '>=18'} + cpu: [ppc64] os: [linux] '@esbuild/linux-riscv64@0.25.0': @@ -1794,10 +1788,10 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.21.5': - resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} - engines: {node: '>=12'} - cpu: [s390x] + '@esbuild/linux-riscv64@0.27.3': + resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==} + engines: {node: '>=18'} + cpu: [riscv64] os: [linux] '@esbuild/linux-s390x@0.25.0': @@ -1812,10 +1806,10 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.21.5': - resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} - engines: {node: '>=12'} - cpu: [x64] + '@esbuild/linux-s390x@0.27.3': + resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==} + engines: {node: '>=18'} + cpu: [s390x] os: [linux] '@esbuild/linux-x64@0.25.0': @@ -1830,6 +1824,12 @@ packages: cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.27.3': + resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-arm64@0.25.0': resolution: {integrity: sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==} engines: {node: '>=18'} @@ -1842,10 +1842,10 @@ packages: cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.21.5': - resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} - engines: {node: '>=12'} - cpu: [x64] + '@esbuild/netbsd-arm64@0.27.3': + resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==} + engines: {node: '>=18'} + cpu: [arm64] os: [netbsd] '@esbuild/netbsd-x64@0.25.0': @@ -1860,6 +1860,12 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.27.3': + resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.25.0': resolution: {integrity: sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==} engines: {node: '>=18'} @@ -1872,10 +1878,10 @@ packages: cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.21.5': - resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} - engines: {node: '>=12'} - cpu: [x64] + '@esbuild/openbsd-arm64@0.27.3': + resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==} + engines: {node: '>=18'} + cpu: [arm64] os: [openbsd] '@esbuild/openbsd-x64@0.25.0': @@ -1890,17 +1896,23 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.27.3': + resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openharmony-arm64@0.25.11': resolution: {integrity: sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] - '@esbuild/sunos-x64@0.21.5': - resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] + '@esbuild/openharmony-arm64@0.27.3': + resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] '@esbuild/sunos-x64@0.25.0': resolution: {integrity: sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==} @@ -1914,11 +1926,11 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.21.5': - resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] + '@esbuild/sunos-x64@0.27.3': + resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] '@esbuild/win32-arm64@0.25.0': resolution: {integrity: sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==} @@ -1932,10 +1944,10 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.21.5': - resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} - engines: {node: '>=12'} - cpu: [ia32] + '@esbuild/win32-arm64@0.27.3': + resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==} + engines: {node: '>=18'} + cpu: [arm64] os: [win32] '@esbuild/win32-ia32@0.25.0': @@ -1950,10 +1962,10 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.21.5': - resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} - engines: {node: '>=12'} - cpu: [x64] + '@esbuild/win32-ia32@0.27.3': + resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==} + engines: {node: '>=18'} + cpu: [ia32] os: [win32] '@esbuild/win32-x64@0.25.0': @@ -1968,6 +1980,12 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.27.3': + resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.9.0': resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1996,6 +2014,10 @@ packages: resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/core@1.1.0': + resolution: {integrity: sha512-/nr9K9wkr3P1EzFTdFdMoLuo1PmIxjmwvPozwoSodjNBdefGujXQUF93u1DDZpEaTuDvMsIQddsd35BwtrW9Xw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + '@eslint/eslintrc@3.3.3': resolution: {integrity: sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2004,9 +2026,9 @@ packages: resolution: {integrity: sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/json@0.14.0': - resolution: {integrity: sha512-rvR/EZtvUG3p9uqrSmcDJPYSH7atmWr0RnFWN6m917MAPx82+zQgPUmDu0whPFG6XTyM0vB/hR6c1Q63OaYtCQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/json@1.0.1': + resolution: {integrity: sha512-bE2nGv8/U+uRvQEJWOgCsZCa65XsCBgxyyx/sXtTHVv0kqdauACLzyp7A1C3yNn7pRaWjIt5acxY+TAbSyIJXw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@eslint/object-schema@2.1.7': resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} @@ -2016,6 +2038,10 @@ packages: resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/plugin-kit@0.6.0': + resolution: {integrity: sha512-bIZEUzOI1jkhviX2cp5vNyXQc6olzb2ohewQubuYlMXZ2Q/XjBO0x0XhGPvc9fjSIiUN0vw+0hq53BJ4eQSJKQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + '@exodus/bytes@1.8.0': resolution: {integrity: sha512-8JPn18Bcp8Uo1T82gR8lh2guEOa5KKU/IEKvvdp0sgmi7coPBWf1Doi1EXsGZb2ehc8ym/StJCjffYV+ne7sXQ==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} @@ -2515,8 +2541,8 @@ packages: '@kwsites/promise-deferred@1.1.1': resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==} - '@leonabcd123/modern-caps-lock@2.0.3': - resolution: {integrity: sha512-g4wPe1tHAR7hxOrvUwzxCrxBD+pjI1vEe+STXgsL2jQS95MXxge7h4afKXTLKguOtPc6gqK0Ljle4FLI60rWhw==} + '@leonabcd123/modern-caps-lock@2.2.2': + resolution: {integrity: sha512-0e8onO4ovdeVj9d/1Ddl1q7nq/p+PNsLscp1yOXQLOiyANUCLq41/H8qh5RDZAOs6j9yNzyxlP5h4o8u2HCwFA==} '@mapbox/node-pre-gyp@1.0.11': resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==} @@ -2525,6 +2551,9 @@ packages: '@mdn/browser-compat-data@5.7.6': resolution: {integrity: sha512-7xdrMX0Wk7grrTZQwAoy1GkvPMFoizStUoL+VmtUkAxegbCCec+3FKwOM6yc/uGU5+BEczQHXAlWiqvM8JeENg==} + '@mdn/browser-compat-data@6.1.5': + resolution: {integrity: sha512-PzdZZzRhcXvKB0begee28n5lvwAcinGKYuLZOVxHAZm+n7y01ddEGfdS1ZXRuVcV+ndG6mSEAE8vgudom5UjYg==} + '@mongodb-js/saslprep@1.1.8': resolution: {integrity: sha512-qKwC/M/nNNaKUBMQ0nuzm47b7ZYWQHN3pcXq4IIcoSBc2hOIrflAxJduIvvqmhoz3gR2TacTAs8vlsCVPkiEdQ==} @@ -3468,65 +3497,65 @@ packages: '@surma/rollup-plugin-off-main-thread@2.2.3': resolution: {integrity: sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==} - '@tailwindcss/node@4.1.18': - resolution: {integrity: sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==} + '@tailwindcss/node@4.2.1': + resolution: {integrity: sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg==} - '@tailwindcss/oxide-android-arm64@4.1.18': - resolution: {integrity: sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==} - engines: {node: '>= 10'} + '@tailwindcss/oxide-android-arm64@4.2.1': + resolution: {integrity: sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg==} + engines: {node: '>= 20'} cpu: [arm64] os: [android] - '@tailwindcss/oxide-darwin-arm64@4.1.18': - resolution: {integrity: sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==} - engines: {node: '>= 10'} + '@tailwindcss/oxide-darwin-arm64@4.2.1': + resolution: {integrity: sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw==} + engines: {node: '>= 20'} cpu: [arm64] os: [darwin] - '@tailwindcss/oxide-darwin-x64@4.1.18': - resolution: {integrity: sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==} - engines: {node: '>= 10'} + '@tailwindcss/oxide-darwin-x64@4.2.1': + resolution: {integrity: sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw==} + engines: {node: '>= 20'} cpu: [x64] os: [darwin] - '@tailwindcss/oxide-freebsd-x64@4.1.18': - resolution: {integrity: sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==} - engines: {node: '>= 10'} + '@tailwindcss/oxide-freebsd-x64@4.2.1': + resolution: {integrity: sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA==} + engines: {node: '>= 20'} cpu: [x64] os: [freebsd] - '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18': - resolution: {integrity: sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==} - engines: {node: '>= 10'} + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.1': + resolution: {integrity: sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw==} + engines: {node: '>= 20'} cpu: [arm] os: [linux] - '@tailwindcss/oxide-linux-arm64-gnu@4.1.18': - resolution: {integrity: sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==} - engines: {node: '>= 10'} + '@tailwindcss/oxide-linux-arm64-gnu@4.2.1': + resolution: {integrity: sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ==} + engines: {node: '>= 20'} cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-arm64-musl@4.1.18': - resolution: {integrity: sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==} - engines: {node: '>= 10'} + '@tailwindcss/oxide-linux-arm64-musl@4.2.1': + resolution: {integrity: sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==} + engines: {node: '>= 20'} cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-x64-gnu@4.1.18': - resolution: {integrity: sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==} - engines: {node: '>= 10'} + '@tailwindcss/oxide-linux-x64-gnu@4.2.1': + resolution: {integrity: sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==} + engines: {node: '>= 20'} cpu: [x64] os: [linux] - '@tailwindcss/oxide-linux-x64-musl@4.1.18': - resolution: {integrity: sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==} - engines: {node: '>= 10'} + '@tailwindcss/oxide-linux-x64-musl@4.2.1': + resolution: {integrity: sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==} + engines: {node: '>= 20'} cpu: [x64] os: [linux] - '@tailwindcss/oxide-wasm32-wasi@4.1.18': - resolution: {integrity: sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==} + '@tailwindcss/oxide-wasm32-wasi@4.2.1': + resolution: {integrity: sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==} engines: {node: '>=14.0.0'} cpu: [wasm32] bundledDependencies: @@ -3537,24 +3566,24 @@ packages: - '@emnapi/wasi-threads' - tslib - '@tailwindcss/oxide-win32-arm64-msvc@4.1.18': - resolution: {integrity: sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==} - engines: {node: '>= 10'} + '@tailwindcss/oxide-win32-arm64-msvc@4.2.1': + resolution: {integrity: sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA==} + engines: {node: '>= 20'} cpu: [arm64] os: [win32] - '@tailwindcss/oxide-win32-x64-msvc@4.1.18': - resolution: {integrity: sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==} - engines: {node: '>= 10'} + '@tailwindcss/oxide-win32-x64-msvc@4.2.1': + resolution: {integrity: sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ==} + engines: {node: '>= 20'} cpu: [x64] os: [win32] - '@tailwindcss/oxide@4.1.18': - resolution: {integrity: sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==} - engines: {node: '>= 10'} + '@tailwindcss/oxide@4.2.1': + resolution: {integrity: sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw==} + engines: {node: '>= 20'} - '@tailwindcss/vite@4.1.18': - resolution: {integrity: sha512-jVA+/UpKL1vRLg6Hkao5jldawNmRo7mQYrZtNHMIVpLfLhDml5nMRUo/8MwoX2vNXvnaXNNMedrMfMugAVX1nA==} + '@tailwindcss/vite@4.2.1': + resolution: {integrity: sha512-TBf2sJjYeb28jD2U/OhwdW0bbOsxkWPwQ7SrqGf9sVcoYwZj7rkXljroBO9wKBut9XnmQLXanuDUeqQK0lGg/w==} peerDependencies: vite: ^5.2.0 || ^6 || ^7 @@ -4259,8 +4288,8 @@ packages: resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} engines: {node: '>=8.0.0'} - autoprefixer@10.4.20: - resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} + autoprefixer@10.4.27: + resolution: {integrity: sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: @@ -4431,18 +4460,13 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.23.3: - resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - - browserslist@4.24.4: - resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==} + browserslist@4.28.0: + resolution: {integrity: sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true - browserslist@4.28.0: - resolution: {integrity: sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==} + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -4548,14 +4572,8 @@ packages: camelize@1.0.1: resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} - caniuse-lite@1.0.30001649: - resolution: {integrity: sha512-fJegqZZ0ZX8HOWr6rcafGr72+xcgJKI9oWfDW5DrD7ExUtgZC7a7R7ZYmZqplh7XDocFdGeIFn7roAxhOeYrPQ==} - - caniuse-lite@1.0.30001715: - resolution: {integrity: sha512-7ptkFGMm2OAOgvZpwgA4yjQ5SQbrNVGdRjzH0pBdy1Fasvcr+KAeECmbCAECzTuDuoX0FCY8KzUxjf9+9kfZEw==} - - caniuse-lite@1.0.30001762: - resolution: {integrity: sha512-PxZwGNvH7Ak8WX5iXzoK1KPZttBXNPuaOvI2ZYU7NrlM+d9Ov+TUvlLOBNGzVXAntMSMMlJPd+jY6ovrVjSmUw==} + caniuse-lite@1.0.30001774: + resolution: {integrity: sha512-DDdwPGz99nmIEv216hKSgLD+D4ikHQHjBC/seF98N9CPqRX4M5mSxT9eTV6oyisnJcuzxtZy4n17yKKQYmYQOA==} canvas-confetti@1.5.1: resolution: {integrity: sha512-Ncz+oZJP6OvY7ti4E1slxVlyAV/3g7H7oQtcCDXgwGgARxPnwYY9PW5Oe+I8uvspYNtuHviAdgA0LfcKFWJfpg==} @@ -5382,14 +5400,8 @@ packages: engines: {node: '>=0.10.0'} hasBin: true - electron-to-chromium@1.5.144: - resolution: {integrity: sha512-eJIaMRKeAzxfBSxtjYnoIAw/tdD6VIH6tHBZepZnAbE3Gyqqs5mGN87DvcldPUbVkIljTK8pY0CMcUljP64lfQ==} - - electron-to-chromium@1.5.267: - resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} - - electron-to-chromium@1.5.5: - resolution: {integrity: sha512-QR7/A7ZkMS8tZuoftC/jfqNkZLQO779SSW3YuZHP4eXpj3EffGLFcB/Xu9AAZQzLccTiCV+EmUo3ha4mQ9wnlA==} + electron-to-chromium@1.5.302: + resolution: {integrity: sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -5421,8 +5433,8 @@ packages: resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==} engines: {node: '>=10.13.0'} - enhanced-resolve@5.18.4: - resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==} + enhanced-resolve@5.20.0: + resolution: {integrity: sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ==} engines: {node: '>=10.13.0'} entities@2.2.0: @@ -5487,11 +5499,6 @@ packages: es6-promise@3.3.1: resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==} - esbuild@0.21.5: - resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} - engines: {node: '>=12'} - hasBin: true - esbuild@0.25.0: resolution: {integrity: sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==} engines: {node: '>=18'} @@ -5502,6 +5509,11 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.27.3: + resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -5530,11 +5542,11 @@ packages: engines: {node: '>=6.0'} hasBin: true - eslint-plugin-compat@6.0.2: - resolution: {integrity: sha512-1ME+YfJjmOz1blH0nPZpHgjMGK4kjgEeoYqGCqoBPQ/mGu/dJzdoP0f1C8H2jcWZjzhZjAMccbM/VdXhPORIfA==} + eslint-plugin-compat@7.0.0: + resolution: {integrity: sha512-P5AKzirW/Z6T5XzN+4N7O2HKVyFwfDD9NaUdBNrG9c4652Ef2W77whXDtzJXxPuRXppljJavzBvTLcYpcY0UXw==} engines: {node: '>=18.x'} peerDependencies: - eslint: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 + eslint: ^9.0.0 || ^10.0.0 eslint-plugin-solid@0.14.5: resolution: {integrity: sha512-nfuYK09ah5aJG/oEN6P1qziy1zLgW4PDWe75VNPi4CEFYk1x2AEqwFeQfEPR7gNn0F2jOeqKhx2E+5oNCOBYWQ==} @@ -5749,8 +5761,8 @@ packages: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} - filelist@1.0.4: - resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + filelist@1.0.6: + resolution: {integrity: sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==} filesize@6.4.0: resolution: {integrity: sha512-mjFIpOHC4jbfcTfoh4rkWpI31mF7viw9ikj/JyLoKzqlwG/YsefKfvYlYhdYdg/9mtK2z1AzgN/0LvVQ3zdlSQ==} @@ -5876,8 +5888,8 @@ packages: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} - fraction.js@4.3.7: - resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + fraction.js@5.3.4: + resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} fresh@0.5.2: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} @@ -6912,74 +6924,74 @@ packages: light-my-request@4.12.0: resolution: {integrity: sha512-0y+9VIfJEsPVzK5ArSIJ8Dkxp8QMP7/aCuxCUtG/tr9a2NoOf/snATE/OUc05XUplJCEnRh6gTkH7xh9POt1DQ==} - lightningcss-android-arm64@1.30.2: - resolution: {integrity: sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==} + lightningcss-android-arm64@1.31.1: + resolution: {integrity: sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [android] - lightningcss-darwin-arm64@1.30.2: - resolution: {integrity: sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==} + lightningcss-darwin-arm64@1.31.1: + resolution: {integrity: sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [darwin] - lightningcss-darwin-x64@1.30.2: - resolution: {integrity: sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==} + lightningcss-darwin-x64@1.31.1: + resolution: {integrity: sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [darwin] - lightningcss-freebsd-x64@1.30.2: - resolution: {integrity: sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==} + lightningcss-freebsd-x64@1.31.1: + resolution: {integrity: sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [freebsd] - lightningcss-linux-arm-gnueabihf@1.30.2: - resolution: {integrity: sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==} + lightningcss-linux-arm-gnueabihf@1.31.1: + resolution: {integrity: sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==} engines: {node: '>= 12.0.0'} cpu: [arm] os: [linux] - lightningcss-linux-arm64-gnu@1.30.2: - resolution: {integrity: sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==} + lightningcss-linux-arm64-gnu@1.31.1: + resolution: {integrity: sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - lightningcss-linux-arm64-musl@1.30.2: - resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==} + lightningcss-linux-arm64-musl@1.31.1: + resolution: {integrity: sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - lightningcss-linux-x64-gnu@1.30.2: - resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==} + lightningcss-linux-x64-gnu@1.31.1: + resolution: {integrity: sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - lightningcss-linux-x64-musl@1.30.2: - resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==} + lightningcss-linux-x64-musl@1.31.1: + resolution: {integrity: sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - lightningcss-win32-arm64-msvc@1.30.2: - resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==} + lightningcss-win32-arm64-msvc@1.31.1: + resolution: {integrity: sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [win32] - lightningcss-win32-x64-msvc@1.30.2: - resolution: {integrity: sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==} + lightningcss-win32-x64-msvc@1.31.1: + resolution: {integrity: sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [win32] - lightningcss@1.30.2: - resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==} + lightningcss@1.31.1: + resolution: {integrity: sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==} engines: {node: '>= 12.0.0'} lilconfig@2.1.0: @@ -7354,6 +7366,10 @@ packages: resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} engines: {node: '>=10'} + minimatch@5.1.9: + resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} + engines: {node: '>=10'} + minimatch@6.2.0: resolution: {integrity: sha512-sauLxniAmvnhhRjFwPNnJKaPFYyddAgbYdeUpHULtCT/GhzdCx/MDNy+Y40lBxTQUrMzDE8e0S43Z5uqfO0REg==} engines: {node: '>=10'} @@ -7653,11 +7669,6 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - nanoid@3.3.7: - resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -7738,12 +7749,6 @@ packages: node-readfiles@0.2.0: resolution: {integrity: sha512-SU00ZarexNlE4Rjdm83vglt5Y9yiQ+XI1XpflWlb7q7UTN1JUItm69xMeiQCTxtTfnzt+83T8Cx+vI2ED++VDA==} - node-releases@2.0.18: - resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} - - node-releases@2.0.19: - resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} - node-releases@2.0.27: resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} @@ -7785,10 +7790,6 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} - normalize-range@0.1.2: - resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} - engines: {node: '>=0.10.0'} - normalize.css@8.0.1: resolution: {integrity: sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==} @@ -8146,9 +8147,6 @@ packages: pgpass@1.0.5: resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} - picocolors@1.0.1: - resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} - picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -8219,10 +8217,6 @@ packages: peerDependencies: postcss: ^8.2.9 - postcss@8.4.31: - resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} - engines: {node: ^10 || ^12 || >=14} - postcss@8.4.38: resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} engines: {node: ^10 || ^12 || >=14} @@ -8989,10 +8983,6 @@ packages: sort-any@2.0.0: resolution: {integrity: sha512-T9JoiDewQEmWcnmPn/s9h/PH9t3d/LSWi0RgVmXSuDYeZXTZOZ1/wrK2PHaptuR1VXe3clLLt0pD6sgVOwjNEA==} - source-map-js@1.2.0: - resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} - engines: {node: '>=0.10.0'} - source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -9294,10 +9284,17 @@ packages: tailwindcss@4.1.18: resolution: {integrity: sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==} + tailwindcss@4.2.1: + resolution: {integrity: sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==} + tapable@2.2.1: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} + tapable@2.3.0: + resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} + engines: {node: '>=6'} + tar-fs@2.1.4: resolution: {integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==} @@ -9560,8 +9557,8 @@ packages: typescript: optional: true - tsx@4.16.2: - resolution: {integrity: sha512-C1uWweJDgdtX2x600HjaFaucXTilT7tgUZHbOE4+ypskZ1OP8CRCSDkCxG6Vya9EwaFIVagWwpaVAn5wzypaqQ==} + tsx@4.21.0: + resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} engines: {node: '>=18.0.0'} hasBin: true @@ -9782,18 +9779,6 @@ packages: resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==} engines: {node: '>=4'} - update-browserslist-db@1.1.0: - resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - - update-browserslist-db@1.1.3: - resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - update-browserslist-db@1.2.3: resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} hasBin: true @@ -10487,7 +10472,7 @@ snapshots: dependencies: '@babel/compat-data': 7.25.2 '@babel/helper-validator-option': 7.24.8 - browserslist: 4.24.4 + browserslist: 4.28.0 lru-cache: 5.1.1 semver: 6.3.1 @@ -10503,7 +10488,7 @@ snapshots: dependencies: '@babel/compat-data': 7.28.6 '@babel/helper-validator-option': 7.27.1 - browserslist: 4.28.0 + browserslist: 4.28.1 lru-cache: 5.1.1 semver: 6.3.1 @@ -10554,7 +10539,7 @@ snapshots: '@babel/helper-module-imports@7.24.7': dependencies: '@babel/traverse': 7.25.2 - '@babel/types': 7.28.5 + '@babel/types': 7.28.6 transitivePeerDependencies: - supports-color @@ -10629,7 +10614,7 @@ snapshots: '@babel/helper-simple-access@7.24.7': dependencies: '@babel/traverse': 7.25.2 - '@babel/types': 7.28.5 + '@babel/types': 7.28.6 transitivePeerDependencies: - supports-color @@ -11433,16 +11418,13 @@ snapshots: to-pascal-case: 1.0.0 unescape-js: 1.1.4 - '@esbuild/aix-ppc64@0.21.5': - optional: true - '@esbuild/aix-ppc64@0.25.0': optional: true '@esbuild/aix-ppc64@0.25.11': optional: true - '@esbuild/android-arm64@0.21.5': + '@esbuild/aix-ppc64@0.27.3': optional: true '@esbuild/android-arm64@0.25.0': @@ -11451,7 +11433,7 @@ snapshots: '@esbuild/android-arm64@0.25.11': optional: true - '@esbuild/android-arm@0.21.5': + '@esbuild/android-arm64@0.27.3': optional: true '@esbuild/android-arm@0.25.0': @@ -11460,7 +11442,7 @@ snapshots: '@esbuild/android-arm@0.25.11': optional: true - '@esbuild/android-x64@0.21.5': + '@esbuild/android-arm@0.27.3': optional: true '@esbuild/android-x64@0.25.0': @@ -11469,7 +11451,7 @@ snapshots: '@esbuild/android-x64@0.25.11': optional: true - '@esbuild/darwin-arm64@0.21.5': + '@esbuild/android-x64@0.27.3': optional: true '@esbuild/darwin-arm64@0.25.0': @@ -11478,7 +11460,7 @@ snapshots: '@esbuild/darwin-arm64@0.25.11': optional: true - '@esbuild/darwin-x64@0.21.5': + '@esbuild/darwin-arm64@0.27.3': optional: true '@esbuild/darwin-x64@0.25.0': @@ -11487,7 +11469,7 @@ snapshots: '@esbuild/darwin-x64@0.25.11': optional: true - '@esbuild/freebsd-arm64@0.21.5': + '@esbuild/darwin-x64@0.27.3': optional: true '@esbuild/freebsd-arm64@0.25.0': @@ -11496,7 +11478,7 @@ snapshots: '@esbuild/freebsd-arm64@0.25.11': optional: true - '@esbuild/freebsd-x64@0.21.5': + '@esbuild/freebsd-arm64@0.27.3': optional: true '@esbuild/freebsd-x64@0.25.0': @@ -11505,7 +11487,7 @@ snapshots: '@esbuild/freebsd-x64@0.25.11': optional: true - '@esbuild/linux-arm64@0.21.5': + '@esbuild/freebsd-x64@0.27.3': optional: true '@esbuild/linux-arm64@0.25.0': @@ -11514,7 +11496,7 @@ snapshots: '@esbuild/linux-arm64@0.25.11': optional: true - '@esbuild/linux-arm@0.21.5': + '@esbuild/linux-arm64@0.27.3': optional: true '@esbuild/linux-arm@0.25.0': @@ -11523,7 +11505,7 @@ snapshots: '@esbuild/linux-arm@0.25.11': optional: true - '@esbuild/linux-ia32@0.21.5': + '@esbuild/linux-arm@0.27.3': optional: true '@esbuild/linux-ia32@0.25.0': @@ -11532,7 +11514,7 @@ snapshots: '@esbuild/linux-ia32@0.25.11': optional: true - '@esbuild/linux-loong64@0.21.5': + '@esbuild/linux-ia32@0.27.3': optional: true '@esbuild/linux-loong64@0.25.0': @@ -11541,7 +11523,7 @@ snapshots: '@esbuild/linux-loong64@0.25.11': optional: true - '@esbuild/linux-mips64el@0.21.5': + '@esbuild/linux-loong64@0.27.3': optional: true '@esbuild/linux-mips64el@0.25.0': @@ -11550,7 +11532,7 @@ snapshots: '@esbuild/linux-mips64el@0.25.11': optional: true - '@esbuild/linux-ppc64@0.21.5': + '@esbuild/linux-mips64el@0.27.3': optional: true '@esbuild/linux-ppc64@0.25.0': @@ -11559,7 +11541,7 @@ snapshots: '@esbuild/linux-ppc64@0.25.11': optional: true - '@esbuild/linux-riscv64@0.21.5': + '@esbuild/linux-ppc64@0.27.3': optional: true '@esbuild/linux-riscv64@0.25.0': @@ -11568,7 +11550,7 @@ snapshots: '@esbuild/linux-riscv64@0.25.11': optional: true - '@esbuild/linux-s390x@0.21.5': + '@esbuild/linux-riscv64@0.27.3': optional: true '@esbuild/linux-s390x@0.25.0': @@ -11577,7 +11559,7 @@ snapshots: '@esbuild/linux-s390x@0.25.11': optional: true - '@esbuild/linux-x64@0.21.5': + '@esbuild/linux-s390x@0.27.3': optional: true '@esbuild/linux-x64@0.25.0': @@ -11586,13 +11568,16 @@ snapshots: '@esbuild/linux-x64@0.25.11': optional: true + '@esbuild/linux-x64@0.27.3': + optional: true + '@esbuild/netbsd-arm64@0.25.0': optional: true '@esbuild/netbsd-arm64@0.25.11': optional: true - '@esbuild/netbsd-x64@0.21.5': + '@esbuild/netbsd-arm64@0.27.3': optional: true '@esbuild/netbsd-x64@0.25.0': @@ -11601,13 +11586,16 @@ snapshots: '@esbuild/netbsd-x64@0.25.11': optional: true + '@esbuild/netbsd-x64@0.27.3': + optional: true + '@esbuild/openbsd-arm64@0.25.0': optional: true '@esbuild/openbsd-arm64@0.25.11': optional: true - '@esbuild/openbsd-x64@0.21.5': + '@esbuild/openbsd-arm64@0.27.3': optional: true '@esbuild/openbsd-x64@0.25.0': @@ -11616,10 +11604,13 @@ snapshots: '@esbuild/openbsd-x64@0.25.11': optional: true + '@esbuild/openbsd-x64@0.27.3': + optional: true + '@esbuild/openharmony-arm64@0.25.11': optional: true - '@esbuild/sunos-x64@0.21.5': + '@esbuild/openharmony-arm64@0.27.3': optional: true '@esbuild/sunos-x64@0.25.0': @@ -11628,7 +11619,7 @@ snapshots: '@esbuild/sunos-x64@0.25.11': optional: true - '@esbuild/win32-arm64@0.21.5': + '@esbuild/sunos-x64@0.27.3': optional: true '@esbuild/win32-arm64@0.25.0': @@ -11637,7 +11628,7 @@ snapshots: '@esbuild/win32-arm64@0.25.11': optional: true - '@esbuild/win32-ia32@0.21.5': + '@esbuild/win32-arm64@0.27.3': optional: true '@esbuild/win32-ia32@0.25.0': @@ -11646,7 +11637,7 @@ snapshots: '@esbuild/win32-ia32@0.25.11': optional: true - '@esbuild/win32-x64@0.21.5': + '@esbuild/win32-ia32@0.27.3': optional: true '@esbuild/win32-x64@0.25.0': @@ -11655,6 +11646,9 @@ snapshots: '@esbuild/win32-x64@0.25.11': optional: true + '@esbuild/win32-x64@0.27.3': + optional: true + '@eslint-community/eslint-utils@4.9.0(eslint@9.39.1(jiti@2.6.1))': dependencies: eslint: 9.39.1(jiti@2.6.1) @@ -11683,6 +11677,10 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 + '@eslint/core@1.1.0': + dependencies: + '@types/json-schema': 7.0.15 + '@eslint/eslintrc@3.3.3': dependencies: ajv: 6.12.6 @@ -11699,10 +11697,10 @@ snapshots: '@eslint/js@9.39.1': {} - '@eslint/json@0.14.0': + '@eslint/json@1.0.1': dependencies: - '@eslint/core': 0.17.0 - '@eslint/plugin-kit': 0.4.1 + '@eslint/core': 1.1.0 + '@eslint/plugin-kit': 0.6.0 '@humanwhocodes/momoa': 3.3.10 natural-compare: 1.4.0 @@ -11713,6 +11711,11 @@ snapshots: '@eslint/core': 0.17.0 levn: 0.4.1 + '@eslint/plugin-kit@0.6.0': + dependencies: + '@eslint/core': 1.1.0 + levn: 0.4.1 + '@exodus/bytes@1.8.0': {} '@exodus/schemasafe@1.3.0': {} @@ -12443,7 +12446,7 @@ snapshots: '@kwsites/promise-deferred@1.1.1': {} - '@leonabcd123/modern-caps-lock@2.0.3': {} + '@leonabcd123/modern-caps-lock@2.2.2': {} '@mapbox/node-pre-gyp@1.0.11(encoding@0.1.13)': dependencies: @@ -12462,6 +12465,8 @@ snapshots: '@mdn/browser-compat-data@5.7.6': {} + '@mdn/browser-compat-data@6.1.5': {} + '@mongodb-js/saslprep@1.1.8': dependencies: sparse-bitfield: 3.0.3 @@ -13272,73 +13277,73 @@ snapshots: magic-string: 0.25.9 string.prototype.matchall: 4.0.12 - '@tailwindcss/node@4.1.18': + '@tailwindcss/node@4.2.1': dependencies: '@jridgewell/remapping': 2.3.5 - enhanced-resolve: 5.18.4 + enhanced-resolve: 5.20.0 jiti: 2.6.1 - lightningcss: 1.30.2 + lightningcss: 1.31.1 magic-string: 0.30.21 source-map-js: 1.2.1 - tailwindcss: 4.1.18 + tailwindcss: 4.2.1 - '@tailwindcss/oxide-android-arm64@4.1.18': + '@tailwindcss/oxide-android-arm64@4.2.1': optional: true - '@tailwindcss/oxide-darwin-arm64@4.1.18': + '@tailwindcss/oxide-darwin-arm64@4.2.1': optional: true - '@tailwindcss/oxide-darwin-x64@4.1.18': + '@tailwindcss/oxide-darwin-x64@4.2.1': optional: true - '@tailwindcss/oxide-freebsd-x64@4.1.18': + '@tailwindcss/oxide-freebsd-x64@4.2.1': optional: true - '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18': + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.1': optional: true - '@tailwindcss/oxide-linux-arm64-gnu@4.1.18': + '@tailwindcss/oxide-linux-arm64-gnu@4.2.1': optional: true - '@tailwindcss/oxide-linux-arm64-musl@4.1.18': + '@tailwindcss/oxide-linux-arm64-musl@4.2.1': optional: true - '@tailwindcss/oxide-linux-x64-gnu@4.1.18': + '@tailwindcss/oxide-linux-x64-gnu@4.2.1': optional: true - '@tailwindcss/oxide-linux-x64-musl@4.1.18': + '@tailwindcss/oxide-linux-x64-musl@4.2.1': optional: true - '@tailwindcss/oxide-wasm32-wasi@4.1.18': + '@tailwindcss/oxide-wasm32-wasi@4.2.1': optional: true - '@tailwindcss/oxide-win32-arm64-msvc@4.1.18': + '@tailwindcss/oxide-win32-arm64-msvc@4.2.1': optional: true - '@tailwindcss/oxide-win32-x64-msvc@4.1.18': + '@tailwindcss/oxide-win32-x64-msvc@4.2.1': optional: true - '@tailwindcss/oxide@4.1.18': + '@tailwindcss/oxide@4.2.1': optionalDependencies: - '@tailwindcss/oxide-android-arm64': 4.1.18 - '@tailwindcss/oxide-darwin-arm64': 4.1.18 - '@tailwindcss/oxide-darwin-x64': 4.1.18 - '@tailwindcss/oxide-freebsd-x64': 4.1.18 - '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.18 - '@tailwindcss/oxide-linux-arm64-gnu': 4.1.18 - '@tailwindcss/oxide-linux-arm64-musl': 4.1.18 - '@tailwindcss/oxide-linux-x64-gnu': 4.1.18 - '@tailwindcss/oxide-linux-x64-musl': 4.1.18 - '@tailwindcss/oxide-wasm32-wasi': 4.1.18 - '@tailwindcss/oxide-win32-arm64-msvc': 4.1.18 - '@tailwindcss/oxide-win32-x64-msvc': 4.1.18 - - '@tailwindcss/vite@4.1.18(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1))': - dependencies: - '@tailwindcss/node': 4.1.18 - '@tailwindcss/oxide': 4.1.18 - tailwindcss: 4.1.18 - vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1) + '@tailwindcss/oxide-android-arm64': 4.2.1 + '@tailwindcss/oxide-darwin-arm64': 4.2.1 + '@tailwindcss/oxide-darwin-x64': 4.2.1 + '@tailwindcss/oxide-freebsd-x64': 4.2.1 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.1 + '@tailwindcss/oxide-linux-arm64-gnu': 4.2.1 + '@tailwindcss/oxide-linux-arm64-musl': 4.2.1 + '@tailwindcss/oxide-linux-x64-gnu': 4.2.1 + '@tailwindcss/oxide-linux-x64-musl': 4.2.1 + '@tailwindcss/oxide-wasm32-wasi': 4.2.1 + '@tailwindcss/oxide-win32-arm64-msvc': 4.2.1 + '@tailwindcss/oxide-win32-x64-msvc': 4.2.1 + + '@tailwindcss/vite@4.2.1(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))': + dependencies: + '@tailwindcss/node': 4.2.1 + '@tailwindcss/oxide': 4.2.1 + tailwindcss: 4.2.1 + vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) '@tanstack/eslint-plugin-query@5.91.4(eslint@9.39.1(jiti@2.6.1))(typescript@6.0.0-beta)': dependencies: @@ -13770,7 +13775,7 @@ snapshots: '@typescript-eslint/types': 8.52.0 eslint-visitor-keys: 4.2.1 - '@vitest/coverage-v8@4.0.15(vitest@4.0.15(@types/node@20.5.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1))': + '@vitest/coverage-v8@4.0.15(vitest@4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))': dependencies: '@bcoe/v8-coverage': 1.0.2 '@vitest/utils': 4.0.15 @@ -13783,11 +13788,11 @@ snapshots: obug: 2.1.1 std-env: 3.10.0 tinyrainbow: 3.0.3 - vitest: 4.0.15(@types/node@20.5.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1) + vitest: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) transitivePeerDependencies: - supports-color - '@vitest/coverage-v8@4.0.15(vitest@4.0.15(@types/node@24.9.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1))': + '@vitest/coverage-v8@4.0.15(vitest@4.0.15(@types/node@20.5.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))': dependencies: '@bcoe/v8-coverage': 1.0.2 '@vitest/utils': 4.0.15 @@ -13800,7 +13805,7 @@ snapshots: obug: 2.1.1 std-env: 3.10.0 tinyrainbow: 3.0.3 - vitest: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1) + vitest: 4.0.15(@types/node@20.5.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) transitivePeerDependencies: - supports-color @@ -13813,13 +13818,21 @@ snapshots: chai: 6.2.1 tinyrainbow: 3.0.3 - '@vitest/mocker@4.0.15(vite@7.1.12(@types/node@20.5.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1))': + '@vitest/mocker@4.0.15(vite@7.1.12(@types/node@20.5.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))': dependencies: '@vitest/spy': 4.0.15 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.1.12(@types/node@20.5.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1) + vite: 7.1.12(@types/node@20.5.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) + + '@vitest/mocker@4.0.15(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))': + dependencies: + '@vitest/spy': 4.0.15 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) '@vitest/pretty-format@4.0.15': dependencies: @@ -13845,7 +13858,7 @@ snapshots: '@vue/compiler-core@3.4.37': dependencies: - '@babel/parser': 7.28.5 + '@babel/parser': 7.28.6 '@vue/shared': 3.4.37 entities: 5.0.0 estree-walker: 2.0.2 @@ -13858,7 +13871,7 @@ snapshots: '@vue/compiler-sfc@3.4.37': dependencies: - '@babel/parser': 7.28.5 + '@babel/parser': 7.28.6 '@vue/compiler-core': 3.4.37 '@vue/compiler-dom': 3.4.37 '@vue/compiler-ssr': 3.4.37 @@ -14119,14 +14132,13 @@ snapshots: atomic-sleep@1.0.0: {} - autoprefixer@10.4.20(postcss@8.4.31): + autoprefixer@10.4.27(postcss@8.5.6): dependencies: - browserslist: 4.23.3 - caniuse-lite: 1.0.30001649 - fraction.js: 4.3.7 - normalize-range: 0.1.2 - picocolors: 1.0.1 - postcss: 8.4.31 + browserslist: 4.28.1 + caniuse-lite: 1.0.30001774 + fraction.js: 5.3.4 + picocolors: 1.1.1 + postcss: 8.5.6 postcss-value-parser: 4.2.0 available-typed-arrays@1.0.7: @@ -14350,28 +14362,22 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.23.3: - dependencies: - caniuse-lite: 1.0.30001649 - electron-to-chromium: 1.5.5 - node-releases: 2.0.18 - update-browserslist-db: 1.1.0(browserslist@4.23.3) - - browserslist@4.24.4: - dependencies: - caniuse-lite: 1.0.30001715 - electron-to-chromium: 1.5.144 - node-releases: 2.0.19 - update-browserslist-db: 1.1.3(browserslist@4.24.4) - browserslist@4.28.0: dependencies: baseline-browser-mapping: 2.9.11 - caniuse-lite: 1.0.30001762 - electron-to-chromium: 1.5.267 + caniuse-lite: 1.0.30001774 + electron-to-chromium: 1.5.302 node-releases: 2.0.27 update-browserslist-db: 1.2.3(browserslist@4.28.0) + browserslist@4.28.1: + dependencies: + baseline-browser-mapping: 2.9.11 + caniuse-lite: 1.0.30001774 + electron-to-chromium: 1.5.302 + node-releases: 2.0.27 + update-browserslist-db: 1.2.3(browserslist@4.28.1) + bson@6.8.0: {} buffer-crc32@1.0.0: {} @@ -14491,11 +14497,7 @@ snapshots: camelize@1.0.1: {} - caniuse-lite@1.0.30001649: {} - - caniuse-lite@1.0.30001715: {} - - caniuse-lite@1.0.30001762: {} + caniuse-lite@1.0.30001774: {} canvas-confetti@1.5.1: {} @@ -14890,7 +14892,7 @@ snapshots: core-js-compat@3.47.0: dependencies: - browserslist: 4.28.0 + browserslist: 4.28.1 core-js@3.37.1: {} @@ -15339,11 +15341,7 @@ snapshots: dependencies: jake: 10.9.4 - electron-to-chromium@1.5.144: {} - - electron-to-chromium@1.5.267: {} - - electron-to-chromium@1.5.5: {} + electron-to-chromium@1.5.302: {} emoji-regex@8.0.0: {} @@ -15371,10 +15369,10 @@ snapshots: graceful-fs: 4.2.11 tapable: 2.2.1 - enhanced-resolve@5.18.4: + enhanced-resolve@5.20.0: dependencies: graceful-fs: 4.2.11 - tapable: 2.2.1 + tapable: 2.3.0 entities@2.2.0: {} @@ -15480,32 +15478,6 @@ snapshots: es6-promise@3.3.1: {} - esbuild@0.21.5: - optionalDependencies: - '@esbuild/aix-ppc64': 0.21.5 - '@esbuild/android-arm': 0.21.5 - '@esbuild/android-arm64': 0.21.5 - '@esbuild/android-x64': 0.21.5 - '@esbuild/darwin-arm64': 0.21.5 - '@esbuild/darwin-x64': 0.21.5 - '@esbuild/freebsd-arm64': 0.21.5 - '@esbuild/freebsd-x64': 0.21.5 - '@esbuild/linux-arm': 0.21.5 - '@esbuild/linux-arm64': 0.21.5 - '@esbuild/linux-ia32': 0.21.5 - '@esbuild/linux-loong64': 0.21.5 - '@esbuild/linux-mips64el': 0.21.5 - '@esbuild/linux-ppc64': 0.21.5 - '@esbuild/linux-riscv64': 0.21.5 - '@esbuild/linux-s390x': 0.21.5 - '@esbuild/linux-x64': 0.21.5 - '@esbuild/netbsd-x64': 0.21.5 - '@esbuild/openbsd-x64': 0.21.5 - '@esbuild/sunos-x64': 0.21.5 - '@esbuild/win32-arm64': 0.21.5 - '@esbuild/win32-ia32': 0.21.5 - '@esbuild/win32-x64': 0.21.5 - esbuild@0.25.0: optionalDependencies: '@esbuild/aix-ppc64': 0.25.0 @@ -15563,6 +15535,35 @@ snapshots: '@esbuild/win32-ia32': 0.25.11 '@esbuild/win32-x64': 0.25.11 + esbuild@0.27.3: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.3 + '@esbuild/android-arm': 0.27.3 + '@esbuild/android-arm64': 0.27.3 + '@esbuild/android-x64': 0.27.3 + '@esbuild/darwin-arm64': 0.27.3 + '@esbuild/darwin-x64': 0.27.3 + '@esbuild/freebsd-arm64': 0.27.3 + '@esbuild/freebsd-x64': 0.27.3 + '@esbuild/linux-arm': 0.27.3 + '@esbuild/linux-arm64': 0.27.3 + '@esbuild/linux-ia32': 0.27.3 + '@esbuild/linux-loong64': 0.27.3 + '@esbuild/linux-mips64el': 0.27.3 + '@esbuild/linux-ppc64': 0.27.3 + '@esbuild/linux-riscv64': 0.27.3 + '@esbuild/linux-s390x': 0.27.3 + '@esbuild/linux-x64': 0.27.3 + '@esbuild/netbsd-arm64': 0.27.3 + '@esbuild/netbsd-x64': 0.27.3 + '@esbuild/openbsd-arm64': 0.27.3 + '@esbuild/openbsd-x64': 0.27.3 + '@esbuild/openharmony-arm64': 0.27.3 + '@esbuild/sunos-x64': 0.27.3 + '@esbuild/win32-arm64': 0.27.3 + '@esbuild/win32-ia32': 0.27.3 + '@esbuild/win32-x64': 0.27.3 + escalade@3.2.0: {} escape-goat@2.1.1: {} @@ -15583,17 +15584,16 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-plugin-compat@6.0.2(eslint@9.39.1(jiti@2.6.1)): + eslint-plugin-compat@7.0.0(eslint@9.39.1(jiti@2.6.1)): dependencies: - '@mdn/browser-compat-data': 5.7.6 + '@mdn/browser-compat-data': 6.1.5 ast-metadata-inferer: 0.8.1 - browserslist: 4.24.4 - caniuse-lite: 1.0.30001715 + browserslist: 4.28.0 eslint: 9.39.1(jiti@2.6.1) find-up: 5.0.0 globals: 15.15.0 lodash.memoize: 4.1.2 - semver: 7.6.3 + semver: 7.7.3 eslint-plugin-solid@0.14.5(eslint@9.39.1(jiti@2.6.1))(typescript@6.0.0-beta): dependencies: @@ -15929,9 +15929,9 @@ snapshots: dependencies: flat-cache: 4.0.1 - filelist@1.0.4: + filelist@1.0.6: dependencies: - minimatch: 5.1.6 + minimatch: 5.1.9 filesize@6.4.0: {} @@ -16202,7 +16202,7 @@ snapshots: forwarded@0.2.0: {} - fraction.js@4.3.7: {} + fraction.js@5.3.4: {} fresh@0.5.2: {} @@ -17109,7 +17109,7 @@ snapshots: jake@10.9.4: dependencies: async: 3.2.6 - filelist: 1.0.4 + filelist: 1.0.6 picocolors: 1.1.1 jiti@1.19.1: {} @@ -17366,54 +17366,54 @@ snapshots: process-warning: 1.0.0 set-cookie-parser: 2.6.0 - lightningcss-android-arm64@1.30.2: + lightningcss-android-arm64@1.31.1: optional: true - lightningcss-darwin-arm64@1.30.2: + lightningcss-darwin-arm64@1.31.1: optional: true - lightningcss-darwin-x64@1.30.2: + lightningcss-darwin-x64@1.31.1: optional: true - lightningcss-freebsd-x64@1.30.2: + lightningcss-freebsd-x64@1.31.1: optional: true - lightningcss-linux-arm-gnueabihf@1.30.2: + lightningcss-linux-arm-gnueabihf@1.31.1: optional: true - lightningcss-linux-arm64-gnu@1.30.2: + lightningcss-linux-arm64-gnu@1.31.1: optional: true - lightningcss-linux-arm64-musl@1.30.2: + lightningcss-linux-arm64-musl@1.31.1: optional: true - lightningcss-linux-x64-gnu@1.30.2: + lightningcss-linux-x64-gnu@1.31.1: optional: true - lightningcss-linux-x64-musl@1.30.2: + lightningcss-linux-x64-musl@1.31.1: optional: true - lightningcss-win32-arm64-msvc@1.30.2: + lightningcss-win32-arm64-msvc@1.31.1: optional: true - lightningcss-win32-x64-msvc@1.30.2: + lightningcss-win32-x64-msvc@1.31.1: optional: true - lightningcss@1.30.2: + lightningcss@1.31.1: dependencies: detect-libc: 2.0.3 optionalDependencies: - lightningcss-android-arm64: 1.30.2 - lightningcss-darwin-arm64: 1.30.2 - lightningcss-darwin-x64: 1.30.2 - lightningcss-freebsd-x64: 1.30.2 - lightningcss-linux-arm-gnueabihf: 1.30.2 - lightningcss-linux-arm64-gnu: 1.30.2 - lightningcss-linux-arm64-musl: 1.30.2 - lightningcss-linux-x64-gnu: 1.30.2 - lightningcss-linux-x64-musl: 1.30.2 - lightningcss-win32-arm64-msvc: 1.30.2 - lightningcss-win32-x64-msvc: 1.30.2 + lightningcss-android-arm64: 1.31.1 + lightningcss-darwin-arm64: 1.31.1 + lightningcss-darwin-x64: 1.31.1 + lightningcss-freebsd-x64: 1.31.1 + lightningcss-linux-arm-gnueabihf: 1.31.1 + lightningcss-linux-arm64-gnu: 1.31.1 + lightningcss-linux-arm64-musl: 1.31.1 + lightningcss-linux-x64-gnu: 1.31.1 + lightningcss-linux-x64-musl: 1.31.1 + lightningcss-win32-arm64-msvc: 1.31.1 + lightningcss-win32-x64-msvc: 1.31.1 lilconfig@2.1.0: {} @@ -17624,8 +17624,8 @@ snapshots: magicast@0.5.1: dependencies: - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 + '@babel/parser': 7.28.6 + '@babel/types': 7.28.6 source-map-js: 1.2.1 make-dir@3.1.0: @@ -17762,6 +17762,10 @@ snapshots: dependencies: brace-expansion: 2.0.2 + minimatch@5.1.9: + dependencies: + brace-expansion: 2.0.2 + minimatch@6.2.0: dependencies: brace-expansion: 2.0.2 @@ -18234,8 +18238,6 @@ snapshots: nanoid@3.3.11: {} - nanoid@3.3.7: {} - natural-compare@1.4.0: {} nearley@2.20.1: @@ -18319,10 +18321,6 @@ snapshots: dependencies: es6-promise: 3.3.1 - node-releases@2.0.18: {} - - node-releases@2.0.19: {} - node-releases@2.0.27: {} node-source-walk@7.0.0: @@ -18374,8 +18372,6 @@ snapshots: normalize-path@3.0.0: {} - normalize-range@0.1.2: {} - normalize.css@8.0.1: {} npm-normalize-package-bin@3.0.1: {} @@ -18790,8 +18786,6 @@ snapshots: dependencies: split2: 4.2.0 - picocolors@1.0.1: {} - picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -18830,13 +18824,13 @@ snapshots: possible-typed-array-names@1.1.0: {} - postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.16.2)(yaml@2.8.1): + postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.1): dependencies: lilconfig: 3.1.3 optionalDependencies: jiti: 2.6.1 postcss: 8.5.6 - tsx: 4.16.2 + tsx: 4.21.0 yaml: 2.8.1 postcss-value-parser@4.2.0: {} @@ -18848,12 +18842,6 @@ snapshots: postcss: 8.5.6 quote-unquote: 1.0.0 - postcss@8.4.31: - dependencies: - nanoid: 3.3.7 - picocolors: 1.0.1 - source-map-js: 1.2.0 - postcss@8.4.38: dependencies: nanoid: 3.3.11 @@ -19816,8 +19804,6 @@ snapshots: dependencies: lodash: 4.17.21 - source-map-js@1.2.0: {} - source-map-js@1.2.1: {} source-map-support@0.5.21: @@ -20189,8 +20175,12 @@ snapshots: tailwindcss@4.1.18: {} + tailwindcss@4.2.1: {} + tapable@2.2.1: {} + tapable@2.3.0: {} + tar-fs@2.1.4: dependencies: chownr: 1.1.4 @@ -20460,7 +20450,7 @@ snapshots: tsscmp@1.0.6: {} - tsup@8.4.0(jiti@2.6.1)(postcss@8.5.6)(tsx@4.16.2)(typescript@6.0.0-beta)(yaml@2.8.1): + tsup@8.4.0(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(typescript@6.0.0-beta)(yaml@2.8.1): dependencies: bundle-require: 5.1.0(esbuild@0.25.0) cac: 6.7.14 @@ -20470,7 +20460,7 @@ snapshots: esbuild: 0.25.0 joycon: 3.1.1 picocolors: 1.1.1 - postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.16.2)(yaml@2.8.1) + postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.1) resolve-from: 5.0.0 rollup: 4.40.0 source-map: 0.8.0-beta.0 @@ -20487,9 +20477,9 @@ snapshots: - tsx - yaml - tsx@4.16.2: + tsx@4.21.0: dependencies: - esbuild: 0.21.5 + esbuild: 0.27.3 get-tsconfig: 4.7.6 optionalDependencies: fsevents: 2.3.3 @@ -20687,21 +20677,15 @@ snapshots: upath@1.2.0: {} - update-browserslist-db@1.1.0(browserslist@4.23.3): - dependencies: - browserslist: 4.23.3 - escalade: 3.2.0 - picocolors: 1.1.1 - - update-browserslist-db@1.1.3(browserslist@4.24.4): + update-browserslist-db@1.2.3(browserslist@4.28.0): dependencies: - browserslist: 4.24.4 + browserslist: 4.28.0 escalade: 3.2.0 picocolors: 1.1.1 - update-browserslist-db@1.2.3(browserslist@4.28.0): + update-browserslist-db@1.2.3(browserslist@4.28.1): dependencies: - browserslist: 4.28.0 + browserslist: 4.28.1 escalade: 3.2.0 picocolors: 1.1.1 @@ -20774,15 +20758,15 @@ snapshots: - rollup - supports-color - vite-dev-rpc@1.1.0(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1)): + vite-dev-rpc@1.1.0(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)): dependencies: birpc: 2.6.1 - vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1) - vite-hot-client: 2.1.0(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1)) + vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) + vite-hot-client: 2.1.0(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)) - vite-hot-client@2.1.0(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1)): + vite-hot-client@2.1.0(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)): dependencies: - vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1) + vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) vite-plugin-filter-replace@0.1.14: dependencies: @@ -20790,7 +20774,7 @@ snapshots: vite-plugin-html-inject@1.1.2: {} - vite-plugin-inspect@11.3.3(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1)): + vite-plugin-inspect@11.3.3(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)): dependencies: ansis: 4.2.0 debug: 4.4.3 @@ -20800,29 +20784,29 @@ snapshots: perfect-debounce: 2.0.0 sirv: 3.0.2 unplugin-utils: 0.3.1 - vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1) - vite-dev-rpc: 1.1.0(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1)) + vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) + vite-dev-rpc: 1.1.0(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)) transitivePeerDependencies: - supports-color - vite-plugin-minify@2.1.0(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1)): + vite-plugin-minify@2.1.0(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)): dependencies: '@types/html-minifier-terser': 7.0.2 html-minifier-terser: 7.2.0 - vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1) + vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) - vite-plugin-pwa@1.1.0(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1))(workbox-build@7.1.1(@types/babel__core@7.20.5))(workbox-window@7.1.0): + vite-plugin-pwa@1.1.0(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))(workbox-build@7.1.1(@types/babel__core@7.20.5))(workbox-window@7.1.0): dependencies: debug: 4.4.3 pretty-bytes: 6.1.1 tinyglobby: 0.2.15 - vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1) + vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) workbox-build: 7.1.1(@types/babel__core@7.20.5) workbox-window: 7.1.0 transitivePeerDependencies: - supports-color - vite-plugin-solid@2.11.10(@testing-library/jest-dom@6.9.1)(solid-js@1.9.10)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1)): + vite-plugin-solid@2.11.10(@testing-library/jest-dom@6.9.1)(solid-js@1.9.10)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)): dependencies: '@babel/core': 7.28.5 '@types/babel__core': 7.20.5 @@ -20830,14 +20814,14 @@ snapshots: merge-anything: 5.1.7 solid-js: 1.9.10 solid-refresh: 0.6.3(solid-js@1.9.10) - vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1) - vitefu: 1.1.1(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1)) + vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) + vitefu: 1.1.1(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)) optionalDependencies: '@testing-library/jest-dom': 6.9.1 transitivePeerDependencies: - supports-color - vite@7.1.12(@types/node@20.5.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1): + vite@7.1.12(@types/node@20.5.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1): dependencies: esbuild: 0.25.11 fdir: 6.5.0(picomatch@4.0.3) @@ -20849,13 +20833,13 @@ snapshots: '@types/node': 20.5.1 fsevents: 2.3.3 jiti: 2.6.1 - lightningcss: 1.30.2 + lightningcss: 1.31.1 sass: 1.70.0 terser: 5.46.0 - tsx: 4.16.2 + tsx: 4.21.0 yaml: 2.8.1 - vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1): + vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1): dependencies: esbuild: 0.25.11 fdir: 6.5.0(picomatch@4.0.3) @@ -20867,20 +20851,20 @@ snapshots: '@types/node': 24.9.1 fsevents: 2.3.3 jiti: 2.6.1 - lightningcss: 1.30.2 + lightningcss: 1.31.1 sass: 1.70.0 terser: 5.46.0 - tsx: 4.16.2 + tsx: 4.21.0 yaml: 2.8.1 - vitefu@1.1.1(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1)): + vitefu@1.1.1(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)): optionalDependencies: - vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1) + vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) - vitest@4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1): + vitest@4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1): dependencies: '@vitest/expect': 4.0.15 - '@vitest/mocker': 4.0.15(vite@7.1.12(@types/node@20.5.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1)) + '@vitest/mocker': 4.0.15(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)) '@vitest/pretty-format': 4.0.15 '@vitest/runner': 4.0.15 '@vitest/snapshot': 4.0.15 @@ -20897,7 +20881,7 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1) + vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.8.0 @@ -20917,10 +20901,10 @@ snapshots: - tsx - yaml - vitest@4.0.15(@types/node@20.5.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1): + vitest@4.0.15(@types/node@20.5.1)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1): dependencies: '@vitest/expect': 4.0.15 - '@vitest/mocker': 4.0.15(vite@7.1.12(@types/node@20.5.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1)) + '@vitest/mocker': 4.0.15(vite@7.1.12(@types/node@20.5.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)) '@vitest/pretty-format': 4.0.15 '@vitest/runner': 4.0.15 '@vitest/snapshot': 4.0.15 @@ -20937,7 +20921,7 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 7.1.12(@types/node@20.5.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.70.0)(terser@5.46.0)(tsx@4.16.2)(yaml@2.8.1) + vite: 7.1.12(@types/node@20.5.1)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.70.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 20.5.1 diff --git a/vitest.config.ts b/vitest.config.ts index 88a31c7e23bd..3c47f62fb281 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -47,6 +47,7 @@ function convertTests( function copySolidPlugin(config: UserWorkspaceConfig): void { if (!config.plugins) return; config.plugins - .filter((it) => it?.["name"] === "solid") + //@ts-expect-error this is fine + .filter((it) => it?.name === "solid") .forEach((it) => globalPlugins.push(it)); }