From b59ccdf6806914a2c8c673e5654c5349d59b96e0 Mon Sep 17 00:00:00 2001 From: Miodec Date: Thu, 9 Jul 2026 12:48:34 +0200 Subject: [PATCH 1/8] fix: editing profile would break the account page --- frontend/src/ts/components/modals/EditProfileModal.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frontend/src/ts/components/modals/EditProfileModal.tsx b/frontend/src/ts/components/modals/EditProfileModal.tsx index 7cc9f5c0434d..23c8cc30b968 100644 --- a/frontend/src/ts/components/modals/EditProfileModal.tsx +++ b/frontend/src/ts/components/modals/EditProfileModal.tsx @@ -8,14 +8,13 @@ import { createForm } from "@tanstack/solid-form"; import { For } from "solid-js"; import Ape from "../../ape"; -import { setSnapshot } from "../../db"; +import { getSnapshot, setSnapshot } from "../../db"; import { invalidateMyProfile } from "../../queries/profile"; import { hideModal } from "../../states/modals"; import { showErrorNotification, showSuccessNotification, } from "../../states/notifications"; -import { getSnapshot } from "../../states/snapshot"; import { cn } from "../../utils/cn"; import { AnimatedModal } from "../common/AnimatedModal"; import { Button } from "../common/Button"; From 7c2a6a496d4c056453c6338ebf217d6959f5f08b Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 9 Jul 2026 13:32:53 +0200 Subject: [PATCH 2/8] chore: bump oxc (@miodec) (#8214) --- .../__integration__/dal/result.spec.ts | 2 +- .../__integration__/dal/user.spec.ts | 2 +- .../__tests__/api/controllers/quotes.spec.ts | 2 +- .../__tests__/api/controllers/user.spec.ts | 3 +- backend/__tests__/middlewares/auth.spec.ts | 2 +- backend/package.json | 4 +- backend/src/api/controllers/dev.ts | 2 +- backend/src/api/controllers/user.ts | 2 +- backend/src/api/routes/index.ts | 5 +- .../components/common/AnimatedModal.spec.tsx | 6 +- .../controllers/preset-controller.spec.ts | 2 +- frontend/__tests__/test/events/data.spec.ts | 6 +- frontend/__tests__/test/events/stats.spec.ts | 4 +- frontend/package.json | 4 +- frontend/src/ts/collections/inbox.ts | 11 +- frontend/src/ts/commandline/commandline.ts | 2 +- .../layout/overlays/Notifications.tsx | 2 +- .../ts/components/modals/QuoteSubmitModal.tsx | 6 +- .../src/ts/components/modals/SimpleModal.tsx | 4 +- .../custom-setting/CustomBackground.tsx | 2 +- .../settings/custom-setting/FontFamily.tsx | 7 +- frontend/src/ts/config/setters.ts | 6 +- frontend/src/ts/config/utils.ts | 3 +- frontend/src/ts/constants/themes.ts | 11 +- .../src/ts/controllers/badge-controller.ts | 2 +- .../src/ts/controllers/quotes-controller.ts | 2 +- .../src/ts/controllers/sound-controller.ts | 2 +- .../src/ts/controllers/theme-controller.ts | 7 +- frontend/src/ts/states/quote-rate.ts | 2 +- frontend/src/ts/test/custom-text.ts | 2 +- frontend/src/ts/test/funbox/list.ts | 2 +- frontend/src/ts/test/replay-ui.ts | 3 +- frontend/src/ts/test/test-logic.ts | 2 +- frontend/src/ts/test/test-ui.ts | 4 +- frontend/src/ts/utils/dom.ts | 5 +- frontend/src/ts/utils/misc.ts | 2 +- .../storybook/.storybook/ThemeDecorator.tsx | 4 +- .../stories/AnimatedModal.stories.tsx | 4 +- frontend/storybook/stories/Anime.stories.tsx | 4 +- .../storybook/stories/AnimeGroup.stories.tsx | 4 +- .../stories/AnimePresence.stories.tsx | 4 +- .../storybook/stories/AnimeShow.stories.tsx | 4 +- .../storybook/stories/AnimeSwitch.stories.tsx | 4 +- .../stories/AsyncContent.stories.tsx | 2 +- .../storybook/stories/AutoShrink.stories.tsx | 4 +- .../storybook/stories/Balloon.stories.tsx | 4 +- frontend/storybook/stories/Bar.stories.tsx | 4 +- frontend/storybook/stories/Button.stories.tsx | 3 +- .../storybook/stories/ChartJs.stories.tsx | 4 +- .../storybook/stories/Checkbox.stories.tsx | 8 +- .../storybook/stories/DataTable.stories.tsx | 4 +- .../stories/DiscordAvatar.stories.tsx | 4 +- frontend/storybook/stories/Fa.stories.tsx | 4 +- .../stories/FieldIndicator.stories.tsx | 3 +- frontend/storybook/stories/H2.stories.tsx | 4 +- frontend/storybook/stories/H3.stories.tsx | 4 +- .../storybook/stories/InputField.stories.tsx | 3 +- .../stories/NotificationBubble.stories.tsx | 2 +- .../storybook/stories/SlimSelect.stories.tsx | 4 +- frontend/storybook/stories/User.stories.tsx | 4 +- .../storybook/stories/UserBadge.stories.tsx | 4 +- .../storybook/stories/UserFlags.stories.tsx | 4 +- .../storybook/stories/UserProfile.stories.tsx | 3 +- frontend/vite.config.ts | 4 +- frontend/vitest.config.ts | 2 +- package.json | 6 +- packages/challenges/package.json | 4 +- packages/contracts/package.json | 4 +- packages/funbox/package.json | 4 +- packages/oxlint-config/rules/enabled.jsonc | 7 +- packages/release/package.json | 4 +- packages/schemas/package.json | 4 +- packages/tsup-config/package.json | 4 +- packages/util/package.json | 4 +- packages/util/src/json.ts | 7 +- pnpm-lock.yaml | 822 ++++++++++-------- 76 files changed, 566 insertions(+), 549 deletions(-) diff --git a/backend/__tests__/__integration__/dal/result.spec.ts b/backend/__tests__/__integration__/dal/result.spec.ts index f466cf528eb9..15581dd3f160 100644 --- a/backend/__tests__/__integration__/dal/result.spec.ts +++ b/backend/__tests__/__integration__/dal/result.spec.ts @@ -39,7 +39,7 @@ async function createDummyData( charStats: [0, 0, 0, 0], acc: 0, mode: "time", - mode2: "10" as never, + mode2: "10", quoteLength: 1, timestamp, restartCount: 0, diff --git a/backend/__tests__/__integration__/dal/user.spec.ts b/backend/__tests__/__integration__/dal/user.spec.ts index 5f44cffe1d41..5b3200f1add5 100644 --- a/backend/__tests__/__integration__/dal/user.spec.ts +++ b/backend/__tests__/__integration__/dal/user.spec.ts @@ -2137,7 +2137,7 @@ describe("UserDal", () => { maxLength: 50, lastResultTimestamp: 0, hourOffset: -1, - } as any, + }, xp: 42, inventory: { badges: [{ id: 23 }, { id: 5 }], diff --git a/backend/__tests__/api/controllers/quotes.spec.ts b/backend/__tests__/api/controllers/quotes.spec.ts index d183e6f06672..96e4098dccc0 100644 --- a/backend/__tests__/api/controllers/quotes.spec.ts +++ b/backend/__tests__/api/controllers/quotes.spec.ts @@ -160,7 +160,7 @@ describe("QuotesController", () => { beforeEach(() => { addQuoteMock.mockClear(); - addQuoteMock.mockResolvedValue({} as any); + addQuoteMock.mockResolvedValue({}); verifyCaptchaMock.mockClear(); verifyCaptchaMock.mockResolvedValue(true); diff --git a/backend/__tests__/api/controllers/user.spec.ts b/backend/__tests__/api/controllers/user.spec.ts index 25a036a47fbf..17e9ac1f64bb 100644 --- a/backend/__tests__/api/controllers/user.spec.ts +++ b/backend/__tests__/api/controllers/user.spec.ts @@ -24,7 +24,6 @@ import GeorgeQueue from "../../../src/queues/george-queue"; import * as DiscordUtils from "../../../src/utils/discord"; import * as Captcha from "../../../src/utils/captcha"; import * as FirebaseAdmin from "../../../src/init/firebase-admin"; -import { FirebaseError } from "firebase-admin"; import * as ApeKeysDal from "../../../src/dal/ape-keys"; import * as LogDal from "../../../src/dal/logs"; import { ObjectId } from "mongodb"; @@ -1439,7 +1438,7 @@ describe("user controller test", () => { }); it("should fail for unknown error", async () => { //GIVEN - authUpdateEmailMock.mockRejectedValue({} as FirebaseError); + authUpdateEmailMock.mockRejectedValue({}); //WHEN await mockApp diff --git a/backend/__tests__/middlewares/auth.spec.ts b/backend/__tests__/middlewares/auth.spec.ts index 902e3196691c..a49ac1ce8e40 100644 --- a/backend/__tests__/middlewares/auth.spec.ts +++ b/backend/__tests__/middlewares/auth.spec.ts @@ -77,7 +77,7 @@ describe("middlewares/auth", () => { throw error; } return "Next function called"; - }) as unknown as NextFunction; + }); }); afterEach(() => { diff --git a/backend/package.json b/backend/package.json index bc0e77f0f078..a47cf2102b57 100644 --- a/backend/package.json +++ b/backend/package.json @@ -81,8 +81,8 @@ "@vitest/coverage-v8": "4.1.5", "concurrently": "8.2.2", "openapi3-ts": "2.0.2", - "oxlint": "1.68.0", - "oxlint-tsgolint": "0.23.0", + "oxlint": "1.73.0", + "oxlint-tsgolint": "0.24.0", "readline-sync": "1.4.10", "supertest": "7.1.4", "testcontainers": "11.11.0", diff --git a/backend/src/api/controllers/dev.ts b/backend/src/api/controllers/dev.ts index e16572f441ce..134a8f50e6e3 100644 --- a/backend/src/api/controllers/dev.ts +++ b/backend/src/api/controllers/dev.ts @@ -163,7 +163,7 @@ function createResult( charStats: [131, 0, 0, 0], acc: random(80, 100), language: "english", - mode: mode as Mode, + mode: mode, mode2: mode2 as unknown as never, timestamp: timestamp.valueOf(), testDuration: testDuration, diff --git a/backend/src/api/controllers/user.ts b/backend/src/api/controllers/user.ts index c9eb977bbad4..80baab7dfb71 100644 --- a/backend/src/api/controllers/user.ts +++ b/backend/src/api/controllers/user.ts @@ -536,7 +536,7 @@ function getRelevantUserInfo(user: UserDAL.DBUser): RelevantUserInfo { "ips", "testActivity", "suspicious", - ]) as RelevantUserInfo; + ]); } export async function getUser(req: MonkeyRequest): Promise { diff --git a/backend/src/api/routes/index.ts b/backend/src/api/routes/index.ts index d8f9e69262fa..911524010796 100644 --- a/backend/src/api/routes/index.ts +++ b/backend/src/api/routes/index.ts @@ -30,7 +30,6 @@ import { getLiveConfiguration } from "../../init/configuration"; import Logger from "../../utils/logger"; import { createExpressEndpoints, initServer } from "@ts-rest/express"; import { ZodIssue } from "zod"; -import { MonkeyValidationError } from "@monkeytype/contracts/util/api"; import { authenticateTsRestRequest } from "../../middlewares/auth"; import { rateLimitRequest } from "../../middlewares/rate-limit"; import { verifyPermissions } from "../../middlewares/permission"; @@ -111,9 +110,7 @@ function applyTsRestApiRoutes(app: IRouter): void { return; } - res - .status(422) - .json({ message, validationErrors } as MonkeyValidationError); + res.status(422).json({ message, validationErrors }); }, globalMiddleware: [ authenticateTsRestRequest(), diff --git a/frontend/__tests__/components/common/AnimatedModal.spec.tsx b/frontend/__tests__/components/common/AnimatedModal.spec.tsx index 3eb79f9a145e..61e5a4a5e178 100644 --- a/frontend/__tests__/components/common/AnimatedModal.spec.tsx +++ b/frontend/__tests__/components/common/AnimatedModal.spec.tsx @@ -2,11 +2,11 @@ import { render } from "@solidjs/testing-library"; import { describe, it, expect, vi, beforeEach } from "vitest"; import { AnimatedModal } from "../../../src/ts/components/common/AnimatedModal"; -import { hideModal, ModalId, showModal } from "../../../src/ts/states/modals"; +import { hideModal, showModal } from "../../../src/ts/states/modals"; describe("AnimatedModal", () => { beforeEach(() => { - showModal("Support" as ModalId); + showModal("Support"); vi.clearAllMocks(); // Mock dialog methods that don't exist in jsdom @@ -60,7 +60,7 @@ describe("AnimatedModal", () => { }); it("doesnt render children if not open", () => { - hideModal("Support" as ModalId); + hideModal("Support"); const { modalDiv } = renderModal({}); expect(modalDiv).not.toBeInTheDocument(); diff --git a/frontend/__tests__/controllers/preset-controller.spec.ts b/frontend/__tests__/controllers/preset-controller.spec.ts index 4b23d4cb3b4f..3d412e47e021 100644 --- a/frontend/__tests__/controllers/preset-controller.spec.ts +++ b/frontend/__tests__/controllers/preset-controller.spec.ts @@ -164,7 +164,7 @@ describe("PresetController", () => { ...partialPreset, } as any; dbGetSnapshotMock.mockReturnValue({} as any); - getPresetMock.mockReturnValue(preset as any); + getPresetMock.mockReturnValue(preset); return preset; }; }); diff --git a/frontend/__tests__/test/events/data.spec.ts b/frontend/__tests__/test/events/data.spec.ts index 3cd8f6625bb5..d093fae25e7f 100644 --- a/frontend/__tests__/test/events/data.spec.ts +++ b/frontend/__tests__/test/events/data.spec.ts @@ -223,10 +223,10 @@ describe("data.ts", () => { // simulate forceReleaseAllKeys passing indexed codes directly logTestEvent("keyup", 1030, { code: "NoCode0", - } as KeyupEventData); + }); logTestEvent("keyup", 1040, { code: "NoCode1", - } as KeyupEventData); + }); const events = getAllTestEvents(); expect(events).toHaveLength(4); @@ -239,7 +239,7 @@ describe("data.ts", () => { it("rejects indexed NoCode keyup with no matching keydown", () => { logTestEvent("keyup", 1010, { code: "NoCode0", - } as KeyupEventData); + }); expect(getAllTestEvents()).toHaveLength(0); }); diff --git a/frontend/__tests__/test/events/stats.spec.ts b/frontend/__tests__/test/events/stats.spec.ts index 4682015fff07..862fd8a8db06 100644 --- a/frontend/__tests__/test/events/stats.spec.ts +++ b/frontend/__tests__/test/events/stats.spec.ts @@ -844,7 +844,7 @@ describe("stats.ts", () => { charIndex: 3, inputType: "deleteWordBackward", inputValue: "=", - } as InputEventData); + }); // second Ctrl+Backspace: Firefox ate sentinel + "=" → goToPreviousWord; // clearedNextWord marks word 1 (= wordIndex + 1) as abandoned @@ -854,7 +854,7 @@ describe("stats.ts", () => { inputType: "deleteWordBackward", inputValue: "", clearedNextWord: true, - } as InputEventData); + }); logTestEvent("timer", 5000, timer("end", 4)); diff --git a/frontend/package.json b/frontend/package.json index 28577153aaac..bd52eaa7aa61 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -110,8 +110,8 @@ "madge": "8.0.0", "magic-string": "0.30.17", "normalize.css": "8.0.1", - "oxlint": "1.68.0", - "oxlint-tsgolint": "0.23.0", + "oxlint": "1.73.0", + "oxlint-tsgolint": "0.24.0", "postcss": "8.5.15", "sass": "1.70.0", "solid-devtools": "0.34.5", diff --git a/frontend/src/ts/collections/inbox.ts b/frontend/src/ts/collections/inbox.ts index 79c3a28dd0f5..812d6a95452e 100644 --- a/frontend/src/ts/collections/inbox.ts +++ b/frontend/src/ts/collections/inbox.ts @@ -44,11 +44,12 @@ const inboxCollection = createCollection( queryFn: async () => { const addStatus = (item: MonkeyMail): InboxItem => ({ ...item, - status: (item.rewards.length > 0 && !item.read - ? "unclaimed" - : item.read - ? "read" - : "unread") as InboxItem["status"], + status: + item.rewards.length > 0 && !item.read + ? "unclaimed" + : item.read + ? "read" + : "unread", }); const response = await Ape.users.getInbox(); diff --git a/frontend/src/ts/commandline/commandline.ts b/frontend/src/ts/commandline/commandline.ts index 878677174183..6ef92d7e36d1 100644 --- a/frontend/src/ts/commandline/commandline.ts +++ b/frontend/src/ts/commandline/commandline.ts @@ -475,7 +475,7 @@ async function showCommands(): Promise { } } - return { ...command, isActive } as CommandWithIsActive; + return { ...command, isActive }; }); if ( diff --git a/frontend/src/ts/components/layout/overlays/Notifications.tsx b/frontend/src/ts/components/layout/overlays/Notifications.tsx index 2ecc6f4a039c..cbdf5b449d88 100644 --- a/frontend/src/ts/components/layout/overlays/Notifications.tsx +++ b/frontend/src/ts/components/layout/overlays/Notifications.tsx @@ -58,7 +58,7 @@ function NotificationItem(props: { notification: Notification }): JSXElement { icon: `fa-${props.notification.customIcon}`, fixedWidth: true, } as FaProps) - : ({ icon: config().icon } as FaProps); + : { icon: config().icon }; const title = (): string => props.notification.customTitle ?? config().title; diff --git a/frontend/src/ts/components/modals/QuoteSubmitModal.tsx b/frontend/src/ts/components/modals/QuoteSubmitModal.tsx index c2838c75e2f8..23822f8208c8 100644 --- a/frontend/src/ts/components/modals/QuoteSubmitModal.tsx +++ b/frontend/src/ts/components/modals/QuoteSubmitModal.tsx @@ -35,11 +35,13 @@ export function QuoteSubmitModal(): JSXElement { text: g.replace(/_/g, " "), })); + const language = removeLanguageSize(Config.language) as string; + const form = createForm(() => ({ defaultValues: { text: "", source: "", - language: removeLanguageSize(Config.language) as string, + language, captcha: "", }, onSubmit: async ({ value }) => { @@ -76,7 +78,7 @@ export function QuoteSubmitModal(): JSXElement { defaultValues: { text: "", source: "", - language: removeLanguageSize(Config.language) as string, + language: removeLanguageSize(Config.language), captcha: "", }, }); diff --git a/frontend/src/ts/components/modals/SimpleModal.tsx b/frontend/src/ts/components/modals/SimpleModal.tsx index c7a0337944ae..0646991dec2a 100644 --- a/frontend/src/ts/components/modals/SimpleModal.tsx +++ b/frontend/src/ts/components/modals/SimpleModal.tsx @@ -84,9 +84,9 @@ function getValidators( // oxlint-disable-next-line typescript/no-unsafe-argument validators.onChange = fromSchema(schema, { convert, - }) as SyncValidator; + }); } else if (required) { - validators.onChange = fieldMandatory() as SyncValidator; + validators.onChange = fieldMandatory(); } if (isValid !== undefined) { diff --git a/frontend/src/ts/components/pages/settings/custom-setting/CustomBackground.tsx b/frontend/src/ts/components/pages/settings/custom-setting/CustomBackground.tsx index 74c65f3e6d68..78615c898719 100644 --- a/frontend/src/ts/components/pages/settings/custom-setting/CustomBackground.tsx +++ b/frontend/src/ts/components/pages/settings/custom-setting/CustomBackground.tsx @@ -97,7 +97,7 @@ export function CustomBackground(): JSXElement { accept="image/*" class="hidden" onChange={async (e) => { - const fileInput = e.target as HTMLInputElement; + const fileInput = e.target; const file = fileInput.files?.[0]; if (!file) { diff --git a/frontend/src/ts/components/pages/settings/custom-setting/FontFamily.tsx b/frontend/src/ts/components/pages/settings/custom-setting/FontFamily.tsx index 44cd8bdee7d2..3922ff1b36b1 100644 --- a/frontend/src/ts/components/pages/settings/custom-setting/FontFamily.tsx +++ b/frontend/src/ts/components/pages/settings/custom-setting/FontFamily.tsx @@ -79,7 +79,7 @@ export function FontFamily(): JSXElement { accept="font/woff,font/woff2,font/ttf,font/otf" class="hidden" onChange={async (e) => { - const fileInput = e.target as HTMLInputElement; + const fileInput = e.target; const file = fileInput.files?.[0]; if (!file) { @@ -126,10 +126,7 @@ export function FontFamily(): JSXElement {
{(option) => { - const optionsMeta = configMetadata.fontFamily - .optionsMetadata as - | Record - | undefined; + const optionsMeta = configMetadata.fontFamily.optionsMetadata; const match = optionsMeta?.[String(option)]; const displayString = match?.displayString ?? String(option).replace(/_/g, " "); diff --git a/frontend/src/ts/config/setters.ts b/frontend/src/ts/config/setters.ts index f571baa401be..0898169fabfc 100644 --- a/frontend/src/ts/config/setters.ts +++ b/frontend/src/ts/config/setters.ts @@ -1,7 +1,7 @@ import * as ConfigSchemas from "@monkeytype/schemas/configs"; import { ZodType as ZodSchema } from "zod"; import { saveToLocalStorage } from "../config/persistence"; -import { configMetadata, ConfigMetadataObject } from "./metadata"; +import { configMetadata } from "./metadata"; import { isConfigValueValid } from "./validation"; import { configEvent } from "../events/config"; import { showNoticeNotification } from "../states/notifications"; @@ -24,7 +24,7 @@ export function setConfig( partOfFullConfigChange?: boolean; }, ): boolean { - const metadata = configMetadata[key] as ConfigMetadataObject[T]; + const metadata = configMetadata[key]; if (metadata === undefined) { throw new Error(`Config metadata for key "${key}" is not defined.`); } @@ -129,7 +129,7 @@ export function setConfig( key: key, newValue: value, nosave: options?.nosave ?? false, - previousValue: previousValue as ConfigSchemas.Config[T], + previousValue: previousValue, }); if (!options?.partOfFullConfigChange) { diff --git a/frontend/src/ts/config/utils.ts b/frontend/src/ts/config/utils.ts index ac3bd0e985eb..82a7d465ad14 100644 --- a/frontend/src/ts/config/utils.ts +++ b/frontend/src/ts/config/utils.ts @@ -1,6 +1,5 @@ import type { Config as ConfigSchema, - ConfigValue, FunboxName, PartialConfig, } from "@monkeytype/schemas/configs"; @@ -22,7 +21,7 @@ function mergeWithDefaultConfig(config: PartialConfig): ConfigSchema { const defaultConfig = getDefaultConfig(); const mergedConfig = {} as ConfigSchema; for (const key of typedKeys(defaultConfig)) { - const newValue = config[key] ?? (defaultConfig[key] as ConfigValue); + const newValue = config[key] ?? defaultConfig[key]; //@ts-expect-error cant be bothered to deal with this mergedConfig[key] = newValue; } diff --git a/frontend/src/ts/constants/themes.ts b/frontend/src/ts/constants/themes.ts index 0bb86f625671..dc0fcaa3d20a 100644 --- a/frontend/src/ts/constants/themes.ts +++ b/frontend/src/ts/constants/themes.ts @@ -2327,10 +2327,7 @@ export const themes: Record = { export type ThemeWithName = Theme & { name: ThemeName }; export const ThemesList: ThemeWithName[] = Object.keys(themes) .sort() - .map( - (it) => - ({ - ...themes[it as ThemeName], - name: it as ThemeName, - }) as Theme & { name: ThemeName }, - ); + .map((it) => ({ + ...themes[it as ThemeName], + name: it as ThemeName, + })); diff --git a/frontend/src/ts/controllers/badge-controller.ts b/frontend/src/ts/controllers/badge-controller.ts index a517319990cc..0ba859be297a 100644 --- a/frontend/src/ts/controllers/badge-controller.ts +++ b/frontend/src/ts/controllers/badge-controller.ts @@ -196,7 +196,7 @@ export function getHTMLById( noBalloon = false, showUnknown = false, ): string { - const badge = badges[id] as UserBadge | undefined; + const badge = badges[id]; if (!badge && !showUnknown) { return ""; diff --git a/frontend/src/ts/controllers/quotes-controller.ts b/frontend/src/ts/controllers/quotes-controller.ts index 4a443a425ed6..6f13d384fab2 100644 --- a/frontend/src/ts/controllers/quotes-controller.ts +++ b/frontend/src/ts/controllers/quotes-controller.ts @@ -250,7 +250,7 @@ const quoteController = new QuotesController(); configEvent.subscribe(({ key, newValue }) => { if (key === "quoteLength") { - quoteController.updateQuoteQueue(newValue as number[]); + quoteController.updateQuoteQueue(newValue); } }); diff --git a/frontend/src/ts/controllers/sound-controller.ts b/frontend/src/ts/controllers/sound-controller.ts index fd4da3a0cb56..2bdb163ccb00 100644 --- a/frontend/src/ts/controllers/sound-controller.ts +++ b/frontend/src/ts/controllers/sound-controller.ts @@ -419,7 +419,7 @@ function extractScaleSounds( { preview: createPreviewScale(config.validNotes), meta: { ...defaultScaleData }, - } as ScaleMeta, + }, ]; }), ); diff --git a/frontend/src/ts/controllers/theme-controller.ts b/frontend/src/ts/controllers/theme-controller.ts index cc76551a81f7..fc680803bbba 100644 --- a/frontend/src/ts/controllers/theme-controller.ts +++ b/frontend/src/ts/controllers/theme-controller.ts @@ -215,9 +215,7 @@ export async function randomizeTheme(): Promise { let colorsOverride: CustomThemeColors | undefined; if (Config.randomTheme === "custom") { - const theme = CustomThemes.__nonReactive.getCustomTheme( - randomTheme as string, - ); + const theme = CustomThemes.__nonReactive.getCustomTheme(randomTheme); colorsOverride = theme?.colors; randomTheme = "custom"; } @@ -231,8 +229,7 @@ export async function randomizeTheme(): Promise { let name = randomTheme.replace(/_/g, " "); if (Config.randomTheme === "custom") { name = ( - CustomThemes.__nonReactive.getCustomTheme(randomTheme as string) - ?.name ?? "custom" + CustomThemes.__nonReactive.getCustomTheme(randomTheme)?.name ?? "custom" ).replace(/_/g, " "); } showNoticeNotification(name); diff --git a/frontend/src/ts/states/quote-rate.ts b/frontend/src/ts/states/quote-rate.ts index ce030c74dbeb..cb5c2daebf4d 100644 --- a/frontend/src/ts/states/quote-rate.ts +++ b/frontend/src/ts/states/quote-rate.ts @@ -54,7 +54,7 @@ export async function getQuoteStats( if (response.body.data === null) { setQuoteStats({}); - return {} as QuoteStats; + return {}; } const stats = response.body.data as QuoteStats; diff --git a/frontend/src/ts/test/custom-text.ts b/frontend/src/ts/test/custom-text.ts index 43271d92b57b..d60f6a7aec77 100644 --- a/frontend/src/ts/test/custom-text.ts +++ b/frontend/src/ts/test/custom-text.ts @@ -88,7 +88,7 @@ export function setMode(val: CustomTextMode): void { } export function getLimit(): CustomTextLimit { - return customTextSettings.get().limit as CustomTextLimit; + return customTextSettings.get().limit; } export function getLimitValue(): number { diff --git a/frontend/src/ts/test/funbox/list.ts b/frontend/src/ts/test/funbox/list.ts index 266813190bbf..3548c9b7c007 100644 --- a/frontend/src/ts/test/funbox/list.ts +++ b/frontend/src/ts/test/funbox/list.ts @@ -126,7 +126,7 @@ export function findSingleActiveFunboxWithFunction< >(functionName: F): FunboxWithFunction | undefined { const matching = getActiveFunboxesWithFunction(functionName); if (matching.length === 0) return undefined; - if (matching.length === 1) return matching[0] as FunboxWithFunction; + if (matching.length === 1) return matching[0]; throw new Error( `Expecting exactly one funbox implementing "${functionName} but found ${matching.length}`, ); diff --git a/frontend/src/ts/test/replay-ui.ts b/frontend/src/ts/test/replay-ui.ts index cffdc7a77974..5664a1184af0 100644 --- a/frontend/src/ts/test/replay-ui.ts +++ b/frontend/src/ts/test/replay-ui.ts @@ -222,7 +222,8 @@ function handleDisplayLogic(item: Replay, nosound = false): void { const replayWords = document.getElementById("replayWords"); if (replayWords !== null) { - activeWord = replayWords.children[wordPos] as HTMLElement; + const fallback = replayWords.children[wordPos] as HTMLElement; + activeWord = fallback; } curPos = activeWord.children.length; diff --git a/frontend/src/ts/test/test-logic.ts b/frontend/src/ts/test/test-logic.ts index fec205c18563..903f6bc6640b 100644 --- a/frontend/src/ts/test/test-logic.ts +++ b/frontend/src/ts/test/test-logic.ts @@ -821,7 +821,7 @@ function buildCompletedEvent( keySpacing: keypressSpacing, keyDuration: getKeypressDurations(eventLog), keyOverlap: getKeypressOverlap(eventLog), - } as Omit; + }; if (completedEvent.mode !== "custom") delete completedEvent.customText; if (completedEvent.mode !== "quote") delete completedEvent.quoteLength; diff --git a/frontend/src/ts/test/test-ui.ts b/frontend/src/ts/test/test-ui.ts index 1779503ee3ef..35eba81484cc 100644 --- a/frontend/src/ts/test/test-ui.ts +++ b/frontend/src/ts/test/test-ui.ts @@ -1540,7 +1540,7 @@ export async function applyBurstHeatmap(): Promise { steps.forEach((step) => { if (wordBurstVal >= step.val) { word.addClass("heatmapInherit"); - word.setStyle({ color: colors[step.colorId] as string }); + word.setStyle({ color: colors[step.colorId] }); } }); } @@ -1549,7 +1549,7 @@ export async function applyBurstHeatmap(): Promise { const boxes = qsa("#resultWordsHistory .heatmapLegend .boxes .box"); for (let i = 0; i < boxes.length; i++) { (boxes[i] as ElementWithUtils).setStyle({ - background: colors[i] as string, + background: colors[i], }); } } else { diff --git a/frontend/src/ts/utils/dom.ts b/frontend/src/ts/utils/dom.ts index 8f0225bda0c3..4a788349d851 100644 --- a/frontend/src/ts/utils/dom.ts +++ b/frontend/src/ts/utils/dom.ts @@ -345,10 +345,7 @@ export class ElementWithUtils { | ((this: T, ev: Event) => void), ): this { // this type was some AI magic but if it works it works - this.native.addEventListener( - event, - handler as EventListenerOrEventListenerObject, - ); + this.native.addEventListener(event, handler); return this; } diff --git a/frontend/src/ts/utils/misc.ts b/frontend/src/ts/utils/misc.ts index 6d5cde55b255..510a82e1fe31 100644 --- a/frontend/src/ts/utils/misc.ts +++ b/frontend/src/ts/utils/misc.ts @@ -568,7 +568,7 @@ export function promiseWithResolvers(): { return { resolve, reject, - promise: promiseLike as Promise, + promise: promiseLike, reset, }; } diff --git a/frontend/storybook/.storybook/ThemeDecorator.tsx b/frontend/storybook/.storybook/ThemeDecorator.tsx index bb7c9e54d2be..8d65ad4a6574 100644 --- a/frontend/storybook/.storybook/ThemeDecorator.tsx +++ b/frontend/storybook/.storybook/ThemeDecorator.tsx @@ -16,8 +16,8 @@ export function ThemeDecorator( context: StoryContext, ): JSXElement { const themeName = (context.globals.theme ?? "serika_dark") as ThemeName; - const theme = - themeMap.get(themeName) ?? (themeMap.get("serika_dark") as ThemeWithName); + const fallback = themeMap.get("serika_dark") as ThemeWithName; + const theme = themeMap.get(themeName) ?? fallback; const root = document.documentElement; root.style.setProperty("--bg-color", theme.bg); diff --git a/frontend/storybook/stories/AnimatedModal.stories.tsx b/frontend/storybook/stories/AnimatedModal.stories.tsx index 4163ffb94db0..9cd06a080fb1 100644 --- a/frontend/storybook/stories/AnimatedModal.stories.tsx +++ b/frontend/storybook/stories/AnimatedModal.stories.tsx @@ -1,5 +1,3 @@ -import { Component } from "solid-js"; - import preview from "#.storybook/preview"; import { AnimatedModal } from "../../src/ts/components/common/AnimatedModal"; @@ -25,7 +23,7 @@ function ModalTrigger(props: { modalId: ModalId; label: string }) { const meta = preview.meta({ title: "Common/AnimatedModal", - component: AnimatedModal as Component, + component: AnimatedModal, parameters: { layout: "fullscreen", }, diff --git a/frontend/storybook/stories/Anime.stories.tsx b/frontend/storybook/stories/Anime.stories.tsx index a2ed36d22d07..59f6e86f9c3a 100644 --- a/frontend/storybook/stories/Anime.stories.tsx +++ b/frontend/storybook/stories/Anime.stories.tsx @@ -1,5 +1,5 @@ import { AnimationParams } from "animejs"; -import { Component, createSignal } from "solid-js"; +import { createSignal } from "solid-js"; import preview from "#.storybook/preview"; @@ -7,7 +7,7 @@ import { Anime } from "../../src/ts/components/common/anime/Anime"; const meta = preview.meta({ title: "Common/Anime/Anime", - component: Anime as Component, + component: Anime, parameters: { layout: "centered", }, diff --git a/frontend/storybook/stories/AnimeGroup.stories.tsx b/frontend/storybook/stories/AnimeGroup.stories.tsx index 6680a6d7858a..4a0c4e6ade13 100644 --- a/frontend/storybook/stories/AnimeGroup.stories.tsx +++ b/frontend/storybook/stories/AnimeGroup.stories.tsx @@ -1,5 +1,5 @@ import { AnimationParams } from "animejs"; -import { Component, createSignal, For } from "solid-js"; +import { createSignal, For } from "solid-js"; import preview from "#.storybook/preview"; @@ -7,7 +7,7 @@ import { AnimeGroup } from "../../src/ts/components/common/anime/AnimeGroup"; const meta = preview.meta({ title: "Common/Anime/AnimeGroup", - component: AnimeGroup as Component, + component: AnimeGroup, parameters: { layout: "centered", }, diff --git a/frontend/storybook/stories/AnimePresence.stories.tsx b/frontend/storybook/stories/AnimePresence.stories.tsx index a342645c803a..54409e769c4e 100644 --- a/frontend/storybook/stories/AnimePresence.stories.tsx +++ b/frontend/storybook/stories/AnimePresence.stories.tsx @@ -1,5 +1,5 @@ import { AnimationParams } from "animejs"; -import { Component, createSignal, For, Show } from "solid-js"; +import { createSignal, For, Show } from "solid-js"; import preview from "#.storybook/preview"; @@ -8,7 +8,7 @@ import { AnimePresence } from "../../src/ts/components/common/anime/AnimePresenc const meta = preview.meta({ title: "Common/Anime/AnimePresence", - component: AnimePresence as Component, + component: AnimePresence, parameters: { layout: "centered", }, diff --git a/frontend/storybook/stories/AnimeShow.stories.tsx b/frontend/storybook/stories/AnimeShow.stories.tsx index 1688a9a7db5f..6e0f20b92f72 100644 --- a/frontend/storybook/stories/AnimeShow.stories.tsx +++ b/frontend/storybook/stories/AnimeShow.stories.tsx @@ -1,4 +1,4 @@ -import { Component, createSignal } from "solid-js"; +import { createSignal } from "solid-js"; import preview from "#.storybook/preview"; @@ -6,7 +6,7 @@ import { AnimeShow } from "../../src/ts/components/common/anime/AnimeShow"; const meta = preview.meta({ title: "Common/Anime/AnimeShow", - component: AnimeShow as Component, + component: AnimeShow, parameters: { layout: "centered", }, diff --git a/frontend/storybook/stories/AnimeSwitch.stories.tsx b/frontend/storybook/stories/AnimeSwitch.stories.tsx index 94fd1a3b2afc..5ff19c88cc39 100644 --- a/frontend/storybook/stories/AnimeSwitch.stories.tsx +++ b/frontend/storybook/stories/AnimeSwitch.stories.tsx @@ -1,4 +1,4 @@ -import { Component, createSignal } from "solid-js"; +import { createSignal } from "solid-js"; import preview from "#.storybook/preview"; @@ -7,7 +7,7 @@ import { AnimeSwitch } from "../../src/ts/components/common/anime/AnimeSwitch"; const meta = preview.meta({ title: "Common/Anime/AnimeSwitch", - component: AnimeSwitch as Component, + component: AnimeSwitch, parameters: { layout: "centered", }, diff --git a/frontend/storybook/stories/AsyncContent.stories.tsx b/frontend/storybook/stories/AsyncContent.stories.tsx index a7e00de380c2..c238463aa5f3 100644 --- a/frontend/storybook/stories/AsyncContent.stories.tsx +++ b/frontend/storybook/stories/AsyncContent.stories.tsx @@ -15,7 +15,7 @@ const queryClient = new QueryClient({ const meta = preview.meta({ title: "Common/AsyncContent", // oxlint-disable-next-line typescript/no-unsafe-assignment -- generic component - component: AsyncContent as unknown as () => ReturnType, + component: AsyncContent, parameters: { layout: "centered", }, diff --git a/frontend/storybook/stories/AutoShrink.stories.tsx b/frontend/storybook/stories/AutoShrink.stories.tsx index 538d3ebd34a5..ae142ac78f70 100644 --- a/frontend/storybook/stories/AutoShrink.stories.tsx +++ b/frontend/storybook/stories/AutoShrink.stories.tsx @@ -1,12 +1,10 @@ -import { Component } from "solid-js"; - import preview from "#.storybook/preview"; import { AutoShrink } from "../../src/ts/components/common/AutoShrink"; const meta = preview.meta({ title: "Common/AutoShrink", - component: AutoShrink as Component, + component: AutoShrink, parameters: { layout: "centered", }, diff --git a/frontend/storybook/stories/Balloon.stories.tsx b/frontend/storybook/stories/Balloon.stories.tsx index a5f3b276f3a3..4fdce2b66b80 100644 --- a/frontend/storybook/stories/Balloon.stories.tsx +++ b/frontend/storybook/stories/Balloon.stories.tsx @@ -1,12 +1,10 @@ -import { Component } from "solid-js"; - import preview from "#.storybook/preview"; import { Balloon } from "../../src/ts/components/common/Balloon"; const meta = preview.meta({ title: "Common/Balloon", - component: Balloon as Component, + component: Balloon, parameters: { layout: "centered", }, diff --git a/frontend/storybook/stories/Bar.stories.tsx b/frontend/storybook/stories/Bar.stories.tsx index 47ea5bf8c54b..fa625a789642 100644 --- a/frontend/storybook/stories/Bar.stories.tsx +++ b/frontend/storybook/stories/Bar.stories.tsx @@ -1,12 +1,10 @@ -import { Component } from "solid-js"; - import preview from "#.storybook/preview"; import { Bar } from "../../src/ts/components/common/Bar"; const meta = preview.meta({ title: "Common/Bar", - component: Bar as Component, + component: Bar, parameters: { layout: "padded", }, diff --git a/frontend/storybook/stories/Button.stories.tsx b/frontend/storybook/stories/Button.stories.tsx index 2e6e77d4ad1c..de1b91e2d6aa 100644 --- a/frontend/storybook/stories/Button.stories.tsx +++ b/frontend/storybook/stories/Button.stories.tsx @@ -1,4 +1,3 @@ -import { Component } from "solid-js"; import { fn } from "storybook/test"; import preview from "#.storybook/preview"; @@ -7,7 +6,7 @@ import { Button } from "../../src/ts/components/common/Button"; const meta = preview.meta({ title: "Common/Button", - component: Button as Component, + component: Button, parameters: { layout: "centered", }, diff --git a/frontend/storybook/stories/ChartJs.stories.tsx b/frontend/storybook/stories/ChartJs.stories.tsx index 0e14008cd53e..28a691436fba 100644 --- a/frontend/storybook/stories/ChartJs.stories.tsx +++ b/frontend/storybook/stories/ChartJs.stories.tsx @@ -1,12 +1,10 @@ -import { Component } from "solid-js"; - import preview from "#.storybook/preview"; import { ChartJs } from "../../src/ts/components/common/ChartJs"; const meta = preview.meta({ title: "Common/ChartJs", - component: ChartJs as Component, + component: ChartJs, parameters: { layout: "padded", }, diff --git a/frontend/storybook/stories/Checkbox.stories.tsx b/frontend/storybook/stories/Checkbox.stories.tsx index c92870caedf1..21344717895d 100644 --- a/frontend/storybook/stories/Checkbox.stories.tsx +++ b/frontend/storybook/stories/Checkbox.stories.tsx @@ -1,5 +1,5 @@ import { AnyFieldApi } from "@tanstack/solid-form"; -import { Accessor, Component, createSignal } from "solid-js"; +import { createSignal } from "solid-js"; import preview from "#.storybook/preview"; @@ -21,11 +21,7 @@ function createFieldMock(options: { name?: string; value?: boolean }) { const meta = preview.meta({ title: "UI/Form/Checkbox", - component: Checkbox as Component<{ - field: Accessor; - label?: string; - disabled?: boolean; - }>, + component: Checkbox, parameters: { layout: "centered", }, diff --git a/frontend/storybook/stories/DataTable.stories.tsx b/frontend/storybook/stories/DataTable.stories.tsx index dc894c2ede9e..2b0a7b6a715a 100644 --- a/frontend/storybook/stories/DataTable.stories.tsx +++ b/frontend/storybook/stories/DataTable.stories.tsx @@ -1,4 +1,4 @@ -import { Component, createSignal } from "solid-js"; +import { createSignal } from "solid-js"; import preview from "#.storybook/preview"; @@ -48,7 +48,7 @@ const columns: DataTableColumnDef[] = [ const meta = preview.meta({ title: "UI/DataTable", - component: DataTable as Component, + component: DataTable, parameters: { layout: "padded", }, diff --git a/frontend/storybook/stories/DiscordAvatar.stories.tsx b/frontend/storybook/stories/DiscordAvatar.stories.tsx index 45f125d5a8ea..b7d119d90501 100644 --- a/frontend/storybook/stories/DiscordAvatar.stories.tsx +++ b/frontend/storybook/stories/DiscordAvatar.stories.tsx @@ -1,12 +1,10 @@ -import { Component } from "solid-js"; - import preview from "#.storybook/preview"; import { DiscordAvatar } from "../../src/ts/components/common/DiscordAvatar"; const meta = preview.meta({ title: "Common/DiscordAvatar", - component: DiscordAvatar as Component, + component: DiscordAvatar, parameters: { layout: "centered", }, diff --git a/frontend/storybook/stories/Fa.stories.tsx b/frontend/storybook/stories/Fa.stories.tsx index 9ac01293a570..93f681c55fa7 100644 --- a/frontend/storybook/stories/Fa.stories.tsx +++ b/frontend/storybook/stories/Fa.stories.tsx @@ -1,12 +1,10 @@ -import { Component } from "solid-js"; - import preview from "#.storybook/preview"; import { Fa } from "../../src/ts/components/common/Fa"; const meta = preview.meta({ title: "Common/Fa", - component: Fa as Component, + component: Fa, parameters: { layout: "centered", }, diff --git a/frontend/storybook/stories/FieldIndicator.stories.tsx b/frontend/storybook/stories/FieldIndicator.stories.tsx index 2cbf63dc7919..4014d7e5368b 100644 --- a/frontend/storybook/stories/FieldIndicator.stories.tsx +++ b/frontend/storybook/stories/FieldIndicator.stories.tsx @@ -1,5 +1,4 @@ import { AnyFieldApi } from "@tanstack/solid-form"; -import { Component } from "solid-js"; import preview from "#.storybook/preview"; @@ -41,7 +40,7 @@ function createFieldMock(meta: MetaState) { const meta = preview.meta({ title: "UI/Form/FieldIndicator", - component: FieldIndicator as Component, + component: FieldIndicator, parameters: { layout: "centered", }, diff --git a/frontend/storybook/stories/H2.stories.tsx b/frontend/storybook/stories/H2.stories.tsx index e700a19516b6..2ebb763eebf5 100644 --- a/frontend/storybook/stories/H2.stories.tsx +++ b/frontend/storybook/stories/H2.stories.tsx @@ -1,12 +1,10 @@ -import { Component } from "solid-js"; - import preview from "#.storybook/preview"; import { H2 } from "../../src/ts/components/common/Headers"; const metaH2 = preview.meta({ title: "Common/H2", - component: H2 as Component, + component: H2, parameters: { layout: "centered", }, diff --git a/frontend/storybook/stories/H3.stories.tsx b/frontend/storybook/stories/H3.stories.tsx index 597f4ea22759..3ea198ea02e0 100644 --- a/frontend/storybook/stories/H3.stories.tsx +++ b/frontend/storybook/stories/H3.stories.tsx @@ -1,12 +1,10 @@ -import { Component } from "solid-js"; - import preview from "#.storybook/preview"; import { H3 } from "../../src/ts/components/common/Headers"; const meta = preview.meta({ title: "Common/H3", - component: H3 as Component, + component: H3, parameters: { layout: "centered", }, diff --git a/frontend/storybook/stories/InputField.stories.tsx b/frontend/storybook/stories/InputField.stories.tsx index f08554a32892..5540b0390765 100644 --- a/frontend/storybook/stories/InputField.stories.tsx +++ b/frontend/storybook/stories/InputField.stories.tsx @@ -1,5 +1,4 @@ import { AnyFieldApi } from "@tanstack/solid-form"; -import { Component } from "solid-js"; import preview from "#.storybook/preview"; @@ -49,7 +48,7 @@ function createFieldMock(options: { const meta = preview.meta({ title: "UI/Form/InputField", - component: InputField as Component, + component: InputField, parameters: { layout: "centered", }, diff --git a/frontend/storybook/stories/NotificationBubble.stories.tsx b/frontend/storybook/stories/NotificationBubble.stories.tsx index 2a10a2f8f37f..8a8740ff1708 100644 --- a/frontend/storybook/stories/NotificationBubble.stories.tsx +++ b/frontend/storybook/stories/NotificationBubble.stories.tsx @@ -6,7 +6,7 @@ import { NotificationBubble } from "../../src/ts/components/common/NotificationB const meta = preview.meta({ title: "Common/NotificationBubble", - component: NotificationBubble as Component, + component: NotificationBubble, parameters: { layout: "centered", }, diff --git a/frontend/storybook/stories/SlimSelect.stories.tsx b/frontend/storybook/stories/SlimSelect.stories.tsx index c3575b681c1b..36c3dfbbd44b 100644 --- a/frontend/storybook/stories/SlimSelect.stories.tsx +++ b/frontend/storybook/stories/SlimSelect.stories.tsx @@ -1,4 +1,4 @@ -import { Component, createSignal } from "solid-js"; +import { createSignal } from "solid-js"; import { fn } from "storybook/test"; import preview from "#.storybook/preview"; @@ -7,7 +7,7 @@ import SlimSelect from "../../src/ts/components/ui/SlimSelect"; const meta = preview.meta({ title: "UI/SlimSelect", - component: SlimSelect as Component, + component: SlimSelect, parameters: { layout: "centered", }, diff --git a/frontend/storybook/stories/User.stories.tsx b/frontend/storybook/stories/User.stories.tsx index 4dad99ad761e..868ed2b8bbb8 100644 --- a/frontend/storybook/stories/User.stories.tsx +++ b/frontend/storybook/stories/User.stories.tsx @@ -1,4 +1,4 @@ -import { Component, createSignal, onCleanup } from "solid-js"; +import { createSignal, onCleanup } from "solid-js"; import preview from "#.storybook/preview"; @@ -6,7 +6,7 @@ import { User } from "../../src/ts/components/common/User"; const meta = preview.meta({ title: "Common/User", - component: User as Component, + component: User, parameters: { layout: "centered", }, diff --git a/frontend/storybook/stories/UserBadge.stories.tsx b/frontend/storybook/stories/UserBadge.stories.tsx index b5b710eeaecd..752befa81dd1 100644 --- a/frontend/storybook/stories/UserBadge.stories.tsx +++ b/frontend/storybook/stories/UserBadge.stories.tsx @@ -1,12 +1,10 @@ -import { Component } from "solid-js"; - import preview from "#.storybook/preview"; import { UserBadge } from "../../src/ts/components/common/UserBadge"; const meta = preview.meta({ title: "Common/UserBadge", - component: UserBadge as Component, + component: UserBadge, parameters: { layout: "centered", }, diff --git a/frontend/storybook/stories/UserFlags.stories.tsx b/frontend/storybook/stories/UserFlags.stories.tsx index 49909e93bad3..32659ad95381 100644 --- a/frontend/storybook/stories/UserFlags.stories.tsx +++ b/frontend/storybook/stories/UserFlags.stories.tsx @@ -1,12 +1,10 @@ -import { Component } from "solid-js"; - import preview from "#.storybook/preview"; import { UserFlags } from "../../src/ts/components/common/UserFlags"; const meta = preview.meta({ title: "Common/UserFlags", - component: UserFlags as Component, + component: UserFlags, parameters: { layout: "centered", }, diff --git a/frontend/storybook/stories/UserProfile.stories.tsx b/frontend/storybook/stories/UserProfile.stories.tsx index 6b6339f36e57..3b226b4374b4 100644 --- a/frontend/storybook/stories/UserProfile.stories.tsx +++ b/frontend/storybook/stories/UserProfile.stories.tsx @@ -1,5 +1,4 @@ import { UserProfile as UserProfileType } from "@monkeytype/schemas/users"; -import { Component } from "solid-js"; import preview from "#.storybook/preview"; @@ -156,7 +155,7 @@ const baseProfile: UserProfileType = { const meta = preview.meta({ title: "Pages/UserProfile", - component: UserProfile as Component, + component: UserProfile, parameters: { layout: "padded", }, diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 962821e6c4d5..44ee9a85b5c2 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -205,7 +205,7 @@ function getBuildOptions({ emptyOutDir: true, outDir: "../dist", assetsInlineLimit: 0, //dont inline small files as data - rollupOptions: { + rolldownOptions: { input: { monkeytype: path.resolve(__dirname, "src/index.html"), email: path.resolve(__dirname, "src/email-handler.html"), @@ -275,7 +275,7 @@ function getBuildOptions({ }, }, }, - } as BuildEnvironmentOptions; + }; } function getCssOptions({ diff --git a/frontend/vitest.config.ts b/frontend/vitest.config.ts index 2ec39aa7c064..b85c92d647dd 100644 --- a/frontend/vitest.config.ts +++ b/frontend/vitest.config.ts @@ -66,7 +66,7 @@ export const projects: UserWorkspaceConfig[] = [ ]; export default defineConfig({ test: { - projects: projects as never, + projects: projects, coverage: { include: ["**/*.ts", "**/*.tsx"], }, diff --git a/package.json b/package.json index 8d768d573981..65d6c34911cb 100644 --- a/package.json +++ b/package.json @@ -71,9 +71,9 @@ "knip": "2.19.2", "lint-staged": "13.2.3", "only-allow": "1.2.1", - "oxfmt": "0.53.0", - "oxlint": "1.68.0", - "oxlint-tsgolint": "0.23.0", + "oxfmt": "0.58.0", + "oxlint": "1.73.0", + "oxlint-tsgolint": "0.24.0", "prettier": "3.7.1", "stylelint": "17.6.0", "stylelint-config-standard": "40.0.0", diff --git a/packages/challenges/package.json b/packages/challenges/package.json index a3ffc505242d..717fc67cba74 100644 --- a/packages/challenges/package.json +++ b/packages/challenges/package.json @@ -26,8 +26,8 @@ "@monkeytype/typescript-config": "workspace:*", "@types/node": "24.9.1", "madge": "8.0.0", - "oxlint": "1.68.0", - "oxlint-tsgolint": "0.23.0", + "oxlint": "1.73.0", + "oxlint-tsgolint": "0.24.0", "tsup": "8.4.0", "typescript": "6.0.2", "vitest": "4.1.0" diff --git a/packages/contracts/package.json b/packages/contracts/package.json index a3e892506d27..9fa967859c2d 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -30,8 +30,8 @@ "@monkeytype/typescript-config": "workspace:*", "@types/node": "24.9.1", "madge": "8.0.0", - "oxlint": "1.68.0", - "oxlint-tsgolint": "0.23.0", + "oxlint": "1.73.0", + "oxlint-tsgolint": "0.24.0", "tsup": "8.4.0", "typescript": "6.0.2", "vitest": "4.1.0" diff --git a/packages/funbox/package.json b/packages/funbox/package.json index afa7b22fc152..1bb357ba00b2 100644 --- a/packages/funbox/package.json +++ b/packages/funbox/package.json @@ -26,8 +26,8 @@ "@monkeytype/typescript-config": "workspace:*", "@types/node": "24.9.1", "madge": "8.0.0", - "oxlint": "1.68.0", - "oxlint-tsgolint": "0.23.0", + "oxlint": "1.73.0", + "oxlint-tsgolint": "0.24.0", "tsup": "8.4.0", "typescript": "6.0.2", "vitest": "4.1.0" diff --git a/packages/oxlint-config/rules/enabled.jsonc b/packages/oxlint-config/rules/enabled.jsonc index 3519cf9e551d..a4d2b5bd724b 100644 --- a/packages/oxlint-config/rules/enabled.jsonc +++ b/packages/oxlint-config/rules/enabled.jsonc @@ -50,7 +50,12 @@ "no-self-compare": "error", "no-throw-literal": "error", "no-constant-condition": "error", - "no-constant-binary-expression": "error", + "no-constant-binary-expression": [ + "error", + { + "checkRelationalComparisons": true, + }, + ], "no-unnecessary-type-constraint": "error", "no-useless-constructor": "error", "prefer-literal-enum-member": "error", diff --git a/packages/release/package.json b/packages/release/package.json index 288acbc8f241..90258988b376 100644 --- a/packages/release/package.json +++ b/packages/release/package.json @@ -20,7 +20,7 @@ }, "devDependencies": { "nodemon": "3.1.14", - "oxlint": "1.68.0", - "oxlint-tsgolint": "0.23.0" + "oxlint": "1.73.0", + "oxlint-tsgolint": "0.24.0" } } diff --git a/packages/schemas/package.json b/packages/schemas/package.json index aceb7c028a40..6af28147cd48 100644 --- a/packages/schemas/package.json +++ b/packages/schemas/package.json @@ -30,8 +30,8 @@ "@monkeytype/typescript-config": "workspace:*", "@types/node": "24.9.1", "madge": "8.0.0", - "oxlint": "1.68.0", - "oxlint-tsgolint": "0.23.0", + "oxlint": "1.73.0", + "oxlint-tsgolint": "0.24.0", "tsup": "8.4.0", "typescript": "6.0.2", "vitest": "4.1.0" diff --git a/packages/tsup-config/package.json b/packages/tsup-config/package.json index d8981ffe3f47..ffd39d4ac591 100644 --- a/packages/tsup-config/package.json +++ b/packages/tsup-config/package.json @@ -18,8 +18,8 @@ "devDependencies": { "@monkeytype/typescript-config": "workspace:*", "@types/node": "24.9.1", - "oxlint": "1.68.0", - "oxlint-tsgolint": "0.23.0", + "oxlint": "1.73.0", + "oxlint-tsgolint": "0.24.0", "typescript": "6.0.2" }, "peerDependencies": { diff --git a/packages/util/package.json b/packages/util/package.json index caaabed5cd7a..f01fced3010a 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -21,8 +21,8 @@ "@monkeytype/typescript-config": "workspace:*", "@types/node": "24.9.1", "madge": "8.0.0", - "oxlint": "1.68.0", - "oxlint-tsgolint": "0.23.0", + "oxlint": "1.73.0", + "oxlint-tsgolint": "0.24.0", "tsup": "8.4.0", "typescript": "6.0.2", "vitest": "4.1.0", diff --git a/packages/util/src/json.ts b/packages/util/src/json.ts index f0c264dc1536..df67334c12c8 100644 --- a/packages/util/src/json.ts +++ b/packages/util/src/json.ts @@ -37,7 +37,9 @@ export function parseWithSchema( if (fallback === undefined) { throw new Error(`Invalid JSON: ${error.message}`); } - return fallback as unknown; + + // oxlint-disable-next-line typescript/no-unsafe-return + return fallback; } const safeParse = schema.safeParse(jsonParsed); @@ -64,7 +66,8 @@ export function parseWithSchema( .join(", ")}`, ); } - return fallback as unknown; + // oxlint-disable-next-line typescript/no-unsafe-return + return fallback; } return safeParseMigrated.data as T; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bff67bf9d916..f6e1e81657d7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,7 +25,7 @@ importers: version: 24.9.1 '@vitest/coverage-v8': specifier: 4.1.5 - version: 4.1.5(vitest@4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))) + version: 4.1.5(vitest@4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))) caniuse-lite: specifier: 1.0.30001778 version: 1.0.30001778 @@ -45,14 +45,14 @@ importers: specifier: 1.2.1 version: 1.2.1 oxfmt: - specifier: 0.53.0 - version: 0.53.0 + specifier: 0.58.0 + version: 0.58.0 oxlint: - specifier: 1.68.0 - version: 1.68.0(oxlint-tsgolint@0.23.0) + specifier: 1.73.0 + version: 1.73.0(oxlint-tsgolint@0.24.0) oxlint-tsgolint: - specifier: 0.23.0 - version: 0.23.0 + specifier: 0.24.0 + version: 0.24.0 prettier: specifier: 3.7.1 version: 3.7.1 @@ -70,7 +70,7 @@ importers: version: 2.9.14 vitest: specifier: 4.1.0 - version: 4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + version: 4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) yaml: specifier: 2.8.3 version: 2.8.3 @@ -248,7 +248,7 @@ importers: version: 10.0.0 '@vitest/coverage-v8': specifier: 4.1.5 - version: 4.1.5(vitest@4.1.0(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2))) + version: 4.1.5(vitest@4.1.0(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.2))) concurrently: specifier: 8.2.2 version: 8.2.2 @@ -256,11 +256,11 @@ importers: specifier: 2.0.2 version: 2.0.2 oxlint: - specifier: 1.68.0 - version: 1.68.0(oxlint-tsgolint@0.23.0) + specifier: 1.73.0 + version: 1.73.0(oxlint-tsgolint@0.24.0) oxlint-tsgolint: - specifier: 0.23.0 - version: 0.23.0 + specifier: 0.24.0 + version: 0.24.0 readline-sync: specifier: 1.4.10 version: 1.4.10 @@ -278,7 +278,7 @@ importers: version: 6.0.2 vitest: specifier: 4.1.0 - version: 4.1.0(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2)) + version: 4.1.0(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.2)) yaml: specifier: 2.8.2 version: 2.8.2 @@ -444,7 +444,7 @@ importers: version: 0.8.10(solid-js@1.9.13) '@tailwindcss/vite': specifier: 4.3.2 - version: 4.3.2(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + version: 4.3.2(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) '@tanstack/eslint-plugin-query': specifier: 5.101.0 version: 5.101.0(eslint@9.39.1(jiti@2.7.0))(typescript@6.0.2) @@ -492,7 +492,7 @@ importers: version: 5.0.2 '@vitest/coverage-v8': specifier: 4.1.5 - version: 4.1.5(vitest@4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))) + version: 4.1.5(vitest@4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))) autoprefixer: specifier: 10.4.27 version: 10.4.27(postcss@8.5.8) @@ -533,11 +533,11 @@ importers: specifier: 8.0.1 version: 8.0.1 oxlint: - specifier: 1.68.0 - version: 1.68.0(oxlint-tsgolint@0.23.0) + specifier: 1.73.0 + version: 1.73.0(oxlint-tsgolint@0.24.0) oxlint-tsgolint: - specifier: 0.23.0 - version: 0.23.0 + specifier: 0.24.0 + version: 0.24.0 postcss: specifier: 8.5.8 version: 8.5.8 @@ -546,7 +546,7 @@ importers: version: 1.70.0 solid-devtools: specifier: 0.34.5 - version: 0.34.5(solid-js@1.9.13)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + version: 0.34.5(solid-js@1.9.13)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) solid-js: specifier: 1.9.13 version: 1.9.13 @@ -567,7 +567,7 @@ importers: version: 3.0.0 vite: specifier: 8.0.5 - version: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) + version: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) vite-bundle-visualizer: specifier: 1.2.1 version: 1.2.1(rollup@2.80.0) @@ -576,19 +576,19 @@ importers: version: 1.1.2 vite-plugin-inspect: specifier: 11.3.3 - version: 11.3.3(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + version: 11.3.3(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) vite-plugin-minify: specifier: 2.1.0 - version: 2.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + version: 2.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) vite-plugin-pwa: specifier: 1.1.0 - version: 1.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))(workbox-build@7.1.1(@types/babel__core@7.20.5))(workbox-window@7.1.0) + version: 1.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))(workbox-build@7.1.1(@types/babel__core@7.20.5))(workbox-window@7.1.0) vite-plugin-solid: specifier: 2.11.11 - version: 2.11.11(@testing-library/jest-dom@6.9.1)(solid-js@1.9.13)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + version: 2.11.11(@testing-library/jest-dom@6.9.1)(solid-js@1.9.13)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) vitest: specifier: 4.1.0 - version: 4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + version: 4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) frontend/storybook: dependencies: @@ -604,7 +604,7 @@ importers: version: 10.2.16(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) '@storybook/addon-docs': specifier: ^10.2.14 - version: 10.2.16(@types/react@19.2.14)(esbuild@0.27.7)(rollup@4.60.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + version: 10.2.16(@types/react@19.2.14)(esbuild@0.27.7)(rollup@4.60.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) '@storybook/addon-links': specifier: ^10.2.14 version: 10.2.16(react@18.3.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) @@ -613,22 +613,22 @@ importers: version: 10.4.1(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) '@storybook/addon-vitest': specifier: ^10.2.14 - version: 10.2.16(@vitest/browser-playwright@4.0.18)(@vitest/browser@4.1.8(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0))(@vitest/runner@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vitest@4.1.0) + version: 10.2.16(@vitest/browser-playwright@4.0.18)(@vitest/browser@4.1.8(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0))(@vitest/runner@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vitest@4.1.0) '@storybook/builder-vite': specifier: ^10.2.14 - version: 10.2.16(esbuild@0.27.7)(rollup@4.60.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + version: 10.2.16(esbuild@0.27.7)(rollup@4.60.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) '@tailwindcss/vite': specifier: ^4.2.1 - version: 4.2.1(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + version: 4.2.1(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) '@vitest/browser': specifier: ^4.1.8 - version: 4.1.8(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0) + version: 4.1.8(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0) '@vitest/browser-playwright': specifier: ^4.0.18 - version: 4.0.18(playwright@1.58.2)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0) + version: 4.0.18(playwright@1.58.2)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0) '@vitest/coverage-v8': specifier: ^4.1.5 - version: 4.1.5(@vitest/browser@4.1.8(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0))(vitest@4.1.0) + version: 4.1.5(@vitest/browser@4.1.8(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0))(vitest@4.1.0) playwright: specifier: ^1.58.2 version: 1.58.2 @@ -640,13 +640,13 @@ importers: version: 10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) storybook-solidjs-vite: specifier: ^10.1.1 - version: 10.1.1(esbuild@0.27.7)(rollup@4.60.1)(solid-js@1.9.13)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@6.0.2)(vite-plugin-solid@2.11.11(@testing-library/jest-dom@6.9.1)(solid-js@1.9.13)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + version: 10.1.1(esbuild@0.27.7)(rollup@4.60.1)(solid-js@1.9.13)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@6.0.2)(vite-plugin-solid@2.11.11(@testing-library/jest-dom@6.9.1)(solid-js@1.9.13)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) vite: specifier: ^7.3.2 - version: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) + version: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) vitest: specifier: ^4.1.0 - version: 4.1.0(@types/node@24.9.1)(@vitest/browser-playwright@4.0.18)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + version: 4.1.0(@types/node@24.9.1)(@vitest/browser-playwright@4.0.18)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) packages/challenges: dependencies: @@ -667,11 +667,11 @@ importers: specifier: 8.0.0 version: 8.0.0(typescript@6.0.2) oxlint: - specifier: 1.68.0 - version: 1.68.0(oxlint-tsgolint@0.23.0) + specifier: 1.73.0 + version: 1.73.0(oxlint-tsgolint@0.24.0) oxlint-tsgolint: - specifier: 0.23.0 - version: 0.23.0 + specifier: 0.24.0 + version: 0.24.0 tsup: specifier: 8.4.0 version: 8.4.0(jiti@2.7.0)(postcss@8.5.8)(tsx@4.21.0)(typescript@6.0.2)(yaml@2.8.3) @@ -680,7 +680,7 @@ importers: version: 6.0.2 vitest: specifier: 4.1.0 - version: 4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + version: 4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.25.0)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) packages/contracts: dependencies: @@ -707,11 +707,11 @@ importers: specifier: 8.0.0 version: 8.0.0(typescript@6.0.2) oxlint: - specifier: 1.68.0 - version: 1.68.0(oxlint-tsgolint@0.23.0) + specifier: 1.73.0 + version: 1.73.0(oxlint-tsgolint@0.24.0) oxlint-tsgolint: - specifier: 0.23.0 - version: 0.23.0 + specifier: 0.24.0 + version: 0.24.0 tsup: specifier: 8.4.0 version: 8.4.0(jiti@2.7.0)(postcss@8.5.8)(tsx@4.21.0)(typescript@6.0.2)(yaml@2.8.3) @@ -720,7 +720,7 @@ importers: version: 6.0.2 vitest: specifier: 4.1.0 - version: 4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + version: 4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) packages/funbox: dependencies: @@ -744,11 +744,11 @@ importers: specifier: 8.0.0 version: 8.0.0(typescript@6.0.2) oxlint: - specifier: 1.68.0 - version: 1.68.0(oxlint-tsgolint@0.23.0) + specifier: 1.73.0 + version: 1.73.0(oxlint-tsgolint@0.24.0) oxlint-tsgolint: - specifier: 0.23.0 - version: 0.23.0 + specifier: 0.24.0 + version: 0.24.0 tsup: specifier: 8.4.0 version: 8.4.0(jiti@2.7.0)(postcss@8.5.8)(tsx@4.21.0)(typescript@6.0.2)(yaml@2.8.3) @@ -757,7 +757,7 @@ importers: version: 6.0.2 vitest: specifier: 4.1.0 - version: 4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + version: 4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) packages/oxlint-config: devDependencies: @@ -781,11 +781,11 @@ importers: specifier: 3.1.14 version: 3.1.14 oxlint: - specifier: 1.68.0 - version: 1.68.0(oxlint-tsgolint@0.23.0) + specifier: 1.73.0 + version: 1.73.0(oxlint-tsgolint@0.24.0) oxlint-tsgolint: - specifier: 0.23.0 - version: 0.23.0 + specifier: 0.24.0 + version: 0.24.0 packages/schemas: dependencies: @@ -809,11 +809,11 @@ importers: specifier: 8.0.0 version: 8.0.0(typescript@6.0.2) oxlint: - specifier: 1.68.0 - version: 1.68.0(oxlint-tsgolint@0.23.0) + specifier: 1.73.0 + version: 1.73.0(oxlint-tsgolint@0.24.0) oxlint-tsgolint: - specifier: 0.23.0 - version: 0.23.0 + specifier: 0.24.0 + version: 0.24.0 tsup: specifier: 8.4.0 version: 8.4.0(jiti@2.7.0)(postcss@8.5.8)(tsx@4.21.0)(typescript@6.0.2)(yaml@2.8.3) @@ -822,7 +822,7 @@ importers: version: 6.0.2 vitest: specifier: 4.1.0 - version: 4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + version: 4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) packages/tsup-config: dependencies: @@ -837,11 +837,11 @@ importers: specifier: 24.9.1 version: 24.9.1 oxlint: - specifier: 1.68.0 - version: 1.68.0(oxlint-tsgolint@0.23.0) + specifier: 1.73.0 + version: 1.73.0(oxlint-tsgolint@0.24.0) oxlint-tsgolint: - specifier: 0.23.0 - version: 0.23.0 + specifier: 0.24.0 + version: 0.24.0 typescript: specifier: 6.0.2 version: 6.0.2 @@ -863,11 +863,11 @@ importers: specifier: 8.0.0 version: 8.0.0(typescript@6.0.2) oxlint: - specifier: 1.68.0 - version: 1.68.0(oxlint-tsgolint@0.23.0) + specifier: 1.73.0 + version: 1.73.0(oxlint-tsgolint@0.24.0) oxlint-tsgolint: - specifier: 0.23.0 - version: 0.23.0 + specifier: 0.24.0 + version: 0.24.0 tsup: specifier: 8.4.0 version: 8.4.0(jiti@2.7.0)(postcss@8.5.8)(tsx@4.21.0)(typescript@6.0.2)(yaml@2.8.3) @@ -876,7 +876,7 @@ importers: version: 6.0.2 vitest: specifier: 4.1.0 - version: 4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + version: 4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) zod: specifier: 3.23.8 version: 3.23.8 @@ -3226,260 +3226,260 @@ packages: '@oxc-project/types@0.122.0': resolution: {integrity: sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA==} - '@oxfmt/binding-android-arm-eabi@0.53.0': - resolution: {integrity: sha512-XfVM8AmIovBTKXCt14Op5wbfcoM8418nttd+nhMgM3RAVaJg1MtJc73FyWfUt0oxLyBGVwfniNVUsbV/b3VmPg==} + '@oxfmt/binding-android-arm-eabi@0.58.0': + resolution: {integrity: sha512-Uz62sHduGGPftXtILGyxdSW4PX82rUg+rfdNqhsgxe881g4rIoXlIqmZQ6HVKcF4f+F8qMhdD03Bx5u7gmeTdg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxfmt/binding-android-arm64@0.53.0': - resolution: {integrity: sha512-btHDfXckwdf9zgyAVznfZkf+GVyB0I1m1hlvaOMRx2xoyz3hphfPX97s89J3wfCN8QBETLtk4lQUaeOkrMuQOg==} + '@oxfmt/binding-android-arm64@0.58.0': + resolution: {integrity: sha512-rD0lRaJp1b+9vw6X4A2dJWKukd6X8yxiicN4JxXcXayolmUypRZxk+lKR+fVOu5q/iYc0fh5fR4bgmfOfVlbaA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxfmt/binding-darwin-arm64@0.53.0': - resolution: {integrity: sha512-k2RjMcSTkHjoOlsVGbL35JVzXL+oQco3GHPl/5kjebVF4oHNfE24In8F5isqBh9LBJucycWHKDXdGrCchdWcHQ==} + '@oxfmt/binding-darwin-arm64@0.58.0': + resolution: {integrity: sha512-uzbPPk7O6M+w2K65vcQ1woga3wgP8zghjL1KOG5b6qJ8dvYHZJ1VShaslg2KOK6yQIwCQtcMCXqLBM6sqXUNTg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxfmt/binding-darwin-x64@0.53.0': - resolution: {integrity: sha512-65jIBE2H1l5SSs16fmv6/7b6sAx/WpvnsgDhVWK9qSjNFDUro7MPQ6q5UhpY7kl46yltfR046iAnxy/Bzqbiew==} + '@oxfmt/binding-darwin-x64@0.58.0': + resolution: {integrity: sha512-L0nKYDxU32oxeQqJj21W9SlIMnf81VZEhyah6iDvFhf5q0oynq498Fopth7blErUJVBpVtxQ98RMCfMPqpJX6w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxfmt/binding-freebsd-x64@0.53.0': - resolution: {integrity: sha512-oYe1gkz7U49PCYrS9147d2fJZj8mDI4Di6AvlsU5fu9p+Tq8S7qqOMSZjUiVTLX8bXuSA9Lk/tIxuegVjkNYRA==} + '@oxfmt/binding-freebsd-x64@0.58.0': + resolution: {integrity: sha512-woNwfD58dC5PGS9LSLSD5JYfo/EFK5iG9vhDWkcCg3q78ag7KC8bpDqgvPHrMoXpx83OLXxoSOhu6z8FsVTHlg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxfmt/binding-linux-arm-gnueabihf@0.53.0': - resolution: {integrity: sha512-ailB2vLzGi629tymdAb2VYJyEHref7oqGxP+tRBrtRBxQrb6NV55JMT7xtGZ8uTeG2+Y9zojqW4LhJYxQnz9Pg==} + '@oxfmt/binding-linux-arm-gnueabihf@0.58.0': + resolution: {integrity: sha512-Sqs8nMLxuQpY21NKJ1u4stPDmO5hskBCNNh2E3AdCfI1QqWtf4m+Qn4mGEIUO4KGmuq3SWc/SZ80uy5IiwTCDw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxfmt/binding-linux-arm-musleabihf@0.53.0': - resolution: {integrity: sha512-abh4mWBvOvD966sobqF7r103y2yYx7Rb4WGHLOS4+5igGqLbbPxS9aK5+45D6iUY7dWMsk3Muz9a8gUtufvqJA==} + '@oxfmt/binding-linux-arm-musleabihf@0.58.0': + resolution: {integrity: sha512-Vd4exzBI5B5hB9m22JiTQzIL23WvHo/Pe+sNXPNeBLXSP9swCBPKCEBRwKpmpQzYhlgYaCgfPcGXPKAJBRIiZQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxfmt/binding-linux-arm64-gnu@0.53.0': - resolution: {integrity: sha512-z73PvuhJ8qA+cDbaiqbtopHglA91U4+y5wn2sTJJrnpB957d5P33FEuyP3DQIFd7ofljmDmfVT4G0CVGHZaJWg==} + '@oxfmt/binding-linux-arm64-gnu@0.58.0': + resolution: {integrity: sha512-bUWi5mHV+4Vi56RLHE1h6q/HHfwAIT3XoB9vJAVeRzfu5NriXM8y6eeJu0vlKa0C9kq2rq1sOWRClhdLHPocrg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@oxfmt/binding-linux-arm64-musl@0.53.0': - resolution: {integrity: sha512-I6bhOTroqc3ThrwZ89l2k3ivKuELhdPLbAcJhRNyjWvlgwb0vjRgEnVL1XLx5Jud04/ypNRZBykAWrSk6l/D+g==} + '@oxfmt/binding-linux-arm64-musl@0.58.0': + resolution: {integrity: sha512-2ZHxemzgHcjtktAuVUwSoyXmGo/t+aF5tS1ciPpPei4rhSyrz3JOqDosXXrmhN/yLUSzJjtuW7ToTWqfQpCj2w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@oxfmt/binding-linux-ppc64-gnu@0.53.0': - resolution: {integrity: sha512-w0p3JzB/PkkQjXALMJMqP9YfP3yq4w6zGsu5kezQmUnxRkN3b/Theg2l/nDgBsOcczxS3gL6Gam5XNAVrO6QJQ==} + '@oxfmt/binding-linux-ppc64-gnu@0.58.0': + resolution: {integrity: sha512-AwKkVwjVmFQ3bcO7j0McGYAqCKH2a326fswfofng/E8VewCT/raeeGQr4huVhY704deK8AWASSTlxzMj0eZc6Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] - '@oxfmt/binding-linux-riscv64-gnu@0.53.0': - resolution: {integrity: sha512-mzBhF6k1Yq1K/dqDmVe/AAafnlJfEpx7yfUiksyeWXJk5iSzZqBSxcsa02zIytYgQFRZ7h6WPZfwHg/DoOE1Kw==} + '@oxfmt/binding-linux-riscv64-gnu@0.58.0': + resolution: {integrity: sha512-xsRpTxfUnJF8D3AUKko/qyWdjw4GZVHlCVFuGlzSCTeewLmykKINW8em1+wx+axsDVtJJcMtvsiaXggXxrlHgw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] - '@oxfmt/binding-linux-riscv64-musl@0.53.0': - resolution: {integrity: sha512-AlFCpnRQhogQFzZXWbO6xB6/Udy745L+eQNmDPGg7G/OeWsYmJc4jZYfUN5pQg0reOPWSED2mOQqKZOJM1U8cA==} + '@oxfmt/binding-linux-riscv64-musl@0.58.0': + resolution: {integrity: sha512-Z4AYOTcy7nYEIiXwD62PlerimyYRcfJOgUbQAEBjXz098kxKuERBlRntofGy69HHhe9E0TLVNMl1yspVNu+efw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] - '@oxfmt/binding-linux-s390x-gnu@0.53.0': - resolution: {integrity: sha512-XD4ulY4f1DWbuuZXAqxhVn+gdPmrhnmojWtFN78ctVoupmS845fGhsUrk1HZXKQI+iymbaiz9vAjPsghHNQ7Ag==} + '@oxfmt/binding-linux-s390x-gnu@0.58.0': + resolution: {integrity: sha512-A3nhhtZPC/TKVWOPj9q/H3p2znJDCcHWYlJBhWL8hGq/bFmBaNBHC8Np6E581yVq1w9Mi3rMDNzDalWvtUfJtQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] - '@oxfmt/binding-linux-x64-gnu@0.53.0': - resolution: {integrity: sha512-xg8KWX0QnxmYWRe60CgHYWXI0ZOtBbqTsXvWiWrcl2XUHJ3fht2QerOk2iWvylzX3zNT2GpvBRxGoR4d3sxPRQ==} + '@oxfmt/binding-linux-x64-gnu@0.58.0': + resolution: {integrity: sha512-2g+tVkgwqphw8R4hgo+kF4oz8+P5RwVOtr9+irsC7uwEp0e9j7Crw8kDGKL20uYlLPD7g02DqA61mC/UNYx98A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@oxfmt/binding-linux-x64-musl@0.53.0': - resolution: {integrity: sha512-MWExpYBGvl+pIvVB/gj/CcWlN2al8AizT7rUbtaYaWNoQkhWARM6W3qpgoCr72CYSN9PborzPmM5MIRe2BrNdA==} + '@oxfmt/binding-linux-x64-musl@0.58.0': + resolution: {integrity: sha512-rc15P6AbyyB7426aN8AakLd02Trb3a6ML/mmfAQeVHJEfVofWLcWIrBdy6zDEY+DIaL/s8E4GGPboVw+oP3+EA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@oxfmt/binding-openharmony-arm64@0.53.0': - resolution: {integrity: sha512-u4sajgO4nxgmJIgc/y2AqPhkdbOkQH8WugXpA1+pW0ESQhvGZ1oGq61Q4xMbJHJU1hFgtO18QNrcFYDPYH0gwQ==} + '@oxfmt/binding-openharmony-arm64@0.58.0': + resolution: {integrity: sha512-ZWoTM27/HYPOh9iq86DAbhPu9nXb8qKvvGU/h8OfliyVUFAMMNTLDkGsWDKKnDqIkqvZ9+dXlgUOsH1LYO3O7g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxfmt/binding-win32-arm64-msvc@0.53.0': - resolution: {integrity: sha512-Yq9sOZoIOJ5xPjO0qOyHJS4CiPuTkB2en9auxZz7Ar2p5RaC7BzLyVVmAA7zz9/L9YnjjY1DwNxN+ivKXimN/A==} + '@oxfmt/binding-win32-arm64-msvc@0.58.0': + resolution: {integrity: sha512-LHZnqFXe2dEfkRI4XdZS/57nEOT/I4UCRX5IyM9v4GYW9XwQCjGe1IUK59SuKw3POwvcgWQ4pme2cYXmNqTNPg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxfmt/binding-win32-ia32-msvc@0.53.0': - resolution: {integrity: sha512-es1fVNZEkBqEcQtBpn19SYFgZF7FawlkCjkT/iImfEAus4gun8fBwB1E9hpV5LcR9B0DBNvRIXhW8BQk3JaE+Q==} + '@oxfmt/binding-win32-ia32-msvc@0.58.0': + resolution: {integrity: sha512-mZKpg20TpheCJym1rarcZCUJeW1sSruw8zAAaCYWvuVfwIUDN1CXdrPU/JgCWReXTCTrEfCB8Wyo3hh9jSZ2EA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxfmt/binding-win32-x64-msvc@0.53.0': - resolution: {integrity: sha512-QFmJs2bEu9AO4O6qsmEaZNGi6dFq8N+rT8EHAAnZIq/B9SeJDUbc4DzVxQ48MfDsL7D3sCZzo37zuTuspcURgg==} + '@oxfmt/binding-win32-x64-msvc@0.58.0': + resolution: {integrity: sha512-N/wUU4N5PZ2orBtI+Ko7MnMfYLfE7K91UrGMY/c/pYyHR3lA9kwst1XugkZx+92YcRh/Eo+iv2eTESSWXfiZPA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@oxlint-tsgolint/darwin-arm64@0.23.0': - resolution: {integrity: sha512-gOs9PVr2wEg4ox9z0aJo+RKhhImW86YL5N6yav8BK/rgPsIrwN/igSZ+pbRr723NFvUNKde9fgMhRA6JrXAOZw==} + '@oxlint-tsgolint/darwin-arm64@0.24.0': + resolution: {integrity: sha512-C2uMmwK5Bc4ri4ysZ6sA8Rcu+A5zBQTp6ml2u0CLLbRZp4kMFPV3yWk8B5DK9Aw7y9bbjogIm75tUwGLFzlsYQ==} cpu: [arm64] os: [darwin] - '@oxlint-tsgolint/darwin-x64@0.23.0': - resolution: {integrity: sha512-kjJ8B+7n4tB9VJdxS5A9GdJt6/bYpzbu4lXp2uO1S3sRmCB5gDEABlGoiePNApRWaW+xqL4b4xgiE727jSLhuA==} + '@oxlint-tsgolint/darwin-x64@0.24.0': + resolution: {integrity: sha512-Wgvt/1lRbDxmoNqWQKKcL+UIiqLmdJ+EWLpQa1qzoNVAfNB0PJpa82/8dH1twT/3rSs4zrP5TXPWl4juB71WuQ==} cpu: [x64] os: [darwin] - '@oxlint-tsgolint/linux-arm64@0.23.0': - resolution: {integrity: sha512-6dCZuKNu135seMXilkRk9SpCx6i1XgmiipYGalLij5WVRX6ZYS8c4xI7preN/zv9fCXhsQclTIMDu2Y/cytTjw==} + '@oxlint-tsgolint/linux-arm64@0.24.0': + resolution: {integrity: sha512-PB1rxII7KV83+ASY4sSkXtqvpij6ME66+QCRL49uksi/ofs2Rf/UVboYr095n0Rkbl2wgvlsHGl6DHC361jQUQ==} cpu: [arm64] os: [linux] - '@oxlint-tsgolint/linux-x64@0.23.0': - resolution: {integrity: sha512-3bdilnyA7kmSTjK27rvjIjSxL5SIg3wt7vwNiRkouWB83ytssyKnuGvxSYJxgMEmFpSutzaBzcCUM2jDtPGcgA==} + '@oxlint-tsgolint/linux-x64@0.24.0': + resolution: {integrity: sha512-xcz3CxKmjTQLREtE/UShh+ruWmm9nAb7UM9zKcD65BStiuYgOakAKkPHl4YS5DztpVcDrE0+HqbOolTlRKYWmw==} cpu: [x64] os: [linux] - '@oxlint-tsgolint/win32-arm64@0.23.0': - resolution: {integrity: sha512-j+OEp44SVYiQ+ZD+uttsX7u6L9SvmbbQ77SO1pSFCcJlsVMeCk8qZsjhKfGKuT/jIA+ipOJMVs/+pqUfObBWNw==} + '@oxlint-tsgolint/win32-arm64@0.24.0': + resolution: {integrity: sha512-A2i6ZGBec3i20S7RaxkgHc6r3HYtD5Mn7j/mb22NkTz14u0JuudvTu6JggAnbGMcv8+dBKQI//EasxSPJLD8pw==} cpu: [arm64] os: [win32] - '@oxlint-tsgolint/win32-x64@0.23.0': - resolution: {integrity: sha512-5MyjFuqf+g8OUPJBSGWHJtmoWnzFJYyOg4To9WMQshZYEWig/vtu7JtJ03VWnzHv9LJkAUeApY0gVCOywFR/iQ==} + '@oxlint-tsgolint/win32-x64@0.24.0': + resolution: {integrity: sha512-0ZbGd9qRB6zs82moekaKdEvncRANq49EAwfNX62JpTS46feXUhKAuoyVDvZMj6Rywejylrmmu79Wo6faYCo4Ew==} cpu: [x64] os: [win32] - '@oxlint/binding-android-arm-eabi@1.68.0': - resolution: {integrity: sha512-wEdsIspexXLLMCPAEOcCuFLMt6aE3AzTuA/nQKLPRnoJ+EQTturmGheDkhHuuVHx0GbutjQ3JKmEn+Gz6Ag28Q==} + '@oxlint/binding-android-arm-eabi@1.73.0': + resolution: {integrity: sha512-HZQRN/UMBu+Ut+/9MiAChkbP4qZqrNOWBcNI45vOT40GVhbGR0JgHB87L48D4iAqFQIdVmeQYtV9RF89AjTKkg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxlint/binding-android-arm64@1.68.0': - resolution: {integrity: sha512-6aZRNNXQTsYtgaus8HTb9nuCcsrQTlKXGnktwvwW0n/SooRWNxNb3925grDkC63aEYZuCIyOVLV16IdYIoC2aQ==} + '@oxlint/binding-android-arm64@1.73.0': + resolution: {integrity: sha512-Gp+KJRylv2aW7thRpG5p1KTxZq4ZJFbWowrKzufNq9d3ssl3r3JviYV45/+p+7CN1Nv0zDd1e8Ex0b/HUDq4TQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxlint/binding-darwin-arm64@1.68.0': - resolution: {integrity: sha512-lVTbsE3kO4bLpZELgjRZuAJc8kP98wb83yMXWH8gaPaFZ+cM2IDeZto4ByoUAYj0Mxv2rvw+A1ssZequSepVSg==} + '@oxlint/binding-darwin-arm64@1.73.0': + resolution: {integrity: sha512-3de96NdtXhxERMjIz7wsp2HYMY6pMQycGxFWac2mFecAx6VeARF/IqFb1QIaqiCRIdfzBwzTed+pCTCoiS+CYA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxlint/binding-darwin-x64@1.68.0': - resolution: {integrity: sha512-nCmw2XrmQskjBUh/sfP5yKs93V68LijQgjd1cuuZ/q4SCARngLYs60/qqyzuMsg8QQ9KArDI98hxs/RDGE4KRQ==} + '@oxlint/binding-darwin-x64@1.73.0': + resolution: {integrity: sha512-5zx/uPW32TiaOeVY1dQ/H5iOf0K1HOdFKOJhLqGl4o63+i1fpzoqqu/mKtd7OFgFjNCdhlyTGgjVkQTZm1ELcg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxlint/binding-freebsd-x64@1.68.0': - resolution: {integrity: sha512-TI4ovQJliYE9V6e06cEv+qEI9uj7Ao65fmif4er4HD+aouyYyh0P31q2jh3KtqsOHHcQqv2PZ61TjJFLpBDGWQ==} + '@oxlint/binding-freebsd-x64@1.73.0': + resolution: {integrity: sha512-qNe4gKHaGnLuZJ8toUg90JAa0S2vTVvDw+0bRi3q1avXZXDT4u5mMeECf3nD4HYrbdn1O7dXqWut4onY/yx/Xg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxlint/binding-linux-arm-gnueabihf@1.68.0': - resolution: {integrity: sha512-LcNnEi9g71Cmry5ZpLbKT+oVv+/zYG3hYVAbBBB5X85nOQZSk8l92CnDkxJMcxUg0NCnMCOFZuaVDlMyv4tYJw==} + '@oxlint/binding-linux-arm-gnueabihf@1.73.0': + resolution: {integrity: sha512-cCehYh5hTbfShm/fxTD6wwrGUWIpvX+N5OxmAMhFhDeTGXvw+BeNj889tpxsFQ9ZLatQ6wImuY8tsKLZ+FMz7w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxlint/binding-linux-arm-musleabihf@1.68.0': - resolution: {integrity: sha512-OovHahL3FX4UaK+hgSf11llUx2vszqjSdQQ61Ck9InOEI/ptZoC4XSQJurITqItVvd53JSlmkLMeaNjM1PoQew==} + '@oxlint/binding-linux-arm-musleabihf@1.73.0': + resolution: {integrity: sha512-d5j5GDU/2dMgjVhw7TQT9ITrsIr1Y02KEXKyVGIXUkD+KiaxE9TP65FS2ZdgTBemQvoRL+gSBdbrIm3cQIeacg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxlint/binding-linux-arm64-gnu@1.68.0': - resolution: {integrity: sha512-YbzTglnHLzzi9zv5or8Ztz5fykAoZE8W9iM42/bOrF4HBSB6rJTqdLQWuoP76EHQw9DuKl76K1QmFlG29sPJXQ==} + '@oxlint/binding-linux-arm64-gnu@1.73.0': + resolution: {integrity: sha512-Eyf1SrP3+yR1DI3OJgOY2Pvrr9dWP9TK37xPaDYycwTtlGlI45erJAVIfH5/m/xosDt6BupJYEFi47bvbTuuyw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@oxlint/binding-linux-arm64-musl@1.68.0': - resolution: {integrity: sha512-qVKtCZNic+OoNnOr/hCQAu22HSQzflI7Fsq/Blzkw02SnLuv163k3kfmrVpZjSBlUHgsRKj6WgQiw30d3SX02Q==} + '@oxlint/binding-linux-arm64-musl@1.73.0': + resolution: {integrity: sha512-IlT/OJApEDKaMmCooHuncgJZbbCe7T5QIWmTZBEtYscWvzPQuuEinVcid6kwQRVQOUdb7PUCz4jQHnaYXdfJXw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@oxlint/binding-linux-ppc64-gnu@1.68.0': - resolution: {integrity: sha512-zExyZ8ZOUuAyQ0y9jpTcyjKUz62YY9JhKPyVxzvjTpXzZ3ujdqiVwfPWDdnA1SsIOrxdtxHn7KErDHLWskFjXg==} + '@oxlint/binding-linux-ppc64-gnu@1.73.0': + resolution: {integrity: sha512-L+JYcb/vdg5fmcH08V6o0YYLU28cTH1SPNulwJdvK9NK49aXSkYy6oNpKBmddArVOXYqNepriDGiZ04G54kh1Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] - '@oxlint/binding-linux-riscv64-gnu@1.68.0': - resolution: {integrity: sha512-6C4MPuwewyDavA7sxM14wzgRi5GGL68HPIxRCdVyS75U4MDbpFVYzKO9WNR6KLKTMPq2pcz3THwo1sK2uiqngw==} + '@oxlint/binding-linux-riscv64-gnu@1.73.0': + resolution: {integrity: sha512-Qtk0g3bKV6OwWjIm7R8kQN1uOZRKQt/MODK2a8QfkwhTpXBD53ozx5XLVWLGDQAVyp2otLW4D2wB98XfAfMPGA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] - '@oxlint/binding-linux-riscv64-musl@1.68.0': - resolution: {integrity: sha512-bnZooVeHAcvA+dH0EDLgx+7HY/DRi6e0hFszg3P+OBatuUjV6EvfIyNIzWOusmqAVh4L6r21GGTZtiKE4iqM4Q==} + '@oxlint/binding-linux-riscv64-musl@1.73.0': + resolution: {integrity: sha512-wX0NQKZVxltkAOVmzFcpOaMpdaUvsq1Eqpx9tkAfl71UdkTlSo1R4AdAnGccR1Fm2+TzFgZ22CyyGuZ41RDr/A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] - '@oxlint/binding-linux-s390x-gnu@1.68.0': - resolution: {integrity: sha512-dIqnZnJSmHCMOUpUcWQOiV14o3DDPVx1DSsMaSzvdhNjC1tB1iEPZbdiMSCIEYbkgbsYznHXWqFdKL8WUB3F8g==} + '@oxlint/binding-linux-s390x-gnu@1.73.0': + resolution: {integrity: sha512-vPe7UGBMWyiLTtnqS4xxgMQFSFGmtQwhwCxuiw6lXygaO6bVt0D8dFVg8Xv05eaiN3ybC0HXXHUAohFMFvqoCQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] - '@oxlint/binding-linux-x64-gnu@1.68.0': - resolution: {integrity: sha512-zc9lEnfV/HreDTY6gdMlZe+irkwHSxQ4/B1pS9GyK7RVaA5LxhoZY/w6/o2vIwLLEYiXQ5ujGxOM1ZazeFAAIA==} + '@oxlint/binding-linux-x64-gnu@1.73.0': + resolution: {integrity: sha512-2CwIWr9cemFC/CbRBWZvuk5mffz6ObmfFkfcC/9rTQ7f+icNhYr2kOjf9Rt8lLvugvkdGDOmkoVoFFHh6ClCTw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@oxlint/binding-linux-x64-musl@1.68.0': - resolution: {integrity: sha512-Dl5QEX0TCo/40Cdh1o1JdPS//+YiWqjC+Hrrya5OQmStZZr4svAFtdlqcpCrU9yq2Mo3vRVyO9B3h0dzD8s36Q==} + '@oxlint/binding-linux-x64-musl@1.73.0': + resolution: {integrity: sha512-nDadfJgg7NBBxG0N560wOe7LLX5QiYp6qBaI7viuk5EUORFBktU/NfV0MbTqU3gTqQDCh4VyxKdo5VADxk9w8Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@oxlint/binding-openharmony-arm64@1.68.0': - resolution: {integrity: sha512-/qy6dOvi4S3/LeXq0l5BT5pRKPYA7oj3uKwJOAZOr5HRLL+HK6jdBynvWuXIA2wwfE01RzNYmbBdM7vwYx00sA==} + '@oxlint/binding-openharmony-arm64@1.73.0': + resolution: {integrity: sha512-wGjJC+NLH9xP+IKGn9RDW94ojJR/wPbg5WCnQjj/oReaOtCQthr8ws1zICe77JFmo4ouUdeTHHZL/ESGiF6Pmw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxlint/binding-win32-arm64-msvc@1.68.0': - resolution: {integrity: sha512-fHNtVqPHSYE7UFDSLVFUjxQjnSVXxseNJmRW+XuP4pXXDwePdPda43NL7/BBCFTxHjycOc44JNDaOPtFDNui9A==} + '@oxlint/binding-win32-arm64-msvc@1.73.0': + resolution: {integrity: sha512-I7X47GPGljw225YUQ5SbC/rb1Kkdrd0yQf0x+hYxeKS6DpfjMbo9ccQPQ6LNY6BoJQ1sHhgDUGuMn5Vg5gHT6w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxlint/binding-win32-ia32-msvc@1.68.0': - resolution: {integrity: sha512-NnKXr4Wgo4nps3erhrE0f8shBvBPZMHg72nDsvX0JyrRvsNiP3f1JNvbCKh+A6VFvpF7ZoJxu904P3cKMhvZnA==} + '@oxlint/binding-win32-ia32-msvc@1.73.0': + resolution: {integrity: sha512-5lWj+3h+74Fm1jYOO9qkJA4xkAlZA099DkXppuXsk7UpnpZLttsefrZU469vChGaG6hcSqrkKXQOvMTZtbjeNg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxlint/binding-win32-x64-msvc@1.68.0': - resolution: {integrity: sha512-zg5pA+84AlU6XHJ3ruiRxziO71QTrz8nLsk6u01JGS5+tL9/bnlakFiklFrcy4R1/V7ktWtaNitN3JZWmKnf6g==} + '@oxlint/binding-win32-x64-msvc@1.73.0': + resolution: {integrity: sha512-WaNRvh4f6zY9CvUQk2YoA1O90ieWrIklI84+HXFr9Isjz9CSESrdqo/RtIYt4Dll/cAchqGDMehfaZd0vqEFZw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -5752,8 +5752,8 @@ packages: brace-expansion@2.0.2: resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} - brace-expansion@2.1.1: - resolution: {integrity: sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==} + brace-expansion@2.1.2: + resolution: {integrity: sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==} brace-expansion@5.0.4: resolution: {integrity: sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==} @@ -6750,8 +6750,8 @@ packages: electron-to-chromium@1.5.267: resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} - electron-to-chromium@1.5.388: - resolution: {integrity: sha512-Pl/aJaqOOxYxda3vcx1IKSJimwYXHDkEnGn0F+kG2EE68dDtx2uCinaS+Vih8Z91B9t8CSAbiF/HKyWcnXjhzw==} + electron-to-chromium@1.5.389: + resolution: {integrity: sha512-cEto7aeOqBfU1D+c5py5pE+ooscKE75JifxLBdFUZsqAxRS6y7kebtxAZvICszSl05gPjYHDTjY+lXpyGvpJbg==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -7080,9 +7080,6 @@ packages: fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - fast-uri@3.1.2: - resolution: {integrity: sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==} - fast-uri@3.1.3: resolution: {integrity: sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg==} @@ -9261,8 +9258,8 @@ packages: node-releases@2.0.27: resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} - node-releases@2.0.50: - resolution: {integrity: sha512-J6l92tKHX6w8Jy5nO1Vuc01NoIiRGi/d6qBKVxh+IQ8Cr3b6HbVNfKiF8ZpFKufTwpwxMmce2W3iQZ861ZRyTg==} + node-releases@2.0.51: + resolution: {integrity: sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==} engines: {node: '>=18'} node-source-walk@7.0.0: @@ -9436,8 +9433,8 @@ packages: resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} engines: {node: '>= 0.4'} - oxfmt@0.53.0: - resolution: {integrity: sha512-9cB5glS3Ip6NMuZ+6NYTao9FCWkDhRtPYCtR3QBu/NxHoFbgzzTvi41N4jxz/GqGfuLKspui1qb/LlSu2IbMcw==} + oxfmt@0.58.0: + resolution: {integrity: sha512-8feG/7NVEHDVwc1OUpP6Pks+TnaDFUw2jLLFIMi5bcmmwxAX2wBQvjSzj62RRTYBf2Op1Wt8xbkmagmPTR5ETg==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -9449,16 +9446,16 @@ packages: vite-plus: optional: true - oxlint-tsgolint@0.23.0: - resolution: {integrity: sha512-3mBv3CoPbh8dFbzfDGIWa2ytZjn2v+3EX4aKRXjIhsoGFzG8GCjfRirz3rwZf1wYbZzsNLTSgpw8VjQuWdp/jA==} + oxlint-tsgolint@0.24.0: + resolution: {integrity: sha512-giCk5sEvG02d5tzPmFMX3hem8ndzEEu1xvGYS5OwNfO2WGl6ZVxt5LjE0yiMDoz94INI7XkXwgFAQiydPvVHDw==} hasBin: true - oxlint@1.68.0: - resolution: {integrity: sha512-dXcbq+xsmLrMy6T8d0euf3IYUfLmjHIE11pOxiUSi5LHkFZaYPv568R6sEjcavVpUxoaQe66UBuK4HEi74NxpA==} + oxlint@1.73.0: + resolution: {integrity: sha512-u91G9TJzU6yqKWNZUYprQB07W7YvntZXaRxQ6CkoytepYhLWUXWsr1M8zUJ34VatNPuUAr3Z8GH+O2A331CluQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: - oxlint-tsgolint: '>=0.22.1' + oxlint-tsgolint: '>=0.24.0' vite-plus: '*' peerDependenciesMeta: oxlint-tsgolint: @@ -11025,8 +11022,8 @@ packages: engines: {node: '>=10'} hasBin: true - terser@5.48.0: - resolution: {integrity: sha512-J/9An6vs9Us6wKRriSFXBWdRZapREHqFzdNUKk0pmu804EMR6dr6winwo7e5JDxN4xahxQsuysyYFwlwj4XN/Q==} + terser@5.49.0: + resolution: {integrity: sha512-SNiDnXyHSrxVcIOtVbULzcTmniUiwcV7Nwdyj1twVubeTmbjoa8p69KKDpfkdoOavuM4/GRm1+ykI8qqnavHoA==} engines: {node: '>=10'} hasBin: true @@ -13600,7 +13597,7 @@ snapshots: '@eslint/eslintrc@3.3.3': dependencies: - ajv: 6.15.0 + ajv: 6.12.6 debug: 4.4.3 espree: 10.4.0 globals: 14.0.0 @@ -14318,11 +14315,11 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 - '@joshwooding/vite-plugin-react-docgen-typescript@0.7.0(typescript@6.0.2)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))': + '@joshwooding/vite-plugin-react-docgen-typescript@0.7.0(typescript@6.0.2)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))': dependencies: glob: 13.0.6 react-docgen-typescript: 2.4.0(typescript@6.0.2) - vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) + vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) optionalDependencies: typescript: 6.0.2 @@ -14621,136 +14618,136 @@ snapshots: '@oxc-project/types@0.122.0': {} - '@oxfmt/binding-android-arm-eabi@0.53.0': + '@oxfmt/binding-android-arm-eabi@0.58.0': optional: true - '@oxfmt/binding-android-arm64@0.53.0': + '@oxfmt/binding-android-arm64@0.58.0': optional: true - '@oxfmt/binding-darwin-arm64@0.53.0': + '@oxfmt/binding-darwin-arm64@0.58.0': optional: true - '@oxfmt/binding-darwin-x64@0.53.0': + '@oxfmt/binding-darwin-x64@0.58.0': optional: true - '@oxfmt/binding-freebsd-x64@0.53.0': + '@oxfmt/binding-freebsd-x64@0.58.0': optional: true - '@oxfmt/binding-linux-arm-gnueabihf@0.53.0': + '@oxfmt/binding-linux-arm-gnueabihf@0.58.0': optional: true - '@oxfmt/binding-linux-arm-musleabihf@0.53.0': + '@oxfmt/binding-linux-arm-musleabihf@0.58.0': optional: true - '@oxfmt/binding-linux-arm64-gnu@0.53.0': + '@oxfmt/binding-linux-arm64-gnu@0.58.0': optional: true - '@oxfmt/binding-linux-arm64-musl@0.53.0': + '@oxfmt/binding-linux-arm64-musl@0.58.0': optional: true - '@oxfmt/binding-linux-ppc64-gnu@0.53.0': + '@oxfmt/binding-linux-ppc64-gnu@0.58.0': optional: true - '@oxfmt/binding-linux-riscv64-gnu@0.53.0': + '@oxfmt/binding-linux-riscv64-gnu@0.58.0': optional: true - '@oxfmt/binding-linux-riscv64-musl@0.53.0': + '@oxfmt/binding-linux-riscv64-musl@0.58.0': optional: true - '@oxfmt/binding-linux-s390x-gnu@0.53.0': + '@oxfmt/binding-linux-s390x-gnu@0.58.0': optional: true - '@oxfmt/binding-linux-x64-gnu@0.53.0': + '@oxfmt/binding-linux-x64-gnu@0.58.0': optional: true - '@oxfmt/binding-linux-x64-musl@0.53.0': + '@oxfmt/binding-linux-x64-musl@0.58.0': optional: true - '@oxfmt/binding-openharmony-arm64@0.53.0': + '@oxfmt/binding-openharmony-arm64@0.58.0': optional: true - '@oxfmt/binding-win32-arm64-msvc@0.53.0': + '@oxfmt/binding-win32-arm64-msvc@0.58.0': optional: true - '@oxfmt/binding-win32-ia32-msvc@0.53.0': + '@oxfmt/binding-win32-ia32-msvc@0.58.0': optional: true - '@oxfmt/binding-win32-x64-msvc@0.53.0': + '@oxfmt/binding-win32-x64-msvc@0.58.0': optional: true - '@oxlint-tsgolint/darwin-arm64@0.23.0': + '@oxlint-tsgolint/darwin-arm64@0.24.0': optional: true - '@oxlint-tsgolint/darwin-x64@0.23.0': + '@oxlint-tsgolint/darwin-x64@0.24.0': optional: true - '@oxlint-tsgolint/linux-arm64@0.23.0': + '@oxlint-tsgolint/linux-arm64@0.24.0': optional: true - '@oxlint-tsgolint/linux-x64@0.23.0': + '@oxlint-tsgolint/linux-x64@0.24.0': optional: true - '@oxlint-tsgolint/win32-arm64@0.23.0': + '@oxlint-tsgolint/win32-arm64@0.24.0': optional: true - '@oxlint-tsgolint/win32-x64@0.23.0': + '@oxlint-tsgolint/win32-x64@0.24.0': optional: true - '@oxlint/binding-android-arm-eabi@1.68.0': + '@oxlint/binding-android-arm-eabi@1.73.0': optional: true - '@oxlint/binding-android-arm64@1.68.0': + '@oxlint/binding-android-arm64@1.73.0': optional: true - '@oxlint/binding-darwin-arm64@1.68.0': + '@oxlint/binding-darwin-arm64@1.73.0': optional: true - '@oxlint/binding-darwin-x64@1.68.0': + '@oxlint/binding-darwin-x64@1.73.0': optional: true - '@oxlint/binding-freebsd-x64@1.68.0': + '@oxlint/binding-freebsd-x64@1.73.0': optional: true - '@oxlint/binding-linux-arm-gnueabihf@1.68.0': + '@oxlint/binding-linux-arm-gnueabihf@1.73.0': optional: true - '@oxlint/binding-linux-arm-musleabihf@1.68.0': + '@oxlint/binding-linux-arm-musleabihf@1.73.0': optional: true - '@oxlint/binding-linux-arm64-gnu@1.68.0': + '@oxlint/binding-linux-arm64-gnu@1.73.0': optional: true - '@oxlint/binding-linux-arm64-musl@1.68.0': + '@oxlint/binding-linux-arm64-musl@1.73.0': optional: true - '@oxlint/binding-linux-ppc64-gnu@1.68.0': + '@oxlint/binding-linux-ppc64-gnu@1.73.0': optional: true - '@oxlint/binding-linux-riscv64-gnu@1.68.0': + '@oxlint/binding-linux-riscv64-gnu@1.73.0': optional: true - '@oxlint/binding-linux-riscv64-musl@1.68.0': + '@oxlint/binding-linux-riscv64-musl@1.73.0': optional: true - '@oxlint/binding-linux-s390x-gnu@1.68.0': + '@oxlint/binding-linux-s390x-gnu@1.73.0': optional: true - '@oxlint/binding-linux-x64-gnu@1.68.0': + '@oxlint/binding-linux-x64-gnu@1.73.0': optional: true - '@oxlint/binding-linux-x64-musl@1.68.0': + '@oxlint/binding-linux-x64-musl@1.73.0': optional: true - '@oxlint/binding-openharmony-arm64@1.68.0': + '@oxlint/binding-openharmony-arm64@1.73.0': optional: true - '@oxlint/binding-win32-arm64-msvc@1.68.0': + '@oxlint/binding-win32-arm64-msvc@1.73.0': optional: true - '@oxlint/binding-win32-ia32-msvc@1.68.0': + '@oxlint/binding-win32-ia32-msvc@1.73.0': optional: true - '@oxlint/binding-win32-x64-msvc@1.68.0': + '@oxlint/binding-win32-x64-msvc@1.73.0': optional: true '@oxlint/plugins@1.43.0': {} @@ -15043,7 +15040,7 @@ snapshots: dependencies: serialize-javascript: 6.0.2 smob: 1.6.2 - terser: 5.48.0 + terser: 5.49.0 optionalDependencies: rollup: 2.80.0 @@ -15555,10 +15552,10 @@ snapshots: axe-core: 4.11.1 storybook: 10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@storybook/addon-docs@10.2.16(@types/react@19.2.14)(esbuild@0.27.7)(rollup@4.60.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))': + '@storybook/addon-docs@10.2.16(@types/react@19.2.14)(esbuild@0.27.7)(rollup@4.60.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))': dependencies: '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@18.3.1) - '@storybook/csf-plugin': 10.2.16(esbuild@0.27.7)(rollup@4.60.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + '@storybook/csf-plugin': 10.2.16(esbuild@0.27.7)(rollup@4.60.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) '@storybook/icons': 2.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@storybook/react-dom-shim': 10.2.16(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) react: 18.3.1 @@ -15583,59 +15580,59 @@ snapshots: dependencies: storybook: 10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@storybook/addon-vitest@10.2.16(@vitest/browser-playwright@4.0.18)(@vitest/browser@4.1.8(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0))(@vitest/runner@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vitest@4.1.0)': + '@storybook/addon-vitest@10.2.16(@vitest/browser-playwright@4.0.18)(@vitest/browser@4.1.8(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0))(@vitest/runner@4.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vitest@4.1.0)': dependencies: '@storybook/global': 5.0.0 '@storybook/icons': 2.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) storybook: 10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) optionalDependencies: - '@vitest/browser': 4.1.8(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0) - '@vitest/browser-playwright': 4.0.18(playwright@1.58.2)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0) + '@vitest/browser': 4.1.8(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0) + '@vitest/browser-playwright': 4.0.18(playwright@1.58.2)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0) '@vitest/runner': 4.1.0 - vitest: 4.1.0(@types/node@24.9.1)(@vitest/browser-playwright@4.0.18)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + vitest: 4.1.0(@types/node@24.9.1)(@vitest/browser-playwright@4.0.18)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) transitivePeerDependencies: - react - react-dom - '@storybook/builder-vite@10.2.16(esbuild@0.27.7)(rollup@4.60.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))': + '@storybook/builder-vite@10.2.16(esbuild@0.27.7)(rollup@4.60.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))': dependencies: - '@storybook/csf-plugin': 10.2.16(esbuild@0.27.7)(rollup@4.60.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + '@storybook/csf-plugin': 10.2.16(esbuild@0.27.7)(rollup@4.60.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) storybook: 10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) ts-dedent: 2.2.0 - vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) + vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) transitivePeerDependencies: - esbuild - rollup - webpack - '@storybook/builder-vite@10.4.4(esbuild@0.27.7)(rollup@4.60.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))': + '@storybook/builder-vite@10.4.4(esbuild@0.27.7)(rollup@4.60.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))': dependencies: - '@storybook/csf-plugin': 10.4.4(esbuild@0.27.7)(rollup@4.60.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + '@storybook/csf-plugin': 10.4.4(esbuild@0.27.7)(rollup@4.60.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) storybook: 10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) ts-dedent: 2.3.0 - vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) + vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) transitivePeerDependencies: - esbuild - rollup - webpack - '@storybook/csf-plugin@10.2.16(esbuild@0.27.7)(rollup@4.60.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))': + '@storybook/csf-plugin@10.2.16(esbuild@0.27.7)(rollup@4.60.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))': dependencies: storybook: 10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) unplugin: 2.3.11 optionalDependencies: esbuild: 0.27.7 rollup: 4.60.1 - vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) + vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) - '@storybook/csf-plugin@10.4.4(esbuild@0.27.7)(rollup@4.60.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))': + '@storybook/csf-plugin@10.4.4(esbuild@0.27.7)(rollup@4.60.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))': dependencies: storybook: 10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) unplugin: 2.3.11 optionalDependencies: esbuild: 0.27.7 rollup: 4.60.1 - vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) + vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) '@storybook/global@5.0.0': {} @@ -15779,19 +15776,19 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.3.2 '@tailwindcss/oxide-win32-x64-msvc': 4.3.2 - '@tailwindcss/vite@4.2.1(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))': + '@tailwindcss/vite@4.2.1(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))': dependencies: '@tailwindcss/node': 4.2.1 '@tailwindcss/oxide': 4.2.1 tailwindcss: 4.2.1 - vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) + vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) - '@tailwindcss/vite@4.3.2(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))': + '@tailwindcss/vite@4.3.2(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))': dependencies: '@tailwindcss/node': 4.3.2 '@tailwindcss/oxide': 4.3.2 tailwindcss: 4.3.2 - vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) + vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) '@tanstack/db-ivm@0.1.18(typescript@6.0.2)': dependencies: @@ -16442,29 +16439,29 @@ snapshots: '@typescript-eslint/types': 8.61.0 eslint-visitor-keys: 5.0.1 - '@vitest/browser-playwright@4.0.18(playwright@1.58.2)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0)': + '@vitest/browser-playwright@4.0.18(playwright@1.58.2)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0)': dependencies: - '@vitest/browser': 4.0.18(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0) - '@vitest/mocker': 4.0.18(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + '@vitest/browser': 4.0.18(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0) + '@vitest/mocker': 4.0.18(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) playwright: 1.58.2 tinyrainbow: 3.0.3 - vitest: 4.1.0(@types/node@24.9.1)(@vitest/browser-playwright@4.0.18)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + vitest: 4.1.0(@types/node@24.9.1)(@vitest/browser-playwright@4.0.18)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) transitivePeerDependencies: - bufferutil - msw - utf-8-validate - vite - '@vitest/browser@4.0.18(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0)': + '@vitest/browser@4.0.18(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0)': dependencies: - '@vitest/mocker': 4.0.18(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + '@vitest/mocker': 4.0.18(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) '@vitest/utils': 4.0.18 magic-string: 0.30.21 pixelmatch: 7.1.0 pngjs: 7.0.0 sirv: 3.0.2 tinyrainbow: 3.1.0 - vitest: 4.1.0(@types/node@24.9.1)(@vitest/browser-playwright@4.0.18)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + vitest: 4.1.0(@types/node@24.9.1)(@vitest/browser-playwright@4.0.18)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) ws: 8.21.0 transitivePeerDependencies: - bufferutil @@ -16472,16 +16469,16 @@ snapshots: - utf-8-validate - vite - '@vitest/browser@4.1.8(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0)': + '@vitest/browser@4.1.8(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0)': dependencies: '@blazediff/core': 1.9.1 - '@vitest/mocker': 4.1.8(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + '@vitest/mocker': 4.1.8(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) '@vitest/utils': 4.1.8 magic-string: 0.30.21 pngjs: 7.0.0 sirv: 3.0.2 tinyrainbow: 3.1.0 - vitest: 4.1.0(@types/node@24.9.1)(@vitest/browser-playwright@4.0.18)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + vitest: 4.1.0(@types/node@24.9.1)(@vitest/browser-playwright@4.0.18)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) ws: 8.21.0 transitivePeerDependencies: - bufferutil @@ -16489,7 +16486,7 @@ snapshots: - utf-8-validate - vite - '@vitest/coverage-v8@4.1.5(@vitest/browser@4.1.8(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0))(vitest@4.1.0)': + '@vitest/coverage-v8@4.1.5(@vitest/browser@4.1.8(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0))(vitest@4.1.0)': dependencies: '@bcoe/v8-coverage': 1.0.2 '@vitest/utils': 4.1.5 @@ -16501,11 +16498,11 @@ snapshots: obug: 2.1.1 std-env: 4.1.0 tinyrainbow: 3.1.0 - vitest: 4.1.0(@types/node@24.9.1)(@vitest/browser-playwright@4.0.18)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + vitest: 4.1.0(@types/node@24.9.1)(@vitest/browser-playwright@4.0.18)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) optionalDependencies: - '@vitest/browser': 4.1.8(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0) + '@vitest/browser': 4.1.8(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0) - '@vitest/coverage-v8@4.1.5(vitest@4.1.0(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@vitest/coverage-v8@4.1.5(vitest@4.1.0(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: '@bcoe/v8-coverage': 1.0.2 '@vitest/utils': 4.1.5 @@ -16517,9 +16514,9 @@ snapshots: obug: 2.1.1 std-env: 4.1.0 tinyrainbow: 3.1.0 - vitest: 4.1.0(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2)) + vitest: 4.1.0(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.2)) - '@vitest/coverage-v8@4.1.5(vitest@4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)))': + '@vitest/coverage-v8@4.1.5(vitest@4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)))': dependencies: '@bcoe/v8-coverage': 1.0.2 '@vitest/utils': 4.1.5 @@ -16531,9 +16528,9 @@ snapshots: obug: 2.1.1 std-env: 4.1.0 tinyrainbow: 3.1.0 - vitest: 4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + vitest: 4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) - '@vitest/coverage-v8@4.1.5(vitest@4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)))': + '@vitest/coverage-v8@4.1.5(vitest@4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)))': dependencies: '@bcoe/v8-coverage': 1.0.2 '@vitest/utils': 4.1.5 @@ -16545,7 +16542,7 @@ snapshots: obug: 2.1.1 std-env: 4.1.0 tinyrainbow: 3.1.0 - vitest: 4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + vitest: 4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) '@vitest/expect@3.2.4': dependencies: @@ -16564,53 +16561,61 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.0.18(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))': + '@vitest/mocker@4.0.18(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))': dependencies: '@vitest/spy': 4.0.18 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) + vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) + + '@vitest/mocker@4.1.0(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))': + dependencies: + '@vitest/spy': 4.1.0 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) - '@vitest/mocker@4.1.0(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))': + '@vitest/mocker@4.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.25.0)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))': dependencies: '@vitest/spy': 4.1.0 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) + vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.25.0)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) - '@vitest/mocker@4.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))': + '@vitest/mocker@4.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))': dependencies: '@vitest/spy': 4.1.0 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) + vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) - '@vitest/mocker@4.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/mocker@4.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@vitest/spy': 4.1.0 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.2) - '@vitest/mocker@4.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))': + '@vitest/mocker@4.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))': dependencies: '@vitest/spy': 4.1.0 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) + vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) - '@vitest/mocker@4.1.8(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))': + '@vitest/mocker@4.1.8(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))': dependencies: '@vitest/spy': 4.1.8 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) + vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) '@vitest/pretty-format@3.2.4': dependencies: @@ -16791,7 +16796,7 @@ snapshots: ajv@8.20.0: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.1.2 + fast-uri: 3.1.3 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 @@ -17187,7 +17192,7 @@ snapshots: dependencies: balanced-match: 1.0.2 - brace-expansion@2.1.1: + brace-expansion@2.1.2: dependencies: balanced-match: 1.0.2 @@ -17223,8 +17228,8 @@ snapshots: dependencies: baseline-browser-mapping: 2.10.42 caniuse-lite: 1.0.30001803 - electron-to-chromium: 1.5.388 - node-releases: 2.0.50 + electron-to-chromium: 1.5.389 + node-releases: 2.0.51 update-browserslist-db: 1.2.3(browserslist@4.28.5) bson@6.8.0: {} @@ -18214,7 +18219,7 @@ snapshots: electron-to-chromium@1.5.267: {} - electron-to-chromium@1.5.388: {} + electron-to-chromium@1.5.389: {} emoji-regex@8.0.0: {} @@ -18780,8 +18785,6 @@ snapshots: fast-safe-stringify@2.1.1: {} - fast-uri@3.1.2: {} - fast-uri@3.1.3: {} fast-url-parser@1.1.3: @@ -20785,7 +20788,7 @@ snapshots: minimatch@5.1.9: dependencies: - brace-expansion: 2.1.1 + brace-expansion: 2.1.2 minimatch@6.2.3: dependencies: @@ -21339,7 +21342,7 @@ snapshots: node-releases@2.0.27: {} - node-releases@2.0.50: {} + node-releases@2.0.51: {} node-source-walk@7.0.0: dependencies: @@ -21549,61 +21552,61 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 - oxfmt@0.53.0: + oxfmt@0.58.0: dependencies: tinypool: 2.1.0 optionalDependencies: - '@oxfmt/binding-android-arm-eabi': 0.53.0 - '@oxfmt/binding-android-arm64': 0.53.0 - '@oxfmt/binding-darwin-arm64': 0.53.0 - '@oxfmt/binding-darwin-x64': 0.53.0 - '@oxfmt/binding-freebsd-x64': 0.53.0 - '@oxfmt/binding-linux-arm-gnueabihf': 0.53.0 - '@oxfmt/binding-linux-arm-musleabihf': 0.53.0 - '@oxfmt/binding-linux-arm64-gnu': 0.53.0 - '@oxfmt/binding-linux-arm64-musl': 0.53.0 - '@oxfmt/binding-linux-ppc64-gnu': 0.53.0 - '@oxfmt/binding-linux-riscv64-gnu': 0.53.0 - '@oxfmt/binding-linux-riscv64-musl': 0.53.0 - '@oxfmt/binding-linux-s390x-gnu': 0.53.0 - '@oxfmt/binding-linux-x64-gnu': 0.53.0 - '@oxfmt/binding-linux-x64-musl': 0.53.0 - '@oxfmt/binding-openharmony-arm64': 0.53.0 - '@oxfmt/binding-win32-arm64-msvc': 0.53.0 - '@oxfmt/binding-win32-ia32-msvc': 0.53.0 - '@oxfmt/binding-win32-x64-msvc': 0.53.0 - - oxlint-tsgolint@0.23.0: + '@oxfmt/binding-android-arm-eabi': 0.58.0 + '@oxfmt/binding-android-arm64': 0.58.0 + '@oxfmt/binding-darwin-arm64': 0.58.0 + '@oxfmt/binding-darwin-x64': 0.58.0 + '@oxfmt/binding-freebsd-x64': 0.58.0 + '@oxfmt/binding-linux-arm-gnueabihf': 0.58.0 + '@oxfmt/binding-linux-arm-musleabihf': 0.58.0 + '@oxfmt/binding-linux-arm64-gnu': 0.58.0 + '@oxfmt/binding-linux-arm64-musl': 0.58.0 + '@oxfmt/binding-linux-ppc64-gnu': 0.58.0 + '@oxfmt/binding-linux-riscv64-gnu': 0.58.0 + '@oxfmt/binding-linux-riscv64-musl': 0.58.0 + '@oxfmt/binding-linux-s390x-gnu': 0.58.0 + '@oxfmt/binding-linux-x64-gnu': 0.58.0 + '@oxfmt/binding-linux-x64-musl': 0.58.0 + '@oxfmt/binding-openharmony-arm64': 0.58.0 + '@oxfmt/binding-win32-arm64-msvc': 0.58.0 + '@oxfmt/binding-win32-ia32-msvc': 0.58.0 + '@oxfmt/binding-win32-x64-msvc': 0.58.0 + + oxlint-tsgolint@0.24.0: optionalDependencies: - '@oxlint-tsgolint/darwin-arm64': 0.23.0 - '@oxlint-tsgolint/darwin-x64': 0.23.0 - '@oxlint-tsgolint/linux-arm64': 0.23.0 - '@oxlint-tsgolint/linux-x64': 0.23.0 - '@oxlint-tsgolint/win32-arm64': 0.23.0 - '@oxlint-tsgolint/win32-x64': 0.23.0 - - oxlint@1.68.0(oxlint-tsgolint@0.23.0): + '@oxlint-tsgolint/darwin-arm64': 0.24.0 + '@oxlint-tsgolint/darwin-x64': 0.24.0 + '@oxlint-tsgolint/linux-arm64': 0.24.0 + '@oxlint-tsgolint/linux-x64': 0.24.0 + '@oxlint-tsgolint/win32-arm64': 0.24.0 + '@oxlint-tsgolint/win32-x64': 0.24.0 + + oxlint@1.73.0(oxlint-tsgolint@0.24.0): optionalDependencies: - '@oxlint/binding-android-arm-eabi': 1.68.0 - '@oxlint/binding-android-arm64': 1.68.0 - '@oxlint/binding-darwin-arm64': 1.68.0 - '@oxlint/binding-darwin-x64': 1.68.0 - '@oxlint/binding-freebsd-x64': 1.68.0 - '@oxlint/binding-linux-arm-gnueabihf': 1.68.0 - '@oxlint/binding-linux-arm-musleabihf': 1.68.0 - '@oxlint/binding-linux-arm64-gnu': 1.68.0 - '@oxlint/binding-linux-arm64-musl': 1.68.0 - '@oxlint/binding-linux-ppc64-gnu': 1.68.0 - '@oxlint/binding-linux-riscv64-gnu': 1.68.0 - '@oxlint/binding-linux-riscv64-musl': 1.68.0 - '@oxlint/binding-linux-s390x-gnu': 1.68.0 - '@oxlint/binding-linux-x64-gnu': 1.68.0 - '@oxlint/binding-linux-x64-musl': 1.68.0 - '@oxlint/binding-openharmony-arm64': 1.68.0 - '@oxlint/binding-win32-arm64-msvc': 1.68.0 - '@oxlint/binding-win32-ia32-msvc': 1.68.0 - '@oxlint/binding-win32-x64-msvc': 1.68.0 - oxlint-tsgolint: 0.23.0 + '@oxlint/binding-android-arm-eabi': 1.73.0 + '@oxlint/binding-android-arm64': 1.73.0 + '@oxlint/binding-darwin-arm64': 1.73.0 + '@oxlint/binding-darwin-x64': 1.73.0 + '@oxlint/binding-freebsd-x64': 1.73.0 + '@oxlint/binding-linux-arm-gnueabihf': 1.73.0 + '@oxlint/binding-linux-arm-musleabihf': 1.73.0 + '@oxlint/binding-linux-arm64-gnu': 1.73.0 + '@oxlint/binding-linux-arm64-musl': 1.73.0 + '@oxlint/binding-linux-ppc64-gnu': 1.73.0 + '@oxlint/binding-linux-riscv64-gnu': 1.73.0 + '@oxlint/binding-linux-riscv64-musl': 1.73.0 + '@oxlint/binding-linux-s390x-gnu': 1.73.0 + '@oxlint/binding-linux-x64-gnu': 1.73.0 + '@oxlint/binding-linux-x64-musl': 1.73.0 + '@oxlint/binding-openharmony-arm64': 1.73.0 + '@oxlint/binding-win32-arm64-msvc': 1.73.0 + '@oxlint/binding-win32-ia32-msvc': 1.73.0 + '@oxlint/binding-win32-x64-msvc': 1.73.0 + oxlint-tsgolint: 0.24.0 p-defer@3.0.0: {} @@ -22883,7 +22886,7 @@ snapshots: ip-address: 9.0.5 smart-buffer: 4.2.0 - solid-devtools@0.34.5(solid-js@1.9.13)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)): + solid-devtools@0.34.5(solid-js@1.9.13)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)): dependencies: '@babel/core': 7.28.6 '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.28.6) @@ -22892,7 +22895,7 @@ snapshots: '@solid-devtools/shared': 0.20.0(solid-js@1.9.13) solid-js: 1.9.13 optionalDependencies: - vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) + vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) transitivePeerDependencies: - supports-color @@ -23012,16 +23015,16 @@ snapshots: es-errors: 1.3.0 internal-slot: 1.1.0 - storybook-solidjs-vite@10.1.1(esbuild@0.27.7)(rollup@4.60.1)(solid-js@1.9.13)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@6.0.2)(vite-plugin-solid@2.11.11(@testing-library/jest-dom@6.9.1)(solid-js@1.9.13)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)): + storybook-solidjs-vite@10.1.1(esbuild@0.27.7)(rollup@4.60.1)(solid-js@1.9.13)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@6.0.2)(vite-plugin-solid@2.11.11(@testing-library/jest-dom@6.9.1)(solid-js@1.9.13)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)): dependencies: - '@joshwooding/vite-plugin-react-docgen-typescript': 0.7.0(typescript@6.0.2)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) - '@storybook/builder-vite': 10.4.4(esbuild@0.27.7)(rollup@4.60.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + '@joshwooding/vite-plugin-react-docgen-typescript': 0.7.0(typescript@6.0.2)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) + '@storybook/builder-vite': 10.4.4(esbuild@0.27.7)(rollup@4.60.1)(storybook@10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) '@storybook/global': 5.0.0 semver: 7.8.1 solid-js: 1.9.13 storybook: 10.2.16(@testing-library/dom@10.4.1)(prettier@3.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) - vite-plugin-solid: 2.11.11(@testing-library/jest-dom@6.9.1)(solid-js@1.9.13)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) + vite-plugin-solid: 2.11.11(@testing-library/jest-dom@6.9.1)(solid-js@1.9.13)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) optionalDependencies: typescript: 6.0.2 transitivePeerDependencies: @@ -23515,7 +23518,7 @@ snapshots: commander: 2.20.3 source-map-support: 0.5.21 - terser@5.48.0: + terser@5.49.0: dependencies: '@jridgewell/source-map': 0.3.11 acorn: 8.17.0 @@ -23993,19 +23996,19 @@ snapshots: - rollup - supports-color - vite-dev-rpc@1.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)): + vite-dev-rpc@1.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)): dependencies: birpc: 2.6.1 - vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) - vite-hot-client: 2.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) + vite-hot-client: 2.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) - vite-hot-client@2.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)): + vite-hot-client@2.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)): dependencies: - vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) + vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) vite-plugin-html-inject@1.1.2: {} - vite-plugin-inspect@11.3.3(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)): + vite-plugin-inspect@11.3.3(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)): dependencies: ansis: 4.2.0 debug: 4.4.3 @@ -24015,29 +24018,29 @@ snapshots: perfect-debounce: 2.0.0 sirv: 3.0.2 unplugin-utils: 0.3.1 - vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) - vite-dev-rpc: 1.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) + vite-dev-rpc: 1.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) transitivePeerDependencies: - supports-color - vite-plugin-minify@2.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)): + vite-plugin-minify@2.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)): dependencies: '@types/html-minifier-terser': 7.0.2 html-minifier-terser: 7.2.0 - vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) + vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) - vite-plugin-pwa@1.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))(workbox-build@7.1.1(@types/babel__core@7.20.5))(workbox-window@7.1.0): + vite-plugin-pwa@1.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))(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: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) + vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) workbox-build: 7.1.1(@types/babel__core@7.20.5) workbox-window: 7.1.0 transitivePeerDependencies: - supports-color - vite-plugin-solid@2.11.11(@testing-library/jest-dom@6.9.1)(solid-js@1.9.13)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)): + vite-plugin-solid@2.11.11(@testing-library/jest-dom@6.9.1)(solid-js@1.9.13)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)): dependencies: '@babel/core': 7.28.6 '@types/babel__core': 7.20.5 @@ -24045,14 +24048,14 @@ snapshots: merge-anything: 5.1.7 solid-js: 1.9.13 solid-refresh: 0.6.3(solid-js@1.9.13) - vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) - vitefu: 1.1.1(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) + vitefu: 1.1.1(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) optionalDependencies: '@testing-library/jest-dom': 6.9.1 transitivePeerDependencies: - supports-color - vite-plugin-solid@2.11.11(@testing-library/jest-dom@6.9.1)(solid-js@1.9.13)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)): + vite-plugin-solid@2.11.11(@testing-library/jest-dom@6.9.1)(solid-js@1.9.13)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)): dependencies: '@babel/core': 7.28.6 '@types/babel__core': 7.20.5 @@ -24060,14 +24063,14 @@ snapshots: merge-anything: 5.1.7 solid-js: 1.9.13 solid-refresh: 0.6.3(solid-js@1.9.13) - vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) - vitefu: 1.1.1(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) + vitefu: 1.1.1(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) optionalDependencies: '@testing-library/jest-dom': 6.9.1 transitivePeerDependencies: - supports-color - vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3): + vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3): dependencies: esbuild: 0.27.7 fdir: 6.5.0(picomatch@4.0.4) @@ -24081,11 +24084,31 @@ snapshots: jiti: 2.7.0 lightningcss: 1.32.0 sass: 1.98.0 - terser: 5.48.0 + terser: 5.49.0 tsx: 4.21.0 yaml: 2.8.3 - vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3): + vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.25.0)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3): + dependencies: + lightningcss: 1.32.0 + picomatch: 4.0.4 + postcss: 8.5.8 + rolldown: 1.0.0-rc.12(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0) + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 24.9.1 + esbuild: 0.25.0 + fsevents: 2.3.3 + jiti: 2.7.0 + sass: 1.98.0 + terser: 5.49.0 + tsx: 4.21.0 + yaml: 2.8.3 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' + + vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3): dependencies: lightningcss: 1.32.0 picomatch: 4.0.4 @@ -24098,14 +24121,14 @@ snapshots: fsevents: 2.3.3 jiti: 2.7.0 sass: 1.70.0 - terser: 5.48.0 + terser: 5.49.0 tsx: 4.21.0 yaml: 2.8.3 transitivePeerDependencies: - '@emnapi/core' - '@emnapi/runtime' - vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2): + vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: lightningcss: 1.32.0 picomatch: 4.0.4 @@ -24118,14 +24141,14 @@ snapshots: fsevents: 2.3.3 jiti: 2.7.0 sass: 1.98.0 - terser: 5.48.0 + terser: 5.49.0 tsx: 4.21.0 yaml: 2.8.2 transitivePeerDependencies: - '@emnapi/core' - '@emnapi/runtime' - vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3): + vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3): dependencies: lightningcss: 1.32.0 picomatch: 4.0.4 @@ -24138,25 +24161,25 @@ snapshots: fsevents: 2.3.3 jiti: 2.7.0 sass: 1.98.0 - terser: 5.48.0 + terser: 5.49.0 tsx: 4.21.0 yaml: 2.8.3 transitivePeerDependencies: - '@emnapi/core' - '@emnapi/runtime' - vitefu@1.1.1(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)): + vitefu@1.1.1(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)): optionalDependencies: - vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) + vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) - vitefu@1.1.1(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)): + vitefu@1.1.1(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)): optionalDependencies: - vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) + vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) - vitest@4.1.0(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2)): + vitest@4.1.0(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.2)): dependencies: '@vitest/expect': 4.1.0 - '@vitest/mocker': 4.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/mocker': 4.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.2)) '@vitest/pretty-format': 4.1.0 '@vitest/runner': 4.1.0 '@vitest/snapshot': 4.1.0 @@ -24173,7 +24196,7 @@ snapshots: tinyexec: 1.1.2 tinyglobby: 0.2.17 tinyrainbow: 3.1.0 - vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.2) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.8.0 @@ -24183,10 +24206,40 @@ snapshots: transitivePeerDependencies: - msw - vitest@4.1.0(@types/node@24.9.1)(@vitest/browser-playwright@4.0.18)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)): + vitest@4.1.0(@types/node@24.9.1)(@vitest/browser-playwright@4.0.18)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)): + dependencies: + '@vitest/expect': 4.1.0 + '@vitest/mocker': 4.1.0(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) + '@vitest/pretty-format': 4.1.0 + '@vitest/runner': 4.1.0 + '@vitest/snapshot': 4.1.0 + '@vitest/spy': 4.1.0 + '@vitest/utils': 4.1.0 + es-module-lexer: 2.0.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.1 + pathe: 2.0.3 + picomatch: 4.0.4 + std-env: 4.1.0 + tinybench: 2.9.0 + tinyexec: 1.1.2 + tinyglobby: 0.2.17 + tinyrainbow: 3.1.0 + vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 24.9.1 + '@vitest/browser-playwright': 4.0.18(playwright@1.58.2)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0) + happy-dom: 20.8.9 + jsdom: 27.4.0 + transitivePeerDependencies: + - msw + + vitest@4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.25.0)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)): dependencies: '@vitest/expect': 4.1.0 - '@vitest/mocker': 4.1.0(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + '@vitest/mocker': 4.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.25.0)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) '@vitest/pretty-format': 4.1.0 '@vitest/runner': 4.1.0 '@vitest/snapshot': 4.1.0 @@ -24203,20 +24256,19 @@ snapshots: tinyexec: 1.1.2 tinyglobby: 0.2.17 tinyrainbow: 3.1.0 - vite: 7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) + vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.25.0)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 24.9.1 - '@vitest/browser-playwright': 4.0.18(playwright@1.58.2)(vite@7.3.2(@types/node@24.9.1)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.0) happy-dom: 20.8.9 jsdom: 27.4.0 transitivePeerDependencies: - msw - vitest@4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)): + vitest@4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)): dependencies: '@vitest/expect': 4.1.0 - '@vitest/mocker': 4.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + '@vitest/mocker': 4.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) '@vitest/pretty-format': 4.1.0 '@vitest/runner': 4.1.0 '@vitest/snapshot': 4.1.0 @@ -24233,7 +24285,7 @@ snapshots: tinyexec: 1.1.2 tinyglobby: 0.2.17 tinyrainbow: 3.1.0 - vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) + vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.70.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 24.9.1 @@ -24242,10 +24294,10 @@ snapshots: transitivePeerDependencies: - msw - vitest@4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)): + vitest@4.1.0(@types/node@24.9.1)(happy-dom@20.8.9)(jsdom@27.4.0)(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)): dependencies: '@vitest/expect': 4.1.0 - '@vitest/mocker': 4.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3)) + '@vitest/mocker': 4.1.0(vite@8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3)) '@vitest/pretty-format': 4.1.0 '@vitest/runner': 4.1.0 '@vitest/snapshot': 4.1.0 @@ -24262,7 +24314,7 @@ snapshots: tinyexec: 1.1.2 tinyglobby: 0.2.17 tinyrainbow: 3.1.0 - vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.48.0)(tsx@4.21.0)(yaml@2.8.3) + vite: 8.0.5(@emnapi/core@1.9.0)(@emnapi/runtime@1.9.0)(@types/node@24.9.1)(esbuild@0.27.7)(jiti@2.7.0)(sass@1.98.0)(terser@5.49.0)(tsx@4.21.0)(yaml@2.8.3) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 24.9.1 From a8d473d79275078f83cd59bc7804da844f1ffd14 Mon Sep 17 00:00:00 2001 From: Christian Fehmer Date: Thu, 9 Jul 2026 13:41:40 +0200 Subject: [PATCH 3/8] refactor: prevent miniSnapshot to be set to db (@fehmer) (#8215) Co-authored-by: Jack --- .../ts/components/pages/account/MyProfile.tsx | 3 +-- frontend/src/ts/constants/default-snapshot.ts | 1 + frontend/src/ts/states/snapshot.ts | 21 ++++++++++++------- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/frontend/src/ts/components/pages/account/MyProfile.tsx b/frontend/src/ts/components/pages/account/MyProfile.tsx index 9b1708c2243b..a78c97316ea9 100644 --- a/frontend/src/ts/components/pages/account/MyProfile.tsx +++ b/frontend/src/ts/components/pages/account/MyProfile.tsx @@ -1,4 +1,3 @@ -import { UserProfile as UserProfileType } from "@monkeytype/schemas/users"; import { JSXElement, Show } from "solid-js"; import { getActivePage } from "../../../states/core"; @@ -9,7 +8,7 @@ export function MyProfile(): JSXElement { const profile = () => getActivePage() === "account" ? getSnapshot() : undefined; return ( - + {(p) => } ); diff --git a/frontend/src/ts/constants/default-snapshot.ts b/frontend/src/ts/constants/default-snapshot.ts index d0451fd1af5d..4f5a5e9fad52 100644 --- a/frontend/src/ts/constants/default-snapshot.ts +++ b/frontend/src/ts/constants/default-snapshot.ts @@ -71,6 +71,7 @@ export type Snapshot = Omit< xp: number; testActivity?: ModifiableTestActivityCalendar; testActivityByYear?: { [key: string]: TestActivityCalendar }; + isMiniSnapshot?: never; }; const defaultSnap = { diff --git a/frontend/src/ts/states/snapshot.ts b/frontend/src/ts/states/snapshot.ts index c154f163024b..8dbff0462baf 100644 --- a/frontend/src/ts/states/snapshot.ts +++ b/frontend/src/ts/states/snapshot.ts @@ -5,8 +5,8 @@ import { Mode } from "@monkeytype/schemas/shared"; export type MiniSnapshot = Omit< Snapshot, - "results" | "presets" | "filterPresets" ->; + "testActivity" | "testActivityByYear" | "isMiniSnapshot" +> & { isMiniSnapshot: boolean }; const [snapshot, updateSnapshot] = createStore<{ value: MiniSnapshot | undefined; }>({ value: undefined }); @@ -14,14 +14,21 @@ const [snapshot, updateSnapshot] = createStore<{ /** * This does not update the DB.snapshot. Use DB.setSnapshot for now. */ -export function _setSnapshot(newValue: MiniSnapshot | undefined): void { +export function _setSnapshot(newValue: Snapshot | undefined): void { if (newValue === undefined) { updateSnapshot("value", undefined); } else { - updateSnapshot( - "value", - reconcile(structuredClone(unwrap(newValue)), { merge: true }), - ); + const snapshot = structuredClone(unwrap(newValue)); + + delete snapshot.testActivity; + delete snapshot.testActivityByYear; + + const miniSnapshot = { + ...snapshot, + isMiniSnapshot: true, + }; + + updateSnapshot("value", reconcile(miniSnapshot, { merge: true })); } } From fc737e3f3a8bca503218cd28149e9cb5317bf610 Mon Sep 17 00:00:00 2001 From: Christian Fehmer Date: Thu, 9 Jul 2026 13:43:37 +0200 Subject: [PATCH 4/8] fix(test): missing average notice for quotes (@fehmer) (#8201) average not showing in quotes mode if the selected language has a size suffix. --- frontend/src/ts/collections/results.ts | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/frontend/src/ts/collections/results.ts b/frontend/src/ts/collections/results.ts index 7a4de663911a..c742e1d7e491 100644 --- a/frontend/src/ts/collections/results.ts +++ b/frontend/src/ts/collections/results.ts @@ -40,6 +40,7 @@ import { applyIdWorkaround } from "./utils/misc"; import { getConfig } from "../config/store"; import { getMode2 } from "../utils/misc"; import { getCurrentQuote } from "../states/test"; +import { removeLanguageSize } from "../utils/strings"; export type ResultsQueryState = { difficulty: SnapshotResult["difficulty"][]; @@ -590,10 +591,18 @@ export type CurrentSettingsFilter = { export function useUserAverage10LiveQuery(options: { isEnabled: Accessor; }) { - const settingsFilter = createMemo(() => ({ - ...getConfig, - mode2: getMode2(getConfig, getCurrentQuote()), - })); + const settingsFilter = createMemo(() => { + const language = + getConfig.mode === "quote" + ? removeLanguageSize(getConfig.language) + : getConfig.language; + + return { + ...getConfig, + mode2: getMode2(getConfig, getCurrentQuote()), + language, + }; + }); const activeTagsQuery = useActiveTagsLiveQuery(); From 1c862b7a3b82ad85e8b38808de0588b774882d25 Mon Sep 17 00:00:00 2001 From: Christian Fehmer Date: Thu, 9 Jul 2026 13:44:20 +0200 Subject: [PATCH 5/8] impr: native support for number in InputField (@fehmer) (#8197) --- .../components/ui/form/InputField.spec.tsx | 83 ++++++++++++++++--- .../modals/CustomGeneratorModal.tsx | 12 +-- .../modals/CustomWordAmountModal.tsx | 16 ++-- .../pages/settings/SearchableAutoSetting.tsx | 16 +--- .../settings/custom-setting/MaxLineWidth.tsx | 14 +--- .../pages/settings/custom-setting/MinAcc.tsx | 12 +-- .../settings/custom-setting/MinBurst.tsx | 12 +-- .../settings/custom-setting/MinSpeed.tsx | 10 +-- .../settings/custom-setting/PaceCaret.tsx | 12 +-- .../src/ts/components/ui/form/InputField.tsx | 31 ++++++- 10 files changed, 126 insertions(+), 92 deletions(-) diff --git a/frontend/__tests__/components/ui/form/InputField.spec.tsx b/frontend/__tests__/components/ui/form/InputField.spec.tsx index 8b079abdcf3e..aaa221edf9d1 100644 --- a/frontend/__tests__/components/ui/form/InputField.spec.tsx +++ b/frontend/__tests__/components/ui/form/InputField.spec.tsx @@ -4,22 +4,32 @@ import { describe, it, expect, vi } from "vitest"; import { InputField } from "../../../../src/ts/components/ui/form/InputField"; -function makeField(name: string, value = ""): AnyFieldApi { +function makeField( + name: string, + value?: string | number | boolean, +): AnyFieldApi { + let current = value; + const meta = { + isValidating: false, + isTouched: false, + isValid: true, + isDefaultValue: true, + errors: [] as string[], + }; return { name, - state: { - value, - meta: { - isValidating: false, - isTouched: false, - isValid: true, - isDefaultValue: true, - errors: [], - }, + get state() { + return { + value: current, + meta, + }; }, - options: {}, + options: { default: value }, handleBlur: vi.fn(), - handleChange: vi.fn(), + handleChange: vi.fn((v: unknown) => { + current = v as typeof value; + }), + setValue: vi.fn(), getMeta: () => ({ hasWarning: false, warnings: [] }), } as unknown as AnyFieldApi; } @@ -61,6 +71,16 @@ describe("InputField", () => { expect(field.handleChange).toHaveBeenCalledWith("test"); }); + it("calls handleChange on input for number", async () => { + const field = makeField("name", 2.5); + render(() => field} type="number" />); + + fireEvent.input(screen.getByRole("spinbutton"), { + target: { value: "1.25" }, + }); + expect(field.handleChange).toHaveBeenCalledWith(1.25); + }); + it("calls handleBlur on blur", async () => { const field = makeField("name"); render(() => field} />); @@ -100,4 +120,43 @@ describe("InputField", () => { expect(container.querySelector(".fa-circle-notch")).not.toBeInTheDocument(); }); + + it("resets to default value on blur when empty for type number", async () => { + const field = makeField("age", 25); + field.form = { options: { defaultValues: { age: 25 } } } as any; + render(() => ( + field} + type="number" + resetToDefaultIfEmptyOnBlur + /> + )); + + fireEvent.input(screen.getByRole("spinbutton"), { + target: { value: "" }, + }); + fireEvent.blur(screen.getByRole("spinbutton")); + expect(field.setValue).toHaveBeenCalledWith(25); + }); + + it("resets to default value on blur when empty for type string", async () => { + const field = makeField("name", "Alice"); + field.form = { options: { defaultValues: { name: "Alice" } } } as any; + render(() => ( + field} resetToDefaultIfEmptyOnBlur /> + )); + + fireEvent.input(screen.getByRole("textbox"), { + target: { value: "" }, + }); + fireEvent.blur(screen.getByRole("textbox")); + expect(field.setValue).toHaveBeenCalledWith("Alice"); + }); + + it("renders NaN as empty string for type number", async () => { + const field = makeField("value", NaN); + render(() => field} type="number" />); + + expect(screen.getByRole("spinbutton").getAttribute("value")).toBeNull(); + }); }); diff --git a/frontend/src/ts/components/modals/CustomGeneratorModal.tsx b/frontend/src/ts/components/modals/CustomGeneratorModal.tsx index 4d7631f8fb13..5c94924b5976 100644 --- a/frontend/src/ts/components/modals/CustomGeneratorModal.tsx +++ b/frontend/src/ts/components/modals/CustomGeneratorModal.tsx @@ -104,9 +104,9 @@ export function CustomGeneratorModal(props: { const form = createForm(() => ({ defaultValues: { characterSet: "", - minLength: "2", - maxLength: "5", - wordCount: "100", + minLength: 2, + maxLength: 5, + wordCount: 100, }, onSubmit: ({ value }) => { const input = value.characterSet.trim(); @@ -116,9 +116,9 @@ export function CustomGeneratorModal(props: { } const characters = input.split(/\s+/); - const minLength = parseInt(value.minLength) || 2; - const maxLength = parseInt(value.maxLength) || 5; - const wordCount = parseInt(value.wordCount) || 100; + const minLength = value.minLength ?? 2; + const maxLength = value.maxLength ?? 5; + const wordCount = value.wordCount ?? 100; const generatedWords: string[] = []; for (let i = 0; i < wordCount; i++) { diff --git a/frontend/src/ts/components/modals/CustomWordAmountModal.tsx b/frontend/src/ts/components/modals/CustomWordAmountModal.tsx index 57e6ced0a9f2..766b037dbd08 100644 --- a/frontend/src/ts/components/modals/CustomWordAmountModal.tsx +++ b/frontend/src/ts/components/modals/CustomWordAmountModal.tsx @@ -1,5 +1,6 @@ import { createForm } from "@tanstack/solid-form"; import { JSXElement } from "solid-js"; +import { z } from "zod"; import { setConfig } from "../../config/setters"; import { getConfig } from "../../config/store"; @@ -9,15 +10,15 @@ import { showNoticeNotification } from "../../states/notifications"; import { AnimatedModal } from "../common/AnimatedModal"; import { InputField } from "../ui/form/InputField"; import { SubmitButton } from "../ui/form/SubmitButton"; +import { fromSchema } from "../ui/form/utils"; export function CustomWordAmountModal(): JSXElement { const form = createForm(() => ({ defaultValues: { - words: getConfig.words.toString(), + words: getConfig.words, }, onSubmit: ({ value }) => { - const val = parseInt(value.words, 10); - + const val = value.words; setConfig("words", val); restartTestEvent.dispatch(); @@ -40,7 +41,7 @@ export function CustomWordAmountModal(): JSXElement { title="Custom word amount" focusFirstInput="focusAndSelect" beforeShow={() => { - form.reset({ words: getConfig.words.toString() }); + form.reset({ words: getConfig.words }); }} >
{ - const val = parseInt(value, 10); - if (isNaN(val) || !isFinite(val)) return "Must be a number"; - if (val < 0) return "Must be non-negative"; - return undefined; - }, + onChange: fromSchema(z.number().nonnegative().safe()), }} children={(field) => ( diff --git a/frontend/src/ts/components/pages/settings/SearchableAutoSetting.tsx b/frontend/src/ts/components/pages/settings/SearchableAutoSetting.tsx index 13a2e115e08e..bfff9ac024e5 100644 --- a/frontend/src/ts/components/pages/settings/SearchableAutoSetting.tsx +++ b/frontend/src/ts/components/pages/settings/SearchableAutoSetting.tsx @@ -31,7 +31,7 @@ export function SearchableAutoSetting(props: { [props.key]: getConfig[props.key], }, onSubmit: ({ value }) => { - const val = parseFloat(String(value[props.key])); + const val = value[props.key]; if (val === getConfig[props.key]) return; savedIndicator.flash(); setConfig(props.key, val as Config[T]); @@ -56,17 +56,9 @@ export function SearchableAutoSetting(props: { //@ts-expect-error -- i think because props.key is a key of config, which is a zod schema, the typechecker gives up (too complex to infer or something) name={props.key} validators={{ - onChange: ({ value }) => { - const val = parseFloat(String(value)); - if (isNaN(val)) { - return "Must be a number"; - } - return fromSchema( - ConfigSchema.shape[props.key] as z.ZodNumber, - )({ - value: val, - }); - }, + onChange: fromSchema( + ConfigSchema.shape[props.key] as z.ZodNumber, + ), onBlur: () => { void form.handleSubmit(); }, diff --git a/frontend/src/ts/components/pages/settings/custom-setting/MaxLineWidth.tsx b/frontend/src/ts/components/pages/settings/custom-setting/MaxLineWidth.tsx index 74d60ad3b301..c00eaca0992b 100644 --- a/frontend/src/ts/components/pages/settings/custom-setting/MaxLineWidth.tsx +++ b/frontend/src/ts/components/pages/settings/custom-setting/MaxLineWidth.tsx @@ -6,7 +6,6 @@ import { configMetadata } from "../../../../config/metadata"; import { setConfig } from "../../../../config/setters"; import { getConfig } from "../../../../config/store"; import { useSavedIndicator } from "../../../../hooks/useSavedIndicator"; -// import { showSuccessNotification } from "../../../../states/notifications"; import { InputField } from "../../../ui/form/InputField"; import { fromSchema } from "../../../ui/form/utils"; import { SearchableSetting } from "../SearchableSetting"; @@ -19,7 +18,8 @@ export function MaxLineWidth(): JSXElement { maxLineWidth: getConfig.maxLineWidth, }, onSubmit: ({ value }) => { - const val = parseFloat(String(value.maxLineWidth)); + const val = value.maxLineWidth; + if (val === getConfig.maxLineWidth) return; flash(); setConfig("maxLineWidth", val); @@ -44,15 +44,7 @@ export function MaxLineWidth(): JSXElement { { - const val = parseFloat(String(value)); - if (isNaN(val)) { - return "Must be a number"; - } - return fromSchema(MaxLineWidthSchema)({ - value: val, - }); - }, + onChange: fromSchema(MaxLineWidthSchema), onBlur: () => { void form.handleSubmit(); }, diff --git a/frontend/src/ts/components/pages/settings/custom-setting/MinAcc.tsx b/frontend/src/ts/components/pages/settings/custom-setting/MinAcc.tsx index 47204d95869d..beedc431d894 100644 --- a/frontend/src/ts/components/pages/settings/custom-setting/MinAcc.tsx +++ b/frontend/src/ts/components/pages/settings/custom-setting/MinAcc.tsx @@ -20,7 +20,7 @@ export function MinAcc(): JSXElement { minAccCustom: getConfig.minAccCustom, }, onSubmit: ({ value }) => { - const val = parseFloat(String(value.minAccCustom)); + const val = value.minAccCustom; if (val === getConfig.minAccCustom) return; if (getConfig.minAcc === "custom") { // @@ -50,15 +50,7 @@ export function MinAcc(): JSXElement { { - const val = parseFloat(String(value)); - if (isNaN(val)) { - return "Must be a number"; - } - return fromSchema(MinimumAccuracyCustomSchema)({ - value: val, - }); - }, + onChange: fromSchema(MinimumAccuracyCustomSchema), onBlur: () => { void form.handleSubmit(); }, diff --git a/frontend/src/ts/components/pages/settings/custom-setting/MinBurst.tsx b/frontend/src/ts/components/pages/settings/custom-setting/MinBurst.tsx index 45293467adda..768c99d94ce9 100644 --- a/frontend/src/ts/components/pages/settings/custom-setting/MinBurst.tsx +++ b/frontend/src/ts/components/pages/settings/custom-setting/MinBurst.tsx @@ -20,7 +20,7 @@ export function MinBurst(): JSXElement { minBurstCustomSpeed: getConfig.minBurstCustomSpeed, }, onSubmit: ({ value }) => { - const val = parseFloat(String(value.minBurstCustomSpeed)); + const val = value.minBurstCustomSpeed; if (val === getConfig.minBurstCustomSpeed) return; if (getConfig.minBurst !== "off") { // @@ -50,15 +50,7 @@ export function MinBurst(): JSXElement { { - const val = parseFloat(String(value)); - if (isNaN(val)) { - return "Must be a number"; - } - return fromSchema(MinimumBurstCustomSpeedSchema)({ - value: val, - }); - }, + onChange: fromSchema(MinimumBurstCustomSpeedSchema), onBlur: () => { void form.handleSubmit(); }, diff --git a/frontend/src/ts/components/pages/settings/custom-setting/MinSpeed.tsx b/frontend/src/ts/components/pages/settings/custom-setting/MinSpeed.tsx index fc4a1a8d754c..122510c63080 100644 --- a/frontend/src/ts/components/pages/settings/custom-setting/MinSpeed.tsx +++ b/frontend/src/ts/components/pages/settings/custom-setting/MinSpeed.tsx @@ -20,7 +20,7 @@ export function MinSpeed(): JSXElement { minWpmCustomSpeed: getConfig.minWpmCustomSpeed, }, onSubmit: ({ value }) => { - const val = parseFloat(String(value.minWpmCustomSpeed)); + const val = value.minWpmCustomSpeed; if (val === getConfig.minWpmCustomSpeed) return; if (getConfig.minWpm === "custom") { // @@ -50,13 +50,7 @@ export function MinSpeed(): JSXElement { { - const val = parseFloat(String(value)); - if (isNaN(val)) { - return "Must be a number"; - } - return fromSchema(MinWpmCustomSpeedSchema)({ value: val }); - }, + onChange: fromSchema(MinWpmCustomSpeedSchema), onBlur: () => { void form.handleSubmit(); }, diff --git a/frontend/src/ts/components/pages/settings/custom-setting/PaceCaret.tsx b/frontend/src/ts/components/pages/settings/custom-setting/PaceCaret.tsx index 8e20275d3d91..124af98666bc 100644 --- a/frontend/src/ts/components/pages/settings/custom-setting/PaceCaret.tsx +++ b/frontend/src/ts/components/pages/settings/custom-setting/PaceCaret.tsx @@ -26,7 +26,7 @@ export function PaceCaret(): JSXElement { paceCaretCustomSpeed: getConfig.paceCaretCustomSpeed, }, onSubmit: ({ value }) => { - const val = parseFloat(String(value.paceCaretCustomSpeed)); + const val = value.paceCaretCustomSpeed; if (val === getConfig.paceCaretCustomSpeed) return; if (getConfig.paceCaret !== "off") { // @@ -57,15 +57,7 @@ export function PaceCaret(): JSXElement { { - const val = parseFloat(String(value)); - if (isNaN(val)) { - return "Must be a number"; - } - return fromSchema(PaceCaretCustomSpeedSchema)({ - value: val, - }); - }, + onChange: fromSchema(PaceCaretCustomSpeedSchema), onBlur: () => { void form.handleSubmit(); }, diff --git a/frontend/src/ts/components/ui/form/InputField.tsx b/frontend/src/ts/components/ui/form/InputField.tsx index cb72a3f5268f..ad080d184cab 100644 --- a/frontend/src/ts/components/ui/form/InputField.tsx +++ b/frontend/src/ts/components/ui/form/InputField.tsx @@ -69,11 +69,12 @@ export function InputField(props: { placeholder={props.placeholder ?? ""} autocomplete={props.autocomplete} name={props.field().name as string} - value={(props.field().state.value as string) ?? ""} + value={convertValueToString(props.field().state.value)} onBlur={() => { if ( props.resetToDefaultIfEmptyOnBlur && - props.field().state.value === "" + (props.field().state.value === undefined || + props.field().state.value === "") ) { props.field().setValue( // oxlint-disable-next-line typescript/no-unsafe-member-access @@ -84,7 +85,11 @@ export function InputField(props: { props.field().handleBlur(); }} onInput={(e) => { - props.field().handleChange(e.target.value); + const value: unknown = convertStringToValue( + props.field().state.value, + e.target.value, + ); + props.field().handleChange(value); }} onKeyDown={(e) => { if (e.key === "Enter") { @@ -151,3 +156,23 @@ function getDateOptions( max: applyFormat((schema as ZodDate).maxDate), }; } + +function convertValueToString(input: unknown | undefined): string { + if (input === undefined || input === null) return ""; + if (typeof input === "number") { + if (isFinite(input)) return input.toString(); + else return ""; + } + return input as string; +} + +function convertStringToValue( + defaultValue: T, + newValue: string, +): T | undefined { + if (defaultValue === undefined || defaultValue === null) return newValue as T; + if (newValue === "") return undefined; + if (typeof defaultValue === "number") return Number.parseFloat(newValue) as T; + + return newValue as T; +} From 6068a2c58f0ca5004e16cf530b4c1dd94265c80d Mon Sep 17 00:00:00 2001 From: Miodec Date: Thu, 9 Jul 2026 13:52:06 +0200 Subject: [PATCH 6/8] refactor: move test active state to a signal --- frontend/__tests__/root/config.spec.ts | 8 +++---- frontend/src/ts/config/setters.ts | 6 ++--- frontend/src/ts/controllers/ad-controller.ts | 4 ++-- .../src/ts/controllers/route-controller.ts | 3 ++- .../src/ts/input/handlers/before-delete.ts | 3 ++- frontend/src/ts/input/handlers/insert-text.ts | 3 ++- .../src/ts/input/listeners/composition.ts | 3 ++- frontend/src/ts/legacy-states/connection.ts | 4 ++-- frontend/src/ts/states/test.ts | 2 ++ frontend/src/ts/test/live-acc.ts | 4 ++-- frontend/src/ts/test/live-burst.ts | 4 ++-- frontend/src/ts/test/live-speed.ts | 4 ++-- frontend/src/ts/test/monkey.ts | 4 ++-- frontend/src/ts/test/pace-caret.ts | 13 ++++++----- frontend/src/ts/test/test-logic.ts | 22 ++++++++++--------- frontend/src/ts/test/test-state.ts | 5 ----- frontend/src/ts/test/test-timer.ts | 5 +++-- frontend/src/ts/test/test-ui.ts | 8 +++++-- frontend/src/ts/test/timer-progress.ts | 6 ++--- frontend/src/ts/ui.ts | 3 ++- 20 files changed, 62 insertions(+), 52 deletions(-) diff --git a/frontend/__tests__/root/config.spec.ts b/frontend/__tests__/root/config.spec.ts index 40e3ced07ee2..23b066b0db86 100644 --- a/frontend/__tests__/root/config.spec.ts +++ b/frontend/__tests__/root/config.spec.ts @@ -15,6 +15,8 @@ import * as ConfigValidation from "../../src/ts/config/validation"; import { configEvent } from "../../src/ts/events/config"; import * as ApeConfig from "../../src/ts/ape/config"; import * as Notifications from "../../src/ts/states/notifications"; +import * as TestState from "../../src/ts/states/test"; + const { replaceConfig, getConfig } = __testing; describe("Config", () => { @@ -41,6 +43,7 @@ describe("Config", () => { ); const miscReloadAfterMock = vi.spyOn(Misc, "reloadAfter"); const miscTriggerResizeMock = vi.spyOn(Misc, "triggerResize"); + const stateIsTestActiveMock = vi.spyOn(TestState, "isTestActive"); const mocks = [ canSetConfigWithCurrentFunboxesMock, @@ -56,13 +59,10 @@ describe("Config", () => { vi.useFakeTimers(); mocks.forEach((it) => it.mockClear()); - vi.mock("../../src/ts/test/test-state", () => ({ - isActive: true, - })); - isConfigValueValidMock.mockReturnValue(true); canSetConfigWithCurrentFunboxesMock.mockReturnValue(true); dbSaveConfigMock.mockResolvedValue(); + stateIsTestActiveMock.mockReturnValue(true); replaceConfig({}); }); diff --git a/frontend/src/ts/config/setters.ts b/frontend/src/ts/config/setters.ts index 0898169fabfc..7b185cefe6e1 100644 --- a/frontend/src/ts/config/setters.ts +++ b/frontend/src/ts/config/setters.ts @@ -9,12 +9,12 @@ import { canSetConfigWithCurrentFunboxes, canSetFunboxWithConfig, } from "./funbox-validation"; -import * as TestState from "../test/test-state"; import { triggerResize, escapeHTML } from "../utils/misc"; import { camelCaseToWords, capitalizeFirstLetter } from "../utils/strings"; import { Config, setConfigStore } from "./store"; import { FunboxName } from "@monkeytype/schemas/configs"; import { typedKeys } from "@monkeytype/util/objects"; +import { isTestActive } from "../states/test"; export function setConfig( key: T, @@ -41,7 +41,7 @@ export function setConfig( if ( metadata.changeRequiresRestart && - TestState.isActive && + isTestActive() && Config.funbox.includes("no_quit") ) { showNoticeNotification( @@ -154,7 +154,7 @@ export function setQuoteLengthAll(nosave?: boolean): boolean { } export function toggleFunbox(funbox: FunboxName, nosave?: boolean): boolean { - if (TestState.isActive && Config.funbox.includes("no_quit")) { + if (isTestActive() && Config.funbox.includes("no_quit")) { showNoticeNotification( "No quit funbox is active. Please finish the test.", { diff --git a/frontend/src/ts/controllers/ad-controller.ts b/frontend/src/ts/controllers/ad-controller.ts index f8f471827be8..9c1e3cb1c3c4 100644 --- a/frontend/src/ts/controllers/ad-controller.ts +++ b/frontend/src/ts/controllers/ad-controller.ts @@ -2,10 +2,10 @@ import { debounce } from "throttle-debounce"; import { configEvent } from "../events/config"; import { Config } from "../config/store"; -import * as TestState from "../test/test-state"; import * as EG from "./eg-ad-controller"; import * as PW from "./pw-ad-controller"; import { onDOMReady, qs } from "../utils/dom"; +import { isTestActive } from "../states/test"; // import { createEffect } from "solid-js"; const breakpoint = 900; @@ -41,7 +41,7 @@ function init(): void { } setInterval(() => { - if (TestState.isActive) { + if (isTestActive()) { return; } if (choice === "eg") { diff --git a/frontend/src/ts/controllers/route-controller.ts b/frontend/src/ts/controllers/route-controller.ts index a704fa59c514..dc9b533426c9 100644 --- a/frontend/src/ts/controllers/route-controller.ts +++ b/frontend/src/ts/controllers/route-controller.ts @@ -7,6 +7,7 @@ import * as TestState from "../test/test-state"; import { showNoticeNotification } from "../states/notifications"; import { navigationEvent, type NavigateOptions } from "../events/navigation"; import { authEvent } from "../events/auth"; +import { isTestActive } from "../states/test"; //source: https://www.youtube.com/watch?v=OstALBk-jTc // https://www.youtube.com/watch?v=OstALBk-jTc @@ -176,7 +177,7 @@ export async function navigate( } const noQuit = isFunboxActive("no_quit"); - if (TestState.isActive && noQuit) { + if (isTestActive() && noQuit) { showNoticeNotification( "No quit funbox is active. Please finish the test.", { diff --git a/frontend/src/ts/input/handlers/before-delete.ts b/frontend/src/ts/input/handlers/before-delete.ts index 50d84df13ea0..b9fd550211da 100644 --- a/frontend/src/ts/input/handlers/before-delete.ts +++ b/frontend/src/ts/input/handlers/before-delete.ts @@ -5,9 +5,10 @@ import { getInputElementValue } from "../input-element"; import * as TestUI from "../../test/test-ui"; import { isAwaitingNextWord } from "../state"; import { getInputForWord } from "../../test/events/data"; +import { isTestActive } from "../../states/test"; export function onBeforeDelete(event: InputEvent): void { - if (!TestState.isActive) { + if (!isTestActive()) { event.preventDefault(); return; } diff --git a/frontend/src/ts/input/handlers/insert-text.ts b/frontend/src/ts/input/handlers/insert-text.ts index ec5a50d7cab8..4756bd16f725 100644 --- a/frontend/src/ts/input/handlers/insert-text.ts +++ b/frontend/src/ts/input/handlers/insert-text.ts @@ -31,6 +31,7 @@ import { shouldGoToNextWord, isCharCorrect } from "../helpers/validation"; import { getCurrentInput, logTestEvent } from "../../test/events/data"; import { getCommitCharacterType, normalizeData } from "../helpers/util"; import { areAllWordsGenerated } from "../../test/words-generator"; +import { isTestActive } from "../../states/test"; const charOverrides = new Map([ ["…", "..."], @@ -132,7 +133,7 @@ export async function onInsertText(options: OnInsertTextParams): Promise { const data = normalizedData ?? options.data; // start if needed - if (!TestState.isActive) { + if (!isTestActive()) { TestLogic.startTest(now); } diff --git a/frontend/src/ts/input/listeners/composition.ts b/frontend/src/ts/input/listeners/composition.ts index c144fe3bd334..8f7272543782 100644 --- a/frontend/src/ts/input/listeners/composition.ts +++ b/frontend/src/ts/input/listeners/composition.ts @@ -6,6 +6,7 @@ import { setLastInsertCompositionTextData } from "../state"; import * as CompositionDisplay from "../../elements/composition-display"; import { onInsertText } from "../handlers/insert-text"; import { logTestEvent } from "../../test/events/data"; +import { isTestActive } from "../../states/test"; const inputEl = getInputElement(); @@ -21,7 +22,7 @@ inputEl.addEventListener("compositionstart", (event) => { CompositionState.setComposing(true); CompositionState.setData(""); setLastInsertCompositionTextData(""); - if (!TestState.isActive) { + if (!isTestActive()) { TestLogic.startTest(now); } diff --git a/frontend/src/ts/legacy-states/connection.ts b/frontend/src/ts/legacy-states/connection.ts index a3a6e3dfc3c4..f9facc27f102 100644 --- a/frontend/src/ts/legacy-states/connection.ts +++ b/frontend/src/ts/legacy-states/connection.ts @@ -1,9 +1,9 @@ import { debounce } from "throttle-debounce"; import { showSuccessNotification } from "../states/notifications"; import { connectionEvent } from "../events/connection"; -import * as TestState from "../test/test-state"; import { onDOMReady } from "../utils/dom"; import { addBanner, removeBanner } from "../states/banners"; +import { isTestActive } from "../states/test"; let state = navigator.onLine; @@ -38,7 +38,7 @@ const throttledHandleState = debounce(5000, () => { noInternetBannerId = undefined; } bannerAlreadyClosed = false; - } else if (!TestState.isActive) { + } else if (!isTestActive()) { showOfflineBanner(); } }); diff --git a/frontend/src/ts/states/test.ts b/frontend/src/ts/states/test.ts index 13186f92ebad..34e5d66b5799 100644 --- a/frontend/src/ts/states/test.ts +++ b/frontend/src/ts/states/test.ts @@ -58,6 +58,8 @@ export const [getCurrentQuote, setCurrentQuote] = export const [getLastSignedOutResult, setLastSignedOutResult] = createSignal(null); +export const [isTestActive, setTestActive] = createSignal(false); + createEffect(() => { getActivePage(); // depend on active page setIsLongTest( diff --git a/frontend/src/ts/test/live-acc.ts b/frontend/src/ts/test/live-acc.ts index a340772b89f3..db091352ae06 100644 --- a/frontend/src/ts/test/live-acc.ts +++ b/frontend/src/ts/test/live-acc.ts @@ -1,9 +1,9 @@ import { Config } from "../config/store"; -import * as TestState from "../test/test-state"; import { configEvent } from "../events/config"; import { applyReducedMotion } from "../utils/misc"; import { requestDebouncedAnimationFrame } from "../utils/debounced-animation-frame"; import { qs } from "../utils/dom"; +import { isTestActive } from "../states/test"; const textEl = qs("#liveStatsTextBottom .liveAcc"); const miniEl = qs("#liveStatsMini .acc"); @@ -30,7 +30,7 @@ let state = false; export function show(): void { if (Config.liveAccStyle === "off") return; - if (!TestState.isActive) return; + if (!isTestActive()) return; if (state) return; requestDebouncedAnimationFrame("live-acc.show", () => { if (Config.liveAccStyle === "mini") { diff --git a/frontend/src/ts/test/live-burst.ts b/frontend/src/ts/test/live-burst.ts index 9ed2ebac2025..8f3d79cc0f50 100644 --- a/frontend/src/ts/test/live-burst.ts +++ b/frontend/src/ts/test/live-burst.ts @@ -1,10 +1,10 @@ import { Config } from "../config/store"; -import * as TestState from "../test/test-state"; import { configEvent } from "../events/config"; import Format from "../singletons/format"; import { applyReducedMotion } from "../utils/misc"; import { requestDebouncedAnimationFrame } from "../utils/debounced-animation-frame"; import { qs } from "../utils/dom"; +import { isTestActive } from "../states/test"; const textEl = qs("#liveStatsTextBottom .liveBurst"); const miniEl = qs("#liveStatsMini .burst"); @@ -28,7 +28,7 @@ let state = false; export function show(): void { if (Config.liveBurstStyle === "off") return; - if (!TestState.isActive) return; + if (!isTestActive()) return; if (state) return; requestDebouncedAnimationFrame("live-burst.show", () => { if (Config.liveBurstStyle === "mini") { diff --git a/frontend/src/ts/test/live-speed.ts b/frontend/src/ts/test/live-speed.ts index 34a963359d9a..1016c399ee8d 100644 --- a/frontend/src/ts/test/live-speed.ts +++ b/frontend/src/ts/test/live-speed.ts @@ -1,10 +1,10 @@ import { Config } from "../config/store"; -import * as TestState from "./test-state"; import { configEvent } from "../events/config"; import Format from "../singletons/format"; import { applyReducedMotion } from "../utils/misc"; import { requestDebouncedAnimationFrame } from "../utils/debounced-animation-frame"; import { qs } from "../utils/dom"; +import { isTestActive } from "../states/test"; const textElement = qs("#liveStatsTextBottom .liveSpeed"); const miniElement = qs("#liveStatsMini .speed"); @@ -32,7 +32,7 @@ let state = false; export function show(): void { if (Config.liveSpeedStyle === "off") return; - if (!TestState.isActive) return; + if (!isTestActive()) return; if (state) return; requestDebouncedAnimationFrame("live-speed.show", () => { if (Config.liveSpeedStyle === "mini") { diff --git a/frontend/src/ts/test/monkey.ts b/frontend/src/ts/test/monkey.ts index c0f2f59167e4..8c369c95e1eb 100644 --- a/frontend/src/ts/test/monkey.ts +++ b/frontend/src/ts/test/monkey.ts @@ -1,11 +1,11 @@ import { mapRange } from "@monkeytype/util/numbers"; import { Config } from "../config/store"; import { configEvent } from "../events/config"; -import * as TestState from "../test/test-state"; import * as KeyConverter from "../utils/key-converter"; import { qs } from "../utils/dom"; import { Keycode } from "../constants/keys"; import { JSAnimation } from "animejs"; +import { isTestActive } from "../states/test"; const monkeyEl = qs("#monkey"); const monkeyFastEl = qs("#monkey .fast"); @@ -13,7 +13,7 @@ const monkeyFastEl = qs("#monkey .fast"); let monkeyFastOpacityAnimation: JSAnimation | undefined; configEvent.subscribe(({ key }) => { - if (key === "monkey" && TestState.isActive) { + if (key === "monkey" && isTestActive()) { if (Config.monkey) { monkeyEl?.show(); } else { diff --git a/frontend/src/ts/test/pace-caret.ts b/frontend/src/ts/test/pace-caret.ts index 31a950a29920..55348cf7888d 100644 --- a/frontend/src/ts/test/pace-caret.ts +++ b/frontend/src/ts/test/pace-caret.ts @@ -12,7 +12,12 @@ import { getUserAverage10Once, getUserDailyBestOnce, } from "../collections/results"; -import { getCurrentQuote, isPaceRepeat, setPaceCaretWpm } from "../states/test"; +import { + getCurrentQuote, + isPaceRepeat, + isTestActive, + setPaceCaretWpm, +} from "../states/test"; type Settings = { wpm: number; @@ -116,11 +121,7 @@ export async function init(): Promise { export async function update(expectedStepEnd: number): Promise { const currentSettings = settings; - if ( - currentSettings === null || - !TestState.isActive || - TestState.resultVisible - ) { + if (currentSettings === null || !isTestActive() || TestState.resultVisible) { return; } diff --git a/frontend/src/ts/test/test-logic.ts b/frontend/src/ts/test/test-logic.ts index 903f6bc6640b..cabf7eb36dc4 100644 --- a/frontend/src/ts/test/test-logic.ts +++ b/frontend/src/ts/test/test-logic.ts @@ -34,6 +34,7 @@ import { getRestartCount, isPaceRepeat, isRepeated, + isTestActive, pushIncompleteTest, resetIncompleteTests, setIsPaceRepeat, @@ -42,6 +43,7 @@ import { setLastResult, setLastSignedOutResult, setResultVisible, + setTestActive, setWordsHaveNewline, setWordsHaveNumbers, setWordsHaveTab, @@ -135,7 +137,7 @@ export function startTest(now: number): boolean { void AnalyticsController.log("testStartedNoLogin"); } - TestState.setActive(true); + setTestActive(true); Time.set(0); TestTimer.clear(); @@ -178,7 +180,7 @@ export function restart(options = {} as RestartOptions): void { const animationTime = options.noAnim ? 0 : Misc.applyReducedMotion(125); const noQuit = isFunboxActive("no_quit"); - if (TestState.isActive && noQuit) { + if (isTestActive() && noQuit) { showNoticeNotification( "No quit funbox is active. Please finish the test.", { @@ -193,7 +195,7 @@ export function restart(options = {} as RestartOptions): void { options.event?.preventDefault(); return; } - if (TestState.isActive) { + if (isTestActive()) { if (options.isQuickRestart) { if (Config.mode !== "zen") options.event?.preventDefault(); if ( @@ -247,7 +249,7 @@ export function restart(options = {} as RestartOptions): void { currentQuote !== null && Config.language.startsWith(currentQuote.language) && Config.repeatQuotes === "typing" && - (TestState.isActive || failReason !== "") + (isTestActive() || failReason !== "") ) { options.withSameWordset = true; } @@ -283,7 +285,7 @@ export function restart(options = {} as RestartOptions): void { setIsTestInvalid(false); resetModifierState(); Caret.hide(); - TestState.setActive(false); + setTestActive(false); Replay.pauseReplay(); TestState.setBailedOut(false); Caret.resetPosition(); @@ -830,7 +832,7 @@ function buildCompletedEvent( } export async function finish(difficultyFailed = false): Promise { - if (!TestState.isActive) return; + if (!isTestActive()) return; TestState.setResultCalculating(true); const now = performance.now(); TestTimer.clear(true, now); @@ -856,7 +858,7 @@ export async function finish(difficultyFailed = false): Promise { setResultVisible(true); TestState.setResultVisible(true); - TestState.setActive(false); + setTestActive(false); cleanupData(); @@ -1283,7 +1285,7 @@ qs(".pageTest")?.onChild("click", "#testInitFailed button.restart", () => { qs(".pageTest")?.onChild("click", "#restartTestButton", () => { if (TestState.resultCalculating) return; if ( - TestState.isActive && + isTestActive() && Config.repeatQuotes === "typing" && Config.mode === "quote" ) { @@ -1318,7 +1320,7 @@ qs(".pageTest")?.onChild("click", "#restartTestButtonWithSameWordset", () => { // little roadblock for basic cheating window.addEventListener("focus", () => { if ( - !TestState.isActive && + !isTestActive() && !TestState.resultVisible && (Config.mode === "time" || Config.mode === "words") ) { @@ -1332,7 +1334,7 @@ window.addEventListener("focus", () => { document.addEventListener("visibilitychange", () => { if (document.visibilityState !== "visible") return; if ( - !TestState.isActive && + !isTestActive() && !TestState.resultVisible && (Config.mode === "time" || Config.mode === "words") ) { diff --git a/frontend/src/ts/test/test-state.ts b/frontend/src/ts/test/test-state.ts index 59628dca46bf..1417615b7f27 100644 --- a/frontend/src/ts/test/test-state.ts +++ b/frontend/src/ts/test/test-state.ts @@ -1,7 +1,6 @@ import { promiseWithResolvers } from "../utils/misc"; import { EventLog } from "./events/types"; -export let isActive = false; export let bailedOut = false; export let selectedQuoteId = parseInt(localStorage.getItem("selectedQuoteId") ?? "1", 10) || 1; @@ -28,10 +27,6 @@ export function setKoreanStatus(val: boolean): void { koreanStatus = val; } -export function setActive(tf: boolean): void { - isActive = tf; -} - export function setBailedOut(tf: boolean): void { bailedOut = tf; } diff --git a/frontend/src/ts/test/test-timer.ts b/frontend/src/ts/test/test-timer.ts index 022f3673bd3f..99e1d402528c 100644 --- a/frontend/src/ts/test/test-timer.ts +++ b/frontend/src/ts/test/test-timer.ts @@ -33,6 +33,7 @@ import { } from "./events/live-cache"; import { getChars } from "./events/stats"; import { calculateWpm } from "../utils/numbers"; +import { isTestActive } from "../states/test"; let timerStartMs = 0; let stopped = true; @@ -40,7 +41,7 @@ const newTimer = createTimer({ duration: 1000, autoplay: false, onComplete: () => { - // sync guard — finish() is async and TestState.isActive flips behind an await + // sync guard — finish() is async and isTestActive() flips behind an await if (stopped) return; const now = performance.now(); const expectedThisFireMs = timerStartMs + (Time.get() + 1) * 1000; @@ -402,7 +403,7 @@ async function _startOld(now: number): Promise { const drift = roundTo2(Math.abs(interval - delay)); checkIfTimerIsSlow(drift); timer = setTimeout(function () { - if (!TestState.isActive) { + if (!isTestActive()) { if (timer !== null) clearTimeout(timer); SlowTimer.clear(); slowTimerCount = 0; diff --git a/frontend/src/ts/test/test-ui.ts b/frontend/src/ts/test/test-ui.ts index 35eba81484cc..b11e3113781b 100644 --- a/frontend/src/ts/test/test-ui.ts +++ b/frontend/src/ts/test/test-ui.ts @@ -62,7 +62,11 @@ import { } from "../utils/dom"; import { getTheme } from "../states/theme"; import { skipBreakdownEvent } from "../states/header"; -import { getCurrentQuote, wordsHaveNewline } from "../states/test"; +import { + getCurrentQuote, + isTestActive, + wordsHaveNewline, +} from "../states/test"; import { getCorrectedWordsHistory, getInputHistory, @@ -90,7 +94,7 @@ export function focusWords(force = false): void { blurInputElement(); } focusInputElement(true); - if (TestState.isActive) { + if (isTestActive()) { keepWordsInputInTheCenter(true); } else { const typingTest = document.querySelector("#typingTest"); diff --git a/frontend/src/ts/test/timer-progress.ts b/frontend/src/ts/test/timer-progress.ts index 4e8063cd0752..ca15f28d2940 100644 --- a/frontend/src/ts/test/timer-progress.ts +++ b/frontend/src/ts/test/timer-progress.ts @@ -8,7 +8,7 @@ import { configEvent } from "../events/config"; import { applyReducedMotion } from "../utils/misc"; import { requestDebouncedAnimationFrame } from "../utils/debounced-animation-frame"; import { animate } from "animejs"; -import { getCurrentQuote } from "../states/test"; +import { getCurrentQuote, isTestActive } from "../states/test"; const barEl = document.querySelector("#barTimerProgress .bar") as HTMLElement; const barOpacityEl = document.querySelector( @@ -30,7 +30,7 @@ function showElement(el: HTMLElement): void { } export function show(): void { - if (!TestState.isActive) return; + if (!isTestActive()) return; requestDebouncedAnimationFrame("timer-progress.show", () => { if (Config.mode !== "zen" && Config.timerStyle === "bar") { showElement(barOpacityEl); @@ -246,7 +246,7 @@ export function update(): void { } export function updateStyle(): void { - if (!TestState.isActive) return; + if (!isTestActive()) return; hide(); update(); if (Config.timerStyle === "off") return; diff --git a/frontend/src/ts/ui.ts b/frontend/src/ts/ui.ts index 2283c1870186..aa460fee676f 100644 --- a/frontend/src/ts/ui.ts +++ b/frontend/src/ts/ui.ts @@ -17,6 +17,7 @@ import { qs, qsr } from "./utils/dom"; import { createEffect } from "solid-js"; import fileStorage from "./utils/file-storage"; import { convertRemToPixels } from "./utils/numbers"; +import { isTestActive } from "./states/test"; let isPreviewingFont = false; export function previewFontFamily(font: FontName): void { @@ -94,7 +95,7 @@ window.addEventListener("beforeunload", (event) => { ) { //ignore } else { - if (TestState.isActive) { + if (isTestActive()) { event.preventDefault(); // Included for legacy support, e.g. Chrome/Edge < 119 // oxlint-disable-next-line no-deprecated From f4cc210c18e825561f45bf4c3f5ac0f24c1bc8bc Mon Sep 17 00:00:00 2001 From: Christian Fehmer Date: Thu, 9 Jul 2026 14:16:28 +0200 Subject: [PATCH 7/8] refactor(test): solid monkey (@fehmer) (#8182) Co-authored-by: Miodec --- frontend/__tests__/root/config.spec.ts | 1 + frontend/src/html/pages/test.html | 13 +- frontend/src/styles/index.scss | 4 +- frontend/src/styles/monkey.scss | 37 ---- frontend/src/styles/tailwind.css | 4 + frontend/src/ts/components/mount.tsx | 2 + .../src/ts/components/pages/test/Monkey.tsx | 72 ++++++++ frontend/src/ts/config/setters.ts | 4 +- frontend/src/ts/input/handlers/keydown.ts | 9 - frontend/src/ts/input/handlers/keyup.ts | 5 - frontend/src/ts/states/monkey.ts | 87 ++++++++++ frontend/src/ts/states/test.ts | 7 + frontend/src/ts/test/monkey.ts | 159 ------------------ frontend/src/ts/test/test-timer.ts | 12 +- frontend/src/ts/test/test-ui.ts | 6 +- 15 files changed, 182 insertions(+), 240 deletions(-) delete mode 100644 frontend/src/styles/monkey.scss create mode 100644 frontend/src/ts/components/pages/test/Monkey.tsx create mode 100644 frontend/src/ts/states/monkey.ts delete mode 100644 frontend/src/ts/test/monkey.ts diff --git a/frontend/__tests__/root/config.spec.ts b/frontend/__tests__/root/config.spec.ts index 23b066b0db86..6a95f6a54887 100644 --- a/frontend/__tests__/root/config.spec.ts +++ b/frontend/__tests__/root/config.spec.ts @@ -53,6 +53,7 @@ describe("Config", () => { notificationAddMock, miscReloadAfterMock, miscTriggerResizeMock, + stateIsTestActiveMock, ]; beforeEach(async () => { diff --git a/frontend/src/html/pages/test.html b/frontend/src/html/pages/test.html index 55ea01f92bc1..a4e0c0482850 100644 --- a/frontend/src/html/pages/test.html +++ b/frontend/src/html/pages/test.html @@ -65,6 +65,7 @@
+
- diff --git a/frontend/src/styles/index.scss b/frontend/src/styles/index.scss index bc08a6267fa6..34df003ff782 100644 --- a/frontend/src/styles/index.scss +++ b/frontend/src/styles/index.scss @@ -17,8 +17,8 @@ @layer custom-styles { @import "buttons", "ads", "test-activity", "animations", "caret", - "commandline", "core", "fonts", "inputs", "monkey", "popups", "scroll", - "test", "loading", "media-queries"; + "commandline", "core", "fonts", "inputs", "popups", "scroll", "test", + "loading", "media-queries"; .chartCanvas { width: 100% !important; diff --git a/frontend/src/styles/monkey.scss b/frontend/src/styles/monkey.scss deleted file mode 100644 index f5d4776d2fdc..000000000000 --- a/frontend/src/styles/monkey.scss +++ /dev/null @@ -1,37 +0,0 @@ -#monkey { - width: 308px; - height: 0; - margin: 0 auto; - animation: shake 0s infinite; - div { - height: 200px; - width: 308px; - position: fixed; - } - .up { - background-image: url("/images/monkey/m3.png"); - } - .left { - background-image: url("/images/monkey/m1.png"); - } - .right { - background-image: url("/images/monkey/m2.png"); - } - .both { - background-image: url("/images/monkey/m4.png"); - } - .fast { - .up { - background-image: url("/images/monkey/m3_fast.png"); - } - .left { - background-image: url("/images/monkey/m1_fast.png"); - } - .right { - background-image: url("/images/monkey/m2_fast.png"); - } - .both { - background-image: url("/images/monkey/m4_fast.png"); - } - } -} diff --git a/frontend/src/styles/tailwind.css b/frontend/src/styles/tailwind.css index 566e152a00e2..28f75b14b638 100644 --- a/frontend/src/styles/tailwind.css +++ b/frontend/src/styles/tailwind.css @@ -120,4 +120,8 @@ filter: invert(1); } } + + .animate-shake { + animation: shake 0.1s ease-in-out infinite; + } } diff --git a/frontend/src/ts/components/mount.tsx b/frontend/src/ts/components/mount.tsx index d6ca2b10e06d..3b4f88c755c9 100644 --- a/frontend/src/ts/components/mount.tsx +++ b/frontend/src/ts/components/mount.tsx @@ -24,6 +24,7 @@ import { ProfileSearchPage } from "./pages/profile/ProfileSearchPage"; import { SettingsPage } from "./pages/settings/SettingsPage"; import { Keymap } from "./pages/test/Keymap"; import { TestModesNotice } from "./pages/test/modes-notice/TestModesNotice"; +import { Monkey } from "./pages/test/Monkey"; import { TestConfig } from "./pages/test/TestConfig"; import { Popups } from "./popups/Popups"; @@ -50,6 +51,7 @@ const components: Record JSXElement> = { notfoundpage: () => , accountsettingspage: () => , keymap: () => , + monkey: () => , }; function mountToMountpoint(name: string, component: () => JSXElement): void { diff --git a/frontend/src/ts/components/pages/test/Monkey.tsx b/frontend/src/ts/components/pages/test/Monkey.tsx new file mode 100644 index 000000000000..4aaeba40bf0d --- /dev/null +++ b/frontend/src/ts/components/pages/test/Monkey.tsx @@ -0,0 +1,72 @@ +import { mapRange } from "@monkeytype/util/numbers"; + +import { getConfig } from "../../../config/store"; +import { getMonkeyState } from "../../../states/monkey"; +import { currentLiveStats, isTestActive } from "../../../states/test"; +import { AnimeShow } from "../../common/anime"; + +const MIN_WPM = 130; +const MAX_WPM = 180; + +export function Monkey() { + const speed = () => + (getConfig.blindMode ? currentLiveStats.raw : currentLiveStats.wpm) ?? 0; + + const fastOpacity = () => mapRange(speed(), MIN_WPM, MAX_WPM, 0, 1); + + const animDuration = () => { + const duration = mapRange(speed(), MIN_WPM, MAX_WPM, 0.25, 0.01); + return duration === 0.25 ? 0 : duration; + }; + + const state = () => { + const { left, right } = getMonkeyState(); + if (left && !right) return "left" as const; + if (right && !left) return "right" as const; + if (!left && !right) return "none" as const; + return "both" as const; + }; + + const monkeyImages = (suffix?: string) => { + const cur = state(); + return ( + <> + + + + + + ); + }; + + return ( + + + + ); +} diff --git a/frontend/src/ts/config/setters.ts b/frontend/src/ts/config/setters.ts index 7b185cefe6e1..c4fae23df085 100644 --- a/frontend/src/ts/config/setters.ts +++ b/frontend/src/ts/config/setters.ts @@ -1,8 +1,6 @@ import * as ConfigSchemas from "@monkeytype/schemas/configs"; import { ZodType as ZodSchema } from "zod"; import { saveToLocalStorage } from "../config/persistence"; -import { configMetadata } from "./metadata"; -import { isConfigValueValid } from "./validation"; import { configEvent } from "../events/config"; import { showNoticeNotification } from "../states/notifications"; import { @@ -11,7 +9,9 @@ import { } from "./funbox-validation"; import { triggerResize, escapeHTML } from "../utils/misc"; import { camelCaseToWords, capitalizeFirstLetter } from "../utils/strings"; +import { configMetadata } from "./metadata"; import { Config, setConfigStore } from "./store"; +import { isConfigValueValid } from "./validation"; import { FunboxName } from "@monkeytype/schemas/configs"; import { typedKeys } from "@monkeytype/util/objects"; import { isTestActive } from "../states/test"; diff --git a/frontend/src/ts/input/handlers/keydown.ts b/frontend/src/ts/input/handlers/keydown.ts index 6b070f410f57..6588988b0f0c 100644 --- a/frontend/src/ts/input/handlers/keydown.ts +++ b/frontend/src/ts/input/handlers/keydown.ts @@ -1,7 +1,6 @@ import { Config } from "../../config/store"; import * as TestLogic from "../../test/test-logic"; import { getCharFromEvent } from "../../test/layout-emulator"; -import * as Monkey from "../../test/monkey"; import { emulateInsertText } from "./insert-text"; import * as TestState from "../../test/test-state"; import { @@ -155,14 +154,6 @@ export async function onKeydown(event: KeyboardEvent): Promise { return; } - if (!event.repeat) { - //delaying because type() is called before show() - // meaning the first keypress of the test is not animated - setTimeout(() => { - Monkey.type(event); - }, 0); - } - if (Config.layout !== "default") { const emulatedChar = await getCharFromEvent(event); if (emulatedChar !== null) { diff --git a/frontend/src/ts/input/handlers/keyup.ts b/frontend/src/ts/input/handlers/keyup.ts index 2652404fe493..3b55fa514baa 100644 --- a/frontend/src/ts/input/handlers/keyup.ts +++ b/frontend/src/ts/input/handlers/keyup.ts @@ -1,5 +1,4 @@ import { Config } from "../../config/store"; -import * as Monkey from "../../test/monkey"; import { logTestEvent } from "../../test/events/data"; import { getTestEventCode } from "../../test/events/helpers"; @@ -25,8 +24,4 @@ export async function onKeyup(event: KeyboardEvent): Promise { event.preventDefault(); return; } - - setTimeout(() => { - Monkey.stop(event); - }, 0); } diff --git a/frontend/src/ts/states/monkey.ts b/frontend/src/ts/states/monkey.ts new file mode 100644 index 000000000000..82b6de74557b --- /dev/null +++ b/frontend/src/ts/states/monkey.ts @@ -0,0 +1,87 @@ +import { createEffect, createSignal, onCleanup } from "solid-js"; +import { getActivePage } from "./core"; +import { keycodeToKeyboardSide } from "../utils/key-converter"; +import { Keycode } from "../constants/keys"; +import { getConfig } from "../config/store"; + +const [getMonkeyState, setMonkeyState] = createSignal<{ + left: boolean; + right: boolean; +}>({ left: false, right: false }); + +export { getMonkeyState }; + +createEffect(() => { + setMonkeyState({ left: false, right: false }); + + if (getActivePage() === "test" && getConfig.monkey) { + const onKeyDown = (e: KeyboardEvent): void => handleKey(e, true); + const onKeyUp = (e: KeyboardEvent): void => handleKey(e, false); + + document.addEventListener("keydown", onKeyDown); + document.addEventListener("keyup", onKeyUp); + + onCleanup(() => { + document.removeEventListener("keydown", onKeyDown); + document.removeEventListener("keyup", onKeyUp); + }); + } +}); + +const middleKeysState = { left: false, right: false, last: "right" }; +function handleKey(event: KeyboardEvent, isKeyDown: boolean): void { + if (isKeyDown && event.repeat) return; + const { leftSide, rightSide } = keycodeToKeyboardSide(event.code as Keycode); + let { left, right } = getMonkeyState(); + + if (isKeyDown) { + if (leftSide && rightSide) { + // if its a middle key handle special case + if (middleKeysState.last === "left") { + if (!right) { + right = true; + middleKeysState.last = "right"; + middleKeysState.right = true; + } else if (!left) { + left = true; + middleKeysState.last = "left"; + middleKeysState.left = true; + } + } else { + if (!left) { + left = true; + middleKeysState.last = "left"; + middleKeysState.left = true; + } else if (!right) { + right = true; + middleKeysState.last = "right"; + middleKeysState.right = true; + } + } + } else { + // normal key set hand + left = left || leftSide; + right = right || rightSide; + } + } else { + //key up event + if (leftSide && rightSide) { + // if middle key handle special case + if (middleKeysState.left && middleKeysState.last === "left") { + left = false; + middleKeysState.left = false; + } else if (middleKeysState.right && middleKeysState.last === "right") { + right = false; + middleKeysState.right = false; + } else { + left = left && !middleKeysState.left; + right = right && !middleKeysState.right; + } + } else { + // normal key unset hand + left = left && !leftSide; + right = right && !rightSide; + } + } + setMonkeyState({ left, right }); +} diff --git a/frontend/src/ts/states/test.ts b/frontend/src/ts/states/test.ts index 34e5d66b5799..a60831a50f99 100644 --- a/frontend/src/ts/states/test.ts +++ b/frontend/src/ts/states/test.ts @@ -59,6 +59,13 @@ export const [getLastSignedOutResult, setLastSignedOutResult] = createSignal(null); export const [isTestActive, setTestActive] = createSignal(false); +export const [currentLiveStats, setCurrentLiveStats] = createStore<{ + wpm?: number; + acc?: number; + raw?: number; +}>({}); +export const resetCurrentLiveStats = (): void => + setCurrentLiveStats({ wpm: undefined, acc: undefined, raw: undefined }); createEffect(() => { getActivePage(); // depend on active page diff --git a/frontend/src/ts/test/monkey.ts b/frontend/src/ts/test/monkey.ts deleted file mode 100644 index 8c369c95e1eb..000000000000 --- a/frontend/src/ts/test/monkey.ts +++ /dev/null @@ -1,159 +0,0 @@ -import { mapRange } from "@monkeytype/util/numbers"; -import { Config } from "../config/store"; -import { configEvent } from "../events/config"; -import * as KeyConverter from "../utils/key-converter"; -import { qs } from "../utils/dom"; -import { Keycode } from "../constants/keys"; -import { JSAnimation } from "animejs"; -import { isTestActive } from "../states/test"; - -const monkeyEl = qs("#monkey"); -const monkeyFastEl = qs("#monkey .fast"); - -let monkeyFastOpacityAnimation: JSAnimation | undefined; - -configEvent.subscribe(({ key }) => { - if (key === "monkey" && isTestActive()) { - if (Config.monkey) { - monkeyEl?.show(); - } else { - monkeyEl?.hide(); - } - } -}); - -let left = false; -let right = false; -const middleKeysState = { left: false, right: false, last: "right" }; - -const upEls = monkeyEl?.qsa(".up"); -const rightEls = monkeyEl?.qsa(".right"); -const leftEls = monkeyEl?.qsa(".left"); -const bothEls = monkeyEl?.qsa(".both"); - -function update(): void { - if (!Config.monkey) return; - if (!monkeyEl?.hasClass("hidden")) { - upEls?.hide(); - rightEls?.hide(); - leftEls?.hide(); - bothEls?.hide(); - - if (left && right) { - bothEls?.show(); - } else if (right) { - rightEls?.show(); - } else if (left) { - leftEls?.show(); - } else { - upEls?.show(); - } - } -} - -export function updateFastOpacity(num: number): void { - if (!Config.monkey) return; - const opacity = mapRange(num, 130, 180, 0, 1); - monkeyFastOpacityAnimation = monkeyFastEl?.animate({ - opacity: opacity, - duration: 1000, - }); - let animDuration = mapRange(num, 130, 180, 0.25, 0.01); - if (animDuration === 0.25) animDuration = 0; - monkeyEl?.setStyle({ animationDuration: `${animDuration}s` }); -} - -export function type(event: KeyboardEvent): void { - if (!Config.monkey) return; - - const { leftSide, rightSide } = KeyConverter.keycodeToKeyboardSide( - event.code as Keycode, - ); - if (leftSide && rightSide) { - // if its a middle key handle special case - if (middleKeysState.last === "left") { - if (!right) { - right = true; - middleKeysState.last = "right"; - middleKeysState.right = true; - } else if (!left) { - left = true; - middleKeysState.last = "left"; - middleKeysState.left = true; - } - } else { - if (!left) { - left = true; - middleKeysState.last = "left"; - middleKeysState.left = true; - } else if (!right) { - right = true; - middleKeysState.last = "right"; - middleKeysState.right = true; - } - } - } else { - // normal key set hand - left = left || leftSide; - right = right || rightSide; - } - - update(); -} - -export function stop(event: KeyboardEvent): void { - if (!Config.monkey) return; - - const { leftSide, rightSide } = KeyConverter.keycodeToKeyboardSide( - event.code as Keycode, - ); - if (leftSide && rightSide) { - // if middle key handle special case - if (middleKeysState.left && middleKeysState.last === "left") { - left = false; - middleKeysState.left = false; - } else if (middleKeysState.right && middleKeysState.last === "right") { - right = false; - middleKeysState.right = false; - } else { - left = left && !middleKeysState.left; - right = right && !middleKeysState.right; - } - } else { - // normal key unset hand - left = left && !leftSide; - right = right && !rightSide; - } - - update(); -} - -export function show(): void { - if (!Config.monkey) return; - monkeyEl?.show(); - monkeyEl?.animate({ - opacity: [0, 1], - duration: 125, - }); -} - -export function hide(): void { - monkeyEl?.animate({ - opacity: [1, 0], - duration: 125, - onComplete: () => { - monkeyEl?.hide(); - monkeyEl?.setStyle({ animationDuration: "0s" }); - monkeyFastOpacityAnimation?.cancel(); - monkeyFastEl?.setStyle({ opacity: "0" }); - }, - }); -} - -export function instantHide(): void { - monkeyEl?.hide(); - monkeyEl?.setStyle({ opacity: "0" }); - monkeyEl?.setStyle({ animationDuration: "0s" }); - monkeyFastOpacityAnimation?.cancel(); - monkeyFastEl?.setStyle({ opacity: "0" }); -} diff --git a/frontend/src/ts/test/test-timer.ts b/frontend/src/ts/test/test-timer.ts index 99e1d402528c..f410da020534 100644 --- a/frontend/src/ts/test/test-timer.ts +++ b/frontend/src/ts/test/test-timer.ts @@ -7,7 +7,6 @@ import * as CustomText from "./custom-text"; import * as TimerProgress from "./timer-progress"; import * as LiveSpeed from "./live-speed"; import * as TestWords from "./test-words"; -import * as Monkey from "./monkey"; import { showNoticeNotification, showErrorNotification, @@ -33,7 +32,7 @@ import { } from "./events/live-cache"; import { getChars } from "./events/stats"; import { calculateWpm } from "../utils/numbers"; -import { isTestActive } from "../states/test"; +import { isTestActive, setCurrentLiveStats } from "../states/test"; let timerStartMs = 0; let stopped = true; @@ -147,13 +146,6 @@ function premid(): void { if (timerDebug) console.timeEnd("premid"); } -function monkey(wpmAndRaw: { wpm: number; raw: number }): void { - if (timerDebug) console.time("update monkey"); - const num = Config.blindMode ? wpmAndRaw.raw : wpmAndRaw.wpm; - Monkey.updateFastOpacity(num); - if (timerDebug) console.timeEnd("update monkey"); -} - function layoutfluid(): void { if (timerDebug) console.time("layoutfluid"); if (Config.funbox.includes("layoutfluid") && Config.mode === "time") { @@ -311,12 +303,12 @@ function timerStep(now: number, catchingUp: boolean): void { //ui updates requestDebouncedAnimationFrame("test-timer.timerStep", () => { premid(); - monkey(wpmAndRaw); }); // already using raf TimerProgress.update(); LiveSpeed.update(wpmAndRaw.wpm, wpmAndRaw.raw); + setCurrentLiveStats({ wpm: wpmAndRaw.wpm, acc, raw: wpmAndRaw.raw }); //logic if (Config.playTimeWarning !== "off") playTimeWarning(); diff --git a/frontend/src/ts/test/test-ui.ts b/frontend/src/ts/test/test-ui.ts index b11e3113781b..f5667b69a828 100644 --- a/frontend/src/ts/test/test-ui.ts +++ b/frontend/src/ts/test/test-ui.ts @@ -38,7 +38,6 @@ import * as Focus from "../test/focus"; import * as TimerProgress from "../test/timer-progress"; import * as LiveBurst from "./live-burst"; import * as LiveSpeed from "./live-speed"; -import * as Monkey from "./monkey"; import { blurInputElement, focusInputElement, @@ -65,6 +64,7 @@ import { skipBreakdownEvent } from "../states/header"; import { getCurrentQuote, isTestActive, + resetCurrentLiveStats, wordsHaveNewline, } from "../states/test"; import { @@ -1853,7 +1853,6 @@ export async function afterTestWordChange( export function onTestStart(): void { Focus.set(true); - Monkey.show(); TimerProgress.show(); LiveSpeed.show(); LiveAcc.show(); @@ -1874,7 +1873,7 @@ export function onTestRestart(source: "testPage" | "resultPage"): void { LiveAcc.reset(); TimerProgress.instantHide(); TimerProgress.reset(); - Monkey.instantHide(); + resetCurrentLiveStats(); LayoutfluidFunboxTimer.instantHide(); updatePremid(); focusWords(true); @@ -1912,7 +1911,6 @@ export function onTestFinish(): void { LiveBurst.hide(); TimerProgress.hide(); OutOfFocus.hide(); - Monkey.hide(); if (Config.playSoundOnClick === "16") { void SoundController.playFartReverb(); } From 37bb96cafbb03ffffe80960f2c28ddd2a088497a Mon Sep 17 00:00:00 2001 From: Christian Fehmer Date: Thu, 9 Jul 2026 14:28:51 +0200 Subject: [PATCH 8/8] feat: allow languages to set specific fonts (@Shamsuddin45, @fehmer) (#8208) Co-authored-by: Jack --- docs/LANGUAGES.md | 2 ++ frontend/src/ts/ui.ts | 23 +++++++++++++++++------ frontend/static/languages/lao.json | 1 + frontend/static/languages/sindhi.json | 1 + packages/schemas/src/fonts.ts | 2 +- packages/schemas/src/languages.ts | 2 ++ 6 files changed, 24 insertions(+), 7 deletions(-) diff --git a/docs/LANGUAGES.md b/docs/LANGUAGES.md index 6f380d669371..2cd639af9734 100644 --- a/docs/LANGUAGES.md +++ b/docs/LANGUAGES.md @@ -24,6 +24,7 @@ The contents of the file should be as follows: "joiningScript": boolean, "orderedByFrequency": boolean, "bcp47": string, + "preferredFont":string, "words": string[] } ``` @@ -34,6 +35,7 @@ It is recommended that you familiarize yourselves with JSON before adding a lang For `bcp47` put your languages [IETF language tag](https://en.wikipedia.org/wiki/IETF_language_tag). If the words you're adding are ordered by frequency (most common words at the top, least at the bottom) set the value of `orderedByFrequency` to `true`, otherwise `false`. Finally, add your list of words to the `words` field. +If the language is not rendered correctly, you can provide a `preferredFont`. The font needs to be one of monkeytypes fonts. Check the [fonts documentation](./FONTS.md). Then, go to `packages/schemas/src/languages.ts` and add your new language name at the _end_ of the `LanguageSchema` enum. Make sure to end the line with a comma. Make sure to add all your language names if you have created multiple word lists of differing lengths in the same language. diff --git a/frontend/src/ts/ui.ts b/frontend/src/ts/ui.ts index aa460fee676f..beeabd5d5a32 100644 --- a/frontend/src/ts/ui.ts +++ b/frontend/src/ts/ui.ts @@ -17,6 +17,8 @@ import { qs, qsr } from "./utils/dom"; import { createEffect } from "solid-js"; import fileStorage from "./utils/file-storage"; import { convertRemToPixels } from "./utils/numbers"; +import { getLanguage } from "./utils/json-data"; +import { replaceUnderscoresWithSpaces } from "./utils/strings"; import { isTestActive } from "./states/test"; let isPreviewingFont = false; @@ -30,7 +32,7 @@ export function previewFontFamily(font: FontName): void { } export async function applyFontFamily(): Promise { - let font = Config.fontFamily.replace(/_/g, " "); + let font = replaceUnderscoresWithSpaces(Config.fontFamily); const localFont = await fileStorage.getFile("LocalFontFamilyFile"); if (localFont === undefined) { @@ -49,10 +51,19 @@ export async function applyFontFamily(): Promise { }`); } - document.documentElement.style.setProperty( - "--font", - `"${font}", "Roboto Mono", "Vazirharf", monospace`, - ); + const preferredFont = (await getLanguage(Config.language))?.preferredFont; + + const fonts = [ + font, + preferredFont !== undefined + ? `"${replaceUnderscoresWithSpaces(preferredFont)}"` + : undefined, + '"Roboto Mono"', + '"Vazirharf"', + "monospace", + ].filter((it) => it !== undefined); + + document.documentElement.style.setProperty("--font", fonts.join(",")); } export function clearFontPreview(): void { @@ -136,7 +147,7 @@ createEffect(() => { }); configEvent.subscribe(async ({ key }) => { - if (key === "fontFamily") { + if (key === "fontFamily" || key === "language") { await applyFontFamily(); } }); diff --git a/frontend/static/languages/lao.json b/frontend/static/languages/lao.json index e16bf468a60b..87c3f1fc196f 100644 --- a/frontend/static/languages/lao.json +++ b/frontend/static/languages/lao.json @@ -4,6 +4,7 @@ "joiningScript": false, "orderedByFrequency": false, "bcp47": "lo", + "preferredFont": "Noto_Sans_Lao", "words": [ "ຂ້ອຍ", "ເຈົ້າ", diff --git a/frontend/static/languages/sindhi.json b/frontend/static/languages/sindhi.json index 9f34d8fdbdee..79b6d508027a 100644 --- a/frontend/static/languages/sindhi.json +++ b/frontend/static/languages/sindhi.json @@ -4,6 +4,7 @@ "joiningScript": true, "orderedByFrequency": false, "bcp47": "sd", + "preferredFont": "Noto_Naskh_Arabic", "words": [ "جي", "۾", diff --git a/packages/schemas/src/fonts.ts b/packages/schemas/src/fonts.ts index ed7f13276c44..472ac8306231 100644 --- a/packages/schemas/src/fonts.ts +++ b/packages/schemas/src/fonts.ts @@ -1,7 +1,7 @@ import { z } from "zod"; import { customEnumErrorHandler } from "./util"; -const KnownFontNameSchema = z.enum( +export const KnownFontNameSchema = z.enum( [ "Roboto_Mono", "Noto_Naskh_Arabic", diff --git a/packages/schemas/src/languages.ts b/packages/schemas/src/languages.ts index 6bdef92a348f..c971ec14c103 100644 --- a/packages/schemas/src/languages.ts +++ b/packages/schemas/src/languages.ts @@ -1,4 +1,5 @@ import { z } from "zod"; +import { KnownFontNameSchema } from "./fonts"; import { customEnumErrorHandler } from "./util"; export const LanguageSchema = z.enum( @@ -469,6 +470,7 @@ export const LanguageObjectSchema = z .array(z.tuple([z.string().min(1), z.string().min(1)])) .optional(), bcp47: z.string().optional(), + preferredFont: KnownFontNameSchema.optional(), originalPunctuation: z.boolean().optional(), }) .strict();