diff --git a/web/.gitignore b/web/.gitignore
index a547bf3..f52343a 100644
--- a/web/.gitignore
+++ b/web/.gitignore
@@ -22,3 +22,6 @@ dist-ssr
*.njsproj
*.sln
*.sw?
+
+*storybook.log
+storybook-static
diff --git a/web/.storybook/main.ts b/web/.storybook/main.ts
new file mode 100644
index 0000000..375769e
--- /dev/null
+++ b/web/.storybook/main.ts
@@ -0,0 +1,18 @@
+import type { StorybookConfig } from '@storybook/react-vite';
+
+const config: StorybookConfig = {
+ "stories": [
+ "../src/**/*.mdx",
+ "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"
+ ],
+ "addons": [
+ "@chromatic-com/storybook",
+ "@storybook/addon-vitest",
+ "@storybook/addon-a11y",
+ "@storybook/addon-docs",
+ "@storybook/addon-mcp"
+ ],
+ "framework": "@storybook/react-vite",
+ "staticDirs": ["../public"]
+};
+export default config;
\ No newline at end of file
diff --git a/web/.storybook/preview.tsx b/web/.storybook/preview.tsx
new file mode 100644
index 0000000..729d088
--- /dev/null
+++ b/web/.storybook/preview.tsx
@@ -0,0 +1,57 @@
+import type { Preview } from '@storybook/react-vite'
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
+import { initialize, mswLoader } from 'msw-storybook-addon'
+import { MemoryRouter } from 'react-router-dom'
+
+import '../src/index.css'
+import '../src/i18n'
+import { LOCALE_KEY } from '../src/i18n'
+import { ConfigProvider } from '../src/config/config-provider'
+import { handlers } from '../src/test/handlers'
+
+initialize({ onUnhandledRequest: 'bypass' })
+
+const preview: Preview = {
+ parameters: {
+ controls: {
+ matchers: {
+ color: /(background|color)$/i,
+ date: /Date$/i,
+ },
+ },
+
+ a11y: {
+ // 'todo' - show a11y violations in the test UI only
+ // 'error' - fail CI on a11y violations
+ // 'off' - skip a11y checks entirely
+ test: 'todo'
+ },
+
+ msw: { handlers },
+ },
+ loaders: [mswLoader],
+ beforeEach() {
+ // Pin the UI language so text-based assertions are deterministic; also
+ // stops ConfigProvider from switching to the instance default at runtime.
+ localStorage.setItem(LOCALE_KEY, 'en')
+ },
+ decorators: [
+ (Story) => {
+ const queryClient = new QueryClient({
+ defaultOptions: { queries: { retry: false } },
+ })
+
+ return (
+
+
+
+
+
+
+
+ )
+ },
+ ],
+};
+
+export default preview;
diff --git a/web/eslint.config.js b/web/eslint.config.js
index ecbceb4..ed2f7e6 100644
--- a/web/eslint.config.js
+++ b/web/eslint.config.js
@@ -1,19 +1,19 @@
+// For more info, see https://github.com/storybookjs/eslint-plugin-storybook#configuration-flat-config-format
+import storybook from "eslint-plugin-storybook";
+
import js from "@eslint/js";
import globals from "globals";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import tseslint from "typescript-eslint";
-export default tseslint.config(
- { ignores: ["dist", "src/components/ui", "src/api/schema.d.ts"] },
- {
- extends: [js.configs.recommended, ...tseslint.configs.recommended],
- files: ["**/*.{ts,tsx}"],
- languageOptions: { ecmaVersion: 2022, globals: globals.browser },
- plugins: { "react-hooks": reactHooks, "react-refresh": reactRefresh },
- rules: {
- ...reactHooks.configs.recommended.rules,
- "react-refresh/only-export-components": ["warn", { allowConstantExport: true }],
- },
+export default tseslint.config({ ignores: ["dist", "src/components/ui", "src/api/schema.d.ts", "public/mockServiceWorker.js"] }, {
+ extends: [js.configs.recommended, ...tseslint.configs.recommended],
+ files: ["**/*.{ts,tsx}"],
+ languageOptions: { ecmaVersion: 2022, globals: globals.browser },
+ plugins: { "react-hooks": reactHooks, "react-refresh": reactRefresh },
+ rules: {
+ ...reactHooks.configs.recommended.rules,
+ "react-refresh/only-export-components": ["warn", { allowConstantExport: true }],
},
-);
+}, storybook.configs["flat/recommended"]);
diff --git a/web/package.json b/web/package.json
index e2be0ee..be54783 100644
--- a/web/package.json
+++ b/web/package.json
@@ -13,7 +13,9 @@
"typecheck": "tsc -b --noEmit",
"lint": "eslint .",
"gen:api": "openapi-typescript http://localhost:8080/api-docs/openapi.json -o src/api/schema.d.ts",
- "check:size": "node scripts/check-bundle-size.mjs"
+ "check:size": "node scripts/check-bundle-size.mjs",
+ "storybook": "storybook dev -p 6006",
+ "build-storybook": "storybook build"
},
"dependencies": {
"@base-ui/react": "^1.5.0",
@@ -33,7 +35,13 @@
"tw-animate-css": "^1.4.0"
},
"devDependencies": {
+ "@chromatic-com/storybook": "^5.2.1",
"@eslint/js": "^10.0.1",
+ "@storybook/addon-a11y": "^10.4.2",
+ "@storybook/addon-docs": "^10.4.2",
+ "@storybook/addon-mcp": "^0.6.0",
+ "@storybook/addon-vitest": "^10.4.2",
+ "@storybook/react-vite": "^10.4.2",
"@tailwindcss/vite": "^4.3.0",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.3.0",
@@ -42,18 +50,29 @@
"@types/react": "^19.1.5",
"@types/react-dom": "^19.1.3",
"@vitejs/plugin-react": "^4.5.2",
+ "@vitest/browser": "3.2.6",
+ "@vitest/coverage-v8": "3.2.6",
"eslint": "^10.4.1",
"eslint-plugin-react-hooks": "^7.1.1",
"eslint-plugin-react-refresh": "^0.5.2",
+ "eslint-plugin-storybook": "^10.4.2",
"globals": "^17.6.0",
"jsdom": "^26.1.0",
"msw": "^2.14.6",
+ "msw-storybook-addon": "^2.0.7",
"openapi-typescript": "^7.13.0",
+ "playwright": "^1.60.0",
"shadcn": "^4.10.0",
+ "storybook": "^10.4.2",
"tailwindcss": "^4.3.0",
"typescript": "~5.8.3",
"typescript-eslint": "^8.60.1",
"vite": "^6.3.5",
"vitest": "^3.2.2"
+ },
+ "msw": {
+ "workerDirectory": [
+ "public"
+ ]
}
-}
+}
\ No newline at end of file
diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml
index 5186ed4..9b62fbe 100644
--- a/web/pnpm-lock.yaml
+++ b/web/pnpm-lock.yaml
@@ -54,9 +54,27 @@ importers:
specifier: ^1.4.0
version: 1.4.0
devDependencies:
+ '@chromatic-com/storybook':
+ specifier: ^5.2.1
+ version: 5.2.1(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))
'@eslint/js':
specifier: ^10.0.1
version: 10.0.1(eslint@10.4.1(jiti@2.7.0))
+ '@storybook/addon-a11y':
+ specifier: ^10.4.2
+ version: 10.4.2(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))
+ '@storybook/addon-docs':
+ specifier: ^10.4.2
+ version: 10.4.2(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(esbuild@0.25.12)(rollup@4.61.0)(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0))
+ '@storybook/addon-mcp':
+ specifier: ^0.6.0
+ version: 0.6.0(@storybook/addon-vitest@10.4.2(@vitest/browser@3.2.6)(@vitest/runner@3.2.6)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vitest@3.2.6))(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(typescript@5.8.3)
+ '@storybook/addon-vitest':
+ specifier: ^10.4.2
+ version: 10.4.2(@vitest/browser@3.2.6)(@vitest/runner@3.2.6)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vitest@3.2.6)
+ '@storybook/react-vite':
+ specifier: ^10.4.2
+ version: 10.4.2(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(esbuild@0.25.12)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rollup@4.61.0)(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(typescript@5.8.3)(vite@6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0))
'@tailwindcss/vite':
specifier: ^4.3.0
version: 4.3.0(vite@6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0))
@@ -81,6 +99,12 @@ importers:
'@vitejs/plugin-react':
specifier: ^4.5.2
version: 4.7.0(vite@6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0))
+ '@vitest/browser':
+ specifier: 3.2.6
+ version: 3.2.6(msw@2.14.6(@types/node@25.9.1)(typescript@5.8.3))(playwright@1.60.0)(vite@6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0))(vitest@3.2.6)
+ '@vitest/coverage-v8':
+ specifier: 3.2.6
+ version: 3.2.6(@vitest/browser@3.2.6)(vitest@3.2.6)
eslint:
specifier: ^10.4.1
version: 10.4.1(jiti@2.7.0)
@@ -90,6 +114,9 @@ importers:
eslint-plugin-react-refresh:
specifier: ^0.5.2
version: 0.5.2(eslint@10.4.1(jiti@2.7.0))
+ eslint-plugin-storybook:
+ specifier: ^10.4.2
+ version: 10.4.2(eslint@10.4.1(jiti@2.7.0))(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(typescript@5.8.3)
globals:
specifier: ^17.6.0
version: 17.6.0
@@ -99,12 +126,21 @@ importers:
msw:
specifier: ^2.14.6
version: 2.14.6(@types/node@25.9.1)(typescript@5.8.3)
+ msw-storybook-addon:
+ specifier: ^2.0.7
+ version: 2.0.7(msw@2.14.6(@types/node@25.9.1)(typescript@5.8.3))
openapi-typescript:
specifier: ^7.13.0
version: 7.13.0(typescript@5.8.3)
+ playwright:
+ specifier: ^1.60.0
+ version: 1.60.0
shadcn:
specifier: ^4.10.0
version: 4.10.0(@types/node@25.9.1)(typescript@5.8.3)
+ storybook:
+ specifier: ^10.4.2
+ version: 10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
tailwindcss:
specifier: ^4.3.0
version: 4.3.0
@@ -119,13 +155,17 @@ importers:
version: 6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0)
vitest:
specifier: ^3.2.2
- version: 3.2.6(@types/node@25.9.1)(jiti@2.7.0)(jsdom@26.1.0)(lightningcss@1.32.0)(msw@2.14.6(@types/node@25.9.1)(typescript@5.8.3))
+ version: 3.2.6(@types/node@25.9.1)(@vitest/browser@3.2.6)(jiti@2.7.0)(jsdom@26.1.0)(lightningcss@1.32.0)(msw@2.14.6(@types/node@25.9.1)(typescript@5.8.3))
packages:
'@adobe/css-tools@4.5.0':
resolution: {integrity: sha512-6OzddxPio9UiWTCemp4N8cYLV2ZN1ncRnV1cVGtve7dhPOtRkleRyx32GQCYSwDYgaHU3USMm84tNsvKzRCa1Q==}
+ '@ampproject/remapping@2.3.0':
+ resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
+ engines: {node: '>=6.0.0'}
+
'@asamuzakjp/css-color@3.2.0':
resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==}
@@ -301,6 +341,16 @@ packages:
'@types/react':
optional: true
+ '@bcoe/v8-coverage@1.0.2':
+ resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==}
+ engines: {node: '>=18'}
+
+ '@chromatic-com/storybook@5.2.1':
+ resolution: {integrity: sha512-z6I7NJk/0VngA64y5TNYaB4Hc2X8+90n4op6lBt9PvWk5TmIlFLDqdX33rlrwbNRkkYijVgA/wO04rVYXi5Mlg==}
+ engines: {node: '>=20.0.0', yarn: '>=1.22.18'}
+ peerDependencies:
+ storybook: ^0.0.0-0 || ^10.1.0 || ^10.1.0-0 || ^10.2.0-0 || ^10.3.0-0 || ^10.4.0-0 || ^10.5.0-0 || ^10.6.0-0
+
'@csstools/color-helpers@5.1.0':
resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==}
engines: {node: '>=18'}
@@ -339,6 +389,21 @@ packages:
peerDependencies:
'@noble/ciphers': ^1.0.0
+ '@emnapi/core@1.10.0':
+ resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==}
+
+ '@emnapi/core@1.9.2':
+ resolution: {integrity: sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==}
+
+ '@emnapi/runtime@1.10.0':
+ resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==}
+
+ '@emnapi/runtime@1.9.2':
+ resolution: {integrity: sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==}
+
+ '@emnapi/wasi-threads@1.2.1':
+ resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==}
+
'@esbuild/aix-ppc64@0.25.12':
resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==}
engines: {node: '>=18'}
@@ -613,6 +678,23 @@ packages:
'@types/node':
optional: true
+ '@isaacs/cliui@8.0.2':
+ resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
+ engines: {node: '>=12'}
+
+ '@istanbuljs/schema@0.1.6':
+ resolution: {integrity: sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==}
+ engines: {node: '>=8'}
+
+ '@joshwooding/vite-plugin-react-docgen-typescript@0.7.0':
+ resolution: {integrity: sha512-qvsTEwEFefhdirGOPnu9Wp6ChfIwy2dBCRuETU3uE+4cC+PFoxMSiiEhxk4lOluA34eARHA0OxqsEUYDqRMgeQ==}
+ peerDependencies:
+ typescript: '>= 4.3.x'
+ vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
'@jridgewell/gen-mapping@0.3.13':
resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
@@ -629,6 +711,12 @@ packages:
'@jridgewell/trace-mapping@0.3.31':
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
+ '@mdx-js/react@3.1.1':
+ resolution: {integrity: sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==}
+ peerDependencies:
+ '@types/react': '>=16'
+ react: '>=16'
+
'@modelcontextprotocol/sdk@1.29.0':
resolution: {integrity: sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==}
engines: {node: '>=18'}
@@ -643,6 +731,15 @@ packages:
resolution: {integrity: sha512-VVPPgHyQ6ShqnrmDWuxjmUIsO9gWyOZFmuOfLd9LfBGQJwZfy0gvv9pbHSJuoFNIYC7ZDX9aoFwowjcdSC4E8w==}
engines: {node: '>=18'}
+ '@napi-rs/wasm-runtime@1.1.4':
+ resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==}
+ peerDependencies:
+ '@emnapi/core': ^1.7.1
+ '@emnapi/runtime': ^1.7.1
+
+ '@neoconfetti/react@1.0.0':
+ resolution: {integrity: sha512-klcSooChXXOzIm+SE5IISIAn3bYzYfPjbX7D7HoqZL84oAfgREeSg5vSIaSFH+DaGzzvImTyWe1OyrJ67vik4A==}
+
'@noble/ciphers@1.3.0':
resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==}
engines: {node: ^14.21.3 || >=16}
@@ -679,6 +776,246 @@ packages:
'@open-draft/until@2.1.0':
resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==}
+ '@oxc-parser/binding-android-arm-eabi@0.127.0':
+ resolution: {integrity: sha512-0LC7ye4hvqbIKxAzThzvswgHLFu2AURKzYLeSVvLdu2TBOYWQDmHnTqPLeA597BcUCxiLqLsS4CJ5uoI5WYWCQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm]
+ os: [android]
+
+ '@oxc-parser/binding-android-arm64@0.127.0':
+ resolution: {integrity: sha512-b5jtVTH6AU5CJXHNdj7Jj9IEiR9yVjjnwHzPJhGyHGPdcsZSzBCkS9GBbV33niRMvKthDwQRFRJfI4a+k4PvYg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [android]
+
+ '@oxc-parser/binding-darwin-arm64@0.127.0':
+ resolution: {integrity: sha512-obCE8B7ISKkJidjlhv9xRGJPOSDG2Yu6PRga9Ruaz35uintHxbp1Ki/Yc71wx4rj3Edrm0a1kzG1TAwit0wFpg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@oxc-parser/binding-darwin-x64@0.127.0':
+ resolution: {integrity: sha512-JL6Xb5IwPQT8rUzlpsX7E+AgfcdNklXNPFp8pjCQQ5MQOQo5rtEB2ui+3Hgg9Sn7Y9Egj6YOLLiHhLpdAe12Aw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [darwin]
+
+ '@oxc-parser/binding-freebsd-x64@0.127.0':
+ resolution: {integrity: sha512-SDQ/3MQFw58fqQz3Z1PhSKFF3JoCF4gmlNjziDm8X02tTahCw0qJbd7FGPDKw1i4VTBZene9JPyC3mHtSvi+wA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@oxc-parser/binding-linux-arm-gnueabihf@0.127.0':
+ resolution: {integrity: sha512-Av+D1MIqzV0YMGPT9we2SIZaMKD7Cxs4CvXSx/yxaWHewZjYEjScpOf5igc8IILASViw4WTnjlwUdI1KzVtDHQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm]
+ os: [linux]
+
+ '@oxc-parser/binding-linux-arm-musleabihf@0.127.0':
+ resolution: {integrity: sha512-Cs2fdJ8cPpFdeebj6p4dag8A4+56hPvZ0AhQQzlaLswGz1tz7bXt1nETLeorrM9+AMcWFFkqxcXwDGfTVidY8g==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm]
+ os: [linux]
+
+ '@oxc-parser/binding-linux-arm64-gnu@0.127.0':
+ resolution: {integrity: sha512-qdOfTcT6SY8gsJrrV92uyEUyjqMGPpIB5JZUG6QN5dukYd+7/j0kX6MwK1DgQj39jtUYixxPiaRUiEN1+0CXgQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@oxc-parser/binding-linux-arm64-musl@0.127.0':
+ resolution: {integrity: sha512-EoTCZneNFU/P2qrpEM+RHmQwt+CvDkyGESG6qhr7KaegXLZwePfbrkCDfAk8/rhxbDUVGsZILX+2tqPzFtoFWA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@oxc-parser/binding-linux-ppc64-gnu@0.127.0':
+ resolution: {integrity: sha512-zALjmZYgxFLHjXeudcDF0xFGNydTAtkAeXAr2EuC17ywCyFxcmQra4w0BMde0Yi/re4Bi4iwEoEXtYN7l6eBLQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@oxc-parser/binding-linux-riscv64-gnu@0.127.0':
+ resolution: {integrity: sha512-fPP8M6zQLS7Jz7o9d5ArUSuAuSK3e+WCYVrCpdzeCOejidtZExJ9tjhDrAd3HEPqARBCPmdpqxESPFqy44vkBQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@oxc-parser/binding-linux-riscv64-musl@0.127.0':
+ resolution: {integrity: sha512-7IcC4Ao02oGpfnjt+X/oF4U2mllo2qoSkw5xxiXNKL9MCTsTiAC6616beOuehdxGcnz1bRoPC1RQ2f1GQDdN+g==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [musl]
+
+ '@oxc-parser/binding-linux-s390x-gnu@0.127.0':
+ resolution: {integrity: sha512-pbXIhiNFHoqWeqDNLiJ9JkpHz1IM9k4DXa66x+1GTWMG7iLxtkXgE53iiuKSXwmk3zIYmaPVfBvgcAhS583K4Q==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@oxc-parser/binding-linux-x64-gnu@0.127.0':
+ resolution: {integrity: sha512-MYCguB9RvBvlSd6gbuNI7QwiLoCCAlGnlRJFPrzLI6U1/9wkC/WK6LtBAUln55H1Ctqw45PWmqrobKoMhsYQzQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@oxc-parser/binding-linux-x64-musl@0.127.0':
+ resolution: {integrity: sha512-5eY0B/bxf1xIUxb4NOTvOI3KWtBQfPWYyKAzgcrCt0mDibSZygVpO1Pz8bkeiSZ5Jj9+M09dkggG3H8I5d0Uyg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@oxc-parser/binding-openharmony-arm64@0.127.0':
+ resolution: {integrity: sha512-Gld0ajrFTUXNtdw20fVBuTQx66FA75nIVg+//pPfR3sXkuABB4mTBhl3r9JNzrJpgW//qiwxf0nWXUWGJSL3UQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@oxc-parser/binding-wasm32-wasi@0.127.0':
+ resolution: {integrity: sha512-T6KVD7rhLzFlwGRXMnxUFfkCZD8FHnb968wVXW1mXzgRFc5RNXOBY2mPPDZ77x5Ln76ltLMgtPg0cOkU1NSrEQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [wasm32]
+
+ '@oxc-parser/binding-win32-arm64-msvc@0.127.0':
+ resolution: {integrity: sha512-Ujvw4X+LD1CCGULcsQcvb4YNVoBGqt+JHgNNzGGaCImELiZLk477ifUH53gIbE7EKd933NdTi25JWEr9K2HwXw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [win32]
+
+ '@oxc-parser/binding-win32-ia32-msvc@0.127.0':
+ resolution: {integrity: sha512-0cwxKO7KHQQQfo4Uf4B2SQrhgm+cJaP9OvFFhx52Tkg4bezsacu83GB2/In5bC415Ueeym+kXdnge/57rbSfTw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [ia32]
+ os: [win32]
+
+ '@oxc-parser/binding-win32-x64-msvc@0.127.0':
+ resolution: {integrity: sha512-rOrnSQSCbhI2kowr9XxE7m9a8oQXnBHjnS6j95LxxAnEZ0+Fz20WlRXG4ondQb+ejjt2KOsa65sE6++L6kUd+w==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [win32]
+
+ '@oxc-project/types@0.127.0':
+ resolution: {integrity: sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==}
+
+ '@oxc-resolver/binding-android-arm-eabi@11.20.0':
+ resolution: {integrity: sha512-IjfWOXRgJFNdORDl+Uf1aibNgZY2guOD3zmOhx1BGVb/MIiqlFTdmjpQNplSN58lhWehnX4UNqC3QwpUo8pjJg==}
+ cpu: [arm]
+ os: [android]
+
+ '@oxc-resolver/binding-android-arm64@11.20.0':
+ resolution: {integrity: sha512-QqslZAuFQG8Q9xm7JuIn8JUbvywhSBMVhuQHtYW+auirZJloS41oxUUaBXk7uUhZJgp44c5zQLeVvmFaDQB+2Q==}
+ cpu: [arm64]
+ os: [android]
+
+ '@oxc-resolver/binding-darwin-arm64@11.20.0':
+ resolution: {integrity: sha512-MUcavykj2ewlR+kc5arpg4tC2RvzJkUxWtNv74pf7lcNk00GpIpN43vXMj+j6r4eMmfZhlb8hueKoIb8e9kAGQ==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@oxc-resolver/binding-darwin-x64@11.20.0':
+ resolution: {integrity: sha512-BGB16nRUK5Etiv//ihPyzj8Lj1px0mhh4YIfe0FDf045ywknfSm0GEbiRESpr6Q4K82AvnyaRIhhluHByvS4bg==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@oxc-resolver/binding-freebsd-x64@11.20.0':
+ resolution: {integrity: sha512-JZgtePaqj3qmD5XFHJaSLWzHRxQu0LaPkdoM1KJXYADvAaa83ijXHclV3ej3CueeW0wxfIAbGCZVP45J0CA7uQ==}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@oxc-resolver/binding-linux-arm-gnueabihf@11.20.0':
+ resolution: {integrity: sha512-hOQ/p3ry3v3SchUBXicrrnszaI/UmYzM4wtS4RGfwgVUX7a+HbyQSzJ5aOzu+o6XZkFkS3ZXN4PZAzhOb77OSg==}
+ cpu: [arm]
+ os: [linux]
+
+ '@oxc-resolver/binding-linux-arm-musleabihf@11.20.0':
+ resolution: {integrity: sha512-2ArPksaw0AqeuGBfoS715VF+JvJQAhD2niWgjE5hVO+L+nAfikVQopvngCMX9x4BD8itWoQ3dnikrQyl5Ho5Jg==}
+ cpu: [arm]
+ os: [linux]
+
+ '@oxc-resolver/binding-linux-arm64-gnu@11.20.0':
+ resolution: {integrity: sha512-0bJnmYFp62JdZ4nVMDUZ/C58BCZOCcqgKtnUlp7L9Ojf/czIN+3j72YlLPeWLkzlr6SlYvIQA4SGV/HyO0d+qg==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@oxc-resolver/binding-linux-arm64-musl@11.20.0':
+ resolution: {integrity: sha512-wKHHzPKZo7Ufhv/Bt6yxT7FOgnIgW4gwXcJUipkShGp68W3wGVqvr1Sr0fY65lN0Oy6y41+g2kIDvkgZaMMUkw==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@oxc-resolver/binding-linux-ppc64-gnu@11.20.0':
+ resolution: {integrity: sha512-RN8goF7Ie0B79L4i4G6OeBocTgSC56vJbQ65VJje+oXnldVpLnOU7j/AQ/dP94TcCS+Yh6WG8u3Qt4ETteXFNQ==}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@oxc-resolver/binding-linux-riscv64-gnu@11.20.0':
+ resolution: {integrity: sha512-5l1yU6/xQEqLZRzxqmMxJfWPslpwCmBsdDGaBvABPehxquCXDC7dd7oraNdKSJUMDXSM7VvVj8H2D2FTjU7oWw==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@oxc-resolver/binding-linux-riscv64-musl@11.20.0':
+ resolution: {integrity: sha512-xHEvkbgz6UC+A3JOyDQy76LkUaxsNSfIr3/GV8slwZsnuooJiIB34gzJfsyvR4JdCYNUUPsRJc/w/oWkODu+hg==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [musl]
+
+ '@oxc-resolver/binding-linux-s390x-gnu@11.20.0':
+ resolution: {integrity: sha512-aWPDUUmSeyHvlW+SoEUd+JIJsQhVhu6a5tBpDRMu058naPAchTgAVGCFy35zjbnFlt0i8hLWziff6HX0D3LU4g==}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@oxc-resolver/binding-linux-x64-gnu@11.20.0':
+ resolution: {integrity: sha512-x2YeSimvhJjKLVD8KSu8f/rqU1potcdEMkApIPJqjZWN7c2Fpt4g2X32WDg1p+XDAmyT7nuQGe0vnhvXeLbH+g==}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@oxc-resolver/binding-linux-x64-musl@11.20.0':
+ resolution: {integrity: sha512-kcRLEIxpZefeYfLChjpgFf3ilBzRDZ+yobMrpRsQlSrxuFGtm3U6PMU7AaEpMqo3NfDGVyJJseAjnRLzMFHjwQ==}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@oxc-resolver/binding-openharmony-arm64@11.20.0':
+ resolution: {integrity: sha512-HHcfnApSZGtKhTiHqe8OZruOZe5XuFQH5/E0Yhj3u8fnFvzkM4/k6WjacUf4SvA0SPEAbfbgYmVPuo0VX/fIBQ==}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@oxc-resolver/binding-wasm32-wasi@11.20.0':
+ resolution: {integrity: sha512-Tn0y1XOFYHNfK1wp1Z5QK8Rcld/bsOwRISQXfqAZ5IBpv8Gz1IvV39fUWNprqNdRizgcvFhOzWwFun2zkJsyBg==}
+ engines: {node: '>=14.0.0'}
+ cpu: [wasm32]
+
+ '@oxc-resolver/binding-win32-arm64-msvc@11.20.0':
+ resolution: {integrity: sha512-qPi25YNPe4YenS8MgsQU2+bIFHxxpLx1LVna2444cEHqNPhNjvWf9zqj4aWE43H9LpAsTmkkAlA3eL5ElBU3mA==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@oxc-resolver/binding-win32-x64-msvc@11.20.0':
+ resolution: {integrity: sha512-Wb14jWEW8huH6It9F6sXd9vrYmIS7pMrgkU6sxpLxkP+9z+wRgs71hUEhRpcn8FOXAFa27FVWfY2tRpbfTzfLw==}
+ cpu: [x64]
+ os: [win32]
+
+ '@pkgjs/parseargs@0.11.0':
+ resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
+ engines: {node: '>=14'}
+
+ '@polka/url@1.0.0-next.29':
+ resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==}
+
'@redocly/ajv@8.11.2':
resolution: {integrity: sha512-io1JpnwtIcvojV7QKDUSIuMN/ikdOUd1ReEnUnMKGfDVridQZ31J0MmIuqwuRjWDZfmvr+Q0MqCcfHM2gTivOg==}
@@ -692,6 +1029,15 @@ packages:
'@rolldown/pluginutils@1.0.0-beta.27':
resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==}
+ '@rollup/pluginutils@5.4.0':
+ resolution: {integrity: sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
+ peerDependenciesMeta:
+ rollup:
+ optional: true
+
'@rollup/rollup-android-arm-eabi@4.61.0':
resolution: {integrity: sha512-dnxczajOqt0gesZlN5pGQ1s1imQVrsmCw5G2Ci4oM+0WvNz3pyRnlWrT7McoZIb8VlFwCawdmbWRmxRn7HI+VQ==}
cpu: [arm]
@@ -837,6 +1183,125 @@ packages:
resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==}
engines: {node: '>=18'}
+ '@standard-schema/spec@1.1.0':
+ resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
+
+ '@storybook/addon-a11y@10.4.2':
+ resolution: {integrity: sha512-9Bm41peswHVPXm8iDBEA/sCXx+MUQV8Q10yFgNC2zTbtxKamMDb8HZCPIRDxvjBQ5v13eaXA2yZGTwQ+D8S6+g==}
+ peerDependencies:
+ storybook: ^10.4.2
+
+ '@storybook/addon-docs@10.4.2':
+ resolution: {integrity: sha512-CtW1O4xSKZPNtpWgpfp4yB/x4pj/of+3MvlEDfErSlr3Hp3QmEa2pCLaecR08H5LJqJFlt1PtG0UrIynTvgW9w==}
+ peerDependencies:
+ '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ storybook: ^10.4.2
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@storybook/addon-mcp@0.6.0':
+ resolution: {integrity: sha512-E79m2S7ik9wiF1AnI49fwbLQkrD03PicIZpCdeFhbbB19MF4tKFKyaQtbT3f6eaAP4EP2+COLDVLCQ7B3rGF4w==}
+ peerDependencies:
+ '@storybook/addon-vitest': ^0.0.0-0 || ^9.1.16 || ^10.0.0 || ^10.1.0-0 || ^10.2.0-0 || ^10.3.0-0 || ^10.4.0-0
+ storybook: ^0.0.0-0 || ^9.1.16 || ^10.0.0 || ^10.1.0-0 || ^10.2.0-0 || ^10.3.0-0 || ^10.4.0-0
+ peerDependenciesMeta:
+ '@storybook/addon-vitest':
+ optional: true
+
+ '@storybook/addon-vitest@10.4.2':
+ resolution: {integrity: sha512-gq1ZVr0IOLgiS2PzaJqHxKLczwrXvA5g3W2k/FVJA19fJNFNUut1IyQCQRSJTXLLXbnNaa8I0wjGGc2BoLarJg==}
+ peerDependencies:
+ '@vitest/browser': ^3.0.0 || ^4.0.0
+ '@vitest/browser-playwright': ^4.0.0
+ '@vitest/runner': ^3.0.0 || ^4.0.0
+ storybook: ^10.4.2
+ vitest: ^3.0.0 || ^4.0.0
+ peerDependenciesMeta:
+ '@vitest/browser':
+ optional: true
+ '@vitest/browser-playwright':
+ optional: true
+ '@vitest/runner':
+ optional: true
+ vitest:
+ optional: true
+
+ '@storybook/builder-vite@10.4.2':
+ resolution: {integrity: sha512-d3+i9vbbUfV6hvT90qabmy1WmC4bEJ7iAYDm0217doeA+S6awF25GF0qOy9gN9waU4NMntHoVpdB1YQO2wUj/w==}
+ peerDependencies:
+ storybook: ^10.4.2
+ vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0
+
+ '@storybook/csf-plugin@10.4.2':
+ resolution: {integrity: sha512-GqX/2DeF3/jKs5D7gpDiuT9gd0c/f2TKcnQ5av4/s3YqeN+0nhm7btkCrDfgF16uzE1Zj3OrkxvB3AOkfxWgDg==}
+ peerDependencies:
+ esbuild: '*'
+ rollup: '*'
+ storybook: ^10.4.2
+ vite: '*'
+ webpack: '*'
+ peerDependenciesMeta:
+ esbuild:
+ optional: true
+ rollup:
+ optional: true
+ vite:
+ optional: true
+ webpack:
+ optional: true
+
+ '@storybook/global@5.0.0':
+ resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==}
+
+ '@storybook/icons@2.0.2':
+ resolution: {integrity: sha512-KZBCpXsshAIjczYNXR/rlxEtCUX/eAbpFNwKi8bcOomrLA4t/SyPz5RF+lVPO2oZBUE4sAkt43mfJUevQDSEEw==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+
+ '@storybook/mcp@0.7.0':
+ resolution: {integrity: sha512-Pr4E61tM5e7aDzqgNOL/Ylw8CGdb+BIDGOf3vbmFfkR8ZnXjPxaV/vhTEsiXynnIpjQWCzySCxOU1icxZsgjrA==}
+
+ '@storybook/react-dom-shim@10.4.2':
+ resolution: {integrity: sha512-Eng3Yt2NCjPX94QcfyLeUFhrMj0hec2yU9J/qafBVbfj9XrFI8o+0ZwYJ7uXb9ECbvPN4y06dgt/2W/LiR417w==}
+ peerDependencies:
+ '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ '@types/react-dom': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ storybook: ^10.4.2
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@storybook/react-vite@10.4.2':
+ resolution: {integrity: sha512-nGrS74p0ujPSQ7qD5jKLLlao2igfTTb6Kf/uRhVV8XM0uM7WvxR9K20ddCM8jFmx1jY9fRm0UBGaeaXHDIh5SA==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ storybook: ^10.4.2
+ vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0
+
+ '@storybook/react@10.4.2':
+ resolution: {integrity: sha512-NfEH3CrdCAgUV4Z7SPN3Iw6nofcueqtRj8iHuo77GNjz0qSfuVi9iS7a8o7x7QFSeIBZwS0Jv3CgmhN8qvoLjg==}
+ peerDependencies:
+ '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ '@types/react-dom': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ storybook: ^10.4.2
+ typescript: '>= 4.9.x'
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ typescript:
+ optional: true
+
'@tailwindcss/node@4.3.0':
resolution: {integrity: sha512-aFb4gUhFOgdh9AXo4IzBEOzBkkAxm9VigwDJnMIYv3lcfXCJVesNfbEaBl4BNgVRyid92AmdviqwBUBRKSeY3g==}
@@ -968,9 +1433,32 @@ packages:
peerDependencies:
'@testing-library/dom': '>=7.21.4'
+ '@tmcp/adapter-valibot@0.1.6':
+ resolution: {integrity: sha512-drirZeNinhYLiRSMksN+m//u0ImFxtGRk1Vp425Xp/7CbBXFQdjAG+f7grssyHAukbVTGzmWsMMP6ejrGVErUA==}
+ peerDependencies:
+ tmcp: ^1.17.0
+ valibot: ^1.1.0
+
+ '@tmcp/session-manager@0.2.2':
+ resolution: {integrity: sha512-UrCRpTsxh5XnMbplspvftEYboiZWgAiXqqAUbyFTHoHMJ0LoNDy8bQd0+7qtxtT4S5Qsnv650gvs/Nbec5NTCQ==}
+ peerDependencies:
+ tmcp: ^1.16.3
+
+ '@tmcp/transport-http@0.8.6':
+ resolution: {integrity: sha512-iLcxu+tEMbkVHbhFfyXQhxfPDDTfm+F0kEw8Xg/a1rm29s4cBg1vwcpbtk02XTxsdDh8RJ1AZkQwF9WDGeb/IA==}
+ peerDependencies:
+ '@tmcp/auth': ^0.3.3 || ^0.4.0
+ tmcp: ^1.18.0
+ peerDependenciesMeta:
+ '@tmcp/auth':
+ optional: true
+
'@ts-morph/common@0.27.0':
resolution: {integrity: sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ==}
+ '@tybys/wasm-util@0.10.2':
+ resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==}
+
'@types/aria-query@5.0.4':
resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==}
@@ -992,6 +1480,9 @@ packages:
'@types/deep-eql@4.0.2':
resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
+ '@types/doctrine@0.0.9':
+ resolution: {integrity: sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==}
+
'@types/esrecurse@4.3.1':
resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==}
@@ -1001,6 +1492,9 @@ packages:
'@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
+ '@types/mdx@2.0.13':
+ resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==}
+
'@types/node@25.9.1':
resolution: {integrity: sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==}
@@ -1012,6 +1506,9 @@ packages:
'@types/react@19.2.16':
resolution: {integrity: sha512-esJiCAnl0kfpNdE69f3So4WJUXy95dLZydX0KwK46riIHDzHM7O9Vtf9xCHW0PXIqvgqNrswl522kA/5yx+F4w==}
+ '@types/resolve@1.20.6':
+ resolution: {integrity: sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==}
+
'@types/set-cookie-parser@2.4.10':
resolution: {integrity: sha512-GGmQVGpQWUe5qglJozEjZV/5dyxbOOZ0LHe/lqyWssB88Y4svNfst0uqBVscdDeIKl5Jy5+aPSvy7mI9tYRguw==}
@@ -1080,12 +1577,44 @@ packages:
resolution: {integrity: sha512-EbGRQg4FhrmwLodl+t3JNAnXHWVr9Vp+Zl1QBZVPY4ByfkzIT8cX3K6QWODHtkIZqqJVEWvhHSx3v5PDHsaQag==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ '@valibot/to-json-schema@1.7.0':
+ resolution: {integrity: sha512-Y3pPVibbIOHzohrlxSINvO7w/bvXkoYS3BQHoImV9ynE+bXKf171bdMucPurV2zp7gdmt0L1HCcNAsbo7cFRQw==}
+ peerDependencies:
+ valibot: ^1.4.0
+
'@vitejs/plugin-react@4.7.0':
resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==}
engines: {node: ^14.18.0 || >=16.0.0}
peerDependencies:
vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0
+ '@vitest/browser@3.2.6':
+ resolution: {integrity: sha512-CNjSynGBtAVOMTfQITv6Bc8da4/XTU1izorocbDStjUsynXcgx2FHVssh+10a8bKd/BxoqDdQtuSbYHfk302Wg==}
+ peerDependencies:
+ playwright: '*'
+ safaridriver: '*'
+ vitest: 3.2.6
+ webdriverio: ^7.0.0 || ^8.0.0 || ^9.0.0
+ peerDependenciesMeta:
+ playwright:
+ optional: true
+ safaridriver:
+ optional: true
+ webdriverio:
+ optional: true
+
+ '@vitest/coverage-v8@3.2.6':
+ resolution: {integrity: sha512-LsAdmUapA0qSN306d8+zOyawM0hFm2m2Hg9IwVNIKBm+qJV8cijiq2c+gxKZcB1HCfIWAy+0qEZDCUQA58A1cw==}
+ peerDependencies:
+ '@vitest/browser': 3.2.6
+ vitest: 3.2.6
+ peerDependenciesMeta:
+ '@vitest/browser':
+ optional: true
+
+ '@vitest/expect@3.2.4':
+ resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==}
+
'@vitest/expect@3.2.6':
resolution: {integrity: sha512-1+7q9BtaKzEmO+fmNT3kYvoNn5Y71XWAx2Q5HRim4tTVRQVRv4uJFAQ5FbK0OPUeNP/WmVCpxYxoJdvuHVjzBQ==}
@@ -1100,6 +1629,9 @@ packages:
vite:
optional: true
+ '@vitest/pretty-format@3.2.4':
+ resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==}
+
'@vitest/pretty-format@3.2.6':
resolution: {integrity: sha512-lb7XXXzmm2h2ASzFnRvQpDo6onT1NmMJA3tkGTWiBFtRJ9lxGY3d3mm/Apt36gej2bkkOVLL/yTOtufDaFa/jA==}
@@ -1109,12 +1641,21 @@ packages:
'@vitest/snapshot@3.2.6':
resolution: {integrity: sha512-H+ZjNTWGpObenh0YnlBctAPnJSI20P81PL8BPzWpx54YXLLTm8hEsWawtcYLMrwvpK48hGxLLbCS+1KRXhsKhw==}
+ '@vitest/spy@3.2.4':
+ resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==}
+
'@vitest/spy@3.2.6':
resolution: {integrity: sha512-oq6BbH68WzcWmwtBrU9nqLeaXTR4XwJF7FSLkKEZo4i6eoXcrxjcwSuTvWBIRUTC6VC72nXYunzqgZA+IKdtxg==}
+ '@vitest/utils@3.2.4':
+ resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==}
+
'@vitest/utils@3.2.6':
resolution: {integrity: sha512-lI23nIs4bnT3T8NIoh+vFaz5s2/DdP0Jgt2jxwgWljvwn82cLJtyi/If+fjFyoLMGIOz0U/fKvWE0d4jsNQEfg==}
+ '@webcontainer/env@1.1.1':
+ resolution: {integrity: sha512-6aN99yL695Hi9SuIk1oC88l9o0gmxL1nGWWQ/kNy81HigJ0FoaoTXpytCj6ItzgyCEwA9kF1wixsTuv5cjsgng==}
+
accepts@2.0.0:
resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==}
engines: {node: '>= 0.6'}
@@ -1167,6 +1708,10 @@ packages:
resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
engines: {node: '>=10'}
+ ansi-styles@6.2.3:
+ resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==}
+ engines: {node: '>=12'}
+
argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
@@ -1185,6 +1730,13 @@ packages:
resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==}
engines: {node: '>=4'}
+ ast-v8-to-istanbul@0.3.12:
+ resolution: {integrity: sha512-BRRC8VRZY2R4Z4lFIL35MwNXmwVqBityvOIwETtsCSwvjl0IdgFsy9NhdaA6j74nUdtJJlIypeRhpDam19Wq3g==}
+
+ axe-core@4.12.0:
+ resolution: {integrity: sha512-FTavr/7Ba0IptwGOPxnQvdyW2tAsdLBMTBXz7rKH6xJ2skpyxpBxyHkDdBs4lf69yRqYpkqCdfhnwS8YULGOmg==}
+ engines: {node: '>=4'}
+
balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
@@ -1259,6 +1811,21 @@ packages:
resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==}
engines: {node: '>= 16'}
+ chromatic@16.10.0:
+ resolution: {integrity: sha512-nFsztmnu7rFiGafUJgXvLUNpqmRylz92eNvzBoJNTKKQj4EQUyxznwnfpf1dTs7hXtWD8JwcH92jADydaHA1sw==}
+ hasBin: true
+ peerDependencies:
+ '@chromatic-com/cypress': ^0.*.* || ^1.0.0
+ '@chromatic-com/playwright': ^0.*.* || ^1.0.0
+ '@chromatic-com/vitest': ^0.*.* || ^1.0.0
+ peerDependenciesMeta:
+ '@chromatic-com/cypress':
+ optional: true
+ '@chromatic-com/playwright':
+ optional: true
+ '@chromatic-com/vitest':
+ optional: true
+
class-variance-authority@0.7.1:
resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==}
@@ -1429,6 +1996,10 @@ packages:
resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==}
engines: {node: '>=0.3.1'}
+ doctrine@3.0.0:
+ resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
+ engines: {node: '>=6.0.0'}
+
dom-accessibility-api@0.5.16:
resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==}
@@ -1443,6 +2014,9 @@ packages:
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
engines: {node: '>= 0.4'}
+ eastasianwidth@0.2.0:
+ resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
+
eciesjs@0.4.18:
resolution: {integrity: sha512-wG99Zcfcys9fZux7Cft8BAX/YrOJLJSZ3jyYPfhZHqN2E+Ffx+QXBDsv3gubEgPtV6dTzJMSQUwk1H98/t/0wQ==}
engines: {bun: '>=1', deno: '>=2', node: '>=16'}
@@ -1459,6 +2033,13 @@ packages:
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
+ emoji-regex@9.2.2:
+ resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
+
+ empathic@2.0.1:
+ resolution: {integrity: sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q==}
+ engines: {node: '>=14'}
+
encodeurl@2.0.0:
resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
engines: {node: '>= 0.8'}
@@ -1524,6 +2105,12 @@ packages:
peerDependencies:
eslint: ^9 || ^10
+ eslint-plugin-storybook@10.4.2:
+ resolution: {integrity: sha512-l3/vzLRmb8VSi3X1Bo6/Pa+64naw1jFsZE5jPPA4izvVdNhH1rF4rGuOC3kDTU926qKVBQtKua8D24XWQtvcGg==}
+ peerDependencies:
+ eslint: '>=8'
+ storybook: ^10.4.2
+
eslint-scope@9.1.2:
resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==}
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
@@ -1546,6 +2133,9 @@ packages:
jiti:
optional: true
+ esm-env@1.2.2:
+ resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==}
+
espree@11.2.0:
resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==}
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
@@ -1567,6 +2157,9 @@ packages:
resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
engines: {node: '>=4.0'}
+ estree-walker@2.0.2:
+ resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+
estree-walker@3.0.3:
resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
@@ -1676,6 +2269,10 @@ packages:
flatted@3.4.2:
resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==}
+ foreground-child@3.3.1:
+ resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
+ engines: {node: '>=14'}
+
formdata-polyfill@4.0.10:
resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
engines: {node: '>=12.20.0'}
@@ -1692,6 +2289,11 @@ packages:
resolution: {integrity: sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg==}
engines: {node: '>=14.14'}
+ fsevents@2.3.2:
+ resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@@ -1743,6 +2345,15 @@ packages:
resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
engines: {node: '>=10.13.0'}
+ glob@10.5.0:
+ resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==}
+ deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
+ hasBin: true
+
+ glob@13.0.6:
+ resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==}
+ engines: {node: 18 || 20 || >=22}
+
globals@17.6.0:
resolution: {integrity: sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA==}
engines: {node: '>=18'}
@@ -1758,6 +2369,10 @@ packages:
resolution: {integrity: sha512-cQOsSMS/IrDz82PVyRDvf/Q1F/bRbBVjJlh+xYOkI1qw2bWRvWGiWc+m2O0d6l4Bt1fyY+8kzJ8JFWGJqNeDBg==}
engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0}
+ has-flag@4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+
has-symbols@1.1.0:
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
engines: {node: '>= 0.4'}
@@ -1783,6 +2398,9 @@ packages:
resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==}
engines: {node: '>=18'}
+ html-escaper@2.0.2:
+ resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
+
html-parse-stringify@3.0.1:
resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==}
@@ -1860,6 +2478,10 @@ packages:
is-arrayish@0.2.1:
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
+ is-core-module@2.16.2:
+ resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==}
+ engines: {node: '>= 0.4'}
+
is-docker@3.0.0:
resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@@ -1942,6 +2564,25 @@ packages:
resolution: {integrity: sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==}
engines: {node: '>=18'}
+ istanbul-lib-coverage@3.2.2:
+ resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==}
+ engines: {node: '>=8'}
+
+ istanbul-lib-report@3.0.1:
+ resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==}
+ engines: {node: '>=10'}
+
+ istanbul-lib-source-maps@5.0.6:
+ resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==}
+ engines: {node: '>=10'}
+
+ istanbul-reports@3.2.0:
+ resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==}
+ engines: {node: '>=8'}
+
+ jackspeak@3.4.3:
+ resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
+
jiti@2.7.0:
resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==}
hasBin: true
@@ -1953,6 +2594,9 @@ packages:
resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==}
engines: {node: '>=0.10.0'}
+ js-tokens@10.0.0:
+ resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==}
+
js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
@@ -1987,6 +2631,9 @@ packages:
json-parse-even-better-errors@2.3.1:
resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
+ json-rpc-2.0@1.7.1:
+ resolution: {integrity: sha512-JqZjhjAanbpkXIzFE7u8mE/iFblawwlXtONaCvRqI+pyABVz7B4M1EUNpyVW+dZjqgQ2L5HFmZCmOCgUKm00hg==}
+
json-schema-traverse@0.4.1:
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
@@ -2113,6 +2760,10 @@ packages:
lru-cache@10.4.3:
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
+ lru-cache@11.5.1:
+ resolution: {integrity: sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==}
+ engines: {node: 20 || >=22}
+
lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
@@ -2128,6 +2779,13 @@ packages:
magic-string@0.30.21:
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
+ magicast@0.3.5:
+ resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==}
+
+ make-dir@4.0.0:
+ resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==}
+ engines: {node: '>=10'}
+
math-intrinsics@1.1.0:
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
engines: {node: '>= 0.4'}
@@ -2179,12 +2837,29 @@ packages:
resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==}
engines: {node: '>=10'}
+ minimatch@9.0.9:
+ resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+ minipass@7.1.3:
+ resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ mrmime@2.0.1:
+ resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==}
+ engines: {node: '>=10'}
+
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+ msw-storybook-addon@2.0.7:
+ resolution: {integrity: sha512-TGmlxXy2TsaB6QcClVKRxqvay5f93xoLguHOihRFQ+gIEIyiyvcoQjkEeuOe7Y9qvddzGB1LyFomzPo9/EpnuQ==}
+ peerDependencies:
+ msw: ^2.0.0
+
msw@2.14.6:
resolution: {integrity: sha512-ALe+N10S72cyx94cMcy3Zs4HhXCj35sgeAL4c+WTvKi0zWnbd8/h0lcFqv0mb2P+aSgAdD7p9HzvA0DiUPxsyg==}
engines: {node: '>=18'}
@@ -2262,6 +2937,10 @@ packages:
resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==}
engines: {node: '>=18'}
+ open@10.2.0:
+ resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==}
+ engines: {node: '>=18'}
+
open@11.0.0:
resolution: {integrity: sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw==}
engines: {node: '>=20'}
@@ -2289,6 +2968,13 @@ packages:
outvariant@1.4.3:
resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==}
+ oxc-parser@0.127.0:
+ resolution: {integrity: sha512-bkgD4qHlN7WxLdX8bLXdaU54TtQtAIg/ZBAfm0aje/mo3MRDo3P0hZSgr4U7O3xfX+fQmR5AP04JS/TGcZLcFA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+
+ oxc-resolver@11.20.0:
+ resolution: {integrity: sha512-CblytBiV/a/ZXY34dsVU2NxhIOxMXst8CvDCtyBelVITgd7PLrKzbEbA6oKLdPjvDKDzCiW48qzmzZ+mYaqn+g==}
+
p-limit@3.1.0:
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
engines: {node: '>=10'}
@@ -2297,6 +2983,9 @@ packages:
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
engines: {node: '>=10'}
+ package-json-from-dist@1.0.1:
+ resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
+
parent-module@1.0.1:
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
engines: {node: '>=6'}
@@ -2335,6 +3024,17 @@ packages:
resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==}
engines: {node: '>=12'}
+ path-parse@1.0.7:
+ resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+
+ path-scurry@1.11.1:
+ resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
+ engines: {node: '>=16 || 14 >=14.18'}
+
+ path-scurry@2.0.2:
+ resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==}
+ engines: {node: 18 || 20 || >=22}
+
path-to-regexp@6.3.0:
resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==}
@@ -2359,10 +3059,23 @@ packages:
resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==}
engines: {node: '>=12'}
+ picoquery@2.5.0:
+ resolution: {integrity: sha512-j1kgOFxtaCyoFCkpoYG2Oj3OdGakadO7HZ7o5CqyRazlmBekKhbDoUnNnXASE07xSY4nDImWZkrZv7toSxMi/g==}
+
pkce-challenge@5.0.1:
resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==}
engines: {node: '>=16.20.0'}
+ playwright-core@1.60.0:
+ resolution: {integrity: sha512-9bW6zvX/m0lEbgTKJ6YppOKx8H3VOPBMOCFh2irXFOT4BbHgrx5hPjwJYLT40Lu+4qtD36qKc/Hn56StUW57IA==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ playwright@1.60.0:
+ resolution: {integrity: sha512-hheHdokM8cdqCb0lcE3s+zT4t4W+vvjpGxsZlDnikarzx8tSzMebh3UiFtgqwFwnTnjYQcsyMF8ei2mCO/tpeA==}
+ engines: {node: '>=18'}
+ hasBin: true
+
pluralize@8.0.0:
resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==}
engines: {node: '>=4'}
@@ -2418,6 +3131,15 @@ packages:
resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==}
engines: {node: '>= 0.10'}
+ react-docgen-typescript@2.4.0:
+ resolution: {integrity: sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg==}
+ peerDependencies:
+ typescript: '>= 4.3.x'
+
+ react-docgen@8.0.3:
+ resolution: {integrity: sha512-aEZ9qP+/M+58x2qgfSFEWH1BxLyHe5+qkLNJOZQb5iGS017jpbRnoKhNRrXPeA6RfBrZO5wZrT9DMC1UqE1f1w==}
+ engines: {node: ^20.9.0 || >=22}
+
react-dom@19.2.7:
resolution: {integrity: sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==}
peerDependencies:
@@ -2496,6 +3218,11 @@ packages:
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
engines: {node: '>=4'}
+ resolve@1.22.12:
+ resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==}
+ engines: {node: '>= 0.4'}
+ hasBin: true
+
restore-cursor@5.1.0:
resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==}
engines: {node: '>=18'}
@@ -2600,6 +3327,10 @@ packages:
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
engines: {node: '>=14'}
+ sirv@3.0.2:
+ resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==}
+ engines: {node: '>=18'}
+
sisteransi@1.0.5:
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
@@ -2611,6 +3342,9 @@ packages:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
+ sqids@0.3.0:
+ resolution: {integrity: sha512-lOQK1ucVg+W6n3FhRwwSeUijxe93b51Bfz5PMRMihVf1iVkl82ePQG7V5vwrhzB11v0NtsR25PSZRGiSomJaJw==}
+
stackback@0.0.2:
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
@@ -2625,6 +3359,21 @@ packages:
resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==}
engines: {node: '>=18'}
+ storybook@10.4.2:
+ resolution: {integrity: sha512-5Ax5vbHxFgMBGGhQDm75Rrumm/HZC4ICFhMcJaM0UlqnC/4FKj/IaZtImZFupknyiiyUEcWHPQFA2kX3/VSv1A==}
+ hasBin: true
+ peerDependencies:
+ '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ prettier: ^2 || ^3
+ vite-plus: ^0.1.15
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ prettier:
+ optional: true
+ vite-plus:
+ optional: true
+
strict-event-emitter@0.5.1:
resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==}
@@ -2632,6 +3381,10 @@ packages:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
+ string-width@5.1.2:
+ resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
+ engines: {node: '>=12'}
+
string-width@7.2.0:
resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==}
engines: {node: '>=18'}
@@ -2664,6 +3417,10 @@ packages:
resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==}
engines: {node: '>=8'}
+ strip-indent@4.1.1:
+ resolution: {integrity: sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==}
+ engines: {node: '>=12'}
+
strip-literal@3.1.0:
resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==}
@@ -2671,6 +3428,14 @@ packages:
resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==}
engines: {node: '>=18'}
+ supports-color@7.2.0:
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+ engines: {node: '>=8'}
+
+ supports-preserve-symlinks-flag@1.0.0:
+ resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
+ engines: {node: '>= 0.4'}
+
symbol-tree@3.2.4:
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
@@ -2688,6 +3453,10 @@ packages:
resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==}
engines: {node: '>=6'}
+ test-exclude@7.0.2:
+ resolution: {integrity: sha512-u9E6A+ZDYdp7a4WnarkXPZOx8Ilz46+kby6p1yZ8zsGTz9gYa6FIS7lj2oezzNKmtdyyJNNmmXDppga5GB7kSw==}
+ engines: {node: '>=18'}
+
tiny-invariant@1.3.3:
resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==}
@@ -2727,6 +3496,9 @@ packages:
resolution: {integrity: sha512-kCwffuaH8ntKtygnWe1b4BJKWiCUH30n5KfoTr6IchcXOwR7chAOFJxFrH3vjANafUYrIA4a7SDL+nn7SiR4Sw==}
hasBin: true
+ tmcp@1.19.4:
+ resolution: {integrity: sha512-fMoUJ3Gef9iA0yKZNeW2SQCCKTluCwghUyOz/qxPS8XxrQk6Jlw4lgql3S+s6L//FteLeSJ7erKxMWl727mZoQ==}
+
to-regex-range@5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
@@ -2735,6 +3507,10 @@ packages:
resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
engines: {node: '>=0.6'}
+ totalist@3.0.1:
+ resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
+ engines: {node: '>=6'}
+
tough-cookie@5.1.2:
resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==}
engines: {node: '>=16'}
@@ -2753,6 +3529,10 @@ packages:
peerDependencies:
typescript: '>=4.8.4'
+ ts-dedent@2.2.0:
+ resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==}
+ engines: {node: '>=6.10'}
+
ts-morph@26.0.0:
resolution: {integrity: sha512-ztMO++owQnz8c/gIENcM9XfCEzgoGphTv+nKpYNM1bgsdOVC/jRZuEBf6N+mLLDNg68Kl+GgUZfOySaRiG1/Ug==}
@@ -2809,6 +3589,10 @@ packages:
resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
engines: {node: '>= 0.8'}
+ unplugin@2.3.11:
+ resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==}
+ engines: {node: '>=18.12.0'}
+
until-async@3.0.2:
resolution: {integrity: sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw==}
@@ -2824,6 +3608,9 @@ packages:
uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+ uri-template-matcher@1.1.2:
+ resolution: {integrity: sha512-uZc1h12jdO3m/R77SfTEOuo6VbMhgWznaawKpBjRGSJb7i91x5PgI37NQJtG+Cerxkk0yr1pylBY2qG1kQ+aEQ==}
+
use-sync-external-store@1.6.0:
resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==}
peerDependencies:
@@ -2832,6 +3619,14 @@ packages:
util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
+ valibot@1.2.0:
+ resolution: {integrity: sha512-mm1rxUsmOxzrwnX5arGS+U4T25RdvpPjPN4yR0u9pUBov9+zGVtO84tif1eY4r6zWxVxu3KzIyknJy3rxfRZZg==}
+ peerDependencies:
+ typescript: '>=5'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
validate-npm-package-name@7.0.2:
resolution: {integrity: sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A==}
engines: {node: ^20.17.0 || >=22.9.0}
@@ -2929,6 +3724,9 @@ packages:
resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==}
engines: {node: '>=12'}
+ webpack-virtual-modules@0.6.2:
+ resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==}
+
whatwg-encoding@3.1.1:
resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==}
engines: {node: '>=18'}
@@ -2965,6 +3763,10 @@ packages:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
engines: {node: '>=10'}
+ wrap-ansi@8.1.0:
+ resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
+ engines: {node: '>=12'}
+
wrappy@1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
@@ -2980,6 +3782,10 @@ packages:
utf-8-validate:
optional: true
+ wsl-utils@0.1.0:
+ resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==}
+ engines: {node: '>=18'}
+
wsl-utils@0.3.1:
resolution: {integrity: sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==}
engines: {node: '>=20'}
@@ -3039,6 +3845,11 @@ snapshots:
'@adobe/css-tools@4.5.0': {}
+ '@ampproject/remapping@2.3.0':
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.13
+ '@jridgewell/trace-mapping': 0.3.31
+
'@asamuzakjp/css-color@3.2.0':
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)
@@ -3268,6 +4079,20 @@ snapshots:
optionalDependencies:
'@types/react': 19.2.16
+ '@bcoe/v8-coverage@1.0.2': {}
+
+ '@chromatic-com/storybook@5.2.1(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))':
+ dependencies:
+ '@neoconfetti/react': 1.0.0
+ chromatic: 16.10.0
+ jsonfile: 6.2.1
+ storybook: 10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ strip-ansi: 7.2.0
+ transitivePeerDependencies:
+ - '@chromatic-com/cypress'
+ - '@chromatic-com/playwright'
+ - '@chromatic-com/vitest'
+
'@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)':
@@ -3306,6 +4131,33 @@ snapshots:
dependencies:
'@noble/ciphers': 1.3.0
+ '@emnapi/core@1.10.0':
+ dependencies:
+ '@emnapi/wasi-threads': 1.2.1
+ tslib: 2.8.1
+ optional: true
+
+ '@emnapi/core@1.9.2':
+ dependencies:
+ '@emnapi/wasi-threads': 1.2.1
+ tslib: 2.8.1
+ optional: true
+
+ '@emnapi/runtime@1.10.0':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
+ '@emnapi/runtime@1.9.2':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
+ '@emnapi/wasi-threads@1.2.1':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
'@esbuild/aix-ppc64@0.25.12':
optional: true
@@ -3484,6 +4336,25 @@ snapshots:
optionalDependencies:
'@types/node': 25.9.1
+ '@isaacs/cliui@8.0.2':
+ dependencies:
+ string-width: 5.1.2
+ string-width-cjs: string-width@4.2.3
+ strip-ansi: 7.2.0
+ strip-ansi-cjs: strip-ansi@6.0.1
+ wrap-ansi: 8.1.0
+ wrap-ansi-cjs: wrap-ansi@7.0.0
+
+ '@istanbuljs/schema@0.1.6': {}
+
+ '@joshwooding/vite-plugin-react-docgen-typescript@0.7.0(typescript@5.8.3)(vite@6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0))':
+ dependencies:
+ glob: 13.0.6
+ react-docgen-typescript: 2.4.0(typescript@5.8.3)
+ vite: 6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0)
+ optionalDependencies:
+ typescript: 5.8.3
+
'@jridgewell/gen-mapping@0.3.13':
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
@@ -3503,6 +4374,12 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.5
+ '@mdx-js/react@3.1.1(@types/react@19.2.16)(react@19.2.7)':
+ dependencies:
+ '@types/mdx': 2.0.13
+ '@types/react': 19.2.16
+ react: 19.2.7
+
'@modelcontextprotocol/sdk@1.29.0(zod@3.25.76)':
dependencies:
'@hono/node-server': 1.19.14(hono@4.12.23)
@@ -3534,6 +4411,22 @@ snapshots:
outvariant: 1.4.3
strict-event-emitter: 0.5.1
+ '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)':
+ dependencies:
+ '@emnapi/core': 1.10.0
+ '@emnapi/runtime': 1.10.0
+ '@tybys/wasm-util': 0.10.2
+ optional: true
+
+ '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)':
+ dependencies:
+ '@emnapi/core': 1.9.2
+ '@emnapi/runtime': 1.9.2
+ '@tybys/wasm-util': 0.10.2
+ optional: true
+
+ '@neoconfetti/react@1.0.0': {}
+
'@noble/ciphers@1.3.0': {}
'@noble/curves@1.9.7':
@@ -3565,6 +4458,138 @@ snapshots:
'@open-draft/until@2.1.0': {}
+ '@oxc-parser/binding-android-arm-eabi@0.127.0':
+ optional: true
+
+ '@oxc-parser/binding-android-arm64@0.127.0':
+ optional: true
+
+ '@oxc-parser/binding-darwin-arm64@0.127.0':
+ optional: true
+
+ '@oxc-parser/binding-darwin-x64@0.127.0':
+ optional: true
+
+ '@oxc-parser/binding-freebsd-x64@0.127.0':
+ optional: true
+
+ '@oxc-parser/binding-linux-arm-gnueabihf@0.127.0':
+ optional: true
+
+ '@oxc-parser/binding-linux-arm-musleabihf@0.127.0':
+ optional: true
+
+ '@oxc-parser/binding-linux-arm64-gnu@0.127.0':
+ optional: true
+
+ '@oxc-parser/binding-linux-arm64-musl@0.127.0':
+ optional: true
+
+ '@oxc-parser/binding-linux-ppc64-gnu@0.127.0':
+ optional: true
+
+ '@oxc-parser/binding-linux-riscv64-gnu@0.127.0':
+ optional: true
+
+ '@oxc-parser/binding-linux-riscv64-musl@0.127.0':
+ optional: true
+
+ '@oxc-parser/binding-linux-s390x-gnu@0.127.0':
+ optional: true
+
+ '@oxc-parser/binding-linux-x64-gnu@0.127.0':
+ optional: true
+
+ '@oxc-parser/binding-linux-x64-musl@0.127.0':
+ optional: true
+
+ '@oxc-parser/binding-openharmony-arm64@0.127.0':
+ optional: true
+
+ '@oxc-parser/binding-wasm32-wasi@0.127.0':
+ dependencies:
+ '@emnapi/core': 1.9.2
+ '@emnapi/runtime': 1.9.2
+ '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)
+ optional: true
+
+ '@oxc-parser/binding-win32-arm64-msvc@0.127.0':
+ optional: true
+
+ '@oxc-parser/binding-win32-ia32-msvc@0.127.0':
+ optional: true
+
+ '@oxc-parser/binding-win32-x64-msvc@0.127.0':
+ optional: true
+
+ '@oxc-project/types@0.127.0': {}
+
+ '@oxc-resolver/binding-android-arm-eabi@11.20.0':
+ optional: true
+
+ '@oxc-resolver/binding-android-arm64@11.20.0':
+ optional: true
+
+ '@oxc-resolver/binding-darwin-arm64@11.20.0':
+ optional: true
+
+ '@oxc-resolver/binding-darwin-x64@11.20.0':
+ optional: true
+
+ '@oxc-resolver/binding-freebsd-x64@11.20.0':
+ optional: true
+
+ '@oxc-resolver/binding-linux-arm-gnueabihf@11.20.0':
+ optional: true
+
+ '@oxc-resolver/binding-linux-arm-musleabihf@11.20.0':
+ optional: true
+
+ '@oxc-resolver/binding-linux-arm64-gnu@11.20.0':
+ optional: true
+
+ '@oxc-resolver/binding-linux-arm64-musl@11.20.0':
+ optional: true
+
+ '@oxc-resolver/binding-linux-ppc64-gnu@11.20.0':
+ optional: true
+
+ '@oxc-resolver/binding-linux-riscv64-gnu@11.20.0':
+ optional: true
+
+ '@oxc-resolver/binding-linux-riscv64-musl@11.20.0':
+ optional: true
+
+ '@oxc-resolver/binding-linux-s390x-gnu@11.20.0':
+ optional: true
+
+ '@oxc-resolver/binding-linux-x64-gnu@11.20.0':
+ optional: true
+
+ '@oxc-resolver/binding-linux-x64-musl@11.20.0':
+ optional: true
+
+ '@oxc-resolver/binding-openharmony-arm64@11.20.0':
+ optional: true
+
+ '@oxc-resolver/binding-wasm32-wasi@11.20.0':
+ dependencies:
+ '@emnapi/core': 1.10.0
+ '@emnapi/runtime': 1.10.0
+ '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)
+ optional: true
+
+ '@oxc-resolver/binding-win32-arm64-msvc@11.20.0':
+ optional: true
+
+ '@oxc-resolver/binding-win32-x64-msvc@11.20.0':
+ optional: true
+
+ '@pkgjs/parseargs@0.11.0':
+ optional: true
+
+ '@polka/url@1.0.0-next.29': {}
+
'@redocly/ajv@8.11.2':
dependencies:
fast-deep-equal: 3.1.3
@@ -3590,6 +4615,14 @@ snapshots:
'@rolldown/pluginutils@1.0.0-beta.27': {}
+ '@rollup/pluginutils@5.4.0(rollup@4.61.0)':
+ dependencies:
+ '@types/estree': 1.0.9
+ estree-walker: 2.0.2
+ picomatch: 4.0.4
+ optionalDependencies:
+ rollup: 4.61.0
+
'@rollup/rollup-android-arm-eabi@4.61.0':
optional: true
@@ -3669,6 +4702,147 @@ snapshots:
'@sindresorhus/merge-streams@4.0.0': {}
+ '@standard-schema/spec@1.1.0': {}
+
+ '@storybook/addon-a11y@10.4.2(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))':
+ dependencies:
+ '@storybook/global': 5.0.0
+ axe-core: 4.12.0
+ storybook: 10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+
+ '@storybook/addon-docs@10.4.2(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(esbuild@0.25.12)(rollup@4.61.0)(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0))':
+ dependencies:
+ '@mdx-js/react': 3.1.1(@types/react@19.2.16)(react@19.2.7)
+ '@storybook/csf-plugin': 10.4.2(esbuild@0.25.12)(rollup@4.61.0)(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0))
+ '@storybook/icons': 2.0.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ '@storybook/react-dom-shim': 10.4.2(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))
+ react: 19.2.7
+ react-dom: 19.2.7(react@19.2.7)
+ storybook: 10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ ts-dedent: 2.2.0
+ optionalDependencies:
+ '@types/react': 19.2.16
+ transitivePeerDependencies:
+ - '@types/react-dom'
+ - esbuild
+ - rollup
+ - vite
+ - webpack
+
+ '@storybook/addon-mcp@0.6.0(@storybook/addon-vitest@10.4.2(@vitest/browser@3.2.6)(@vitest/runner@3.2.6)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vitest@3.2.6))(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(typescript@5.8.3)':
+ dependencies:
+ '@storybook/mcp': 0.7.0(typescript@5.8.3)
+ '@tmcp/adapter-valibot': 0.1.6(tmcp@1.19.4(typescript@5.8.3))(valibot@1.2.0(typescript@5.8.3))
+ '@tmcp/transport-http': 0.8.6(tmcp@1.19.4(typescript@5.8.3))
+ picoquery: 2.5.0
+ storybook: 10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ tmcp: 1.19.4(typescript@5.8.3)
+ valibot: 1.2.0(typescript@5.8.3)
+ optionalDependencies:
+ '@storybook/addon-vitest': 10.4.2(@vitest/browser@3.2.6)(@vitest/runner@3.2.6)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vitest@3.2.6)
+ transitivePeerDependencies:
+ - '@tmcp/auth'
+ - typescript
+
+ '@storybook/addon-vitest@10.4.2(@vitest/browser@3.2.6)(@vitest/runner@3.2.6)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vitest@3.2.6)':
+ dependencies:
+ '@storybook/global': 5.0.0
+ '@storybook/icons': 2.0.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ storybook: 10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ optionalDependencies:
+ '@vitest/browser': 3.2.6(msw@2.14.6(@types/node@25.9.1)(typescript@5.8.3))(playwright@1.60.0)(vite@6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0))(vitest@3.2.6)
+ '@vitest/runner': 3.2.6
+ vitest: 3.2.6(@types/node@25.9.1)(@vitest/browser@3.2.6)(jiti@2.7.0)(jsdom@26.1.0)(lightningcss@1.32.0)(msw@2.14.6(@types/node@25.9.1)(typescript@5.8.3))
+ transitivePeerDependencies:
+ - react
+ - react-dom
+
+ '@storybook/builder-vite@10.4.2(esbuild@0.25.12)(rollup@4.61.0)(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0))':
+ dependencies:
+ '@storybook/csf-plugin': 10.4.2(esbuild@0.25.12)(rollup@4.61.0)(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0))
+ storybook: 10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ ts-dedent: 2.2.0
+ vite: 6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0)
+ transitivePeerDependencies:
+ - esbuild
+ - rollup
+ - webpack
+
+ '@storybook/csf-plugin@10.4.2(esbuild@0.25.12)(rollup@4.61.0)(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0))':
+ dependencies:
+ storybook: 10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ unplugin: 2.3.11
+ optionalDependencies:
+ esbuild: 0.25.12
+ rollup: 4.61.0
+ vite: 6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0)
+
+ '@storybook/global@5.0.0': {}
+
+ '@storybook/icons@2.0.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7)':
+ dependencies:
+ react: 19.2.7
+ react-dom: 19.2.7(react@19.2.7)
+
+ '@storybook/mcp@0.7.0(typescript@5.8.3)':
+ dependencies:
+ '@tmcp/adapter-valibot': 0.1.6(tmcp@1.19.4(typescript@5.8.3))(valibot@1.2.0(typescript@5.8.3))
+ '@tmcp/transport-http': 0.8.6(tmcp@1.19.4(typescript@5.8.3))
+ tmcp: 1.19.4(typescript@5.8.3)
+ valibot: 1.2.0(typescript@5.8.3)
+ transitivePeerDependencies:
+ - '@tmcp/auth'
+ - typescript
+
+ '@storybook/react-dom-shim@10.4.2(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))':
+ dependencies:
+ react: 19.2.7
+ react-dom: 19.2.7(react@19.2.7)
+ storybook: 10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ optionalDependencies:
+ '@types/react': 19.2.16
+ '@types/react-dom': 19.2.3(@types/react@19.2.16)
+
+ '@storybook/react-vite@10.4.2(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(esbuild@0.25.12)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rollup@4.61.0)(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(typescript@5.8.3)(vite@6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0))':
+ dependencies:
+ '@joshwooding/vite-plugin-react-docgen-typescript': 0.7.0(typescript@5.8.3)(vite@6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0))
+ '@rollup/pluginutils': 5.4.0(rollup@4.61.0)
+ '@storybook/builder-vite': 10.4.2(esbuild@0.25.12)(rollup@4.61.0)(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0))
+ '@storybook/react': 10.4.2(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(typescript@5.8.3)
+ empathic: 2.0.1
+ magic-string: 0.30.21
+ react: 19.2.7
+ react-docgen: 8.0.3
+ react-dom: 19.2.7(react@19.2.7)
+ resolve: 1.22.12
+ storybook: 10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ tsconfig-paths: 4.2.0
+ vite: 6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0)
+ transitivePeerDependencies:
+ - '@types/react'
+ - '@types/react-dom'
+ - esbuild
+ - rollup
+ - supports-color
+ - typescript
+ - webpack
+
+ '@storybook/react@10.4.2(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(typescript@5.8.3)':
+ dependencies:
+ '@storybook/global': 5.0.0
+ '@storybook/react-dom-shim': 10.4.2(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))
+ react: 19.2.7
+ react-docgen: 8.0.3
+ react-docgen-typescript: 2.4.0(typescript@5.8.3)
+ react-dom: 19.2.7(react@19.2.7)
+ storybook: 10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ optionalDependencies:
+ '@types/react': 19.2.16
+ '@types/react-dom': 19.2.3(@types/react@19.2.16)
+ typescript: 5.8.3
+ transitivePeerDependencies:
+ - supports-color
+
'@tailwindcss/node@4.3.0':
dependencies:
'@jridgewell/remapping': 2.3.5
@@ -3778,12 +4952,34 @@ snapshots:
dependencies:
'@testing-library/dom': 10.4.1
+ '@tmcp/adapter-valibot@0.1.6(tmcp@1.19.4(typescript@5.8.3))(valibot@1.2.0(typescript@5.8.3))':
+ dependencies:
+ '@standard-schema/spec': 1.1.0
+ '@valibot/to-json-schema': 1.7.0(valibot@1.2.0(typescript@5.8.3))
+ tmcp: 1.19.4(typescript@5.8.3)
+ valibot: 1.2.0(typescript@5.8.3)
+
+ '@tmcp/session-manager@0.2.2(tmcp@1.19.4(typescript@5.8.3))':
+ dependencies:
+ tmcp: 1.19.4(typescript@5.8.3)
+
+ '@tmcp/transport-http@0.8.6(tmcp@1.19.4(typescript@5.8.3))':
+ dependencies:
+ '@tmcp/session-manager': 0.2.2(tmcp@1.19.4(typescript@5.8.3))
+ esm-env: 1.2.2
+ tmcp: 1.19.4(typescript@5.8.3)
+
'@ts-morph/common@0.27.0':
dependencies:
fast-glob: 3.3.3
minimatch: 10.2.5
path-browserify: 1.0.1
+ '@tybys/wasm-util@0.10.2':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
'@types/aria-query@5.0.4': {}
'@types/babel__core@7.20.5':
@@ -3814,12 +5010,16 @@ snapshots:
'@types/deep-eql@4.0.2': {}
+ '@types/doctrine@0.0.9': {}
+
'@types/esrecurse@4.3.1': {}
'@types/estree@1.0.9': {}
'@types/json-schema@7.0.15': {}
+ '@types/mdx@2.0.13': {}
+
'@types/node@25.9.1':
dependencies:
undici-types: 7.24.6
@@ -3832,6 +5032,8 @@ snapshots:
dependencies:
csstype: 3.2.3
+ '@types/resolve@1.20.6': {}
+
'@types/set-cookie-parser@2.4.10':
dependencies:
'@types/node': 25.9.1
@@ -3931,6 +5133,10 @@ snapshots:
'@typescript-eslint/types': 8.60.1
eslint-visitor-keys: 5.0.1
+ '@valibot/to-json-schema@1.7.0(valibot@1.2.0(typescript@5.8.3))':
+ dependencies:
+ valibot: 1.2.0(typescript@5.8.3)
+
'@vitejs/plugin-react@4.7.0(vite@6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0))':
dependencies:
'@babel/core': 7.29.7
@@ -3943,6 +5149,54 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ '@vitest/browser@3.2.6(msw@2.14.6(@types/node@25.9.1)(typescript@5.8.3))(playwright@1.60.0)(vite@6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0))(vitest@3.2.6)':
+ dependencies:
+ '@testing-library/dom': 10.4.1
+ '@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.1)
+ '@vitest/mocker': 3.2.6(msw@2.14.6(@types/node@25.9.1)(typescript@5.8.3))(vite@6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0))
+ '@vitest/utils': 3.2.6
+ magic-string: 0.30.21
+ sirv: 3.0.2
+ tinyrainbow: 2.0.0
+ vitest: 3.2.6(@types/node@25.9.1)(@vitest/browser@3.2.6)(jiti@2.7.0)(jsdom@26.1.0)(lightningcss@1.32.0)(msw@2.14.6(@types/node@25.9.1)(typescript@5.8.3))
+ ws: 8.21.0
+ optionalDependencies:
+ playwright: 1.60.0
+ transitivePeerDependencies:
+ - bufferutil
+ - msw
+ - utf-8-validate
+ - vite
+
+ '@vitest/coverage-v8@3.2.6(@vitest/browser@3.2.6)(vitest@3.2.6)':
+ dependencies:
+ '@ampproject/remapping': 2.3.0
+ '@bcoe/v8-coverage': 1.0.2
+ ast-v8-to-istanbul: 0.3.12
+ debug: 4.4.3(supports-color@10.2.2)
+ istanbul-lib-coverage: 3.2.2
+ istanbul-lib-report: 3.0.1
+ istanbul-lib-source-maps: 5.0.6
+ istanbul-reports: 3.2.0
+ magic-string: 0.30.21
+ magicast: 0.3.5
+ std-env: 3.10.0
+ test-exclude: 7.0.2
+ tinyrainbow: 2.0.0
+ vitest: 3.2.6(@types/node@25.9.1)(@vitest/browser@3.2.6)(jiti@2.7.0)(jsdom@26.1.0)(lightningcss@1.32.0)(msw@2.14.6(@types/node@25.9.1)(typescript@5.8.3))
+ optionalDependencies:
+ '@vitest/browser': 3.2.6(msw@2.14.6(@types/node@25.9.1)(typescript@5.8.3))(playwright@1.60.0)(vite@6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0))(vitest@3.2.6)
+ transitivePeerDependencies:
+ - supports-color
+
+ '@vitest/expect@3.2.4':
+ dependencies:
+ '@types/chai': 5.2.3
+ '@vitest/spy': 3.2.4
+ '@vitest/utils': 3.2.4
+ chai: 5.3.3
+ tinyrainbow: 2.0.0
+
'@vitest/expect@3.2.6':
dependencies:
'@types/chai': 5.2.3
@@ -3960,6 +5214,10 @@ snapshots:
msw: 2.14.6(@types/node@25.9.1)(typescript@5.8.3)
vite: 6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0)
+ '@vitest/pretty-format@3.2.4':
+ dependencies:
+ tinyrainbow: 2.0.0
+
'@vitest/pretty-format@3.2.6':
dependencies:
tinyrainbow: 2.0.0
@@ -3976,16 +5234,28 @@ snapshots:
magic-string: 0.30.21
pathe: 2.0.3
+ '@vitest/spy@3.2.4':
+ dependencies:
+ tinyspy: 4.0.4
+
'@vitest/spy@3.2.6':
dependencies:
tinyspy: 4.0.4
+ '@vitest/utils@3.2.4':
+ dependencies:
+ '@vitest/pretty-format': 3.2.4
+ loupe: 3.2.1
+ tinyrainbow: 2.0.0
+
'@vitest/utils@3.2.6':
dependencies:
'@vitest/pretty-format': 3.2.6
loupe: 3.2.1
tinyrainbow: 2.0.0
+ '@webcontainer/env@1.1.1': {}
+
accepts@2.0.0:
dependencies:
mime-types: 3.0.2
@@ -4029,6 +5299,8 @@ snapshots:
ansi-styles@5.2.0: {}
+ ansi-styles@6.2.3: {}
+
argparse@2.0.1: {}
aria-query@5.3.0:
@@ -4043,6 +5315,14 @@ snapshots:
dependencies:
tslib: 2.8.1
+ ast-v8-to-istanbul@0.3.12:
+ dependencies:
+ '@jridgewell/trace-mapping': 0.3.31
+ estree-walker: 3.0.3
+ js-tokens: 10.0.0
+
+ axe-core@4.12.0: {}
+
balanced-match@1.0.2: {}
balanced-match@4.0.4: {}
@@ -4119,6 +5399,10 @@ snapshots:
check-error@2.1.3: {}
+ chromatic@16.10.0:
+ dependencies:
+ semver: 7.8.1
+
class-variance-authority@0.7.1:
dependencies:
clsx: 2.1.1
@@ -4238,6 +5522,10 @@ snapshots:
diff@8.0.4: {}
+ doctrine@3.0.0:
+ dependencies:
+ esutils: 2.0.3
+
dom-accessibility-api@0.5.16: {}
dom-accessibility-api@0.6.3: {}
@@ -4250,6 +5538,8 @@ snapshots:
es-errors: 1.3.0
gopd: 1.2.0
+ eastasianwidth@0.2.0: {}
+
eciesjs@0.4.18:
dependencies:
'@ecies/ciphers': 0.2.6(@noble/ciphers@1.3.0)
@@ -4265,6 +5555,10 @@ snapshots:
emoji-regex@8.0.0: {}
+ emoji-regex@9.2.2: {}
+
+ empathic@2.0.1: {}
+
encodeurl@2.0.0: {}
enhanced-resolve@5.22.1:
@@ -4345,6 +5639,15 @@ snapshots:
dependencies:
eslint: 10.4.1(jiti@2.7.0)
+ eslint-plugin-storybook@10.4.2(eslint@10.4.1(jiti@2.7.0))(storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(typescript@5.8.3):
+ dependencies:
+ '@typescript-eslint/utils': 8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@5.8.3)
+ eslint: 10.4.1(jiti@2.7.0)
+ storybook: 10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
+
eslint-scope@9.1.2:
dependencies:
'@types/esrecurse': 4.3.1
@@ -4393,6 +5696,8 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ esm-env@1.2.2: {}
+
espree@11.2.0:
dependencies:
acorn: 8.16.0
@@ -4411,6 +5716,8 @@ snapshots:
estraverse@5.3.0: {}
+ estree-walker@2.0.2: {}
+
estree-walker@3.0.3:
dependencies:
'@types/estree': 1.0.9
@@ -4566,6 +5873,11 @@ snapshots:
flatted@3.4.2: {}
+ foreground-child@3.3.1:
+ dependencies:
+ cross-spawn: 7.0.6
+ signal-exit: 4.1.0
+
formdata-polyfill@4.0.10:
dependencies:
fetch-blob: 3.2.0
@@ -4580,6 +5892,9 @@ snapshots:
jsonfile: 6.2.1
universalify: 2.0.1
+ fsevents@2.3.2:
+ optional: true
+
fsevents@2.3.3:
optional: true
@@ -4628,6 +5943,21 @@ snapshots:
dependencies:
is-glob: 4.0.3
+ glob@10.5.0:
+ dependencies:
+ foreground-child: 3.3.1
+ jackspeak: 3.4.3
+ minimatch: 9.0.9
+ minipass: 7.1.3
+ package-json-from-dist: 1.0.1
+ path-scurry: 1.11.1
+
+ glob@13.0.6:
+ dependencies:
+ minimatch: 10.2.5
+ minipass: 7.1.3
+ path-scurry: 2.0.2
+
globals@17.6.0: {}
gopd@1.2.0: {}
@@ -4636,6 +5966,8 @@ snapshots:
graphql@16.14.1: {}
+ has-flag@4.0.0: {}
+
has-symbols@1.1.0: {}
hasown@2.0.4:
@@ -4659,6 +5991,8 @@ snapshots:
dependencies:
whatwg-encoding: 3.1.1
+ html-escaper@2.0.2: {}
+
html-parse-stringify@3.0.1:
dependencies:
void-elements: 3.1.0
@@ -4724,6 +6058,10 @@ snapshots:
is-arrayish@0.2.1: {}
+ is-core-module@2.16.2:
+ dependencies:
+ hasown: 2.0.4
+
is-docker@3.0.0: {}
is-extglob@2.1.1: {}
@@ -4772,12 +6110,41 @@ snapshots:
isexe@3.1.5: {}
+ istanbul-lib-coverage@3.2.2: {}
+
+ istanbul-lib-report@3.0.1:
+ dependencies:
+ istanbul-lib-coverage: 3.2.2
+ make-dir: 4.0.0
+ supports-color: 7.2.0
+
+ istanbul-lib-source-maps@5.0.6:
+ dependencies:
+ '@jridgewell/trace-mapping': 0.3.31
+ debug: 4.4.3(supports-color@10.2.2)
+ istanbul-lib-coverage: 3.2.2
+ transitivePeerDependencies:
+ - supports-color
+
+ istanbul-reports@3.2.0:
+ dependencies:
+ html-escaper: 2.0.2
+ istanbul-lib-report: 3.0.1
+
+ jackspeak@3.4.3:
+ dependencies:
+ '@isaacs/cliui': 8.0.2
+ optionalDependencies:
+ '@pkgjs/parseargs': 0.11.0
+
jiti@2.7.0: {}
jose@6.2.3: {}
js-levenshtein@1.1.6: {}
+ js-tokens@10.0.0: {}
+
js-tokens@4.0.0: {}
js-tokens@9.0.1: {}
@@ -4823,6 +6190,8 @@ snapshots:
json-parse-even-better-errors@2.3.1: {}
+ json-rpc-2.0@1.7.1: {}
+
json-schema-traverse@0.4.1: {}
json-schema-traverse@1.0.0: {}
@@ -4916,6 +6285,8 @@ snapshots:
lru-cache@10.4.3: {}
+ lru-cache@11.5.1: {}
+
lru-cache@5.1.1:
dependencies:
yallist: 3.1.1
@@ -4930,6 +6301,16 @@ snapshots:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
+ magicast@0.3.5:
+ dependencies:
+ '@babel/parser': 7.29.7
+ '@babel/types': 7.29.7
+ source-map-js: 1.2.1
+
+ make-dir@4.0.0:
+ dependencies:
+ semver: 7.8.1
+
math-intrinsics@1.1.0: {}
media-typer@1.1.0: {}
@@ -4965,10 +6346,23 @@ snapshots:
dependencies:
brace-expansion: 2.1.1
+ minimatch@9.0.9:
+ dependencies:
+ brace-expansion: 2.1.1
+
minimist@1.2.8: {}
+ minipass@7.1.3: {}
+
+ mrmime@2.0.1: {}
+
ms@2.1.3: {}
+ msw-storybook-addon@2.0.7(msw@2.14.6(@types/node@25.9.1)(typescript@5.8.3)):
+ dependencies:
+ is-node-process: 1.2.0
+ msw: 2.14.6(@types/node@25.9.1)(typescript@5.8.3)
+
msw@2.14.6(@types/node@25.9.1)(typescript@5.8.3):
dependencies:
'@inquirer/confirm': 6.1.1(@types/node@25.9.1)
@@ -5045,6 +6439,13 @@ snapshots:
dependencies:
mimic-function: 5.0.1
+ open@10.2.0:
+ dependencies:
+ default-browser: 5.5.0
+ define-lazy-prop: 3.0.0
+ is-inside-container: 1.0.0
+ wsl-utils: 0.1.0
+
open@11.0.0:
dependencies:
default-browser: 5.5.0
@@ -5093,6 +6494,53 @@ snapshots:
outvariant@1.4.3: {}
+ oxc-parser@0.127.0:
+ dependencies:
+ '@oxc-project/types': 0.127.0
+ optionalDependencies:
+ '@oxc-parser/binding-android-arm-eabi': 0.127.0
+ '@oxc-parser/binding-android-arm64': 0.127.0
+ '@oxc-parser/binding-darwin-arm64': 0.127.0
+ '@oxc-parser/binding-darwin-x64': 0.127.0
+ '@oxc-parser/binding-freebsd-x64': 0.127.0
+ '@oxc-parser/binding-linux-arm-gnueabihf': 0.127.0
+ '@oxc-parser/binding-linux-arm-musleabihf': 0.127.0
+ '@oxc-parser/binding-linux-arm64-gnu': 0.127.0
+ '@oxc-parser/binding-linux-arm64-musl': 0.127.0
+ '@oxc-parser/binding-linux-ppc64-gnu': 0.127.0
+ '@oxc-parser/binding-linux-riscv64-gnu': 0.127.0
+ '@oxc-parser/binding-linux-riscv64-musl': 0.127.0
+ '@oxc-parser/binding-linux-s390x-gnu': 0.127.0
+ '@oxc-parser/binding-linux-x64-gnu': 0.127.0
+ '@oxc-parser/binding-linux-x64-musl': 0.127.0
+ '@oxc-parser/binding-openharmony-arm64': 0.127.0
+ '@oxc-parser/binding-wasm32-wasi': 0.127.0
+ '@oxc-parser/binding-win32-arm64-msvc': 0.127.0
+ '@oxc-parser/binding-win32-ia32-msvc': 0.127.0
+ '@oxc-parser/binding-win32-x64-msvc': 0.127.0
+
+ oxc-resolver@11.20.0:
+ optionalDependencies:
+ '@oxc-resolver/binding-android-arm-eabi': 11.20.0
+ '@oxc-resolver/binding-android-arm64': 11.20.0
+ '@oxc-resolver/binding-darwin-arm64': 11.20.0
+ '@oxc-resolver/binding-darwin-x64': 11.20.0
+ '@oxc-resolver/binding-freebsd-x64': 11.20.0
+ '@oxc-resolver/binding-linux-arm-gnueabihf': 11.20.0
+ '@oxc-resolver/binding-linux-arm-musleabihf': 11.20.0
+ '@oxc-resolver/binding-linux-arm64-gnu': 11.20.0
+ '@oxc-resolver/binding-linux-arm64-musl': 11.20.0
+ '@oxc-resolver/binding-linux-ppc64-gnu': 11.20.0
+ '@oxc-resolver/binding-linux-riscv64-gnu': 11.20.0
+ '@oxc-resolver/binding-linux-riscv64-musl': 11.20.0
+ '@oxc-resolver/binding-linux-s390x-gnu': 11.20.0
+ '@oxc-resolver/binding-linux-x64-gnu': 11.20.0
+ '@oxc-resolver/binding-linux-x64-musl': 11.20.0
+ '@oxc-resolver/binding-openharmony-arm64': 11.20.0
+ '@oxc-resolver/binding-wasm32-wasi': 11.20.0
+ '@oxc-resolver/binding-win32-arm64-msvc': 11.20.0
+ '@oxc-resolver/binding-win32-x64-msvc': 11.20.0
+
p-limit@3.1.0:
dependencies:
yocto-queue: 0.1.0
@@ -5101,6 +6549,8 @@ snapshots:
dependencies:
p-limit: 3.1.0
+ package-json-from-dist@1.0.1: {}
+
parent-module@1.0.1:
dependencies:
callsites: 3.1.0
@@ -5134,6 +6584,18 @@ snapshots:
path-key@4.0.0: {}
+ path-parse@1.0.7: {}
+
+ path-scurry@1.11.1:
+ dependencies:
+ lru-cache: 10.4.3
+ minipass: 7.1.3
+
+ path-scurry@2.0.2:
+ dependencies:
+ lru-cache: 11.5.1
+ minipass: 7.1.3
+
path-to-regexp@6.3.0: {}
path-to-regexp@8.4.2: {}
@@ -5148,8 +6610,18 @@ snapshots:
picomatch@4.0.4: {}
+ picoquery@2.5.0: {}
+
pkce-challenge@5.0.1: {}
+ playwright-core@1.60.0: {}
+
+ playwright@1.60.0:
+ dependencies:
+ playwright-core: 1.60.0
+ optionalDependencies:
+ fsevents: 2.3.2
+
pluralize@8.0.0: {}
postcss-selector-parser@7.1.1:
@@ -5204,6 +6676,25 @@ snapshots:
iconv-lite: 0.7.2
unpipe: 1.0.0
+ react-docgen-typescript@2.4.0(typescript@5.8.3):
+ dependencies:
+ typescript: 5.8.3
+
+ react-docgen@8.0.3:
+ dependencies:
+ '@babel/core': 7.29.7
+ '@babel/traverse': 7.29.7
+ '@babel/types': 7.29.7
+ '@types/babel__core': 7.20.5
+ '@types/babel__traverse': 7.28.0
+ '@types/doctrine': 0.0.9
+ '@types/resolve': 1.20.6
+ doctrine: 3.0.0
+ resolve: 1.22.12
+ strip-indent: 4.1.1
+ transitivePeerDependencies:
+ - supports-color
+
react-dom@19.2.7(react@19.2.7):
dependencies:
react: 19.2.7
@@ -5265,6 +6756,13 @@ snapshots:
resolve-from@4.0.0: {}
+ resolve@1.22.12:
+ dependencies:
+ es-errors: 1.3.0
+ is-core-module: 2.16.2
+ path-parse: 1.0.7
+ supports-preserve-symlinks-flag: 1.0.0
+
restore-cursor@5.1.0:
dependencies:
onetime: 7.0.0
@@ -5449,12 +6947,20 @@ snapshots:
signal-exit@4.1.0: {}
+ sirv@3.0.2:
+ dependencies:
+ '@polka/url': 1.0.0-next.29
+ mrmime: 2.0.1
+ totalist: 3.0.1
+
sisteransi@1.0.5: {}
source-map-js@1.2.1: {}
source-map@0.6.1: {}
+ sqids@0.3.0: {}
+
stackback@0.0.2: {}
statuses@2.0.2: {}
@@ -5463,6 +6969,32 @@ snapshots:
stdin-discarder@0.2.2: {}
+ storybook@10.4.2(@testing-library/dom@10.4.1)(@types/react@19.2.16)(react-dom@19.2.7(react@19.2.7))(react@19.2.7):
+ dependencies:
+ '@storybook/global': 5.0.0
+ '@storybook/icons': 2.0.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ '@testing-library/jest-dom': 6.9.1
+ '@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.1)
+ '@vitest/expect': 3.2.4
+ '@vitest/spy': 3.2.4
+ '@webcontainer/env': 1.1.1
+ esbuild: 0.25.12
+ open: 10.2.0
+ oxc-parser: 0.127.0
+ oxc-resolver: 11.20.0
+ recast: 0.23.11
+ semver: 7.8.1
+ use-sync-external-store: 1.6.0(react@19.2.7)
+ ws: 8.21.0
+ optionalDependencies:
+ '@types/react': 19.2.16
+ transitivePeerDependencies:
+ - '@testing-library/dom'
+ - bufferutil
+ - react
+ - react-dom
+ - utf-8-validate
+
strict-event-emitter@0.5.1: {}
string-width@4.2.3:
@@ -5471,6 +7003,12 @@ snapshots:
is-fullwidth-code-point: 3.0.0
strip-ansi: 6.0.1
+ string-width@5.1.2:
+ dependencies:
+ eastasianwidth: 0.2.0
+ emoji-regex: 9.2.2
+ strip-ansi: 7.2.0
+
string-width@7.2.0:
dependencies:
emoji-regex: 10.6.0
@@ -5501,12 +7039,20 @@ snapshots:
dependencies:
min-indent: 1.0.1
+ strip-indent@4.1.1: {}
+
strip-literal@3.1.0:
dependencies:
js-tokens: 9.0.1
supports-color@10.2.2: {}
+ supports-color@7.2.0:
+ dependencies:
+ has-flag: 4.0.0
+
+ supports-preserve-symlinks-flag@1.0.0: {}
+
symbol-tree@3.2.4: {}
tagged-tag@1.0.0: {}
@@ -5517,6 +7063,12 @@ snapshots:
tapable@2.3.3: {}
+ test-exclude@7.0.2:
+ dependencies:
+ '@istanbuljs/schema': 0.1.6
+ glob: 10.5.0
+ minimatch: 10.2.5
+
tiny-invariant@1.3.3: {}
tinybench@2.9.0: {}
@@ -5546,12 +7098,24 @@ snapshots:
dependencies:
tldts-core: 7.4.2
+ tmcp@1.19.4(typescript@5.8.3):
+ dependencies:
+ '@standard-schema/spec': 1.1.0
+ json-rpc-2.0: 1.7.1
+ sqids: 0.3.0
+ uri-template-matcher: 1.1.2
+ valibot: 1.2.0(typescript@5.8.3)
+ transitivePeerDependencies:
+ - typescript
+
to-regex-range@5.0.1:
dependencies:
is-number: 7.0.0
toidentifier@1.0.1: {}
+ totalist@3.0.1: {}
+
tough-cookie@5.1.2:
dependencies:
tldts: 6.1.86
@@ -5568,6 +7132,8 @@ snapshots:
dependencies:
typescript: 5.8.3
+ ts-dedent@2.2.0: {}
+
ts-morph@26.0.0:
dependencies:
'@ts-morph/common': 0.27.0
@@ -5620,6 +7186,13 @@ snapshots:
unpipe@1.0.0: {}
+ unplugin@2.3.11:
+ dependencies:
+ '@jridgewell/remapping': 2.3.5
+ acorn: 8.16.0
+ picomatch: 4.0.4
+ webpack-virtual-modules: 0.6.2
+
until-async@3.0.2: {}
update-browserslist-db@1.2.3(browserslist@4.28.2):
@@ -5634,12 +7207,18 @@ snapshots:
dependencies:
punycode: 2.3.1
+ uri-template-matcher@1.1.2: {}
+
use-sync-external-store@1.6.0(react@19.2.7):
dependencies:
react: 19.2.7
util-deprecate@1.0.2: {}
+ valibot@1.2.0(typescript@5.8.3):
+ optionalDependencies:
+ typescript: 5.8.3
+
validate-npm-package-name@7.0.2: {}
vary@1.1.2: {}
@@ -5679,7 +7258,7 @@ snapshots:
jiti: 2.7.0
lightningcss: 1.32.0
- vitest@3.2.6(@types/node@25.9.1)(jiti@2.7.0)(jsdom@26.1.0)(lightningcss@1.32.0)(msw@2.14.6(@types/node@25.9.1)(typescript@5.8.3)):
+ vitest@3.2.6(@types/node@25.9.1)(@vitest/browser@3.2.6)(jiti@2.7.0)(jsdom@26.1.0)(lightningcss@1.32.0)(msw@2.14.6(@types/node@25.9.1)(typescript@5.8.3)):
dependencies:
'@types/chai': 5.2.3
'@vitest/expect': 3.2.6
@@ -5706,6 +7285,7 @@ snapshots:
why-is-node-running: 2.3.0
optionalDependencies:
'@types/node': 25.9.1
+ '@vitest/browser': 3.2.6(msw@2.14.6(@types/node@25.9.1)(typescript@5.8.3))(playwright@1.60.0)(vite@6.4.3(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0))(vitest@3.2.6)
jsdom: 26.1.0
transitivePeerDependencies:
- jiti
@@ -5731,6 +7311,8 @@ snapshots:
webidl-conversions@7.0.0: {}
+ webpack-virtual-modules@0.6.2: {}
+
whatwg-encoding@3.1.1:
dependencies:
iconv-lite: 0.6.3
@@ -5763,10 +7345,20 @@ snapshots:
string-width: 4.2.3
strip-ansi: 6.0.1
+ wrap-ansi@8.1.0:
+ dependencies:
+ ansi-styles: 6.2.3
+ string-width: 5.1.2
+ strip-ansi: 7.2.0
+
wrappy@1.0.2: {}
ws@8.21.0: {}
+ wsl-utils@0.1.0:
+ dependencies:
+ is-wsl: 3.1.1
+
wsl-utils@0.3.1:
dependencies:
is-wsl: 3.1.1
diff --git a/web/public/mockServiceWorker.js b/web/public/mockServiceWorker.js
new file mode 100644
index 0000000..33dde9e
--- /dev/null
+++ b/web/public/mockServiceWorker.js
@@ -0,0 +1,349 @@
+/* eslint-disable */
+/* tslint:disable */
+
+/**
+ * Mock Service Worker.
+ * @see https://github.com/mswjs/msw
+ * - Please do NOT modify this file.
+ */
+
+const PACKAGE_VERSION = '2.14.6'
+const INTEGRITY_CHECKSUM = '4db4a41e972cec1b64cc569c66952d82'
+const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
+const activeClientIds = new Set()
+
+addEventListener('install', function () {
+ self.skipWaiting()
+})
+
+addEventListener('activate', function (event) {
+ event.waitUntil(self.clients.claim())
+})
+
+addEventListener('message', async function (event) {
+ const clientId = Reflect.get(event.source || {}, 'id')
+
+ if (!clientId || !self.clients) {
+ return
+ }
+
+ const client = await self.clients.get(clientId)
+
+ if (!client) {
+ return
+ }
+
+ const allClients = await self.clients.matchAll({
+ type: 'window',
+ })
+
+ switch (event.data) {
+ case 'KEEPALIVE_REQUEST': {
+ sendToClient(client, {
+ type: 'KEEPALIVE_RESPONSE',
+ })
+ break
+ }
+
+ case 'INTEGRITY_CHECK_REQUEST': {
+ sendToClient(client, {
+ type: 'INTEGRITY_CHECK_RESPONSE',
+ payload: {
+ packageVersion: PACKAGE_VERSION,
+ checksum: INTEGRITY_CHECKSUM,
+ },
+ })
+ break
+ }
+
+ case 'MOCK_ACTIVATE': {
+ activeClientIds.add(clientId)
+
+ sendToClient(client, {
+ type: 'MOCKING_ENABLED',
+ payload: {
+ client: {
+ id: client.id,
+ frameType: client.frameType,
+ },
+ },
+ })
+ break
+ }
+
+ case 'CLIENT_CLOSED': {
+ activeClientIds.delete(clientId)
+
+ const remainingClients = allClients.filter((client) => {
+ return client.id !== clientId
+ })
+
+ // Unregister itself when there are no more clients
+ if (remainingClients.length === 0) {
+ self.registration.unregister()
+ }
+
+ break
+ }
+ }
+})
+
+addEventListener('fetch', function (event) {
+ const requestInterceptedAt = Date.now()
+
+ // Bypass navigation requests.
+ if (event.request.mode === 'navigate') {
+ return
+ }
+
+ // Opening the DevTools triggers the "only-if-cached" request
+ // that cannot be handled by the worker. Bypass such requests.
+ if (
+ event.request.cache === 'only-if-cached' &&
+ event.request.mode !== 'same-origin'
+ ) {
+ return
+ }
+
+ // Bypass all requests when there are no active clients.
+ // Prevents the self-unregistered worked from handling requests
+ // after it's been terminated (still remains active until the next reload).
+ if (activeClientIds.size === 0) {
+ return
+ }
+
+ const requestId = crypto.randomUUID()
+ event.respondWith(handleRequest(event, requestId, requestInterceptedAt))
+})
+
+/**
+ * @param {FetchEvent} event
+ * @param {string} requestId
+ * @param {number} requestInterceptedAt
+ */
+async function handleRequest(event, requestId, requestInterceptedAt) {
+ const client = await resolveMainClient(event)
+ const requestCloneForEvents = event.request.clone()
+ const response = await getResponse(
+ event,
+ client,
+ requestId,
+ requestInterceptedAt,
+ )
+
+ // Send back the response clone for the "response:*" life-cycle events.
+ // Ensure MSW is active and ready to handle the message, otherwise
+ // this message will pend indefinitely.
+ if (client && activeClientIds.has(client.id)) {
+ const serializedRequest = await serializeRequest(requestCloneForEvents)
+
+ // Clone the response so both the client and the library could consume it.
+ const responseClone = response.clone()
+
+ sendToClient(
+ client,
+ {
+ type: 'RESPONSE',
+ payload: {
+ isMockedResponse: IS_MOCKED_RESPONSE in response,
+ request: {
+ id: requestId,
+ ...serializedRequest,
+ },
+ response: {
+ type: responseClone.type,
+ status: responseClone.status,
+ statusText: responseClone.statusText,
+ headers: Object.fromEntries(responseClone.headers.entries()),
+ body: responseClone.body,
+ },
+ },
+ },
+ responseClone.body ? [serializedRequest.body, responseClone.body] : [],
+ )
+ }
+
+ return response
+}
+
+/**
+ * Resolve the main client for the given event.
+ * Client that issues a request doesn't necessarily equal the client
+ * that registered the worker. It's with the latter the worker should
+ * communicate with during the response resolving phase.
+ * @param {FetchEvent} event
+ * @returns {Promise}
+ */
+async function resolveMainClient(event) {
+ const client = await self.clients.get(event.clientId)
+
+ if (activeClientIds.has(event.clientId)) {
+ return client
+ }
+
+ if (client?.frameType === 'top-level') {
+ return client
+ }
+
+ const allClients = await self.clients.matchAll({
+ type: 'window',
+ })
+
+ return allClients
+ .filter((client) => {
+ // Get only those clients that are currently visible.
+ return client.visibilityState === 'visible'
+ })
+ .find((client) => {
+ // Find the client ID that's recorded in the
+ // set of clients that have registered the worker.
+ return activeClientIds.has(client.id)
+ })
+}
+
+/**
+ * @param {FetchEvent} event
+ * @param {Client | undefined} client
+ * @param {string} requestId
+ * @param {number} requestInterceptedAt
+ * @returns {Promise}
+ */
+async function getResponse(event, client, requestId, requestInterceptedAt) {
+ // Clone the request because it might've been already used
+ // (i.e. its body has been read and sent to the client).
+ const requestClone = event.request.clone()
+
+ function passthrough() {
+ // Cast the request headers to a new Headers instance
+ // so the headers can be manipulated with.
+ const headers = new Headers(requestClone.headers)
+
+ // Remove the "accept" header value that marked this request as passthrough.
+ // This prevents request alteration and also keeps it compliant with the
+ // user-defined CORS policies.
+ const acceptHeader = headers.get('accept')
+ if (acceptHeader) {
+ const values = acceptHeader.split(',').map((value) => value.trim())
+ const filteredValues = values.filter(
+ (value) => value !== 'msw/passthrough',
+ )
+
+ if (filteredValues.length > 0) {
+ headers.set('accept', filteredValues.join(', '))
+ } else {
+ headers.delete('accept')
+ }
+ }
+
+ return fetch(requestClone, { headers })
+ }
+
+ // Bypass mocking when the client is not active.
+ if (!client) {
+ return passthrough()
+ }
+
+ // Bypass initial page load requests (i.e. static assets).
+ // The absence of the immediate/parent client in the map of the active clients
+ // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet
+ // and is not ready to handle requests.
+ if (!activeClientIds.has(client.id)) {
+ return passthrough()
+ }
+
+ // Notify the client that a request has been intercepted.
+ const serializedRequest = await serializeRequest(event.request)
+ const clientMessage = await sendToClient(
+ client,
+ {
+ type: 'REQUEST',
+ payload: {
+ id: requestId,
+ interceptedAt: requestInterceptedAt,
+ ...serializedRequest,
+ },
+ },
+ [serializedRequest.body],
+ )
+
+ switch (clientMessage.type) {
+ case 'MOCK_RESPONSE': {
+ return respondWithMock(clientMessage.data)
+ }
+
+ case 'PASSTHROUGH': {
+ return passthrough()
+ }
+ }
+
+ return passthrough()
+}
+
+/**
+ * @param {Client} client
+ * @param {any} message
+ * @param {Array} transferrables
+ * @returns {Promise}
+ */
+function sendToClient(client, message, transferrables = []) {
+ return new Promise((resolve, reject) => {
+ const channel = new MessageChannel()
+
+ channel.port1.onmessage = (event) => {
+ if (event.data && event.data.error) {
+ return reject(event.data.error)
+ }
+
+ resolve(event.data)
+ }
+
+ client.postMessage(message, [
+ channel.port2,
+ ...transferrables.filter(Boolean),
+ ])
+ })
+}
+
+/**
+ * @param {Response} response
+ * @returns {Response}
+ */
+function respondWithMock(response) {
+ // Setting response status code to 0 is a no-op.
+ // However, when responding with a "Response.error()", the produced Response
+ // instance will have status code set to 0. Since it's not possible to create
+ // a Response instance with status code 0, handle that use-case separately.
+ if (response.status === 0) {
+ return Response.error()
+ }
+
+ const mockedResponse = new Response(response.body, response)
+
+ Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, {
+ value: true,
+ enumerable: true,
+ })
+
+ return mockedResponse
+}
+
+/**
+ * @param {Request} request
+ */
+async function serializeRequest(request) {
+ return {
+ url: request.url,
+ mode: request.mode,
+ method: request.method,
+ headers: Object.fromEntries(request.headers.entries()),
+ cache: request.cache,
+ credentials: request.credentials,
+ destination: request.destination,
+ integrity: request.integrity,
+ redirect: request.redirect,
+ referrer: request.referrer,
+ referrerPolicy: request.referrerPolicy,
+ body: await request.arrayBuffer(),
+ keepalive: request.keepalive,
+ }
+}
diff --git a/web/src/components/label-editor.stories.tsx b/web/src/components/label-editor.stories.tsx
new file mode 100644
index 0000000..ef83d97
--- /dev/null
+++ b/web/src/components/label-editor.stories.tsx
@@ -0,0 +1,46 @@
+import type { Meta, StoryObj } from '@storybook/react-vite'
+import { useState } from 'react'
+import { expect } from 'storybook/test'
+
+import type { components } from '../api/schema'
+import { LabelEditor } from './label-editor'
+
+type LabelInput = components['schemas']['LabelInput']
+
+// LabelEditor is controlled — drive it from local state so typing is reflected.
+function ControlledLabelEditor({ value: initial }: { value: LabelInput[] }) {
+ const [value, setValue] = useState(initial)
+
+ return
+}
+
+const meta = {
+ component: LabelEditor,
+ render: (args) => ,
+ args: { value: [], onChange: () => {} },
+ tags: ['ai-generated'],
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Empty: Story = {
+ play: async ({ canvas }) => {
+ await expect(canvas.getByLabelText('Label')).toHaveValue('')
+ },
+}
+
+export const Prefilled: Story = {
+ args: { value: [{ lang: 'en', label: 'Bronze' }] },
+ play: async ({ canvas }) => {
+ await expect(canvas.getByLabelText('Label')).toHaveValue('Bronze')
+ },
+}
+
+export const Editing: Story = {
+ play: async ({ canvas, userEvent }) => {
+ const input = canvas.getByLabelText('Label')
+ await userEvent.type(input, 'Ceramic')
+ await expect(input).toHaveValue('Ceramic')
+ },
+}
diff --git a/web/src/components/ui/badge.stories.tsx b/web/src/components/ui/badge.stories.tsx
new file mode 100644
index 0000000..e8676a8
--- /dev/null
+++ b/web/src/components/ui/badge.stories.tsx
@@ -0,0 +1,32 @@
+import type { Meta, StoryObj } from '@storybook/react-vite'
+import { expect } from 'storybook/test'
+
+import { Badge } from './badge'
+
+const meta = {
+ component: Badge,
+ tags: ['ai-generated'],
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Default: Story = {
+ args: { children: 'Public' },
+ play: async ({ canvas }) => {
+ const badge = canvas.getByText('Public')
+ await expect(badge).toHaveAttribute('data-slot', 'badge')
+ },
+}
+
+export const Secondary: Story = {
+ args: { variant: 'secondary', children: 'Internal' },
+}
+
+export const Destructive: Story = {
+ args: { variant: 'destructive', children: 'Error' },
+}
+
+export const Outline: Story = {
+ args: { variant: 'outline', children: 'Draft' },
+}
diff --git a/web/src/components/ui/button.stories.tsx b/web/src/components/ui/button.stories.tsx
new file mode 100644
index 0000000..0de94dd
--- /dev/null
+++ b/web/src/components/ui/button.stories.tsx
@@ -0,0 +1,35 @@
+import type { Meta, StoryObj } from '@storybook/react-vite'
+import { expect } from 'storybook/test'
+
+import { Button } from './button'
+
+const meta = {
+ component: Button,
+ tags: ['ai-generated'],
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Default: Story = {
+ args: { children: 'Save' },
+ play: async ({ canvas }) => {
+ const button = canvas.getByRole('button', { name: /save/i })
+ await expect(button).toHaveAttribute('data-slot', 'button')
+ },
+}
+
+export const Outline: Story = {
+ args: { variant: 'outline', children: 'Cancel' },
+}
+
+export const Destructive: Story = {
+ args: { variant: 'destructive', children: 'Delete' },
+}
+
+export const Disabled: Story = {
+ args: { children: 'Save', disabled: true },
+ play: async ({ canvas }) => {
+ await expect(canvas.getByRole('button', { name: /save/i })).toBeDisabled()
+ },
+}
diff --git a/web/src/components/ui/checkbox.stories.tsx b/web/src/components/ui/checkbox.stories.tsx
new file mode 100644
index 0000000..9eec260
--- /dev/null
+++ b/web/src/components/ui/checkbox.stories.tsx
@@ -0,0 +1,35 @@
+import type { Meta, StoryObj } from '@storybook/react-vite'
+import { expect } from 'storybook/test'
+
+import { Checkbox } from './checkbox'
+
+const meta = {
+ component: Checkbox,
+ args: { 'aria-label': 'required' },
+ tags: ['ai-generated'],
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Unchecked: Story = {
+ play: async ({ canvas }) => {
+ await expect(canvas.getByRole('checkbox')).toHaveAttribute('aria-checked', 'false')
+ },
+}
+
+export const Checked: Story = {
+ args: { defaultChecked: true },
+ play: async ({ canvas }) => {
+ await expect(canvas.getByRole('checkbox')).toHaveAttribute('aria-checked', 'true')
+ },
+}
+
+export const Toggle: Story = {
+ play: async ({ canvas, userEvent }) => {
+ const checkbox = canvas.getByRole('checkbox')
+ await expect(checkbox).toHaveAttribute('aria-checked', 'false')
+ await userEvent.click(checkbox)
+ await expect(checkbox).toHaveAttribute('aria-checked', 'true')
+ },
+}
diff --git a/web/src/components/ui/input.stories.tsx b/web/src/components/ui/input.stories.tsx
new file mode 100644
index 0000000..fc262bf
--- /dev/null
+++ b/web/src/components/ui/input.stories.tsx
@@ -0,0 +1,32 @@
+import type { Meta, StoryObj } from '@storybook/react-vite'
+import { expect } from 'storybook/test'
+
+import { Input } from './input'
+
+const meta = {
+ component: Input,
+ tags: ['ai-generated'],
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Default: Story = {
+ args: { placeholder: 'Object name', 'aria-label': 'name' },
+}
+
+export const Disabled: Story = {
+ args: { 'aria-label': 'name', disabled: true, defaultValue: 'Amphora' },
+ play: async ({ canvas }) => {
+ await expect(canvas.getByLabelText('name')).toBeDisabled()
+ },
+}
+
+export const Typing: Story = {
+ args: { 'aria-label': 'name' },
+ play: async ({ canvas, userEvent }) => {
+ const input = canvas.getByLabelText('name')
+ await userEvent.type(input, 'Bronze fibula')
+ await expect(input).toHaveValue('Bronze fibula')
+ },
+}
diff --git a/web/src/objects/visibility-badge.stories.tsx b/web/src/objects/visibility-badge.stories.tsx
new file mode 100644
index 0000000..53606c7
--- /dev/null
+++ b/web/src/objects/visibility-badge.stories.tsx
@@ -0,0 +1,41 @@
+import type { Meta, StoryObj } from '@storybook/react-vite'
+import { expect } from 'storybook/test'
+
+import { VisibilityBadge } from './visibility-badge'
+
+const meta = {
+ component: VisibilityBadge,
+ tags: ['ai-generated'],
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Public: Story = {
+ args: { visibility: 'public' },
+ play: async ({ canvas }) => {
+ await expect(canvas.getByText('Public')).toBeVisible()
+ },
+}
+
+export const Internal: Story = {
+ args: { visibility: 'internal' },
+}
+
+export const Draft: Story = {
+ args: { visibility: 'draft' },
+}
+
+// The single project-wide CssCheck. VisibilityBadge applies `bg-green-100` for
+// the `public` visibility (see STYLES in visibility-badge.tsx). A concrete
+// resolved background colour proves the shared preview actually loaded the app's
+// Tailwind stylesheet — an unstyled badge would report a transparent background.
+export const CssCheck: Story = {
+ args: { visibility: 'public' },
+ play: async ({ canvas }) => {
+ const badge = canvas.getByText('Public')
+ await expect(getComputedStyle(badge).backgroundColor).toBe(
+ 'oklch(0.962 0.044 156.743)',
+ )
+ },
+}
diff --git a/web/src/search/highlight.stories.tsx b/web/src/search/highlight.stories.tsx
new file mode 100644
index 0000000..35f60cb
--- /dev/null
+++ b/web/src/search/highlight.stories.tsx
@@ -0,0 +1,35 @@
+import type { Meta, StoryObj } from '@storybook/react-vite'
+import { expect } from 'storybook/test'
+
+import { Highlight } from './highlight'
+
+const PRE = '\x02'
+const POST = '\x03'
+
+const meta = {
+ component: Highlight,
+ tags: ['ai-generated'],
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const PlainText: Story = {
+ args: { text: 'cast bronze with green patina' },
+}
+
+export const Marked: Story = {
+ args: { text: `cast ${PRE}bronze${POST} with green patina` },
+ play: async ({ canvas }) => {
+ const mark = canvas.getByText('bronze')
+ await expect(mark.tagName).toBe('MARK')
+ },
+}
+
+export const MultipleMarks: Story = {
+ args: { text: `${PRE}cast${POST} bronze with ${PRE}green${POST} patina` },
+ play: async ({ canvas }) => {
+ await expect(canvas.getByText('cast').tagName).toBe('MARK')
+ await expect(canvas.getByText('green').tagName).toBe('MARK')
+ },
+}
diff --git a/web/src/search/search-result-row.stories.tsx b/web/src/search/search-result-row.stories.tsx
new file mode 100644
index 0000000..6154f1a
--- /dev/null
+++ b/web/src/search/search-result-row.stories.tsx
@@ -0,0 +1,47 @@
+import type { Meta, StoryObj } from '@storybook/react-vite'
+import { expect } from 'storybook/test'
+
+import type { components } from '../api/schema'
+import { SearchResultRow } from './search-result-row'
+
+type SearchHitView = components['schemas']['SearchHitView']
+
+const hit: SearchHitView = {
+ id: '11111111-1111-1111-1111-111111111111',
+ object_number: '2019.4.12',
+ object_name: 'Bronze figurine',
+ brief_description: 'A small cast figure.',
+ visibility: 'public',
+ snippet: 'cast \x02bronze\x03 with green patina',
+}
+
+const meta = {
+ component: SearchResultRow,
+ render: (args) => (
+
+ ),
+ tags: ['ai-generated'],
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Default: Story = {
+ args: { hit },
+ play: async ({ canvas }) => {
+ const link = canvas.getByRole('link', { name: /bronze figurine/i })
+ await expect(link).toHaveAttribute('href', `/search/${hit.id}`)
+ // The snippet's marked term renders through Highlight.
+ await expect(canvas.getByText('bronze').tagName).toBe('MARK')
+ },
+}
+
+export const NoSnippet: Story = {
+ args: { hit: { ...hit, snippet: null } },
+}
+
+export const Internal: Story = {
+ args: { hit: { ...hit, visibility: 'internal' } },
+}
diff --git a/web/vite.config.ts b/web/vite.config.ts
index 1af8dcf..628630d 100644
--- a/web/vite.config.ts
+++ b/web/vite.config.ts
@@ -3,29 +3,57 @@ import tailwindcss from "@tailwindcss/vite";
import react from "@vitejs/plugin-react";
import path from "node:path";
import { defineConfig } from "vite";
+import { fileURLToPath } from 'node:url';
+import { storybookTest } from '@storybook/addon-vitest/vitest-plugin';
+const dirname = typeof __dirname !== 'undefined' ? __dirname : path.dirname(fileURLToPath(import.meta.url));
+// More info at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon
export default defineConfig({
plugins: [react(), tailwindcss()],
resolve: {
alias: {
- "@": path.resolve(__dirname, "./src"),
- },
+ "@": path.resolve(__dirname, "./src")
+ }
},
server: {
proxy: {
"/api": "http://localhost:8080",
"/api-docs": "http://localhost:8080",
- "/health": "http://localhost:8080",
- },
+ "/health": "http://localhost:8080"
+ }
},
test: {
- environment: "jsdom",
- globals: true,
- setupFiles: ["./src/test/setup.ts"],
- environmentOptions: {
- jsdom: {
- url: "http://localhost",
- },
- },
- },
-});
+ projects: [{
+ extends: true,
+ test: {
+ environment: "jsdom",
+ globals: true,
+ setupFiles: ["./src/test/setup.ts"],
+ environmentOptions: {
+ jsdom: {
+ url: "http://localhost"
+ }
+ }
+ }
+ }, {
+ extends: true,
+ plugins: [
+ // The plugin will run tests for the stories defined in your Storybook config
+ // See options at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon#storybooktest
+ storybookTest({
+ configDir: path.join(dirname, '.storybook')
+ })],
+ test: {
+ name: 'storybook',
+ browser: {
+ enabled: true,
+ headless: true,
+ provider: 'playwright',
+ instances: [{
+ browser: 'chromium'
+ }]
+ }
+ }
+ }]
+ }
+});
\ No newline at end of file
diff --git a/web/vitest.shims.d.ts b/web/vitest.shims.d.ts
new file mode 100644
index 0000000..f923d47
--- /dev/null
+++ b/web/vitest.shims.d.ts
@@ -0,0 +1 @@
+///
\ No newline at end of file