diff --git a/backend/__tests__/middlewares/auth.spec.ts b/backend/__tests__/middlewares/auth.spec.ts
index fc679171af55..37d638ae7677 100644
--- a/backend/__tests__/middlewares/auth.spec.ts
+++ b/backend/__tests__/middlewares/auth.spec.ts
@@ -249,7 +249,7 @@ describe("middlewares/auth", () => {
await expect(() =>
authenticate({ headers: { authorization: "Uid 123" } }),
).rejects.toMatchMonkeyError(
- new MonkeyError(401, "Baerer type uid is not supported"),
+ new MonkeyError(401, "Bearer type uid is not supported"),
);
});
it("should fail without authentication", async () => {
diff --git a/backend/src/middlewares/auth.ts b/backend/src/middlewares/auth.ts
index b7ba840a59a0..d90003c43748 100644
--- a/backend/src/middlewares/auth.ts
+++ b/backend/src/middlewares/auth.ts
@@ -302,7 +302,7 @@ async function authenticateWithApeKey(
async function authenticateWithUid(token: string): Promise {
if (!isDevEnvironment()) {
- throw new MonkeyError(401, "Baerer type uid is not supported");
+ throw new MonkeyError(401, "Bearer type uid is not supported");
}
const [uid, email] = token.split("|");
diff --git a/frontend/.oxlintrc-plugin.json b/frontend/.oxlintrc-plugin.json
index e9b51939e06a..b98ecdbae835 100644
--- a/frontend/.oxlintrc-plugin.json
+++ b/frontend/.oxlintrc-plugin.json
@@ -4,5 +4,37 @@
"jsPlugins": ["eslint-plugin-compat"],
"rules": {
"compat/compat": "error"
- }
+ },
+ "overrides": [
+ {
+ "jsPlugins": ["eslint-plugin-solid"],
+ "files": ["src/**/*.tsx"],
+ "rules": {
+ "solid/components-return-once": "error",
+ "solid/event-handlers": "error",
+ "solid/imports": "error",
+ "solid/jsx-no-duplicate-props": "error",
+ "solid/jsx-no-script-url": "error",
+ "solid/jsx-no-undef": "error",
+ "solid/no-array-handlers": "error",
+ "solid/no-destructure": "error",
+ "solid/no-innerhtml": "error",
+ "solid/no-proxy-apis": "error",
+ "solid/no-react-deps": "error",
+ "solid/no-react-specific-props": "error",
+ "solid/no-unknown-namespaces": "error",
+ "solid/prefer-classlist": "error",
+ "solid/prefer-for": "error",
+ "solid/prefer-show": "error",
+ "solid/reactivity": "error",
+ "solid/self-closing-comp": [
+ "error",
+ {
+ "html": "void"
+ }
+ ],
+ "solid/style-prop": "error"
+ }
+ }
+ ]
}
diff --git a/frontend/__tests__/setup-tests.ts b/frontend/__tests__/__harness__/mock-dom.ts
similarity index 84%
rename from frontend/__tests__/setup-tests.ts
rename to frontend/__tests__/__harness__/mock-dom.ts
index 0456f9681161..e730ea4ed1ff 100644
--- a/frontend/__tests__/setup-tests.ts
+++ b/frontend/__tests__/__harness__/mock-dom.ts
@@ -1,26 +1,8 @@
import { vi } from "vitest";
-import $ from "jquery";
-import { ElementsWithUtils, ElementWithUtils } from "../src/ts/utils/dom";
+import { ElementsWithUtils, ElementWithUtils } from "../../src/ts/utils/dom";
-//@ts-expect-error add to global
-global["$"] = $;
-//@ts-expect-error add to global
-global["jQuery"] = $;
-
-vi.mock("../src/ts/constants/env-config", () => ({
- envConfig: {
- backendUrl: "invalid",
- isDevelopment: true,
- },
-}));
-
-vi.mock("../src/ts/firebase", () => ({
- app: undefined,
- Auth: undefined,
- isAuthenticated: () => false,
-}));
-
-vi.mock("../src/ts/utils/dom", async (importOriginal) => {
+// Mock dom-utils to always return a mock element
+vi.mock("../../src/ts/utils/dom", async (importOriginal) => {
const createMockElement = (): ElementWithUtils => {
return {
disable: vi.fn().mockReturnThis(),
diff --git a/frontend/__tests__/__harness__/mock-env-config.ts b/frontend/__tests__/__harness__/mock-env-config.ts
new file mode 100644
index 000000000000..e39f1ae458ba
--- /dev/null
+++ b/frontend/__tests__/__harness__/mock-env-config.ts
@@ -0,0 +1,7 @@
+import { vi } from "vitest";
+vi.mock("../src/ts/constants/env-config", () => ({
+ envConfig: {
+ backendUrl: "invalid",
+ isDevelopment: true,
+ },
+}));
diff --git a/frontend/__tests__/__harness__/mock-firebase.ts b/frontend/__tests__/__harness__/mock-firebase.ts
new file mode 100644
index 000000000000..b445c2b1979a
--- /dev/null
+++ b/frontend/__tests__/__harness__/mock-firebase.ts
@@ -0,0 +1,6 @@
+import { vi } from "vitest";
+vi.mock("../../src/ts/firebase", () => ({
+ app: undefined,
+ Auth: undefined,
+ isAuthenticated: () => false,
+}));
diff --git a/frontend/__tests__/setup-jsdom.ts b/frontend/__tests__/__harness__/setup-jquery.ts
similarity index 100%
rename from frontend/__tests__/setup-jsdom.ts
rename to frontend/__tests__/__harness__/setup-jquery.ts
diff --git a/frontend/__tests__/__harness__/setup-jsx.ts b/frontend/__tests__/__harness__/setup-jsx.ts
new file mode 100644
index 000000000000..2a14aed4ab14
--- /dev/null
+++ b/frontend/__tests__/__harness__/setup-jsx.ts
@@ -0,0 +1,2 @@
+//extend expect with dom matchers
+import "@testing-library/jest-dom";
diff --git a/frontend/__tests__/components/ScrollToTop.spec.tsx b/frontend/__tests__/components/ScrollToTop.spec.tsx
new file mode 100644
index 000000000000..222c12cd79eb
--- /dev/null
+++ b/frontend/__tests__/components/ScrollToTop.spec.tsx
@@ -0,0 +1,102 @@
+import { describe, it, expect, vi, beforeEach } from "vitest";
+import { render } from "@solidjs/testing-library";
+import { userEvent } from "@testing-library/user-event";
+import {
+ ScrollToTop,
+ __testing,
+ hideScrollToTop,
+} from "../../src/ts/components/ScrollToTop";
+import * as ActivePage from "../../src/ts/states/active-page";
+
+describe("ScrollToTop", () => {
+ const getActivePageMock = vi.spyOn(ActivePage, "get");
+ beforeEach(() => {
+ getActivePageMock.mockClear().mockReturnValue("account");
+ Object.defineProperty(window, "scrollY", { value: 0, writable: true });
+ __testing.resetState();
+ });
+
+ function renderElement(): {
+ container: HTMLElement;
+ button: HTMLButtonElement;
+ } {
+ const { container } = render(() => );
+
+ return {
+ // oxlint-disable-next-line no-non-null-assertion
+ container: container.children[0]! as HTMLElement,
+ // oxlint-disable-next-line no-non-null-assertion
+ button: container.querySelector("div.button")!,
+ };
+ }
+
+ it("renders with correct classes and structure", () => {
+ const { container, button } = renderElement();
+
+ expect(container).toHaveClass("content-grid", "ScrollToTop");
+ expect(button).toHaveClass("breakout", "button");
+ expect(button).toContainHTML(``);
+ });
+
+ it("renders invisible when scrollY is 0", () => {
+ const { button } = renderElement();
+
+ expect(button).toHaveClass("invisible");
+ });
+
+ it("becomes visible when scrollY > 100", () => {
+ const { button } = renderElement();
+ scrollTo(150);
+
+ expect(button).not.toHaveClass("invisible");
+ });
+
+ it("stays invisible on test page regardless of scroll", () => {
+ getActivePageMock.mockReturnValue("test");
+ const { button } = renderElement();
+ scrollTo(150);
+
+ expect(button).toHaveClass("invisible");
+ });
+
+ it("scrolls to top and hides button on click", async () => {
+ const scrollToSpy = vi.fn();
+ window.scrollTo = scrollToSpy;
+ const { button } = renderElement();
+ scrollTo(150);
+
+ await userEvent.click(button);
+
+ expect(scrollToSpy).toHaveBeenCalledWith({
+ top: 0,
+ behavior: "smooth",
+ });
+ expect(button).toHaveClass("invisible");
+ });
+
+ it("hides button when hideScrollToTop is called", () => {
+ const { button } = renderElement();
+ scrollTo(150);
+
+ hideScrollToTop();
+
+ expect(button).toHaveClass("invisible");
+ });
+
+ it("cleans up scroll listener on unmount", () => {
+ const removeEventListenerSpy = vi.spyOn(window, "removeEventListener");
+ const { unmount } = render(() => );
+
+ unmount();
+
+ expect(removeEventListenerSpy).toHaveBeenCalledWith(
+ "scroll",
+ expect.any(Function),
+ );
+ });
+
+ function scrollTo(value: number): void {
+ Object.defineProperty(window, "scrollY", { value, writable: true });
+ window.dispatchEvent(new Event("scroll"));
+ }
+});
diff --git a/frontend/__tests__/tsconfig.json b/frontend/__tests__/tsconfig.json
index 97e01a3900fa..abc9b7a299ae 100644
--- a/frontend/__tests__/tsconfig.json
+++ b/frontend/__tests__/tsconfig.json
@@ -3,8 +3,15 @@
"compilerOptions": {
"moduleResolution": "Bundler",
"module": "ESNext",
- "noEmit": true
+ "noEmit": true,
+ "jsx": "preserve",
+ "jsxImportSource": "solid-js"
},
"files": ["vitest.d.ts"],
- "include": ["./**/*.spec.ts", "./**/*.jsdom-spec.ts", "./setup-tests.ts"]
+ "include": [
+ "./**/*.spec.ts",
+ "./**/*.spec.tsx",
+ "./**/*.jsdom-spec.ts",
+ "./setup-tests.ts"
+ ]
}
diff --git a/frontend/__tests__/utils/dom.jsdom-spec.ts b/frontend/__tests__/utils/dom.jsdom-spec.ts
index 8d38ebf56f40..25c5f424c4ed 100644
--- a/frontend/__tests__/utils/dom.jsdom-spec.ts
+++ b/frontend/__tests__/utils/dom.jsdom-spec.ts
@@ -27,7 +27,7 @@ describe("dom", () => {
}
beforeEach(() => {
- handler.mockReset();
+ handler.mockClear();
document.body.innerHTML = "";
const root = document.createElement("div");
@@ -151,7 +151,7 @@ describe("dom", () => {
);
//WHEN click on mid1 handler is only called one time
- handler.mockReset();
+ handler.mockClear();
clickTarget = screen.getByTestId("mid1");
await userEvent.click(clickTarget);
diff --git a/frontend/__tests__/vitest.d.ts b/frontend/__tests__/vitest.d.ts
index d08189355996..2bff202469b9 100644
--- a/frontend/__tests__/vitest.d.ts
+++ b/frontend/__tests__/vitest.d.ts
@@ -8,6 +8,9 @@ interface ActivityDayMatchers {
toBeFiller: () => ActivityDayMatchers;
}
+///
+import "@testing-library/jest-dom";
+
declare module "vitest" {
interface Assertion extends ActivityDayMatchers {}
interface AsymmetricMatchersContaining extends ActivityDayMatchers {}
diff --git a/frontend/package.json b/frontend/package.json
index 09d7b37315ab..f18b05ab49cb 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -61,7 +61,9 @@
"@fortawesome/fontawesome-free": "5.15.4",
"@monkeytype/oxlint-config": "workspace:*",
"@monkeytype/typescript-config": "workspace:*",
+ "@solidjs/testing-library": "0.8.10",
"@testing-library/dom": "10.4.1",
+ "@testing-library/jest-dom": "6.9.1",
"@testing-library/user-event": "14.6.1",
"@types/canvas-confetti": "1.4.3",
"@types/chartjs-plugin-trendline": "1.0.1",
@@ -77,9 +79,11 @@
"concurrently": "8.2.2",
"eslint": "9.39.1",
"eslint-plugin-compat": "6.0.2",
+ "eslint-plugin-solid": "0.14.5",
"firebase-tools": "13.15.1",
"fontawesome-subset": "4.4.0",
"happy-dom": "20.0.10",
+ "jsdom": "27.4.0",
"madge": "8.0.0",
"magic-string": "0.30.17",
"normalize.css": "8.0.1",
@@ -87,6 +91,7 @@
"oxlint-tsgolint": "0.10.1",
"postcss": "8.4.31",
"sass": "1.70.0",
+ "solid-js": "1.9.10",
"subset-font": "2.3.0",
"tsx": "4.16.2",
"typescript": "5.9.3",
@@ -98,13 +103,14 @@
"vite-plugin-inspect": "11.3.3",
"vite-plugin-minify": "2.1.0",
"vite-plugin-pwa": "1.1.0",
+ "vite-plugin-solid": "2.11.10",
"vitest": "4.0.15"
},
"lint-staged": {
"*": [
"oxfmt --no-error-on-unmatched-pattern"
],
- "*.{ts,js}": [
+ "*.{ts,js,tsx}": [
"oxlint --type-aware --type-check"
]
},
diff --git a/frontend/src/index.html b/frontend/src/index.html
index c514c2b85840..1c74abf77189 100644
--- a/frontend/src/index.html
+++ b/frontend/src/index.html
@@ -21,11 +21,6 @@
-
diff --git a/frontend/src/privacy-policy.html b/frontend/src/privacy-policy.html
index f99d6e951003..50b87e97a28a 100644
--- a/frontend/src/privacy-policy.html
+++ b/frontend/src/privacy-policy.html
@@ -388,7 +388,7 @@ What are cookies?
>
HTTP cookie
- on Wikipedia.
+ on Wikipedia.
How do we use cookies?
diff --git a/frontend/src/styles/core.scss b/frontend/src/styles/core.scss
index 4a34b627101c..73d81b9fd604 100644
--- a/frontend/src/styles/core.scss
+++ b/frontend/src/styles/core.scss
@@ -256,37 +256,6 @@ key {
visibility: hidden !important;
}
-.scrollToTopContainer {
- position: fixed;
- width: 100%;
- height: 100%;
- pointer-events: none;
- z-index: 99999999;
-
- .scrollToTopButton {
- pointer-events: all;
- place-self: end end;
- margin-bottom: 2rem;
- font-size: 2rem;
- width: 4rem;
- height: 4rem;
- text-align: center;
-
- line-height: 4rem;
- background: var(--sub-alt-color);
- border-radius: 99rem;
- outline: 0.5rem solid var(--bg-color);
-
- cursor: pointer;
- color: var(--sub-color);
- transition: 0.25s;
- &:hover {
- background: var(--text-color);
- color: var(--bg-color);
- }
- }
-}
-
.inputAndIndicator {
input {
width: 100%;
diff --git a/frontend/src/ts/components/ScrollToTop.scss b/frontend/src/ts/components/ScrollToTop.scss
new file mode 100644
index 000000000000..16ecc8e2a448
--- /dev/null
+++ b/frontend/src/ts/components/ScrollToTop.scss
@@ -0,0 +1,36 @@
+.ScrollToTop {
+ position: fixed;
+ width: 100%;
+ height: 100%;
+ pointer-events: none;
+ z-index: 99999999;
+ top: 0;
+ left: 0;
+
+ .button {
+ pointer-events: all;
+ place-self: end end;
+ margin-bottom: 2rem;
+ font-size: 2rem;
+ width: 4rem;
+ height: 4rem;
+ text-align: center;
+
+ line-height: 4rem;
+ background: var(--sub-alt-color);
+ border-radius: 99rem;
+ outline: 0.5rem solid var(--bg-color);
+
+ .fas {
+ line-height: 1;
+ }
+
+ cursor: pointer;
+ color: var(--sub-color);
+ transition: 0.25s;
+ &:hover {
+ background: var(--text-color);
+ color: var(--bg-color);
+ }
+ }
+}
diff --git a/frontend/src/ts/components/ScrollToTop.tsx b/frontend/src/ts/components/ScrollToTop.tsx
new file mode 100644
index 000000000000..412d5f65e15b
--- /dev/null
+++ b/frontend/src/ts/components/ScrollToTop.tsx
@@ -0,0 +1,54 @@
+import { JSXElement, createSignal, onMount, onCleanup } from "solid-js";
+import * as ActivePage from "../states/active-page";
+import "./ScrollToTop.scss";
+
+const [visible, setVisible] = createSignal(false);
+
+export function hideScrollToTop(): void {
+ setVisible(false);
+}
+
+export function ScrollToTop(): JSXElement {
+ const handleScroll = (): void => {
+ const page = ActivePage.get();
+ if (page === "test") return;
+
+ const scroll = window.scrollY;
+ setVisible(scroll > 100);
+ };
+
+ onMount(() => {
+ window.addEventListener("scroll", handleScroll, { passive: true });
+ handleScroll();
+ });
+
+ onCleanup(() => {
+ window.removeEventListener("scroll", handleScroll);
+ });
+
+ return (
+
+
{
+ setVisible(false);
+ window.scrollTo({
+ top: 0,
+ behavior: "smooth",
+ });
+ }}
+ >
+
+
+
+ );
+}
+
+export const __testing = {
+ resetState: (): void => {
+ setVisible(false);
+ },
+};
diff --git a/frontend/src/ts/components/mount.tsx b/frontend/src/ts/components/mount.tsx
new file mode 100644
index 000000000000..c1b707e8f567
--- /dev/null
+++ b/frontend/src/ts/components/mount.tsx
@@ -0,0 +1,7 @@
+import { render } from "solid-js/web";
+import { qsr } from "../utils/dom";
+import { ScrollToTop } from "./ScrollToTop";
+
+export function mountComponents(): void {
+ render(() => , qsr("body").native);
+}
diff --git a/frontend/src/ts/db.ts b/frontend/src/ts/db.ts
index 0089fc07458e..99980595f261 100644
--- a/frontend/src/ts/db.ts
+++ b/frontend/src/ts/db.ts
@@ -875,6 +875,64 @@ export async function saveLocalTagPB(
return;
}
+export async function updateLocalTagPB(
+ tagId: string,
+ mode: M,
+ mode2: Mode2,
+ punctuation: boolean,
+ numbers: boolean,
+ language: Language,
+ difficulty: Difficulty,
+ lazyMode: boolean,
+): Promise {
+ if (dbSnapshot === null) return;
+
+ const filteredtag = (getSnapshot()?.tags ?? []).find((t) => t._id === tagId);
+
+ if (filteredtag === undefined) return;
+
+ const pb = {
+ wpm: 0,
+ acc: 0,
+ rawWpm: 0,
+ consistency: 0,
+ };
+
+ getSnapshot()?.results?.forEach((result) => {
+ if (result.tags.includes(tagId) && result.wpm > pb.wpm) {
+ if (
+ result.mode === mode &&
+ result.mode2 === mode2 &&
+ result.punctuation === punctuation &&
+ result.numbers === numbers &&
+ result.language === language &&
+ result.difficulty === difficulty &&
+ result.lazyMode === lazyMode
+ ) {
+ pb.wpm = result.wpm;
+ pb.acc = result.acc;
+ pb.rawWpm = result.rawWpm;
+ pb.consistency = result.consistency;
+ }
+ }
+ });
+
+ await saveLocalTagPB(
+ tagId,
+ mode,
+ mode2,
+ punctuation,
+ numbers,
+ language,
+ difficulty,
+ lazyMode,
+ pb.wpm,
+ pb.acc,
+ pb.rawWpm,
+ pb.consistency,
+ );
+}
+
export async function updateLbMemory(
mode: M,
mode2: Mode2,
diff --git a/frontend/src/ts/elements/scroll-to-top.ts b/frontend/src/ts/elements/scroll-to-top.ts
deleted file mode 100644
index 2ebd2d48ea82..000000000000
--- a/frontend/src/ts/elements/scroll-to-top.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import * as ActivePage from "../states/active-page";
-import { prefersReducedMotion } from "../utils/misc";
-import { qsr } from "../utils/dom";
-
-let visible = false;
-
-const button = qsr(".scrollToTopButton");
-
-export function hide(): void {
- button.addClass("invisible");
- visible = false;
-}
-
-function show(): void {
- button.removeClass("invisible");
- visible = true;
-}
-
-button.on("click", () => {
- button.addClass("invisible");
- window.scrollTo({
- top: 0,
- behavior: prefersReducedMotion() ? "instant" : "smooth",
- });
-});
-
-window.addEventListener("scroll", () => {
- const page = ActivePage.get();
- if (page === "test") return;
-
- const scroll = window.scrollY;
- if (!visible && scroll > 100) {
- show();
- } else if (visible && scroll < 100) {
- hide();
- }
-});
diff --git a/frontend/src/ts/index.ts b/frontend/src/ts/index.ts
index f74f3104e236..e4c7eb954f7e 100644
--- a/frontend/src/ts/index.ts
+++ b/frontend/src/ts/index.ts
@@ -30,7 +30,6 @@ import "./input/listeners";
import "./ready";
import "./controllers/route-controller";
import "./pages/about";
-import "./elements/scroll-to-top";
import * as Account from "./pages/account";
import "./elements/no-css";
import { egVideoListener } from "./popups/video-ad-popup";
@@ -48,6 +47,7 @@ import "./utils/url-handler";
import "./modals/last-signed-out-result";
import { applyEngineSettings } from "./anim";
import { qs, qsa, qsr } from "./utils/dom";
+import { mountComponents } from "./components/mount";
// Lock Math.random
Object.defineProperty(Math, "random", {
@@ -107,3 +107,5 @@ if (isDevEnvironment()) {
module.appendButton();
});
}
+
+mountComponents();
diff --git a/frontend/src/ts/modals/edit-result-tags.ts b/frontend/src/ts/modals/edit-result-tags.ts
index c7d7a94236be..3698c141fb53 100644
--- a/frontend/src/ts/modals/edit-result-tags.ts
+++ b/frontend/src/ts/modals/edit-result-tags.ts
@@ -134,7 +134,23 @@ async function save(): Promise {
DB.getSnapshot()?.results?.forEach((result) => {
if (result._id === state.resultId) {
+ const tagsToUpdate = [
+ ...result.tags.filter((tag) => !state.tags.includes(tag)),
+ ...state.tags.filter((tag) => !result.tags.includes(tag)),
+ ];
result.tags = state.tags;
+ tagsToUpdate.forEach((tag) => {
+ void DB.updateLocalTagPB(
+ tag,
+ result.mode,
+ result.mode2,
+ result.punctuation,
+ result.numbers,
+ result.language,
+ result.difficulty,
+ result.lazyMode,
+ );
+ });
}
});
diff --git a/frontend/src/ts/modals/edit-tag.ts b/frontend/src/ts/modals/edit-tag.ts
index 5582aa14d59d..a56f4e0836c0 100644
--- a/frontend/src/ts/modals/edit-tag.ts
+++ b/frontend/src/ts/modals/edit-tag.ts
@@ -5,6 +5,11 @@ import * as Settings from "../pages/settings";
import AnimatedModal, { ShowOptions } from "../utils/animated-modal";
import { SimpleModal, TextInput } from "../utils/simple-modal";
import { TagNameSchema } from "@monkeytype/schemas/users";
+import { SnapshotUserTag } from "../constants/default-snapshot";
+
+function getTagFromSnapshot(tagId: string): SnapshotUserTag | undefined {
+ return DB.getSnapshot()?.tags.find((tag) => tag._id === tagId);
+}
const cleanTagName = (tagName: string): string => tagName.replaceAll(" ", "_");
const tagNameValidation = async (tagName: string): Promise => {
@@ -89,12 +94,13 @@ const actionModals: Record = {
};
}
- DB.getSnapshot()?.tags?.forEach((tag) => {
- if (tag._id === tagId) {
- tag.name = tagName;
- tag.display = propTagName;
- }
- });
+ const matchingTag = getTagFromSnapshot(tagId);
+
+ if (matchingTag !== undefined) {
+ matchingTag.name = tagName;
+ matchingTag.display = propTagName;
+ }
+
void Settings.update();
return { status: 1, message: `Tag updated` };
@@ -120,11 +126,11 @@ const actionModals: Record = {
};
}
- DB.getSnapshot()?.tags?.forEach((tag, index: number) => {
- if (tag._id === tagId) {
- DB.getSnapshot()?.tags?.splice(index, 1);
- }
- });
+ const snapshot = DB.getSnapshot();
+ if (snapshot?.tags) {
+ snapshot.tags = snapshot.tags.filter((it) => it._id !== tagId);
+ }
+
void Settings.update();
return { status: 1, message: `Tag removed` };
},
@@ -151,6 +157,18 @@ const actionModals: Record = {
};
}
+ const matchingTag = getTagFromSnapshot(tagId);
+
+ if (matchingTag !== undefined) {
+ matchingTag.personalBests = {
+ time: {},
+ words: {},
+ quote: {},
+ zen: {},
+ custom: {},
+ };
+ }
+
void Settings.update();
return { status: 1, message: `Tag PB cleared` };
},
diff --git a/frontend/src/ts/pages/test.ts b/frontend/src/ts/pages/test.ts
index 0791fdd53758..eefd32e9b99c 100644
--- a/frontend/src/ts/pages/test.ts
+++ b/frontend/src/ts/pages/test.ts
@@ -7,9 +7,9 @@ import { updateFooterAndVerticalAds } from "../controllers/ad-controller";
import * as ModesNotice from "../elements/modes-notice";
import * as Keymap from "../elements/keymap";
import * as TestConfig from "../test/test-config";
-import * as ScrollToTop from "../elements/scroll-to-top";
import { blurInputElement } from "../input/input-element";
import { qsr } from "../utils/dom";
+import { hideScrollToTop } from "../components/ScrollToTop";
export const page = new Page({
id: "test",
@@ -36,6 +36,6 @@ export const page = new Page({
});
void TestConfig.instantUpdate();
void Keymap.refresh();
- ScrollToTop.hide();
+ hideScrollToTop();
},
});
diff --git a/frontend/src/ts/test/words-generator.ts b/frontend/src/ts/test/words-generator.ts
index a8de5f054090..c578bc4dfd08 100644
--- a/frontend/src/ts/test/words-generator.ts
+++ b/frontend/src/ts/test/words-generator.ts
@@ -899,16 +899,20 @@ export async function getNextWord(
}
const usingFunboxWithGetWord = isFunboxActiveWithFunction("getWord");
+ const randomWordLanguage =
+ (currentWordset instanceof PolyglotWordset
+ ? currentWordset.wordsWithLanguage.get(randomWord)
+ : Config.language) ?? Config.language; // Fall back to Config language if per-word language is unavailable
if (
Config.mode !== "custom" &&
Config.mode !== "quote" &&
/[A-Z]/.test(randomWord) &&
!Config.punctuation &&
- !Config.language.startsWith("german") &&
- !Config.language.startsWith("swiss_german") &&
- !Config.language.startsWith("code") &&
- !Config.language.startsWith("klingon") &&
+ !randomWordLanguage.startsWith("german") &&
+ !randomWordLanguage.startsWith("swiss_german") &&
+ !randomWordLanguage.startsWith("code") &&
+ !randomWordLanguage.startsWith("klingon") &&
!isCurrentlyUsingFunboxSection &&
!usingFunboxWithGetWord
) {
diff --git a/frontend/static/languages/swiss_german.json b/frontend/static/languages/swiss_german.json
index e7edfec41f3f..d54bdd4e2ff7 100644
--- a/frontend/static/languages/swiss_german.json
+++ b/frontend/static/languages/swiss_german.json
@@ -14,7 +14,7 @@
"sein",
"haben",
"dies",
- "heiss",
+ "heisst",
"Wort",
"aber",
"was",
@@ -71,7 +71,7 @@
"Punkt",
"Mutter",
"Welt",
- "in der Nähe von",
+ "nahe",
"bauen",
"selbst",
"Erde",
@@ -117,7 +117,7 @@
"gleich",
"alle",
"da",
- "nach oben",
+ "oben",
"Verwendung",
"Weg",
"viele",
@@ -142,7 +142,7 @@
"Anzahl",
"klingen",
"nicht",
- "am meisten",
+ "meist",
"Menschen",
"meine",
"wissen",
@@ -150,7 +150,7 @@
"als",
"Anruf",
"erste",
- "nach unten",
+ "unten",
"Seite",
"gewesen",
"jetzt",
@@ -178,6 +178,33 @@
"wenn",
"so",
"über",
- "können"
+ "können",
+ "Velo",
+ "Spital",
+ "parkieren",
+ "Grillieren",
+ "Matur",
+ "Billett",
+ "Estrich",
+ "Glace",
+ "Znüni",
+ "Zvieri",
+ "Rüebli",
+ "Trottinett",
+ "Poulet",
+ "Züri",
+ "Garten",
+ "Sonne",
+ "Blume",
+ "Tisch",
+ "Stuhl",
+ "Fenster",
+ "Essen",
+ "Trinken",
+ "Singen",
+ "Laufen",
+ "Springen",
+ "Sprechen",
+ "Hören"
]
}
diff --git a/frontend/static/languages/swiss_german_1k.json b/frontend/static/languages/swiss_german_1k.json
index e3033ac2ea6c..a296a0f77280 100644
--- a/frontend/static/languages/swiss_german_1k.json
+++ b/frontend/static/languages/swiss_german_1k.json
@@ -13,7 +13,7 @@
"mit",
"sein",
"haben",
- "dies",
+ "heisst",
"Wort",
"aber",
"was",
@@ -45,7 +45,7 @@
"Hafen",
"buchstabieren",
"hinzufügen",
- "Lande",
+ "Land",
"hier",
"muss",
"folgen",
@@ -129,7 +129,7 @@
"Anzahl",
"klingen",
"nicht",
- "höchstens",
+ "meist",
"Menschen",
"meine",
"wissen",
@@ -145,7 +145,7 @@
"stehen",
"besitzen",
"sollte",
- "Land",
+ "Boden",
"gefunden",
"Antwort",
"Schule",
@@ -882,7 +882,7 @@
"gleich",
"beobachten",
"Stein",
- "Boden",
+ "Quartier",
"Kind",
"hoch",
"treffen",
@@ -910,6 +910,98 @@
"Ebene",
"sammeln",
"wählen",
- "breit"
+ "breit",
+ "Velo",
+ "Spital",
+ "parkieren",
+ "Billett",
+ "Estrich",
+ "Glace",
+ "dies",
+ "unten",
+ "Zürich",
+ "Bern",
+ "Basel",
+ "Luzern",
+ "Winterthur",
+ "Genf",
+ "Lausanne",
+ "Chur",
+ "Fribourg",
+ "Schaffhausen",
+ "Biel",
+ "Thun",
+ "Konigs",
+ "grüssen",
+ "Schiessen",
+ "Mass",
+ "Stoss",
+ "beissen",
+ "reissen",
+ "Billette",
+ "Schloss",
+ "Gruss",
+ "Fussball",
+ "Pass",
+ "draussen",
+ "liess",
+ "Süss",
+ "Bloss",
+ "Fass",
+ "Hass",
+ "Kuss",
+ "Massnahme",
+ "Russ",
+ "Schiess",
+ "biss",
+ "floss",
+ "frass",
+ "goss",
+ "hiess",
+ "mass",
+ "riss",
+ "sass",
+ "schoss",
+ "stiess",
+ "vergessen",
+ "geniessen",
+ "schliessen",
+ "Schiesser",
+ "grosser",
+ "weisser",
+ "heisser",
+ "süsser",
+ "blasser",
+ "nasser",
+ "Tasse",
+ "Kasse",
+ "Gasse",
+ "Fassade",
+ "Passage",
+ "Passagier",
+ "Massage",
+ "Kassierer",
+ "Assistent",
+ "Dossier",
+ "Kommission",
+ "Emission",
+ "Mission",
+ "Passiv",
+ "Aggression",
+ "Depression",
+ "Expression",
+ "Impression",
+ "Obsession",
+ "Possession",
+ "Profession",
+ "Progression",
+ "Regression",
+ "Session",
+ "Succession",
+ "Zession",
+ "Accessoire",
+ "Assembler",
+ "Assessment",
+ "Asset"
]
}
diff --git a/frontend/static/languages/swiss_german_2k.json b/frontend/static/languages/swiss_german_2k.json
index e6e0e2fa51a7..16a4dce3fa3a 100644
--- a/frontend/static/languages/swiss_german_2k.json
+++ b/frontend/static/languages/swiss_german_2k.json
@@ -1,114 +1,417 @@
{
"name": "swiss_german_2k",
"_comment": "Sourced from: https://1000mostcommonwords.com/1000-most-common-swiss-german-words/. and and random words from: https://de.wiktionary.org",
-
"bcp47": "de-CH",
"words": [
- "niederschiesset",
- "spitzenmässigere",
- "einmeisselnder",
- "geblösstes",
- "Strassenfahrzeug",
- "stiesse",
- "heisstest",
- "mässen",
- "einreissende",
- "Strassenbauarbeiten",
- "geheisster",
- "Fussgängerdiploms",
- "abstossendes",
- "schweinemässigen",
- "Hinreissens",
- "Ausschliesslichkeiten",
- "Flächenmass",
- "Stossfluges",
- "Grossröhrsdorfs",
- "ausserfahrplanmässigem",
- "bemasste",
- "herumreisst",
- "schliessbares",
- "Vogelstrausse",
- "perlweissen",
- "entzweibeissende",
- "beschliessend",
- "Strassenverkehrsamt",
- "abstiessest",
- "Bosseln",
- "Strassenbahnhaltestelle",
- "Weichenstrassen",
- "weisshaarige",
- "vorreissest",
- "verschiessendem",
- "beschmeissendes",
- "sinngemässeste",
- "Trauerkloss",
- "Maiensässes",
- "Holzmasse",
- "mässige",
- "durchstossendes",
- "Klumpfüsse",
- "nachgiessend",
- "herbeiliessest",
- "geniesserischer",
- "verdriesslichstem",
- "einzuschiessende",
- "spiessbürgerliche",
- "zurückschiesset",
- "Grossnilhechtes",
- "Fusspfades",
- "Übergrössen",
- "hineingiesst",
- "Spasscharmanten",
- "regelmässigem",
- "niederstiess",
- "strassenbahnähnlichem",
- "dreissigprozentigen",
- "strassenbahnähnliche",
- "aussenseiterischer",
- "durchässen",
- "gemassregelte",
- "respekteinflössendsten",
- "gneisstet",
- "weissgedecktes",
- "zerstossenes",
- "herzzerreissendem",
- "Geiselerschiessung",
- "blossgestelltem",
- "Füsslings",
- "ausserkirchliches",
- "Weissbüchern",
- "ungemässen",
- "weggestossen",
- "Klössen",
- "aufstiesse",
- "losschiessendes",
- "hinuntergiessen",
- "Schweissdrähte",
- "Häss",
- "Gegenstosses",
- "ermässigendes",
- "prussischer",
- "heisseren",
- "bestiesset",
- "durchgestossen",
- "ausweisse",
- "mutmassend",
- "zuzuschweissen",
- "schwerpunktmässigem",
- "Prussin",
- "Aussenluft",
- "entsüsstes",
- "Grosssohn",
- "Zensurmassnahme",
- "Strausseneis",
- "Entblössens",
- "Weissburgundern",
- "Grusses",
- "nachliessest",
- "bespasstem",
- "schweisste",
- "herzzerreissendere",
- "Strassenbahnschienen",
+ "ich",
+ "seine",
+ "dass",
+ "er",
+ "war",
+ "für",
+ "auf",
+ "sind",
+ "mit",
+ "sein",
+ "haben",
+ "dies",
+ "heisst",
+ "Wort",
+ "aber",
+ "was",
+ "einige",
+ "ist",
+ "es",
+ "Sie",
+ "oder",
+ "hatte",
+ "von",
+ "und",
+ "wir",
+ "andere",
+ "waren",
+ "tun",
+ "ihre",
+ "Zeit",
+ "werden",
+ "sagte",
+ "tut",
+ "drei",
+ "wollen",
+ "Luft",
+ "spielen",
+ "klein",
+ "Ende",
+ "setzen",
+ "Zuhause",
+ "lesen",
+ "Hand",
+ "Hafen",
+ "buchstabieren",
+ "hinzufügen",
+ "Land",
+ "hier",
+ "muss",
+ "hoch",
+ "folgen",
+ "Akt",
+ "warum",
+ "fragen",
+ "Männer",
+ "Veränderung",
+ "ging",
+ "Licht",
+ "Art",
+ "müssen",
+ "Haus",
+ "Bild",
+ "versuchen",
+ "uns",
+ "wieder",
+ "Tier",
+ "Punkt",
+ "Mutter",
+ "Welt",
+ "nahe",
+ "bauen",
+ "selbst",
+ "Erde",
+ "Vater",
+ "neu",
+ "Arbeit",
+ "Teil",
+ "nehmen",
+ "erhalten",
+ "Ort",
+ "gemacht",
+ "leben",
+ "wo",
+ "nach",
+ "zurück",
+ "wenig",
+ "Runde",
+ "Mann",
+ "Jahr",
+ "kam",
+ "zeigen",
+ "mir",
+ "geben",
+ "unsere",
+ "unter",
+ "Name",
+ "sehr",
+ "Formular",
+ "denken",
+ "Hilfe",
+ "niedrig",
+ "Linie",
+ "abweichen",
+ "wiederum",
+ "Ursache",
+ "viel",
+ "bedeuten",
+ "vor",
+ "Umzug",
+ "Recht",
+ "Junge",
+ "alt",
+ "gleich",
+ "alle",
+ "da",
+ "oben",
+ "Verwendung",
+ "Weg",
+ "viele",
+ "dann",
+ "schreiben",
+ "würde",
+ "diese",
+ "lange",
+ "machen",
+ "Sache",
+ "sehen",
+ "ihm",
+ "zwei",
+ "hat",
+ "suchen",
+ "mehr",
+ "Tag",
+ "könnte",
+ "gehen",
+ "kommen",
+ "tat",
+ "Anzahl",
+ "klingen",
+ "nicht",
+ "meist",
+ "Menschen",
+ "meine",
+ "wissen",
+ "Wasser",
+ "als",
+ "Anruf",
+ "erste",
+ "unten",
+ "Seite",
+ "gewesen",
+ "jetzt",
+ "finden",
+ "Kopf",
+ "stehen",
+ "besitzen",
+ "Velo",
+ "Spital",
+ "parkieren",
+ "Billett",
+ "Estrich",
+ "Glace",
+ "Zürich",
+ "Bern",
+ "Basel",
+ "Luzern",
+ "St.Gallen",
+ "Winterthur",
+ "Genf",
+ "Lausanne",
+ "Chur",
+ "Fribourg",
+ "Schaffhausen",
+ "Biel",
+ "Thun",
+ "Konigs",
+ "Strasse",
+ "Fuss",
+ "gross",
+ "weiss",
+ "grüssen",
+ "fliessen",
+ "Schiessen",
+ "Mass",
+ "Stoss",
+ "beissen",
+ "reissen",
+ "geniessen",
+ "messen",
+ "Schloss",
+ "Gruss",
+ "Fussball",
+ "Pass",
+ "draussen",
+ "heiss",
+ "liess",
+ "Süss",
+ "Bloss",
+ "Fass",
+ "Hass",
+ "Kuss",
+ "Massnahme",
+ "Russ",
+ "Schiess",
+ "Spass",
+ "biss",
+ "floss",
+ "frass",
+ "goss",
+ "hiess",
+ "mass",
+ "riss",
+ "sass",
+ "schoss",
+ "stiess",
+ "vergessen",
+ "essen",
+ "lassen",
+ "schliessen",
+ "Schiesser",
+ "grosser",
+ "weisser",
+ "heisser",
+ "süsser",
+ "blasser",
+ "nasser",
+ "besser",
+ "Klasse",
+ "Masse",
+ "Tasse",
+ "Kasse",
+ "Gasse",
+ "Fassade",
+ "Passage",
+ "Passagier",
+ "Massage",
+ "Kassierer",
+ "Assistent",
+ "Dossier",
+ "Kommission",
+ "Emission",
+ "Mission",
+ "Passiv",
+ "Aggression",
+ "Depression",
+ "Expression",
+ "Impression",
+ "Obsession",
+ "Possession",
+ "Profession",
+ "Progression",
+ "Regression",
+ "Session",
+ "Succession",
+ "Zession",
+ "Accessoire",
+ "Assembler",
+ "Assessment",
+ "Asset",
+ "Assimilierung",
+ "Assoziation",
+ "Assortiment",
+ "Attest",
+ "Bass",
+ "Bypass",
+ "Chassis",
+ "Compass",
+ "Dressur",
+ "Engpass",
+ "Essenz",
+ "Exzess",
+ "Fitness",
+ "Grossist",
+ "Imbiss",
+ "Inkasso",
+ "Kompasse",
+ "Kompass",
+ "Kongress",
+ "Kulisse",
+ "Matratze",
+ "Narzisse",
+ "Oase",
+ "Paralyse",
+ "Parkplatz",
+ "Passepartout",
+ "Passe",
+ "Pikass",
+ "Präzision",
+ "Prozess",
+ "Ressource",
+ "Sessel",
+ "Skizze",
+ "Stress",
+ "Terrasse",
+ "Trasse",
+ "Znüni",
+ "Zvieri",
+ "Nüsslisalat",
+ "Rüebli",
+ "Chuchichäschtli",
+ "Bebbi",
+ "Zmorge",
+ "Zmittag",
+ "Znacht",
+ "Guezli",
+ "Anke",
+ "Gabel",
+ "Löffel",
+ "Messer",
+ "Teller",
+ "Pfanne",
+ "Topf",
+ "Küche",
+ "Zimmer",
+ "Bett",
+ "Schrank",
+ "Tisch",
+ "Stuhl",
+ "Sofa",
+ "Lampe",
+ "Fenster",
+ "Tür",
+ "Wohnung",
+ "Stiege",
+ "Lift",
+ "Garten",
+ "Balkon",
+ "Platz",
+ "Park",
+ "Wald",
+ "Berg",
+ "See",
+ "Fluss",
+ "Bach",
+ "Brücke",
+ "Auto",
+ "Bus",
+ "Zug",
+ "Tram",
+ "Schiff",
+ "Flugzeug",
+ "Bahnhof",
+ "Flughafen",
+ "Schule",
+ "Kirche",
+ "Post",
+ "Bank",
+ "Laden",
+ "Markt",
+ "Bäckerei",
+ "Metzgerei",
+ "Restaurant",
+ "Hotel",
+ "Kino",
+ "Theater",
+ "Museum",
+ "Bibliothek",
+ "Parkieren",
+ "Arbeiten",
+ "Lernen",
+ "Lesen",
+ "Schreiben",
+ "Rechnen",
+ "Sprechen",
+ "Hören",
+ "Sehen",
+ "Laufen",
+ "Gehen",
+ "Rennen",
+ "Springen",
+ "Schwimmen",
+ "Fahren",
+ "Reisen",
+ "Essen",
+ "Trinken",
+ "Schlafen",
+ "Wohnen",
+ "Kaufen",
+ "Verkaufen",
+ "Geben",
+ "Nehmen",
+ "Helfen",
+ "Suchen",
+ "Finden",
+ "Machen",
+ "Tun",
+ "Denken",
+ "Wissen",
+ "Glauben",
+ "Hoften",
+ "Lieben",
+ "Hassen",
+ "Lachen",
+ "Weinen",
+ "Freuen",
+ "Ärgern",
+ "Warten",
+ "Kommen",
+ "Bleiben",
+ "Werden",
+ "Sein",
+ "Haben",
+ "Können",
+ "Müssen",
+ "Dürfen",
+ "Sollen",
+ "Wollen",
+ "Mögen",
+ "Heissen",
"niederzureissender",
"bemassten",
"anschmeisst",
@@ -610,7 +913,6 @@
"viertgrösstes",
"Fussbettes",
"weiterveräusser",
- "Massnahme",
"massvolles",
"bosselnder",
"zerstosset",
@@ -1080,7 +1382,6 @@
"Anreissens",
"abfliessendes",
"spiessiges",
- "schliessen",
"flössbarer",
"Grosssträucher",
"Amateurfussballe",
@@ -1112,12 +1413,9 @@
"Absatz",
"Material",
"Schlag",
- "hinzufügen",
"vorstellen",
"Pose",
"schwimmen",
- "zurück",
- "Veränderung",
"kurz",
"ankommen",
"Tod",
@@ -1125,30 +1423,18 @@
"winzig",
"passen",
"weit",
- "zeigen",
- "erhalten",
"bleiben",
"malen",
"gab",
- "gemacht",
- "müssen",
"Hut",
"Buch",
- "mit",
- "einige",
"Silbe",
- "Spass",
- "diese",
- "Zug",
"weniger",
- "am meisten",
- "Land",
"Dreieck",
"erfordern",
"Ozean",
"Sprache",
"braun",
- "neu",
"Wurzel",
"Spalte",
"Geld",
@@ -1157,24 +1443,18 @@
"Spur",
"Saison",
"hell",
- "besser",
"regen",
"trocken",
"oh",
"Zustand",
"Person",
- "schreiben",
"wahr",
- "Markt",
"entfernt",
"erraten",
- "als",
"Materie",
"erhöhen",
- "Masse",
"Chance",
"wünschen",
- "wollen",
"Abdeckung",
"Obst",
"Feige",
@@ -1182,11 +1462,9 @@
"Elementes",
"Baum",
"bekam",
- "viele",
"geöffnet",
"Hals",
"kostenlos",
- "würde",
"laut",
"Knochen",
"Papa",
@@ -1197,11 +1475,9 @@
"Einheit",
"bis",
"Regel",
- "gross",
"Antriebs",
"Kreis",
"Schlüssel",
- "spielen",
"warme",
"wachsen",
"Million",
@@ -1214,13 +1490,9 @@
"ziehen",
"Kind",
"sieben",
- "Berg",
- "Erde",
- "von",
"Zeichen",
"entweder",
"gerade",
- "Stuhl",
"Angebot",
"Praxis",
"legen",
@@ -1236,9 +1508,6 @@
"Gesicht",
"Wiederholung",
"Baumwolle",
- "leben",
- "Wohnung",
- "Wald",
"Fett",
"vorhanden",
"Einzel",
@@ -1260,13 +1529,11 @@
"Basis",
"Herz",
"Pfund",
- "folgen",
"Übung",
"Feuer",
"Arm",
"scharf",
"Substanz",
- "fragen",
"gefunden",
"begünstigen",
"Immobilien",
@@ -1274,18 +1541,14 @@
"bieten",
"fähig",
"Grad",
- "Verwendung",
"vier",
"Freude",
"Fledermaus",
"Raum",
- "Prozess",
"Stern",
"Nation",
- "klein",
"Ohr",
"Brot",
- "hat",
"Gedicht",
"Eile",
"Lüge",
@@ -1299,8 +1562,6 @@
"Konsonant",
"sagen",
"Verbum",
- "Zürich",
- "Kopf",
"zählen",
"doppelt",
"Begriff",
@@ -1308,11 +1569,8 @@
"geschrieben",
"Rad",
"Schwester",
- "werden",
"Stadt",
- "tat",
"abhängen",
- "seine",
"Säge",
"Frau",
"Frühling",
@@ -1324,11 +1582,9 @@
"eher",
"gewinnen",
"sollte",
- "warum",
"scheinen",
"fünf",
"Kontinent",
- "Runde",
"Stick",
"Unterstützung",
"pleite",
@@ -1347,12 +1603,9 @@
"fallen",
"berühmt",
"mischen",
- "drei",
"Eis",
"so",
- "wieder",
"stark",
- "sehr",
"goldenen",
"Interesse",
"Industrie",
@@ -1364,11 +1617,8 @@
"auftreten",
"Hügel",
"neun",
- "haben",
"Augenblick",
- "Welt",
"Maschine",
- "alle",
"Kunst",
"töten",
"Ecke",
@@ -1383,13 +1633,10 @@
"üblich",
"Meile",
"Messe",
- "Strasse",
"Bewegung",
"Versuch",
"schlecht",
- "lassen",
"Soldat",
- "nehmen",
"Küste",
"Partei",
"vertreten",
@@ -1398,30 +1645,21 @@
"glücklich",
"genau",
"Dollar",
- "Teil",
- "lange",
"Tal",
"Erfolg",
"Tabelle",
"betrachten",
- "stehen",
"Chef",
"produzieren",
- "und",
"Anlage",
- "geben",
"fühlen",
- "hatte",
- "Mann",
"erlauben",
"erscheinen",
"Nacht",
"Cent",
"Hof",
- "wo",
"sammeln",
"Stamm",
- "Ort",
"acht",
"vorschlagen",
"antworten",
@@ -1430,19 +1668,14 @@
"stand",
"gelb",
"Pistole",
- "hier",
- "Lachen",
"Mannschaft",
"weich",
"Futtermittel",
"sonst",
- "ihm",
"Lager",
- "lesen",
"Mantel",
"Filz",
"Tanz",
- "unsere",
"Kasten",
"gemeinsam",
"insbesondere",
@@ -1451,13 +1684,9 @@
"küken",
"noch",
"Fahrt",
- "sein",
"Schnitt",
"fortsetzen",
"Segel",
- "gehen",
- "auf",
- "Seite",
"klar",
"vergleichen",
"aufladen",
@@ -1466,24 +1695,18 @@
"Woche",
"Morgen",
"sprechen",
- "Garten",
"eingeben",
"verbringen",
"Seil",
"Bauernhof",
- "erste",
"fein",
"ganz",
"Farbe",
"Pause",
- "Schreiben",
"Mitte",
- "sehen",
"Mädchen",
"Dorf",
- "Fenster",
"Musik",
- "Hilfe",
"umfassen",
"Fraktion",
"Wolke",
@@ -1491,13 +1714,10 @@
"Blut",
"Lande",
"Zweig",
- "weiss",
"Kleid",
"Gras",
"schnell",
"bereit",
- "wiederum",
- "Männer",
"gebracht",
"Glas",
"beschäftigt",
@@ -1506,15 +1726,12 @@
"Zelle",
"Rolle",
"Rand",
- "kommen",
"Magnet",
- "klingen",
"Westen",
"Finish",
"Sohn",
"arrangieren",
"können",
- "nach",
"wahrscheinlich",
"wie",
"Winter",
@@ -1525,44 +1742,25 @@
"Dauer",
"fliegen",
"Kälte",
- "Wort",
- "für",
- "St. Gallen",
"kühlen",
"erreichen",
- "Licht",
- "Name",
"Bereich",
"Holz",
- "was",
"überprüfen",
"breit",
"Mittag",
"Falte",
- "Fluss",
"Mond",
- "gleich",
"vorwärts",
- "Tag",
"Verbreitung",
"zwischen",
- "Formular",
"falsch",
- "See",
- "abweichen",
- "Arbeit",
- "Sache",
- "ihre",
"Zoll",
- "besitzen",
- "da",
"überqueren",
"Sinn",
- "Bett",
"Sitz",
"System",
"reich",
- "dies",
"sparen",
"steigen",
"Stahl",
@@ -1570,14 +1768,11 @@
"Kraft",
"Auge",
"Form",
- "Linie",
- "selbst",
"rot",
"Frage",
"Speicher",
"Monat",
"Speiche",
- "Weg",
"Sand",
"Melodie",
"tief",
@@ -1587,22 +1782,14 @@
"Quotient",
"hundert",
"Muster",
- "Hand",
"gefangen",
- "nicht",
- "messen",
- "uns",
"Kopie",
"Schüler",
"Rohr",
"Natur",
- "es",
- "Sie",
"Haar",
"Rede",
- "Flugzeug",
"ja",
- "Tier",
"verlassen",
"werfen",
"Blick",
@@ -1610,50 +1797,39 @@
"empfangen",
"letzte",
"gesamt",
- "Zeit",
"deren",
"einreiben",
- "Bild",
"Liste",
"schwer",
"Glanz",
"Mensch",
"Geschicklichkeit",
- "Bern",
"Station",
"milch",
"bestimmen",
- "Anruf",
"Marke",
"Vortrag",
"Schuh",
"Plan",
"während",
"Ernte",
- "heiss",
"laufen",
"Koch",
"Idee",
"ausser",
- "zwei",
- "könnte",
"grün",
"wilden",
"lokalisieren",
"Thema",
"beide",
"Vokal",
- "kam",
"gegen",
- "ging",
"Ente",
"Schrei",
- "jetzt",
"nie",
"dezimal",
"frisch",
"nur",
- "bauen",
"zahlen",
"richtig",
"drücken",
@@ -1667,7 +1843,6 @@
"Partitur",
"enthalten",
"Uhr",
- "fliessen",
"Board",
"füllen",
"Leiste",
@@ -1678,20 +1853,14 @@
"springen",
"kaufen",
"gekauft",
- "er",
- "Hafen",
- "Vater",
"statt",
"Schönheit",
- "setzen",
- "aber",
"Prüfung",
"Wunder",
"Position",
"beschreiben",
"Massstab",
"froh",
- "gewesen",
"erforderlich",
"dünn",
"Appenzell-",
@@ -1700,18 +1869,14 @@
"Orgel",
"Stretch",
"Tatsache",
- "Klasse",
"Boden",
"pflücken",
- "Ursache",
"voll",
"Gedanken",
"Kanton",
"protokollieren",
- "Jahr",
"zustimmen",
"zehn",
- "Bank",
"wenn",
"besiedeln",
"Silber",
@@ -1720,8 +1885,6 @@
"schrieb",
"Kontrolle",
"oft",
- "Haus",
- "unter",
"Lied",
"Meer",
"Wüste",
@@ -1739,7 +1902,6 @@
"Mund",
"Lösung",
"Stopp",
- "hoch",
"Schnur",
"Achtung",
"Moment",
@@ -1747,15 +1909,10 @@
"Strom",
"Start",
"Mine",
- "ich",
"Sklave",
"Lastwagen",
- "Anzahl",
- "Umzug",
- "Tür",
"Anspruch",
"bestellen",
- "Luft",
"sanft",
"Objekt",
"Stein",
@@ -1768,21 +1925,16 @@
"Kampf",
"Flüssigkeit",
"fiel",
- "Akt",
"vielleicht",
"Region",
"Jahrhundert",
"Rutsch",
"sie",
- "oben",
"zusammen",
"nahm",
"tragen",
"bringen",
"subtrahieren",
- "Zimmer",
- "Auto",
- "sagte",
"Insel",
"Minute",
"trennen",
@@ -1790,27 +1942,20 @@
"lehren",
"Band",
"Fang",
- "niedrig",
"Wetter",
- "Zuhause",
"Öl",
- "sind",
"Reifen",
"halten",
"Büro",
"insekt",
"spät",
- "denken",
"Verfahren",
"bei",
"Finger",
"Süden",
- "nach oben",
"arm",
"jeder",
"Rest",
- "Art",
- "suchen",
"allgemein",
"Kosten",
"Leben",
@@ -1827,17 +1972,12 @@
"lernen",
"Feind",
"die",
- "Menschen",
"sterben",
"begeistern",
"Charakter",
"modernen",
- "Schule",
- "versuchen",
"Alter",
- "wissen",
"Dampf",
- "tun",
"merken",
"Sauerstoff",
"Liebe",
@@ -1845,164 +1985,23 @@
"Kapitän",
"Fall",
"Grösse",
- "dann",
"bald",
"dunkel",
"Wasch",
"gemeint",
"Metall",
- "bedeuten",
- "machen",
"möglich",
"Bruder",
"Suche",
"Familie",
"Salz",
- "Platz",
"Studie",
- "Mutter",
- "Fuss",
"Nase",
- "war",
"Entwurf",
- "alt",
"geführt",
"sauber",
"Schiene",
"Aufstieg",
- "meine",
- "senden",
- "Problem",
- "sechs",
- "Katze",
- "wenig",
- "Glocke",
- "Aktie",
- "Abschnitt",
- "schwarz",
- "Haut",
- "passieren",
- "Ärger",
- "geboren",
- "Gemeinde",
- "Stück",
- "Gesetz",
- "Quart",
- "durch",
- "andere",
- "ängstlich",
- "obere",
- "Reihe",
- "Motor",
- "Ergebnis",
- "Firma",
- "einsam",
- "Recht",
- "Macht",
- "Pflege",
- "Satz",
- "mehrere",
- "muss",
- "Punkt",
- "Oberfläche",
- "aus",
- "über",
- "finden",
- "Besuch",
- "blau",
- "brennen",
- "schützen",
- "dritte",
- "träumen",
- "Norden",
- "regieren",
- "Gewicht",
- "Fisch",
- "Schiff",
- "seltsam",
- "beitreten",
- "Blatt",
- "Wasser",
- "stiegen",
- "obwohl",
- "entwickeln",
- "mir",
- "Werkzeug",
- "je",
- "Schulter",
- "Ei",
- "oder",
- "links",
- "Fleisch",
- "warten",
- "Zucker",
- "Lebensmittel",
- "Geruch",
- "viel",
- "einfach",
- "Schritt",
- "Sonne",
- "Zentrum",
- "Schliessen",
- "Veranstaltung",
- "wir",
- "dass",
- "führen",
- "elektrisch",
- "gleichsetzen",
- "danken",
- "Zorn",
- "Vergangenheit",
- "erleichtern",
- "ähnlich",
- "Samen",
- "Schwanz",
- "sa",
- "Reise",
- "verbinden",
- "verloren",
- "Lächeln",
- "Druck",
- "Stunde",
- "ist",
- "Himmel",
- "mehr",
- "waren",
- "ob",
- "variieren",
- "vor",
- "Junge",
- "plötzlich",
- "beweisen",
- "getan",
- "nächste",
- "zwanzig",
- "Ihre",
- "mais",
- "riesig",
- "essen",
- "Kugel",
- "buchstabieren",
- "Schlaf",
- "mehreren",
- "Kluft",
- "Schnee",
- "beobachten",
- "Menge",
- "Rings",
- "Getränk",
- "Sommer",
- "regeln",
- "König",
- "wird",
- "Ende",
- "tut",
- "Boot",
- "Vorbei",
- "gesendet",
- "Geschichte",
- "Akkord",
- "Wärme",
- "Rennen"
+ "senden"
]
}
diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json
index df28ff992246..ddb6ee57af50 100644
--- a/frontend/tsconfig.json
+++ b/frontend/tsconfig.json
@@ -8,6 +8,8 @@
"allowUmdGlobalAccess": true,
"target": "ES6",
"noEmit": true,
+ "jsx": "preserve",
+ "jsxImportSource": "solid-js",
"paths": {
"virtual:language-hashes": [
"./src/ts/types/virtual-language-hashes.d.ts"
@@ -17,9 +19,10 @@
},
"include": [
"./src/**/*.ts",
+ "./src/**/*.tsx",
"./scripts/**/*.ts",
"vite-plugins/**/*.ts",
"vite.config.ts"
],
- "exclude": ["node_modules", "build", "setup-tests.ts", "**/*.spec.ts"]
+ "exclude": ["node_modules", "build", "setup-tests.ts", "./__tests__/**/*.*"]
}
diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts
index 0b81b5466492..929759214fe6 100644
--- a/frontend/vite.config.ts
+++ b/frontend/vite.config.ts
@@ -28,6 +28,7 @@ import replace from "vite-plugin-filter-replace";
// eslint-disable-next-line import/no-unresolved
import UnpluginInjectPreload from "unplugin-inject-preload/vite";
import { KnownFontName } from "@monkeytype/schemas/fonts";
+import solidPlugin from "vite-plugin-solid";
export default defineConfig(({ mode }): UserConfig => {
const env = loadEnv(mode, process.cwd(), "");
@@ -88,6 +89,7 @@ function getPlugins({
}),
jqueryInject(),
injectHTML(),
+ solidPlugin(),
];
const devPlugins: PluginOption[] = [Inspect()];
diff --git a/frontend/vitest.config.ts b/frontend/vitest.config.ts
index 1b720dddc1b0..ac6a13452130 100644
--- a/frontend/vitest.config.ts
+++ b/frontend/vitest.config.ts
@@ -1,10 +1,12 @@
import { defineConfig, UserWorkspaceConfig } from "vitest/config";
import { languageHashes } from "./vite-plugins/language-hashes";
import { envConfig } from "./vite-plugins/env-config";
+import solidPlugin from "vite-plugin-solid";
const plugins = [
languageHashes({ skip: true }),
envConfig({ isDevelopment: true, clientVersion: "TESTING", env: {} }),
+ solidPlugin(),
];
export const projects: UserWorkspaceConfig[] = [
@@ -15,7 +17,12 @@ export const projects: UserWorkspaceConfig[] = [
exclude: ["__tests__/**/*.jsdom-spec.ts"],
environment: "happy-dom",
globalSetup: "__tests__/global-setup.ts",
- setupFiles: ["__tests__/setup-tests.ts"],
+ setupFiles: [
+ "__tests__/__harness__/setup-jquery.ts",
+ "__tests__/__harness__/mock-dom.ts",
+ "__tests__/__harness__/mock-firebase.ts",
+ "__tests__/__harness__/mock-env-config.ts",
+ ],
},
plugins,
},
@@ -23,10 +30,23 @@ export const projects: UserWorkspaceConfig[] = [
test: {
name: { label: "jsdom", color: "yellow" },
include: ["__tests__/**/*.jsdom-spec.ts"],
- exclude: ["__tests__/**/*.spec.ts"],
- environment: "happy-dom",
+ environment: "jsdom",
+ globalSetup: "__tests__/global-setup.ts",
+ setupFiles: ["__tests__/__harness__/setup-jquery.ts"],
+ },
+ plugins,
+ },
+ {
+ test: {
+ name: { label: "jsx", color: "green" },
+ include: ["__tests__/**/*.spec.tsx"],
+ environment: "jsdom",
globalSetup: "__tests__/global-setup.ts",
- setupFiles: ["__tests__/setup-jsdom.ts"],
+ setupFiles: [
+ "__tests__/__harness__/setup-jquery.ts",
+ "__tests__/__harness__/setup-jsx.ts",
+ ],
+ globals: true,
},
plugins,
},
@@ -35,7 +55,7 @@ export default defineConfig({
test: {
projects: projects,
coverage: {
- include: ["**/*.ts"],
+ include: ["**/*.ts", "**/*.tsx"],
},
deps: {
optimizer: {
@@ -45,4 +65,5 @@ export default defineConfig({
},
},
},
+ plugins,
});
diff --git a/monkeytype.code-workspace b/monkeytype.code-workspace
index 73caeac58ae8..b17105423280 100644
--- a/monkeytype.code-workspace
+++ b/monkeytype.code-workspace
@@ -58,6 +58,12 @@
"[typescript]": {
"editor.defaultFormatter": "oxc.oxc-vscode",
},
+ "[typescriptreact]": {
+ "editor.defaultFormatter": "oxc.oxc-vscode",
+ },
+ "[javascriptreact]": {
+ "editor.defaultFormatter": "oxc.oxc-vscode",
+ },
"vitest.maximumConfigs": 10,
"oxc.typeAware": true,
"typescript.format.enable": false,
diff --git a/package.json b/package.json
index aa1d0b896aa2..a69cd880458f 100644
--- a/package.json
+++ b/package.json
@@ -76,7 +76,7 @@
"*": [
"oxfmt --no-error-on-unmatched-pattern"
],
- "*.{ts,js}": [
+ "*.{ts,tsx,js}": [
"oxlint --type-aware --type-check"
]
},
diff --git a/packages/oxlint-config/index.jsonc b/packages/oxlint-config/index.jsonc
index cb61863b3736..2f81a87ab785 100644
--- a/packages/oxlint-config/index.jsonc
+++ b/packages/oxlint-config/index.jsonc
@@ -13,6 +13,7 @@
"./rules/ts-disabled.jsonc",
"./rules/consider.jsonc",
"./rules/ts-consider.jsonc",
+ "./rules/jsx.jsonc",
"./overrides.jsonc",
],
}
diff --git a/packages/oxlint-config/rules/jsx.jsonc b/packages/oxlint-config/rules/jsx.jsonc
new file mode 100644
index 000000000000..57888d8a6b6b
--- /dev/null
+++ b/packages/oxlint-config/rules/jsx.jsonc
@@ -0,0 +1,37 @@
+{
+ "$schema": "https://raw.githubusercontent.com/oxc-project/oxc/main/npm/oxlint/configuration_schema.json",
+ "overrides": [
+ {
+ "plugins": [
+ "typescript",
+ "unicorn",
+ "oxc",
+ "import",
+ "node",
+ "promise",
+ "react",
+ ],
+ "files": ["src/**/*.tsx"],
+ "rules": {
+ "react/react-in-jsx-scope": "off",
+ "react/button-has-type": "error",
+ "react/jsx-no-duplicate-props": "error",
+ "react/jsx-no-undef": "error",
+ "react/jsx-props-no-spread-multi": "error",
+ "react/void-dom-elements-no-children": "error",
+ "react/no-unknown-property": [
+ "error",
+ {
+ "ignore": ["class", "classList"],
+ },
+ ],
+ "react/jsx-no-comment-textnodes": "error",
+ "react/style-prop-object": "error",
+ "react/checked-requires-onchange-or-readonly": "error",
+ "react/jsx-no-useless-fragment": "error",
+ "react/no-unescaped-entities": "error",
+ "react/jsx-pascal-case": "error",
+ },
+ },
+ ],
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 83e4030ce3af..e8e7affdb918 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -19,7 +19,7 @@ importers:
version: link:packages/release
'@vitest/coverage-v8':
specifier: 4.0.15
- version: 4.0.15(vitest@4.0.15(@types/node@20.5.1)(happy-dom@20.0.10)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1))
+ version: 4.0.15(vitest@4.0.15(@types/node@20.5.1)(happy-dom@20.0.10)(jsdom@27.4.0)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1))
conventional-changelog:
specifier: 6.0.0
version: 6.0.0(conventional-commits-filter@5.0.0)
@@ -52,7 +52,7 @@ importers:
version: 2.5.6
vitest:
specifier: 4.0.15
- version: 4.0.15(@types/node@20.5.1)(happy-dom@20.0.10)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
+ version: 4.0.15(@types/node@20.5.1)(happy-dom@20.0.10)(jsdom@27.4.0)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
backend:
dependencies:
@@ -224,7 +224,7 @@ importers:
version: 10.0.0
'@vitest/coverage-v8':
specifier: 4.0.15
- version: 4.0.15(vitest@4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1))
+ version: 4.0.15(vitest@4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jsdom@27.4.0)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1))
concurrently:
specifier: 8.2.2
version: 8.2.2
@@ -254,7 +254,7 @@ importers:
version: 5.9.3
vitest:
specifier: 4.0.15
- version: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
+ version: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jsdom@27.4.0)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
frontend:
dependencies:
@@ -370,9 +370,15 @@ importers:
'@monkeytype/typescript-config':
specifier: workspace:*
version: link:../packages/typescript-config
+ '@solidjs/testing-library':
+ specifier: 0.8.10
+ version: 0.8.10(solid-js@1.9.10)
'@testing-library/dom':
specifier: 10.4.1
version: 10.4.1
+ '@testing-library/jest-dom':
+ specifier: 6.9.1
+ version: 6.9.1
'@testing-library/user-event':
specifier: 14.6.1
version: 14.6.1(@testing-library/dom@10.4.1)
@@ -405,7 +411,7 @@ importers:
version: 5.0.2
'@vitest/coverage-v8':
specifier: 4.0.15
- version: 4.0.15(vitest@4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1))
+ version: 4.0.15(vitest@4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jsdom@27.4.0)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1))
autoprefixer:
specifier: 10.4.20
version: 10.4.20(postcss@8.4.31)
@@ -418,6 +424,9 @@ importers:
eslint-plugin-compat:
specifier: 6.0.2
version: 6.0.2(eslint@9.39.1)
+ eslint-plugin-solid:
+ specifier: 0.14.5
+ version: 0.14.5(eslint@9.39.1)(typescript@5.9.3)
firebase-tools:
specifier: 13.15.1
version: 13.15.1(encoding@0.1.13)
@@ -427,6 +436,9 @@ importers:
happy-dom:
specifier: 20.0.10
version: 20.0.10
+ jsdom:
+ specifier: 27.4.0
+ version: 27.4.0
madge:
specifier: 8.0.0
version: 8.0.0(typescript@5.9.3)
@@ -448,6 +460,9 @@ importers:
sass:
specifier: 1.70.0
version: 1.70.0
+ solid-js:
+ specifier: 1.9.10
+ version: 1.9.10
subset-font:
specifier: 2.3.0
version: 2.3.0
@@ -480,10 +495,13 @@ importers:
version: 2.1.0(vite@7.1.12(@types/node@24.9.1)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1))
vite-plugin-pwa:
specifier: 1.1.0
- version: 1.1.0(vite@7.1.12(@types/node@24.9.1)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1))(workbox-build@7.1.1)(workbox-window@7.1.0)
+ version: 1.1.0(vite@7.1.12(@types/node@24.9.1)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1))(workbox-build@7.1.1(@types/babel__core@7.20.5))(workbox-window@7.1.0)
+ vite-plugin-solid:
+ specifier: 2.11.10
+ version: 2.11.10(@testing-library/jest-dom@6.9.1)(solid-js@1.9.10)(vite@7.1.12(@types/node@24.9.1)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1))
vitest:
specifier: 4.0.15
- version: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
+ version: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jsdom@27.4.0)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
packages/contracts:
dependencies:
@@ -520,7 +538,7 @@ importers:
version: 5.9.3
vitest:
specifier: 4.0.15
- version: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
+ version: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jsdom@27.4.0)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
packages/funbox:
dependencies:
@@ -554,7 +572,7 @@ importers:
version: 5.9.3
vitest:
specifier: 4.0.15
- version: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
+ version: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jsdom@27.4.0)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
packages/oxlint-config: {}
@@ -609,7 +627,7 @@ importers:
version: 5.9.3
vitest:
specifier: 4.0.15
- version: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
+ version: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jsdom@27.4.0)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
packages/tsup-config:
dependencies:
@@ -657,13 +675,19 @@ importers:
version: 5.9.3
vitest:
specifier: 4.0.15
- version: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
+ version: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jsdom@27.4.0)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
zod:
specifier: 3.23.8
version: 3.23.8
packages:
+ '@acemir/cssom@0.9.30':
+ resolution: {integrity: sha512-9CnlMCI0LmCIq0olalQqdWrJHPzm0/tw3gzOA9zJSgvFX7Xau3D24mAGa4BtwxwY69nsuJW6kQqqCzf/mEcQgg==}
+
+ '@adobe/css-tools@4.4.4':
+ resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==}
+
'@ampproject/remapping@2.3.0':
resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
engines: {node: '>=6.0.0'}
@@ -672,7 +696,7 @@ packages:
resolution: {integrity: sha512-q0qHfnuNYVKu0Swrnnvfj9971AEyW7c8v9jCOZGCl5ZbyGMNG4RPyJkRcMi/JC8CRfdOe0IDfNm1nNsi2avprg==}
peerDependencies:
openapi3-ts: ^2.0.0 || ^3.0.0
- zod: ^3.20.0
+ zod: 3.23.8
'@apideck/better-ajv-errors@0.3.6':
resolution: {integrity: sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==}
@@ -683,6 +707,15 @@ packages:
'@apidevtools/json-schema-ref-parser@9.1.2':
resolution: {integrity: sha512-r1w81DpR+KyRWd3f+rk6TNqMgedmAxZP5v5KWlXQWlgMUUtyEJch0DKEci1SorPMiSeM8XPl7MZ3miJ60JIpQg==}
+ '@asamuzakjp/css-color@4.1.1':
+ resolution: {integrity: sha512-B0Hv6G3gWGMn0xKJ0txEi/jM5iFpT3MfDxmhZFb4W047GvytCf1DHQ1D69W3zHI4yWe2aTZAA0JnbMZ7Xc8DuQ==}
+
+ '@asamuzakjp/dom-selector@6.7.6':
+ resolution: {integrity: sha512-hBaJER6A9MpdG3WgdlOolHmbOYvSk46y7IQN/1+iqiCuUu6iWdQrs9DGKF8ocqsEqWujWf/V7b7vaDgiUmIvUg==}
+
+ '@asamuzakjp/nwsapi@2.3.9':
+ resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==}
+
'@babel/code-frame@7.27.1':
resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==}
engines: {node: '>=6.9.0'}
@@ -748,6 +781,10 @@ packages:
resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==}
engines: {node: '>=6.9.0'}
+ '@babel/helper-module-imports@7.18.6':
+ resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==}
+ engines: {node: '>=6.9.0'}
+
'@babel/helper-module-imports@7.24.7':
resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==}
engines: {node: '>=6.9.0'}
@@ -877,6 +914,12 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0-0
+ '@babel/plugin-syntax-jsx@7.27.1':
+ resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
'@babel/plugin-syntax-unicode-sets-regex@7.18.6':
resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==}
engines: {node: '>=6.9.0'}
@@ -1332,6 +1375,38 @@ packages:
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
engines: {node: '>=12'}
+ '@csstools/color-helpers@5.1.0':
+ resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==}
+ engines: {node: '>=18'}
+
+ '@csstools/css-calc@2.1.4':
+ resolution: {integrity: sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@csstools/css-parser-algorithms': ^3.0.5
+ '@csstools/css-tokenizer': ^3.0.4
+
+ '@csstools/css-color-parser@3.1.0':
+ resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@csstools/css-parser-algorithms': ^3.0.5
+ '@csstools/css-tokenizer': ^3.0.4
+
+ '@csstools/css-parser-algorithms@3.0.5':
+ resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@csstools/css-tokenizer': ^3.0.4
+
+ '@csstools/css-syntax-patches-for-csstree@1.0.23':
+ resolution: {integrity: sha512-YEmgyklR6l/oKUltidNVYdjSmLSW88vMsKx0pmiS3r71s8ZZRpd8A0Yf0U+6p/RzElmMnPBv27hNWjDQMSZRtQ==}
+ engines: {node: '>=18'}
+
+ '@csstools/css-tokenizer@3.0.4':
+ resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==}
+ engines: {node: '>=18'}
+
'@dabh/diagnostics@2.0.3':
resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==}
@@ -1806,6 +1881,12 @@ packages:
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
+ '@eslint-community/eslint-utils@4.9.1':
+ resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
+
'@eslint-community/regexpp@4.12.2':
resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==}
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
@@ -1842,6 +1923,15 @@ packages:
resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ '@exodus/bytes@1.8.0':
+ resolution: {integrity: sha512-8JPn18Bcp8Uo1T82gR8lh2guEOa5KKU/IEKvvdp0sgmi7coPBWf1Doi1EXsGZb2ehc8ym/StJCjffYV+ne7sXQ==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
+ peerDependencies:
+ '@exodus/crypto': ^1.0.0-rc.4
+ peerDependenciesMeta:
+ '@exodus/crypto':
+ optional: true
+
'@exodus/schemasafe@1.3.0':
resolution: {integrity: sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==}
@@ -3107,6 +3197,16 @@ packages:
engines: {node: '>=8.10'}
hasBin: true
+ '@solidjs/testing-library@0.8.10':
+ resolution: {integrity: sha512-qdeuIerwyq7oQTIrrKvV0aL9aFeuwTd86VYD3afdq5HYEwoox1OBTJy4y8A3TFZr8oAR0nujYgCzY/8wgHGfeQ==}
+ engines: {node: '>= 14'}
+ peerDependencies:
+ '@solidjs/router': '>=0.9.0'
+ solid-js: '>=1.0.0'
+ peerDependenciesMeta:
+ '@solidjs/router':
+ optional: true
+
'@standard-schema/spec@1.0.0':
resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==}
@@ -3117,6 +3217,10 @@ packages:
resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==}
engines: {node: '>=18'}
+ '@testing-library/jest-dom@6.9.1':
+ resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==}
+ engines: {node: '>=14', npm: '>=6', yarn: '>=1'}
+
'@testing-library/user-event@14.6.1':
resolution: {integrity: sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==}
engines: {node: '>=12', npm: '>=6'}
@@ -3188,6 +3292,18 @@ packages:
'@types/aria-query@5.0.4':
resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==}
+ '@types/babel__core@7.20.5':
+ resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
+
+ '@types/babel__generator@7.27.0':
+ resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==}
+
+ '@types/babel__template@7.4.4':
+ resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==}
+
+ '@types/babel__traverse@7.28.0':
+ resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==}
+
'@types/bcrypt@5.0.2':
resolution: {integrity: sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ==}
@@ -3398,10 +3514,30 @@ packages:
'@types/whatwg-url@11.0.5':
resolution: {integrity: sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==}
+ '@typescript-eslint/project-service@8.52.0':
+ resolution: {integrity: sha512-xD0MfdSdEmeFa3OmVqonHi+Cciab96ls1UhIF/qX/O/gPu5KXD0bY9lu33jj04fjzrXHcuvjBcBC+D3SNSadaw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ typescript: '>=4.8.4 <6.0.0'
+
+ '@typescript-eslint/scope-manager@8.52.0':
+ resolution: {integrity: sha512-ixxqmmCcc1Nf8S0mS0TkJ/3LKcC8mruYJPOU6Ia2F/zUUR4pApW7LzrpU3JmtePbRUTes9bEqRc1Gg4iyRnDzA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@typescript-eslint/tsconfig-utils@8.52.0':
+ resolution: {integrity: sha512-jl+8fzr/SdzdxWJznq5nvoI7qn2tNYV/ZBAEcaFMVXf+K6jmXvAFrgo/+5rxgnL152f//pDEAYAhhBAZGrVfwg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ typescript: '>=4.8.4 <6.0.0'
+
'@typescript-eslint/types@7.18.0':
resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==}
engines: {node: ^18.18.0 || >=20.0.0}
+ '@typescript-eslint/types@8.52.0':
+ resolution: {integrity: sha512-LWQV1V4q9V4cT4H5JCIx3481iIFxH1UkVk+ZkGGAV1ZGcjGI9IoFOfg3O6ywz8QqCDEp7Inlg6kovMofsNRaGg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
'@typescript-eslint/typescript-estree@7.18.0':
resolution: {integrity: sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==}
engines: {node: ^18.18.0 || >=20.0.0}
@@ -3411,10 +3547,27 @@ packages:
typescript:
optional: true
+ '@typescript-eslint/typescript-estree@8.52.0':
+ resolution: {integrity: sha512-XP3LClsCc0FsTK5/frGjolyADTh3QmsLp6nKd476xNI9CsSsLnmn4f0jrzNoAulmxlmNIpeXuHYeEQv61Q6qeQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ typescript: '>=4.8.4 <6.0.0'
+
+ '@typescript-eslint/utils@8.52.0':
+ resolution: {integrity: sha512-wYndVMWkweqHpEpwPhwqE2lnD2DxC6WVLupU/DOt/0/v+/+iQbbzO3jOHjmBMnhu0DgLULvOaU4h4pwHYi2oRQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0
+ typescript: '>=4.8.4 <6.0.0'
+
'@typescript-eslint/visitor-keys@7.18.0':
resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==}
engines: {node: ^18.18.0 || >=20.0.0}
+ '@typescript-eslint/visitor-keys@8.52.0':
+ resolution: {integrity: sha512-ink3/Zofus34nmBsPjow63FP5M7IGff0RKAgqR6+CFpdk22M7aLwC9gOcLGYqr7MczLPzZVERW9hRog3O4n1sQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
'@vitest/coverage-v8@4.0.15':
resolution: {integrity: sha512-FUJ+1RkpTFW7rQITdgTi93qOCWJobWhBirEPCeXh2SW2wsTlFxy51apDz5gzG+ZEYt/THvWeNmhdAoS9DTwpCw==}
peerDependencies:
@@ -3524,6 +3677,10 @@ packages:
resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==}
engines: {node: '>= 14'}
+ agent-base@7.1.4:
+ resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==}
+ engines: {node: '>= 14'}
+
aggregate-error@3.1.0:
resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
engines: {node: '>=8'}
@@ -3742,6 +3899,11 @@ packages:
b4a@1.6.6:
resolution: {integrity: sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==}
+ babel-plugin-jsx-dom-expressions@0.40.3:
+ resolution: {integrity: sha512-5HOwwt0BYiv/zxl7j8Pf2bGL6rDXfV6nUhLs8ygBX+EFJXzBPHM/euj9j/6deMZ6wa52Wb2PBaAV5U/jKwIY1w==}
+ peerDependencies:
+ '@babel/core': ^7.20.12
+
babel-plugin-polyfill-corejs2@0.4.14:
resolution: {integrity: sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==}
peerDependencies:
@@ -3757,6 +3919,15 @@ packages:
peerDependencies:
'@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
+ babel-preset-solid@1.9.10:
+ resolution: {integrity: sha512-HCelrgua/Y+kqO8RyL04JBWS/cVdrtUv/h45GntgQY+cJl4eBcKkCDV3TdMjtKx1nXwRaR9QXslM/Npm1dxdZQ==}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+ solid-js: ^1.9.10
+ peerDependenciesMeta:
+ solid-js:
+ optional: true
+
babylon@6.18.0:
resolution: {integrity: sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==}
hasBin: true
@@ -3831,6 +4002,9 @@ packages:
peerDependencies:
ajv: 4.11.8 - 8
+ bidi-js@1.0.3:
+ resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==}
+
bignumber.js@9.1.2:
resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==}
@@ -4467,10 +4641,21 @@ packages:
css-to-react-native@3.2.0:
resolution: {integrity: sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==}
+ css-tree@3.1.0:
+ resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==}
+ engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
+
css-what@6.1.0:
resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==}
engines: {node: '>= 6'}
+ css.escape@1.5.1:
+ resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==}
+
+ cssstyle@5.3.7:
+ resolution: {integrity: sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==}
+ engines: {node: '>=20'}
+
csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
@@ -4488,6 +4673,10 @@ packages:
resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==}
engines: {node: '>= 14'}
+ data-urls@6.0.0:
+ resolution: {integrity: sha512-BnBS08aLUM+DKamupXs3w2tJJoqU+AkaE/+6vQxi/G/DPmIZFJJp9Dkb1kM03AZx8ADehDUZgsNxju3mPXZYIA==}
+ engines: {node: '>=20'}
+
data-view-buffer@1.0.2:
resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==}
engines: {node: '>= 0.4'}
@@ -4567,6 +4756,9 @@ packages:
resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
engines: {node: '>=0.10.0'}
+ decimal.js@10.6.0:
+ resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==}
+
decko@1.2.0:
resolution: {integrity: sha512-m8FnyHXV1QX+S1cl+KPFDIl6NMkxtKsy6+U/aYyjrOqWMuwAwYWu7ePqrsUHtDR5Y8Yk2pi/KIDSgF+vT4cPOQ==}
@@ -4736,6 +4928,9 @@ packages:
dom-accessibility-api@0.5.16:
resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==}
+ dom-accessibility-api@0.6.3:
+ resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==}
+
dom-serializer@1.4.1:
resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==}
@@ -4860,6 +5055,10 @@ packages:
resolution: {integrity: sha512-BeJFvFRJddxobhvEdm5GqHzRV/X+ACeuw0/BuuxsCh1EUZcAIz8+kYmBp/LrQuloy6K1f3a0M7+IhmZ7QnkISA==}
engines: {node: '>=0.12'}
+ entities@6.0.1:
+ resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==}
+ engines: {node: '>=0.12'}
+
env-paths@2.2.1:
resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
engines: {node: '>=6'}
@@ -4956,6 +5155,13 @@ packages:
peerDependencies:
eslint: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0
+ eslint-plugin-solid@0.14.5:
+ resolution: {integrity: sha512-nfuYK09ah5aJG/oEN6P1qziy1zLgW4PDWe75VNPi4CEFYk1x2AEqwFeQfEPR7gNn0F2jOeqKhx2E+5oNCOBYWQ==}
+ engines: {node: '>=18.0.0'}
+ peerDependencies:
+ eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0
+ typescript: '>=4.8.4'
+
eslint-scope@8.4.0:
resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -5618,6 +5824,13 @@ packages:
howler@2.2.3:
resolution: {integrity: sha512-QM0FFkw0LRX1PR8pNzJVAY25JhIWvbKMBFM4gqk+QdV+kPXOhleWGCB6AiAF/goGjIHK2e/nIElplvjQwhr0jg==}
+ html-encoding-sniffer@6.0.0:
+ resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
+
+ html-entities@2.3.3:
+ resolution: {integrity: sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==}
+
html-entities@2.5.2:
resolution: {integrity: sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==}
@@ -5634,6 +5847,10 @@ packages:
engines: {node: '>=6'}
hasBin: true
+ html-tags@3.3.1:
+ resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==}
+ engines: {node: '>=8'}
+
htmlparser2@5.0.1:
resolution: {integrity: sha512-vKZZra6CSe9qsJzh0BjBGXo8dvzNsq/oGvsjfRdOrrryfeD9UOBEEQdeoqCRmKZchF5h2zOBMQ6YuQ0uRUmdbQ==}
@@ -5672,6 +5889,10 @@ packages:
resolution: {integrity: sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==}
engines: {node: '>= 14'}
+ https-proxy-agent@7.0.6:
+ resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
+ engines: {node: '>= 14'}
+
human-signals@2.1.0:
resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
engines: {node: '>=10.17.0'}
@@ -5760,6 +5981,9 @@ packages:
resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==}
engines: {node: '>=10'}
+ inline-style-parser@0.2.7:
+ resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==}
+
inquirer-autocomplete-prompt@2.0.1:
resolution: {integrity: sha512-jUHrH0btO7j5r8DTQgANf2CBkTZChoVySD8zF/wp5fZCOLIuUbleXhf4ZY5jNBOc1owA3gdfWtfZuppfYBhcUg==}
engines: {node: '>=12'}
@@ -5878,6 +6102,10 @@ packages:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
+ is-html@2.0.0:
+ resolution: {integrity: sha512-S+OpgB5i7wzIue/YSE5hg0e5ZYfG3hhpNh9KGl6ayJ38p7ED6wxQLd1TV91xHpcTvw90KMJ9EwN3F/iNflHBVg==}
+ engines: {node: '>=8'}
+
is-inside-container@1.0.0:
resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==}
engines: {node: '>=14.16'}
@@ -5941,6 +6169,9 @@ packages:
resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==}
engines: {node: '>=0.10.0'}
+ is-potential-custom-element-name@1.0.1:
+ resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
+
is-promise@4.0.0:
resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==}
@@ -6013,6 +6244,10 @@ packages:
resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==}
engines: {node: '>= 0.4'}
+ is-what@4.1.16:
+ resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==}
+ engines: {node: '>=12.13'}
+
is-wsl@1.1.0:
resolution: {integrity: sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==}
engines: {node: '>=4'}
@@ -6148,6 +6383,15 @@ packages:
jsbn@1.1.0:
resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==}
+ jsdom@27.4.0:
+ resolution: {integrity: sha512-mjzqwWRD9Y1J1KUi7W97Gja1bwOOM5Ug0EZ6UDK3xS7j7mndrkwozHtSblfomlzyB4NepioNt+B2sOSzczVgtQ==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
+ peerDependencies:
+ canvas: ^3.0.0
+ peerDependenciesMeta:
+ canvas:
+ optional: true
+
jsep@1.4.0:
resolution: {integrity: sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==}
engines: {node: '>= 10.16.0'}
@@ -6249,6 +6493,9 @@ packages:
jws@4.0.0:
resolution: {integrity: sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==}
+ kebab-case@1.0.2:
+ resolution: {integrity: sha512-7n6wXq4gNgBELfDCpzKc+mRrZFs7D+wgfF5WRFLNAr4DA/qtr9Js8uOAVAfHhuLMfAcQ0pRKqbpjx+TcJVdE1Q==}
+
keygrip@1.1.0:
resolution: {integrity: sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==}
engines: {node: '>= 0.6'}
@@ -6266,6 +6513,9 @@ packages:
engines: {node: '>=16.17.0 <17 || >=18.6.0'}
hasBin: true
+ known-css-properties@0.30.0:
+ resolution: {integrity: sha512-VSWXYUnsPu9+WYKkfmJyLKtIvaRJi1kXUqVmBACORXZQxT5oZDsoZ2vQP+bQFDnWtpI/4eq3MLoRMjI2fnLzTQ==}
+
konami@1.7.0:
resolution: {integrity: sha512-lfw/bXyPcOYVP0Vt05PKVYWp/Rx92eUIg48Kb2jkY2Ko00jWMTzk6jt5bRdkVRfvPr9RLTl1DM6vVrjWLXnQyg==}
@@ -6449,6 +6699,10 @@ packages:
resolution: {integrity: sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==}
engines: {node: 20 || >=22}
+ lru-cache@11.2.4:
+ resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==}
+ engines: {node: 20 || >=22}
+
lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
@@ -6560,6 +6814,9 @@ packages:
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
engines: {node: '>= 0.4'}
+ mdn-data@2.12.2:
+ resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==}
+
media-typer@0.3.0:
resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==}
engines: {node: '>= 0.6'}
@@ -6582,6 +6839,10 @@ packages:
resolution: {integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==}
engines: {node: '>=10'}
+ merge-anything@5.1.7:
+ resolution: {integrity: sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ==}
+ engines: {node: '>=12.13'}
+
merge-descriptors@1.0.3:
resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==}
@@ -7352,6 +7613,9 @@ packages:
parse5@7.1.2:
resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==}
+ parse5@8.0.0:
+ resolution: {integrity: sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==}
+
parseurl@1.3.3:
resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
engines: {node: '>= 0.8'}
@@ -8053,6 +8317,10 @@ packages:
engines: {node: '>=14.0.0'}
hasBin: true
+ saxes@6.0.0:
+ resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==}
+ engines: {node: '>=v12.22.7'}
+
scheduler@0.23.2:
resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==}
@@ -8109,6 +8377,16 @@ packages:
serialize-javascript@6.0.2:
resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==}
+ seroval-plugins@1.3.3:
+ resolution: {integrity: sha512-16OL3NnUBw8JG1jBLUoZJsLnQq0n5Ua6aHalhJK4fMQkz1lqR7Osz1sA30trBtd9VUDc2NgkuRCn8+/pBwqZ+w==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ seroval: ^1.0
+
+ seroval@1.3.2:
+ resolution: {integrity: sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==}
+ engines: {node: '>=10'}
+
serve-static@1.16.2:
resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==}
engines: {node: '>= 0.8.0'}
@@ -8277,6 +8555,14 @@ packages:
resolution: {integrity: sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==}
engines: {node: '>= 10.0.0', npm: '>= 3.0.0'}
+ solid-js@1.9.10:
+ resolution: {integrity: sha512-Coz956cos/EPDlhs6+jsdTxKuJDPT7B5SVIWgABwROyxjY7Xbr8wkzD68Et+NxnV7DLJ3nJdAC2r9InuV/4Jew==}
+
+ solid-refresh@0.6.3:
+ resolution: {integrity: sha512-F3aPsX6hVw9ttm5LYlth8Q15x6MlI/J3Dn+o3EQyRTtTxidepSTwAYdozt01/YA+7ObcciagGEyXIopGZzQtbA==}
+ peerDependencies:
+ solid-js: ^1.3
+
sonic-boom@1.4.1:
resolution: {integrity: sha512-LRHh/A8tpW7ru89lrlkU4AszXt1dbwSjVWguGrmlxE7tawVmDBlI1PILMkXAxJTwqhgsEeTHzj36D5CmHgQmNg==}
@@ -8508,6 +8794,9 @@ packages:
stubs@3.0.0:
resolution: {integrity: sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==}
+ style-to-object@1.0.14:
+ resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==}
+
styled-components@6.1.12:
resolution: {integrity: sha512-n/O4PzRPhbYI0k1vKKayfti3C/IGcPf+DqcrOB7O/ab9x4u/zjqraneT5N45+sIe87cxrCApXM8Bna7NYxwoTA==}
engines: {node: '>= 16'}
@@ -8576,6 +8865,9 @@ packages:
resolution: {integrity: sha512-upi/0ZGkYgEcLeGieoz8gT74oWHA0E7JivX7aN9mAf+Tc7BQoRBvnIGHoPDw+f9TXTW4s6kGYCZJtauP6OYp7g==}
hasBin: true
+ symbol-tree@3.2.4:
+ resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
+
tapable@2.2.1:
resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
engines: {node: '>=6'}
@@ -8688,6 +8980,13 @@ packages:
resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==}
engines: {node: '>=14.0.0'}
+ tldts-core@7.0.19:
+ resolution: {integrity: sha512-lJX2dEWx0SGH4O6p+7FPwYmJ/bu1JbcGJ8RLaG9b7liIgZ85itUVEPbMtWRVrde/0fnDPEPHW10ZsKW3kVsE9A==}
+
+ tldts@7.0.19:
+ resolution: {integrity: sha512-8PWx8tvC4jDB39BQw1m4x8y5MH1BcQ5xHeL2n7UVFulMPH/3Q0uiamahFJ3lXA0zO2SUyRXuVVbWSDmstlt9YA==}
+ hasBin: true
+
tmp@0.0.33:
resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}
engines: {node: '>=0.6.0'}
@@ -8725,6 +9024,10 @@ packages:
resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==}
hasBin: true
+ tough-cookie@6.0.0:
+ resolution: {integrity: sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==}
+ engines: {node: '>=16'}
+
toxic@1.0.1:
resolution: {integrity: sha512-WI3rIGdcaKULYg7KVoB0zcjikqvcYYvcuT6D89bFPz2rVR0Rl0PK6x8/X62rtdLtBKIE985NzVf/auTtGegIIg==}
@@ -8738,6 +9041,10 @@ packages:
resolution: {integrity: sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==}
engines: {node: '>=14'}
+ tr46@6.0.0:
+ resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==}
+ engines: {node: '>=20'}
+
tree-kill@1.2.2:
resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
hasBin: true
@@ -8759,6 +9066,12 @@ packages:
peerDependencies:
typescript: '>=4.2.0'
+ ts-api-utils@2.4.0:
+ resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==}
+ engines: {node: '>=18.12'}
+ peerDependencies:
+ typescript: '>=4.8.4'
+
ts-deepmerge@6.2.1:
resolution: {integrity: sha512-8CYSLazCyj0DJDpPIxOFzJG46r93uh6EynYjuey+bxcLltBeqZL7DMfaE5ZPzZNFlav7wx+2TDa/mBl8gkTYzw==}
engines: {node: '>=14.13.1'}
@@ -9159,6 +9472,16 @@ packages:
'@vite-pwa/assets-generator':
optional: true
+ vite-plugin-solid@2.11.10:
+ resolution: {integrity: sha512-Yr1dQybmtDtDAHkii6hXuc1oVH9CPcS/Zb2jN/P36qqcrkNnVPsMTzQ06jyzFPFjj3U1IYKMVt/9ZqcwGCEbjw==}
+ peerDependencies:
+ '@testing-library/jest-dom': ^5.16.6 || ^5.17.0 || ^6.*
+ solid-js: ^1.7.2
+ vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0
+ peerDependenciesMeta:
+ '@testing-library/jest-dom':
+ optional: true
+
vite@7.1.12:
resolution: {integrity: sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -9199,6 +9522,14 @@ packages:
yaml:
optional: true
+ vitefu@1.1.1:
+ resolution: {integrity: sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==}
+ peerDependencies:
+ vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0
+ peerDependenciesMeta:
+ vite:
+ optional: true
+
vitest@4.0.15:
resolution: {integrity: sha512-n1RxDp8UJm6N0IbJLQo+yzLZ2sQCDyl1o0LeugbPWf8+8Fttp29GghsQBjYJVmWq3gBFfe9Hs1spR44vovn2wA==}
engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0}
@@ -9236,6 +9567,10 @@ packages:
vlq@0.2.3:
resolution: {integrity: sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==}
+ w3c-xmlserializer@5.0.0:
+ resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==}
+ engines: {node: '>=18'}
+
walkdir@0.4.1:
resolution: {integrity: sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==}
engines: {node: '>=6.0.0'}
@@ -9264,6 +9599,10 @@ packages:
resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==}
engines: {node: '>=12'}
+ webidl-conversions@8.0.1:
+ resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==}
+ engines: {node: '>=20'}
+
webpack-sources@3.2.3:
resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==}
engines: {node: '>=10.13.0'}
@@ -9289,10 +9628,18 @@ packages:
resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==}
engines: {node: '>=12'}
+ whatwg-mimetype@4.0.0:
+ resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==}
+ engines: {node: '>=18'}
+
whatwg-url@13.0.0:
resolution: {integrity: sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==}
engines: {node: '>=16'}
+ whatwg-url@15.1.0:
+ resolution: {integrity: sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==}
+ engines: {node: '>=20'}
+
whatwg-url@5.0.0:
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
@@ -9442,6 +9789,18 @@ packages:
utf-8-validate:
optional: true
+ ws@8.19.0:
+ resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==}
+ engines: {node: '>=10.0.0'}
+ peerDependencies:
+ bufferutil: ^4.0.1
+ utf-8-validate: '>=5.0.2'
+ peerDependenciesMeta:
+ bufferutil:
+ optional: true
+ utf-8-validate:
+ optional: true
+
wsl-utils@0.1.0:
resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==}
engines: {node: '>=18'}
@@ -9450,6 +9809,13 @@ packages:
resolution: {integrity: sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==}
engines: {node: '>=8'}
+ xml-name-validator@5.0.0:
+ resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==}
+ engines: {node: '>=18'}
+
+ xmlchars@2.2.0:
+ resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
+
xtend@4.0.2:
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
engines: {node: '>=0.4'}
@@ -9532,6 +9898,10 @@ packages:
snapshots:
+ '@acemir/cssom@0.9.30': {}
+
+ '@adobe/css-tools@4.4.4': {}
+
'@ampproject/remapping@2.3.0':
dependencies:
'@jridgewell/gen-mapping': 0.3.13
@@ -9557,6 +9927,24 @@ snapshots:
call-me-maybe: 1.0.2
js-yaml: 4.1.0
+ '@asamuzakjp/css-color@4.1.1':
+ dependencies:
+ '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)
+ '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)
+ '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4)
+ '@csstools/css-tokenizer': 3.0.4
+ lru-cache: 11.2.4
+
+ '@asamuzakjp/dom-selector@6.7.6':
+ dependencies:
+ '@asamuzakjp/nwsapi': 2.3.9
+ bidi-js: 1.0.3
+ css-tree: 3.1.0
+ is-potential-custom-element-name: 1.0.1
+ lru-cache: 11.2.4
+
+ '@asamuzakjp/nwsapi@2.3.9': {}
+
'@babel/code-frame@7.27.1':
dependencies:
'@babel/helper-validator-identifier': 7.28.5
@@ -9682,6 +10070,10 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ '@babel/helper-module-imports@7.18.6':
+ dependencies:
+ '@babel/types': 7.28.5
+
'@babel/helper-module-imports@7.24.7':
dependencies:
'@babel/traverse': 7.25.2
@@ -9832,6 +10224,11 @@ snapshots:
'@babel/core': 7.28.5
'@babel/helper-plugin-utils': 7.27.1
+ '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.5)':
+ dependencies:
+ '@babel/core': 7.28.5
+ '@babel/helper-plugin-utils': 7.27.1
+
'@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.28.5)':
dependencies:
'@babel/core': 7.28.5
@@ -10444,6 +10841,28 @@ snapshots:
dependencies:
'@jridgewell/trace-mapping': 0.3.9
+ '@csstools/color-helpers@5.1.0': {}
+
+ '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)':
+ dependencies:
+ '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4)
+ '@csstools/css-tokenizer': 3.0.4
+
+ '@csstools/css-color-parser@3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)':
+ dependencies:
+ '@csstools/color-helpers': 5.1.0
+ '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)
+ '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4)
+ '@csstools/css-tokenizer': 3.0.4
+
+ '@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4)':
+ dependencies:
+ '@csstools/css-tokenizer': 3.0.4
+
+ '@csstools/css-syntax-patches-for-csstree@1.0.23': {}
+
+ '@csstools/css-tokenizer@3.0.4': {}
+
'@dabh/diagnostics@2.0.3':
dependencies:
colorspace: 1.1.4
@@ -10712,6 +11131,11 @@ snapshots:
eslint: 9.39.1
eslint-visitor-keys: 3.4.3
+ '@eslint-community/eslint-utils@4.9.1(eslint@9.39.1)':
+ dependencies:
+ eslint: 9.39.1
+ eslint-visitor-keys: 3.4.3
+
'@eslint-community/regexpp@4.12.2': {}
'@eslint/config-array@0.21.1':
@@ -10760,6 +11184,8 @@ snapshots:
'@eslint/core': 0.17.0
levn: 0.4.1
+ '@exodus/bytes@1.8.0': {}
+
'@exodus/schemasafe@1.3.0': {}
'@faker-js/faker@7.6.0': {}
@@ -11932,12 +12358,14 @@ snapshots:
transitivePeerDependencies:
- ajv
- '@rollup/plugin-babel@5.3.1(@babel/core@7.28.5)(rollup@2.79.2)':
+ '@rollup/plugin-babel@5.3.1(@babel/core@7.28.5)(@types/babel__core@7.20.5)(rollup@2.79.2)':
dependencies:
'@babel/core': 7.28.5
'@babel/helper-module-imports': 7.27.1
'@rollup/pluginutils': 3.1.0(rollup@2.79.2)
rollup: 2.79.2
+ optionalDependencies:
+ '@types/babel__core': 7.20.5
transitivePeerDependencies:
- supports-color
@@ -12216,6 +12644,11 @@ snapshots:
ignore: 5.3.2
p-map: 4.0.0
+ '@solidjs/testing-library@0.8.10(solid-js@1.9.10)':
+ dependencies:
+ '@testing-library/dom': 10.4.1
+ solid-js: 1.9.10
+
'@standard-schema/spec@1.0.0': {}
'@surma/rollup-plugin-off-main-thread@2.2.3':
@@ -12236,6 +12669,15 @@ snapshots:
picocolors: 1.1.1
pretty-format: 27.5.1
+ '@testing-library/jest-dom@6.9.1':
+ dependencies:
+ '@adobe/css-tools': 4.4.4
+ aria-query: 5.3.0
+ css.escape: 1.5.1
+ dom-accessibility-api: 0.6.3
+ picocolors: 1.1.1
+ redent: 3.0.0
+
'@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1)':
dependencies:
'@testing-library/dom': 10.4.1
@@ -12288,6 +12730,27 @@ snapshots:
'@types/aria-query@5.0.4': {}
+ '@types/babel__core@7.20.5':
+ dependencies:
+ '@babel/parser': 7.28.5
+ '@babel/types': 7.28.5
+ '@types/babel__generator': 7.27.0
+ '@types/babel__template': 7.4.4
+ '@types/babel__traverse': 7.28.0
+
+ '@types/babel__generator@7.27.0':
+ dependencies:
+ '@babel/types': 7.28.5
+
+ '@types/babel__template@7.4.4':
+ dependencies:
+ '@babel/parser': 7.28.5
+ '@babel/types': 7.28.5
+
+ '@types/babel__traverse@7.28.0':
+ dependencies:
+ '@babel/types': 7.28.5
+
'@types/bcrypt@5.0.2':
dependencies:
'@types/node': 24.9.1
@@ -12527,8 +12990,28 @@ snapshots:
dependencies:
'@types/webidl-conversions': 7.0.3
+ '@typescript-eslint/project-service@8.52.0(typescript@5.9.3)':
+ dependencies:
+ '@typescript-eslint/tsconfig-utils': 8.52.0(typescript@5.9.3)
+ '@typescript-eslint/types': 8.52.0
+ debug: 4.4.3
+ typescript: 5.9.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/scope-manager@8.52.0':
+ dependencies:
+ '@typescript-eslint/types': 8.52.0
+ '@typescript-eslint/visitor-keys': 8.52.0
+
+ '@typescript-eslint/tsconfig-utils@8.52.0(typescript@5.9.3)':
+ dependencies:
+ typescript: 5.9.3
+
'@typescript-eslint/types@7.18.0': {}
+ '@typescript-eslint/types@8.52.0': {}
+
'@typescript-eslint/typescript-estree@7.18.0(typescript@5.9.3)':
dependencies:
'@typescript-eslint/types': 7.18.0
@@ -12544,12 +13027,43 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ '@typescript-eslint/typescript-estree@8.52.0(typescript@5.9.3)':
+ dependencies:
+ '@typescript-eslint/project-service': 8.52.0(typescript@5.9.3)
+ '@typescript-eslint/tsconfig-utils': 8.52.0(typescript@5.9.3)
+ '@typescript-eslint/types': 8.52.0
+ '@typescript-eslint/visitor-keys': 8.52.0
+ debug: 4.4.3
+ minimatch: 9.0.5
+ semver: 7.7.3
+ tinyglobby: 0.2.15
+ ts-api-utils: 2.4.0(typescript@5.9.3)
+ typescript: 5.9.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/utils@8.52.0(eslint@9.39.1)(typescript@5.9.3)':
+ dependencies:
+ '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.1)
+ '@typescript-eslint/scope-manager': 8.52.0
+ '@typescript-eslint/types': 8.52.0
+ '@typescript-eslint/typescript-estree': 8.52.0(typescript@5.9.3)
+ eslint: 9.39.1
+ typescript: 5.9.3
+ transitivePeerDependencies:
+ - supports-color
+
'@typescript-eslint/visitor-keys@7.18.0':
dependencies:
'@typescript-eslint/types': 7.18.0
eslint-visitor-keys: 3.4.3
- '@vitest/coverage-v8@4.0.15(vitest@4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1))':
+ '@typescript-eslint/visitor-keys@8.52.0':
+ dependencies:
+ '@typescript-eslint/types': 8.52.0
+ eslint-visitor-keys: 4.2.1
+
+ '@vitest/coverage-v8@4.0.15(vitest@4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jsdom@27.4.0)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1))':
dependencies:
'@bcoe/v8-coverage': 1.0.2
'@vitest/utils': 4.0.15
@@ -12562,11 +13076,11 @@ snapshots:
obug: 2.1.1
std-env: 3.10.0
tinyrainbow: 3.0.3
- vitest: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
+ vitest: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jsdom@27.4.0)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
transitivePeerDependencies:
- supports-color
- '@vitest/coverage-v8@4.0.15(vitest@4.0.15(@types/node@20.5.1)(happy-dom@20.0.10)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1))':
+ '@vitest/coverage-v8@4.0.15(vitest@4.0.15(@types/node@20.5.1)(happy-dom@20.0.10)(jsdom@27.4.0)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1))':
dependencies:
'@bcoe/v8-coverage': 1.0.2
'@vitest/utils': 4.0.15
@@ -12579,7 +13093,7 @@ snapshots:
obug: 2.1.1
std-env: 3.10.0
tinyrainbow: 3.0.3
- vitest: 4.0.15(@types/node@20.5.1)(happy-dom@20.0.10)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
+ vitest: 4.0.15(@types/node@20.5.1)(happy-dom@20.0.10)(jsdom@27.4.0)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
transitivePeerDependencies:
- supports-color
@@ -12713,6 +13227,8 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ agent-base@7.1.4: {}
+
aggregate-error@3.1.0:
dependencies:
clean-stack: 2.2.0
@@ -12940,6 +13456,15 @@ snapshots:
b4a@1.6.6: {}
+ babel-plugin-jsx-dom-expressions@0.40.3(@babel/core@7.28.5):
+ dependencies:
+ '@babel/core': 7.28.5
+ '@babel/helper-module-imports': 7.18.6
+ '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5)
+ '@babel/types': 7.28.5
+ html-entities: 2.3.3
+ parse5: 7.1.2
+
babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.28.5):
dependencies:
'@babel/compat-data': 7.28.5
@@ -12964,6 +13489,13 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ babel-preset-solid@1.9.10(@babel/core@7.28.5)(solid-js@1.9.10):
+ dependencies:
+ '@babel/core': 7.28.5
+ babel-plugin-jsx-dom-expressions: 0.40.3(@babel/core@7.28.5)
+ optionalDependencies:
+ solid-js: 1.9.10
+
babylon@6.18.0: {}
balanced-match@1.0.2: {}
@@ -13030,6 +13562,10 @@ snapshots:
jsonpointer: 5.0.1
leven: 3.1.0
+ bidi-js@1.0.3:
+ dependencies:
+ require-from-string: 2.0.2
+
bignumber.js@9.1.2: {}
binary-extensions@2.3.0: {}
@@ -13750,8 +14286,22 @@ snapshots:
css-color-keywords: 1.0.0
postcss-value-parser: 4.2.0
+ css-tree@3.1.0:
+ dependencies:
+ mdn-data: 2.12.2
+ source-map-js: 1.2.1
+
css-what@6.1.0: {}
+ css.escape@1.5.1: {}
+
+ cssstyle@5.3.7:
+ dependencies:
+ '@asamuzakjp/css-color': 4.1.1
+ '@csstools/css-syntax-patches-for-csstree': 1.0.23
+ css-tree: 3.1.0
+ lru-cache: 11.2.4
+
csstype@3.1.3: {}
csv-parse@5.5.6: {}
@@ -13762,6 +14312,11 @@ snapshots:
data-uri-to-buffer@6.0.2: {}
+ data-urls@6.0.0:
+ dependencies:
+ whatwg-mimetype: 4.0.0
+ whatwg-url: 15.1.0
+
data-view-buffer@1.0.2:
dependencies:
call-bound: 1.0.4
@@ -13819,6 +14374,8 @@ snapshots:
decamelize@1.2.0: {}
+ decimal.js@10.6.0: {}
+
decko@1.2.0: {}
deep-equal-in-any-order@2.0.6:
@@ -13993,6 +14550,8 @@ snapshots:
dom-accessibility-api@0.5.16: {}
+ dom-accessibility-api@0.6.3: {}
+
dom-serializer@1.4.1:
dependencies:
domelementtype: 2.3.0
@@ -14124,6 +14683,8 @@ snapshots:
entities@5.0.0: {}
+ entities@6.0.1: {}
+
env-paths@2.2.1:
optional: true
@@ -14335,6 +14896,19 @@ snapshots:
lodash.memoize: 4.1.2
semver: 7.6.3
+ eslint-plugin-solid@0.14.5(eslint@9.39.1)(typescript@5.9.3):
+ dependencies:
+ '@typescript-eslint/utils': 8.52.0(eslint@9.39.1)(typescript@5.9.3)
+ eslint: 9.39.1
+ estraverse: 5.3.0
+ is-html: 2.0.0
+ kebab-case: 1.0.2
+ known-css-properties: 0.30.0
+ style-to-object: 1.0.14
+ typescript: 5.9.3
+ transitivePeerDependencies:
+ - supports-color
+
eslint-scope@8.4.0:
dependencies:
esrecurse: 4.3.0
@@ -15324,6 +15898,14 @@ snapshots:
howler@2.2.3: {}
+ html-encoding-sniffer@6.0.0:
+ dependencies:
+ '@exodus/bytes': 1.8.0
+ transitivePeerDependencies:
+ - '@exodus/crypto'
+
+ html-entities@2.3.3: {}
+
html-entities@2.5.2:
optional: true
@@ -15349,6 +15931,8 @@ snapshots:
relateurl: 0.2.7
uglify-js: 3.19.1
+ html-tags@3.3.1: {}
+
htmlparser2@5.0.1:
dependencies:
domelementtype: 2.3.0
@@ -15414,6 +15998,13 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ https-proxy-agent@7.0.6:
+ dependencies:
+ agent-base: 7.1.4
+ debug: 4.4.3
+ transitivePeerDependencies:
+ - supports-color
+
human-signals@2.1.0: {}
human-signals@4.3.1: {}
@@ -15480,6 +16071,8 @@ snapshots:
ini@2.0.0: {}
+ inline-style-parser@0.2.7: {}
+
inquirer-autocomplete-prompt@2.0.1(inquirer@8.2.6):
dependencies:
ansi-escapes: 4.3.2
@@ -15633,6 +16226,10 @@ snapshots:
dependencies:
is-extglob: 2.1.1
+ is-html@2.0.0:
+ dependencies:
+ html-tags: 3.3.1
+
is-inside-container@1.0.0:
dependencies:
is-docker: 3.0.0
@@ -15674,6 +16271,8 @@ snapshots:
is-plain-obj@1.1.0: {}
+ is-potential-custom-element-name@1.0.1: {}
+
is-promise@4.0.0: {}
is-regex@1.2.1:
@@ -15735,6 +16334,8 @@ snapshots:
call-bound: 1.0.4
get-intrinsic: 1.3.0
+ is-what@4.1.16: {}
+
is-wsl@1.1.0: {}
is-wsl@2.2.0:
@@ -15876,6 +16477,34 @@ snapshots:
jsbn@1.1.0: {}
+ jsdom@27.4.0:
+ dependencies:
+ '@acemir/cssom': 0.9.30
+ '@asamuzakjp/dom-selector': 6.7.6
+ '@exodus/bytes': 1.8.0
+ cssstyle: 5.3.7
+ data-urls: 6.0.0
+ decimal.js: 10.6.0
+ html-encoding-sniffer: 6.0.0
+ http-proxy-agent: 7.0.2
+ https-proxy-agent: 7.0.6
+ is-potential-custom-element-name: 1.0.1
+ parse5: 8.0.0
+ saxes: 6.0.0
+ symbol-tree: 3.2.4
+ tough-cookie: 6.0.0
+ w3c-xmlserializer: 5.0.0
+ webidl-conversions: 8.0.1
+ whatwg-mimetype: 4.0.0
+ whatwg-url: 15.1.0
+ ws: 8.19.0
+ xml-name-validator: 5.0.0
+ transitivePeerDependencies:
+ - '@exodus/crypto'
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+
jsep@1.4.0: {}
jsesc@2.5.2: {}
@@ -15996,6 +16625,8 @@ snapshots:
jwa: 2.0.0
safe-buffer: 5.2.1
+ kebab-case@1.0.2: {}
+
keygrip@1.1.0:
dependencies:
tsscmp: 1.0.6
@@ -16026,6 +16657,8 @@ snapshots:
zod: 3.25.76
zod-validation-error: 1.3.1(zod@3.25.76)
+ known-css-properties@0.30.0: {}
+
konami@1.7.0: {}
kuler@2.0.0: {}
@@ -16197,6 +16830,8 @@ snapshots:
lru-cache@11.1.0: {}
+ lru-cache@11.2.4: {}
+
lru-cache@5.1.1:
dependencies:
yallist: 3.1.1
@@ -16319,6 +16954,8 @@ snapshots:
math-intrinsics@1.1.0: {}
+ mdn-data@2.12.2: {}
+
media-typer@0.3.0: {}
media-typer@1.1.0: {}
@@ -16343,6 +16980,10 @@ snapshots:
type-fest: 0.18.1
yargs-parser: 20.2.9
+ merge-anything@5.1.7:
+ dependencies:
+ is-what: 4.1.16
+
merge-descriptors@1.0.3: {}
merge-descriptors@2.0.0: {}
@@ -17318,6 +17959,10 @@ snapshots:
dependencies:
entities: 4.5.0
+ parse5@8.0.0:
+ dependencies:
+ entities: 6.0.1
+
parseurl@1.3.3: {}
pascal-case@3.1.2:
@@ -18108,6 +18753,10 @@ snapshots:
immutable: 4.3.7
source-map-js: 1.2.1
+ saxes@6.0.0:
+ dependencies:
+ xmlchars: 2.2.0
+
scheduler@0.23.2:
dependencies:
loose-envify: 1.4.0
@@ -18190,6 +18839,12 @@ snapshots:
dependencies:
randombytes: 2.1.0
+ seroval-plugins@1.3.3(seroval@1.3.2):
+ dependencies:
+ seroval: 1.3.2
+
+ seroval@1.3.2: {}
+
serve-static@1.16.2:
dependencies:
encodeurl: 2.0.0
@@ -18403,6 +19058,21 @@ snapshots:
ip-address: 9.0.5
smart-buffer: 4.2.0
+ solid-js@1.9.10:
+ dependencies:
+ csstype: 3.1.3
+ seroval: 1.3.2
+ seroval-plugins: 1.3.3(seroval@1.3.2)
+
+ solid-refresh@0.6.3(solid-js@1.9.10):
+ dependencies:
+ '@babel/generator': 7.28.5
+ '@babel/helper-module-imports': 7.27.1
+ '@babel/types': 7.28.5
+ solid-js: 1.9.10
+ transitivePeerDependencies:
+ - supports-color
+
sonic-boom@1.4.1:
dependencies:
atomic-sleep: 1.0.0
@@ -18639,6 +19309,10 @@ snapshots:
stubs@3.0.0: {}
+ style-to-object@1.0.14:
+ dependencies:
+ inline-style-parser: 0.2.7
+
styled-components@6.1.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
'@emotion/is-prop-valid': 1.2.2
@@ -18775,6 +19449,8 @@ snapshots:
transitivePeerDependencies:
- encoding
+ symbol-tree@3.2.4: {}
+
tapable@2.2.1: {}
tar-fs@2.1.4:
@@ -18931,6 +19607,12 @@ snapshots:
tinyrainbow@3.0.3: {}
+ tldts-core@7.0.19: {}
+
+ tldts@7.0.19:
+ dependencies:
+ tldts-core: 7.0.19
+
tmp@0.0.33:
dependencies:
os-tmpdir: 1.0.2
@@ -18959,6 +19641,10 @@ snapshots:
touch@3.1.1: {}
+ tough-cookie@6.0.0:
+ dependencies:
+ tldts: 7.0.19
+
toxic@1.0.1:
dependencies:
lodash: 4.17.21
@@ -18973,6 +19659,10 @@ snapshots:
dependencies:
punycode: 2.3.1
+ tr46@6.0.0:
+ dependencies:
+ punycode: 2.3.1
+
tree-kill@1.2.2: {}
trim-newlines@3.0.1: {}
@@ -18985,6 +19675,10 @@ snapshots:
dependencies:
typescript: 5.9.3
+ ts-api-utils@2.4.0(typescript@5.9.3):
+ dependencies:
+ typescript: 5.9.3
+
ts-deepmerge@6.2.1: {}
ts-graphviz@2.1.2:
@@ -19377,17 +20071,32 @@ snapshots:
html-minifier-terser: 7.2.0
vite: 7.1.12(@types/node@24.9.1)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
- vite-plugin-pwa@1.1.0(vite@7.1.12(@types/node@24.9.1)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1))(workbox-build@7.1.1)(workbox-window@7.1.0):
+ vite-plugin-pwa@1.1.0(vite@7.1.12(@types/node@24.9.1)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1))(workbox-build@7.1.1(@types/babel__core@7.20.5))(workbox-window@7.1.0):
dependencies:
debug: 4.4.3
pretty-bytes: 6.1.1
tinyglobby: 0.2.15
vite: 7.1.12(@types/node@24.9.1)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
- workbox-build: 7.1.1
+ workbox-build: 7.1.1(@types/babel__core@7.20.5)
workbox-window: 7.1.0
transitivePeerDependencies:
- supports-color
+ vite-plugin-solid@2.11.10(@testing-library/jest-dom@6.9.1)(solid-js@1.9.10)(vite@7.1.12(@types/node@24.9.1)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)):
+ dependencies:
+ '@babel/core': 7.28.5
+ '@types/babel__core': 7.20.5
+ babel-preset-solid: 1.9.10(@babel/core@7.28.5)(solid-js@1.9.10)
+ merge-anything: 5.1.7
+ solid-js: 1.9.10
+ solid-refresh: 0.6.3(solid-js@1.9.10)
+ vite: 7.1.12(@types/node@24.9.1)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
+ vitefu: 1.1.1(vite@7.1.12(@types/node@24.9.1)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1))
+ optionalDependencies:
+ '@testing-library/jest-dom': 6.9.1
+ transitivePeerDependencies:
+ - supports-color
+
vite@7.1.12(@types/node@20.5.1)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1):
dependencies:
esbuild: 0.25.11
@@ -19420,7 +20129,11 @@ snapshots:
tsx: 4.16.2
yaml: 2.8.1
- vitest@4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1):
+ vitefu@1.1.1(vite@7.1.12(@types/node@24.9.1)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)):
+ optionalDependencies:
+ vite: 7.1.12(@types/node@24.9.1)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
+
+ vitest@4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(jsdom@27.4.0)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1):
dependencies:
'@vitest/expect': 4.0.15
'@vitest/mocker': 4.0.15(vite@7.1.12(@types/node@24.9.1)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1))
@@ -19446,6 +20159,7 @@ snapshots:
'@opentelemetry/api': 1.8.0
'@types/node': 24.9.1
happy-dom: 20.0.10
+ jsdom: 27.4.0
transitivePeerDependencies:
- jiti
- less
@@ -19459,7 +20173,7 @@ snapshots:
- tsx
- yaml
- vitest@4.0.15(@types/node@20.5.1)(happy-dom@20.0.10)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1):
+ vitest@4.0.15(@types/node@20.5.1)(happy-dom@20.0.10)(jsdom@27.4.0)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1):
dependencies:
'@vitest/expect': 4.0.15
'@vitest/mocker': 4.0.15(vite@7.1.12(@types/node@20.5.1)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1))
@@ -19484,6 +20198,7 @@ snapshots:
optionalDependencies:
'@types/node': 20.5.1
happy-dom: 20.0.10
+ jsdom: 27.4.0
transitivePeerDependencies:
- jiti
- less
@@ -19499,6 +20214,10 @@ snapshots:
vlq@0.2.3: {}
+ w3c-xmlserializer@5.0.0:
+ dependencies:
+ xml-name-validator: 5.0.0
+
walkdir@0.4.1: {}
wawoff2@2.0.1:
@@ -19528,6 +20247,8 @@ snapshots:
webidl-conversions@7.0.0: {}
+ webidl-conversions@8.0.1: {}
+
webpack-sources@3.2.3: {}
webpack-virtual-modules@0.5.0: {}
@@ -19546,11 +20267,18 @@ snapshots:
whatwg-mimetype@3.0.0: {}
+ whatwg-mimetype@4.0.0: {}
+
whatwg-url@13.0.0:
dependencies:
tr46: 4.1.1
webidl-conversions: 7.0.0
+ whatwg-url@15.1.0:
+ dependencies:
+ tr46: 6.0.0
+ webidl-conversions: 8.0.1
+
whatwg-url@5.0.0:
dependencies:
tr46: 0.0.3
@@ -19667,13 +20395,13 @@ snapshots:
dependencies:
workbox-core: 7.1.0
- workbox-build@7.1.1:
+ workbox-build@7.1.1(@types/babel__core@7.20.5):
dependencies:
'@apideck/better-ajv-errors': 0.3.6(ajv@8.17.1)
'@babel/core': 7.28.5
'@babel/preset-env': 7.28.5(@babel/core@7.28.5)
'@babel/runtime': 7.28.4
- '@rollup/plugin-babel': 5.3.1(@babel/core@7.28.5)(rollup@2.79.2)
+ '@rollup/plugin-babel': 5.3.1(@babel/core@7.28.5)(@types/babel__core@7.20.5)(rollup@2.79.2)
'@rollup/plugin-node-resolve': 15.3.1(rollup@2.79.2)
'@rollup/plugin-replace': 2.4.2(rollup@2.79.2)
'@rollup/plugin-terser': 0.4.4(rollup@2.79.2)
@@ -19800,12 +20528,18 @@ snapshots:
ws@7.5.10: {}
+ ws@8.19.0: {}
+
wsl-utils@0.1.0:
dependencies:
is-wsl: 3.1.0
xdg-basedir@4.0.0: {}
+ xml-name-validator@5.0.0: {}
+
+ xmlchars@2.2.0: {}
+
xtend@4.0.2: {}
y18n@5.0.8: {}
diff --git a/vitest.config.ts b/vitest.config.ts
index 22005f4254fc..563c205b2b6d 100644
--- a/vitest.config.ts
+++ b/vitest.config.ts
@@ -2,6 +2,9 @@ import { defineConfig, UserWorkspaceConfig } from "vitest/config";
import { projects as backendProjects } from "./backend/vitest.config";
import { projects as frontendProjects } from "./frontend/vitest.config";
+//oxlint-disable-next-line no-explicit-any
+let globalPlugins: any[] = [];
+
export default defineConfig({
test: {
projects: [
@@ -10,6 +13,7 @@ export default defineConfig({
"packages/**/vitest.config.ts",
],
},
+ plugins: globalPlugins,
});
function convertTests(
@@ -19,11 +23,12 @@ function convertTests(
return (projects as UserWorkspaceConfig[]).map((it) => {
const test = it.test ?? {};
const name: string | { label: string } = test.name ?? "unknown";
+ copySolidPlugin(it);
let updatedName =
name === null || typeof name === "string"
- ? `${name} (${root})`
- : { ...name, label: `${name.label} (${root})` };
+ ? `${name}-${root}`
+ : { ...name, label: `${name.label}-${root}` };
return {
...it,
@@ -35,3 +40,14 @@ function convertTests(
} as UserWorkspaceConfig;
});
}
+
+/**
+ * Tests for solidJs need the solid plugin to run on config level and on test level. idk why
+ */
+function copySolidPlugin(config: UserWorkspaceConfig): void {
+ if (!config.plugins) return;
+ config.plugins
+ //@ts-expect-error this is fine
+ .filter((it) => it["name"] === "solid")
+ .forEach((it) => globalPlugins.push(it));
+}