diff --git a/docs/decisions/ADR-0030-storybook-baseline-vite-8-compatibility.md b/docs/decisions/ADR-0030-storybook-baseline-vite-8-compatibility.md
new file mode 100644
index 000000000..7628bcef7
--- /dev/null
+++ b/docs/decisions/ADR-0030-storybook-baseline-vite-8-compatibility.md
@@ -0,0 +1,43 @@
+# ADR-0030: Storybook Baseline with Vite 8 Compatibility
+
+- **Status**: Accepted
+- **Date**: 2026-04-09
+- **Deciders**: Taskdeck maintainers
+
+## Context
+
+Taskdeck uses Vite 8 in the frontend workspace. The Storybook baseline issue requested Storybook 8.x, but Storybook 8 does not support the Vite 8 toolchain used by the app.
+
+The team still needs a stable, reviewable component catalogue for the 17 `Td*` primitives, plus a place to validate visual variants without touching the production app.
+
+## Decision
+
+Use Storybook 10.3.x for the frontend Storybook baseline.
+
+Reasons:
+
+- Storybook 10.3.x supports `vite@^8.0.0`.
+- The CSF3 story format remains the same, so the story authoring model stays familiar.
+- The preview should import the app stylesheet so Storybook reflects the production component look and spacing as closely as practical.
+- Story files live in `src/stories/` to keep the component directory focused on runtime code.
+
+## Alternatives Considered
+
+- Storybook 8.x: rejected because it is not compatible with Vite 8.
+- Deferring Storybook entirely: rejected because the component library needs a reviewable baseline now.
+- Co-locating stories with components: workable, but rejected for this baseline because a centralized story directory keeps the setup simpler.
+
+## Consequences
+
+- Storybook can be built and maintained without downgrading Vite.
+- Visual review of `Td*` primitives is available through `npm run storybook` and `npm run storybook:build`.
+- Story files are excluded from the app typecheck, so production compilation stays focused on runtime code.
+- Future contributors have a recorded rationale for the Storybook version choice.
+
+## References
+
+- PR #807
+- Issue #251
+- `frontend/taskdeck-web/.storybook/main.ts`
+- `frontend/taskdeck-web/.storybook/preview.ts`
+- `frontend/taskdeck-web/src/stories/`
diff --git a/docs/decisions/INDEX.md b/docs/decisions/INDEX.md
index 9b0089da8..967918c58 100644
--- a/docs/decisions/INDEX.md
+++ b/docs/decisions/INDEX.md
@@ -31,3 +31,4 @@
| [0027](ADR-0027-cloud-target-topology-autoscaling.md) | Cloud Target Topology and Autoscaling Reference Architecture | Accepted | 2026-04-09 |
| [0028](ADR-0028-staged-deployment-bluegreen-canary.md) | Staged Deployment — Blue/Green with Canary Verification | Accepted | 2026-04-09 |
| [0029](ADR-0029-oidc-mfa-pluggable-identity.md) | OIDC/SSO Integration with Optional TOTP MFA | Accepted | 2026-04-09 |
+| [0030](ADR-0030-storybook-baseline-vite-8-compatibility.md) | Storybook Baseline with Vite 8 Compatibility | Accepted | 2026-04-09 |
diff --git a/frontend/taskdeck-web/.gitignore b/frontend/taskdeck-web/.gitignore
index a547bf36d..87b58f06f 100644
--- a/frontend/taskdeck-web/.gitignore
+++ b/frontend/taskdeck-web/.gitignore
@@ -10,6 +10,7 @@ lerna-debug.log*
node_modules
dist
dist-ssr
+storybook-static
*.local
# Editor directories and files
diff --git a/frontend/taskdeck-web/.storybook/main.ts b/frontend/taskdeck-web/.storybook/main.ts
new file mode 100644
index 000000000..9f7a963bf
--- /dev/null
+++ b/frontend/taskdeck-web/.storybook/main.ts
@@ -0,0 +1,52 @@
+import type { StorybookConfig } from '@storybook/vue3-vite'
+
+function isPwaPlugin(plugin: unknown): boolean {
+ if (plugin && typeof plugin === 'object' && 'name' in plugin) {
+ const name = String((plugin as { name?: unknown }).name ?? '').toLowerCase()
+ return name.includes('pwa') || name.includes('workbox')
+ }
+ return false
+}
+
+function stripPwaPlugins(plugins: unknown[]): unknown[] {
+ const filtered: unknown[] = []
+
+ for (const plugin of plugins) {
+ if (Array.isArray(plugin)) {
+ // Recursively filter nested arrays but preserve the array structure
+ const filteredNested = stripPwaPlugins(plugin)
+ if (filteredNested.length > 0) {
+ filtered.push(filteredNested)
+ }
+ continue
+ }
+ if (!isPwaPlugin(plugin)) {
+ filtered.push(plugin)
+ }
+ }
+
+ return filtered
+}
+
+const config: StorybookConfig = {
+ stories: ['../src/**/*.stories.@(ts|tsx)'],
+ framework: {
+ name: '@storybook/vue3-vite',
+ options: {
+ docgen: 'vue-component-meta',
+ },
+ },
+ async viteFinal(viteConfig) {
+ // Strip PWA plugin — it is app-specific and breaks the Storybook build
+ // because the Storybook output includes large JS bundles that exceed
+ // the workbox precache size limit.
+ return {
+ ...viteConfig,
+ plugins: viteConfig.plugins
+ ? (stripPwaPlugins(viteConfig.plugins as unknown[]) as typeof viteConfig.plugins)
+ : viteConfig.plugins,
+ }
+ },
+}
+
+export default config
diff --git a/frontend/taskdeck-web/.storybook/preview.ts b/frontend/taskdeck-web/.storybook/preview.ts
new file mode 100644
index 000000000..59c281a81
--- /dev/null
+++ b/frontend/taskdeck-web/.storybook/preview.ts
@@ -0,0 +1,27 @@
+import type { Preview } from '@storybook/vue3-vite'
+import '../src/style.css'
+
+const preview: Preview = {
+ parameters: {
+ controls: { expanded: true },
+ backgrounds: {
+ default: 'obsidian',
+ values: [
+ { name: 'obsidian', value: '#131313' },
+ { name: 'light', value: '#f5f3f1' },
+ ],
+ },
+ },
+ decorators: [
+ (story) => ({
+ components: { story },
+ template: `
+
+
+
+ `,
+ }),
+ ],
+}
+
+export default preview
diff --git a/frontend/taskdeck-web/package-lock.json b/frontend/taskdeck-web/package-lock.json
index 004442f6f..71b7eeb4a 100644
--- a/frontend/taskdeck-web/package-lock.json
+++ b/frontend/taskdeck-web/package-lock.json
@@ -22,6 +22,7 @@
"@axe-core/playwright": "^4.11.1",
"@eslint/js": "^10.0.1",
"@playwright/test": "^1.59.1",
+ "@storybook/vue3-vite": "^10.3.5",
"@stryker-mutator/core": "^8.7.1",
"@stryker-mutator/vitest-runner": "^8.7.1",
"@tailwindcss/postcss": "^4.2.2",
@@ -44,6 +45,7 @@
"globals": "^17.4.0",
"happy-dom": "^20.8.9",
"postcss": "^8.5.9",
+ "storybook": "^10.3.5",
"tailwindcss": "^4.2.2",
"typescript": "~5.9.3",
"vite": "^8.0.7",
@@ -56,6 +58,13 @@
"node": ">=24.13.1 <25"
}
},
+ "node_modules/@adobe/css-tools": {
+ "version": "4.4.4",
+ "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz",
+ "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@alloc/quick-lru": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
@@ -1844,6 +1853,448 @@
"tslib": "^2.4.0"
}
},
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz",
+ "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz",
+ "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz",
+ "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz",
+ "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz",
+ "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz",
+ "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz",
+ "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz",
+ "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz",
+ "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz",
+ "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz",
+ "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz",
+ "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz",
+ "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz",
+ "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz",
+ "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz",
+ "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz",
+ "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz",
+ "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz",
+ "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz",
+ "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz",
+ "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz",
+ "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz",
+ "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz",
+ "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz",
+ "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz",
+ "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/@eslint-community/eslint-utils": {
"version": "4.9.1",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
@@ -2908,6 +3359,134 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@storybook/builder-vite": {
+ "version": "10.3.5",
+ "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-10.3.5.tgz",
+ "integrity": "sha512-i4KwCOKbhtlbQIbhm53+Kk7bMnxa0cwTn1pxmtA/x5wm1Qu7FrrBQV0V0DNjkUqzcSKo1CjspASJV/HlY0zYlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@storybook/csf-plugin": "10.3.5",
+ "ts-dedent": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^10.3.5",
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/@storybook/csf-plugin": {
+ "version": "10.3.5",
+ "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-10.3.5.tgz",
+ "integrity": "sha512-qlEzNKxOjq86pvrbuMwiGD/bylnsXk1dg7ve0j77YFjEEchqtl7qTlrXvFdNaLA89GhW6D/EV6eOCu/eobPDgw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "unplugin": "^2.3.5"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "esbuild": "*",
+ "rollup": "*",
+ "storybook": "^10.3.5",
+ "vite": "*",
+ "webpack": "*"
+ },
+ "peerDependenciesMeta": {
+ "esbuild": {
+ "optional": true
+ },
+ "rollup": {
+ "optional": true
+ },
+ "vite": {
+ "optional": true
+ },
+ "webpack": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@storybook/global": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@storybook/global/-/global-5.0.0.tgz",
+ "integrity": "sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@storybook/icons": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@storybook/icons/-/icons-2.0.1.tgz",
+ "integrity": "sha512-/smVjw88yK3CKsiuR71vNgWQ9+NuY2L+e8X7IMrFjexjm6ZR8ULrV2DRkTA61aV6ryefslzHEGDInGpnNeIocg==",
+ "dev": true,
+ "license": "MIT",
+ "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"
+ }
+ },
+ "node_modules/@storybook/vue3": {
+ "version": "10.3.5",
+ "resolved": "https://registry.npmjs.org/@storybook/vue3/-/vue3-10.3.5.tgz",
+ "integrity": "sha512-PxgnIlem+w0iCxf+YBMPm7T/v75ax1fzqkrVA3C1c/UQ8pckmJxx7Gfs+84GnPWA6Q4G1F2mJ2FsWWneivkQ1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@storybook/global": "^5.0.0",
+ "type-fest": "~2.19",
+ "vue-component-type-helpers": "latest"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^10.3.5",
+ "vue": "^3.0.0"
+ }
+ },
+ "node_modules/@storybook/vue3-vite": {
+ "version": "10.3.5",
+ "resolved": "https://registry.npmjs.org/@storybook/vue3-vite/-/vue3-vite-10.3.5.tgz",
+ "integrity": "sha512-9a0FDU9lsGDxnTQoDna9fmRx6+tUvnimb61bAcfZeigGyx127qT9rylvSC3WVKTBiQ/o4Dg76v44HIv+ew/DsQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@storybook/builder-vite": "10.3.5",
+ "@storybook/vue3": "10.3.5",
+ "magic-string": "^0.30.0",
+ "typescript": "^5.9.3",
+ "vue-component-meta": "^2.0.0",
+ "vue-docgen-api": "^4.75.1"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^10.3.5",
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/@storybook/vue3/node_modules/type-fest": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
+ "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=12.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/@stryker-mutator/api": {
"version": "8.7.1",
"resolved": "https://registry.npmjs.org/@stryker-mutator/api/-/api-8.7.1.tgz",
@@ -3545,6 +4124,79 @@
"vue": "^2.7.0 || ^3.0.0"
}
},
+ "node_modules/@testing-library/dom": {
+ "version": "10.4.1",
+ "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz",
+ "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.10.4",
+ "@babel/runtime": "^7.12.5",
+ "@types/aria-query": "^5.0.1",
+ "aria-query": "5.3.0",
+ "dom-accessibility-api": "^0.5.9",
+ "lz-string": "^1.5.0",
+ "picocolors": "1.1.1",
+ "pretty-format": "^27.0.2"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@testing-library/dom/node_modules/aria-query": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
+ "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "dequal": "^2.0.3"
+ }
+ },
+ "node_modules/@testing-library/jest-dom": {
+ "version": "6.9.1",
+ "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz",
+ "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@adobe/css-tools": "^4.4.0",
+ "aria-query": "^5.0.0",
+ "css.escape": "^1.5.1",
+ "dom-accessibility-api": "^0.6.3",
+ "picocolors": "^1.1.1",
+ "redent": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=14",
+ "npm": ">=6",
+ "yarn": ">=1"
+ }
+ },
+ "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz",
+ "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@testing-library/user-event": {
+ "version": "14.6.1",
+ "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz",
+ "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12",
+ "npm": ">=6"
+ },
+ "peerDependencies": {
+ "@testing-library/dom": ">=7.21.4"
+ }
+ },
"node_modules/@tybys/wasm-util": {
"version": "0.10.1",
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
@@ -3556,6 +4208,14 @@
"tslib": "^2.4.0"
}
},
+ "node_modules/@types/aria-query": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
+ "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/@types/chai": {
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz",
@@ -4208,6 +4868,17 @@
"@vue/shared": "3.5.32"
}
},
+ "node_modules/@vue/compiler-vue2": {
+ "version": "2.7.16",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-vue2/-/compiler-vue2-2.7.16.tgz",
+ "integrity": "sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "de-indent": "^1.0.2",
+ "he": "^1.2.0"
+ }
+ },
"node_modules/@vue/devtools-api": {
"version": "7.7.9",
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.9.tgz",
@@ -4337,6 +5008,13 @@
}
}
},
+ "node_modules/@webcontainer/env": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@webcontainer/env/-/env-1.1.1.tgz",
+ "integrity": "sha512-6aN99yL695Hi9SuIk1oC88l9o0gmxL1nGWWQ/kNy81HigJ0FoaoTXpytCj6ItzgyCEwA9kF1wixsTuv5cjsgng==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/abbrev": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz",
@@ -4510,6 +5188,20 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/asap": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/assert-never": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.4.0.tgz",
+ "integrity": "sha512-5oJg84os6NMQNl27T9LnZkvvqzvAnHu03ShCnoj6bsJwS7L8AO4lf+C/XjK/nvzEqQB744moC6V128RucQd1jA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/assertion-error": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
@@ -4520,6 +5212,19 @@
"node": ">=12"
}
},
+ "node_modules/ast-types": {
+ "version": "0.16.1",
+ "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz",
+ "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/ast-v8-to-istanbul": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.0.tgz",
@@ -4722,6 +5427,19 @@
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
}
},
+ "node_modules/babel-walk": {
+ "version": "3.0.0-canary-5",
+ "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz",
+ "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.9.6"
+ },
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -4809,6 +5527,22 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/bundle-name": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz",
+ "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "run-applescript": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/call-bind": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
@@ -4902,6 +5636,16 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
+ "node_modules/character-parser": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz",
+ "integrity": "sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-regex": "^1.0.3"
+ }
+ },
"node_modules/chardet": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
@@ -4909,6 +5653,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/check-error": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz",
+ "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 16"
+ }
+ },
"node_modules/cli-width": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz",
@@ -4982,6 +5736,17 @@
"proto-list": "~1.2.1"
}
},
+ "node_modules/constantinople": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz",
+ "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.6.0",
+ "@babel/types": "^7.6.1"
+ }
+ },
"node_modules/convert-source-map": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
@@ -5043,6 +5808,13 @@
"node": ">=8"
}
},
+ "node_modules/css.escape": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
+ "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
@@ -5116,6 +5888,13 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/de-indent": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz",
+ "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/debug": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
@@ -5134,6 +5913,16 @@
}
}
},
+ "node_modules/deep-eql": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz",
+ "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/deep-is": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
@@ -5151,6 +5940,36 @@
"node": ">=0.10.0"
}
},
+ "node_modules/default-browser": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz",
+ "integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bundle-name": "^4.1.0",
+ "default-browser-id": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/default-browser-id": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz",
+ "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/define-data-property": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
@@ -5169,6 +5988,19 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/define-lazy-prop": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
+ "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/define-properties": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
@@ -5196,6 +6028,17 @@
"node": ">=0.4.0"
}
},
+ "node_modules/dequal": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/des.js": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz",
@@ -5224,6 +6067,21 @@
"dev": true,
"license": "Apache-2.0"
},
+ "node_modules/doctypes": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz",
+ "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/dom-accessibility-api": {
+ "version": "0.5.16",
+ "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
+ "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/dompurify": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.3.tgz",
@@ -5494,6 +6352,48 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/esbuild": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz",
+ "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.27.7",
+ "@esbuild/android-arm": "0.27.7",
+ "@esbuild/android-arm64": "0.27.7",
+ "@esbuild/android-x64": "0.27.7",
+ "@esbuild/darwin-arm64": "0.27.7",
+ "@esbuild/darwin-x64": "0.27.7",
+ "@esbuild/freebsd-arm64": "0.27.7",
+ "@esbuild/freebsd-x64": "0.27.7",
+ "@esbuild/linux-arm": "0.27.7",
+ "@esbuild/linux-arm64": "0.27.7",
+ "@esbuild/linux-ia32": "0.27.7",
+ "@esbuild/linux-loong64": "0.27.7",
+ "@esbuild/linux-mips64el": "0.27.7",
+ "@esbuild/linux-ppc64": "0.27.7",
+ "@esbuild/linux-riscv64": "0.27.7",
+ "@esbuild/linux-s390x": "0.27.7",
+ "@esbuild/linux-x64": "0.27.7",
+ "@esbuild/netbsd-arm64": "0.27.7",
+ "@esbuild/netbsd-x64": "0.27.7",
+ "@esbuild/openbsd-arm64": "0.27.7",
+ "@esbuild/openbsd-x64": "0.27.7",
+ "@esbuild/openharmony-arm64": "0.27.7",
+ "@esbuild/sunos-x64": "0.27.7",
+ "@esbuild/win32-arm64": "0.27.7",
+ "@esbuild/win32-ia32": "0.27.7",
+ "@esbuild/win32-x64": "0.27.7"
+ }
+ },
"node_modules/escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
@@ -5717,6 +6617,13 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/esm-resolve": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/esm-resolve/-/esm-resolve-1.0.11.tgz",
+ "integrity": "sha512-LxF0wfUQm3ldUDHkkV2MIbvvY0TgzIpJ420jHSV1Dm+IlplBEWiJTKWM61GtxUfvjV6iD4OtTYFGAGM2uuIUWg==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
"node_modules/espree": {
"version": "11.2.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz",
@@ -5748,6 +6655,20 @@
"url": "https://opencollective.com/eslint"
}
},
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/esquery": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz",
@@ -6539,6 +7460,13 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/hash-sum": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz",
+ "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
@@ -6551,6 +7479,16 @@
"node": ">= 0.4"
}
},
+ "node_modules/he": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "he": "bin/he"
+ }
+ },
"node_modules/hookable": {
"version": "5.5.3",
"resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
@@ -6614,6 +7552,16 @@
"node": ">=0.8.19"
}
},
+ "node_modules/indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
@@ -6802,6 +7750,46 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-docker": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
+ "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "is-docker": "cli.js"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-expression": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz",
+ "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^7.1.1",
+ "object-assign": "^4.1.1"
+ }
+ },
+ "node_modules/is-expression/node_modules/acorn": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -6871,6 +7859,25 @@
"node": ">=0.10.0"
}
},
+ "node_modules/is-inside-container": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
+ "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-docker": "^3.0.0"
+ },
+ "bin": {
+ "is-inside-container": "cli.js"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/is-map": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
@@ -6944,6 +7951,13 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/is-promise": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
+ "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/is-regex": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
@@ -7137,6 +8151,22 @@
"url": "https://github.com/sponsors/mesqueeb"
}
},
+ "node_modules/is-wsl": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz",
+ "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-inside-container": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/isarray": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
@@ -7273,6 +8303,13 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/js-stringify": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz",
+ "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -7360,6 +8397,17 @@
"node": ">=0.10.0"
}
},
+ "node_modules/jstransformer": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz",
+ "integrity": "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-promise": "^2.0.0",
+ "promise": "^7.0.1"
+ }
+ },
"node_modules/keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@@ -7699,6 +8747,13 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/loupe": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz",
+ "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/lru-cache": {
"version": "10.4.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
@@ -7706,6 +8761,17 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/lz-string": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
+ "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "lz-string": "bin/bin.js"
+ }
+ },
"node_modules/magic-string": {
"version": "0.30.21",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
@@ -7785,6 +8851,16 @@
"node": ">= 0.6"
}
},
+ "node_modules/min-indent": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
+ "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/minimalistic-assert": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
@@ -7993,6 +9069,16 @@
"url": "https://github.com/fb55/nth-check?sponsor=1"
}
},
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/object-inspect": {
"version": "1.13.4",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
@@ -8048,6 +9134,25 @@
],
"license": "MIT"
},
+ "node_modules/open": {
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz",
+ "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "default-browser": "^5.2.1",
+ "define-lazy-prop": "^3.0.0",
+ "is-inside-container": "^1.0.0",
+ "wsl-utils": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/optionator": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
@@ -8204,6 +9309,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/pathval": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz",
+ "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.16"
+ }
+ },
"node_modules/perfect-debounce": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz",
@@ -8379,6 +9494,47 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/pretty-format": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+ "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/pretty-format/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pretty-format/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
"node_modules/pretty-ms": {
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.0.tgz",
@@ -8405,6 +9561,16 @@
"node": ">=0.4.0"
}
},
+ "node_modules/promise": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+ "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "asap": "~2.0.3"
+ }
+ },
"node_modules/proto-list": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
@@ -8433,6 +9599,142 @@
"url": "https://github.com/sponsors/lupomontero"
}
},
+ "node_modules/pug": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.4.tgz",
+ "integrity": "sha512-kFfq5mMzrS7+wrl5pLJzZEzemx34OQ0w4SARfhy/3yxTlhbstsudDwJzhf1hP02yHzbjoVMSXUj/Sz6RNfMyXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pug-code-gen": "^3.0.4",
+ "pug-filters": "^4.0.0",
+ "pug-lexer": "^5.0.1",
+ "pug-linker": "^4.0.0",
+ "pug-load": "^3.0.0",
+ "pug-parser": "^6.0.0",
+ "pug-runtime": "^3.0.1",
+ "pug-strip-comments": "^2.0.0"
+ }
+ },
+ "node_modules/pug-attrs": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz",
+ "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "constantinople": "^4.0.1",
+ "js-stringify": "^1.0.2",
+ "pug-runtime": "^3.0.0"
+ }
+ },
+ "node_modules/pug-code-gen": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.4.tgz",
+ "integrity": "sha512-6okWYIKdasTyXICyEtvobmTZAVX57JkzgzIi4iRJlin8kmhG+Xry2dsus+Mun/nGCn6F2U49haHI5mkELXB14g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "constantinople": "^4.0.1",
+ "doctypes": "^1.1.0",
+ "js-stringify": "^1.0.2",
+ "pug-attrs": "^3.0.0",
+ "pug-error": "^2.1.0",
+ "pug-runtime": "^3.0.1",
+ "void-elements": "^3.1.0",
+ "with": "^7.0.0"
+ }
+ },
+ "node_modules/pug-error": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.1.0.tgz",
+ "integrity": "sha512-lv7sU9e5Jk8IeUheHata6/UThZ7RK2jnaaNztxfPYUY+VxZyk/ePVaNZ/vwmH8WqGvDz3LrNYt/+gA55NDg6Pg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/pug-filters": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz",
+ "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "constantinople": "^4.0.1",
+ "jstransformer": "1.0.0",
+ "pug-error": "^2.0.0",
+ "pug-walk": "^2.0.0",
+ "resolve": "^1.15.1"
+ }
+ },
+ "node_modules/pug-lexer": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz",
+ "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "character-parser": "^2.2.0",
+ "is-expression": "^4.0.0",
+ "pug-error": "^2.0.0"
+ }
+ },
+ "node_modules/pug-linker": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz",
+ "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pug-error": "^2.0.0",
+ "pug-walk": "^2.0.0"
+ }
+ },
+ "node_modules/pug-load": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz",
+ "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "object-assign": "^4.1.1",
+ "pug-walk": "^2.0.0"
+ }
+ },
+ "node_modules/pug-parser": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz",
+ "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pug-error": "^2.0.0",
+ "token-stream": "1.0.0"
+ }
+ },
+ "node_modules/pug-runtime": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz",
+ "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/pug-strip-comments": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz",
+ "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pug-error": "^2.0.0"
+ }
+ },
+ "node_modules/pug-walk": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz",
+ "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
@@ -8464,31 +9766,105 @@
"resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz",
"integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==",
"dev": true,
- "license": "BSD-3-Clause",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/querystringify": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
+ "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
+ "license": "MIT"
+ },
+ "node_modules/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "node_modules/react": {
+ "version": "19.2.5",
+ "resolved": "https://registry.npmjs.org/react/-/react-19.2.5.tgz",
+ "integrity": "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "19.2.5",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.5.tgz",
+ "integrity": "sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "scheduler": "^0.27.0"
+ },
+ "peerDependencies": {
+ "react": "^19.2.5"
+ }
+ },
+ "node_modules/react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/recast": {
+ "version": "0.23.11",
+ "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.11.tgz",
+ "integrity": "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "side-channel": "^1.1.0"
+ "ast-types": "^0.16.1",
+ "esprima": "~4.0.0",
+ "source-map": "~0.6.1",
+ "tiny-invariant": "^1.3.3",
+ "tslib": "^2.0.1"
},
"engines": {
- "node": ">=0.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": ">= 4"
}
},
- "node_modules/querystringify": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
- "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
- "license": "MIT"
+ "node_modules/recast/node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
},
- "node_modules/randombytes": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
- "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "node_modules/redent": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
+ "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "safe-buffer": "^5.1.0"
+ "indent-string": "^4.0.0",
+ "strip-indent": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
"node_modules/reflect.getprototypeof": {
@@ -8677,6 +10053,19 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/run-applescript": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz",
+ "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/rxjs": {
"version": "7.8.2",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
@@ -8770,6 +10159,14 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/scheduler": {
+ "version": "0.27.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
+ "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/semver": {
"version": "7.7.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
@@ -9110,6 +10507,128 @@
"node": ">= 0.4"
}
},
+ "node_modules/storybook": {
+ "version": "10.3.5",
+ "resolved": "https://registry.npmjs.org/storybook/-/storybook-10.3.5.tgz",
+ "integrity": "sha512-uBSZu/GZa9aEIW3QMGvdQPMZWhGxSe4dyRWU8B3/Vd47Gy/XLC7tsBxRr13txmmPOEDHZR94uLuq0H50fvuqBw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@storybook/global": "^5.0.0",
+ "@storybook/icons": "^2.0.1",
+ "@testing-library/jest-dom": "^6.9.1",
+ "@testing-library/user-event": "^14.6.1",
+ "@vitest/expect": "3.2.4",
+ "@vitest/spy": "3.2.4",
+ "@webcontainer/env": "^1.1.1",
+ "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0",
+ "open": "^10.2.0",
+ "recast": "^0.23.5",
+ "semver": "^7.7.3",
+ "use-sync-external-store": "^1.5.0",
+ "ws": "^8.18.0"
+ },
+ "bin": {
+ "storybook": "dist/bin/dispatcher.js"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "prettier": "^2 || ^3"
+ },
+ "peerDependenciesMeta": {
+ "prettier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/storybook/node_modules/@vitest/expect": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz",
+ "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/chai": "^5.2.2",
+ "@vitest/spy": "3.2.4",
+ "@vitest/utils": "3.2.4",
+ "chai": "^5.2.0",
+ "tinyrainbow": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/storybook/node_modules/@vitest/pretty-format": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz",
+ "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tinyrainbow": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/storybook/node_modules/@vitest/spy": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz",
+ "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tinyspy": "^4.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/storybook/node_modules/@vitest/utils": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz",
+ "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/pretty-format": "3.2.4",
+ "loupe": "^3.1.4",
+ "tinyrainbow": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/storybook/node_modules/chai": {
+ "version": "5.3.3",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz",
+ "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assertion-error": "^2.0.1",
+ "check-error": "^2.1.1",
+ "deep-eql": "^5.0.1",
+ "loupe": "^3.1.0",
+ "pathval": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/storybook/node_modules/tinyrainbow": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz",
+ "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
"node_modules/string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
@@ -9339,6 +10858,19 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/strip-indent": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
+ "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "min-indent": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/superjson": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.5.tgz",
@@ -9466,6 +10998,13 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/tiny-invariant": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
+ "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/tinybench": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
@@ -9510,6 +11049,16 @@
"node": ">=14.0.0"
}
},
+ "node_modules/tinyspy": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz",
+ "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
"node_modules/tmp": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
@@ -9523,6 +11072,13 @@
"node": ">=0.6.0"
}
},
+ "node_modules/token-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz",
+ "integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/totalist": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
@@ -9577,6 +11133,23 @@
"typescript": ">=4.8.4"
}
},
+ "node_modules/ts-dedent": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz",
+ "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.10"
+ }
+ },
+ "node_modules/ts-map": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/ts-map/-/ts-map-1.0.3.tgz",
+ "integrity": "sha512-vDWbsl26LIcPGmDpoVzjEP6+hvHZkBkLW7JpvwbCv/5IYPJlsbzCVXY3wsCeAxAUeTclNOUZxnLdGh3VBD/J6w==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
@@ -9851,6 +11424,22 @@
"node": ">= 4.0.0"
}
},
+ "node_modules/unplugin": {
+ "version": "2.3.11",
+ "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.11.tgz",
+ "integrity": "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/remapping": "^2.3.5",
+ "acorn": "^8.15.0",
+ "picomatch": "^4.0.3",
+ "webpack-virtual-modules": "^0.6.2"
+ },
+ "engines": {
+ "node": ">=18.12.0"
+ }
+ },
"node_modules/upath": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
@@ -9913,6 +11502,16 @@
"requires-port": "^1.0.0"
}
},
+ "node_modules/use-sync-external-store": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz",
+ "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -10119,6 +11718,16 @@
}
}
},
+ "node_modules/void-elements": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
+ "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/vscode-uri": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz",
@@ -10147,6 +11756,88 @@
}
}
},
+ "node_modules/vue-component-meta": {
+ "version": "2.2.12",
+ "resolved": "https://registry.npmjs.org/vue-component-meta/-/vue-component-meta-2.2.12.tgz",
+ "integrity": "sha512-dQU6/obNSNbennJ1xd+rhDid4g3vQro+9qUBBIg8HMZH2Zs1jTpkFNxuQ3z77bOlU+ew08Qck9sbYkdSePr0Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@volar/typescript": "2.4.15",
+ "@vue/language-core": "2.2.12",
+ "path-browserify": "^1.0.1",
+ "vue-component-type-helpers": "2.2.12"
+ },
+ "peerDependencies": {
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vue-component-meta/node_modules/@volar/language-core": {
+ "version": "2.4.15",
+ "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.15.tgz",
+ "integrity": "sha512-3VHw+QZU0ZG9IuQmzT68IyN4hZNd9GchGPhbD9+pa8CVv7rnoOZwo7T8weIbrRmihqy3ATpdfXFnqRrfPVK6CA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@volar/source-map": "2.4.15"
+ }
+ },
+ "node_modules/vue-component-meta/node_modules/@volar/source-map": {
+ "version": "2.4.15",
+ "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.15.tgz",
+ "integrity": "sha512-CPbMWlUN6hVZJYGcU/GSoHu4EnCHiLaXI9n8c9la6RaI9W5JHX+NqG+GSQcB0JdC2FIBLdZJwGsfKyBB71VlTg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/vue-component-meta/node_modules/@volar/typescript": {
+ "version": "2.4.15",
+ "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.15.tgz",
+ "integrity": "sha512-2aZ8i0cqPGjXb4BhkMsPYDkkuc2ZQ6yOpqwAuNwUoncELqoy5fRgOQtLR9gB0g902iS0NAkvpIzs27geVyVdPg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@volar/language-core": "2.4.15",
+ "path-browserify": "^1.0.1",
+ "vscode-uri": "^3.0.8"
+ }
+ },
+ "node_modules/vue-component-meta/node_modules/@vue/language-core": {
+ "version": "2.2.12",
+ "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.2.12.tgz",
+ "integrity": "sha512-IsGljWbKGU1MZpBPN+BvPAdr55YPkj2nB/TBNGNC32Vy2qLG25DYu/NBN2vNtZqdRbTRjaoYrahLrToim2NanA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@volar/language-core": "2.4.15",
+ "@vue/compiler-dom": "^3.5.0",
+ "@vue/compiler-vue2": "^2.7.16",
+ "@vue/shared": "^3.5.0",
+ "alien-signals": "^1.0.3",
+ "minimatch": "^9.0.3",
+ "muggle-string": "^0.4.1",
+ "path-browserify": "^1.0.1"
+ },
+ "peerDependencies": {
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vue-component-meta/node_modules/alien-signals": {
+ "version": "1.0.13",
+ "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-1.0.13.tgz",
+ "integrity": "sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/vue-component-type-helpers": {
"version": "2.2.12",
"resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-2.2.12.tgz",
@@ -10154,6 +11845,40 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/vue-docgen-api": {
+ "version": "4.79.2",
+ "resolved": "https://registry.npmjs.org/vue-docgen-api/-/vue-docgen-api-4.79.2.tgz",
+ "integrity": "sha512-n9ENAcs+40awPZMsas7STqjkZiVlIjxIKgiJr5rSohDP0/JCrD9VtlzNojafsA1MChm/hz2h3PDtUedx3lbgfA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.24.7",
+ "@babel/types": "^7.24.7",
+ "@vue/compiler-dom": "^3.2.0",
+ "@vue/compiler-sfc": "^3.2.0",
+ "ast-types": "^0.16.1",
+ "esm-resolve": "^1.0.8",
+ "hash-sum": "^2.0.0",
+ "lru-cache": "^8.0.3",
+ "pug": "^3.0.2",
+ "recast": "^0.23.1",
+ "ts-map": "^1.0.3",
+ "vue-inbrowser-compiler-independent-utils": "^4.69.0"
+ },
+ "peerDependencies": {
+ "vue": ">=2"
+ }
+ },
+ "node_modules/vue-docgen-api/node_modules/lru-cache": {
+ "version": "8.0.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz",
+ "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=16.14"
+ }
+ },
"node_modules/vue-eslint-parser": {
"version": "10.4.0",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-10.4.0.tgz",
@@ -10191,6 +11916,16 @@
"url": "https://opencollective.com/eslint"
}
},
+ "node_modules/vue-inbrowser-compiler-independent-utils": {
+ "version": "4.71.1",
+ "resolved": "https://registry.npmjs.org/vue-inbrowser-compiler-independent-utils/-/vue-inbrowser-compiler-independent-utils-4.71.1.tgz",
+ "integrity": "sha512-K3wt3iVmNGaFEOUR4JIThQRWfqokxLfnPslD41FDZB2ajXp789+wCqJyGYlIFsvEQ2P61PInw6/ph5iiqg51gg==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "vue": ">=2"
+ }
+ },
"node_modules/vue-router": {
"version": "4.6.3",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.6.3.tgz",
@@ -10236,6 +11971,13 @@
"dev": true,
"license": "Apache-2.0"
},
+ "node_modules/webpack-virtual-modules": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
+ "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/whatwg-mimetype": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz",
@@ -10384,6 +12126,22 @@
"node": ">=8"
}
},
+ "node_modules/with": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz",
+ "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.9.6",
+ "@babel/types": "^7.9.6",
+ "assert-never": "^1.2.1",
+ "babel-walk": "3.0.0-canary-5"
+ },
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
"node_modules/word-wrap": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
@@ -11000,6 +12758,22 @@
}
}
},
+ "node_modules/wsl-utils": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz",
+ "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-wsl": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/xml-name-validator": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
diff --git a/frontend/taskdeck-web/package.json b/frontend/taskdeck-web/package.json
index 1de0cd569..05346b59b 100644
--- a/frontend/taskdeck-web/package.json
+++ b/frontend/taskdeck-web/package.json
@@ -27,9 +27,12 @@
"test:e2e:concurrency": "playwright test tests/e2e/concurrency.spec.ts --reporter=line",
"test:e2e:live-llm:headed": "playwright test tests/e2e/live-llm.spec.ts --headed --reporter=line",
"test:e2e:headed": "playwright test --headed",
+ "mutation:test": "npx stryker run",
+ "storybook": "storybook dev -p 6006",
+ "storybook:build": "storybook build -o storybook-static",
+ "storybook:docs": "storybook build --docs -o storybook-docs",
"test:visual": "playwright test --config playwright.visual.config.ts",
- "test:visual:update": "playwright test --config playwright.visual.config.ts --update-snapshots",
- "mutation:test": "npx stryker run"
+ "test:visual:update": "playwright test --config playwright.visual.config.ts --update-snapshots"
},
"dependencies": {
"@microsoft/signalr": "^10.0.0",
@@ -51,13 +54,14 @@
"@axe-core/playwright": "^4.11.1",
"@eslint/js": "^10.0.1",
"@playwright/test": "^1.59.1",
+ "@storybook/vue3-vite": "^10.3.5",
+ "@stryker-mutator/core": "^8.7.1",
+ "@stryker-mutator/vitest-runner": "^8.7.1",
"@tailwindcss/postcss": "^4.2.2",
"@types/dompurify": "^3.2.0",
"@types/node": "^25.5.2",
"@typescript-eslint/eslint-plugin": "^8.58.1",
"@typescript-eslint/parser": "^8.46.2",
- "@stryker-mutator/core": "^8.7.1",
- "@stryker-mutator/vitest-runner": "^8.7.1",
"@vitejs/plugin-vue": "^6.0.5",
"@vitest/coverage-v8": "^4.1.3",
"@vitest/ui": "^4.1.2",
@@ -73,6 +77,7 @@
"globals": "^17.4.0",
"happy-dom": "^20.8.9",
"postcss": "^8.5.9",
+ "storybook": "^10.3.5",
"tailwindcss": "^4.2.2",
"typescript": "~5.9.3",
"vite": "^8.0.7",
diff --git a/frontend/taskdeck-web/src/stories/TdBadge.stories.ts b/frontend/taskdeck-web/src/stories/TdBadge.stories.ts
new file mode 100644
index 000000000..769792b01
--- /dev/null
+++ b/frontend/taskdeck-web/src/stories/TdBadge.stories.ts
@@ -0,0 +1,104 @@
+import type { Meta, StoryObj } from '@storybook/vue3-vite'
+import TdBadge from '../components/ui/TdBadge.vue'
+
+const meta = {
+ title: 'UI Primitives/TdBadge',
+ component: TdBadge,
+ tags: ['autodocs'],
+ argTypes: {
+ variant: {
+ control: 'select',
+ options: ['default', 'primary', 'success', 'warning', 'error', 'info'],
+ },
+ size: {
+ control: 'select',
+ options: ['sm', 'md'],
+ },
+ },
+ args: {
+ variant: 'default',
+ size: 'md',
+ },
+ render: (args) => ({
+ components: { TdBadge },
+ setup() {
+ return { args }
+ },
+ template: 'Badge',
+ }),
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Default: Story = {}
+
+export const Primary: Story = {
+ args: { variant: 'primary' },
+ render: (args) => ({
+ components: { TdBadge },
+ setup() { return { args } },
+ template: 'Active',
+ }),
+}
+
+export const Success: Story = {
+ args: { variant: 'success' },
+ render: (args) => ({
+ components: { TdBadge },
+ setup() { return { args } },
+ template: 'Done',
+ }),
+}
+
+export const Warning: Story = {
+ args: { variant: 'warning' },
+ render: (args) => ({
+ components: { TdBadge },
+ setup() { return { args } },
+ template: 'Pending',
+ }),
+}
+
+export const Error: Story = {
+ args: { variant: 'error' },
+ render: (args) => ({
+ components: { TdBadge },
+ setup() { return { args } },
+ template: 'Failed',
+ }),
+}
+
+export const Info: Story = {
+ args: { variant: 'info' },
+ render: (args) => ({
+ components: { TdBadge },
+ setup() { return { args } },
+ template: 'New',
+ }),
+}
+
+export const SmallSize: Story = {
+ args: { size: 'sm' },
+ render: (args) => ({
+ components: { TdBadge },
+ setup() { return { args } },
+ template: 'Small',
+ }),
+}
+
+export const AllVariants: Story = {
+ render: () => ({
+ components: { TdBadge },
+ template: `
+
+ Default
+ Primary
+ Success
+ Warning
+ Error
+ Info
+
+ `,
+ }),
+}
diff --git a/frontend/taskdeck-web/src/stories/TdButton.stories.ts b/frontend/taskdeck-web/src/stories/TdButton.stories.ts
new file mode 100644
index 000000000..4107f5395
--- /dev/null
+++ b/frontend/taskdeck-web/src/stories/TdButton.stories.ts
@@ -0,0 +1,100 @@
+import type { Meta, StoryObj } from '@storybook/vue3-vite'
+import TdButton from '../components/ui/TdButton.vue'
+
+const meta = {
+ title: 'UI Primitives/TdButton',
+ component: TdButton,
+ tags: ['autodocs'],
+ argTypes: {
+ variant: {
+ control: 'select',
+ options: ['primary', 'secondary', 'ghost', 'danger'],
+ },
+ size: {
+ control: 'select',
+ options: ['sm', 'md', 'lg'],
+ },
+ disabled: { control: 'boolean' },
+ loading: { control: 'boolean' },
+ type: {
+ control: 'select',
+ options: ['button', 'submit', 'reset'],
+ },
+ },
+ args: {
+ variant: 'primary',
+ size: 'md',
+ disabled: false,
+ loading: false,
+ type: 'button',
+ },
+ render: (args) => ({
+ components: { TdButton },
+ setup() {
+ return { args }
+ },
+ template: 'Button',
+ }),
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Primary: Story = {
+ args: { variant: 'primary' },
+}
+
+export const Secondary: Story = {
+ args: { variant: 'secondary' },
+}
+
+export const Ghost: Story = {
+ args: { variant: 'ghost' },
+}
+
+export const Danger: Story = {
+ args: { variant: 'danger' },
+}
+
+export const Small: Story = {
+ args: { size: 'sm' },
+}
+
+export const Large: Story = {
+ args: { size: 'lg' },
+}
+
+export const Disabled: Story = {
+ args: { disabled: true },
+}
+
+export const Loading: Story = {
+ args: { loading: true },
+}
+
+export const AllVariants: Story = {
+ render: () => ({
+ components: { TdButton },
+ template: `
+
+ Primary
+ Secondary
+ Ghost
+ Danger
+
+ `,
+ }),
+}
+
+export const AllSizes: Story = {
+ render: () => ({
+ components: { TdButton },
+ template: `
+
+ Small
+ Medium
+ Large
+
+ `,
+ }),
+}
diff --git a/frontend/taskdeck-web/src/stories/TdDialog.stories.ts b/frontend/taskdeck-web/src/stories/TdDialog.stories.ts
new file mode 100644
index 000000000..7559b55d3
--- /dev/null
+++ b/frontend/taskdeck-web/src/stories/TdDialog.stories.ts
@@ -0,0 +1,114 @@
+import type { Meta, StoryObj } from '@storybook/vue3-vite'
+import TdDialog from '../components/ui/TdDialog.vue'
+import TdButton from '../components/ui/TdButton.vue'
+
+const meta = {
+ title: 'UI Primitives/TdDialog',
+ component: TdDialog,
+ tags: ['autodocs'],
+ argTypes: {
+ open: { control: 'boolean' },
+ title: { control: 'text' },
+ description: { control: 'text' },
+ closeOnBackdrop: { control: 'boolean' },
+ },
+ args: {
+ open: false,
+ title: 'Confirm Action',
+ description: 'Are you sure you want to proceed?',
+ closeOnBackdrop: true,
+ },
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Default: Story = {
+ render: (args) => ({
+ components: { TdDialog, TdButton },
+ setup() {
+ return { args }
+ },
+ template: `
+
+
Open Dialog
+
+
+ This action cannot be undone.
+
+
+ Cancel
+ Confirm
+
+
+
+ `,
+ }),
+}
+
+export const DangerDialog: Story = {
+ args: {
+ title: 'Delete Item',
+ description: 'This action cannot be undone.',
+ },
+ render: (args) => ({
+ components: { TdDialog, TdButton },
+ setup() {
+ return { args }
+ },
+ template: `
+
+ Delete Item
+
+
+ Cancel
+ Delete
+
+
+
+ `,
+ }),
+}
+
+export const NoBackdropClose: Story = {
+ args: {
+ closeOnBackdrop: false,
+ },
+ render: (args) => ({
+ components: { TdDialog, TdButton },
+ setup() {
+ return { args }
+ },
+ template: `
+
+
Open (no backdrop close)
+
+
+ You must use the button below to close this dialog.
+
+
+ Acknowledge
+
+
+
+ `,
+ }),
+}
diff --git a/frontend/taskdeck-web/src/stories/TdDropdown.stories.ts b/frontend/taskdeck-web/src/stories/TdDropdown.stories.ts
new file mode 100644
index 000000000..c53c2f561
--- /dev/null
+++ b/frontend/taskdeck-web/src/stories/TdDropdown.stories.ts
@@ -0,0 +1,68 @@
+import type { Meta, StoryObj } from '@storybook/vue3-vite'
+import TdDropdown from '../components/ui/TdDropdown.vue'
+import TdButton from '../components/ui/TdButton.vue'
+
+const meta = {
+ title: 'UI Primitives/TdDropdown',
+ component: TdDropdown,
+ tags: ['autodocs'],
+ argTypes: {
+ open: { control: 'boolean' },
+ align: {
+ control: 'select',
+ options: ['left', 'right'],
+ },
+ },
+ args: {
+ open: false,
+ align: 'left',
+ },
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Default: Story = {
+ render: (args) => ({
+ components: { TdDropdown, TdButton },
+ setup() {
+ return { args }
+ },
+ template: `
+
+
+
+ Actions
+
+
+
+
+
+
+ `,
+ }),
+}
+
+export const AlignRight: Story = {
+ args: {
+ align: 'right',
+ },
+ render: (args) => ({
+ components: { TdDropdown, TdButton },
+ setup() {
+ return { args }
+ },
+ template: `
+
+
+
+ Menu
+
+
+
+
+
+
+ `,
+ }),
+}
diff --git a/frontend/taskdeck-web/src/stories/TdEmptyState.stories.ts b/frontend/taskdeck-web/src/stories/TdEmptyState.stories.ts
new file mode 100644
index 000000000..7348d3f79
--- /dev/null
+++ b/frontend/taskdeck-web/src/stories/TdEmptyState.stories.ts
@@ -0,0 +1,66 @@
+import type { Meta, StoryObj } from '@storybook/vue3-vite'
+import TdEmptyState from '../components/ui/TdEmptyState.vue'
+import TdButton from '../components/ui/TdButton.vue'
+
+const meta = {
+ title: 'UI Primitives/TdEmptyState',
+ component: TdEmptyState,
+ tags: ['autodocs'],
+ argTypes: {
+ title: { control: 'text' },
+ description: { control: 'text' },
+ },
+ args: {
+ title: 'No items yet',
+ description: '',
+ },
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Default: Story = {
+ args: { title: 'No tasks found' },
+}
+
+export const WithDescription: Story = {
+ args: {
+ title: 'No tasks found',
+ description: 'Create your first task to get started with Taskdeck.',
+ },
+}
+
+export const WithAction: Story = {
+ render: () => ({
+ components: { TdEmptyState, TdButton },
+ template: `
+
+
+ Capture Input
+
+
+ `,
+ }),
+}
+
+export const WithIcon: Story = {
+ render: () => ({
+ components: { TdEmptyState, TdButton },
+ template: `
+
+
+
+
+
+ `,
+ }),
+}
diff --git a/frontend/taskdeck-web/src/stories/TdFieldWrapper.stories.ts b/frontend/taskdeck-web/src/stories/TdFieldWrapper.stories.ts
new file mode 100644
index 000000000..092f0a984
--- /dev/null
+++ b/frontend/taskdeck-web/src/stories/TdFieldWrapper.stories.ts
@@ -0,0 +1,67 @@
+import type { Meta, StoryObj } from '@storybook/vue3-vite'
+import TdFieldWrapper from '../components/ui/TdFieldWrapper.vue'
+import TdInput from '../components/ui/TdInput.vue'
+
+const meta = {
+ title: 'UI Primitives/TdFieldWrapper',
+ component: TdFieldWrapper,
+ tags: ['autodocs'],
+ argTypes: {
+ label: { control: 'text' },
+ error: { control: 'text' },
+ hint: { control: 'text' },
+ required: { control: 'boolean' },
+ fieldId: { control: 'text' },
+ },
+ args: {
+ label: 'Task name',
+ error: '',
+ hint: '',
+ required: false,
+ fieldId: 'demo-field',
+ },
+ render: (args) => ({
+ components: { TdFieldWrapper, TdInput },
+ setup() {
+ return { args }
+ },
+ template: `
+
+
+
+ `,
+ }),
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Default: Story = {}
+
+export const WithHint: Story = {
+ args: { hint: 'Use a descriptive name for your task.' },
+}
+
+export const WithError: Story = {
+ args: { error: 'Task name is required.' },
+}
+
+export const Required: Story = {
+ args: { required: true },
+}
+
+export const FullExample: Story = {
+ render: () => ({
+ components: { TdFieldWrapper, TdInput },
+ template: `
+
+
+
+
+
+
+
+
+ `,
+ }),
+}
diff --git a/frontend/taskdeck-web/src/stories/TdIconButton.stories.ts b/frontend/taskdeck-web/src/stories/TdIconButton.stories.ts
new file mode 100644
index 000000000..dcadc0928
--- /dev/null
+++ b/frontend/taskdeck-web/src/stories/TdIconButton.stories.ts
@@ -0,0 +1,96 @@
+import type { Meta, StoryObj } from '@storybook/vue3-vite'
+import TdIconButton from '../components/ui/TdIconButton.vue'
+
+const meta = {
+ title: 'UI Primitives/TdIconButton',
+ component: TdIconButton,
+ tags: ['autodocs'],
+ argTypes: {
+ variant: {
+ control: 'select',
+ options: ['primary', 'secondary', 'ghost', 'danger'],
+ },
+ size: {
+ control: 'select',
+ options: ['sm', 'md', 'lg'],
+ },
+ disabled: { control: 'boolean' },
+ loading: { control: 'boolean' },
+ label: { control: 'text' },
+ },
+ args: {
+ variant: 'ghost',
+ size: 'md',
+ disabled: false,
+ loading: false,
+ label: 'Close',
+ },
+ render: (args) => ({
+ components: { TdIconButton },
+ setup() {
+ return { args }
+ },
+ template: `
+
+
+
+ `,
+ }),
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Default: Story = {}
+
+export const Primary: Story = {
+ args: { variant: 'primary' },
+}
+
+export const Secondary: Story = {
+ args: { variant: 'secondary' },
+}
+
+export const Danger: Story = {
+ args: { variant: 'danger' },
+}
+
+export const Small: Story = {
+ args: { size: 'sm' },
+}
+
+export const Large: Story = {
+ args: { size: 'lg' },
+}
+
+export const Disabled: Story = {
+ args: { disabled: true },
+}
+
+export const Loading: Story = {
+ args: { loading: true },
+}
+
+export const AllVariants: Story = {
+ render: () => ({
+ components: { TdIconButton },
+ template: `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `,
+ }),
+}
diff --git a/frontend/taskdeck-web/src/stories/TdInlineAlert.stories.ts b/frontend/taskdeck-web/src/stories/TdInlineAlert.stories.ts
new file mode 100644
index 000000000..2d6878717
--- /dev/null
+++ b/frontend/taskdeck-web/src/stories/TdInlineAlert.stories.ts
@@ -0,0 +1,88 @@
+import type { Meta, StoryObj } from '@storybook/vue3-vite'
+import TdInlineAlert from '../components/ui/TdInlineAlert.vue'
+
+const meta = {
+ title: 'UI Primitives/TdInlineAlert',
+ component: TdInlineAlert,
+ tags: ['autodocs'],
+ argTypes: {
+ variant: {
+ control: 'select',
+ options: ['info', 'success', 'warning', 'error'],
+ },
+ dismissible: { control: 'boolean' },
+ },
+ args: {
+ variant: 'info',
+ dismissible: false,
+ },
+ render: (args) => ({
+ components: { TdInlineAlert },
+ setup() {
+ return { args }
+ },
+ template: 'This is an inline alert message.',
+ }),
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Info: Story = {
+ args: { variant: 'info' },
+ render: (args) => ({
+ components: { TdInlineAlert },
+ setup() { return { args } },
+ template: 'Board changes require review before applying.',
+ }),
+}
+
+export const Success: Story = {
+ args: { variant: 'success' },
+ render: (args) => ({
+ components: { TdInlineAlert },
+ setup() { return { args } },
+ template: 'Proposal approved and applied.',
+ }),
+}
+
+export const Warning: Story = {
+ args: { variant: 'warning' },
+ render: (args) => ({
+ components: { TdInlineAlert },
+ setup() { return { args } },
+ template: 'Offline mode: changes will sync later.',
+ }),
+}
+
+export const Error: Story = {
+ args: { variant: 'error' },
+ render: (args) => ({
+ components: { TdInlineAlert },
+ setup() { return { args } },
+ template: 'Failed to load board data.',
+ }),
+}
+
+export const Dismissible: Story = {
+ args: { variant: 'warning', dismissible: true },
+ render: (args) => ({
+ components: { TdInlineAlert },
+ setup() { return { args } },
+ template: 'This alert can be dismissed.',
+ }),
+}
+
+export const AllVariants: Story = {
+ render: () => ({
+ components: { TdInlineAlert },
+ template: `
+
+ Info alert message.
+ Success alert message.
+ Warning alert message.
+ Error alert message.
+
+ `,
+ }),
+}
diff --git a/frontend/taskdeck-web/src/stories/TdInput.stories.ts b/frontend/taskdeck-web/src/stories/TdInput.stories.ts
new file mode 100644
index 000000000..6c7907f11
--- /dev/null
+++ b/frontend/taskdeck-web/src/stories/TdInput.stories.ts
@@ -0,0 +1,71 @@
+import type { Meta, StoryObj } from '@storybook/vue3-vite'
+import TdInput from '../components/ui/TdInput.vue'
+
+const meta = {
+ title: 'UI Primitives/TdInput',
+ component: TdInput,
+ tags: ['autodocs'],
+ argTypes: {
+ type: {
+ control: 'select',
+ options: ['text', 'email', 'password', 'number', 'search', 'url', 'tel'],
+ },
+ disabled: { control: 'boolean' },
+ readonly: { control: 'boolean' },
+ error: { control: 'boolean' },
+ placeholder: { control: 'text' },
+ modelValue: { control: 'text' },
+ },
+ args: {
+ type: 'text',
+ placeholder: 'Enter text...',
+ modelValue: '',
+ disabled: false,
+ readonly: false,
+ error: false,
+ },
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Default: Story = {}
+
+export const WithValue: Story = {
+ args: { modelValue: 'Hello, Taskdeck' },
+}
+
+export const WithPlaceholder: Story = {
+ args: { placeholder: 'Search tasks...' },
+}
+
+export const Error: Story = {
+ args: { error: true, modelValue: 'Invalid input' },
+}
+
+export const Disabled: Story = {
+ args: { disabled: true, modelValue: 'Cannot edit' },
+}
+
+export const Readonly: Story = {
+ args: { readonly: true, modelValue: 'Read-only value' },
+}
+
+export const Password: Story = {
+ args: { type: 'password', placeholder: 'Enter password...' },
+}
+
+export const AllStates: Story = {
+ render: () => ({
+ components: { TdInput },
+ template: `
+
+
+
+
+
+
+
+ `,
+ }),
+}
diff --git a/frontend/taskdeck-web/src/stories/TdPopover.stories.ts b/frontend/taskdeck-web/src/stories/TdPopover.stories.ts
new file mode 100644
index 000000000..14e0b1105
--- /dev/null
+++ b/frontend/taskdeck-web/src/stories/TdPopover.stories.ts
@@ -0,0 +1,97 @@
+import type { Meta, StoryObj } from '@storybook/vue3-vite'
+import TdPopover from '../components/ui/TdPopover.vue'
+import TdButton from '../components/ui/TdButton.vue'
+
+const meta = {
+ title: 'UI Primitives/TdPopover',
+ component: TdPopover,
+ tags: ['autodocs'],
+ argTypes: {
+ open: { control: 'boolean' },
+ align: {
+ control: 'select',
+ options: ['left', 'right', 'center'],
+ },
+ position: {
+ control: 'select',
+ options: ['top', 'bottom'],
+ },
+ },
+ args: {
+ open: false,
+ align: 'left',
+ position: 'bottom',
+ },
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Default: Story = {
+ render: (args) => ({
+ components: { TdPopover, TdButton },
+ setup() {
+ return { args }
+ },
+ template: `
+
+
+
+ Show info
+
+
+ Popover content can include any elements.
+
+
+
+ `,
+ }),
+}
+
+export const TopPosition: Story = {
+ args: {
+ position: 'top',
+ },
+ render: (args) => ({
+ components: { TdPopover, TdButton },
+ setup() {
+ return { args }
+ },
+ template: `
+
+
+
+ Show above
+
+
+ This popover appears above the trigger.
+
+
+
+ `,
+ }),
+}
+
+export const CenterAligned: Story = {
+ args: {
+ align: 'center',
+ },
+ render: (args) => ({
+ components: { TdPopover, TdButton },
+ setup() {
+ return { args }
+ },
+ template: `
+
+
+
+ Center aligned
+
+
+ Centered popover content.
+
+
+
+ `,
+ }),
+}
diff --git a/frontend/taskdeck-web/src/stories/TdSelect.stories.ts b/frontend/taskdeck-web/src/stories/TdSelect.stories.ts
new file mode 100644
index 000000000..36ad18522
--- /dev/null
+++ b/frontend/taskdeck-web/src/stories/TdSelect.stories.ts
@@ -0,0 +1,51 @@
+import type { Meta, StoryObj } from '@storybook/vue3-vite'
+import TdSelect from '../components/ui/TdSelect.vue'
+
+const meta = {
+ title: 'UI Primitives/TdSelect',
+ component: TdSelect,
+ tags: ['autodocs'],
+ argTypes: {
+ disabled: { control: 'boolean' },
+ error: { control: 'boolean' },
+ placeholder: { control: 'text' },
+ modelValue: { control: 'text' },
+ },
+ args: {
+ placeholder: 'Choose an option...',
+ modelValue: '',
+ disabled: false,
+ error: false,
+ },
+ render: (args) => ({
+ components: { TdSelect },
+ setup() {
+ return { args }
+ },
+ template: `
+
+
+
+
+
+
+ `,
+ }),
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Default: Story = {}
+
+export const WithSelection: Story = {
+ args: { modelValue: 'in-progress' },
+}
+
+export const Error: Story = {
+ args: { error: true },
+}
+
+export const Disabled: Story = {
+ args: { disabled: true, modelValue: 'todo' },
+}
diff --git a/frontend/taskdeck-web/src/stories/TdSkeleton.stories.ts b/frontend/taskdeck-web/src/stories/TdSkeleton.stories.ts
new file mode 100644
index 000000000..c14d9d629
--- /dev/null
+++ b/frontend/taskdeck-web/src/stories/TdSkeleton.stories.ts
@@ -0,0 +1,59 @@
+import type { Meta, StoryObj } from '@storybook/vue3-vite'
+import TdSkeleton from '../components/ui/TdSkeleton.vue'
+
+const meta = {
+ title: 'UI Primitives/TdSkeleton',
+ component: TdSkeleton,
+ tags: ['autodocs'],
+ argTypes: {
+ width: { control: 'text' },
+ height: { control: 'text' },
+ rounded: { control: 'boolean' },
+ circle: { control: 'boolean' },
+ },
+ args: {
+ width: '100%',
+ height: '1rem',
+ rounded: true,
+ circle: false,
+ },
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Default: Story = {}
+
+export const TextLine: Story = {
+ args: { width: '200px', height: '1rem' },
+}
+
+export const Avatar: Story = {
+ args: { width: '40px', height: '40px', circle: true },
+}
+
+export const Card: Story = {
+ args: { width: '300px', height: '120px' },
+}
+
+export const CardLayout: Story = {
+ render: () => ({
+ components: { TdSkeleton },
+ template: `
+
+ `,
+ }),
+}
diff --git a/frontend/taskdeck-web/src/stories/TdSpinner.stories.ts b/frontend/taskdeck-web/src/stories/TdSpinner.stories.ts
new file mode 100644
index 000000000..249491326
--- /dev/null
+++ b/frontend/taskdeck-web/src/stories/TdSpinner.stories.ts
@@ -0,0 +1,49 @@
+import type { Meta, StoryObj } from '@storybook/vue3-vite'
+import TdSpinner from '../components/ui/TdSpinner.vue'
+
+const meta = {
+ title: 'UI Primitives/TdSpinner',
+ component: TdSpinner,
+ tags: ['autodocs'],
+ argTypes: {
+ size: {
+ control: 'select',
+ options: ['sm', 'md', 'lg'],
+ },
+ label: { control: 'text' },
+ },
+ args: {
+ size: 'md',
+ label: 'Loading',
+ },
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Default: Story = {}
+
+export const Small: Story = {
+ args: { size: 'sm', label: 'Loading...' },
+}
+
+export const Large: Story = {
+ args: { size: 'lg', label: 'Please wait' },
+}
+
+export const CustomLabel: Story = {
+ args: { label: 'Generating proposal...' },
+}
+
+export const AllSizes: Story = {
+ render: () => ({
+ components: { TdSpinner },
+ template: `
+
+
+
+
+
+ `,
+ }),
+}
diff --git a/frontend/taskdeck-web/src/stories/TdTag.stories.ts b/frontend/taskdeck-web/src/stories/TdTag.stories.ts
new file mode 100644
index 000000000..77360f6f5
--- /dev/null
+++ b/frontend/taskdeck-web/src/stories/TdTag.stories.ts
@@ -0,0 +1,70 @@
+import type { Meta, StoryObj } from '@storybook/vue3-vite'
+import TdTag from '../components/ui/TdTag.vue'
+
+const meta = {
+ title: 'UI Primitives/TdTag',
+ component: TdTag,
+ tags: ['autodocs'],
+ argTypes: {
+ color: { control: 'color' },
+ removable: { control: 'boolean' },
+ },
+ args: {
+ color: '',
+ removable: false,
+ },
+ render: (args) => ({
+ components: { TdTag },
+ setup() {
+ return { args }
+ },
+ template: 'feature',
+ }),
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Default: Story = {}
+
+export const CustomColor: Story = {
+ args: { color: '#4ade80' },
+ render: (args) => ({
+ components: { TdTag },
+ setup() { return { args } },
+ template: 'bug-fix',
+ }),
+}
+
+export const Removable: Story = {
+ args: { removable: true },
+ render: (args) => ({
+ components: { TdTag },
+ setup() { return { args } },
+ template: 'removable',
+ }),
+}
+
+export const RemovableWithColor: Story = {
+ args: { removable: true, color: '#fbbf24' },
+ render: (args) => ({
+ components: { TdTag },
+ setup() { return { args } },
+ template: 'priority',
+ }),
+}
+
+export const TagGroup: Story = {
+ render: () => ({
+ components: { TdTag },
+ template: `
+
+ frontend
+ feature
+ priority
+ bug
+ design
+
+ `,
+ }),
+}
diff --git a/frontend/taskdeck-web/src/stories/TdTextarea.stories.ts b/frontend/taskdeck-web/src/stories/TdTextarea.stories.ts
new file mode 100644
index 000000000..86b34a23f
--- /dev/null
+++ b/frontend/taskdeck-web/src/stories/TdTextarea.stories.ts
@@ -0,0 +1,49 @@
+import type { Meta, StoryObj } from '@storybook/vue3-vite'
+import TdTextarea from '../components/ui/TdTextarea.vue'
+
+const meta = {
+ title: 'UI Primitives/TdTextarea',
+ component: TdTextarea,
+ tags: ['autodocs'],
+ argTypes: {
+ disabled: { control: 'boolean' },
+ readonly: { control: 'boolean' },
+ error: { control: 'boolean' },
+ placeholder: { control: 'text' },
+ modelValue: { control: 'text' },
+ rows: { control: 'number' },
+ },
+ args: {
+ placeholder: 'Enter description...',
+ modelValue: '',
+ disabled: false,
+ readonly: false,
+ error: false,
+ rows: 3,
+ },
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Default: Story = {}
+
+export const WithValue: Story = {
+ args: { modelValue: 'This is a multi-line\ntextarea with content.' },
+}
+
+export const Error: Story = {
+ args: { error: true, modelValue: 'Invalid content' },
+}
+
+export const Disabled: Story = {
+ args: { disabled: true, modelValue: 'Cannot edit' },
+}
+
+export const Readonly: Story = {
+ args: { readonly: true, modelValue: 'Read-only content' },
+}
+
+export const TallTextarea: Story = {
+ args: { rows: 8, placeholder: 'More room to write...' },
+}
diff --git a/frontend/taskdeck-web/src/stories/TdToast.stories.ts b/frontend/taskdeck-web/src/stories/TdToast.stories.ts
new file mode 100644
index 000000000..5b6c0d976
--- /dev/null
+++ b/frontend/taskdeck-web/src/stories/TdToast.stories.ts
@@ -0,0 +1,58 @@
+import type { Meta, StoryObj } from '@storybook/vue3-vite'
+import TdToast from '../components/ui/TdToast.vue'
+
+const meta = {
+ title: 'UI Primitives/TdToast',
+ component: TdToast,
+ tags: ['autodocs'],
+ argTypes: {
+ variant: {
+ control: 'select',
+ options: ['info', 'success', 'warning', 'error'],
+ },
+ message: { control: 'text' },
+ dismissible: { control: 'boolean' },
+ },
+ args: {
+ variant: 'info',
+ message: 'This is a toast notification.',
+ dismissible: true,
+ },
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Info: Story = {
+ args: { variant: 'info', message: 'New proposal available for review.' },
+}
+
+export const Success: Story = {
+ args: { variant: 'success', message: 'Task created successfully.' },
+}
+
+export const Warning: Story = {
+ args: { variant: 'warning', message: 'Connection is unstable.' },
+}
+
+export const Error: Story = {
+ args: { variant: 'error', message: 'Failed to save changes.' },
+}
+
+export const NonDismissible: Story = {
+ args: { variant: 'info', message: 'Processing...', dismissible: false },
+}
+
+export const AllVariants: Story = {
+ render: () => ({
+ components: { TdToast },
+ template: `
+
+
+
+
+
+
+ `,
+ }),
+}
diff --git a/frontend/taskdeck-web/src/stories/TdTooltip.stories.ts b/frontend/taskdeck-web/src/stories/TdTooltip.stories.ts
new file mode 100644
index 000000000..8e0878109
--- /dev/null
+++ b/frontend/taskdeck-web/src/stories/TdTooltip.stories.ts
@@ -0,0 +1,58 @@
+import type { Meta, StoryObj } from '@storybook/vue3-vite'
+import TdTooltip from '../components/ui/TdTooltip.vue'
+import TdButton from '../components/ui/TdButton.vue'
+
+const meta = {
+ title: 'UI Primitives/TdTooltip',
+ component: TdTooltip,
+ tags: ['autodocs'],
+ argTypes: {
+ text: { control: 'text' },
+ position: {
+ control: 'select',
+ options: ['top', 'bottom', 'left', 'right'],
+ },
+ delay: { control: 'number' },
+ },
+ args: {
+ text: 'Tooltip text',
+ position: 'top',
+ delay: 300,
+ },
+ render: (args) => ({
+ components: { TdTooltip, TdButton },
+ setup() {
+ return { args }
+ },
+ template: `
+
+
+ Hover me
+
+
+ `,
+ }),
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Top: Story = {
+ args: { text: 'Tooltip on top', position: 'top' },
+}
+
+export const Bottom: Story = {
+ args: { text: 'Tooltip on bottom', position: 'bottom' },
+}
+
+export const Left: Story = {
+ args: { text: 'Tooltip on left', position: 'left' },
+}
+
+export const Right: Story = {
+ args: { text: 'Tooltip on right', position: 'right' },
+}
+
+export const NoDelay: Story = {
+ args: { text: 'Instant tooltip', delay: 0 },
+}
diff --git a/frontend/taskdeck-web/tsconfig.app.json b/frontend/taskdeck-web/tsconfig.app.json
index fbba24865..5c8dad5bd 100644
--- a/frontend/taskdeck-web/tsconfig.app.json
+++ b/frontend/taskdeck-web/tsconfig.app.json
@@ -13,5 +13,5 @@
"noUncheckedSideEffectImports": true
},
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"],
- "exclude": ["src/tests/**"]
+ "exclude": ["src/tests/**", "src/stories/**"]
}