@dreamboard-games/sdk 0.2.0 → 0.2.1-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ThemeProvider-fy0_QzgO.d.ts → ThemeProvider-BBMVT3KG.d.ts} +1 -1
- package/dist/attributes-BeRyboMS.d.ts +279 -0
- package/dist/browser-interaction.d.ts +708 -0
- package/dist/browser-interaction.js +106 -0
- package/dist/browser-interaction.js.map +1 -0
- package/dist/{bundle-TIZcw8LB.d.ts → bundle-CDd5FKeD.d.ts} +3 -1
- package/dist/{chunk-U5C6BONG.js → chunk-326PGVAA.js} +2 -2
- package/dist/{chunk-VFTAA4WO.js → chunk-MKXPVOUT.js} +4 -2
- package/dist/chunk-MKXPVOUT.js.map +1 -0
- package/dist/{chunk-GKKBPPSW.js → chunk-MZNVHMJ5.js} +4 -4
- package/dist/{chunk-KAELH4KC.js → chunk-NKCRKGR2.js} +2 -2
- package/dist/{chunk-WN74KVNY.js → chunk-PEI3FIL2.js} +2 -2
- package/dist/chunk-PEI3FIL2.js.map +1 -0
- package/dist/chunk-QLG6VEMW.js +1691 -0
- package/dist/chunk-QLG6VEMW.js.map +1 -0
- package/dist/{chunk-WYPQ3GG5.js → chunk-WG4JQL3S.js} +4 -1
- package/dist/{chunk-WYPQ3GG5.js.map → chunk-WG4JQL3S.js.map} +1 -1
- package/dist/{chunk-7YAHLYBR.js → chunk-XV6D3ET4.js} +8 -4
- package/dist/{chunk-7YAHLYBR.js.map → chunk-XV6D3ET4.js.map} +1 -1
- package/dist/{chunk-TDSWKVZ4.js → chunk-ZABVH7AO.js} +1236 -17
- package/dist/chunk-ZABVH7AO.js.map +1 -0
- package/dist/{components-D5ZRE2Hl.d.ts → components-BoiVSYqx.d.ts} +1 -1
- package/dist/generated/runtime/primitives.d.ts +5 -4
- package/dist/generated/runtime/primitives.js +4 -3
- package/dist/generated/runtime-api.d.ts +1 -1
- package/dist/generated/runtime.d.ts +5 -4
- package/dist/generated/runtime.js +7 -6
- package/dist/generated/workspace-contract.d.ts +5 -4
- package/dist/generated/workspace-contract.js +6 -5
- package/dist/{hex-board-view-D_07hO6O.d.ts → hex-board-view-1iAyJRFn.d.ts} +1 -0
- package/dist/index.js +1 -1
- package/dist/infrastructure/reducer-bundle-abi.d.ts +113 -113
- package/dist/infrastructure/reducer-bundle-abi.js +1 -1
- package/dist/package-set.d.ts +2 -2
- package/dist/package-set.js +1 -1
- package/dist/reducer.d.ts +1 -1
- package/dist/reducer.js +305 -12
- package/dist/reducer.js.map +1 -1
- package/dist/runtime/primitives.d.ts +6 -5
- package/dist/runtime/primitives.js +4 -3
- package/dist/runtime/workspace-contract.d.ts +6 -5
- package/dist/runtime/workspace-contract.js +6 -5
- package/dist/{runtime-api-DWxvTr-O.d.ts → runtime-api-CPLm_XDG.d.ts} +6 -0
- package/dist/runtime.d.ts +5 -4
- package/dist/runtime.js +6 -5
- package/dist/testing.d.ts +2 -2
- package/dist/ui/components.d.ts +2 -2
- package/dist/ui/components.js +1 -1
- package/dist/{ui-contract-iQfTtUSL.d.ts → ui-contract-rzKBwOLC.d.ts} +5 -3
- package/dist/ui.d.ts +5 -5
- package/dist/ui.js +2 -2
- package/package.json +15 -9
- package/src/browser-interaction/attributes.ts +211 -0
- package/src/browser-interaction/canonical.ts +77 -0
- package/src/browser-interaction/constants.ts +77 -0
- package/src/browser-interaction/effects.ts +176 -0
- package/src/browser-interaction/index.ts +111 -0
- package/src/browser-interaction/normalize.ts +997 -0
- package/src/browser-interaction/registry.ts +70 -0
- package/src/browser-interaction/resolve.ts +596 -0
- package/src/browser-interaction/schemas.ts +152 -0
- package/src/browser-interaction/types.ts +304 -0
- package/src/browser-interaction.ts +1 -0
- package/src/generated/reducer-contract/wire.ts +1 -1
- package/src/generated/reducer-contract/zod.ts +3 -1
- package/src/package-set.ts +1 -1
- package/src/reducer/bundle/ingress-bundle.ts +1 -1
- package/src/reducer/bundle/trusted/interaction-types.ts +3 -0
- package/src/reducer/bundle/trusted/projection-builder.ts +337 -13
- package/src/reducer/ingress/input-codec.ts +1 -1
- package/src/reducer/ingress/session-codec.ts +1 -1
- package/src/runtime-internal/components/InteractionForm.tsx +345 -7
- package/src/runtime-internal/components/PluginRuntime.tsx +2 -0
- package/src/runtime-internal/components/board/target-layer.ts +2 -0
- package/src/runtime-internal/context/PluginStateContext.tsx +41 -0
- package/src/runtime-internal/hooks/useBoardInteractions.ts +73 -11
- package/src/runtime-internal/primitives/board.tsx +71 -0
- package/src/runtime-internal/primitives/interaction.tsx +160 -1
- package/src/runtime-internal/types/plugin-state.ts +6 -0
- package/src/runtime-internal/utils/browser-interaction-effects.ts +240 -0
- package/src/runtime-internal/utils/interaction-draft-digest.ts +252 -0
- package/src/runtime-internal/utils/semantic-projection-digest.ts +407 -0
- package/src/ui/components/board/HexGrid.tsx +3 -0
- package/src/ui/components/board/target-layer.ts +1 -0
- package/dist/chunk-TDSWKVZ4.js.map +0 -1
- package/dist/chunk-VFTAA4WO.js.map +0 -1
- package/dist/chunk-WN74KVNY.js.map +0 -1
- /package/dist/{chunk-U5C6BONG.js.map → chunk-326PGVAA.js.map} +0 -0
- /package/dist/{chunk-GKKBPPSW.js.map → chunk-MZNVHMJ5.js.map} +0 -0
- /package/dist/{chunk-KAELH4KC.js.map → chunk-NKCRKGR2.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ui/hooks/usePanZoom.ts","../src/ui/hooks/useIsMobile.ts","../src/ui/theme/tokens.ts","../src/ui/theme/presets/tabletop.ts","../src/ui/theme/presets/arcade.ts","../src/ui/theme/presets/studio.ts","../src/ui/theme/css-vars.ts","../src/ui/theme/ThemeProvider.tsx","../src/ui/theme/derive.ts","../src/ui/types/tiled-board.ts","../src/ui/types/visual-state.ts","../src/ui/components/Card.tsx","../src/ui/components/Drawer.tsx","../src/ui/components/ChromeSuppressionContext.tsx","../src/ui/components/ThemedButton.tsx","../src/ui/internal/ui/button.tsx","../src/ui/internal/ui/utils.ts","../src/ui/components/HandDock.tsx","../src/ui/components/Hand.tsx","../src/ui/hooks/useHandLayout.ts","../src/ui/components/StagingZone.tsx","../src/ui/components/CardDragSurface.tsx","../src/ui/components/HandView.tsx","../src/ui/hooks/useHandPresentation.ts","../src/ui/components/hand-layout-math.ts","../src/ui/hooks/useHandCardPointer.ts","../src/ui/components/hand-pointer-engine.ts","../src/ui/components/MobileHandTray.tsx","../src/ui/components/PlayArea.tsx","../src/ui/components/GameSkeleton.tsx","../src/ui/components/Toast.tsx","../src/ui/internal/ui/alert.tsx","../src/ui/components/ErrorBoundary.tsx","../src/ui/internal/ui/dialog.tsx","../src/ui/internal/ui/input.tsx","../src/ui/internal/ui/label.tsx","../src/ui/internal/ui/select.tsx","../src/ui/components/ResourceCounter.tsx","../src/ui/components/CostDisplay.tsx","../src/ui/internal/ui/tooltip.tsx","../src/ui/components/ActionButton.tsx","../src/ui/components/PrimaryButton.tsx","../src/ui/components/PrimaryActionButton.tsx","../src/ui/components/ActionPanel.tsx","../src/ui/components/MoreActions.tsx","../src/ui/components/DiceRoller.tsx","../src/ui/primitives/dice.tsx","../src/ui/components/PhaseIndicator.tsx","../src/ui/components/GameEndDisplay.tsx","../src/ui/components/board/NetworkGraph.tsx","../src/ui/components/board/interaction-accessibility.ts","../src/ui/components/board/ZoneMap.tsx","../src/ui/components/board/TrackBoard.tsx","../src/ui/components/board/SlotSystem.tsx","../src/ui/components/board/SquareGrid.tsx","../src/ui/components/board/target-layer.ts","../src/ui/components/board/HexGrid.tsx","../src/ui/components/board/hex-board-view.ts"],"sourcesContent":["/**\n * usePanZoom hook - Unified pan and zoom gestures using @use-gesture/react\n *\n * Provides a declarative API for pan and zoom interactions on board components.\n * Works with both SVG (via viewBox) and HTML (via CSS transforms) elements.\n *\n * Features:\n * - Single finger/mouse drag for panning\n * - Pinch-to-zoom on touch devices\n * - Mouse wheel zoom on desktop\n * - Configurable zoom limits\n * - Optional momentum/inertia\n *\n * @example SVG usage (NetworkGraph, HexGrid, etc.)\n * ```tsx\n * const { transform, bind, resetTransform } = usePanZoom({\n * enabled: enablePanZoom,\n * minZoom: 0.5,\n * maxZoom: 3,\n * });\n *\n * // Apply to viewBox calculation\n * const viewBoxWidth = contentWidth / transform.zoom;\n * const viewBoxX = baseX - transform.pan.x;\n *\n * <svg {...bind()} style={{ touchAction: 'none' }}>\n * ...\n * </svg>\n * ```\n *\n * @example HTML usage (SlotSystem, etc.)\n * ```tsx\n * const { transform, bind, style } = usePanZoom({\n * enabled: enablePanZoom,\n * mode: 'css',\n * });\n *\n * <div {...bind()} style={{ ...style, touchAction: 'none' }}>\n * ...\n * </div>\n * ```\n */\n\nimport { useState, useCallback, useEffect, useMemo } from \"react\";\nimport { useGesture, type Handler } from \"@use-gesture/react\";\n\nexport interface PanZoomTransform {\n /** Current zoom level (1 = 100%) */\n zoom: number;\n /** Current pan offset */\n pan: { x: number; y: number };\n}\n\nexport interface UsePanZoomOptions {\n /** Whether pan/zoom is enabled */\n enabled?: boolean;\n /** Initial zoom level */\n initialZoom?: number;\n /** Minimum zoom level */\n minZoom?: number;\n /** Maximum zoom level */\n maxZoom?: number;\n /** Initial pan offset */\n initialPan?: { x: number; y: number };\n /** Transform mode: 'viewbox' for SVG, 'css' for HTML elements */\n mode?: \"viewbox\" | \"css\";\n /** Zoom sensitivity for wheel events (default: 0.002) */\n wheelSensitivity?: number;\n /** Called when transform changes */\n onTransformChange?: (transform: PanZoomTransform) => void;\n}\n\n/** Type for gesture bind function that returns props to spread on element\n * Note: We omit ref from the return type to avoid conflicts with explicit refs on elements.\n * The gesture library handles its own internal ref binding.\n */\ntype GestureBindFunction = () => Omit<React.HTMLAttributes<Element>, \"ref\">;\n\nexport interface UsePanZoomReturn {\n /** Current transform state */\n transform: PanZoomTransform;\n /** Gesture handlers to spread on the target element - always returns spreadable props */\n bind: GestureBindFunction;\n /** Reset transform to initial values */\n resetTransform: () => void;\n /** Set zoom programmatically */\n setZoom: (zoom: number) => void;\n /** Set pan programmatically */\n setPan: (pan: { x: number; y: number }) => void;\n /** CSS transform style (for mode: 'css') */\n style: React.CSSProperties;\n /** Whether currently dragging/panning */\n isDragging: boolean;\n /** Whether currently pinching */\n isPinching: boolean;\n}\n\n/**\n * Hook for pan and zoom gestures on board components\n */\nexport function usePanZoom(options: UsePanZoomOptions = {}): UsePanZoomReturn {\n const {\n enabled = true,\n initialZoom = 1,\n minZoom = 0.5,\n maxZoom = 3,\n initialPan = { x: 0, y: 0 },\n mode = \"viewbox\",\n wheelSensitivity = 0.002,\n onTransformChange,\n } = options;\n\n const [zoom, setZoomState] = useState(initialZoom);\n const [pan, setPanState] = useState(initialPan);\n const [isDragging, setIsDragging] = useState(false);\n const [isPinching, setIsPinching] = useState(false);\n\n // Clamp zoom to bounds\n const clampZoom = useCallback(\n (z: number) => Math.min(maxZoom, Math.max(minZoom, z)),\n [minZoom, maxZoom],\n );\n\n // Update transform and notify\n const updateTransform = useCallback(\n (newZoom: number, newPan: { x: number; y: number }) => {\n const clampedZoom = clampZoom(newZoom);\n setZoomState(clampedZoom);\n setPanState(newPan);\n onTransformChange?.({ zoom: clampedZoom, pan: newPan });\n },\n [clampZoom, onTransformChange],\n );\n\n // Gesture bindings\n const bind = useGesture(\n {\n onDrag: (({\n delta: [dx, dy],\n active,\n pinching,\n }: Parameters<Handler<\"drag\">>[0]) => {\n if (!enabled || pinching) return;\n\n setIsDragging(active);\n\n if (active) {\n // For viewbox mode, we invert and scale the delta\n // For CSS mode, we apply directly\n const scaleFactor = mode === \"viewbox\" ? 1 / zoom : 1;\n setPanState((prev) => ({\n x: prev.x + dx * scaleFactor,\n y: prev.y + dy * scaleFactor,\n }));\n }\n }) as Handler<\"drag\">,\n onPinch: (({\n offset: [scale],\n active,\n }: Parameters<Handler<\"pinch\">>[0]) => {\n if (!enabled) return;\n\n setIsPinching(active);\n\n if (active) {\n const newZoom = clampZoom(scale);\n setZoomState(newZoom);\n onTransformChange?.({ zoom: newZoom, pan });\n }\n }) as Handler<\"pinch\">,\n onWheel: (({ delta: [, dy], event }: Parameters<Handler<\"wheel\">>[0]) => {\n if (!enabled) return;\n\n event.preventDefault();\n const newZoom = clampZoom(zoom - dy * wheelSensitivity);\n setZoomState(newZoom);\n onTransformChange?.({ zoom: newZoom, pan });\n }) as Handler<\"wheel\">,\n },\n {\n drag: {\n enabled,\n filterTaps: true,\n },\n pinch: {\n enabled,\n scaleBounds: { min: minZoom, max: maxZoom },\n from: () => [zoom, 0],\n },\n wheel: {\n enabled,\n eventOptions: { passive: false },\n },\n },\n );\n\n // Reset to initial values\n const resetTransform = useCallback(() => {\n updateTransform(initialZoom, initialPan);\n }, [initialZoom, initialPan, updateTransform]);\n\n useEffect(() => {\n updateTransform(initialZoom, initialPan);\n }, [initialZoom, initialPan.x, initialPan.y, updateTransform]);\n\n // Programmatic setters\n const setZoom = useCallback(\n (newZoom: number) => {\n updateTransform(clampZoom(newZoom), pan);\n },\n [pan, clampZoom, updateTransform],\n );\n\n const setPan = useCallback(\n (newPan: { x: number; y: number }) => {\n updateTransform(zoom, newPan);\n },\n [zoom, updateTransform],\n );\n\n // CSS transform style for HTML mode\n const style = useMemo<React.CSSProperties>(\n () =>\n mode === \"css\"\n ? {\n transform: `translate(${pan.x}px, ${pan.y}px) scale(${zoom})`,\n transformOrigin: \"center center\",\n }\n : {},\n [mode, pan.x, pan.y, zoom],\n );\n\n // Current transform state\n const transform = useMemo<PanZoomTransform>(\n () => ({ zoom, pan }),\n [zoom, pan],\n );\n\n // Wrap bind to ensure it always returns spreadable props (never void)\n // We exclude 'ref' from the result to avoid type conflicts with explicit element refs\n const safeBind: GestureBindFunction = useCallback(() => {\n const result = bind();\n // If bind returns void (shouldn't happen with our config), return empty object\n // Destructure to omit ref, avoiding type conflicts with SVG/HTML element refs\n\n const { ref: _ref, ...propsWithoutRef } = (result ??\n {}) as React.HTMLAttributes<Element> & { ref?: unknown };\n return propsWithoutRef;\n }, [bind]);\n\n return {\n transform,\n bind: safeBind,\n resetTransform,\n setZoom,\n setPan,\n style,\n isDragging,\n isPinching,\n };\n}\n\n/**\n * Helper to calculate SVG viewBox with pan/zoom applied\n */\nexport function calculateViewBox(\n bounds: { minX: number; minY: number; width: number; height: number },\n transform: PanZoomTransform,\n): string {\n const viewBoxWidth = bounds.width / transform.zoom;\n const viewBoxHeight = bounds.height / transform.zoom;\n const viewBoxX =\n bounds.minX + (bounds.width - viewBoxWidth) / 2 - transform.pan.x;\n const viewBoxY =\n bounds.minY + (bounds.height - viewBoxHeight) / 2 - transform.pan.y;\n\n return `${viewBoxX} ${viewBoxY} ${viewBoxWidth} ${viewBoxHeight}`;\n}\n","import { useState, useEffect } from \"react\";\n\nconst MOBILE_BREAKPOINT = 768;\n\n/**\n * Hook to detect if the user is on a mobile/small screen device\n * @param breakpoint - The width threshold in pixels (default: 768)\n * @returns boolean indicating if the screen is mobile-sized\n */\nexport function useIsMobile(breakpoint: number = MOBILE_BREAKPOINT): boolean {\n const [isMobile, setIsMobile] = useState(() => {\n // SSR-safe: default to false if window is not available\n if (typeof window === \"undefined\") return false;\n return window.innerWidth < breakpoint;\n });\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n const mediaQuery = window.matchMedia(`(max-width: ${breakpoint - 1}px)`);\n\n const handleChange = (e: MediaQueryListEvent | MediaQueryList) => {\n setIsMobile(e.matches);\n };\n\n // Set initial value\n handleChange(mediaQuery);\n\n // Listen for changes\n mediaQuery.addEventListener(\"change\", handleChange);\n return () => mediaQuery.removeEventListener(\"change\", handleChange);\n }, [breakpoint]);\n\n return isMobile;\n}\n","/**\n * Token contract for `@dreamboard-games/sdk/ui`.\n *\n * The {@link Theme} object is the only thing components consume for\n * visual styling. Every preset (tabletop, arcade, studio) is just a\n * different fully-resolved {@link Theme}; every author override is a\n * deep partial of it. Components never inline hex codes, font stacks,\n * or shadow strings — they read from `useTheme()` (or, when written in\n * Tailwind, from CSS variables that the {@link ThemeProvider} writes\n * onto its wrapper element).\n *\n * Architectural rules:\n *\n * 1. **Foundation → Semantic → Component.** Foundation palette ramps\n * (`color.neutral`, `color.brand`, …) are never read directly by\n * components. Components read `semantic.*` (e.g. `surface.card`,\n * `intent.primary`) which the preset maps from foundation tokens.\n * 2. **No optional deep keys.** Presets must supply every leaf so\n * components don't need fallbacks. Author-supplied overrides are\n * `DeepPartial<Theme>` and merged before the provider mounts.\n * 3. **Scalar leaves only.** Every leaf is a string (CSS-ready) so the\n * serializer can emit a CSS variable for it without per-token\n * formatting logic.\n */\n\n/** Identity-only metadata. */\nexport interface ThemeMeta {\n /** Stable id used by `data-dreamboard-theme` and CSS-var scoping. */\n readonly id: string;\n /** Human-readable name for dev tools. */\n readonly name: string;\n /**\n * Render mode hint for components that need to choose between light\n * and dark sub-tokens. Presets pick one; authors don't toggle this.\n */\n readonly mode: \"light\" | \"dark\";\n}\n\n/** Foundation color ramp. Six stops keeps presets compact. */\nexport interface ColorRamp {\n readonly 50: string;\n readonly 100: string;\n readonly 200: string;\n readonly 400: string;\n readonly 600: string;\n readonly 800: string;\n readonly 950: string;\n}\n\n/**\n * Per-player color tokens. The {@link Theme.player} array is indexed by\n * 0-based seat slot (`player[0]` = first seat). Each entry carries a\n * `solid` brand color, a `soft` tint usable as a background, and `on`\n * — the recommended foreground when text sits on `solid`.\n */\nexport interface PlayerColor {\n readonly solid: string;\n readonly soft: string;\n readonly on: string;\n}\n\n/**\n * Foundation palette. Components never read this directly; presets map\n * these into {@link SemanticTokens}. Exposed so authors who write a\n * full theme can compose without inventing their own palette type.\n */\nexport interface FoundationColor {\n readonly neutral: ColorRamp;\n readonly brand: ColorRamp;\n readonly accent: ColorRamp;\n readonly success: ColorRamp;\n readonly warning: ColorRamp;\n readonly danger: ColorRamp;\n readonly info: ColorRamp;\n}\n\n/**\n * Semantic colors consumed by every component. These are the *only*\n * color tokens components should reference. Names describe role\n * (\"the surface a player card sits on\"), not appearance (\"light grey\").\n */\nexport interface SemanticColor {\n readonly surface: {\n /** Outermost shell background. */\n readonly app: string;\n /** Board canvas background (behind tiles). */\n readonly board: string;\n /** HUD chrome panels (top bar, action bar, side rails). */\n readonly hud: string;\n /** Standalone cards (player cards, action cards, hand cards). */\n readonly card: string;\n /** Modal/sheet body. */\n readonly sheet: string;\n /** Scrim behind a blocker overlay. */\n readonly overlay: string;\n /** Subtle inset (resource pills, count badges, …). */\n readonly inset: string;\n };\n readonly text: {\n /** Default body and headline text on light surfaces. */\n readonly primary: string;\n /** De-emphasised metadata, hint copy, captions. */\n readonly muted: string;\n /** Text used on `intent.primary` solid backgrounds. */\n readonly onIntent: string;\n /** Brand-tinted text for emphasis (links, key numbers). */\n readonly accent: string;\n /** Disabled text (button labels in disabled state). */\n readonly disabled: string;\n };\n readonly border: {\n /** Hairline divider between sibling rows. */\n readonly subtle: string;\n /** Standard card / panel border. */\n readonly default: string;\n /** Outlined emphasis (hovered tiles, selected card). */\n readonly strong: string;\n /** Focus ring (keyboard nav). */\n readonly focus: string;\n };\n /**\n * Intent colours map to action emphasis. Components pick a slot\n * (`primary` for \"do the main thing now\", `danger` for destructive\n * confirms, etc.) and read both the surface and on-color from it.\n */\n readonly intent: {\n readonly primary: IntentColor;\n readonly secondary: IntentColor;\n readonly success: IntentColor;\n readonly danger: IntentColor;\n readonly warning: IntentColor;\n readonly info: IntentColor;\n };\n}\n\n/** A semantic intent (button background + matching foreground + soft tint). */\nexport interface IntentColor {\n /** Solid fill (button bg, badge bg). */\n readonly solid: string;\n /** Recommended text/icon color sitting on `solid`. */\n readonly on: string;\n /** Subtle tint (e.g. badge bg with `text` for foreground). */\n readonly soft: string;\n /** Suitable foreground when sitting on `soft`. */\n readonly onSoft: string;\n /** Border tint matched to this intent (e.g. focus ring on intent). */\n readonly border: string;\n}\n\n/** Border-radius ramp. */\nexport interface Radius {\n readonly none: string;\n readonly sm: string;\n readonly md: string;\n readonly lg: string;\n /** HUD chrome (top bar pieces, action-bar bar). */\n readonly hud: string;\n /** Fully-round badges/pills. */\n readonly pill: string;\n}\n\n/** Spacing ramp (rem-based by default). */\nexport interface Space {\n readonly 0: string;\n readonly 0.5: string;\n readonly 1: string;\n readonly 1.5: string;\n readonly 2: string;\n readonly 3: string;\n readonly 4: string;\n readonly 6: string;\n readonly 8: string;\n readonly 12: string;\n}\n\n/** Typography tokens. */\nexport interface Typography {\n readonly fontFamily: {\n /** Hero text — phase name, scoreboard headline, winner banner. */\n readonly display: string;\n /** Default UI body text. */\n readonly body: string;\n /** Numeric runs (scores, counters, tabular data). Tabular figures preferred. */\n readonly tabular: string;\n /** Source/code/raw-id rendering. */\n readonly mono: string;\n };\n readonly fontSize: {\n readonly xs: string;\n readonly sm: string;\n readonly md: string;\n readonly lg: string;\n readonly xl: string;\n readonly \"2xl\": string;\n readonly \"3xl\": string;\n };\n readonly fontWeight: {\n readonly regular: string;\n readonly medium: string;\n readonly bold: string;\n };\n readonly lineHeight: {\n readonly tight: string;\n readonly normal: string;\n readonly relaxed: string;\n };\n readonly letterSpacing: {\n readonly tight: string;\n readonly normal: string;\n readonly wide: string;\n /** All-caps labels (\"YOUR TURN\"). */\n readonly caps: string;\n };\n}\n\n/** Drop-shadow elevation ramp. */\nexport interface Elevation {\n /** Resting state (cards, panels). */\n readonly rest: string;\n /** Hover-lift (interactive cards). */\n readonly hover: string;\n /** Selected / dragged element. */\n readonly lifted: string;\n /** Modal / overlay stack. */\n readonly overlay: string;\n /** Inner shadow (board canvas inset, resource pill well). */\n readonly inset: string;\n}\n\n/**\n * Motion tokens. Components import durations and easings from here so a\n * single `prefers-reduced-motion` switch zeroes everything out at the\n * provider, not per-component.\n */\nexport interface Motion {\n readonly duration: {\n /** Hover, focus, micro-press (~80ms). */\n readonly fast: string;\n /** Default — most state changes (~160ms). */\n readonly normal: string;\n /** Layout shifts, drawer open/close (~280ms). */\n readonly slow: string;\n /**\n * Looping ambient pulses — active-player breath, dice glow.\n * Components should respect `motion.reducedMotion` before kicking\n * off looping animations.\n */\n readonly ambient: string;\n };\n readonly easing: {\n /** Default for entering / settling. */\n readonly out: string;\n /** Default for exiting. */\n readonly in: string;\n /** Symmetric. */\n readonly inOut: string;\n /** Springy — selected card lift, active-player wobble. */\n readonly spring: string;\n };\n /**\n * `\"true\"` when the active client requests reduced motion. Components\n * should branch on this rather than forcing animations off via CSS,\n * because some animations (e.g. dice roll, shuffle) are critical for\n * conveying state and need a static fallback.\n */\n readonly reducedMotion: \"true\" | \"false\";\n}\n\n/**\n * Component-level token slots derived from semantic + foundation tokens.\n * Kept intentionally tiny — a slot is added here only when a component\n * needs to deviate from the semantic mapping in a way that authors\n * should be able to customise without re-skinning the whole intent\n * scale.\n */\nexport interface ComponentTokens {\n readonly board: {\n /** Outer ring around the board canvas. */\n readonly frameBorder: string;\n /** Inner board surface tint (overlays the canvas tile renderer). */\n readonly frameBackground: string;\n /** Highlight ring drawn on hovered interactive targets. */\n readonly hoverRing: string;\n /** Idle hint colour for eligible-but-unhovered targets. */\n readonly eligibleHint: string;\n };\n readonly card: {\n /** Border drawn around face-up cards. */\n readonly border: string;\n /** Border drawn around face-down cards. */\n readonly backBorder: string;\n /** Card-back fill colour. */\n readonly backBackground: string;\n /** Selected outline. */\n readonly selectedRing: string;\n };\n readonly playerCard: {\n /** Background of the active-player card. */\n readonly activeBackground: string;\n /** Border of the active-player card. */\n readonly activeBorder: string;\n /** Glow colour radiated by the active-player card. */\n readonly activeGlow: string;\n /** Background of the \"you\" badge. */\n readonly youBadgeBackground: string;\n /** Foreground of the \"you\" badge. */\n readonly youBadgeForeground: string;\n };\n readonly toast: {\n readonly successBackground: string;\n readonly errorBackground: string;\n readonly infoBackground: string;\n readonly foreground: string;\n };\n}\n\n/**\n * The complete theme contract. Every leaf is a CSS-ready string so the\n * provider can emit a CSS variable for each path without per-leaf\n * formatting. {@link DeepPartial} is exported for author overrides.\n */\nexport interface Theme {\n readonly meta: ThemeMeta;\n readonly color: FoundationColor;\n readonly semantic: SemanticColor;\n readonly radius: Radius;\n readonly space: Space;\n readonly typography: Typography;\n readonly elevation: Elevation;\n readonly motion: Motion;\n readonly player: readonly [\n PlayerColor,\n PlayerColor,\n PlayerColor,\n PlayerColor,\n PlayerColor,\n PlayerColor,\n ];\n readonly component: ComponentTokens;\n}\n\n/**\n * Recursive partial for theme overrides. Authors pass this to\n * `<ThemeProvider override={...}/>` (or to a preset's `extend`\n * helper) to tweak individual tokens without re-declaring the whole\n * tree.\n */\nexport type ThemeOverride = DeepPartial<Theme>;\n\ntype DeepPartial<T> =\n T extends ReadonlyArray<infer U>\n ? ReadonlyArray<DeepPartial<U>>\n : T extends object\n ? { readonly [K in keyof T]?: DeepPartial<T[K]> }\n : T;\n\n/**\n * Deep merge for {@link Theme} overrides. Arrays (notably\n * {@link Theme.player}) are *replaced* rather than merged so callers\n * can't accidentally end up with mixed-preset palettes.\n */\nexport function mergeTheme(base: Theme, override?: ThemeOverride): Theme {\n if (!override) return base;\n return mergeDeep(base, override) as Theme;\n}\n\nfunction mergeDeep<T>(base: T, override: unknown): T {\n if (Array.isArray(override)) {\n // Arrays replace wholesale — see contract docs.\n return override as T;\n }\n if (\n base &&\n typeof base === \"object\" &&\n override &&\n typeof override === \"object\" &&\n !Array.isArray(base)\n ) {\n const result: Record<string, unknown> = {\n ...(base as Record<string, unknown>),\n };\n for (const [key, value] of Object.entries(\n override as Record<string, unknown>,\n )) {\n if (value === undefined) continue;\n const baseValue = (base as Record<string, unknown>)[key];\n result[key] = mergeDeep(baseValue, value);\n }\n return result as T;\n }\n return override === undefined ? base : (override as T);\n}\n","import type { Theme } from \"../tokens.js\";\n\n/**\n * `tabletop` — the default Dreamboard theme.\n *\n * Visual identity: warm paper backgrounds, deep ink-blue brand,\n * confident type, rounded but disciplined corners. Designed to feel\n * like a polished hobby-game client (Splendor digital, modern Catan\n * apps) without leaning into a specific game's IP.\n *\n * Picked deliberately for the default: a board game UI sitting on\n * cool grey or pure white reads as \"spreadsheet\"; warm parchment\n * cues \"play\" without sliding into kitsch.\n */\nexport const tabletopTheme: Theme = {\n meta: {\n id: \"tabletop\",\n name: \"Tabletop\",\n mode: \"light\",\n },\n color: {\n neutral: {\n 50: \"#fbf8f1\",\n 100: \"#f4ecd8\",\n 200: \"#e7dcc1\",\n 400: \"#a89c84\",\n 600: \"#5f5547\",\n 800: \"#2f2a22\",\n 950: \"#15120d\",\n },\n brand: {\n 50: \"#eef3fb\",\n 100: \"#d3e0f3\",\n 200: \"#a7c1e7\",\n 400: \"#5780bf\",\n 600: \"#2d5da1\",\n 800: \"#1a3c6b\",\n 950: \"#0d1f37\",\n },\n accent: {\n 50: \"#fff5e0\",\n 100: \"#ffe5b3\",\n 200: \"#fcd07a\",\n 400: \"#f0a738\",\n 600: \"#c87a16\",\n 800: \"#7e4a08\",\n 950: \"#3c2103\",\n },\n success: {\n 50: \"#e8f6ec\",\n 100: \"#c4ecd0\",\n 200: \"#8fd6a3\",\n 400: \"#3fae62\",\n 600: \"#1f7d3e\",\n 800: \"#0d4a23\",\n 950: \"#062213\",\n },\n warning: {\n 50: \"#fff5dc\",\n 100: \"#ffe7a8\",\n 200: \"#fad164\",\n 400: \"#dca41a\",\n 600: \"#9c6f06\",\n 800: \"#5b4002\",\n 950: \"#2b1d00\",\n },\n danger: {\n 50: \"#fdecec\",\n 100: \"#f9c7c7\",\n 200: \"#f08e8e\",\n 400: \"#d53f3f\",\n 600: \"#a31d1d\",\n 800: \"#5e0d0d\",\n 950: \"#2a0404\",\n },\n info: {\n 50: \"#e6f5fb\",\n 100: \"#bfe3f4\",\n 200: \"#7ec5e6\",\n 400: \"#2f8fc4\",\n 600: \"#0d5e8a\",\n 800: \"#073650\",\n 950: \"#021a26\",\n },\n },\n semantic: {\n surface: {\n app: \"#f6efe0\",\n board: \"#1a3552\",\n hud: \"#fbf8f1\",\n card: \"#ffffff\",\n sheet: \"#fbf8f1\",\n overlay: \"rgba(15, 23, 42, 0.55)\",\n inset: \"#f4ecd8\",\n },\n text: {\n primary: \"#2f2a22\",\n muted: \"#5f5547\",\n onIntent: \"#ffffff\",\n accent: \"#1a3c6b\",\n disabled: \"#a89c84\",\n },\n border: {\n subtle: \"#e7dcc1\",\n default: \"#a89c84\",\n strong: \"#5f5547\",\n focus: \"#2d5da1\",\n },\n intent: {\n primary: {\n solid: \"#2d5da1\",\n on: \"#ffffff\",\n soft: \"#d3e0f3\",\n onSoft: \"#1a3c6b\",\n border: \"#1a3c6b\",\n },\n secondary: {\n solid: \"#fbf8f1\",\n on: \"#2f2a22\",\n soft: \"#f4ecd8\",\n onSoft: \"#2f2a22\",\n border: \"#a89c84\",\n },\n success: {\n solid: \"#1f7d3e\",\n on: \"#ffffff\",\n soft: \"#c4ecd0\",\n onSoft: \"#0d4a23\",\n border: \"#0d4a23\",\n },\n danger: {\n solid: \"#a31d1d\",\n on: \"#ffffff\",\n soft: \"#f9c7c7\",\n onSoft: \"#5e0d0d\",\n border: \"#5e0d0d\",\n },\n warning: {\n solid: \"#dca41a\",\n on: \"#2f2a22\",\n soft: \"#ffe7a8\",\n onSoft: \"#5b4002\",\n border: \"#9c6f06\",\n },\n info: {\n solid: \"#0d5e8a\",\n on: \"#ffffff\",\n soft: \"#bfe3f4\",\n onSoft: \"#073650\",\n border: \"#073650\",\n },\n },\n },\n radius: {\n none: \"0px\",\n sm: \"6px\",\n md: \"10px\",\n lg: \"16px\",\n hud: \"20px\",\n pill: \"9999px\",\n },\n space: {\n 0: \"0\",\n 0.5: \"0.125rem\",\n 1: \"0.25rem\",\n 1.5: \"0.375rem\",\n 2: \"0.5rem\",\n 3: \"0.75rem\",\n 4: \"1rem\",\n 6: \"1.5rem\",\n 8: \"2rem\",\n 12: \"3rem\",\n },\n typography: {\n fontFamily: {\n display:\n '\"Fraunces\", \"Iowan Old Style\", \"Source Serif Pro\", \"Georgia\", serif',\n body: '\"Inter\", \"SF Pro Text\", system-ui, -apple-system, sans-serif',\n tabular: '\"JetBrains Mono\", \"SF Mono\", \"ui-monospace\", monospace',\n mono: '\"JetBrains Mono\", \"SF Mono\", \"ui-monospace\", monospace',\n },\n fontSize: {\n xs: \"0.6875rem\",\n sm: \"0.8125rem\",\n md: \"0.9375rem\",\n lg: \"1.0625rem\",\n xl: \"1.25rem\",\n \"2xl\": \"1.5rem\",\n \"3xl\": \"2rem\",\n },\n fontWeight: {\n regular: \"400\",\n medium: \"500\",\n bold: \"700\",\n },\n lineHeight: {\n tight: \"1.15\",\n normal: \"1.4\",\n relaxed: \"1.6\",\n },\n letterSpacing: {\n tight: \"-0.01em\",\n normal: \"0\",\n wide: \"0.04em\",\n caps: \"0.14em\",\n },\n },\n elevation: {\n rest: \"0 1px 0 rgba(15, 18, 13, 0.06), 0 2px 6px rgba(15, 18, 13, 0.05)\",\n hover: \"0 4px 0 rgba(15, 18, 13, 0.05), 0 8px 18px rgba(15, 18, 13, 0.12)\",\n lifted:\n \"0 12px 0 rgba(15, 18, 13, 0.05), 0 18px 36px rgba(15, 18, 13, 0.18)\",\n overlay: \"0 24px 64px rgba(15, 18, 13, 0.32)\",\n inset: \"inset 0 1px 0 rgba(15, 18, 13, 0.08)\",\n },\n motion: {\n duration: {\n fast: \"80ms\",\n normal: \"160ms\",\n slow: \"280ms\",\n ambient: \"1800ms\",\n },\n easing: {\n out: \"cubic-bezier(0.16, 1, 0.3, 1)\",\n in: \"cubic-bezier(0.4, 0, 1, 0.4)\",\n inOut: \"cubic-bezier(0.65, 0, 0.35, 1)\",\n spring: \"cubic-bezier(0.34, 1.56, 0.64, 1)\",\n },\n reducedMotion: \"false\",\n },\n player: [\n { solid: \"#d04848\", soft: \"#fcdedd\", on: \"#ffffff\" },\n { solid: \"#2d5da1\", soft: \"#d3e0f3\", on: \"#ffffff\" },\n { solid: \"#1f7d3e\", soft: \"#c4ecd0\", on: \"#ffffff\" },\n { solid: \"#c87a16\", soft: \"#ffe5b3\", on: \"#2f2a22\" },\n { solid: \"#7d4a8a\", soft: \"#e6d6ee\", on: \"#ffffff\" },\n { solid: \"#0d5e8a\", soft: \"#bfe3f4\", on: \"#ffffff\" },\n ],\n component: {\n board: {\n frameBorder: \"#a89c84\",\n frameBackground: \"#1a3552\",\n hoverRing: \"#f0a738\",\n eligibleHint: \"rgba(240, 167, 56, 0.55)\",\n },\n card: {\n border: \"#2f2a22\",\n backBorder: \"#1a3c6b\",\n backBackground: \"#2d5da1\",\n selectedRing: \"#d04848\",\n },\n playerCard: {\n activeBackground: \"#fff5e0\",\n activeBorder: \"#f0a738\",\n activeGlow: \"rgba(240, 167, 56, 0.32)\",\n youBadgeBackground: \"#d3e0f3\",\n youBadgeForeground: \"#1a3c6b\",\n },\n toast: {\n successBackground: \"#1f7d3e\",\n errorBackground: \"#a31d1d\",\n infoBackground: \"#0d5e8a\",\n foreground: \"#ffffff\",\n },\n },\n};\n","import type { Theme } from \"../tokens.js\";\n\n/**\n * `arcade` — high-contrast neon theme for fast/competitive games.\n *\n * Visual identity: deep slate background, electric cyan/magenta\n * intents, square-ish corners, sharp drop shadows. Designed to evoke\n * action games and to keep critical CTAs popping at a glance.\n */\nexport const arcadeTheme: Theme = {\n meta: {\n id: \"arcade\",\n name: \"Arcade\",\n mode: \"dark\",\n },\n color: {\n neutral: {\n 50: \"#f5f7fb\",\n 100: \"#d6dde9\",\n 200: \"#a8b2c4\",\n 400: \"#5b6478\",\n 600: \"#2c3344\",\n 800: \"#161b27\",\n 950: \"#070912\",\n },\n brand: {\n 50: \"#e0fbff\",\n 100: \"#aef1fb\",\n 200: \"#62e0f0\",\n 400: \"#1bc4dc\",\n 600: \"#0d8ea1\",\n 800: \"#06525e\",\n 950: \"#03252b\",\n },\n accent: {\n 50: \"#ffe6f6\",\n 100: \"#ffb1de\",\n 200: \"#ff6cbf\",\n 400: \"#ff2891\",\n 600: \"#c80862\",\n 800: \"#73003a\",\n 950: \"#37001b\",\n },\n success: {\n 50: \"#dafdf2\",\n 100: \"#9af2cf\",\n 200: \"#52e1a3\",\n 400: \"#0fc171\",\n 600: \"#067a45\",\n 800: \"#024226\",\n 950: \"#001f10\",\n },\n warning: {\n 50: \"#fff4d8\",\n 100: \"#ffe198\",\n 200: \"#fbc739\",\n 400: \"#dba500\",\n 600: \"#9b7400\",\n 800: \"#5a4200\",\n 950: \"#291e00\",\n },\n danger: {\n 50: \"#ffdcdc\",\n 100: \"#ff9c9c\",\n 200: \"#ff5454\",\n 400: \"#e41e1e\",\n 600: \"#960a0a\",\n 800: \"#5a0202\",\n 950: \"#290000\",\n },\n info: {\n 50: \"#dceefe\",\n 100: \"#9ecdfb\",\n 200: \"#4f9ff5\",\n 400: \"#1d6fde\",\n 600: \"#0a4598\",\n 800: \"#03234f\",\n 950: \"#011024\",\n },\n },\n semantic: {\n surface: {\n app: \"#070912\",\n board: \"#0a0e1d\",\n hud: \"#161b27\",\n card: \"#1f2636\",\n sheet: \"#161b27\",\n overlay: \"rgba(7, 9, 18, 0.78)\",\n inset: \"#0a0e1d\",\n },\n text: {\n primary: \"#f5f7fb\",\n muted: \"#a8b2c4\",\n onIntent: \"#070912\",\n accent: \"#62e0f0\",\n disabled: \"#5b6478\",\n },\n border: {\n subtle: \"#2c3344\",\n default: \"#5b6478\",\n strong: \"#a8b2c4\",\n focus: \"#1bc4dc\",\n },\n intent: {\n primary: {\n solid: \"#1bc4dc\",\n on: \"#070912\",\n soft: \"rgba(27, 196, 220, 0.18)\",\n onSoft: \"#aef1fb\",\n border: \"#62e0f0\",\n },\n secondary: {\n solid: \"#1f2636\",\n on: \"#f5f7fb\",\n soft: \"#161b27\",\n onSoft: \"#a8b2c4\",\n border: \"#5b6478\",\n },\n success: {\n solid: \"#0fc171\",\n on: \"#070912\",\n soft: \"rgba(15, 193, 113, 0.18)\",\n onSoft: \"#9af2cf\",\n border: \"#52e1a3\",\n },\n danger: {\n solid: \"#e41e1e\",\n on: \"#ffffff\",\n soft: \"rgba(228, 30, 30, 0.18)\",\n onSoft: \"#ff9c9c\",\n border: \"#ff5454\",\n },\n warning: {\n solid: \"#fbc739\",\n on: \"#070912\",\n soft: \"rgba(251, 199, 57, 0.18)\",\n onSoft: \"#ffe198\",\n border: \"#dba500\",\n },\n info: {\n solid: \"#4f9ff5\",\n on: \"#070912\",\n soft: \"rgba(79, 159, 245, 0.18)\",\n onSoft: \"#9ecdfb\",\n border: \"#1d6fde\",\n },\n },\n },\n radius: {\n none: \"0px\",\n sm: \"2px\",\n md: \"4px\",\n lg: \"6px\",\n hud: \"10px\",\n pill: \"9999px\",\n },\n space: {\n 0: \"0\",\n 0.5: \"0.125rem\",\n 1: \"0.25rem\",\n 1.5: \"0.375rem\",\n 2: \"0.5rem\",\n 3: \"0.75rem\",\n 4: \"1rem\",\n 6: \"1.5rem\",\n 8: \"2rem\",\n 12: \"3rem\",\n },\n typography: {\n fontFamily: {\n display: '\"Space Grotesk\", \"Inter\", system-ui, -apple-system, sans-serif',\n body: '\"Inter\", \"SF Pro Text\", system-ui, -apple-system, sans-serif',\n tabular: '\"JetBrains Mono\", \"SF Mono\", ui-monospace, monospace',\n mono: '\"JetBrains Mono\", \"SF Mono\", ui-monospace, monospace',\n },\n fontSize: {\n xs: \"0.6875rem\",\n sm: \"0.8125rem\",\n md: \"0.9375rem\",\n lg: \"1.0625rem\",\n xl: \"1.25rem\",\n \"2xl\": \"1.5rem\",\n \"3xl\": \"2rem\",\n },\n fontWeight: {\n regular: \"400\",\n medium: \"500\",\n bold: \"700\",\n },\n lineHeight: {\n tight: \"1.1\",\n normal: \"1.35\",\n relaxed: \"1.55\",\n },\n letterSpacing: {\n tight: \"-0.01em\",\n normal: \"0\",\n wide: \"0.06em\",\n caps: \"0.18em\",\n },\n },\n elevation: {\n rest: \"0 1px 0 rgba(0, 0, 0, 0.4), 0 2px 0 rgba(27, 196, 220, 0.15)\",\n hover:\n \"0 0 0 1px rgba(27, 196, 220, 0.4), 0 6px 16px rgba(27, 196, 220, 0.35)\",\n lifted:\n \"0 0 0 2px rgba(27, 196, 220, 0.6), 0 14px 28px rgba(27, 196, 220, 0.45)\",\n overlay: \"0 20px 60px rgba(0, 0, 0, 0.7)\",\n inset: \"inset 0 0 0 1px rgba(27, 196, 220, 0.18)\",\n },\n motion: {\n duration: {\n fast: \"60ms\",\n normal: \"120ms\",\n slow: \"220ms\",\n ambient: \"1400ms\",\n },\n easing: {\n out: \"cubic-bezier(0.22, 1, 0.36, 1)\",\n in: \"cubic-bezier(0.36, 0, 1, 0.36)\",\n inOut: \"cubic-bezier(0.7, 0, 0.3, 1)\",\n spring: \"cubic-bezier(0.32, 1.6, 0.6, 1)\",\n },\n reducedMotion: \"false\",\n },\n player: [\n { solid: \"#1bc4dc\", soft: \"rgba(27, 196, 220, 0.2)\", on: \"#070912\" },\n { solid: \"#ff2891\", soft: \"rgba(255, 40, 145, 0.2)\", on: \"#ffffff\" },\n { solid: \"#0fc171\", soft: \"rgba(15, 193, 113, 0.2)\", on: \"#070912\" },\n { solid: \"#fbc739\", soft: \"rgba(251, 199, 57, 0.2)\", on: \"#070912\" },\n { solid: \"#9b59ff\", soft: \"rgba(155, 89, 255, 0.2)\", on: \"#ffffff\" },\n { solid: \"#ff7b3a\", soft: \"rgba(255, 123, 58, 0.2)\", on: \"#070912\" },\n ],\n component: {\n board: {\n frameBorder: \"#1bc4dc\",\n frameBackground: \"#0a0e1d\",\n hoverRing: \"#ff2891\",\n eligibleHint: \"rgba(27, 196, 220, 0.55)\",\n },\n card: {\n border: \"#1bc4dc\",\n backBorder: \"#ff2891\",\n backBackground: \"#161b27\",\n selectedRing: \"#ff2891\",\n },\n playerCard: {\n activeBackground: \"rgba(27, 196, 220, 0.18)\",\n activeBorder: \"#1bc4dc\",\n activeGlow: \"rgba(27, 196, 220, 0.5)\",\n youBadgeBackground: \"rgba(27, 196, 220, 0.22)\",\n youBadgeForeground: \"#aef1fb\",\n },\n toast: {\n successBackground: \"#0fc171\",\n errorBackground: \"#e41e1e\",\n infoBackground: \"#1bc4dc\",\n foreground: \"#070912\",\n },\n },\n};\n","import type { Theme } from \"../tokens.js\";\n\n/**\n * `studio` — clean monochrome theme for prototypes and design reviews.\n *\n * Visual identity: pure white surfaces, near-black text, single brand\n * accent, generous whitespace. Designed for screenshot-friendly demos\n * and games where the board art does the storytelling.\n */\nexport const studioTheme: Theme = {\n meta: {\n id: \"studio\",\n name: \"Studio\",\n mode: \"light\",\n },\n color: {\n neutral: {\n 50: \"#ffffff\",\n 100: \"#f5f5f5\",\n 200: \"#e5e5e5\",\n 400: \"#a3a3a3\",\n 600: \"#525252\",\n 800: \"#262626\",\n 950: \"#0a0a0a\",\n },\n brand: {\n 50: \"#eef2ff\",\n 100: \"#e0e7ff\",\n 200: \"#c7d2fe\",\n 400: \"#818cf8\",\n 600: \"#4f46e5\",\n 800: \"#3730a3\",\n 950: \"#1e1b4b\",\n },\n accent: {\n 50: \"#fdf4ff\",\n 100: \"#fae8ff\",\n 200: \"#f5d0fe\",\n 400: \"#e879f9\",\n 600: \"#a21caf\",\n 800: \"#701a75\",\n 950: \"#4a044e\",\n },\n success: {\n 50: \"#ecfdf5\",\n 100: \"#d1fae5\",\n 200: \"#a7f3d0\",\n 400: \"#34d399\",\n 600: \"#059669\",\n 800: \"#065f46\",\n 950: \"#022c22\",\n },\n warning: {\n 50: \"#fffbeb\",\n 100: \"#fef3c7\",\n 200: \"#fde68a\",\n 400: \"#facc15\",\n 600: \"#ca8a04\",\n 800: \"#854d0e\",\n 950: \"#422006\",\n },\n danger: {\n 50: \"#fef2f2\",\n 100: \"#fee2e2\",\n 200: \"#fecaca\",\n 400: \"#f87171\",\n 600: \"#dc2626\",\n 800: \"#991b1b\",\n 950: \"#450a0a\",\n },\n info: {\n 50: \"#eff6ff\",\n 100: \"#dbeafe\",\n 200: \"#bfdbfe\",\n 400: \"#60a5fa\",\n 600: \"#2563eb\",\n 800: \"#1e40af\",\n 950: \"#172554\",\n },\n },\n semantic: {\n surface: {\n app: \"#fafafa\",\n board: \"#ffffff\",\n hud: \"#ffffff\",\n card: \"#ffffff\",\n sheet: \"#ffffff\",\n overlay: \"rgba(10, 10, 10, 0.4)\",\n inset: \"#f5f5f5\",\n },\n text: {\n primary: \"#0a0a0a\",\n muted: \"#525252\",\n onIntent: \"#ffffff\",\n accent: \"#4f46e5\",\n disabled: \"#a3a3a3\",\n },\n border: {\n subtle: \"#f5f5f5\",\n default: \"#e5e5e5\",\n strong: \"#a3a3a3\",\n focus: \"#4f46e5\",\n },\n intent: {\n primary: {\n solid: \"#0a0a0a\",\n on: \"#ffffff\",\n soft: \"#f5f5f5\",\n onSoft: \"#0a0a0a\",\n border: \"#0a0a0a\",\n },\n secondary: {\n solid: \"#ffffff\",\n on: \"#0a0a0a\",\n soft: \"#f5f5f5\",\n onSoft: \"#0a0a0a\",\n border: \"#e5e5e5\",\n },\n success: {\n solid: \"#059669\",\n on: \"#ffffff\",\n soft: \"#d1fae5\",\n onSoft: \"#065f46\",\n border: \"#34d399\",\n },\n danger: {\n solid: \"#dc2626\",\n on: \"#ffffff\",\n soft: \"#fee2e2\",\n onSoft: \"#991b1b\",\n border: \"#f87171\",\n },\n warning: {\n solid: \"#ca8a04\",\n on: \"#ffffff\",\n soft: \"#fef3c7\",\n onSoft: \"#854d0e\",\n border: \"#facc15\",\n },\n info: {\n solid: \"#2563eb\",\n on: \"#ffffff\",\n soft: \"#dbeafe\",\n onSoft: \"#1e40af\",\n border: \"#60a5fa\",\n },\n },\n },\n radius: {\n none: \"0px\",\n sm: \"4px\",\n md: \"8px\",\n lg: \"12px\",\n hud: \"16px\",\n pill: \"9999px\",\n },\n space: {\n 0: \"0\",\n 0.5: \"0.125rem\",\n 1: \"0.25rem\",\n 1.5: \"0.375rem\",\n 2: \"0.5rem\",\n 3: \"0.75rem\",\n 4: \"1rem\",\n 6: \"1.5rem\",\n 8: \"2rem\",\n 12: \"3rem\",\n },\n typography: {\n fontFamily: {\n display:\n '\"Inter\", \"SF Pro Display\", system-ui, -apple-system, sans-serif',\n body: '\"Inter\", \"SF Pro Text\", system-ui, -apple-system, sans-serif',\n tabular: '\"Inter\", \"SF Pro Text\", system-ui, sans-serif',\n mono: '\"JetBrains Mono\", \"SF Mono\", ui-monospace, monospace',\n },\n fontSize: {\n xs: \"0.75rem\",\n sm: \"0.875rem\",\n md: \"1rem\",\n lg: \"1.125rem\",\n xl: \"1.25rem\",\n \"2xl\": \"1.5rem\",\n \"3xl\": \"2rem\",\n },\n fontWeight: {\n regular: \"400\",\n medium: \"500\",\n bold: \"600\",\n },\n lineHeight: {\n tight: \"1.2\",\n normal: \"1.5\",\n relaxed: \"1.65\",\n },\n letterSpacing: {\n tight: \"-0.015em\",\n normal: \"0\",\n wide: \"0.02em\",\n caps: \"0.08em\",\n },\n },\n elevation: {\n rest: \"0 1px 2px rgba(10, 10, 10, 0.05)\",\n hover: \"0 4px 8px rgba(10, 10, 10, 0.06), 0 1px 2px rgba(10, 10, 10, 0.04)\",\n lifted:\n \"0 12px 24px rgba(10, 10, 10, 0.08), 0 2px 4px rgba(10, 10, 10, 0.06)\",\n overlay: \"0 24px 48px rgba(10, 10, 10, 0.18)\",\n inset: \"inset 0 1px 0 rgba(10, 10, 10, 0.04)\",\n },\n motion: {\n duration: {\n fast: \"100ms\",\n normal: \"180ms\",\n slow: \"300ms\",\n ambient: \"2400ms\",\n },\n easing: {\n out: \"cubic-bezier(0.16, 1, 0.3, 1)\",\n in: \"cubic-bezier(0.4, 0, 1, 0.4)\",\n inOut: \"cubic-bezier(0.65, 0, 0.35, 1)\",\n spring: \"cubic-bezier(0.34, 1.56, 0.64, 1)\",\n },\n reducedMotion: \"false\",\n },\n player: [\n { solid: \"#4f46e5\", soft: \"#e0e7ff\", on: \"#ffffff\" },\n { solid: \"#dc2626\", soft: \"#fee2e2\", on: \"#ffffff\" },\n { solid: \"#059669\", soft: \"#d1fae5\", on: \"#ffffff\" },\n { solid: \"#ca8a04\", soft: \"#fef3c7\", on: \"#ffffff\" },\n { solid: \"#a21caf\", soft: \"#fae8ff\", on: \"#ffffff\" },\n { solid: \"#0891b2\", soft: \"#cffafe\", on: \"#ffffff\" },\n ],\n component: {\n board: {\n frameBorder: \"#e5e5e5\",\n frameBackground: \"#ffffff\",\n hoverRing: \"#4f46e5\",\n eligibleHint: \"rgba(79, 70, 229, 0.4)\",\n },\n card: {\n border: \"#e5e5e5\",\n backBorder: \"#0a0a0a\",\n backBackground: \"#0a0a0a\",\n selectedRing: \"#4f46e5\",\n },\n playerCard: {\n activeBackground: \"#f5f5f5\",\n activeBorder: \"#0a0a0a\",\n activeGlow: \"rgba(10, 10, 10, 0.06)\",\n youBadgeBackground: \"#0a0a0a\",\n youBadgeForeground: \"#ffffff\",\n },\n toast: {\n successBackground: \"#059669\",\n errorBackground: \"#dc2626\",\n infoBackground: \"#2563eb\",\n foreground: \"#ffffff\",\n },\n },\n};\n","import type { CSSProperties } from \"react\";\nimport type { Theme } from \"./tokens.js\";\n\n/**\n * CSS variable bridge for {@link Theme}.\n *\n * The {@link ThemeProvider} mounts a wrapper element and applies the\n * map returned by {@link themeToCssVars} as inline `style`, which\n * declares one CSS custom property per leaf token. Components inside\n * the provider can:\n *\n * 1. Read tokens via `useTheme()` (typed) and use them inline, or\n * 2. Read the CSS variable directly in Tailwind / className styling\n * via the helpers in {@link var()} below.\n *\n * The variable naming scheme is `--db-<dot.path>` with `.` and any\n * non-identifier characters replaced by `-`. Example:\n *\n * - `theme.semantic.intent.primary.solid` → `--db-semantic-intent-primary-solid`\n * - `theme.player[0].solid` → `--db-player-1-solid`\n * - `theme.color.brand.600` → `--db-color-brand-600`\n *\n * The 1-based player suffix (rather than 0-based) keeps the variable\n * name aligned with how seats are labelled in product UI (\"Player 1\").\n */\n\nconst PREFIX = \"--db\";\n\n/** Convert a token-tree path to a kebab-case CSS variable name. */\nfunction toVarName(parts: ReadonlyArray<string | number>): string {\n const tail = parts\n .map((part) => String(part))\n .join(\"-\")\n .replace(/[^a-zA-Z0-9-]/g, \"-\")\n .replace(/-+/g, \"-\");\n return `${PREFIX}-${tail}`;\n}\n\n/**\n * Walk the theme tree and produce a flat `{ \"--db-...\": value }` map.\n * Arrays are walked positionally with a 1-based index (so\n * `theme.player[0]` → `--db-player-1-...`).\n */\nexport function themeToCssVars(theme: Theme): CSSProperties {\n const out: Record<string, string> = {};\n walk(theme as unknown as Record<string, unknown>, [], out);\n return out as CSSProperties;\n}\n\nfunction walk(\n node: unknown,\n path: ReadonlyArray<string | number>,\n out: Record<string, string>,\n): void {\n if (node === null || node === undefined) return;\n if (typeof node === \"string\" || typeof node === \"number\") {\n out[toVarName(path)] = String(node);\n return;\n }\n if (Array.isArray(node)) {\n node.forEach((child, idx) => {\n // 1-based index for player slots, etc.\n walk(child, [...path, idx + 1], out);\n });\n return;\n }\n if (typeof node === \"object\") {\n for (const [key, value] of Object.entries(\n node as Record<string, unknown>,\n )) {\n walk(value, [...path, key], out);\n }\n }\n}\n\n/**\n * Build a `var(--db-...)` reference for a token path.\n *\n * @example\n * ```ts\n * cssVar(\"semantic\", \"intent\", \"primary\", \"solid\")\n * // => \"var(--db-semantic-intent-primary-solid)\"\n * cssVar(\"player\", 1, \"solid\")\n * // => \"var(--db-player-1-solid)\"\n * ```\n */\nexport function cssVar(...path: Array<string | number>): string {\n return `var(${toVarName(path)})`;\n}\n\n/**\n * Convenience for declaring a `var(--db-...)` with an inline fallback.\n *\n * @example\n * ```ts\n * cssVarOr(\"transparent\", \"semantic\", \"border\", \"default\")\n * // => \"var(--db-semantic-border-default, transparent)\"\n * ```\n */\nexport function cssVarOr(\n fallback: string,\n ...path: Array<string | number>\n): string {\n return `var(${toVarName(path)}, ${fallback})`;\n}\n","import {\n createContext,\n useContext,\n useEffect,\n useMemo,\n useState,\n type CSSProperties,\n type ReactNode,\n} from \"react\";\nimport { themeToCssVars } from \"./css-vars.js\";\nimport { arcadeTheme } from \"./presets/arcade.js\";\nimport { studioTheme } from \"./presets/studio.js\";\nimport { tabletopTheme } from \"./presets/tabletop.js\";\nimport { mergeTheme, type Theme, type ThemeOverride } from \"./tokens.js\";\n\n/**\n * The set of preset theme ids ships in `@dreamboard-games/sdk/ui`. Authors\n * may register additional ones by passing a fully-resolved {@link Theme}\n * instead of an id.\n */\nexport type ThemePresetId = \"tabletop\" | \"arcade\" | \"studio\";\n\nconst PRESETS: Readonly<Record<ThemePresetId, Theme>> = {\n tabletop: tabletopTheme,\n arcade: arcadeTheme,\n studio: studioTheme,\n};\n\n/**\n * Resolve a preset id (or a full theme) into a {@link Theme}.\n *\n * Used internally by {@link ThemeProvider}; exported so authors who\n * compose at the call site (e.g. for a side-by-side preview) can do\n * the same resolution without mounting a provider.\n */\nexport function resolveTheme(input: ThemePresetId | Theme | undefined): Theme {\n if (!input) return tabletopTheme;\n if (typeof input === \"string\") {\n const preset = PRESETS[input];\n if (!preset) {\n throw new Error(\n `[ui-sdk] Unknown theme preset \"${input}\". Pass a full Theme object or one of: ${Object.keys(\n PRESETS,\n ).join(\", \")}.`,\n );\n }\n return preset;\n }\n return input;\n}\n\n/** Look up a registered preset by id. Returns `undefined` if missing. */\nexport function getThemePreset(id: ThemePresetId): Theme | undefined {\n return PRESETS[id];\n}\n\n/**\n * Subset returned by {@link useTheme} — the resolved theme plus a\n * stable copy of its CSS-variable map so consumers can reuse it (for\n * example, to apply tokens to a portal that escapes the provider).\n */\nexport interface ThemeContextValue {\n /** Fully resolved theme. */\n readonly theme: Theme;\n /** CSS-var map consumable as `style` on a wrapper. */\n readonly cssVars: CSSProperties;\n}\n\nconst ThemeCtx = createContext<ThemeContextValue | null>(null);\n\nexport interface ThemeProviderProps {\n /**\n * Preset id, a full {@link Theme}, or omitted to use the `tabletop`\n * default.\n */\n theme?: ThemePresetId | Theme;\n /**\n * Deep-partial overrides merged onto the resolved base theme. Use\n * for one-off tweaks (e.g. swapping the player palette per game)\n * without writing a full theme.\n */\n override?: ThemeOverride;\n /**\n * Render mode for reduced-motion enforcement.\n *\n * - `auto` (default): respect the user's OS-level preference via\n * `prefers-reduced-motion: reduce`.\n * - `force`: force `motion.reducedMotion = \"true\"` regardless of the\n * OS preference (useful for screenshot CI).\n * - `ignore`: never override motion (use only when the embedding\n * shell already decides motion behaviour).\n */\n reducedMotion?: \"auto\" | \"force\" | \"ignore\";\n /**\n * Where to mount the wrapper. `block` (default) renders a `div` and\n * applies the CSS variables to it. `none` skips the wrapper entirely\n * — only useful when the parent is already a Dreamboard provider and\n * just needs to publish a different sub-tree (rare).\n */\n as?: \"block\" | \"none\";\n /** Extra style merged after the CSS-var map. */\n style?: CSSProperties;\n /** Extra className for the wrapper. */\n className?: string;\n children: ReactNode;\n}\n\nfunction usePrefersReducedMotion(): boolean {\n const [prefers, setPrefers] = useState(false);\n useEffect(() => {\n if (typeof window === \"undefined\" || !window.matchMedia) return;\n const media = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n setPrefers(media.matches);\n const handle = (event: MediaQueryListEvent) => setPrefers(event.matches);\n media.addEventListener(\"change\", handle);\n return () => media.removeEventListener(\"change\", handle);\n }, []);\n return prefers;\n}\n\n/**\n * Mounts a Dreamboard theme. The provider:\n *\n * 1. Resolves the preset (or accepts a full theme).\n * 2. Applies any deep-partial `override`.\n * 3. Optionally clamps `motion.reducedMotion` to `\"true\"` based on the\n * OS-level preference (or a forced override).\n * 4. Serialises the resolved theme into CSS variables on a wrapper\n * element so descendants can read tokens via `useTheme()` *or* via\n * `var(--db-...)` references in their own CSS / Tailwind.\n *\n * Defaults such as `<GameLayout>` mount this for you with the configured\n * theme; mount it manually only when you need a sub-tree to use a different\n * theme (e.g. a dark sheet over a light layout).\n */\nexport function ThemeProvider({\n theme: themeInput,\n override,\n reducedMotion = \"auto\",\n as = \"block\",\n style,\n className,\n children,\n}: ThemeProviderProps) {\n const prefersReduced = usePrefersReducedMotion();\n\n const value = useMemo<ThemeContextValue>(() => {\n const base = resolveTheme(themeInput);\n const merged = mergeTheme(base, override);\n const motionResolved =\n reducedMotion === \"force\"\n ? \"true\"\n : reducedMotion === \"ignore\"\n ? merged.motion.reducedMotion\n : prefersReduced\n ? \"true\"\n : merged.motion.reducedMotion;\n const final: Theme =\n motionResolved === merged.motion.reducedMotion\n ? merged\n : {\n ...merged,\n motion: { ...merged.motion, reducedMotion: motionResolved },\n };\n return { theme: final, cssVars: themeToCssVars(final) };\n }, [themeInput, override, reducedMotion, prefersReduced]);\n\n if (as === \"none\") {\n return <ThemeCtx.Provider value={value}>{children}</ThemeCtx.Provider>;\n }\n\n const wrapperStyle: CSSProperties = {\n ...themeToShadcnVars(value.theme),\n ...value.cssVars,\n fontFamily: value.theme.typography.fontFamily.body,\n ...style,\n };\n\n return (\n <ThemeCtx.Provider value={value}>\n <div\n data-dreamboard-theme={value.theme.meta.id}\n data-dreamboard-mode={value.theme.meta.mode}\n data-dreamboard-reduced-motion={value.theme.motion.reducedMotion}\n className={className}\n style={wrapperStyle}\n >\n {children}\n </div>\n </ThemeCtx.Provider>\n );\n}\n\n/**\n * Read the active {@link Theme} from a {@link ThemeProvider} ancestor.\n *\n * Falls back to the `tabletop` preset (with no overrides) when called\n * outside a provider — components remain renderable in isolated tests\n * and Storybook/Cosmos fixtures without a wrapping shell.\n */\nexport function useTheme(): Theme {\n const ctx = useContext(ThemeCtx);\n return ctx?.theme ?? tabletopTheme;\n}\n\n/**\n * Read the {@link CSSProperties} that publish the active theme as CSS\n * variables. Useful when porting a theme into a portal or drawer that\n * is rendered outside the provider's DOM subtree.\n */\nexport function useThemeCssVars(): CSSProperties {\n const ctx = useContext(ThemeCtx);\n if (ctx) return { ...themeToShadcnVars(ctx.theme), ...ctx.cssVars };\n // Match the fallback theme exposed by `useTheme()`.\n return {\n ...themeToShadcnVars(tabletopTheme),\n ...themeToCssVars(tabletopTheme),\n };\n}\n\nexport { ThemeCtx };\n\ntype CssVariableStyle = CSSProperties & {\n [K in `--${string}`]?: string | number;\n};\n\nfunction themeToShadcnVars(theme: Theme): CSSProperties {\n const vars: CssVariableStyle = {\n \"--background\": theme.semantic.surface.app,\n \"--foreground\": theme.semantic.text.primary,\n \"--card\": theme.semantic.surface.card,\n \"--card-foreground\": theme.semantic.text.primary,\n \"--popover\": theme.semantic.surface.sheet,\n \"--popover-foreground\": theme.semantic.text.primary,\n \"--primary\": theme.semantic.intent.primary.solid,\n \"--primary-foreground\": theme.semantic.intent.primary.on,\n \"--secondary\": theme.semantic.intent.secondary.solid,\n \"--secondary-foreground\": theme.semantic.intent.secondary.on,\n \"--muted\": theme.semantic.surface.inset,\n \"--muted-foreground\": theme.semantic.text.muted,\n \"--accent\": theme.semantic.intent.info.soft,\n \"--accent-foreground\": theme.semantic.intent.info.onSoft,\n \"--destructive\": theme.semantic.intent.danger.solid,\n \"--destructive-foreground\": theme.semantic.intent.danger.on,\n \"--border\": theme.semantic.border.default,\n \"--input\": theme.semantic.border.default,\n \"--ring\": theme.semantic.border.focus,\n \"--font-sans\": theme.typography.fontFamily.body,\n \"--font-display\": theme.typography.fontFamily.display,\n };\n return vars;\n}\n","import type { CSSProperties } from \"react\";\nimport type { IntentColor, Theme } from \"./tokens.js\";\n\n/**\n * Helpers that derive component-specific style fragments from a\n * resolved {@link Theme}. They live alongside the theme module (rather\n * than in each component) so that:\n *\n * - There is one canonical mapping of \"intent → button style\", \"intent →\n * chip style\", etc.\n * - Component visuals stay aligned automatically when an author tweaks\n * the theme; nobody has to remember to update a bespoke calc inside\n * `<CardFace>` or `<ThemedButton>`.\n *\n * Each helper returns a plain {@link CSSProperties} fragment so the\n * caller can spread it into an inline style (or pass it through to\n * Framer Motion's `style` prop).\n */\n\n/** Button visual variants derived from semantic intent slots. */\nexport type ButtonVariant =\n | \"primary\"\n | \"secondary\"\n | \"danger\"\n | \"submitted\"\n | \"success\"\n | \"warning\"\n | \"info\"\n | \"ghost\";\n\nexport type ButtonSize = \"sm\" | \"md\" | \"lg\";\n\n/**\n * Compute the inline style for a button in `variant`/`size` from the\n * theme. `disabled` and `pressed` are visual-only — they affect colour\n * intensity and elevation but never touch interactivity (the consuming\n * component owns `aria-disabled` and event wiring).\n */\nexport function buttonStyle(\n theme: Theme,\n options: {\n variant?: ButtonVariant;\n size?: ButtonSize;\n disabled?: boolean;\n pressed?: boolean;\n } = {},\n): CSSProperties {\n const { variant = \"primary\", size = \"md\", disabled, pressed } = options;\n const intent = intentForVariant(theme, variant);\n const sizing = BUTTON_SIZE[size];\n const visuallyDisabled = disabled && variant !== \"submitted\";\n\n const baseShadow =\n variant === \"ghost\"\n ? \"none\"\n : pressed\n ? theme.elevation.rest\n : theme.elevation.hover;\n\n return {\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: theme.space[2],\n minHeight: sizing.minHeight,\n paddingBlock: sizing.paddingBlock,\n paddingInline: sizing.paddingInline,\n borderRadius: theme.radius.md,\n border:\n variant === \"ghost\"\n ? \"1px solid transparent\"\n : `1px solid ${visuallyDisabled ? theme.semantic.border.subtle : intent.border}`,\n background:\n variant === \"ghost\"\n ? \"transparent\"\n : visuallyDisabled\n ? theme.semantic.surface.inset\n : intent.solid,\n color: visuallyDisabled\n ? theme.semantic.text.disabled\n : variant === \"ghost\"\n ? theme.semantic.text.primary\n : intent.on,\n fontFamily: theme.typography.fontFamily.body,\n fontSize: sizing.fontSize,\n fontWeight: theme.typography.fontWeight.bold,\n lineHeight: theme.typography.lineHeight.tight,\n letterSpacing: theme.typography.letterSpacing.normal,\n cursor: disabled ? \"not-allowed\" : \"pointer\",\n boxShadow: disabled ? \"none\" : baseShadow,\n transition: `background-color ${theme.motion.duration.fast} ${theme.motion.easing.out}, transform ${theme.motion.duration.fast} ${theme.motion.easing.out}, box-shadow ${theme.motion.duration.normal} ${theme.motion.easing.out}`,\n userSelect: \"none\",\n WebkitTapHighlightColor: \"transparent\",\n };\n}\n\nconst BUTTON_SIZE: Record<\n ButtonSize,\n {\n minHeight: number;\n paddingBlock: string;\n paddingInline: string;\n fontSize: string;\n }\n> = {\n sm: {\n minHeight: 32,\n paddingBlock: \"0.25rem\",\n paddingInline: \"0.625rem\",\n fontSize: \"0.8125rem\",\n },\n md: {\n minHeight: 40,\n paddingBlock: \"0.5rem\",\n paddingInline: \"0.875rem\",\n fontSize: \"0.9375rem\",\n },\n lg: {\n minHeight: 52,\n paddingBlock: \"0.75rem\",\n paddingInline: \"1.125rem\",\n fontSize: \"1.0625rem\",\n },\n};\n\n/**\n * Soft-intent chip (\"Your turn\", \"Largest army\", \"Waiting…\"). Reads\n * `intent.<variant>.soft` for background and `.onSoft` for text.\n */\nexport function chipStyle(\n theme: Theme,\n options: {\n variant?: Exclude<ButtonVariant, \"ghost\">;\n size?: \"sm\" | \"md\";\n } = {},\n): CSSProperties {\n const { variant = \"secondary\", size = \"sm\" } = options;\n const intent = intentForVariant(theme, variant);\n return {\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: theme.space[1],\n paddingBlock: size === \"md\" ? \"0.25rem\" : \"0.125rem\",\n paddingInline: size === \"md\" ? \"0.625rem\" : \"0.5rem\",\n borderRadius: theme.radius.pill,\n border: `1px solid ${intent.border}`,\n background: intent.soft,\n color: intent.onSoft,\n fontFamily: theme.typography.fontFamily.body,\n fontSize:\n size === \"md\"\n ? theme.typography.fontSize.sm\n : theme.typography.fontSize.xs,\n fontWeight: theme.typography.fontWeight.bold,\n letterSpacing: theme.typography.letterSpacing.wide,\n textTransform: \"uppercase\",\n whiteSpace: \"nowrap\",\n };\n}\n\n/**\n * Standard surface card (player card, action panel, hand drawer). The\n * `tone` selects which `surface.*` slot to read; `interactive` adds\n * the hover-elevation transition baseline.\n */\nexport function surfaceStyle(\n theme: Theme,\n options: {\n tone?: keyof Theme[\"semantic\"][\"surface\"];\n interactive?: boolean;\n /** Override radius to one of the theme tokens. Defaults to `lg`. */\n radius?: keyof Theme[\"radius\"];\n } = {},\n): CSSProperties {\n const { tone = \"card\", interactive, radius = \"lg\" } = options;\n return {\n background: theme.semantic.surface[tone],\n color: theme.semantic.text.primary,\n border: `1px solid ${theme.semantic.border.subtle}`,\n borderRadius: theme.radius[radius],\n boxShadow: theme.elevation.rest,\n transition: interactive\n ? `box-shadow ${theme.motion.duration.normal} ${theme.motion.easing.out}, transform ${theme.motion.duration.normal} ${theme.motion.easing.out}`\n : undefined,\n };\n}\n\n/** Resolve a {@link ButtonVariant} to its underlying {@link IntentColor}. */\nexport function intentForVariant(\n theme: Theme,\n variant: ButtonVariant,\n): IntentColor {\n switch (variant) {\n case \"primary\":\n return theme.semantic.intent.primary;\n case \"secondary\":\n return theme.semantic.intent.secondary;\n case \"danger\":\n return theme.semantic.intent.danger;\n case \"submitted\":\n return theme.semantic.intent.success;\n case \"success\":\n return theme.semantic.intent.success;\n case \"warning\":\n return theme.semantic.intent.warning;\n case \"info\":\n return theme.semantic.intent.info;\n case \"ghost\":\n return theme.semantic.intent.secondary;\n }\n}\n\n/**\n * Pick a {@link Theme.player} entry by 0-based seat slot, wrapping\n * around when there are more players than palette entries (so a\n * 7-player game cycles back to player 1's palette).\n */\nexport function playerColor(theme: Theme, slot: number) {\n const length = theme.player.length;\n const idx = ((slot % length) + length) % length;\n // The {@link Theme.player} contract pins length === 6 at the type\n // level, but indexing by a runtime-computed value widens the result\n // to `PlayerColor | undefined`. Falling back to slot 0 (also typed\n // `PlayerColor`) keeps the return type narrow without a non-null\n // assertion.\n return theme.player[idx] ?? theme.player[0];\n}\n\n/**\n * Returns `theme.motion.duration.<key>` zeroed out when the theme has\n * `motion.reducedMotion === \"true\"`. Use this in any component that\n * starts an animation so `prefers-reduced-motion` is honoured uniformly.\n */\nexport function motionDuration(\n theme: Theme,\n key: keyof Theme[\"motion\"][\"duration\"],\n): string {\n if (theme.motion.reducedMotion === \"true\") return \"0ms\";\n return theme.motion.duration[key];\n}\n","import type {\n BoardId,\n EdgeTypeId,\n PlayerId,\n SpaceTypeId,\n VertexTypeId,\n} from \"./player-state.js\";\nimport type {\n HexBoardState,\n HexEdgeState,\n HexTileState,\n HexVertexState,\n SquareBoardState,\n SquareCellState,\n SquareEdgeState,\n SquarePieceState,\n SquareVertexState,\n} from \"./player-state.js\";\n\ntype RuntimeFields = Record<string, unknown>;\n\ntype NormalizeOptional<T> = Exclude<T, null | undefined> | undefined;\n\nexport interface GeneratedTiledEdgeStateLike<\n SpaceIdValue extends string = string,\n EdgeIdValue extends string = string,\n Fields = RuntimeFields,\n> {\n id: EdgeIdValue;\n spaceIds: readonly SpaceIdValue[];\n typeId?: EdgeTypeId | null;\n label?: string | null;\n ownerId?: PlayerId | null;\n fields?: Fields;\n}\n\nexport interface GeneratedTiledVertexStateLike<\n SpaceIdValue extends string = string,\n VertexIdValue extends string = string,\n Fields = RuntimeFields,\n> {\n id: VertexIdValue;\n spaceIds: readonly SpaceIdValue[];\n typeId?: VertexTypeId | null;\n label?: string | null;\n ownerId?: PlayerId | null;\n fields?: Fields;\n}\n\nexport interface GeneratedHexSpaceStateLike<\n SpaceIdValue extends string = string,\n Fields = RuntimeFields,\n> {\n id: SpaceIdValue;\n q: number;\n r: number;\n typeId?: SpaceTypeId | null;\n label?: string | null;\n ownerId?: PlayerId | null;\n fields?: Fields;\n}\n\nexport interface GeneratedSquareSpaceStateLike<\n SpaceIdValue extends string = string,\n Fields = RuntimeFields,\n> {\n id: SpaceIdValue;\n row: number;\n col: number;\n typeId?: SpaceTypeId | null;\n label?: string | null;\n ownerId?: PlayerId | null;\n fields?: Fields;\n}\n\nexport interface GeneratedHexBoardInput<\n BoardIdValue extends string = BoardId,\n SpaceIdValue extends string = string,\n EdgeIdValue extends string = string,\n VertexIdValue extends string = string,\n SpaceFields = RuntimeFields,\n EdgeFields = RuntimeFields,\n VertexFields = RuntimeFields,\n> {\n id: BoardIdValue;\n layout?: \"hex\";\n orientation?: \"pointy-top\" | \"flat-top\";\n spaces: Readonly<\n Record<SpaceIdValue, GeneratedHexSpaceStateLike<SpaceIdValue, SpaceFields>>\n >;\n edges: ReadonlyArray<\n | HexEdgeState<BoardIdValue, SpaceIdValue, EdgeIdValue, EdgeFields>\n | GeneratedTiledEdgeStateLike<SpaceIdValue, EdgeIdValue, EdgeFields>\n >;\n vertices: ReadonlyArray<\n | HexVertexState<BoardIdValue, SpaceIdValue, VertexIdValue, VertexFields>\n | GeneratedTiledVertexStateLike<SpaceIdValue, VertexIdValue, VertexFields>\n >;\n}\n\nexport interface AuthoredHexBoardInput<\n BoardIdValue extends string = BoardId,\n SpaceIdValue extends string = string,\n EdgeIdValue extends string = string,\n VertexIdValue extends string = string,\n SpaceFields = RuntimeFields,\n EdgeFields = RuntimeFields,\n VertexFields = RuntimeFields,\n SpaceView = unknown,\n> {\n id: BoardIdValue;\n layout?: \"hex\";\n orientation?: \"pointy-top\" | \"flat-top\";\n tiles: ReadonlyArray<\n HexTileState<BoardIdValue, SpaceIdValue, SpaceFields, SpaceView>\n >;\n edges: ReadonlyArray<\n | HexEdgeState<BoardIdValue, SpaceIdValue, EdgeIdValue, EdgeFields>\n | GeneratedTiledEdgeStateLike<SpaceIdValue, EdgeIdValue, EdgeFields>\n >;\n vertices: ReadonlyArray<\n | HexVertexState<BoardIdValue, SpaceIdValue, VertexIdValue, VertexFields>\n | GeneratedTiledVertexStateLike<SpaceIdValue, VertexIdValue, VertexFields>\n >;\n}\n\nexport type HexBoardInput<\n BoardIdValue extends string = BoardId,\n SpaceIdValue extends string = string,\n EdgeIdValue extends string = string,\n VertexIdValue extends string = string,\n SpaceFields = RuntimeFields,\n EdgeFields = RuntimeFields,\n VertexFields = RuntimeFields,\n> =\n | AuthoredHexBoardInput<\n BoardIdValue,\n SpaceIdValue,\n EdgeIdValue,\n VertexIdValue,\n SpaceFields,\n EdgeFields,\n VertexFields\n >\n | GeneratedHexBoardInput<\n BoardIdValue,\n SpaceIdValue,\n EdgeIdValue,\n VertexIdValue,\n SpaceFields,\n EdgeFields,\n VertexFields\n >;\n\nexport interface GeneratedSquareBoardInput<\n BoardIdValue extends string = BoardId,\n SpaceIdValue extends string = string,\n EdgeIdValue extends string = string,\n VertexIdValue extends string = string,\n PieceIdValue extends string = string,\n SpaceFields = RuntimeFields,\n EdgeFields = RuntimeFields,\n VertexFields = RuntimeFields,\n PieceFields = RuntimeFields,\n> {\n id: BoardIdValue;\n layout?: \"square\";\n spaces: Readonly<\n Record<\n SpaceIdValue,\n GeneratedSquareSpaceStateLike<SpaceIdValue, SpaceFields>\n >\n >;\n edges: ReadonlyArray<\n | SquareEdgeState<SpaceIdValue, EdgeIdValue, EdgeFields>\n | GeneratedTiledEdgeStateLike<SpaceIdValue, EdgeIdValue, EdgeFields>\n >;\n vertices: ReadonlyArray<\n | SquareVertexState<SpaceIdValue, VertexIdValue, VertexFields>\n | GeneratedTiledVertexStateLike<SpaceIdValue, VertexIdValue, VertexFields>\n >;\n pieces?: ReadonlyArray<SquarePieceState<PieceIdValue, PieceFields>>;\n}\n\nexport interface AuthoredSquareBoardInput<\n BoardIdValue extends string = BoardId,\n SpaceIdValue extends string = string,\n EdgeIdValue extends string = string,\n VertexIdValue extends string = string,\n PieceIdValue extends string = string,\n SpaceFields = RuntimeFields,\n EdgeFields = RuntimeFields,\n VertexFields = RuntimeFields,\n PieceFields = RuntimeFields,\n> {\n id: BoardIdValue;\n layout?: \"square\";\n rows: number;\n cols: number;\n cells: ReadonlyArray<SquareCellState<SpaceIdValue, SpaceFields>>;\n edges: ReadonlyArray<\n | SquareEdgeState<SpaceIdValue, EdgeIdValue, EdgeFields>\n | GeneratedTiledEdgeStateLike<SpaceIdValue, EdgeIdValue, EdgeFields>\n >;\n vertices: ReadonlyArray<\n | SquareVertexState<SpaceIdValue, VertexIdValue, VertexFields>\n | GeneratedTiledVertexStateLike<SpaceIdValue, VertexIdValue, VertexFields>\n >;\n pieces: ReadonlyArray<SquarePieceState<PieceIdValue, PieceFields>>;\n}\n\nexport type SquareBoardInput<\n BoardIdValue extends string = BoardId,\n SpaceIdValue extends string = string,\n EdgeIdValue extends string = string,\n VertexIdValue extends string = string,\n PieceIdValue extends string = string,\n SpaceFields = RuntimeFields,\n EdgeFields = RuntimeFields,\n VertexFields = RuntimeFields,\n PieceFields = RuntimeFields,\n> =\n | AuthoredSquareBoardInput<\n BoardIdValue,\n SpaceIdValue,\n EdgeIdValue,\n VertexIdValue,\n PieceIdValue,\n SpaceFields,\n EdgeFields,\n VertexFields,\n PieceFields\n >\n | GeneratedSquareBoardInput<\n BoardIdValue,\n SpaceIdValue,\n EdgeIdValue,\n VertexIdValue,\n PieceIdValue,\n SpaceFields,\n EdgeFields,\n VertexFields,\n PieceFields\n >;\n\nexport type AnyHexBoardInput = HexBoardInput<\n string,\n string,\n string,\n string,\n RuntimeFields,\n RuntimeFields,\n RuntimeFields\n>;\nexport type AnySquareBoardInput = SquareBoardInput<\n string,\n string,\n string,\n string,\n string,\n RuntimeFields,\n RuntimeFields,\n RuntimeFields,\n RuntimeFields\n>;\n\nexport type BoardIdOf<TBoard> = TBoard extends { id: infer Id extends string }\n ? Id\n : string;\n\ntype SpaceRecordValueOf<TBoard> = TBoard extends {\n spaces: Readonly<Record<string, infer Space>>;\n}\n ? Space\n : never;\ntype TileValueOf<TBoard> = TBoard extends { tiles: ReadonlyArray<infer Tile> }\n ? Tile\n : never;\ntype CellValueOf<TBoard> = TBoard extends { cells: ReadonlyArray<infer Cell> }\n ? Cell\n : never;\ntype EdgeValueOf<TBoard> = TBoard extends { edges: ReadonlyArray<infer Edge> }\n ? Edge\n : never;\ntype VertexValueOf<TBoard> = TBoard extends {\n vertices: ReadonlyArray<infer Vertex>;\n}\n ? Vertex\n : never;\ntype PieceValueOf<TBoard> = TBoard extends {\n pieces?: ReadonlyArray<infer Piece>;\n}\n ? Piece\n : never;\n\nexport type BoardSpaceIdOf<TBoard> =\n SpaceRecordValueOf<TBoard> extends { id: infer Id extends string }\n ? Id\n : TileValueOf<TBoard> extends { id: infer Id extends string }\n ? Id\n : CellValueOf<TBoard> extends { id: infer Id extends string }\n ? Id\n : never;\n\nexport type BoardEdgeIdOf<TBoard> =\n EdgeValueOf<TBoard> extends {\n id: infer Id extends string;\n }\n ? Id\n : never;\n\nexport type BoardVertexIdOf<TBoard> =\n VertexValueOf<TBoard> extends {\n id: infer Id extends string;\n }\n ? Id\n : never;\n\ntype HexTilePropertiesOf<TBoard> =\n SpaceRecordValueOf<TBoard> extends { fields?: infer Fields }\n ? Fields\n : TileValueOf<TBoard> extends { properties?: infer Properties }\n ? Properties\n : RuntimeFields;\n\ntype HexTileViewOf<TBoard> =\n TileValueOf<TBoard> extends { view: infer View }\n ? View\n : TileValueOf<TBoard> extends { view?: infer View }\n ? View | undefined\n : unknown;\n\ntype HexEdgePropertiesOf<TBoard> =\n EdgeValueOf<TBoard> extends { fields?: infer Fields }\n ? Fields\n : EdgeValueOf<TBoard> extends { properties?: infer Properties }\n ? Properties\n : RuntimeFields;\n\ntype HexVertexPropertiesOf<TBoard> =\n VertexValueOf<TBoard> extends { fields?: infer Fields }\n ? Fields\n : VertexValueOf<TBoard> extends { properties?: infer Properties }\n ? Properties\n : RuntimeFields;\n\ntype SquareCellPropertiesOf<TBoard> =\n SpaceRecordValueOf<TBoard> extends { fields?: infer Fields }\n ? Fields\n : CellValueOf<TBoard> extends { properties?: infer Properties }\n ? Properties\n : RuntimeFields;\n\ntype SquareEdgePropertiesOf<TBoard> =\n EdgeValueOf<TBoard> extends { fields?: infer Fields }\n ? Fields\n : EdgeValueOf<TBoard> extends { properties?: infer Properties }\n ? Properties\n : RuntimeFields;\n\ntype SquareVertexPropertiesOf<TBoard> =\n VertexValueOf<TBoard> extends { fields?: infer Fields }\n ? Fields\n : VertexValueOf<TBoard> extends { properties?: infer Properties }\n ? Properties\n : RuntimeFields;\n\ntype SquarePiecePropertiesOf<TBoard> =\n PieceValueOf<TBoard> extends {\n properties?: infer Properties;\n }\n ? Properties\n : RuntimeFields;\n\n/**\n * Normalized hex tile shape for a given board input.\n *\n * `view` is always present (required) on the result so consumers can\n * read overlay fields without a null-check. For boards that do not\n * statically declare a `view` shape (the generic case), `view` falls\n * back to `unknown`, which still admits any value.\n *\n * The runtime normalizer injects `view: undefined` for inputs that\n * do not author a `view` field, keeping the runtime contract aligned\n * with this static shape.\n */\nexport type NormalizedHexTileOf<TBoard extends AnyHexBoardInput> = Omit<\n HexTileState<\n BoardIdOf<TBoard>,\n BoardSpaceIdOf<TBoard>,\n HexTilePropertiesOf<TBoard>,\n HexTileViewOf<TBoard>\n >,\n \"view\"\n> & { view: HexTileViewOf<TBoard> };\n\nexport type NormalizedHexEdgeOf<TBoard extends AnyHexBoardInput> = HexEdgeState<\n BoardIdOf<TBoard>,\n BoardSpaceIdOf<TBoard>,\n BoardEdgeIdOf<TBoard>,\n HexEdgePropertiesOf<TBoard>\n>;\n\nexport type NormalizedHexVertexOf<TBoard extends AnyHexBoardInput> =\n HexVertexState<\n BoardIdOf<TBoard>,\n BoardSpaceIdOf<TBoard>,\n BoardVertexIdOf<TBoard>,\n HexVertexPropertiesOf<TBoard>\n >;\n\nexport type NormalizedSquareCellOf<TBoard extends AnySquareBoardInput> =\n SquareCellState<BoardSpaceIdOf<TBoard>, SquareCellPropertiesOf<TBoard>>;\n\nexport type NormalizedSquareEdgeOf<TBoard extends AnySquareBoardInput> =\n SquareEdgeState<\n BoardSpaceIdOf<TBoard>,\n BoardEdgeIdOf<TBoard>,\n SquareEdgePropertiesOf<TBoard>\n >;\n\nexport type NormalizedSquareVertexOf<TBoard extends AnySquareBoardInput> =\n SquareVertexState<\n BoardSpaceIdOf<TBoard>,\n BoardVertexIdOf<TBoard>,\n SquareVertexPropertiesOf<TBoard>\n >;\n\nexport type NormalizedSquarePieceOf<TBoard extends AnySquareBoardInput> =\n SquarePieceState<\n PieceValueOf<TBoard> extends { id: infer PieceIdValue extends string }\n ? PieceIdValue\n : string,\n SquarePiecePropertiesOf<TBoard>\n >;\n\nexport type NormalizedHexBoard<TBoard extends AnyHexBoardInput> = Omit<\n Pick<\n HexBoardState<\n BoardIdOf<TBoard>,\n BoardSpaceIdOf<TBoard>,\n BoardEdgeIdOf<TBoard>,\n BoardVertexIdOf<TBoard>,\n HexTilePropertiesOf<TBoard>,\n HexEdgePropertiesOf<TBoard>,\n HexVertexPropertiesOf<TBoard>\n >,\n \"id\" | \"tiles\" | \"edges\" | \"vertices\"\n >,\n \"tiles\"\n> & {\n tiles: ReadonlyArray<NormalizedHexTileOf<TBoard>>;\n orientation?: \"pointy-top\" | \"flat-top\";\n};\n\nexport type NormalizedSquareBoard<TBoard extends AnySquareBoardInput> = Pick<\n SquareBoardState<\n BoardIdOf<TBoard>,\n BoardSpaceIdOf<TBoard>,\n BoardEdgeIdOf<TBoard>,\n BoardVertexIdOf<TBoard>,\n PieceValueOf<TBoard> extends { id: infer PieceIdValue extends string }\n ? PieceIdValue\n : string,\n SquareCellPropertiesOf<TBoard>,\n SquareEdgePropertiesOf<TBoard>,\n SquareVertexPropertiesOf<TBoard>,\n SquarePiecePropertiesOf<TBoard>\n >,\n \"id\" | \"rows\" | \"cols\" | \"cells\" | \"edges\" | \"vertices\" | \"pieces\"\n>;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction firstValue(record: Readonly<Record<string, unknown>>): unknown {\n const [first] = Object.values(record);\n return first;\n}\n\nfunction normalizeOptional<T>(\n value: T | null | undefined,\n): NormalizeOptional<T> {\n return (value ?? undefined) as NormalizeOptional<T>;\n}\n\nexport function isGeneratedHexBoardInput<\n TBoard extends AnyHexBoardInput | AnySquareBoardInput,\n>(\n board: TBoard,\n): board is Extract<TBoard, { spaces: Readonly<Record<string, unknown>> }> {\n if (!isRecord(board) || !(\"spaces\" in board) || !isRecord(board.spaces)) {\n return false;\n }\n if (\"tiles\" in board || \"cells\" in board) {\n return false;\n }\n if (board.layout === \"hex\") {\n return true;\n }\n const firstSpace = firstValue(\n board.spaces as Readonly<Record<string, unknown>>,\n );\n return (\n isRecord(firstSpace) &&\n typeof firstSpace.q === \"number\" &&\n typeof firstSpace.r === \"number\"\n );\n}\n\nexport function isGeneratedSquareBoardInput<\n TBoard extends AnyHexBoardInput | AnySquareBoardInput,\n>(\n board: TBoard,\n): board is Extract<TBoard, { spaces: Readonly<Record<string, unknown>> }> {\n if (!isRecord(board) || !(\"spaces\" in board) || !isRecord(board.spaces)) {\n return false;\n }\n if (\"tiles\" in board || \"cells\" in board) {\n return false;\n }\n if (board.layout === \"square\") {\n return true;\n }\n const firstSpace = firstValue(\n board.spaces as Readonly<Record<string, unknown>>,\n );\n return (\n isRecord(firstSpace) &&\n typeof firstSpace.row === \"number\" &&\n typeof firstSpace.col === \"number\"\n );\n}\n\nfunction normalizeHexTile<TBoard extends AnyHexBoardInput>(\n tile: SpaceRecordValueOf<TBoard>,\n): NormalizedHexTileOf<TBoard> {\n return {\n id: tile.id as BoardSpaceIdOf<TBoard>,\n q: tile.q as number,\n r: tile.r as number,\n typeId: normalizeOptional(tile.typeId as SpaceTypeId | null | undefined),\n label: normalizeOptional(tile.label as string | null | undefined),\n owner: normalizeOptional(tile.ownerId as PlayerId | null | undefined),\n properties: (tile.fields ?? undefined) as HexTilePropertiesOf<TBoard>,\n view: undefined,\n } as unknown as NormalizedHexTileOf<TBoard>;\n}\n\nfunction normalizeHexEdge<TBoard extends AnyHexBoardInput>(\n edge: EdgeValueOf<TBoard>,\n): NormalizedHexEdgeOf<TBoard> {\n if (\"hex1\" in edge && \"hex2\" in edge) {\n return {\n ...edge,\n label: normalizeOptional(edge.label),\n owner: normalizeOptional(edge.owner),\n typeId: normalizeOptional(edge.typeId),\n properties: edge.properties,\n } as NormalizedHexEdgeOf<TBoard>;\n }\n\n const [hex1 = \"\", hex2 = \"\"] = edge.spaceIds;\n return {\n id: edge.id as BoardEdgeIdOf<TBoard>,\n hex1: hex1 as BoardSpaceIdOf<TBoard>,\n hex2: hex2 as BoardSpaceIdOf<TBoard>,\n typeId: normalizeOptional(edge.typeId),\n label: normalizeOptional(edge.label),\n owner: normalizeOptional(edge.ownerId),\n properties: (edge.fields ?? undefined) as HexEdgePropertiesOf<TBoard>,\n };\n}\n\nfunction normalizeHexVertex<TBoard extends AnyHexBoardInput>(\n vertex: VertexValueOf<TBoard>,\n): NormalizedHexVertexOf<TBoard> {\n if (\"hexes\" in vertex) {\n return {\n ...vertex,\n label: normalizeOptional(vertex.label),\n owner: normalizeOptional(vertex.owner),\n typeId: normalizeOptional(vertex.typeId),\n properties: vertex.properties,\n } as NormalizedHexVertexOf<TBoard>;\n }\n\n return {\n id: vertex.id as BoardVertexIdOf<TBoard>,\n hexes: vertex.spaceIds as ReadonlyArray<BoardSpaceIdOf<TBoard>>,\n typeId: normalizeOptional(vertex.typeId),\n label: normalizeOptional(vertex.label),\n owner: normalizeOptional(vertex.ownerId),\n properties: (vertex.fields ?? undefined) as HexVertexPropertiesOf<TBoard>,\n };\n}\n\nfunction normalizeSquareCell<TBoard extends AnySquareBoardInput>(\n cell: SpaceRecordValueOf<TBoard>,\n): NormalizedSquareCellOf<TBoard> {\n return {\n id: cell.id as BoardSpaceIdOf<TBoard>,\n row: cell.row as number,\n col: cell.col as number,\n typeId: normalizeOptional(cell.typeId as SpaceTypeId | null | undefined),\n label: normalizeOptional(cell.label as string | null | undefined),\n owner: normalizeOptional(cell.ownerId as PlayerId | null | undefined),\n properties: (cell.fields ?? undefined) as SquareCellPropertiesOf<TBoard>,\n };\n}\n\nfunction normalizeSquareEdge<TBoard extends AnySquareBoardInput>(\n edge: EdgeValueOf<TBoard>,\n): NormalizedSquareEdgeOf<TBoard> {\n if (\"ownerId\" in edge || \"fields\" in edge) {\n return {\n id: edge.id as BoardEdgeIdOf<TBoard>,\n spaceIds: edge.spaceIds as ReadonlyArray<BoardSpaceIdOf<TBoard>>,\n typeId: normalizeOptional(edge.typeId),\n label: normalizeOptional(edge.label),\n owner: normalizeOptional(edge.ownerId),\n properties: (edge.fields ?? undefined) as SquareEdgePropertiesOf<TBoard>,\n };\n }\n\n return {\n id: edge.id as BoardEdgeIdOf<TBoard>,\n spaceIds: edge.spaceIds as ReadonlyArray<BoardSpaceIdOf<TBoard>>,\n typeId: normalizeOptional(edge.typeId),\n label: normalizeOptional(edge.label),\n owner: normalizeOptional(\n (edge as SquareEdgeState<string, string, RuntimeFields>).owner,\n ),\n properties: (edge as SquareEdgeState<string, string, RuntimeFields>)\n .properties as SquareEdgePropertiesOf<TBoard>,\n };\n}\n\nfunction normalizeSquareVertex<TBoard extends AnySquareBoardInput>(\n vertex: VertexValueOf<TBoard>,\n): NormalizedSquareVertexOf<TBoard> {\n if (\"ownerId\" in vertex || \"fields\" in vertex) {\n return {\n id: vertex.id as BoardVertexIdOf<TBoard>,\n spaceIds: vertex.spaceIds as ReadonlyArray<BoardSpaceIdOf<TBoard>>,\n typeId: normalizeOptional(vertex.typeId),\n label: normalizeOptional(vertex.label),\n owner: normalizeOptional(vertex.ownerId),\n properties: (vertex.fields ??\n undefined) as SquareVertexPropertiesOf<TBoard>,\n };\n }\n\n return {\n id: vertex.id as BoardVertexIdOf<TBoard>,\n spaceIds: vertex.spaceIds as ReadonlyArray<BoardSpaceIdOf<TBoard>>,\n typeId: normalizeOptional(vertex.typeId),\n label: normalizeOptional(vertex.label),\n owner: normalizeOptional(\n (vertex as SquareVertexState<string, string, RuntimeFields>).owner,\n ),\n properties: (vertex as SquareVertexState<string, string, RuntimeFields>)\n .properties as SquareVertexPropertiesOf<TBoard>,\n };\n}\n\nfunction isAuthoredHexBoardInput(\n board: AnyHexBoardInput,\n): board is Extract<AnyHexBoardInput, { tiles: readonly unknown[] }> {\n return \"tiles\" in board;\n}\n\nfunction isAuthoredSquareBoardInput(\n board: AnySquareBoardInput,\n): board is Extract<AnySquareBoardInput, { cells: readonly unknown[] }> {\n return \"cells\" in board;\n}\n\nexport function normalizeHexBoardInput<TBoard extends AnyHexBoardInput>(\n board: TBoard,\n): NormalizedHexBoard<TBoard> {\n if (isGeneratedHexBoardInput(board)) {\n return {\n id: board.id,\n orientation: board.orientation,\n tiles: Object.values(board.spaces).map((tile) =>\n normalizeHexTile<TBoard>(tile as SpaceRecordValueOf<TBoard>),\n ),\n edges: board.edges.map((edge) =>\n normalizeHexEdge<TBoard>(edge as EdgeValueOf<TBoard>),\n ),\n vertices: board.vertices.map((vertex) =>\n normalizeHexVertex<TBoard>(vertex as VertexValueOf<TBoard>),\n ),\n } as unknown as NormalizedHexBoard<TBoard>;\n }\n\n if (!isAuthoredHexBoardInput(board)) {\n throw new Error(\"Expected authored hex board input.\");\n }\n const authoredBoard = board as Extract<TBoard, { tiles: readonly unknown[] }>;\n return {\n id: authoredBoard.id,\n orientation: authoredBoard.orientation,\n tiles: authoredBoard.tiles.map((tile) => ({\n ...tile,\n label: normalizeOptional(tile.label),\n owner: normalizeOptional(tile.owner),\n typeId: normalizeOptional(tile.typeId),\n properties: tile.properties,\n view: tile.view,\n })),\n edges: authoredBoard.edges.map((edge) =>\n normalizeHexEdge<TBoard>(edge as EdgeValueOf<TBoard>),\n ),\n vertices: authoredBoard.vertices.map((vertex) =>\n normalizeHexVertex<TBoard>(vertex as VertexValueOf<TBoard>),\n ),\n } as unknown as NormalizedHexBoard<TBoard>;\n}\n\nexport function normalizeSquareBoardInput<TBoard extends AnySquareBoardInput>(\n board: TBoard,\n): NormalizedSquareBoard<TBoard> {\n if (isGeneratedSquareBoardInput(board)) {\n const cells = Object.values(board.spaces).map((cell) =>\n normalizeSquareCell<TBoard>(cell as SpaceRecordValueOf<TBoard>),\n );\n const rows =\n cells.length === 0 ? 0 : Math.max(...cells.map((cell) => cell.row)) + 1;\n const cols =\n cells.length === 0 ? 0 : Math.max(...cells.map((cell) => cell.col)) + 1;\n\n return {\n id: board.id,\n rows,\n cols,\n cells,\n edges: board.edges.map((edge) =>\n normalizeSquareEdge<TBoard>(edge as EdgeValueOf<TBoard>),\n ),\n vertices: board.vertices.map((vertex) =>\n normalizeSquareVertex<TBoard>(vertex as VertexValueOf<TBoard>),\n ),\n pieces: (\n (board.pieces ?? []) as ReadonlyArray<NormalizedSquarePieceOf<TBoard>>\n ).map((piece) => ({\n ...piece,\n owner: normalizeOptional(piece.owner),\n typeId: piece.typeId,\n properties: piece.properties,\n })),\n } as unknown as NormalizedSquareBoard<TBoard>;\n }\n\n if (!isAuthoredSquareBoardInput(board)) {\n throw new Error(\"Expected authored square board input.\");\n }\n const authoredBoard = board as Extract<TBoard, { cells: readonly unknown[] }>;\n return {\n id: authoredBoard.id,\n rows: authoredBoard.rows,\n cols: authoredBoard.cols,\n cells: authoredBoard.cells.map((cell) => ({\n ...cell,\n label: normalizeOptional(cell.label),\n owner: normalizeOptional(cell.owner),\n typeId: normalizeOptional(cell.typeId),\n properties: cell.properties,\n })),\n edges: authoredBoard.edges.map((edge) =>\n normalizeSquareEdge<TBoard>(edge as EdgeValueOf<TBoard>),\n ),\n vertices: authoredBoard.vertices.map((vertex) =>\n normalizeSquareVertex<TBoard>(vertex as VertexValueOf<TBoard>),\n ),\n pieces: (authoredBoard.pieces ?? []).map((piece) => ({\n ...piece,\n owner: normalizeOptional(piece.owner),\n typeId: piece.typeId,\n properties: piece.properties,\n })),\n } as unknown as NormalizedSquareBoard<TBoard>;\n}\n","/**\n * Controlled visual state contract for `@dreamboard-games/sdk/ui` components.\n *\n * The SDK is Dreamboard-interaction unaware: components consume `display data`\n * and `controlled semantic states`. Runtime adapters compute these states from\n * descriptors/drafts and pass them in as plain props.\n */\n\n/**\n * Generic semantic state attached to a presentational component.\n *\n * Every flag is optional and renders as a stable `data-*` attribute on the\n * underlying element so that selectors, snapshot diffs and accessibility\n * announcements can react to state without inspecting class strings.\n */\nexport interface InteractionVisualState {\n /** Caller may activate this surface right now. */\n eligible?: boolean;\n /**\n * Eligible *and* a meaningful subset — i.e. at least one peer surface is not\n * eligible. Use this (rather than `eligible`) to drive a \"highlight the\n * playable cards\" affordance: when every card in a hand is a legal target\n * (e.g. a pass where any card may be chosen, or a turn where you may play\n * anything) the highlight carries no information, so `distinctlyEligible` is\n * `false` for all of them and the ring naturally disappears. `eligible`\n * keeps its literal meaning (\"is a legal target\") for dimming/logic.\n */\n distinctlyEligible?: boolean;\n /** Currently chosen as part of a draft selection or focus state. */\n selected?: boolean;\n /** Surface is non-interactive and visually muted. */\n disabled?: boolean;\n /** Caller's draft is invalid — render an error tint without removing the surface. */\n invalid?: boolean;\n /** Action has been submitted; render a settled/locked feedback state. */\n submitted?: boolean;\n /** Surface is being previewed (long-press, hover hold) without commitment. */\n previewing?: boolean;\n /**\n * Optional 0..1 progress reading for an in-flight UI intent (swipe, hold,\n * etc.). Components may render this as a fill, scale or halo without owning\n * the gesture pipeline themselves.\n */\n intentProgress?: number;\n}\n\n/**\n * Generic UI intent emitted by SDK components.\n *\n * Components do not know what `activate`/`drop` mean in Dreamboard terms —\n * that mapping belongs to a runtime adapter. They only emit when a generic\n * pointer/keyboard gesture completes.\n *\n * - `activate` is a single-target commit produced by a desktop click or a\n * keyboard activation in `direct-activate` mode.\n * - `drop` is a card→target commit produced by mobile drag or keyboard drop\n * in `drag-to-target` mode. The opaque `targetId` is registered by a\n * `CardDropTargetView` and resolved against pointer geometry inside the\n * `CardDragSurface`.\n * - `previewStart`/`previewEnd` bracket a long-press inspection that does\n * not commit.\n */\nexport type CardIntent<\n CardId extends string = string,\n TargetId extends string = string,\n> =\n | { type: \"activate\"; cardId: CardId; source: \"tap\" | \"keyboard\" }\n | { type: \"previewStart\"; cardId: CardId }\n | { type: \"previewEnd\"; cardId: CardId }\n | {\n type: \"drop\";\n cardId: CardId;\n targetId: TargetId;\n source: \"pointer\" | \"keyboard\";\n };\n\n/**\n * Generic UI intent emitted for a board target (space/edge/vertex).\n */\nexport type TargetIntent<TargetId extends string = string> =\n | { type: \"activate\"; targetId: TargetId; source: \"tap\" | \"keyboard\" }\n | { type: \"previewStart\"; targetId: TargetId }\n | { type: \"previewEnd\"; targetId: TargetId };\n\n/**\n * Controlled visual state for a card drop target rendered through\n * `CardDropTargetView`.\n *\n * `active` is `true` when any card is currently being dragged anywhere on\n * the surface (eligible target should advertise itself). `over` is `true`\n * only for the target that the lifted pointer would currently drop on.\n */\nexport interface CardDropTargetVisualState extends InteractionVisualState {\n active?: boolean;\n over?: boolean;\n}\n\n/**\n * Build the `data-*` attribute bag for an {@link InteractionVisualState} so\n * that components apply a single consistent attribute surface.\n *\n * `undefined` values are emitted (rather than `false`) so that CSS\n * `[data-…=\"true\"]` selectors do not match by mistake.\n */\nexport function visualStateDataAttributes(\n state: InteractionVisualState | undefined,\n): Readonly<Record<string, string | undefined>> {\n if (!state) return {};\n return {\n \"data-eligible\": state.eligible ? \"true\" : undefined,\n \"data-distinctly-eligible\": state.distinctlyEligible ? \"true\" : undefined,\n \"data-selected\": state.selected ? \"true\" : undefined,\n \"data-disabled\": state.disabled ? \"true\" : undefined,\n \"data-invalid\": state.invalid ? \"true\" : undefined,\n \"data-submitted\": state.submitted ? \"true\" : undefined,\n \"data-previewing\": state.previewing ? \"true\" : undefined,\n \"data-intent-progress\":\n typeof state.intentProgress === \"number\"\n ? String(Math.max(0, Math.min(1, state.intentProgress)))\n : undefined,\n };\n}\n\n/**\n * Build the `data-*` attribute bag for a {@link CardDropTargetVisualState}.\n */\nexport function dropTargetVisualStateDataAttributes(\n state: CardDropTargetVisualState | undefined,\n): Readonly<Record<string, string | undefined>> {\n const base = visualStateDataAttributes(state);\n if (!state) return base;\n return {\n ...base,\n \"data-drag-active\": state.active ? \"true\" : undefined,\n \"data-drag-over\": state.over ? \"true\" : undefined,\n };\n}\n","/**\n * Presentational card shell. Feed from reducer views, not runtime state.\n *\n * `CardFace` is the only public reusable card shell in `@dreamboard-games/sdk/ui`.\n * It renders display content with controlled {@link InteractionVisualState}\n * (eligible / selected / disabled / invalid / submitted / previewing) and\n * exposes stable `data-*` attributes. It does not own activation behavior —\n * compose it with a generic `<button>` (or with a runtime adapter) when an\n * authored surface needs to react to taps or keyboard activation.\n */\n\nimport { clsx } from \"clsx\";\nimport type { ViewCard } from \"../../types/index.js\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\nimport { motionDuration } from \"../theme/derive.js\";\nimport {\n visualStateDataAttributes,\n type InteractionVisualState,\n} from \"../types/visual-state.js\";\n\nexport interface CardFaceProps<CardData extends ViewCard = ViewCard>\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, \"children\">,\n InteractionVisualState {\n card: CardData;\n size?: \"sm\" | \"md\" | \"lg\";\n faceDown?: boolean;\n renderContent?: (card: CardData) => React.ReactNode;\n children?: React.ReactNode;\n}\n\n/**\n * Reserved keys on `ViewCard.properties` that the default content\n * renderer recognises and styles consistently. Authors who set these\n * keys at view-build time get a properly laid-out card face for free\n * (icon → title → subtitle → effect → cost), instead of the previous\n * \"first three properties as label/value\" fallback that produced\n * inconsistent card faces across games.\n *\n * Any other property keys are still rendered, just below the\n * conventional cluster, so authors can mix and match without losing\n * data — but the canonical surface should pick from these slots first.\n *\n * Slots:\n *\n * - `icon` — short visual flag (emoji, glyph). Rendered large at the\n * top of the card.\n * - `title` — primary label. Falls back to `card.name`.\n * - `subtitle` — short qualifier (\"1 VP\", \"Action\", \"Resource\").\n * - `effect` — body text describing what the card does.\n * - `cost` — short cost line (\"3 brick\"); rendered as a chip footer.\n */\nconst RESERVED_CONTENT_KEYS = [\n \"icon\",\n \"title\",\n \"subtitle\",\n \"effect\",\n \"cost\",\n] as const;\n\ntype ReservedKey = (typeof RESERVED_CONTENT_KEYS)[number];\n\nconst RESERVED_KEY_SET: ReadonlySet<string> = new Set(RESERVED_CONTENT_KEYS);\n\nfunction readReserved(\n props: Record<string, unknown> | undefined,\n key: ReservedKey,\n): string | undefined {\n if (!props) return undefined;\n const raw = props[key];\n if (raw === undefined || raw === null) return undefined;\n return String(raw);\n}\n\n/** Default card content renderer. */\nfunction DefaultCardContent({\n card,\n size,\n}: {\n card: ViewCard;\n size: NonNullable<CardFaceProps[\"size\"]>;\n}) {\n const theme = useTheme();\n const props = card.properties as Record<string, unknown> | undefined;\n const icon = readReserved(props, \"icon\");\n const title = readReserved(props, \"title\") ?? card.name;\n const subtitle = readReserved(props, \"subtitle\");\n const effect = readReserved(props, \"effect\");\n const cost = readReserved(props, \"cost\");\n const extra = props\n ? Object.entries(props).filter(([key]) => !RESERVED_KEY_SET.has(key))\n : [];\n\n const hasAnyReserved = icon || title || subtitle || effect || cost;\n const compact = size === \"sm\";\n\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n height: \"100%\",\n minHeight: 0,\n boxSizing: \"border-box\",\n overflow: \"hidden\",\n textAlign: \"center\",\n padding: compact ? theme.space[1] : theme.space[2],\n gap: compact ? theme.space[0.5] : theme.space[1],\n }}\n >\n {icon ? (\n <span\n aria-hidden\n style={{\n flexShrink: 0,\n fontSize: compact\n ? theme.typography.fontSize.lg\n : theme.typography.fontSize[\"2xl\"],\n lineHeight: 1,\n }}\n >\n {icon}\n </span>\n ) : null}\n {title ? (\n <span\n style={{\n flexShrink: 0,\n fontFamily: theme.typography.fontFamily.display,\n fontSize: theme.typography.fontSize.sm,\n fontWeight: theme.typography.fontWeight.bold,\n color: theme.semantic.text.primary,\n lineHeight: theme.typography.lineHeight.tight,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n display: \"-webkit-box\",\n WebkitLineClamp: 2,\n WebkitBoxOrient: \"vertical\",\n wordBreak: \"break-word\",\n }}\n >\n {title}\n </span>\n ) : null}\n {subtitle ? (\n <span\n style={{\n flexShrink: 0,\n fontFamily: theme.typography.fontFamily.body,\n fontSize: theme.typography.fontSize.xs,\n fontWeight: theme.typography.fontWeight.medium,\n color: theme.semantic.text.muted,\n letterSpacing: theme.typography.letterSpacing.wide,\n textTransform: \"uppercase\",\n }}\n >\n {subtitle}\n </span>\n ) : null}\n {effect ? (\n <span\n style={{\n flex: \"1 1 auto\",\n minHeight: 0,\n fontFamily: theme.typography.fontFamily.body,\n fontSize: theme.typography.fontSize.xs,\n color: theme.semantic.text.muted,\n lineHeight: theme.typography.lineHeight.normal,\n display: \"-webkit-box\",\n WebkitLineClamp: compact ? 1 : size === \"md\" ? 2 : 3,\n WebkitBoxOrient: \"vertical\",\n overflow: \"hidden\",\n }}\n >\n {effect}\n </span>\n ) : null}\n {cost ? (\n <span\n style={{\n display: \"inline-flex\",\n flexShrink: 0,\n alignItems: \"center\",\n gap: theme.space[1],\n paddingBlock: theme.space[0.5],\n paddingInline: theme.space[2],\n borderRadius: theme.radius.pill,\n background: theme.semantic.surface.inset,\n border: `1px solid ${theme.semantic.border.subtle}`,\n fontFamily: theme.typography.fontFamily.tabular,\n fontSize: theme.typography.fontSize.xs,\n fontWeight: theme.typography.fontWeight.bold,\n color: theme.semantic.text.primary,\n marginTop: \"auto\",\n }}\n >\n {cost}\n </span>\n ) : null}\n {!hasAnyReserved && extra.length > 0\n ? extra.slice(0, 3).map(([key, value]) => (\n <span\n key={key}\n style={{\n flexShrink: 0,\n fontFamily: theme.typography.fontFamily.body,\n fontSize: theme.typography.fontSize.xs,\n color: theme.semantic.text.primary,\n }}\n >\n <span style={{ color: theme.semantic.text.muted }}>{key}:</span>{\" \"}\n <span style={{ fontWeight: theme.typography.fontWeight.bold }}>\n {String(value)}\n </span>\n </span>\n ))\n : null}\n {!hasAnyReserved && extra.length === 0 ? (\n <span\n style={{\n flexShrink: 0,\n fontFamily: theme.typography.fontFamily.mono,\n fontSize: theme.typography.fontSize.xs,\n color: theme.semantic.text.disabled,\n }}\n >\n {card.id.slice(0, 8)}\n </span>\n ) : null}\n </div>\n );\n}\n\nconst CARD_SIZE_CLASSES = {\n sm: \"w-16 h-24 sm:w-20 sm:h-28\",\n md: \"w-20 h-32 sm:w-24 sm:h-36\",\n lg: \"w-24 h-36 sm:w-32 sm:h-48\",\n} as const;\n\nexport function CardFace<CardData extends ViewCard = ViewCard>({\n card,\n eligible,\n selected = false,\n disabled = false,\n invalid,\n submitted,\n previewing,\n intentProgress,\n size = \"md\",\n faceDown = false,\n renderContent,\n children,\n className,\n style,\n ...props\n}: CardFaceProps<CardData>) {\n const theme = useTheme();\n const calmCornerRadius = theme.radius.md;\n const accentCornerRadius = `${theme.radius.lg} ${theme.radius.sm} ${theme.radius.lg} ${theme.radius.sm} / ${theme.radius.sm} ${theme.radius.lg} ${theme.radius.sm} ${theme.radius.lg}`;\n const selectionRingColor = theme.component.card.selectedRing;\n const eligibleRingColor = theme.semantic.intent.warning.border;\n const invalidRingColor = theme.semantic.intent.danger.border;\n const submittedRingColor = theme.semantic.intent.success.border;\n const restBorderColor = theme.component.card.border;\n const dataAttributes = visualStateDataAttributes({\n eligible,\n selected,\n disabled,\n invalid,\n submitted,\n previewing,\n intentProgress,\n });\n // Routine resting cards use a calm modern surface. Hard-shadow / irregular\n // corner accents are reserved for explicit emphasis states so a fanned\n // hand reads as ordered play instead of repeated decoration.\n const accentColor = invalid\n ? invalidRingColor\n : submitted\n ? submittedRingColor\n : selected\n ? selectionRingColor\n : previewing\n ? selectionRingColor\n : eligible\n ? eligibleRingColor\n : undefined;\n const isAccented = Boolean(accentColor);\n const accentShadow = selected\n ? `6px 6px 0px 0px ${selectionRingColor}`\n : previewing\n ? `4px 4px 0px 0px ${selectionRingColor}`\n : invalid\n ? `4px 4px 0px 0px ${invalidRingColor}`\n : submitted\n ? `4px 4px 0px 0px ${submittedRingColor}`\n : eligible\n ? `4px 4px 0px 0px ${eligibleRingColor}`\n : undefined;\n const restShadow = theme.elevation.rest;\n\n return (\n <div\n {...props}\n {...dataAttributes}\n data-dreamboard-card-face=\"\"\n data-accented={isAccented ? \"true\" : undefined}\n data-face-down={faceDown ? \"true\" : undefined}\n className={clsx(\"relative\", CARD_SIZE_CLASSES[size], className)}\n style={{\n opacity: disabled ? 0.5 : submitted ? 0.85 : 1,\n transitionProperty: \"transform, box-shadow, border-color\",\n transitionDuration: motionDuration(theme, \"normal\"),\n transitionTimingFunction: theme.motion.easing.out,\n transform: previewing ? \"translateY(-2px) scale(1.02)\" : undefined,\n ...style,\n }}\n >\n {faceDown ? (\n // Card back: keep the playful diagonal pattern as artwork, but\n // anchor the shell on the same calm baseline as a face-up card so\n // a row of opponent hands or a draw pile reads as ordered chrome\n // rather than repeated decoration. Emphasis states (selected,\n // eligible, invalid, submitted, previewing) still upgrade to the\n // accent radius + hard-offset shadow.\n <div\n className=\"absolute inset-0 overflow-hidden pointer-events-none\"\n style={{\n background: theme.component.card.backBackground,\n borderStyle: \"solid\",\n borderWidth: isAccented ? 3 : 1,\n borderColor: accentColor ?? restBorderColor,\n borderRadius: isAccented ? accentCornerRadius : calmCornerRadius,\n boxShadow: accentShadow ?? restShadow,\n }}\n >\n <div\n className=\"absolute inset-2\"\n style={{\n borderRadius: calmCornerRadius,\n background:\n \"repeating-linear-gradient(45deg, transparent, transparent 10px, rgba(255,255,255,0.2) 10px, rgba(255,255,255,0.2) 20px)\",\n }}\n />\n </div>\n ) : (\n <div\n className=\"absolute inset-0 overflow-hidden pointer-events-none\"\n style={{\n background: submitted\n ? theme.semantic.intent.success.soft\n : theme.semantic.surface.card,\n borderStyle: \"solid\",\n borderWidth: isAccented ? 3 : 1,\n borderColor: accentColor ?? restBorderColor,\n borderRadius: isAccented ? accentCornerRadius : calmCornerRadius,\n boxShadow: accentShadow ?? restShadow,\n outline:\n selected || invalid\n ? `2px solid ${accentColor ?? selectionRingColor}`\n : undefined,\n outlineOffset: selected || invalid ? \"1px\" : undefined,\n }}\n >\n {children ??\n (renderContent ? (\n renderContent(card)\n ) : (\n <DefaultCardContent card={card} size={size} />\n ))}\n </div>\n )}\n </div>\n );\n}\n\nexport type { ViewCard };\n","/** Mobile-friendly slide-out panel built on vaul. Used as fallback when cards can't fit on screen. */\n\nimport * as React from \"react\";\nimport { Drawer as DrawerPrimitive } from \"vaul\";\nimport { clsx } from \"clsx\";\n\nfunction Drawer({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Root>) {\n return <DrawerPrimitive.Root data-slot=\"drawer\" {...props} />;\n}\n\nfunction DrawerTrigger({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {\n return <DrawerPrimitive.Trigger data-slot=\"drawer-trigger\" {...props} />;\n}\n\nfunction DrawerPortal({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Portal>) {\n return <DrawerPrimitive.Portal data-slot=\"drawer-portal\" {...props} />;\n}\n\nfunction DrawerClose({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Close>) {\n return <DrawerPrimitive.Close data-slot=\"drawer-close\" {...props} />;\n}\n\nfunction DrawerOverlay({\n className,\n style,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {\n return (\n <DrawerPrimitive.Overlay\n data-slot=\"drawer-overlay\"\n className={clsx(\n \"fixed inset-0 z-50 bg-black/50\",\n \"data-[state=open]:animate-in data-[state=closed]:animate-out\",\n \"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n className,\n )}\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 50,\n background: \"rgba(0, 0, 0, 0.5)\",\n ...style,\n }}\n {...props}\n />\n );\n}\n\ninterface DrawerContentProps extends React.ComponentPropsWithoutRef<\n typeof DrawerPrimitive.Content\n> {\n showHandle?: boolean;\n children?: React.ReactNode;\n}\n\nfunction DrawerContent({\n className,\n children,\n showHandle = true,\n ...props\n}: DrawerContentProps) {\n return (\n <DrawerPortal data-slot=\"drawer-portal\">\n <DrawerOverlay />\n <DrawerPrimitive.Content\n data-slot=\"drawer-content\"\n className={clsx(\n \"group/drawer-content fixed z-50 flex h-auto flex-col bg-white\",\n // Bottom drawer (default for mobile hand display)\n \"data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0\",\n \"data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh]\",\n \"data-[vaul-drawer-direction=bottom]:rounded-t-xl data-[vaul-drawer-direction=bottom]:border-t\",\n // Top drawer\n \"data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0\",\n \"data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh]\",\n \"data-[vaul-drawer-direction=top]:rounded-b-xl data-[vaul-drawer-direction=top]:border-b\",\n // Right drawer\n \"data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0\",\n \"data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:max-w-sm\",\n \"data-[vaul-drawer-direction=right]:rounded-l-xl data-[vaul-drawer-direction=right]:border-l\",\n // Left drawer\n \"data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0\",\n \"data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:max-w-sm\",\n \"data-[vaul-drawer-direction=left]:rounded-r-xl data-[vaul-drawer-direction=left]:border-r\",\n className,\n )}\n {...props}\n >\n {/* Drag handle for bottom drawer */}\n {showHandle && (\n <div\n className=\"mx-auto mt-4 h-2 w-[100px] shrink-0 rounded-full bg-slate-300\"\n style={{\n width: 100,\n height: 8,\n margin: \"16px auto 0\",\n flexShrink: 0,\n borderRadius: 999,\n background: \"#cbd5e1\",\n }}\n />\n )}\n {children}\n </DrawerPrimitive.Content>\n </DrawerPortal>\n );\n}\n\nfunction DrawerHeader({\n className,\n ...props\n}: React.ComponentPropsWithoutRef<\"div\">) {\n return (\n <div\n data-slot=\"drawer-header\"\n className={clsx(\"flex flex-col gap-1.5 p-4\", className)}\n {...props}\n />\n );\n}\n\nfunction DrawerFooter({\n className,\n ...props\n}: React.ComponentPropsWithoutRef<\"div\">) {\n return (\n <div\n data-slot=\"drawer-footer\"\n className={clsx(\"mt-auto flex flex-col gap-2 p-4\", className)}\n {...props}\n />\n );\n}\n\nfunction DrawerTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Title>) {\n return (\n <DrawerPrimitive.Title\n data-slot=\"drawer-title\"\n className={clsx(\"text-slate-900 font-semibold text-lg\", className)}\n {...props}\n />\n );\n}\n\nfunction DrawerDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Description>) {\n return (\n <DrawerPrimitive.Description\n data-slot=\"drawer-description\"\n className={clsx(\"text-slate-500 text-sm\", className)}\n {...props}\n />\n );\n}\n\nexport {\n Drawer,\n DrawerPortal,\n DrawerOverlay,\n DrawerTrigger,\n DrawerClose,\n DrawerContent,\n DrawerHeader,\n DrawerFooter,\n DrawerTitle,\n DrawerDescription,\n};\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n type ReactNode,\n} from \"react\";\n\ntype ChromeSuppressionRegistration = (id: string, suppressed: boolean) => void;\n\nconst ChromeSuppressionContext =\n createContext<ChromeSuppressionRegistration | null>(null);\n\nexport function ChromeSuppressionProvider({\n children,\n onSuppressedChange,\n}: {\n children: ReactNode;\n onSuppressedChange: (suppressed: boolean) => void;\n}) {\n const [suppressedEntries, setSuppressedEntries] = useState<\n ReadonlySet<string>\n >(() => new Set());\n\n const register = useCallback<ChromeSuppressionRegistration>(\n (id, suppressed) => {\n setSuppressedEntries((current) =>\n updateSuppressedEntries(current, id, suppressed),\n );\n },\n [],\n );\n const suppressed = suppressedEntries.size > 0;\n\n useEffect(() => {\n onSuppressedChange(suppressed);\n }, [onSuppressedChange, suppressed]);\n\n const value = useMemo(() => register, [register]);\n\n return (\n <ChromeSuppressionContext.Provider value={value}>\n {children}\n </ChromeSuppressionContext.Provider>\n );\n}\n\nexport function useChromeSuppression(id: string, suppressed: boolean) {\n const register = useContext(ChromeSuppressionContext);\n\n useEffect(() => {\n if (!register) return;\n register(id, suppressed);\n return () => register(id, false);\n }, [id, register, suppressed]);\n}\n\nfunction updateSuppressedEntries(\n current: ReadonlySet<string>,\n id: string,\n suppressed: boolean,\n) {\n if (current.has(id) === suppressed) return current;\n const next = new Set(current);\n if (suppressed) next.add(id);\n else next.delete(id);\n return next;\n}\n","import type { ComponentProps } from \"react\";\nimport { clsx } from \"clsx\";\nimport { Button as ShadcnButton } from \"../internal/ui/button.js\";\nimport {\n buttonStyle,\n type ButtonSize,\n type ButtonVariant,\n} from \"../theme/derive.js\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\nimport {\n visualStateDataAttributes,\n type InteractionVisualState,\n} from \"../types/visual-state.js\";\n\ntype ShadcnButtonProps = ComponentProps<typeof ShadcnButton>;\n\nexport interface ThemedButtonProps\n extends Omit<ShadcnButtonProps, \"variant\" | \"size\">, InteractionVisualState {\n variant?: ButtonVariant;\n size?: ButtonSize;\n /** Renders the pressed/active visual treatment without changing variant. */\n pressed?: boolean;\n /** Render the in-flight loading state and disable activation. */\n loading?: boolean;\n}\n\nexport function ThemedButton({\n variant = \"primary\",\n size = \"md\",\n pressed = false,\n loading = false,\n eligible,\n selected,\n disabled,\n invalid,\n submitted,\n previewing,\n intentProgress,\n className,\n style,\n ...props\n}: ThemedButtonProps) {\n const theme = useTheme();\n const isDisabled = disabled || loading || submitted;\n const dataAttributes = visualStateDataAttributes({\n eligible,\n selected,\n disabled: isDisabled,\n invalid,\n submitted,\n previewing,\n intentProgress,\n });\n return (\n <ShadcnButton\n variant={toShadcnVariant(submitted ? \"submitted\" : variant)}\n size={toShadcnSize(size)}\n disabled={isDisabled}\n data-dreamboard-button\n data-dreamboard-button-variant={submitted ? \"submitted\" : variant}\n data-dreamboard-button-size={size}\n data-pressed={pressed ? \"true\" : undefined}\n data-loading={loading ? \"true\" : undefined}\n aria-busy={loading || undefined}\n aria-pressed={selected ? true : pressed ? true : undefined}\n aria-invalid={invalid || undefined}\n {...dataAttributes}\n className={clsx(\"font-sans\", className)}\n style={{\n ...buttonStyle(theme, {\n variant: submitted ? \"submitted\" : variant,\n size,\n disabled: isDisabled,\n pressed,\n }),\n ...style,\n }}\n {...props}\n />\n );\n}\n\nfunction toShadcnVariant(\n variant: ButtonVariant,\n): NonNullable<ShadcnButtonProps[\"variant\"]> {\n switch (variant) {\n case \"danger\":\n return \"destructive\";\n case \"ghost\":\n return \"ghost\";\n case \"secondary\":\n return \"secondary\";\n case \"primary\":\n case \"submitted\":\n case \"success\":\n case \"warning\":\n case \"info\":\n return \"default\";\n }\n}\n\nfunction toShadcnSize(\n size: ButtonSize,\n): NonNullable<ShadcnButtonProps[\"size\"]> {\n switch (size) {\n case \"sm\":\n return \"sm\";\n case \"md\":\n return \"default\";\n case \"lg\":\n return \"lg\";\n }\n}\n","import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cn } from \"./utils.js\";\n\nexport type ButtonVariant =\n | \"default\"\n | \"destructive\"\n | \"outline\"\n | \"secondary\"\n | \"ghost\"\n | \"link\";\n\nexport type ButtonSize = \"default\" | \"sm\" | \"lg\" | \"icon\";\n\nexport interface ButtonProps extends React.ComponentProps<\"button\"> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n asChild?: boolean;\n}\n\nconst variantClass: Record<ButtonVariant, string> = {\n default: \"border-slate-900 bg-white text-slate-950 hover:bg-slate-100\",\n destructive: \"border-red-900 bg-red-600 text-white hover:bg-red-700\",\n outline: \"border-slate-900 bg-transparent hover:bg-slate-100\",\n secondary: \"border-slate-700 bg-slate-100 text-slate-950 hover:bg-slate-200\",\n ghost: \"border-transparent bg-transparent hover:bg-slate-100\",\n link: \"border-transparent bg-transparent text-blue-700 underline-offset-4 hover:underline\",\n};\n\nconst sizeClass: Record<ButtonSize, string> = {\n default: \"h-10 px-4 py-2\",\n sm: \"h-9 px-3\",\n lg: \"h-11 px-8\",\n icon: \"size-10\",\n};\n\nexport function Button({\n className,\n variant = \"default\",\n size = \"default\",\n asChild = false,\n ...props\n}: ButtonProps) {\n const Comp = asChild ? Slot : \"button\";\n return (\n <Comp\n data-slot=\"button\"\n className={cn(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md border text-sm font-medium transition-colors outline-none disabled:pointer-events-none disabled:opacity-50\",\n \"focus-visible:ring-2 focus-visible:ring-slate-400 focus-visible:ring-offset-2\",\n variantClass[variant],\n sizeClass[size],\n className,\n )}\n {...props}\n />\n );\n}\n","import { clsx, type ClassValue } from \"clsx\";\n\nexport function cn(...inputs: ClassValue[]) {\n return clsx(inputs);\n}\n","import { useId, useState, type CSSProperties, type ReactNode } from \"react\";\nimport { useDrag } from \"@use-gesture/react\";\nimport {\n Drawer,\n DrawerContent,\n DrawerDescription,\n DrawerHeader,\n DrawerTitle,\n DrawerTrigger,\n} from \"./Drawer.js\";\nimport { useChromeSuppression } from \"./ChromeSuppressionContext.js\";\nimport { ThemedButton } from \"./ThemedButton.js\";\nimport { useThemeCssVars } from \"../theme/ThemeProvider.js\";\n\nexport type HandDockMode = \"inline\" | \"drawer\" | \"hidden\";\nexport type HandDockPlacement =\n | \"bottom-left\"\n | \"bottom-center\"\n | \"bottom-right\";\n\nexport interface HandDockToggleContext {\n label: string;\n count: number;\n open: boolean;\n}\n\nexport interface HandDockPresentation {\n /**\n * `inline` preserves the normal shell hand strip. `drawer` collapses the\n * zone behind a viewport-safe toggle. `hidden` suppresses the zone entirely.\n */\n mode?: HandDockMode;\n /** Initial drawer state. Defaults to closed. */\n defaultOpen?: boolean;\n /** Where the drawer toggle/tray docks in the viewport. */\n placement?: HandDockPlacement;\n /** Toggle label override. Receives card count and open state. */\n toggleLabel?: ReactNode | ((context: HandDockToggleContext) => ReactNode);\n /** Width of the opened tray. */\n maxWidth?: CSSProperties[\"maxWidth\"];\n /** Height of the opened tray before it scrolls. */\n maxHeight?: CSSProperties[\"maxHeight\"];\n /** Extra style escape hatch for the outer dock. */\n style?: CSSProperties;\n}\n\nexport interface HandDockProps {\n label: string;\n count: number;\n presentation?: HandDockPresentation;\n children: ReactNode;\n}\n\nconst DEFAULT_MAX_WIDTH = \"min(28rem, calc(100vw - 24px))\";\nconst DEFAULT_MAX_HEIGHT = \"min(65vh, calc(100vh - 96px))\";\n\nfunction placementStyle(placement: HandDockPlacement): CSSProperties {\n const base: CSSProperties = {\n position: \"fixed\",\n bottom: \"calc(12px + env(safe-area-inset-bottom, 0px))\",\n zIndex: 900,\n };\n switch (placement) {\n case \"bottom-center\":\n return {\n ...base,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n };\n case \"bottom-right\":\n return {\n ...base,\n right: \"calc(12px + env(safe-area-inset-right, 0px))\",\n };\n case \"bottom-left\":\n default:\n return {\n ...base,\n left: \"calc(12px + env(safe-area-inset-left, 0px))\",\n };\n }\n}\n\nfunction triggerAlignment(\n placement: HandDockPlacement,\n): CSSProperties[\"alignSelf\"] {\n switch (placement) {\n case \"bottom-center\":\n return \"center\";\n case \"bottom-right\":\n return \"flex-end\";\n case \"bottom-left\":\n default:\n return \"flex-start\";\n }\n}\n\nfunction renderToggleLabel(\n label: string,\n count: number,\n open: boolean,\n override: HandDockPresentation[\"toggleLabel\"],\n) {\n if (typeof override === \"function\") return override({ label, count, open });\n if (override !== undefined) return override;\n return `${label} (${count})`;\n}\n\nexport function HandDock({\n label,\n count,\n presentation,\n children,\n}: HandDockProps) {\n const mode = presentation?.mode ?? \"inline\";\n const [open, setOpen] = useState(presentation?.defaultOpen ?? false);\n const contentId = useId();\n const themeCssVars = useThemeCssVars();\n useChromeSuppression(contentId, mode === \"drawer\" && open);\n\n // Swipe-up-to-open gesture on the dock handle strip.\n // The hook must be called unconditionally (React rules); we apply the\n // bindings only in drawer mode when the drawer is closed.\n const bindDrag = useDrag(\n ({ movement: [, my], velocity: [, vy], last }) => {\n // Require: upward movement > 40 px at > 0.3 px/ms velocity on release\n if (last && my < -40 && vy > 0.3) {\n setOpen(true);\n }\n },\n { axis: \"y\", filterTaps: true },\n );\n\n if (mode === \"hidden\") return null;\n if (mode === \"inline\") return <>{children}</>;\n\n const placement = presentation?.placement ?? \"bottom-left\";\n const toggleLabel = renderToggleLabel(\n label,\n count,\n open,\n presentation?.toggleLabel,\n );\n\n const fallbackContentStyle: CSSProperties = {\n maxHeight: presentation?.maxHeight ?? DEFAULT_MAX_HEIGHT,\n overflow: \"auto\",\n padding: 12,\n pointerEvents: \"auto\",\n };\n const triggerStyle: CSSProperties = {\n alignSelf: triggerAlignment(placement),\n boxShadow: \"0 10px 28px rgba(15, 23, 42, 0.22)\",\n pointerEvents: \"auto\",\n visibility: open ? \"hidden\" : \"visible\",\n };\n const canUsePortal = typeof document !== \"undefined\";\n const serverOpenContent =\n !canUsePortal && open ? (\n <div\n id={contentId}\n role=\"region\"\n aria-label={label}\n style={fallbackContentStyle}\n >\n {children}\n </div>\n ) : null;\n\n return (\n <Drawer open={open} onOpenChange={setOpen} direction=\"bottom\">\n <div\n data-hand-dock={label}\n data-state={open ? \"open\" : \"closed\"}\n style={{\n ...placementStyle(placement),\n display: \"flex\",\n maxWidth: presentation?.maxWidth ?? DEFAULT_MAX_WIDTH,\n width: presentation?.maxWidth ?? DEFAULT_MAX_WIDTH,\n flexDirection: \"column\",\n alignItems: \"stretch\",\n gap: 8,\n pointerEvents: \"none\",\n ...presentation?.style,\n }}\n >\n {serverOpenContent}\n {/* Drag-handle strip — visible only when drawer is closed.\n Provides a touch target for the swipe-up-to-open gesture and a\n visual affordance matching the standard mobile bottom-sheet pattern. */}\n {!open && (\n <div\n {...bindDrag()}\n aria-hidden\n role=\"presentation\"\n style={{\n alignSelf: triggerAlignment(placement),\n padding: \"8px 16px 4px\",\n cursor: \"grab\",\n touchAction: \"none\",\n pointerEvents: \"auto\",\n display: \"flex\",\n justifyContent: \"center\",\n }}\n >\n <div\n style={{\n width: 36,\n height: 4,\n borderRadius: 2,\n background: \"rgba(15, 23, 42, 0.25)\",\n }}\n />\n </div>\n )}\n <DrawerTrigger asChild>\n <ThemedButton\n type=\"button\"\n variant=\"secondary\"\n size=\"sm\"\n data-state={open ? \"open\" : \"closed\"}\n aria-expanded={open}\n aria-controls={open ? contentId : undefined}\n className=\"rounded-full\"\n style={triggerStyle}\n >\n {toggleLabel}\n </ThemedButton>\n </DrawerTrigger>\n </div>\n {canUsePortal ? (\n <DrawerContent\n id={contentId}\n aria-describedby={undefined}\n className=\"border-border bg-background/95 shadow-2xl backdrop-blur supports-[backdrop-filter]:bg-background/90\"\n style={{\n ...themeCssVars,\n position: \"fixed\",\n right: 0,\n bottom: 0,\n left: 0,\n zIndex: 50,\n display: \"flex\",\n maxHeight: \"80vh\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n borderTop: \"1px solid var(--border, #cbd5e1)\",\n borderTopLeftRadius: 16,\n borderTopRightRadius: 16,\n background: \"var(--background, rgba(255, 255, 255, 0.96))\",\n color: \"var(--foreground, #0f172a)\",\n fontFamily: \"var(--font-sans)\",\n boxShadow: \"0 -18px 48px rgba(15, 23, 42, 0.22)\",\n backdropFilter: \"blur(8px)\",\n }}\n >\n <DrawerHeader\n className=\"border-border border-b px-4 pb-3 pt-3 text-left\"\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 4,\n borderBottom: \"1px solid var(--border, #e2e8f0)\",\n padding: \"12px 16px\",\n textAlign: \"left\",\n }}\n >\n <DrawerTitle\n className=\"text-base\"\n style={{ fontSize: 16, fontWeight: 600, lineHeight: 1.25 }}\n >\n {label}\n </DrawerTitle>\n <DrawerDescription>\n {count} card{count === 1 ? \"\" : \"s\"} available.\n </DrawerDescription>\n </DrawerHeader>\n <div\n role=\"region\"\n aria-label={label}\n style={{\n maxHeight: presentation?.maxHeight ?? DEFAULT_MAX_HEIGHT,\n maxWidth: presentation?.maxWidth ?? DEFAULT_MAX_WIDTH,\n width: \"100%\",\n margin: \"0 auto\",\n overflow: \"auto\",\n padding:\n \"12px 16px calc(16px + env(safe-area-inset-bottom, 0px))\",\n boxSizing: \"border-box\",\n }}\n className=\"mx-auto w-full overflow-y-auto px-4 pb-[calc(1rem+env(safe-area-inset-bottom,0px))] pt-3\"\n >\n {children}\n </div>\n </DrawerContent>\n ) : null}\n </Drawer>\n );\n}\n","/**\n * Player hand with adaptive overlap, automatic drawer fallback, and keyboard navigation.\n * For full control, use the `useHandLayout` hook directly.\n */\n\nimport { clsx } from \"clsx\";\nimport { useCallback, useState } from \"react\";\nimport {\n useHandLayout,\n type CardSize,\n type HandLayout,\n} from \"../hooks/useHandLayout.js\";\nimport { CardFace, type ViewCard } from \"./Card.js\";\nimport { HandDock } from \"./HandDock.js\";\nimport type { ReactNode } from \"react\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\n\nexport interface HandCardRenderProps<CardData extends ViewCard = ViewCard> {\n card: CardData;\n index: number;\n isHovered: boolean;\n isSelected: boolean;\n x: number;\n y: number;\n zIndex: number;\n cardDimensions: { width: number; height: number };\n}\n\nexport interface HandDrawerRenderProps<CardData extends ViewCard = ViewCard> {\n cards: readonly CardData[];\n selectedIds: readonly string[];\n cardCount: number;\n selectedCount: number;\n disabled: boolean;\n cardDimensions: { width: number; height: number };\n}\n\nexport interface HandEmptyRenderProps {\n layout: HandLayout;\n}\n\nexport interface HandContainerRenderProps {\n totalWidth: number;\n totalHeight: number;\n cardDimensions: { width: number; height: number };\n children: ReactNode;\n onMouseMove: (e: React.MouseEvent<HTMLDivElement>) => void;\n onMouseLeave: () => void;\n}\n\nexport interface HandProps<CardData extends ViewCard = ViewCard> {\n cards: readonly CardData[];\n selectedIds?: readonly string[];\n disabled?: boolean;\n cardSize?: CardSize;\n layout?: HandLayout;\n \"aria-label\"?: string;\n /**\n * Called when a card is clicked. Wired into the default `renderCard`;\n * ignored when the caller supplies a custom `renderCard`.\n */\n onCardClick?: (cardId: string) => void;\n /** Per-card content renderer forwarded to the default `<CardFace>`. */\n renderCardContent?: (card: CardData) => ReactNode;\n /** Defaults to a positioned `<CardFace>` honouring click/selection state. */\n renderCard?: (props: HandCardRenderProps<CardData>) => ReactNode;\n /**\n * Custom drawer fallback for large hands (when `useHandLayout` switches\n * to drawer mode). When omitted, `Hand` renders a `HandDock` bottom drawer\n * automatically.\n */\n renderDrawer?: (props: HandDrawerRenderProps<CardData>) => ReactNode;\n /** Defaults to a subtle \"No cards in hand\" placeholder. */\n renderEmpty?: (props: HandEmptyRenderProps) => ReactNode;\n renderContainer?: (props: HandContainerRenderProps) => ReactNode;\n className?: string;\n}\n\nconst EMPTY_SELECTED_IDS: readonly string[] = [];\n\n// DefaultDrawer is intentionally omitted — when no `renderDrawer` prop is\n// provided, `Hand` automatically renders a `HandDock` bottom drawer instead\n// (see the drawer-mode branch in the `Hand` component below).\n// This gives large hands a proper mobile-friendly expandable UI for free.\n\nfunction DefaultEmpty(): ReactNode {\n const theme = useTheme();\n return (\n <span\n style={{\n fontFamily: theme.typography.fontFamily.body,\n fontSize: theme.typography.fontSize.xs,\n color: theme.semantic.text.disabled,\n }}\n >\n No cards in hand\n </span>\n );\n}\n\ninterface ClickableCardFaceProps<CardData extends ViewCard = ViewCard> {\n card: CardData;\n selected?: boolean;\n disabled?: boolean;\n size?: CardSize;\n onCardClick?: (cardId: CardData[\"id\"]) => void;\n renderContent?: (card: CardData) => ReactNode;\n}\n\nfunction ClickableCardFace<CardData extends ViewCard = ViewCard>({\n card,\n selected,\n disabled,\n size,\n onCardClick,\n renderContent,\n}: ClickableCardFaceProps<CardData>) {\n const interactive = !disabled && Boolean(onCardClick);\n const handleActivate = () => {\n if (!interactive) return;\n onCardClick?.(card.id);\n };\n\n return (\n <button\n type=\"button\"\n disabled={disabled}\n aria-pressed={selected ? true : undefined}\n aria-disabled={disabled || undefined}\n tabIndex={disabled ? -1 : 0}\n onClick={handleActivate}\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n handleActivate();\n }\n }}\n className={clsx(\n \"border-0 bg-transparent p-0\",\n \"focus-visible:outline-none\",\n interactive ? \"cursor-pointer\" : \"cursor-default\",\n )}\n style={{ all: \"unset\" }}\n >\n <CardFace\n card={card}\n selected={selected}\n disabled={disabled}\n size={size}\n renderContent={renderContent}\n />\n </button>\n );\n}\n\n/**\n * Hand component with customizable rendering via render props.\n *\n * `renderCard`, `renderDrawer`, and `renderEmpty` are all optional — the\n * defaults render the built-in `<CardFace>` with the supplied `onCardClick` /\n * `renderCardContent`, a compact drawer fallback on small screens, and a\n * muted empty placeholder. Override any of them when you need a different\n * visual treatment.\n *\n * For complete control over layout and interactions, use the\n * `useHandLayout` hook directly.\n *\n * @example Zero-config\n * ```tsx\n * <Hand cards={cards} onCardClick={(id) => play(id)} />\n * ```\n *\n * @example Custom card content\n * ```tsx\n * <Hand\n * cards={cards}\n * onCardClick={(id) => play(id)}\n * renderCardContent={(card) => <DevCardFace card={card} />}\n * />\n * ```\n */\nexport function Hand<CardData extends ViewCard = ViewCard>({\n cards,\n selectedIds = EMPTY_SELECTED_IDS,\n disabled = false,\n cardSize = \"md\",\n layout = \"overlap\",\n \"aria-label\": ariaLabel = \"Your hand\",\n onCardClick,\n renderCardContent,\n renderCard,\n renderDrawer,\n renderEmpty,\n renderContainer,\n className,\n}: HandProps<CardData>) {\n const defaultRenderCard = useCallback(\n (props: HandCardRenderProps<CardData>): ReactNode => (\n <div\n key={props.card.id}\n className=\"absolute bottom-0 transition-all duration-150 ease-out\"\n style={{\n left: props.x,\n zIndex: props.zIndex,\n transform: `translateY(${props.y}px)`,\n }}\n >\n <ClickableCardFace\n card={props.card}\n selected={props.isSelected}\n disabled={disabled}\n size={cardSize}\n onCardClick={onCardClick}\n renderContent={renderCardContent}\n />\n </div>\n ),\n [cardSize, disabled, onCardClick, renderCardContent],\n );\n const effectiveRenderCard = renderCard ?? defaultRenderCard;\n const effectiveRenderEmpty = renderEmpty ?? DefaultEmpty;\n const cardCount = cards.length;\n const [focusedIndex, setFocusedIndex] = useState(-1);\n\n const {\n containerRef,\n cardsContainerRef,\n totalWidth,\n useDrawerMode,\n cardDimensions,\n constants,\n hoveredIndex,\n handleMouseMove,\n handleMouseLeave,\n handleTouchMove,\n handleTouchEnd,\n getCardPosition,\n } = useHandLayout({\n cardCount,\n cardSize,\n layout,\n });\n\n const selectedCount = cards.filter((c) => selectedIds.includes(c.id)).length;\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (cardCount === 0) return;\n switch (e.key) {\n case \"ArrowLeft\":\n e.preventDefault();\n setFocusedIndex((prev) => (prev <= 0 ? cardCount - 1 : prev - 1));\n break;\n case \"ArrowRight\":\n e.preventDefault();\n setFocusedIndex((prev) => (prev >= cardCount - 1 ? 0 : prev + 1));\n break;\n case \"Home\":\n e.preventDefault();\n setFocusedIndex(0);\n break;\n case \"End\":\n e.preventDefault();\n setFocusedIndex(cardCount - 1);\n break;\n }\n },\n [cardCount],\n );\n\n // Drawer mode — too many cards to show inline.\n // If the caller provides a custom `renderDrawer`, delegate entirely to it.\n // Otherwise render a `HandDock` bottom drawer so the hand is always\n // reachable on mobile without any extra author wiring.\n if (useDrawerMode && layout === \"overlap\" && cardCount > 0) {\n if (renderDrawer) {\n return (\n <div\n ref={containerRef}\n className={clsx(\n \"relative w-full flex items-center justify-center py-4\",\n className,\n )}\n role=\"group\"\n aria-label={`${ariaLabel} - ${cardCount} card${cardCount !== 1 ? \"s\" : \"\"}`}\n >\n {renderDrawer({\n cards,\n selectedIds,\n cardCount,\n selectedCount,\n disabled,\n cardDimensions,\n })}\n </div>\n );\n }\n\n // Default: HandDock bottom drawer with the cards in a wrap grid.\n // The outer div is kept for the containerRef measurement; HandDock itself\n // is fixed-position and renders outside normal flow.\n return (\n <div\n ref={containerRef}\n className={clsx(\n \"relative w-full flex items-center justify-center\",\n className,\n )}\n role=\"group\"\n aria-label={`${ariaLabel} - ${cardCount} card${cardCount !== 1 ? \"s\" : \"\"}`}\n >\n <HandDock\n label={ariaLabel}\n count={cardCount}\n presentation={{ mode: \"drawer\", placement: \"bottom-center\" }}\n >\n <div\n style={{\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: 8,\n padding: \"4px 0 8px\",\n justifyContent: \"center\",\n }}\n >\n {cards.map((card) => (\n <ClickableCardFace\n key={card.id}\n card={card}\n selected={selectedIds.includes(card.id)}\n disabled={disabled}\n size={cardSize}\n onCardClick={onCardClick}\n renderContent={renderCardContent}\n />\n ))}\n </div>\n </HandDock>\n </div>\n );\n }\n\n // Empty hand\n if (cardCount === 0) {\n return (\n <div\n ref={containerRef}\n className={clsx(\n \"relative w-full flex items-end justify-center py-4 sm:py-6\",\n className,\n )}\n role=\"group\"\n aria-label={`${ariaLabel} - empty`}\n >\n {effectiveRenderEmpty({ layout })}\n </div>\n );\n }\n\n const renderedCards = cards.map((card, index) => {\n const isSelected = selectedIds.includes(card.id);\n const isFocused = focusedIndex === index;\n const isHovered = hoveredIndex === index || isFocused;\n const position = getCardPosition(index, isHovered, isSelected);\n\n return effectiveRenderCard({\n card,\n index,\n isHovered,\n isSelected,\n x: position.x,\n y: position.y,\n zIndex: position.zIndex,\n cardDimensions,\n });\n });\n\n if (layout === \"spread\") {\n return (\n <div\n ref={containerRef}\n className={clsx(\n \"relative w-full flex items-end justify-center py-4 sm:py-6\",\n className,\n )}\n role=\"group\"\n aria-label={`${ariaLabel} - ${cardCount} card${cardCount !== 1 ? \"s\" : \"\"}`}\n tabIndex={0}\n onKeyDown={handleKeyDown}\n onBlur={() => setFocusedIndex(-1)}\n >\n <div className=\"flex gap-1 justify-center flex-wrap\">\n {renderedCards}\n </div>\n </div>\n );\n }\n\n // Overlap/Stack layout\n const totalHeight = cardDimensions.height + constants.hoverLift + 8;\n\n const containerProps: HandContainerRenderProps = {\n totalWidth,\n totalHeight,\n cardDimensions,\n children: renderedCards,\n onMouseMove: handleMouseMove,\n onMouseLeave: handleMouseLeave,\n };\n\n // Allow custom container rendering\n if (renderContainer) {\n return (\n <div\n ref={containerRef}\n className={clsx(\n \"relative w-full flex items-end justify-center py-4 sm:py-6 overflow-visible\",\n className,\n )}\n role=\"group\"\n aria-label={`${ariaLabel} - ${cardCount} card${cardCount !== 1 ? \"s\" : \"\"}`}\n >\n {renderContainer(containerProps)}\n </div>\n );\n }\n\n return (\n <div\n ref={containerRef}\n className={clsx(\n \"relative w-full flex items-end justify-center py-4 sm:py-6 overflow-visible\",\n className,\n )}\n role=\"group\"\n aria-label={`${ariaLabel} - ${cardCount} card${cardCount !== 1 ? \"s\" : \"\"}`}\n tabIndex={0}\n onKeyDown={handleKeyDown}\n onBlur={() => setFocusedIndex(-1)}\n >\n <div\n ref={cardsContainerRef}\n className=\"relative\"\n style={{\n width: layout === \"overlap\" ? totalWidth : undefined,\n height: totalHeight,\n }}\n onMouseMove={handleMouseMove}\n onMouseLeave={handleMouseLeave}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n >\n {renderedCards}\n </div>\n </div>\n );\n}\n\n// Re-export types and hook for users who want full control\nexport { useHandLayout } from \"../hooks/useHandLayout.js\";\nexport type {\n UseHandLayoutOptions,\n UseHandLayoutReturn,\n CardPositionProps,\n CardSize,\n HandLayout,\n} from \"../hooks/useHandLayout.js\";\nexport type { ViewCard } from \"./Card.js\";\n","import { useState, useRef, useEffect, useMemo, useCallback } from \"react\";\nimport type { RefObject } from \"react\";\n\n// Card dimensions used for fan offset and total-width calculations.\n// These must match the rendered widths from `Card.tsx`'s `sizeClasses`\n// at the `sm` Tailwind breakpoint (≥640px), since that's the size\n// player decks render at on virtually all gameplay viewports. Older\n// values here were ~30% smaller than what `Card` actually paints,\n// which caused cards to overlap by 30+ pixels even when there was\n// plenty of horizontal room in the hand container.\nconst CARD_DIMENSIONS = {\n sm: { width: 80, height: 112 },\n md: { width: 96, height: 144 },\n lg: { width: 128, height: 192 },\n} as const;\n\nconst MIN_VISIBLE_PORTION = 16; // minimum visible pixels per card when overlapping\nconst HOVER_LIFT = 20; // pixels to lift on hover\nconst SELECTED_LIFT = 8; // pixels to lift when selected\nconst DRAWER_THRESHOLD_RATIO = 0.3; // if overlap is less than 30% of card width, use drawer\n\nexport type CardSize = \"sm\" | \"md\" | \"lg\";\nexport type HandLayout = \"spread\" | \"stack\" | \"overlap\";\n\nexport interface CardPositionProps {\n /** X position (left offset) */\n x: number;\n /** Y position (vertical offset for hover/selected) */\n y: number;\n /** Z-index for layering */\n zIndex: number;\n /** CSS transform origin */\n transformOrigin: string;\n}\n\nexport interface UseHandLayoutOptions {\n /** Number of cards in the hand */\n cardCount: number;\n /** Card size variant */\n cardSize?: CardSize;\n /** Layout style */\n layout?: HandLayout;\n /** Padding to subtract from container width */\n containerPadding?: number;\n}\n\nexport interface UseHandLayoutReturn {\n /** Ref to attach to the container element */\n containerRef: RefObject<HTMLDivElement | null>;\n /** Ref to attach to the cards container element (for mouse/touch tracking) */\n cardsContainerRef: RefObject<HTMLDivElement | null>;\n /** Measured container width */\n containerWidth: number;\n /** Calculated offset between cards */\n cardOffset: number;\n /** Total width of all cards */\n totalWidth: number;\n /** Whether drawer mode should be used */\n useDrawerMode: boolean;\n /** Card dimensions for the current size */\n cardDimensions: { width: number; height: number };\n /** Constants for positioning */\n constants: {\n hoverLift: number;\n selectedLift: number;\n };\n /** Currently hovered card index */\n hoveredIndex: number | null;\n /** Mouse move handler for the cards container */\n handleMouseMove: (e: React.MouseEvent<HTMLDivElement>) => void;\n /** Mouse leave handler for the cards container */\n handleMouseLeave: () => void;\n /** Touch move handler for the cards container (mirrors mouse hover lift on touch) */\n handleTouchMove: (e: React.TouchEvent<HTMLDivElement>) => void;\n /** Touch end handler for the cards container */\n handleTouchEnd: () => void;\n /** Get position props for a card at the given index */\n getCardPosition: (\n index: number,\n isHovered: boolean,\n isSelected: boolean,\n ) => CardPositionProps;\n}\n\n/**\n * Hook for managing hand layout calculations and interactions.\n *\n * Provides container measurement, overlap calculations, drawer mode detection,\n * and hover state management for card hand displays.\n *\n * @example\n * ```tsx\n * function MyHand({ cards, selectedIds }) {\n * const {\n * containerRef,\n * cardsContainerRef,\n * totalWidth,\n * useDrawerMode,\n * cardDimensions,\n * hoveredIndex,\n * handleMouseMove,\n * handleMouseLeave,\n * getCardPosition,\n * constants,\n * } = useHandLayout({\n * cardCount: cards.length,\n * cardSize: \"md\",\n * layout: \"overlap\",\n * });\n *\n * if (useDrawerMode) {\n * return <MyDrawerUI cards={cards} />;\n * }\n *\n * return (\n * <div ref={containerRef}>\n * <div\n * ref={cardsContainerRef}\n * style={{ width: totalWidth, height: cardDimensions.height + constants.hoverLift }}\n * onMouseMove={handleMouseMove}\n * onMouseLeave={handleMouseLeave}\n * >\n * {cards.map((card, index) => {\n * const isHovered = hoveredIndex === index;\n * const isSelected = selectedIds.includes(card.id);\n * const position = getCardPosition(index, isHovered, isSelected);\n *\n * return (\n * <div\n * key={card.id}\n * style={{\n * position: \"absolute\",\n * left: position.x,\n * transform: `translateY(${position.y}px)`,\n * zIndex: position.zIndex,\n * }}\n * >\n * <MyCard card={card} />\n * </div>\n * );\n * })}\n * </div>\n * </div>\n * );\n * }\n * ```\n */\nexport function useHandLayout({\n cardCount,\n cardSize = \"md\",\n layout = \"overlap\",\n containerPadding = 32,\n}: UseHandLayoutOptions): UseHandLayoutReturn {\n const containerRef = useRef<HTMLDivElement>(null);\n const cardsContainerRef = useRef<HTMLDivElement>(null);\n const [containerWidth, setContainerWidth] = useState(0);\n const [hoveredIndex, setHoveredIndex] = useState<number | null>(null);\n\n const cardDimensions = CARD_DIMENSIONS[cardSize];\n\n // Measure container width with ResizeObserver\n useEffect(() => {\n const updateWidth = () => {\n if (containerRef.current) {\n setContainerWidth(containerRef.current.clientWidth - containerPadding);\n }\n };\n\n updateWidth();\n const observer = new ResizeObserver(updateWidth);\n if (containerRef.current) {\n observer.observe(containerRef.current);\n }\n\n return () => observer.disconnect();\n }, [containerPadding]);\n\n // Calculate adaptive overlap based on container width and card count\n const { cardOffset, totalWidth, useDrawerMode } = useMemo(() => {\n if (layout !== \"overlap\") {\n return {\n cardOffset: cardDimensions.width,\n totalWidth: 0,\n useDrawerMode: false,\n };\n }\n\n if (cardCount === 0) {\n return { cardOffset: 0, totalWidth: 0, useDrawerMode: false };\n }\n if (cardCount === 1) {\n return {\n cardOffset: cardDimensions.width,\n totalWidth: cardDimensions.width,\n useDrawerMode: false,\n };\n }\n\n // Available width for overlap distribution\n const availableWidth = containerWidth;\n if (availableWidth <= 0) {\n return {\n cardOffset: cardDimensions.width,\n totalWidth: cardDimensions.width * cardCount,\n useDrawerMode: false,\n };\n }\n\n // Calculate the offset needed to fit all cards\n // Total width = cardWidth + (cardCount - 1) * offset\n // So offset = (availableWidth - cardWidth) / (cardCount - 1)\n const idealOffset =\n (availableWidth - cardDimensions.width) / (cardCount - 1);\n\n // Clamp offset between minimum visible portion and full card width\n const clampedOffset = Math.max(\n MIN_VISIBLE_PORTION,\n Math.min(cardDimensions.width, idealOffset),\n );\n\n // Calculate total width with this offset\n const width = cardDimensions.width + (cardCount - 1) * clampedOffset;\n\n // Determine if we should use drawer mode\n // Use drawer if cards are overlapping too much (less than threshold of card visible)\n const visiblePortion = clampedOffset / cardDimensions.width;\n const shouldUseDrawer =\n visiblePortion < DRAWER_THRESHOLD_RATIO && cardCount > 2;\n\n return {\n cardOffset: clampedOffset,\n totalWidth: width,\n useDrawerMode: shouldUseDrawer,\n };\n }, [cardCount, containerWidth, layout, cardDimensions.width]);\n\n // Shared logic: map a clientX coordinate to the card index it's over.\n // Used by both mouse and touch move handlers.\n const getHoveredIndexFromClientX = useCallback(\n (clientX: number): number | null => {\n if (!cardsContainerRef.current) return null;\n const rect = cardsContainerRef.current.getBoundingClientRect();\n const mouseX = clientX - rect.left;\n\n let newHoveredIndex: number | null = null;\n\n // Find which card the pointer is over based on X position.\n // Iterate right-to-left so cards on top (higher z-index) win.\n for (let i = cardCount - 1; i >= 0; i--) {\n const cardLeft = i * cardOffset;\n const cardRight =\n i === cardCount - 1\n ? cardLeft + cardDimensions.width\n : (i + 1) * cardOffset;\n\n if (mouseX >= cardLeft && mouseX < cardRight) {\n newHoveredIndex = i;\n break;\n }\n }\n\n // Check if pointer is in the rightmost card's full area\n if (newHoveredIndex === null && mouseX >= 0 && mouseX < totalWidth) {\n const lastCardLeft = (cardCount - 1) * cardOffset;\n if (mouseX >= lastCardLeft) {\n newHoveredIndex = cardCount - 1;\n }\n }\n\n return newHoveredIndex;\n },\n [cardCount, cardOffset, totalWidth, cardDimensions.width],\n );\n\n // Calculate hovered card index based on mouse X position.\n // This allows hovering on adjacent cards even when one is popped up.\n const handleMouseMove = useCallback(\n (e: React.MouseEvent<HTMLDivElement>) => {\n if (cardCount === 0 || layout === \"spread\" || layout === \"stack\") {\n return;\n }\n setHoveredIndex(getHoveredIndexFromClientX(e.clientX));\n },\n [cardCount, layout, getHoveredIndexFromClientX],\n );\n\n const handleMouseLeave = useCallback(() => {\n setHoveredIndex(null);\n }, []);\n\n // Touch equivalents — mirror the hover-lift feedback on touch devices so\n // the active card is clearly highlighted while the finger is moving.\n const handleTouchMove = useCallback(\n (e: React.TouchEvent<HTMLDivElement>) => {\n if (cardCount === 0 || layout === \"spread\" || layout === \"stack\") {\n return;\n }\n const touch = e.touches[0];\n if (!touch) return;\n setHoveredIndex(getHoveredIndexFromClientX(touch.clientX));\n },\n [cardCount, layout, getHoveredIndexFromClientX],\n );\n\n const handleTouchEnd = useCallback(() => {\n setHoveredIndex(null);\n }, []);\n\n // Calculate z-index: hovered > selected > position\n const getZIndex = useCallback(\n (index: number, isHovered: boolean, isSelected: boolean) => {\n if (isHovered) return 200;\n if (isSelected) return 100 + index;\n return index;\n },\n [],\n );\n\n // Get card position props for different layouts\n const getCardPosition = useCallback(\n (\n index: number,\n isHovered: boolean,\n isSelected: boolean,\n ): CardPositionProps => {\n const zIndex = getZIndex(index, isHovered, isSelected);\n\n if (layout === \"stack\") {\n return {\n x: index * 4,\n y: 0,\n zIndex,\n transformOrigin: \"bottom center\",\n };\n }\n\n if (layout === \"spread\") {\n return {\n x: 0,\n y: 0,\n zIndex,\n transformOrigin: \"bottom center\",\n };\n }\n\n // Overlap layout (default) - simple horizontal overlap with lift on hover/select\n const yOffset = isHovered ? -HOVER_LIFT : isSelected ? -SELECTED_LIFT : 0;\n\n return {\n x: index * cardOffset,\n y: yOffset,\n zIndex,\n transformOrigin: \"bottom center\",\n };\n },\n [layout, cardOffset, getZIndex],\n );\n\n return {\n containerRef,\n cardsContainerRef,\n containerWidth,\n cardOffset,\n totalWidth,\n useDrawerMode,\n cardDimensions,\n constants: {\n hoverLift: HOVER_LIFT,\n selectedLift: SELECTED_LIFT,\n },\n hoveredIndex,\n handleMouseMove,\n handleMouseLeave,\n handleTouchMove,\n handleTouchEnd,\n getCardPosition,\n };\n}\n","/**\n * Controlled staging zone — a fixed row of card slots for a many-select\n * collection (e.g. \"the cards you are passing\"). Filled slots render a\n * caller-provided card and are tappable to remove it; the remaining slots\n * render a themed empty placeholder so the zone is always visible (and always\n * an obvious target) even before anything is staged.\n *\n * Purely presentational: it does not read or mutate any Dreamboard draft. A\n * runtime adapter feeds it the staged cards plus an `onRemove` that toggles the\n * card back out of the collection. In a later slice this same surface becomes\n * the drop target for drag-to-stage.\n */\n\nimport { clsx } from \"clsx\";\nimport type { ReactNode } from \"react\";\nimport type { ViewCard } from \"../../types/index.js\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\n\nexport interface StagingZoneProps<CardData extends ViewCard = ViewCard> {\n /** Cards currently staged, in order. */\n cards: readonly CardData[];\n /** Total number of slots to render (e.g. the collector's selection max). */\n slotCount: number;\n /** Card size; empty-slot dimensions match the SDK `CardFace` sizes. */\n size?: \"sm\" | \"md\" | \"lg\";\n /** Visual for a staged card (typically a `CardFace`). */\n renderCard: (card: CardData) => ReactNode;\n /** Fires when a staged card is activated — remove it from the collection. */\n onRemove?: (cardId: string) => void;\n /** Custom empty-slot content. Defaults to an empty dashed placeholder. */\n renderEmptySlot?: (index: number) => ReactNode;\n /** Optional heading rendered above the slots. */\n label?: ReactNode;\n /** Accessible label for the region. */\n \"aria-label\"?: string;\n className?: string;\n}\n\n// Match `CardFace`'s `sizeClasses` so empty slots line up with staged cards.\nconst SLOT_SIZE_CLASS: Record<\"sm\" | \"md\" | \"lg\", string> = {\n sm: \"w-16 h-24 sm:w-20 sm:h-28\",\n md: \"w-20 h-32 sm:w-24 sm:h-36\",\n lg: \"w-24 h-36 sm:w-32 sm:h-48\",\n};\n\nexport function StagingZone<CardData extends ViewCard = ViewCard>({\n cards,\n slotCount,\n size = \"sm\",\n renderCard,\n onRemove,\n renderEmptySlot,\n label,\n \"aria-label\": ariaLabel = \"Staged cards\",\n className,\n}: StagingZoneProps<CardData>) {\n const theme = useTheme();\n const total = Math.max(0, slotCount, cards.length);\n const slotClass = SLOT_SIZE_CLASS[size];\n const interactive = Boolean(onRemove);\n\n return (\n <div\n data-dreamboard-staging-zone=\"\"\n data-staged-count={cards.length}\n role=\"group\"\n aria-label={ariaLabel}\n className={clsx(\n \"flex flex-col items-center gap-2 rounded-2xl px-4 py-3\",\n className,\n )}\n style={{\n background: theme.semantic.surface.inset,\n border: `2px solid ${theme.semantic.border.subtle}`,\n }}\n >\n {label != null ? (\n <span\n className=\"text-[11px] font-bold uppercase tracking-[0.12em]\"\n style={{ color: theme.semantic.text.muted }}\n >\n {label}\n </span>\n ) : null}\n <div className=\"flex items-end justify-center gap-2\">\n {Array.from({ length: total }, (_, index) => {\n const card = cards[index];\n if (!card) {\n return (\n <div\n key={`empty-${index}`}\n data-dreamboard-staging-slot=\"empty\"\n aria-hidden\n className={clsx(\n \"flex shrink-0 items-center justify-center rounded-xl\",\n slotClass,\n )}\n style={{\n border: `2px dashed ${theme.semantic.border.subtle}`,\n color: theme.semantic.text.disabled,\n }}\n >\n {renderEmptySlot ? renderEmptySlot(index) : null}\n </div>\n );\n }\n const cardId = card.id as string;\n return (\n <button\n key={cardId}\n type=\"button\"\n data-dreamboard-staging-slot=\"filled\"\n data-card-id={cardId}\n disabled={!interactive}\n aria-label={\n interactive ? `Remove ${card.name ?? cardId}` : undefined\n }\n onClick={interactive ? () => onRemove?.(cardId) : undefined}\n className={clsx(\n \"relative shrink-0 appearance-none border-0 bg-transparent p-0 m-0\",\n \"transition-transform focus-visible:outline-none\",\n interactive\n ? \"cursor-pointer hover:-translate-y-1\"\n : \"cursor-default\",\n )}\n >\n {renderCard(card)}\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n","/**\n * Controlled drag-to-target surface for the SDK hand and drop-target views.\n *\n * `CardDragSurface` is the single owner of:\n *\n * - the drag-lifecycle phase (`idle`/`inspecting`/`dragging`/`settling`/\n * `returning`)\n * - the registry of drop targets, including their eligibility\n * - all committed `CardIntent` emission (`activate`, `previewStart`,\n * `previewEnd`, and `drop`)\n * - the lifted-card overlay, settle/snap-back animation and live\n * announcement\n *\n * `CardDropTargetView` is a generic controlled drop-target wrapper. It\n * registers the underlying DOM element (and its eligible/disabled state) so\n * the lifted pointer can be matched without exposing geometry to the\n * caller. Its registration is stable: only the `targetId` triggers register/\n * unregister; eligibility and label changes flow through `updateTarget`.\n *\n * `HandView` (and the hook it uses) drives this surface through the\n * controller exposed by `useCardDragSurface()`. Pointer events come from\n * `HandPointerEngine`'s lift callbacks. Keyboard pickup, target traversal\n * and Escape are handled here so that the drag-lifecycle has exactly one\n * authoritative owner.\n */\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type KeyboardEvent,\n type ReactNode,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { clsx } from \"clsx\";\nimport { AnimatePresence, motion, type Transition } from \"framer-motion\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\nimport {\n dropTargetVisualStateDataAttributes,\n type CardDropTargetVisualState,\n type CardIntent,\n} from \"../types/visual-state.js\";\n\ninterface RegisteredDropTarget {\n targetId: string;\n disabled: boolean;\n eligible: boolean;\n element: HTMLElement;\n /** Plain-text label used for the live a11y announcement. */\n label: string | null;\n /** Order hint for keyboard target traversal (lower numbers focus first). */\n order: number;\n}\n\nexport type DragPhase =\n | \"idle\"\n | \"inspecting\"\n | \"dragging\"\n | \"settling\"\n | \"returning\";\n\ninterface ActiveDragState {\n cardId: string;\n cardLabel: string | null;\n source: \"pointer\" | \"keyboard\";\n pointerId: number | null;\n pointerX: number;\n pointerY: number;\n grabOffsetX: number;\n grabOffsetY: number;\n /**\n * Source rectangle captured at lift time, used as the snap-back/origin\n * geometry for animated returns.\n */\n sourceRect: { left: number; top: number; width: number; height: number };\n content: ReactNode;\n overTargetId: string | null;\n keyboardFocusedTargetId: string | null;\n /** DOM node we should focus when the lifecycle ends. */\n sourceFocus: HTMLElement | null;\n}\n\ninterface SettlingState {\n cardId: string;\n source: \"pointer\" | \"keyboard\";\n pointerX: number;\n pointerY: number;\n grabOffsetX: number;\n grabOffsetY: number;\n sourceRect: { left: number; top: number; width: number; height: number };\n targetRect: { left: number; top: number; width: number; height: number };\n content: ReactNode;\n}\n\ninterface ReturningState {\n cardId: string;\n source: \"pointer\" | \"keyboard\";\n pointerX: number;\n pointerY: number;\n grabOffsetX: number;\n grabOffsetY: number;\n sourceRect: { left: number; top: number; width: number; height: number };\n content: ReactNode;\n}\n\nexport interface CardDragSurfaceController {\n /** Identity of the card currently in the drag-lifecycle, if any. */\n activeCardId: string | null;\n /** Source of the active drag, if any. */\n activeSource: \"pointer\" | \"keyboard\" | null;\n /** Drag-lifecycle phase. */\n phase: DragPhase;\n /** Currently highlighted drop target id, if any. */\n overTargetId: string | null;\n /** Currently keyboard-focused target id, if any. */\n keyboardFocusedTargetId: string | null;\n /**\n * Begin a pointer drag session. Returns `true` if the session started.\n */\n startPointerDrag: (input: PointerDragInput) => boolean;\n /** Update the pointer coordinates of an active pointer drag. */\n updatePointer: (point: { x: number; y: number }) => void;\n /**\n * Commit the active pointer drag at the supplied release position. Emits\n * a `drop` intent if the pointer is over an eligible target, or schedules\n * a snap back otherwise.\n */\n releasePointer: (point: { x: number; y: number }) => void;\n /** Cancel the active drag (pointer or keyboard) without committing. */\n cancelDrag: () => void;\n /**\n * Begin a keyboard drag session. The first eligible registered target is\n * focused automatically.\n */\n startKeyboardDrag: (input: KeyboardDragInput) => boolean;\n /** Move keyboard focus across registered eligible targets. */\n moveKeyboardFocus: (direction: \"next\" | \"prev\") => void;\n /** Commit the active keyboard drag on the focused target. */\n commitKeyboardDrop: () => void;\n /**\n * Record a tap that did not produce a lift. The surface holds the\n * `inspecting` phase until another lift, drop, or external dismissal.\n */\n recordTap: (input: TapInput) => void;\n /**\n * Record a `previewStart` intent. Surface owns canonical intent emission\n * so consumers subscribe in one place.\n */\n recordPreviewStart: (cardId: string) => void;\n /** Record a `previewEnd` intent. */\n recordPreviewEnd: (cardId: string) => void;\n /**\n * Record a desktop/keyboard `activate` intent under the `direct-activate`\n * policy. Drag-to-target policy never calls this; it is centralized here\n * so that the surface remains the only ingress for `CardIntent`.\n */\n recordActivate: (cardId: string, source: \"tap\" | \"keyboard\") => void;\n /** Clear the `inspecting` phase. */\n clearInspect: () => void;\n /** Total number of currently registered eligible targets. */\n eligibleTargetCount: number;\n}\n\ninterface TapInput {\n cardId: string;\n cardEligible: boolean;\n cardDisabled: boolean;\n sourceFocus?: HTMLElement | null;\n}\n\ninterface PointerDragInput {\n cardId: string;\n cardLabel?: string | null;\n pointerId: number;\n startX: number;\n startY: number;\n pointerX: number;\n pointerY: number;\n grabOffsetX: number;\n grabOffsetY: number;\n sourceRect: { left: number; top: number; width: number; height: number };\n content: ReactNode;\n sourceFocus?: HTMLElement | null;\n}\n\ninterface KeyboardDragInput {\n cardId: string;\n cardLabel?: string | null;\n cardEligible: boolean;\n sourceRect: { left: number; top: number; width: number; height: number };\n content: ReactNode;\n sourceFocus?: HTMLElement | null;\n}\n\nexport interface CardDragSurfaceContextValue {\n registerTarget: (target: RegisteredDropTarget) => () => void;\n updateTarget: (\n targetId: string,\n patch: Partial<Omit<RegisteredDropTarget, \"targetId\" | \"element\">>,\n ) => void;\n controller: CardDragSurfaceController;\n /** Expose the most recent active card id for visual-state computation. */\n activeCardId: string | null;\n /** Expose the highlighted target id for visual-state computation. */\n overTargetId: string | null;\n /** Expose whether any drag is in progress. */\n dragActive: boolean;\n keyboardFocusedTargetId: string | null;\n}\n\nconst CardDragSurfaceContext =\n createContext<CardDragSurfaceContextValue | null>(null);\n\nexport function useCardDragSurface(): CardDragSurfaceContextValue | null {\n return useContext(CardDragSurfaceContext);\n}\n\nexport interface CardDragSurfaceProps {\n onCardIntent?: (intent: CardIntent) => void;\n /**\n * Approximate inset (px) used for the deterministic hit test. Defaults to\n * `8`. Lowering this lets edges register more aggressively; raising it\n * makes overlapping targets less ambiguous.\n */\n hitTestInsetPx?: number;\n /** Suppress the live a11y announcement (for environments providing their own). */\n suppressLiveAnnouncement?: boolean;\n /** Animation transition tunable for settle/return. */\n motionTransition?: Transition;\n className?: string;\n style?: CSSProperties;\n children: ReactNode;\n}\n\nconst SETTLE_TRANSITION: Transition = {\n type: \"spring\",\n stiffness: 380,\n damping: 32,\n mass: 0.9,\n};\nconst RETURN_TRANSITION: Transition = {\n type: \"spring\",\n stiffness: 320,\n damping: 26,\n mass: 0.8,\n};\nconst REDUCED_TRANSITION: Transition = { duration: 0 };\n\nexport function CardDragSurface({\n onCardIntent,\n hitTestInsetPx = 8,\n suppressLiveAnnouncement = false,\n motionTransition,\n className,\n style,\n children,\n}: CardDragSurfaceProps) {\n const theme = useTheme();\n const reducedMotion = theme.motion.reducedMotion === \"true\";\n const liveRegionId = useId();\n const targetsRef = useRef(new Map<string, RegisteredDropTarget>());\n const orderCounterRef = useRef(0);\n const activeDragRef = useRef<ActiveDragState | null>(null);\n const inspectingRef = useRef<string | null>(null);\n const [activeDrag, setActiveDrag] = useState<ActiveDragState | null>(null);\n const [inspectingCardId, setInspectingCardId] = useState<string | null>(null);\n const [settlingState, setSettlingState] = useState<SettlingState | null>(\n null,\n );\n const [returningState, setReturningState] = useState<ReturningState | null>(\n null,\n );\n const onIntentRef = useRef(onCardIntent);\n onIntentRef.current = onCardIntent;\n\n const settleTransition = motionTransition ?? SETTLE_TRANSITION;\n const returnTransition = motionTransition ?? RETURN_TRANSITION;\n\n const setActive = useCallback((next: ActiveDragState | null) => {\n activeDragRef.current = next;\n setActiveDrag(next);\n }, []);\n\n const setInspecting = useCallback((next: string | null) => {\n inspectingRef.current = next;\n setInspectingCardId(next);\n }, []);\n\n const finalizeInteraction = useCallback((sourceFocus: HTMLElement | null) => {\n if (sourceFocus) {\n // Defer focus restoration so animation can complete first frame.\n queueMicrotask(() => {\n try {\n sourceFocus.focus({ preventScroll: true });\n } catch {\n // Source may have been unmounted; ignore.\n }\n });\n }\n }, []);\n\n const registerTarget = useCallback(\n (target: RegisteredDropTarget) => {\n targetsRef.current.set(target.targetId, {\n ...target,\n order: target.order || ++orderCounterRef.current,\n });\n return () => {\n targetsRef.current.delete(target.targetId);\n const active = activeDragRef.current;\n if (active && active.keyboardFocusedTargetId === target.targetId) {\n setActive({ ...active, keyboardFocusedTargetId: null });\n }\n };\n },\n [setActive],\n );\n\n const updateTarget = useCallback(\n (\n targetId: string,\n patch: Partial<Omit<RegisteredDropTarget, \"targetId\" | \"element\">>,\n ) => {\n const existing = targetsRef.current.get(targetId);\n if (!existing) return;\n targetsRef.current.set(targetId, { ...existing, ...patch });\n },\n [],\n );\n\n const isTargetUsable = useCallback((target: RegisteredDropTarget) => {\n return !target.disabled && target.eligible !== false;\n }, []);\n\n const resolveDropTarget = useCallback(\n (point: { x: number; y: number }): string | null => {\n for (const target of targetsRef.current.values()) {\n if (!isTargetUsable(target)) continue;\n const rect = target.element.getBoundingClientRect();\n if (\n point.x >= rect.left + hitTestInsetPx &&\n point.x <= rect.right - hitTestInsetPx &&\n point.y >= rect.top + hitTestInsetPx &&\n point.y <= rect.bottom - hitTestInsetPx\n ) {\n return target.targetId;\n }\n }\n return null;\n },\n [hitTestInsetPx, isTargetUsable],\n );\n\n const sortedUsableTargetIds = useCallback((): string[] => {\n const entries = Array.from(targetsRef.current.values()).filter((t) =>\n isTargetUsable(t),\n );\n entries.sort((a, b) => a.order - b.order);\n return entries.map((t) => t.targetId);\n }, [isTargetUsable]);\n\n const recordTap = useCallback(\n (input: TapInput) => {\n if (input.cardDisabled || !input.cardEligible) return;\n // Tap is non-committing in drag-to-target mode regardless of whether\n // any usable target is currently registered. A missing target is a\n // composition/availability problem, not a reason to silently fall\n // back to tap-to-play. Hold the card in `inspecting` so the user can\n // see what they tapped while the runtime decides what to do next.\n setInspecting(input.cardId);\n },\n [setInspecting],\n );\n\n const recordPreviewStart = useCallback((cardId: string) => {\n onIntentRef.current?.({ type: \"previewStart\", cardId });\n }, []);\n\n const recordPreviewEnd = useCallback((cardId: string) => {\n onIntentRef.current?.({ type: \"previewEnd\", cardId });\n }, []);\n\n const recordActivate = useCallback(\n (cardId: string, source: \"tap\" | \"keyboard\") => {\n onIntentRef.current?.({ type: \"activate\", cardId, source });\n },\n [],\n );\n\n const clearInspect = useCallback(() => {\n if (inspectingRef.current !== null) setInspecting(null);\n }, [setInspecting]);\n\n const startPointerDrag = useCallback(\n (input: PointerDragInput): boolean => {\n if (activeDragRef.current) return false;\n if (inspectingRef.current) setInspecting(null);\n const overTargetId = resolveDropTarget({\n x: input.pointerX,\n y: input.pointerY,\n });\n const next: ActiveDragState = {\n cardId: input.cardId,\n cardLabel: input.cardLabel ?? null,\n source: \"pointer\",\n pointerId: input.pointerId,\n pointerX: input.pointerX,\n pointerY: input.pointerY,\n grabOffsetX: input.grabOffsetX,\n grabOffsetY: input.grabOffsetY,\n sourceRect: input.sourceRect,\n content: input.content,\n overTargetId,\n keyboardFocusedTargetId: null,\n sourceFocus: input.sourceFocus ?? null,\n };\n setActive(next);\n return true;\n },\n [resolveDropTarget, setActive, setInspecting],\n );\n\n const updatePointer = useCallback(\n (point: { x: number; y: number }) => {\n const active = activeDragRef.current;\n if (!active || active.source !== \"pointer\") return;\n const overTargetId = resolveDropTarget(point);\n setActive({\n ...active,\n pointerX: point.x,\n pointerY: point.y,\n overTargetId,\n });\n },\n [resolveDropTarget, setActive],\n );\n\n const completeWithDrop = useCallback(\n (\n active: ActiveDragState,\n targetId: string,\n releaseX: number,\n releaseY: number,\n ) => {\n const target = targetsRef.current.get(targetId);\n const targetRect = target?.element.getBoundingClientRect();\n const settling: SettlingState = {\n cardId: active.cardId,\n source: active.source,\n pointerX: releaseX,\n pointerY: releaseY,\n grabOffsetX: active.grabOffsetX,\n grabOffsetY: active.grabOffsetY,\n sourceRect: active.sourceRect,\n targetRect: targetRect\n ? {\n left: targetRect.left,\n top: targetRect.top,\n width: targetRect.width,\n height: targetRect.height,\n }\n : active.sourceRect,\n content: active.content,\n };\n onIntentRef.current?.({\n type: \"drop\",\n cardId: active.cardId,\n targetId,\n source: active.source === \"keyboard\" ? \"keyboard\" : \"pointer\",\n });\n setSettlingState(settling);\n setReturningState(null);\n setActive(null);\n finalizeInteraction(active.sourceFocus);\n },\n [finalizeInteraction, setActive],\n );\n\n const completeWithReturn = useCallback(\n (active: ActiveDragState, releaseX: number, releaseY: number) => {\n const returning: ReturningState = {\n cardId: active.cardId,\n source: active.source,\n pointerX: releaseX,\n pointerY: releaseY,\n grabOffsetX: active.grabOffsetX,\n grabOffsetY: active.grabOffsetY,\n sourceRect: active.sourceRect,\n content: active.content,\n };\n setReturningState(returning);\n setSettlingState(null);\n setActive(null);\n finalizeInteraction(active.sourceFocus);\n },\n [finalizeInteraction, setActive],\n );\n\n const releasePointer = useCallback(\n (point: { x: number; y: number }) => {\n const active = activeDragRef.current;\n if (!active || active.source !== \"pointer\") return;\n const overTargetId = resolveDropTarget(point);\n if (overTargetId) {\n completeWithDrop(active, overTargetId, point.x, point.y);\n return;\n }\n completeWithReturn(active, point.x, point.y);\n },\n [completeWithDrop, completeWithReturn, resolveDropTarget],\n );\n\n const cancelDrag = useCallback(() => {\n const active = activeDragRef.current;\n if (!active) return;\n completeWithReturn(active, active.pointerX, active.pointerY);\n }, [completeWithReturn]);\n\n const startKeyboardDrag = useCallback(\n (input: KeyboardDragInput): boolean => {\n if (activeDragRef.current) return false;\n if (!input.cardEligible) return false;\n if (inspectingRef.current) setInspecting(null);\n const ids = sortedUsableTargetIds();\n if (ids.length === 0) return false;\n const firstFocus = ids[0]!;\n const firstTarget = targetsRef.current.get(firstFocus);\n const firstRect = firstTarget?.element.getBoundingClientRect();\n const next: ActiveDragState = {\n cardId: input.cardId,\n cardLabel: input.cardLabel ?? null,\n source: \"keyboard\",\n pointerId: null,\n pointerX: firstRect ? firstRect.left + firstRect.width / 2 : 0,\n pointerY: firstRect ? firstRect.top + firstRect.height / 2 : 0,\n grabOffsetX: 0,\n grabOffsetY: 0,\n sourceRect: input.sourceRect,\n content: input.content,\n overTargetId: firstFocus,\n keyboardFocusedTargetId: firstFocus,\n sourceFocus: input.sourceFocus ?? null,\n };\n setActive(next);\n // Focus is moved by `CardDropTargetView` in an effect that watches\n // `keyboardFocusedTargetId`, ensuring focus transfer happens after\n // React commits the render that promotes this target.\n return true;\n },\n [setActive, setInspecting, sortedUsableTargetIds],\n );\n\n const moveKeyboardFocus = useCallback(\n (direction: \"next\" | \"prev\") => {\n const active = activeDragRef.current;\n if (!active || active.source !== \"keyboard\") return;\n const ids = sortedUsableTargetIds();\n if (ids.length === 0) return;\n const currentIdx = active.keyboardFocusedTargetId\n ? ids.indexOf(active.keyboardFocusedTargetId)\n : -1;\n const nextIdx =\n direction === \"next\"\n ? (currentIdx + 1) % ids.length\n : (currentIdx - 1 + ids.length) % ids.length;\n const nextId = ids[nextIdx]!;\n const target = targetsRef.current.get(nextId);\n const rect = target?.element.getBoundingClientRect();\n setActive({\n ...active,\n keyboardFocusedTargetId: nextId,\n overTargetId: nextId,\n pointerX: rect ? rect.left + rect.width / 2 : active.pointerX,\n pointerY: rect ? rect.top + rect.height / 2 : active.pointerY,\n });\n // Focus moved by the target's keyboardFocused effect.\n },\n [setActive, sortedUsableTargetIds],\n );\n\n const commitKeyboardDrop = useCallback(() => {\n const active = activeDragRef.current;\n if (!active || active.source !== \"keyboard\") return;\n const targetId = active.keyboardFocusedTargetId;\n if (!targetId) return;\n const target = targetsRef.current.get(targetId);\n if (!target || !isTargetUsable(target)) return;\n const rect = target.element.getBoundingClientRect();\n completeWithDrop(\n active,\n targetId,\n rect.left + rect.width / 2,\n rect.top + rect.height / 2,\n );\n }, [completeWithDrop, isTargetUsable]);\n\n const phase: DragPhase = useMemo(() => {\n if (activeDrag) return \"dragging\";\n if (settlingState) return \"settling\";\n if (returningState) return \"returning\";\n if (inspectingCardId) return \"inspecting\";\n return \"idle\";\n }, [activeDrag, inspectingCardId, returningState, settlingState]);\n\n const eligibleTargetCount = useMemo(\n () => sortedUsableTargetIds().length,\n // Recompute whenever any target patch changes — `activeDrag` is a cheap\n // proxy: target updates also bump the surface re-render via parent state.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [activeDrag, sortedUsableTargetIds],\n );\n\n const controller: CardDragSurfaceController = useMemo(\n () => ({\n activeCardId:\n activeDrag?.cardId ??\n settlingState?.cardId ??\n returningState?.cardId ??\n (inspectingCardId ? inspectingCardId : null),\n activeSource: activeDrag?.source ?? null,\n phase,\n overTargetId: activeDrag?.overTargetId ?? null,\n keyboardFocusedTargetId: activeDrag?.keyboardFocusedTargetId ?? null,\n startPointerDrag,\n updatePointer,\n releasePointer,\n cancelDrag,\n startKeyboardDrag,\n moveKeyboardFocus,\n commitKeyboardDrop,\n recordTap,\n recordPreviewStart,\n recordPreviewEnd,\n recordActivate,\n clearInspect,\n eligibleTargetCount,\n }),\n [\n activeDrag,\n cancelDrag,\n clearInspect,\n commitKeyboardDrop,\n eligibleTargetCount,\n inspectingCardId,\n moveKeyboardFocus,\n phase,\n recordActivate,\n recordPreviewEnd,\n recordPreviewStart,\n recordTap,\n releasePointer,\n returningState,\n settlingState,\n startKeyboardDrag,\n startPointerDrag,\n updatePointer,\n ],\n );\n\n const contextValue: CardDragSurfaceContextValue = useMemo(\n () => ({\n registerTarget,\n updateTarget,\n controller,\n activeCardId: controller.activeCardId,\n overTargetId: activeDrag?.overTargetId ?? null,\n dragActive: activeDrag !== null,\n keyboardFocusedTargetId: activeDrag?.keyboardFocusedTargetId ?? null,\n }),\n [activeDrag, controller, registerTarget, updateTarget],\n );\n\n useEffect(() => {\n if (!activeDrag) return;\n function onKeyDown(event: globalThis.KeyboardEvent) {\n if (event.key === \"Escape\") {\n event.preventDefault();\n cancelDrag();\n }\n }\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [activeDrag, cancelDrag]);\n\n const announcement = useMemo(() => {\n if (!activeDrag) return null;\n const overTarget = activeDrag.overTargetId\n ? targetsRef.current.get(activeDrag.overTargetId)\n : null;\n const overLabel = overTarget?.label ?? null;\n const cardLabel = activeDrag.cardLabel ?? \"Card\";\n if (overLabel) {\n return `${cardLabel} over ${overLabel}. Press Enter to drop or Escape to cancel.`;\n }\n return `${cardLabel} picked up. Move to a target or press Escape to cancel.`;\n }, [activeDrag]);\n\n const overlayContent = activeDrag ? (\n <DragOverlay session={activeDrag} reducedMotion={reducedMotion} />\n ) : null;\n\n const settleOverlay = settlingState ? (\n <SettleOverlay\n key={`settle-${settlingState.cardId}`}\n session={settlingState}\n transition={reducedMotion ? REDUCED_TRANSITION : settleTransition}\n onDone={() => setSettlingState(null)}\n />\n ) : null;\n\n const returnOverlay = returningState ? (\n <ReturnOverlay\n key={`return-${returningState.cardId}`}\n session={returningState}\n transition={reducedMotion ? REDUCED_TRANSITION : returnTransition}\n onDone={() => setReturningState(null)}\n />\n ) : null;\n\n const portalRoot = typeof document !== \"undefined\" ? document.body : null;\n\n return (\n <CardDragSurfaceContext.Provider value={contextValue}>\n <div\n data-dreamboard-card-drag-surface=\"\"\n data-drag-active={activeDrag ? \"true\" : undefined}\n data-drag-source={activeDrag?.source}\n data-drag-phase={phase}\n className={clsx(\"relative\", className)}\n style={style}\n >\n {children}\n </div>\n {portalRoot\n ? createPortal(\n <AnimatePresence initial={false}>\n {overlayContent}\n {settleOverlay}\n {returnOverlay}\n </AnimatePresence>,\n portalRoot,\n )\n : null}\n {!suppressLiveAnnouncement ? (\n <div\n id={liveRegionId}\n role=\"status\"\n aria-live=\"polite\"\n className=\"sr-only\"\n data-dreamboard-card-drag-announcement=\"\"\n style={{\n position: \"absolute\",\n width: 1,\n height: 1,\n padding: 0,\n margin: -1,\n overflow: \"hidden\",\n clip: \"rect(0,0,0,0)\",\n whiteSpace: \"nowrap\",\n border: 0,\n }}\n >\n {announcement ?? \"\"}\n </div>\n ) : null}\n </CardDragSurfaceContext.Provider>\n );\n}\n\ninterface DragOverlayProps {\n session: ActiveDragState;\n reducedMotion: boolean;\n}\n\nfunction DragOverlay({ session, reducedMotion }: DragOverlayProps) {\n if (session.source === \"keyboard\") {\n return (\n <motion.div\n key=\"overlay-keyboard\"\n data-dreamboard-card-drag-overlay=\"\"\n data-source=\"keyboard\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={reducedMotion ? REDUCED_TRANSITION : { duration: 0.12 }}\n style={{\n position: \"fixed\",\n left: session.sourceRect.left,\n top: session.sourceRect.top,\n width: session.sourceRect.width,\n height: session.sourceRect.height,\n pointerEvents: \"none\",\n zIndex: 1000,\n boxShadow: reducedMotion ? \"none\" : \"0 12px 32px rgba(0,0,0,0.18)\",\n borderRadius: 12,\n }}\n >\n {session.content}\n </motion.div>\n );\n }\n\n const liftedAnimate = reducedMotion\n ? {\n scale: 1,\n rotate: 0,\n filter: \"drop-shadow(0 0 0 rgba(0,0,0,0))\",\n }\n : {\n scale: [1, 1.42, 1.35],\n rotate: [0, -3, 3, -1.8, 1.8, 0],\n filter: [\n \"drop-shadow(0 4px 8px rgba(0,0,0,0.18))\",\n \"drop-shadow(0 24px 36px rgba(0,0,0,0.36))\",\n ],\n };\n const liftedTransition: Transition = reducedMotion\n ? REDUCED_TRANSITION\n : {\n scale: { type: \"spring\", stiffness: 420, damping: 22, mass: 0.7 },\n rotate: { duration: 0.55, ease: \"easeInOut\" },\n filter: { duration: 0.18, ease: \"easeOut\" },\n };\n return (\n <motion.div\n key=\"overlay-pointer\"\n data-dreamboard-card-drag-overlay=\"\"\n data-source=\"pointer\"\n initial={{\n scale: 1,\n rotate: 0,\n opacity: 1,\n filter: \"drop-shadow(0 2px 6px rgba(0,0,0,0.15))\",\n }}\n animate={liftedAnimate}\n exit={{ opacity: 0 }}\n transition={liftedTransition}\n style={{\n position: \"fixed\",\n left: session.pointerX - session.sourceRect.width / 2,\n top: session.pointerY - session.sourceRect.height / 2,\n width: session.sourceRect.width,\n height: session.sourceRect.height,\n zIndex: 1000,\n pointerEvents: \"none\",\n touchAction: \"none\",\n transformOrigin: \"center center\",\n willChange: \"transform, filter\",\n }}\n >\n {session.content}\n </motion.div>\n );\n}\n\ninterface SettleOverlayProps {\n session: SettlingState;\n transition: Transition;\n onDone: () => void;\n}\n\nfunction SettleOverlay({ session, transition, onDone }: SettleOverlayProps) {\n const startLeft = session.pointerX - session.sourceRect.width / 2;\n const startTop = session.pointerY - session.sourceRect.height / 2;\n const endLeft =\n session.targetRect.left +\n session.targetRect.width / 2 -\n session.sourceRect.width / 2;\n const endTop =\n session.targetRect.top +\n session.targetRect.height / 2 -\n session.sourceRect.height / 2;\n return (\n <motion.div\n data-dreamboard-card-drag-overlay=\"\"\n data-source={session.source}\n data-drag-phase=\"settling\"\n initial={{ left: startLeft, top: startTop, scale: 1.06, opacity: 1 }}\n animate={{ left: endLeft, top: endTop, scale: 0.92, opacity: 0 }}\n transition={transition}\n onAnimationComplete={onDone}\n style={{\n position: \"fixed\",\n width: session.sourceRect.width,\n height: session.sourceRect.height,\n zIndex: 1000,\n pointerEvents: \"none\",\n }}\n >\n {session.content}\n </motion.div>\n );\n}\n\ninterface ReturnOverlayProps {\n session: ReturningState;\n transition: Transition;\n onDone: () => void;\n}\n\nfunction ReturnOverlay({ session, transition, onDone }: ReturnOverlayProps) {\n const startLeft = session.pointerX - session.sourceRect.width / 2;\n const startTop = session.pointerY - session.sourceRect.height / 2;\n return (\n <motion.div\n data-dreamboard-card-drag-overlay=\"\"\n data-source={session.source}\n data-drag-phase=\"returning\"\n initial={{ left: startLeft, top: startTop, scale: 1.06, opacity: 1 }}\n animate={{\n left: session.sourceRect.left,\n top: session.sourceRect.top,\n scale: 1,\n opacity: 1,\n }}\n exit={{ opacity: 0 }}\n transition={transition}\n onAnimationComplete={onDone}\n style={{\n position: \"fixed\",\n width: session.sourceRect.width,\n height: session.sourceRect.height,\n zIndex: 1000,\n pointerEvents: \"none\",\n }}\n >\n {session.content}\n </motion.div>\n );\n}\n\nexport interface CardDropTargetViewProps {\n targetId: string;\n state?: CardDropTargetVisualState;\n /** Plain-text label used in live announcements (\"Selected cards\", etc.). */\n label?: string;\n renderTarget: (state: CardDropTargetVisualState) => ReactNode;\n className?: string;\n style?: CSSProperties;\n /** Tab order hint (lower numbers focus first). */\n order?: number;\n /** ARIA role override; defaults to `button`. */\n role?: string;\n}\n\nexport function CardDropTargetView({\n targetId,\n state,\n label,\n renderTarget,\n className,\n style,\n order,\n role = \"button\",\n}: CardDropTargetViewProps) {\n const surface = useCardDragSurface();\n const ref = useRef<HTMLDivElement | null>(null);\n const disabled = state?.disabled ?? false;\n const baseEligible = state?.eligible ?? true;\n const baseLabel = label ?? null;\n const orderProp = order ?? 0;\n\n const registerTargetRef = useRef(surface?.registerTarget);\n registerTargetRef.current = surface?.registerTarget;\n const updateTargetRef = useRef(surface?.updateTarget);\n updateTargetRef.current = surface?.updateTarget;\n\n // Stable register/unregister keyed only on `targetId`. Eligibility, label\n // and disabled flow through `updateTarget` so changing surface context\n // values cannot tear down the registration mid-drag.\n useEffect(() => {\n const element = ref.current;\n const register = registerTargetRef.current;\n if (!register || !element) return;\n const unregister = register({\n targetId,\n disabled,\n eligible: baseEligible,\n element,\n label: baseLabel,\n order: orderProp,\n });\n return unregister;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [targetId]);\n\n useEffect(() => {\n updateTargetRef.current?.(targetId, {\n disabled,\n eligible: baseEligible,\n label: baseLabel,\n order: orderProp,\n });\n }, [targetId, disabled, baseEligible, baseLabel, orderProp]);\n\n const dragActive = surface?.dragActive ?? false;\n const overTargetId = surface?.overTargetId ?? null;\n const keyboardFocused = surface?.keyboardFocusedTargetId === targetId;\n\n // Move focus into this target whenever the surface promotes it to the\n // keyboard-focused id. Doing it here, after React commits, is more\n // reliable than firing focus() from inside the surface's `setActive`\n // callback (where React batching can race the source card's commit).\n useEffect(() => {\n if (!keyboardFocused) return;\n const el = ref.current;\n if (!el) return;\n if (document.activeElement === el) return;\n try {\n el.focus({ preventScroll: true });\n } catch {\n // Element may have unmounted; ignore.\n }\n }, [keyboardFocused, targetId]);\n\n const computedState: CardDropTargetVisualState = {\n ...state,\n eligible: baseEligible,\n active: dragActive ? true : state?.active,\n over:\n overTargetId === targetId && baseEligible ? true : (state?.over ?? false),\n };\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n if (!surface) return;\n const controller = surface.controller;\n if (controller.activeSource !== \"keyboard\") return;\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n controller.commitKeyboardDrop();\n return;\n }\n if (event.key === \"ArrowRight\" || event.key === \"ArrowDown\") {\n event.preventDefault();\n controller.moveKeyboardFocus(\"next\");\n return;\n }\n if (event.key === \"ArrowLeft\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n controller.moveKeyboardFocus(\"prev\");\n return;\n }\n if (event.key === \"Escape\") {\n event.preventDefault();\n controller.cancelDrag();\n }\n },\n [surface],\n );\n\n return (\n <div\n ref={ref}\n data-dreamboard-card-drop-target=\"\"\n data-target-id={targetId}\n data-keyboard-focused={keyboardFocused ? \"true\" : undefined}\n role={role}\n tabIndex={disabled || !baseEligible ? -1 : 0}\n aria-disabled={disabled || !baseEligible || undefined}\n aria-label={label}\n onKeyDown={handleKeyDown}\n className={className}\n style={style}\n {...dropTargetVisualStateDataAttributes(computedState)}\n >\n {renderTarget(computedState)}\n </div>\n );\n}\n","/**\n * Controlled, presentational hand view.\n *\n * `HandView` does not consume any Dreamboard descriptor or runtime state.\n * Callers supply:\n *\n * - the cards to render\n * - a `stateForCard(card)` function returning a controlled\n * {@link InteractionVisualState}\n * - a `renderCard(card, state)` slot for the visual surface (typically\n * a {@link CardFace})\n *\n * The component emits generic {@link CardIntent} events. A runtime\n * adapter is responsible for turning an `activate`/`drop` intent into a\n * Dreamboard submission.\n *\n * `mobileInteraction` selects the gesture policy:\n * - `direct-activate` — desktop tap and keyboard Enter/Space emit a single\n * `activate` intent.\n * - `drag-to-target` — pointer/keyboard lift initiates a drag against a\n * surrounding `CardDragSurface`. Tap collapses to an `inspecting` state\n * that does not commit. Drop emits an opaque `drop` intent.\n *\n * Layout, gesture, scroll arbitration and tray presentation are documented in\n * `docs/references/ui-sdk-mobile-hand-and-card-interactions.md`.\n */\n\nimport {\n useCallback,\n useId,\n useMemo,\n type CSSProperties,\n type ReactNode,\n} from \"react\";\nimport { clsx } from \"clsx\";\nimport type { ViewCard } from \"../../types/index.js\";\nimport type {\n CardIntent,\n InteractionVisualState,\n} from \"../types/visual-state.js\";\nimport type {\n HandPresentationMode,\n FanCardPosition,\n} from \"./hand-layout-math.js\";\nimport { useHandPresentation } from \"../hooks/useHandPresentation.js\";\nimport { useHandCardPointer } from \"../hooks/useHandCardPointer.js\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\nimport { useCardDragSurface } from \"./CardDragSurface.js\";\nimport type { HandInteractionPolicy } from \"./hand-pointer-engine.js\";\n\nexport type HandLayoutKind = HandPresentationMode | \"stack\";\n\nexport interface HandLayoutPolicy {\n desktop?: HandLayoutKind;\n mobile?: HandLayoutKind;\n}\n\nexport interface HandViewProps<CardData extends ViewCard = ViewCard> {\n cards: readonly CardData[];\n /**\n * Layout policy. Pass a single layout kind to use the same layout in every\n * viewport, or pass `{ desktop, mobile }` for a measured-width decision.\n * Defaults to `{ desktop: \"fan\", mobile: \"tray\" }`.\n */\n layout?: HandLayoutKind | HandLayoutPolicy;\n /**\n * Mobile interaction policy. Defaults to `direct-activate`. Use\n * `drag-to-target` together with a surrounding `CardDragSurface` and one\n * or more `CardDropTargetView` children.\n */\n mobileInteraction?: HandInteractionPolicy;\n /** Returns the controlled visual state for a card. */\n stateForCard?: (\n card: CardData,\n index: number,\n ) => InteractionVisualState | undefined;\n /** Visual surface renderer. */\n renderCard: (\n card: CardData,\n state: InteractionVisualState,\n index: number,\n ) => ReactNode;\n /** Generic UI intent callback. */\n onCardIntent?: (intent: CardIntent<CardData[\"id\"] & string>) => void;\n /** Card width hint for fan geometry. */\n cardSize?: \"sm\" | \"md\" | \"lg\";\n /** Slot for the empty state. Defaults to nothing rendered. */\n renderEmpty?: () => ReactNode;\n /** ARIA label for the hand region. */\n \"aria-label\"?: string;\n className?: string;\n style?: CSSProperties;\n}\n\nconst CARD_DIMENSIONS = {\n sm: { width: 80, height: 112 },\n md: { width: 96, height: 144 },\n lg: { width: 128, height: 192 },\n} as const;\n\nconst EMPTY_STATE: InteractionVisualState = {};\n\ninterface ResolvedLayoutPolicy {\n desktop: HandPresentationMode;\n mobile: HandPresentationMode;\n /** What we report on `data-layout` for stories/tests. */\n reported: HandLayoutKind;\n}\n\nfunction resolveLayoutPolicy(\n layout: HandViewProps[\"layout\"],\n): ResolvedLayoutPolicy {\n if (!layout) {\n return { desktop: \"fan\", mobile: \"tray\", reported: \"fan\" };\n }\n if (typeof layout === \"string\") {\n if (layout === \"stack\") {\n return { desktop: \"strip\", mobile: \"strip\", reported: \"stack\" };\n }\n return { desktop: layout, mobile: layout, reported: layout };\n }\n const desktop =\n layout.desktop === \"stack\" ? \"strip\" : (layout.desktop ?? \"fan\");\n const mobile =\n layout.mobile === \"stack\" ? \"strip\" : (layout.mobile ?? \"tray\");\n return {\n desktop,\n mobile,\n reported: (layout.desktop ?? layout.mobile ?? \"fan\") as HandLayoutKind,\n };\n}\n\nexport function HandView<CardData extends ViewCard = ViewCard>({\n cards,\n layout,\n mobileInteraction = \"direct-activate\",\n stateForCard,\n renderCard,\n onCardIntent,\n cardSize = \"md\",\n renderEmpty,\n \"aria-label\": ariaLabel = \"Your hand\",\n className,\n style,\n}: HandViewProps<CardData>) {\n const policy = useMemo(() => resolveLayoutPolicy(layout), [layout]);\n const dims = CARD_DIMENSIONS[cardSize];\n const regionId = useId();\n const theme = useTheme();\n const reducedMotion = theme.motion.reducedMotion === \"true\";\n\n const presentation = useHandPresentation({\n cardCount: cards.length,\n cardWidth: dims.width,\n cardHeight: dims.height,\n desktop: policy.desktop,\n mobile: policy.mobile,\n });\n\n const surface = useCardDragSurface();\n const surfaceController = surface?.controller ?? null;\n\n const emit = useCallback(\n (intent: CardIntent<CardData[\"id\"] & string>) => {\n onCardIntent?.(intent);\n },\n [onCardIntent],\n );\n\n const items = useMemo(\n () =>\n cards.map((card, index) => {\n const baseState = stateForCard?.(card, index) ?? EMPTY_STATE;\n return { card, index, baseState };\n }),\n [cards, stateForCard],\n );\n\n const renderLiftedCard = useCallback(\n (cardId: string): ReactNode => {\n const found = items.find((item) => (item.card.id as string) === cardId);\n if (!found) return null;\n return renderCard(found.card, found.baseState, found.index);\n },\n [items, renderCard],\n );\n\n const resolveCardLabel = useCallback(\n (cardId: string): string | null => {\n const found = items.find((item) => (item.card.id as string) === cardId);\n if (!found) return null;\n const card = found.card as ViewCard;\n return (\n card.name ??\n (card.properties as { title?: string } | undefined)?.title ??\n null\n );\n },\n [items],\n );\n\n const pointer = useHandCardPointer({\n onIntent: (intent) => emit(intent as CardIntent<CardData[\"id\"] & string>),\n policy: mobileInteraction,\n surface: surfaceController,\n renderLiftedCard,\n resolveCardLabel,\n });\n\n if (cards.length === 0) {\n return (\n <div\n ref={presentation.containerRef}\n data-dreamboard-hand-view=\"\"\n data-layout={policy.reported}\n data-mode=\"empty\"\n data-empty=\"true\"\n data-mobile-interaction={mobileInteraction}\n role=\"group\"\n aria-label={`${ariaLabel} - empty`}\n className={clsx(\n \"relative w-full min-w-0 flex items-end justify-center py-4 sm:py-6\",\n className,\n )}\n style={style}\n >\n {renderEmpty ? renderEmpty() : null}\n </div>\n );\n }\n\n const ariaCount = `${ariaLabel} - ${cards.length} card${cards.length === 1 ? \"\" : \"s\"}`;\n\n const surfacePhase = surfaceController?.phase ?? \"idle\";\n const surfaceActiveCardId = surfaceController?.activeCardId ?? null;\n\n const renderItem = (\n {\n card,\n index,\n baseState,\n }: { card: CardData; index: number; baseState: InteractionVisualState },\n extra: { positioned?: FanCardPosition } = {},\n ) => {\n const cardId = card.id as string;\n const isPointerActive = pointer.activeCardId === cardId;\n const isSurfaceActive = surfaceActiveCardId === cardId;\n const previewing =\n isPointerActive && pointer.recognitionState.kind === \"preview\"\n ? true\n : baseState.previewing;\n const isInspecting = isSurfaceActive && surfacePhase === \"inspecting\";\n const isDragging = isSurfaceActive && surfacePhase === \"dragging\";\n const isSettling = isSurfaceActive && surfacePhase === \"settling\";\n const isReturning = isSurfaceActive && surfacePhase === \"returning\";\n // Hide the source slot whenever the portal overlay is showing this card\n // (drag, settle, or return). The overlay is the visible card during\n // those phases — leaving the source visible duplicates it.\n const isLifted = isDragging || isSettling || isReturning;\n const state: InteractionVisualState = {\n ...baseState,\n previewing,\n };\n const eligible = state.eligible ?? false;\n const disabled = state.disabled ?? false;\n const bindings = pointer.bindCard({\n cardId,\n eligible,\n disabled,\n });\n const positioned = extra.positioned;\n const transformParts: string[] = [];\n if (positioned) {\n transformParts.push(`translateY(${positioned.translateY}px)`);\n transformParts.push(`rotate(${positioned.rotate}deg)`);\n }\n if (isInspecting && !reducedMotion) {\n transformParts.push(\"translateY(-12px)\", \"scale(1.04)\");\n }\n const transform = transformParts.length\n ? transformParts.join(\" \")\n : undefined;\n const liftVisualOpacity = isLifted ? 0.25 : 1;\n const inspectShadow =\n isInspecting && !reducedMotion\n ? \"0 14px 28px rgba(0,0,0,0.18)\"\n : undefined;\n return (\n <div\n key={card.id}\n role=\"gridcell\"\n aria-rowindex={1}\n aria-colindex={index + 1}\n id={`${regionId}-${index}`}\n tabIndex={disabled ? -1 : 0}\n data-lifted={isLifted ? \"true\" : undefined}\n data-returning={isReturning ? \"true\" : undefined}\n data-inspecting={isInspecting ? \"true\" : undefined}\n {...bindings}\n style={{\n ...bindings.style,\n opacity: liftVisualOpacity,\n boxShadow: inspectShadow,\n ...(positioned\n ? {\n position: \"absolute\",\n left: positioned.left,\n bottom: 0,\n zIndex: isInspecting ? 50 : positioned.zIndex,\n transform,\n transformOrigin: \"bottom center\",\n transition: reducedMotion\n ? \"none\"\n : \"transform 180ms ease-out, box-shadow 180ms ease-out\",\n }\n : transform\n ? {\n transform,\n transformOrigin: \"bottom center\",\n transition: reducedMotion\n ? \"none\"\n : \"transform 180ms ease-out, box-shadow 180ms ease-out\",\n }\n : null),\n }}\n >\n {renderCard(card, state, index)}\n </div>\n );\n };\n\n if (presentation.mode === \"fan\" || presentation.mode === \"compressed-fan\") {\n const totalHeight = dims.height + 24;\n return (\n <div\n ref={presentation.containerRef}\n data-dreamboard-hand-view=\"\"\n data-layout={policy.reported}\n data-mode={presentation.mode}\n data-mobile-interaction={mobileInteraction}\n data-reduced-motion={reducedMotion ? \"true\" : undefined}\n role=\"grid\"\n aria-label={ariaCount}\n aria-rowcount={1}\n aria-colcount={cards.length}\n className={clsx(\n \"relative w-full min-w-0 flex items-end justify-center py-4 sm:py-6 overflow-visible\",\n className,\n )}\n style={{\n touchAction: \"pan-x\",\n ...style,\n }}\n >\n <div\n role=\"row\"\n className=\"relative\"\n style={{\n width: presentation.totalWidth,\n height: totalHeight,\n }}\n >\n {items.map((item, index) =>\n renderItem(item, {\n positioned: presentation.fanPositions[index],\n }),\n )}\n </div>\n </div>\n );\n }\n\n if (presentation.mode === \"tray\") {\n return (\n <div\n ref={presentation.containerRef}\n data-dreamboard-hand-view=\"\"\n data-layout={policy.reported}\n data-mode=\"tray\"\n data-mobile-interaction={mobileInteraction}\n data-reduced-motion={reducedMotion ? \"true\" : undefined}\n role=\"grid\"\n aria-label={ariaCount}\n aria-rowcount={1}\n aria-colcount={cards.length}\n className={clsx(\"relative w-full min-w-0\", className)}\n style={style}\n >\n <div\n role=\"row\"\n className={clsx(\n \"flex items-end gap-3 overflow-x-auto px-4\",\n \"snap-x scroll-px-4\",\n )}\n style={{\n touchAction: pointer.scrollLocked ? \"none\" : \"pan-x\",\n paddingTop: 12,\n paddingBottom: \"max(1rem, env(safe-area-inset-bottom, 0px))\",\n scrollBehavior: reducedMotion ? \"auto\" : \"smooth\",\n }}\n >\n {items.map((item) => (\n <div\n key={item.card.id}\n className=\"snap-start shrink-0\"\n role=\"presentation\"\n >\n {renderItem(item)}\n </div>\n ))}\n </div>\n </div>\n );\n }\n\n // strip / stack — flow-based layout that keeps every card individually\n // touch-usable. Stack layout draws cards with a small horizontal cascade.\n return (\n <div\n ref={presentation.containerRef}\n data-dreamboard-hand-view=\"\"\n data-layout={policy.reported}\n data-mode={presentation.mode}\n data-mobile-interaction={mobileInteraction}\n data-reduced-motion={reducedMotion ? \"true\" : undefined}\n role=\"grid\"\n aria-label={ariaCount}\n aria-rowcount={1}\n aria-colcount={cards.length}\n className={clsx(\n \"relative w-full min-w-0 flex items-end justify-center py-4 sm:py-6\",\n className,\n )}\n style={{ touchAction: \"pan-x\", ...style }}\n >\n <div role=\"row\" className=\"flex flex-wrap justify-center gap-1\">\n {items.map((item) => renderItem(item))}\n </div>\n </div>\n );\n}\n","/**\n * Width-aware presentation selector for the controlled `HandView`.\n *\n * Measures the wrapping element with `ResizeObserver` and returns the chosen\n * presentation mode plus the resolved fan geometry. The hook is purely\n * presentational: it does not consume runtime state or descriptors.\n */\n\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n HAND_MODE_GEOMETRY,\n chooseHandLayoutMode,\n computeFanLayout,\n type FanCardPosition,\n type HandPresentationMode,\n} from \"../components/hand-layout-math.js\";\n\nexport interface HandPresentationOptions {\n cardCount: number;\n cardWidth: number;\n cardHeight: number;\n /** Desktop preference; defaults to `fan`. */\n desktop?: HandPresentationMode;\n /** Mobile fallback; defaults to `tray`. */\n mobile?: HandPresentationMode;\n /** Subtracted from measured container width (gutter, scroll padding). */\n containerPadding?: number;\n}\n\nexport interface HandPresentationResult {\n containerRef: React.RefObject<HTMLDivElement | null>;\n containerWidth: number;\n mode: HandPresentationMode;\n fanPositions: FanCardPosition[];\n fanStep: number;\n totalWidth: number;\n visibleSlice: number;\n}\n\nconst DEFAULT_PADDING = 16;\n\nexport function useHandPresentation({\n cardCount,\n cardWidth,\n cardHeight,\n desktop = \"fan\",\n mobile = \"tray\",\n containerPadding = DEFAULT_PADDING,\n}: HandPresentationOptions): HandPresentationResult {\n const containerRef = useRef<HTMLDivElement>(null);\n const [containerWidth, setContainerWidth] = useState(0);\n\n useEffect(() => {\n const node = containerRef.current;\n if (!node) return;\n let frame = 0;\n // Round to whole pixels and bail when the width is unchanged. The chosen\n // mode (fan vs compressed-fan) feeds the rendered card geometry, so an\n // unguarded float setState here can ping-pong the layout via ResizeObserver\n // (sub-pixel jitter, or a content-sized ancestor) and re-render forever.\n // Deferring to rAF also avoids \"ResizeObserver loop limit exceeded\".\n const apply = () => {\n const node = containerRef.current;\n if (!node) return;\n const next = Math.max(\n 0,\n Math.round(node.getBoundingClientRect().width) - containerPadding,\n );\n setContainerWidth((prev) => (prev === next ? prev : next));\n };\n apply();\n if (typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(() => {\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(apply);\n });\n observer.observe(node);\n return () => {\n cancelAnimationFrame(frame);\n observer.disconnect();\n };\n }, [containerPadding]);\n\n return useMemo<HandPresentationResult>(() => {\n const mode = chooseHandLayoutMode({\n containerWidth,\n cardCount,\n cardWidth,\n desktop,\n mobile,\n });\n if (mode === \"fan\" || mode === \"compressed-fan\") {\n const geometry = HAND_MODE_GEOMETRY[mode];\n const layout = computeFanLayout({\n availableWidth: containerWidth || cardWidth * cardCount,\n cardWidth,\n cardHeight,\n count: cardCount,\n ...geometry,\n });\n return {\n containerRef,\n containerWidth,\n mode,\n fanPositions: layout.positions,\n fanStep: layout.step,\n totalWidth: layout.totalWidth,\n visibleSlice: layout.visibleSlice,\n };\n }\n return {\n containerRef,\n containerWidth,\n mode,\n fanPositions: [],\n fanStep: cardWidth,\n totalWidth: cardWidth * cardCount,\n visibleSlice: cardWidth,\n };\n }, [cardCount, cardHeight, cardWidth, containerWidth, desktop, mobile]);\n}\n","/**\n * Pure layout math for the controlled `HandView`.\n *\n * The functions here are independent of React and DOM measurement so they can\n * be unit-tested directly. {@link computeFanLayout} matches the algorithm\n * documented in `docs/references/ui-sdk-mobile-hand-and-card-interactions.md`,\n * and {@link chooseHandLayoutMode} translates a measured container width and a\n * caller policy into the actual presentation mode the hand should render.\n */\n\nexport type HandPresentationMode = \"fan\" | \"compressed-fan\" | \"strip\" | \"tray\";\n\nexport interface FanLayoutOptions {\n availableWidth: number;\n cardWidth: number;\n cardHeight: number;\n count: number;\n /** Minimum visible slice for any card (touch readability floor). */\n minVisibleSlice: number;\n /** Maximum tilt of the outermost card, in degrees. */\n maxAngle: number;\n /** How many pixels the outermost cards drop below the center card. */\n arcDepth: number;\n}\n\nexport interface FanCardPosition {\n left: number;\n rotate: number;\n translateY: number;\n zIndex: number;\n}\n\nexport interface FanLayoutResult {\n positions: FanCardPosition[];\n /** Step between successive card origins (left offset). */\n step: number;\n /** Minimum bounding width of the laid-out hand. */\n totalWidth: number;\n /** Visible portion of each card after overlap, in pixels. */\n visibleSlice: number;\n}\n\nexport function computeFanLayout(options: FanLayoutOptions): FanLayoutResult {\n const {\n availableWidth,\n cardWidth,\n count,\n minVisibleSlice,\n maxAngle,\n arcDepth,\n } = options;\n if (count <= 0) {\n return { positions: [], step: 0, totalWidth: 0, visibleSlice: cardWidth };\n }\n if (count === 1) {\n return {\n positions: [{ left: 0, rotate: 0, translateY: 0, zIndex: 1 }],\n step: cardWidth,\n totalWidth: cardWidth,\n visibleSlice: cardWidth,\n };\n }\n\n const idealStep =\n availableWidth > cardWidth\n ? (availableWidth - cardWidth) / (count - 1)\n : minVisibleSlice;\n const step = Math.max(minVisibleSlice, Math.min(cardWidth, idealStep));\n const center = (count - 1) / 2;\n\n const positions: FanCardPosition[] = Array.from(\n { length: count },\n (_, index) => {\n const t = center === 0 ? 0 : (index - center) / center;\n return {\n left: index * step,\n rotate: t * maxAngle,\n translateY: Math.abs(t) * arcDepth,\n zIndex: index + 1,\n };\n },\n );\n\n return {\n positions,\n step,\n totalWidth: cardWidth + (count - 1) * step,\n visibleSlice: step,\n };\n}\n\nexport interface ChooseHandLayoutModeOptions {\n /** Measured container width in CSS pixels. `0` means unmeasured. */\n containerWidth: number;\n cardCount: number;\n cardWidth: number;\n /**\n * Caller-stated layout preference. The pair represents the desktop/mobile\n * intent — the visible-slice gate decides which one renders.\n */\n desktop: HandPresentationMode;\n mobile: HandPresentationMode;\n /** Minimum visible per-card slice that still feels touch-usable. */\n comfortableSlice?: number;\n /** Floor for compressed fan; below this the mobile fallback wins. */\n compressedSlice?: number;\n}\n\n/**\n * Choose the actual presentation mode for the current viewport.\n *\n * The decision is target-exposure based, not breakpoint based:\n *\n * - if the desktop preference fits with a comfortable slice, render it as-is;\n * - if it would only barely fit, use a `compressed-fan` when the desktop side\n * is fan-like;\n * - otherwise switch to the mobile fallback (`tray`, `strip`, or whatever the\n * caller asked for) so playable targets stay usable.\n */\nexport function chooseHandLayoutMode({\n containerWidth,\n cardCount,\n cardWidth,\n desktop,\n mobile,\n comfortableSlice = HAND_MODE_GEOMETRY.fan.minVisibleSlice,\n compressedSlice = HAND_MODE_GEOMETRY[\"compressed-fan\"].minVisibleSlice,\n}: ChooseHandLayoutModeOptions): HandPresentationMode {\n if (cardCount <= 1) return desktop;\n if (containerWidth <= 0) return desktop;\n\n const idealStep = (containerWidth - cardWidth) / (cardCount - 1);\n const step = Math.max(0, Math.min(cardWidth, idealStep));\n\n const desktopIsFanLike = desktop === \"fan\" || desktop === \"compressed-fan\";\n if (!desktopIsFanLike) {\n if (containerWidth >= cardWidth * cardCount) return desktop;\n return mobile;\n }\n\n if (step >= comfortableSlice) {\n return desktop === \"compressed-fan\" ? \"compressed-fan\" : \"fan\";\n }\n if (step >= compressedSlice) {\n return \"compressed-fan\";\n }\n return mobile;\n}\n\nexport interface HandModeGeometry {\n minVisibleSlice: number;\n maxAngle: number;\n arcDepth: number;\n}\n\n/** Recommended starting values from the mobile-hand reference. */\nexport const HAND_MODE_GEOMETRY: Record<\n Exclude<HandPresentationMode, \"tray\" | \"strip\">,\n HandModeGeometry\n> = {\n fan: { minVisibleSlice: 64, maxAngle: 5, arcDepth: 12 },\n \"compressed-fan\": { minVisibleSlice: 44, maxAngle: 4, arcDepth: 8 },\n};\n","/**\n * React binding for the {@link HandPointerEngine}.\n *\n * The hook recognizes pointer/keyboard activity on a card and forwards it to\n * the surrounding `CardDragSurface` controller. All `CardIntent` emission\n * (`activate`, `previewStart`, `previewEnd`, `drop`) flows through the\n * surface so that the surface is the single source of truth for the\n * drag-lifecycle.\n *\n * Two interaction policies:\n *\n * - `direct-activate` — desktop tap/click and keyboard Enter/Space emit one\n * `activate` (the hook calls `onIntent` directly because no drag-lifecycle\n * exists in this mode).\n * - `drag-to-target` — pointer lift starts a surface drag session; release\n * commits/returns through the surface; tap/keyboard Enter trigger the\n * surface's `recordTap`/`startKeyboardDrag` so it owns the lifecycle.\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n DEFAULT_POINTER_THRESHOLDS,\n HandPointerEngine,\n type CardPointerState,\n type HandInteractionPolicy,\n type PointerEngineCardSnapshot,\n type PointerEngineThresholds,\n} from \"../components/hand-pointer-engine.js\";\nimport type { CardDragSurfaceController } from \"../components/CardDragSurface.js\";\nimport type { CardIntent } from \"../types/visual-state.js\";\nimport type { ReactNode } from \"react\";\n\nexport interface UseHandCardPointerOptions {\n onIntent?: (intent: CardIntent) => void;\n thresholds?: PointerEngineThresholds;\n /**\n * Active interaction policy. Defaults to `direct-activate`.\n */\n policy?: HandInteractionPolicy;\n /**\n * Drag-surface controller for `drag-to-target` mode. The hook forwards\n * pointer/keyboard lifts to the controller; the controller emits intents.\n */\n surface?: CardDragSurfaceController | null;\n /**\n * Render the lifted card payload. Required when a `surface` is supplied;\n * the hook calls this to produce the overlay content for the active card.\n */\n renderLiftedCard?: (cardId: string) => ReactNode;\n /**\n * Resolve the human-readable label of the card being dragged for live\n * announcements.\n */\n resolveCardLabel?: (cardId: string) => string | null | undefined;\n}\n\nexport interface HandCardPointerBindings {\n /** Identity of the card the engine is currently tracking, if any. */\n activeCardId: string | null;\n /** Pointer recognition state (used for previewing/scroll-lock visuals). */\n recognitionState: CardPointerState;\n /** Whether the host should suppress vertical scrolling. */\n scrollLocked: boolean;\n /** Returns the props bag for a single card. */\n bindCard: (card: PointerEngineCardSnapshot) => HandCardPointerProps;\n /** Programmatic activation, for keyboard and synthetic clicks. */\n activateKeyboard: (card: PointerEngineCardSnapshot) => void;\n}\n\nexport interface HandCardPointerProps {\n ref: (element: HTMLElement | null) => void;\n onPointerDown: (event: React.PointerEvent<HTMLElement>) => void;\n onPointerMove: (event: React.PointerEvent<HTMLElement>) => void;\n onPointerUp: (event: React.PointerEvent<HTMLElement>) => void;\n onPointerCancel: (event: React.PointerEvent<HTMLElement>) => void;\n onLostPointerCapture: (event: React.PointerEvent<HTMLElement>) => void;\n onKeyDown: (event: React.KeyboardEvent<HTMLElement>) => void;\n onClick: (event: React.MouseEvent<HTMLElement>) => void;\n style: React.CSSProperties;\n \"data-pointer-state\": CardPointerState[\"kind\"];\n}\n\nexport function useHandCardPointer({\n onIntent,\n thresholds = DEFAULT_POINTER_THRESHOLDS,\n policy = \"direct-activate\",\n surface = null,\n renderLiftedCard,\n resolveCardLabel,\n}: UseHandCardPointerOptions = {}): HandCardPointerBindings {\n const intentRef = useRef(onIntent);\n intentRef.current = onIntent;\n const policyRef = useRef(policy);\n policyRef.current = policy;\n const surfaceRef = useRef<CardDragSurfaceController | null>(surface);\n surfaceRef.current = surface;\n const renderLiftedCardRef = useRef(renderLiftedCard);\n renderLiftedCardRef.current = renderLiftedCard;\n const resolveCardLabelRef = useRef(resolveCardLabel);\n resolveCardLabelRef.current = resolveCardLabel;\n\n const cardElementsRef = useRef(new Map<string, HTMLElement>());\n const cardRefsRef = useRef(\n new Map<string, (element: HTMLElement | null) => void>(),\n );\n\n const getCardRef = useCallback((cardId: string) => {\n let stable = cardRefsRef.current.get(cardId);\n if (!stable) {\n stable = (element: HTMLElement | null) => {\n if (element) {\n cardElementsRef.current.set(cardId, element);\n } else {\n cardElementsRef.current.delete(cardId);\n }\n };\n cardRefsRef.current.set(cardId, stable);\n }\n return stable;\n }, []);\n\n const [activeCardId, setActiveCardId] = useState<string | null>(null);\n const [recognitionState, setRecognitionState] = useState<CardPointerState>({\n kind: \"idle\",\n });\n const [scrollLocked, setScrollLocked] = useState(false);\n\n const captureSourceRect = useCallback((cardId: string) => {\n const el = cardElementsRef.current.get(cardId);\n if (!el) return { left: 0, top: 0, width: 0, height: 0 };\n const rect = el.getBoundingClientRect();\n return {\n left: rect.left,\n top: rect.top,\n width: rect.width,\n height: rect.height,\n };\n }, []);\n\n const engine = useMemo(\n () =>\n new HandPointerEngine(\n {\n onTap: (cardId) => {\n const cardEl = cardElementsRef.current.get(cardId);\n if (policyRef.current === \"drag-to-target\" && surfaceRef.current) {\n surfaceRef.current.recordTap({\n cardId,\n cardEligible: true,\n cardDisabled: false,\n sourceFocus: cardEl ?? null,\n });\n return;\n }\n if (surfaceRef.current) {\n surfaceRef.current.recordActivate(cardId, \"tap\");\n return;\n }\n intentRef.current?.({\n type: \"activate\",\n cardId,\n source: \"tap\",\n });\n },\n onPreviewStart: (cardId) => {\n // Surface is the canonical owner of all `CardIntent` emission\n // when present. Without a surface (legacy direct-activate-only\n // mounts), fall back to the local `onIntent` callback.\n if (surfaceRef.current) {\n surfaceRef.current.recordPreviewStart(cardId);\n return;\n }\n intentRef.current?.({ type: \"previewStart\", cardId });\n },\n onPreviewEnd: (cardId) => {\n if (surfaceRef.current) {\n surfaceRef.current.recordPreviewEnd(cardId);\n return;\n }\n intentRef.current?.({ type: \"previewEnd\", cardId });\n },\n onLiftStart: (event) => {\n if (policyRef.current !== \"drag-to-target\") return;\n const surfaceController = surfaceRef.current;\n if (!surfaceController) return;\n const content = renderLiftedCardRef.current?.(event.cardId) ?? null;\n const label = resolveCardLabelRef.current?.(event.cardId) ?? null;\n const sourceRect = captureSourceRect(event.cardId);\n const cardEl = cardElementsRef.current.get(event.cardId) ?? null;\n surfaceController.startPointerDrag({\n cardId: event.cardId,\n cardLabel: label,\n pointerId: event.pointerId,\n startX: event.startX,\n startY: event.startY,\n pointerX: event.pointerX,\n pointerY: event.pointerY,\n grabOffsetX: event.grabOffsetX,\n grabOffsetY: event.grabOffsetY,\n sourceRect,\n content,\n sourceFocus: cardEl,\n });\n },\n onLiftMove: (event) => {\n surfaceRef.current?.updatePointer({\n x: event.pointerX,\n y: event.pointerY,\n });\n },\n onLiftEnd: (event) => {\n surfaceRef.current?.releasePointer({\n x: event.pointerX,\n y: event.pointerY,\n });\n },\n onLiftCancel: () => {\n surfaceRef.current?.cancelDrag();\n },\n onLockScroll: setScrollLocked,\n onStateChange: (next) => {\n setRecognitionState(next);\n if (next.kind === \"idle\") {\n setActiveCardId(null);\n } else {\n setActiveCardId(next.cardId);\n }\n },\n },\n thresholds,\n ),\n [captureSourceRect, thresholds],\n );\n\n useEffect(() => () => engine.dispose(), [engine]);\n\n const bindCard = useCallback(\n (card: PointerEngineCardSnapshot): HandCardPointerProps => {\n const isActive = activeCardId === card.cardId;\n const pointerStateKind: CardPointerState[\"kind\"] = isActive\n ? recognitionState.kind\n : \"idle\";\n return {\n ref: getCardRef(card.cardId),\n style: {\n touchAction: isActive && scrollLocked ? \"none\" : \"pan-x\",\n userSelect: \"none\",\n WebkitUserSelect: \"none\",\n },\n \"data-pointer-state\": pointerStateKind,\n onPointerDown: (event) => {\n if (event.button !== undefined && event.button !== 0) return;\n if (card.disabled) return;\n try {\n (event.currentTarget as HTMLElement).setPointerCapture?.(\n event.pointerId,\n );\n } catch {\n // Test environments without an OS-backed pointer (jsdom-like\n // headless Chromium with synthesized PointerEvents) may throw\n // here. Capture is a UX nicety, not required for correctness.\n }\n engine.handlePointerDown(card, {\n pointerId: event.pointerId,\n clientX: event.clientX,\n clientY: event.clientY,\n });\n },\n onPointerMove: (event) => {\n engine.handlePointerMove(card, {\n pointerId: event.pointerId,\n clientX: event.clientX,\n clientY: event.clientY,\n });\n },\n onPointerUp: (event) => {\n try {\n (event.currentTarget as HTMLElement).releasePointerCapture?.(\n event.pointerId,\n );\n } catch {\n // Pair with the synthesized-pointer try in `onPointerDown`.\n }\n engine.handlePointerUp(card, {\n pointerId: event.pointerId,\n clientX: event.clientX,\n clientY: event.clientY,\n });\n },\n onPointerCancel: () => {\n engine.handlePointerCancel(card);\n },\n onLostPointerCapture: () => {\n engine.handlePointerCancel(card);\n },\n onKeyDown: (event) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n surfaceRef.current?.cancelDrag();\n return;\n }\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n if (card.disabled || !card.eligible) return;\n if (policyRef.current === \"drag-to-target\") {\n const surfaceController = surfaceRef.current;\n if (!surfaceController) return;\n const cardEl = cardElementsRef.current.get(card.cardId) ?? null;\n const content =\n renderLiftedCardRef.current?.(card.cardId) ?? null;\n const label = resolveCardLabelRef.current?.(card.cardId) ?? null;\n const sourceRect = captureSourceRect(card.cardId);\n const started = surfaceController.startKeyboardDrag({\n cardId: card.cardId,\n cardLabel: label,\n cardEligible: card.eligible,\n sourceRect,\n content,\n sourceFocus: cardEl,\n });\n if (!started) {\n // No eligible target — record an inspection through the\n // surface so the visual treatment matches a tap. We never\n // silently revert to direct activate under drag-to-target.\n surfaceController.recordTap({\n cardId: card.cardId,\n cardEligible: card.eligible,\n cardDisabled: card.disabled,\n sourceFocus: cardEl,\n });\n }\n return;\n }\n if (surfaceRef.current) {\n surfaceRef.current.recordActivate(card.cardId, \"keyboard\");\n return;\n }\n intentRef.current?.({\n type: \"activate\",\n cardId: card.cardId,\n source: \"keyboard\",\n });\n }\n },\n onClick: () => {\n // Pointerup paths already emit; suppress the synthetic click.\n },\n };\n },\n [\n activeCardId,\n captureSourceRect,\n engine,\n getCardRef,\n recognitionState.kind,\n scrollLocked,\n ],\n );\n\n const activateKeyboard = useCallback((card: PointerEngineCardSnapshot) => {\n if (card.disabled || !card.eligible) return;\n if (policyRef.current === \"drag-to-target\") return;\n if (surfaceRef.current) {\n surfaceRef.current.recordActivate(card.cardId, \"keyboard\");\n return;\n }\n intentRef.current?.({\n type: \"activate\",\n cardId: card.cardId,\n source: \"keyboard\",\n });\n }, []);\n\n return {\n activeCardId,\n recognitionState,\n scrollLocked,\n bindCard,\n activateKeyboard,\n };\n}\n","/**\n * Deterministic pointer recognizer for the controlled hand view.\n *\n * The engine is independent from React: it consumes pointer events and a\n * caller-supplied callbacks bag, and produces semantic gesture events. It\n * owns no DOM, emits no `CardIntent`, and does not track the drag-lifecycle\n * `phase` — that responsibility lives in `CardDragSurface`. The engine only\n * recognizes `tap`, `previewStart`/`previewEnd`, `liftStart`/`liftMove`/\n * `liftEnd`/`liftCancel`, and a `horizontalBrowse` informational signal.\n *\n * The thresholds match\n * `docs/references/ui-sdk-mobile-hand-and-card-interactions.md`:\n *\n * | Threshold | Default |\n * | ------------------------- | ----------- |\n * | Press preview delay | `220ms` |\n * | Movement slop | `8px` |\n * | Axis bias | `1.25` |\n * | Drag lift distance | `28px` |\n *\n * Callers wire the engine's `handlePointerDown` / `handlePointerMove` /\n * `handlePointerUp` / `handlePointerCancel` to the matching DOM events on\n * each interactive card.\n */\n\nexport type HandInteractionPolicy = \"direct-activate\" | \"drag-to-target\";\n\n/**\n * Internal recognition state. Not exposed to consumers because drag-lifecycle\n * phases (`inspecting`/`dragging`/`settling`/`returning`) live in\n * `CardDragSurface`.\n */\nexport type CardPointerState =\n | { kind: \"idle\" }\n | { kind: \"pressing\"; pointerId: number; cardId: string; startedAt: number }\n | { kind: \"preview\"; pointerId: number; cardId: string }\n | { kind: \"horizontalBrowse\"; pointerId: number; cardId: string }\n | { kind: \"lifted\"; pointerId: number; cardId: string };\n\nexport interface PointerEngineThresholds {\n pressPreviewMs: number;\n movementSlopPx: number;\n axisBiasRatio: number;\n dragLiftDistancePx: number;\n}\n\nexport const DEFAULT_POINTER_THRESHOLDS: PointerEngineThresholds = {\n pressPreviewMs: 220,\n movementSlopPx: 8,\n axisBiasRatio: 1.25,\n dragLiftDistancePx: 28,\n};\n\nexport type AxisDecision = \"undecided\" | \"horizontal\" | \"upward\";\n\nexport function resolveAxis(\n dx: number,\n dy: number,\n thresholds: PointerEngineThresholds = DEFAULT_POINTER_THRESHOLDS,\n): AxisDecision {\n if (\n Math.abs(dx) < thresholds.movementSlopPx &&\n Math.abs(dy) < thresholds.movementSlopPx\n ) {\n return \"undecided\";\n }\n if (Math.abs(dx) > Math.abs(dy) * thresholds.axisBiasRatio)\n return \"horizontal\";\n if (-dy > Math.abs(dx) * thresholds.axisBiasRatio) return \"upward\";\n return \"undecided\";\n}\n\nexport interface PointerEngineCardSnapshot {\n cardId: string;\n /** Whether the runtime adapter says this card is interactive. */\n eligible: boolean;\n /** Whether the runtime adapter says this card is disabled. */\n disabled: boolean;\n}\n\nexport interface LiftStartEvent {\n cardId: string;\n pointerId: number;\n startX: number;\n startY: number;\n pointerX: number;\n pointerY: number;\n grabOffsetX: number;\n grabOffsetY: number;\n}\n\nexport interface LiftMoveEvent {\n cardId: string;\n pointerId: number;\n pointerX: number;\n pointerY: number;\n}\n\nexport interface LiftEndEvent {\n cardId: string;\n pointerId: number;\n pointerX: number;\n pointerY: number;\n}\n\nexport interface PointerEngineCallbacks {\n /**\n * Recognized clean tap (no movement, no preview). Source is `pointer` for\n * pointerup taps; the keyboard activation path is a separate caller method\n * (see `triggerKeyboardActivate`/`triggerKeyboardLift`).\n */\n onTap?: (cardId: string) => void;\n /** Long-press preview started. */\n onPreviewStart?: (cardId: string) => void;\n /** Preview ended (release or axis disqualification). */\n onPreviewEnd?: (cardId: string) => void;\n /** Vertical lift gesture began past the drag threshold. */\n onLiftStart?: (event: LiftStartEvent) => void;\n /** Pointer move while lifted. */\n onLiftMove?: (event: LiftMoveEvent) => void;\n /** Pointer release while lifted. */\n onLiftEnd?: (event: LiftEndEvent) => void;\n /** Lift was cancelled (pointer cancel/lost capture). */\n onLiftCancel?: (cardId: string) => void;\n /** Horizontal browse arbitration (informational). */\n onHorizontalBrowse?: (cardId: string) => void;\n /**\n * Called when the engine has captured the pointer and wants the host to\n * suppress scrolling. The host controls the `touch-action` value.\n */\n onLockScroll?: (locked: boolean) => void;\n /** Called whenever the recognition state transitions, for visual hints. */\n onStateChange?: (next: CardPointerState) => void;\n}\n\ninterface ActivePointer {\n cardId: string;\n pointerId: number;\n startedAt: number;\n startX: number;\n startY: number;\n lastX: number;\n lastY: number;\n axis: AxisDecision;\n /** Set when the long-press preview timer fires. */\n previewActive: boolean;\n}\n\nexport class HandPointerEngine {\n private readonly callbacks: PointerEngineCallbacks;\n private readonly thresholds: PointerEngineThresholds;\n private active: ActivePointer | null = null;\n private state: CardPointerState = { kind: \"idle\" };\n private previewTimer: ReturnType<typeof setTimeout> | null = null;\n private now: () => number;\n\n constructor(\n callbacks: PointerEngineCallbacks,\n thresholds: PointerEngineThresholds = DEFAULT_POINTER_THRESHOLDS,\n now: () => number = () => Date.now(),\n ) {\n this.callbacks = callbacks;\n this.thresholds = thresholds;\n this.now = now;\n }\n\n /** Returns the most recently emitted recognition state (test helper). */\n getState(): CardPointerState {\n return this.state;\n }\n\n dispose(): void {\n this.clearPreviewTimer();\n if (this.state.kind === \"lifted\") {\n this.callbacks.onLiftCancel?.(this.state.cardId);\n }\n this.active = null;\n this.transition({ kind: \"idle\" });\n this.callbacks.onLockScroll?.(false);\n }\n\n handlePointerDown(\n card: PointerEngineCardSnapshot,\n event: { pointerId: number; clientX: number; clientY: number },\n ): void {\n if (this.active) return;\n if (card.disabled) return;\n\n const startedAt = this.now();\n this.active = {\n cardId: card.cardId,\n pointerId: event.pointerId,\n startedAt,\n startX: event.clientX,\n startY: event.clientY,\n lastX: event.clientX,\n lastY: event.clientY,\n axis: \"undecided\",\n previewActive: false,\n };\n this.transition({\n kind: \"pressing\",\n pointerId: event.pointerId,\n cardId: card.cardId,\n startedAt,\n });\n this.schedulePreview(card);\n }\n\n handlePointerMove(\n card: PointerEngineCardSnapshot,\n event: { pointerId: number; clientX: number; clientY: number },\n ): void {\n const pointer = this.active;\n if (!pointer || pointer.pointerId !== event.pointerId) return;\n if (pointer.cardId !== card.cardId) return;\n\n pointer.lastX = event.clientX;\n pointer.lastY = event.clientY;\n\n const dx = event.clientX - pointer.startX;\n const dy = event.clientY - pointer.startY;\n const axis = resolveAxis(dx, dy, this.thresholds);\n if (axis !== \"undecided\") pointer.axis = axis;\n\n if (this.state.kind === \"lifted\") {\n this.callbacks.onLiftMove?.({\n cardId: pointer.cardId,\n pointerId: pointer.pointerId,\n pointerX: event.clientX,\n pointerY: event.clientY,\n });\n return;\n }\n\n if (this.state.kind === \"pressing\") {\n if (axis === \"horizontal\") {\n this.clearPreviewTimer();\n this.transition({\n kind: \"horizontalBrowse\",\n pointerId: pointer.pointerId,\n cardId: pointer.cardId,\n });\n this.callbacks.onHorizontalBrowse?.(pointer.cardId);\n return;\n }\n if (\n axis === \"upward\" &&\n card.eligible &&\n -dy >= this.thresholds.dragLiftDistancePx\n ) {\n this.clearPreviewTimer();\n this.beginLift(pointer, event.clientX, event.clientY);\n return;\n }\n return;\n }\n\n if (this.state.kind === \"preview\") {\n if (\n axis === \"upward\" &&\n card.eligible &&\n -dy >= this.thresholds.dragLiftDistancePx\n ) {\n this.callbacks.onPreviewEnd?.(card.cardId);\n pointer.previewActive = false;\n this.beginLift(pointer, event.clientX, event.clientY);\n return;\n }\n if (axis === \"horizontal\") {\n this.callbacks.onPreviewEnd?.(card.cardId);\n pointer.previewActive = false;\n this.transition({\n kind: \"horizontalBrowse\",\n pointerId: pointer.pointerId,\n cardId: pointer.cardId,\n });\n this.callbacks.onHorizontalBrowse?.(pointer.cardId);\n return;\n }\n return;\n }\n\n // horizontalBrowse — remain locked until release.\n }\n\n handlePointerUp(\n card: PointerEngineCardSnapshot,\n event: { pointerId: number; clientX: number; clientY: number },\n ): void {\n const pointer = this.active;\n if (!pointer || pointer.pointerId !== event.pointerId) return;\n if (pointer.cardId !== card.cardId) return;\n this.clearPreviewTimer();\n\n const dx = event.clientX - pointer.startX;\n const dy = event.clientY - pointer.startY;\n const isTap =\n pointer.axis === \"undecided\" &&\n !pointer.previewActive &&\n Math.abs(dx) < this.thresholds.movementSlopPx &&\n Math.abs(dy) < this.thresholds.movementSlopPx;\n\n if (this.state.kind === \"lifted\") {\n this.callbacks.onLiftEnd?.({\n cardId: pointer.cardId,\n pointerId: pointer.pointerId,\n pointerX: event.clientX,\n pointerY: event.clientY,\n });\n this.reset();\n return;\n }\n\n if (isTap) {\n if (card.eligible && !card.disabled) {\n this.callbacks.onTap?.(card.cardId);\n }\n this.reset();\n return;\n }\n\n if (pointer.previewActive) {\n this.callbacks.onPreviewEnd?.(card.cardId);\n }\n this.reset();\n }\n\n handlePointerCancel(card: PointerEngineCardSnapshot): void {\n const pointer = this.active;\n if (!pointer || pointer.cardId !== card.cardId) return;\n this.clearPreviewTimer();\n if (this.state.kind === \"lifted\") {\n this.callbacks.onLiftCancel?.(card.cardId);\n this.reset();\n return;\n }\n if (pointer.previewActive) {\n this.callbacks.onPreviewEnd?.(card.cardId);\n }\n this.reset();\n }\n\n /**\n * Programmatic reset of recognition state (e.g. after the surface commits\n * a keyboard lift externally). Does not emit callbacks.\n */\n resetRecognition(): void {\n this.clearPreviewTimer();\n this.active = null;\n this.callbacks.onLockScroll?.(false);\n this.transition({ kind: \"idle\" });\n }\n\n private beginLift(\n pointer: ActivePointer,\n clientX: number,\n clientY: number,\n ): void {\n this.callbacks.onLockScroll?.(true);\n const grabOffsetX = clientX - pointer.startX;\n const grabOffsetY = clientY - pointer.startY;\n this.transition({\n kind: \"lifted\",\n pointerId: pointer.pointerId,\n cardId: pointer.cardId,\n });\n this.callbacks.onLiftStart?.({\n cardId: pointer.cardId,\n pointerId: pointer.pointerId,\n startX: pointer.startX,\n startY: pointer.startY,\n pointerX: clientX,\n pointerY: clientY,\n grabOffsetX,\n grabOffsetY,\n });\n }\n\n private schedulePreview(card: PointerEngineCardSnapshot): void {\n this.clearPreviewTimer();\n this.previewTimer = setTimeout(() => {\n const pointer = this.active;\n if (!pointer || pointer.cardId !== card.cardId) return;\n if (pointer.axis !== \"undecided\") return;\n pointer.previewActive = true;\n this.callbacks.onPreviewStart?.(card.cardId);\n this.transition({\n kind: \"preview\",\n pointerId: pointer.pointerId,\n cardId: card.cardId,\n });\n }, this.thresholds.pressPreviewMs);\n }\n\n private clearPreviewTimer(): void {\n if (this.previewTimer !== null) {\n clearTimeout(this.previewTimer);\n this.previewTimer = null;\n }\n }\n\n private reset(): void {\n this.active = null;\n this.callbacks.onLockScroll?.(false);\n this.transition({ kind: \"idle\" });\n }\n\n private transition(next: CardPointerState): void {\n this.state = next;\n this.callbacks.onStateChange?.(next);\n }\n}\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\nimport { useDrag } from \"@use-gesture/react\";\nimport { clsx } from \"clsx\";\nimport { useIsMobile } from \"../hooks/useIsMobile.js\";\nimport { useThemeCssVars } from \"../theme/ThemeProvider.js\";\n\nexport type HandRole = \"primary\" | \"auxiliary\" | \"task\";\n\nexport interface MobileHandRegistration {\n id: string;\n zone: string;\n label: string;\n role: HandRole;\n order?: number;\n version: string;\n count: number;\n active: boolean;\n autoOpen: boolean;\n content: ReactNode;\n}\n\ninterface MobileHandTrayContextValue {\n registerHand: (hand: MobileHandRegistration) => () => void;\n}\n\nconst MobileHandTrayContext = createContext<MobileHandTrayContextValue | null>(\n null,\n);\n\n// Kept separate from the registration context on purpose: this value changes\n// whenever the tray opens/closes or hands (de)register, whereas `registerHand`\n// must stay referentially stable so `useRegisterMobileHand`'s effect does not\n// re-run and thrash registrations.\nconst MobileHandTrayStateContext = createContext<{ active: boolean }>({\n active: false,\n});\n\nconst ROLE_PRIORITY: Record<HandRole, number> = {\n task: 0,\n primary: 1,\n auxiliary: 2,\n};\n\nconst TRAY_CONTENT_ID = \"dreamboard-mobile-hand-tray\";\n\n/** Dock snap heights, ordered collapsed → tall. */\nconst DOCK_SNAPS = [\"peek\", \"raised\", \"expanded\"] as const;\ntype DockSnap = (typeof DOCK_SNAPS)[number];\nconst DOCK_SNAP_MAX_HEIGHT: Record<DockSnap, number | string> = {\n peek: 0,\n raised: \"min(52vh, 440px)\",\n expanded: \"82vh\",\n};\n\nexport function MobileHandTrayProvider({ children }: { children: ReactNode }) {\n const [handsById, setHandsById] = useState<\n ReadonlyMap<string, MobileHandRegistration>\n >(() => new Map());\n const isMobile = useIsMobile();\n const registerHand = useCallback((hand: MobileHandRegistration) => {\n setHandsById((current) => {\n const previous = current.get(hand.id);\n if (\n previous &&\n previous.zone === hand.zone &&\n previous.label === hand.label &&\n previous.role === hand.role &&\n previous.order === hand.order &&\n previous.version === hand.version &&\n previous.count === hand.count &&\n previous.active === hand.active &&\n previous.autoOpen === hand.autoOpen\n ) {\n return current;\n }\n const next = new Map(current);\n next.set(hand.id, hand);\n return next;\n });\n return () => {\n setHandsById((current) => {\n if (!current.has(hand.id)) return current;\n const next = new Map(current);\n next.delete(hand.id);\n return next;\n });\n };\n }, []);\n const value = useMemo<MobileHandTrayContextValue>(\n () => ({ registerHand }),\n [registerHand],\n );\n const hands = useMemo(\n () =>\n [...handsById.values()].sort(\n (a, b) =>\n (a.order ?? ROLE_PRIORITY[a.role]) -\n (b.order ?? ROLE_PRIORITY[b.role]) ||\n ROLE_PRIORITY[a.role] - ROLE_PRIORITY[b.role] ||\n a.label.localeCompare(b.label),\n ),\n [handsById],\n );\n\n const trayActive = isMobile && hands.length > 0;\n const stateValue = useMemo(() => ({ active: trayActive }), [trayActive]);\n\n return (\n <MobileHandTrayContext.Provider value={value}>\n <MobileHandTrayStateContext.Provider value={stateValue}>\n <div\n data-dreamboard-mobile-hand-shell=\"\"\n data-mobile-hand-count={hands.length}\n data-mobile-hand-tray-active={trayActive ? \"true\" : undefined}\n style={{\n minHeight: \"100%\",\n paddingBottom: trayActive\n ? \"calc(92px + env(safe-area-inset-bottom, 0px))\"\n : undefined,\n }}\n >\n {children}\n </div>\n {trayActive ? <MobileHandTray hands={hands} /> : null}\n </MobileHandTrayStateContext.Provider>\n </MobileHandTrayContext.Provider>\n );\n}\n\nexport function useRegisterMobileHand(hand: MobileHandRegistration): void {\n const context = useContext(MobileHandTrayContext);\n if (!context) {\n throw new Error(\n \"Generated hand surfaces must be rendered inside <UI.Root>; mobile hand tray registration is unavailable.\",\n );\n }\n useEffect(() => context.registerHand(hand), [context, hand]);\n}\n\n/**\n * Whether the mobile hand tray is currently presenting hands — i.e. the\n * viewport is below the mobile breakpoint and at least one primary/auxiliary\n * hand has registered. Authors can use this to drop redundant inline hand\n * chrome (labels, framing) that the tray already provides, instead of guessing\n * the breakpoint with a CSS media query. Returns `false` outside `<UI.Root>`.\n */\nexport function useMobileHandTrayActive(): boolean {\n return useContext(MobileHandTrayStateContext).active;\n}\n\nfunction MobileHandTray({\n hands,\n}: {\n hands: readonly MobileHandRegistration[];\n}) {\n // Snap height of the dock. `peek` is the collapsed handle bar; `raised` shows\n // the hand at an actionable height; `expanded` opens it tall for a long hand.\n // The dock is always mounted and never modal — there is no scrim, and only\n // the dock surface captures pointer events, so the board behind it stays\n // visible and interactive.\n const [snap, setSnap] = useState<DockSnap>(\"peek\");\n const open = snap !== \"peek\";\n const advanceSnap = useCallback((direction: 1 | -1) => {\n setSnap((current) => {\n const index = DOCK_SNAPS.indexOf(current);\n const next = Math.min(\n DOCK_SNAPS.length - 1,\n Math.max(0, index + direction),\n );\n return DOCK_SNAPS[next] ?? current;\n });\n }, []);\n const [activeId, setActiveId] = useState<string | null>(null);\n const themeCssVars = useThemeCssVars();\n\n const preferredHand =\n hands.find((hand) => hand.id === activeId) ??\n hands.find((hand) => hand.active) ??\n hands.find((hand) => hand.role === \"primary\") ??\n hands[0] ??\n null;\n const selectedHand =\n hands.find((hand) => hand.id === activeId) ?? preferredHand;\n\n useEffect(() => {\n if (!preferredHand) {\n setActiveId(null);\n return;\n }\n setActiveId((current) =>\n current && hands.some((hand) => hand.id === current)\n ? current\n : preferredHand.id,\n );\n }, [hands, preferredHand]);\n\n // Auto-raise to the actionable height when it becomes this seat's turn to\n // act, and settle back to the peek when the turn passes. We only toggle on\n // the active transition, so a manual expand/collapse sticks until the turn\n // changes.\n const active = selectedHand?.active ?? false;\n const prevActiveRef = useRef(false);\n useEffect(() => {\n if (active !== prevActiveRef.current) {\n prevActiveRef.current = active;\n setSnap(active ? \"raised\" : \"peek\");\n }\n }, [active]);\n\n // Swipe the handle up to expand a step (peek → raised → expanded), down to\n // collapse a step. Taps fall through to the handle's onClick toggle\n // (filterTaps), and velocity lets a quick flick advance even on a short drag.\n const bindDrag = useDrag(\n ({ movement: [, my], velocity: [, vy], last }) => {\n if (!last) return;\n if (my < -24 || (my < 0 && vy > 0.4)) advanceSnap(1);\n else if (my > 24 || (my > 0 && vy > 0.4)) advanceSnap(-1);\n },\n { axis: \"y\", filterTaps: true },\n );\n\n if (!selectedHand) return null;\n\n const activeBadges = hands.filter(\n (hand) => hand.id !== selectedHand.id && hand.active,\n );\n\n return (\n <div\n data-dreamboard-mobile-hand-tray=\"\"\n data-state={snap}\n data-active-hand={selectedHand.id}\n style={{\n ...themeCssVars,\n position: \"fixed\",\n left: \"env(safe-area-inset-left, 0px)\",\n right: \"env(safe-area-inset-right, 0px)\",\n bottom: 0,\n zIndex: 900,\n display: \"flex\",\n justifyContent: \"center\",\n // Non-modal: the wrapper ignores pointers so taps land on the board;\n // only the dock panel below opts back in.\n pointerEvents: \"none\",\n }}\n >\n <div\n className=\"flex w-full flex-col overflow-hidden rounded-t-2xl\"\n style={{\n pointerEvents: \"auto\",\n maxWidth: \"min(40rem, 100%)\",\n background: \"var(--background, #fdfbf7)\",\n color: \"var(--foreground, #2d2d2d)\",\n borderTop: \"1px solid var(--border, rgba(45,45,45,0.18))\",\n borderLeft: \"1px solid var(--border, rgba(45,45,45,0.10))\",\n borderRight: \"1px solid var(--border, rgba(45,45,45,0.10))\",\n boxShadow:\n \"0 -18px 48px -22px rgba(45,45,45,0.30), 0 -6px 18px -16px rgba(45,45,45,0.20)\",\n }}\n >\n {/* Handle + summary bar — drag or tap to toggle peek/open. */}\n <button\n type=\"button\"\n {...bindDrag()}\n onClick={() =>\n setSnap((value) => (value === \"peek\" ? \"raised\" : \"peek\"))\n }\n aria-controls={TRAY_CONTENT_ID}\n aria-expanded={open}\n data-dreamboard-mobile-hand-trigger=\"\"\n data-hand-role={selectedHand.role}\n data-active-badges={activeBadges.length || undefined}\n className=\"flex w-full flex-col items-stretch gap-1.5 px-4 pb-2 pt-2 text-left\"\n style={{\n touchAction: \"none\",\n background: \"transparent\",\n border: 0,\n cursor: \"pointer\",\n }}\n >\n <span\n aria-hidden\n className=\"mx-auto h-1.5 w-10 rounded-full\"\n style={{ background: \"rgba(45,45,45,0.28)\" }}\n />\n <span className=\"flex items-center justify-between gap-2\">\n <span className=\"flex min-w-0 items-center gap-2 text-sm font-semibold\">\n <span className=\"truncate\">{selectedHand.label}</span>\n <span\n className=\"rounded-full px-2 py-0.5 text-xs font-bold\"\n style={{ background: \"rgba(45,45,45,0.08)\" }}\n >\n {selectedHand.count}\n </span>\n {active ? (\n <span className=\"rounded-full bg-amber-400 px-2 py-0.5 text-[10px] font-bold uppercase tracking-wide text-amber-950\">\n your turn\n </span>\n ) : null}\n </span>\n {activeBadges.length > 0 ? (\n <span\n aria-label={`${activeBadges.length} other active hand sections`}\n className=\"inline-flex min-w-5 items-center justify-center rounded-full bg-red-500 px-1.5 text-xs font-bold text-white\"\n >\n {activeBadges.length}\n </span>\n ) : null}\n </span>\n </button>\n\n {/* Collapsible body — kept mounted at the peek (clipped to zero height\n and made inert) so raising the dock never remounts the hand or\n loses scroll position, and so the auto-raise can animate. The body\n is the scroll container, so the action slot's sticky footer pins to\n its bottom edge. */}\n <div\n id={TRAY_CONTENT_ID}\n role=\"region\"\n aria-label={selectedHand.label}\n data-state={snap}\n inert={open ? undefined : true}\n className=\"overscroll-contain\"\n style={{\n maxHeight: DOCK_SNAP_MAX_HEIGHT[snap],\n overflowY: open ? \"auto\" : \"hidden\",\n transition: \"max-height 240ms ease\",\n }}\n >\n {hands.length > 1 ? (\n <div\n role=\"tablist\"\n aria-label=\"Hand sections\"\n className=\"flex gap-2 overflow-x-auto px-4 pb-2 pt-1 [scrollbar-width:none]\"\n >\n {hands.map((hand) => (\n <button\n key={hand.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={hand.id === selectedHand.id}\n data-active={hand.active || undefined}\n data-hand-role={hand.role}\n onClick={() => setActiveId(hand.id)}\n className={clsx(\n \"shrink-0 rounded-full border px-3 py-1 text-sm font-semibold\",\n hand.id === selectedHand.id\n ? \"border-slate-900 bg-white text-slate-950\"\n : \"border-slate-300 bg-white/60 text-slate-600\",\n hand.active && hand.id !== selectedHand.id\n ? \"ring-2 ring-red-400\"\n : null,\n )}\n >\n {hand.label} ({hand.count})\n </button>\n ))}\n </div>\n ) : null}\n <div\n className=\"px-3 pt-2 sm:px-4\"\n style={{\n paddingBottom: \"calc(20px + env(safe-area-inset-bottom, 0px))\",\n }}\n >\n {selectedHand.content}\n </div>\n </div>\n </div>\n </div>\n );\n}\n","/**\n * Central game board area for active game components (tricks, played\n * cards, zones, etc.).\n *\n * Visual chrome (frame, empty placeholder, card entrance/exit) is\n * sourced from the active {@link useTheme} so the play area re-skins\n * with the rest of the shell.\n */\n\nimport { motion, AnimatePresence } from \"framer-motion\";\nimport { clsx } from \"clsx\";\nimport { CardFace, type CardFaceProps, type ViewCard } from \"./Card.js\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\nimport { chipStyle } from \"../theme/derive.js\";\n\nexport interface PlayAreaProps<CardData extends ViewCard = ViewCard> {\n cards: readonly CardData[];\n filter?: (card: CardData) => boolean;\n cardSize?: CardFaceProps[\"size\"];\n renderCard?: CardFaceProps<CardData>[\"renderContent\"];\n layout?: \"grid\" | \"row\";\n interactive?: boolean;\n onCardClick?: (cardId: string) => void;\n \"aria-label\"?: string;\n className?: string;\n}\n\n/**\n * @example\n * ```tsx\n * <PlayArea cards={trickCards} layout=\"row\" renderCard={(card) => <PlayingCard card={card} />} />\n * ```\n */\nexport function PlayArea<CardData extends ViewCard = ViewCard>({\n cards,\n filter,\n cardSize = \"md\",\n renderCard,\n layout = \"row\",\n interactive = false,\n onCardClick,\n \"aria-label\": ariaLabel = \"Play area\",\n className,\n}: PlayAreaProps<CardData>) {\n const theme = useTheme();\n const reducedMotion = theme.motion.reducedMotion === \"true\";\n const visibleCards = filter ? cards.filter(filter) : cards;\n\n const layoutClasses = {\n grid: \"grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-3 sm:gap-6\",\n row: \"flex flex-wrap items-center justify-center gap-3 sm:gap-6\",\n };\n\n return (\n <div\n className={clsx(\n \"relative w-full min-h-[200px] sm:min-h-[300px] p-6 sm:p-8\",\n className,\n )}\n style={{\n background: theme.semantic.surface.inset,\n border: `2px dashed ${theme.semantic.border.default}`,\n borderRadius: theme.radius.hud,\n fontFamily: theme.typography.fontFamily.body,\n color: theme.semantic.text.primary,\n }}\n role=\"region\"\n aria-label={`${ariaLabel} - ${visibleCards.length} item${visibleCards.length !== 1 ? \"s\" : \"\"}`}\n >\n <AnimatePresence mode=\"popLayout\">\n {visibleCards.length === 0 ? (\n <motion.div\n className=\"flex items-center justify-center h-full absolute inset-0 pointer-events-none\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n role=\"status\"\n aria-live=\"polite\"\n >\n <div\n style={{\n ...chipStyle(theme, { variant: \"warning\", size: \"md\" }),\n fontSize: theme.typography.fontSize.md,\n paddingBlock: theme.space[2],\n paddingInline: theme.space[4],\n }}\n >\n No cards in play\n </div>\n </motion.div>\n ) : (\n <div className={layoutClasses[layout]}>\n {visibleCards.map((card, index) => (\n <motion.div\n key={card.id}\n layout={!reducedMotion}\n initial={\n reducedMotion\n ? { opacity: 0, scale: 1 }\n : { opacity: 0, scale: 0.8 }\n }\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.8 }}\n transition={{\n type: \"spring\",\n stiffness: 260,\n damping: 20,\n delay: reducedMotion ? 0 : index * 0.05,\n }}\n >\n {interactive && onCardClick ? (\n <button\n type=\"button\"\n aria-label={card.name ?? `Card ${card.id}`}\n onClick={() => onCardClick(card.id)}\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onCardClick(card.id);\n }\n }}\n className=\"border-0 bg-transparent p-0 cursor-pointer focus-visible:outline-none\"\n style={{ all: \"unset\", cursor: \"pointer\" }}\n >\n <CardFace\n card={card}\n size={cardSize}\n renderContent={renderCard}\n />\n </button>\n ) : (\n <CardFace\n card={card}\n size={cardSize}\n renderContent={renderCard}\n disabled={!interactive}\n />\n )}\n </motion.div>\n ))}\n </div>\n )}\n </AnimatePresence>\n </div>\n );\n}\n","/**\n * GameSkeleton - Loading state component\n *\n * Displays animated placeholders while game content loads\n */\n\nimport { motion } from \"framer-motion\";\nimport { clsx } from \"clsx\";\nimport { Loader2 } from \"lucide-react\";\n\nconst CARD_SKELETON_KEYS = [\"card-1\", \"card-2\", \"card-3\", \"card-4\", \"card-5\"];\nconst PLAYER_SKELETON_KEYS = [\"player-1\", \"player-2\", \"player-3\", \"player-4\"];\nconst HAND_SKELETON_KEYS = [\n \"hand-card-1\",\n \"hand-card-2\",\n \"hand-card-3\",\n \"hand-card-4\",\n \"hand-card-5\",\n \"hand-card-6\",\n];\n\nexport interface GameSkeletonProps {\n variant?: \"default\" | \"cards\" | \"players\" | \"minimal\";\n message?: string;\n className?: string;\n}\nfunction SkeletonBox({\n className,\n animate = true,\n}: {\n className?: string;\n animate?: boolean;\n}) {\n return (\n <motion.div\n className={clsx(\"bg-slate-200 rounded\", className)}\n animate={\n animate\n ? {\n opacity: [0.5, 1, 0.5],\n }\n : undefined\n }\n transition={{\n duration: 1.5,\n repeat: Infinity,\n ease: \"easeInOut\",\n }}\n aria-hidden=\"true\"\n />\n );\n}\n\nfunction CardSkeleton({ size = \"md\" }: { size?: \"sm\" | \"md\" | \"lg\" }) {\n const sizeClasses = {\n sm: \"w-16 h-24 sm:w-20 sm:h-28\",\n md: \"w-20 h-32 sm:w-24 sm:h-36\",\n lg: \"w-24 h-36 sm:w-32 sm:h-48\",\n };\n\n return (\n <motion.div\n className={clsx(\n \"rounded-lg sm:rounded-xl overflow-hidden\",\n sizeClasses[size],\n )}\n initial={{ opacity: 0, y: 20 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ type: \"spring\", stiffness: 300, damping: 25 }}\n >\n <SkeletonBox className=\"w-full h-full\" />\n </motion.div>\n );\n}\n\nfunction PlayerSkeleton() {\n return (\n <div className=\"flex items-center gap-3 p-3 bg-white/80 rounded-xl border-2 border-slate-200\">\n <SkeletonBox className=\"w-12 h-12 sm:w-14 sm:h-14 rounded-full\" />\n <div className=\"flex-1 space-y-2\">\n <SkeletonBox className=\"h-4 w-24 sm:w-32\" />\n <SkeletonBox className=\"h-3 w-16 sm:w-20\" />\n </div>\n </div>\n );\n}\n\nexport function GameSkeleton({\n variant = \"default\",\n message = \"Loading game...\",\n className,\n}: GameSkeletonProps) {\n if (variant === \"minimal\") {\n return (\n <div\n className={clsx(\n \"flex flex-col items-center justify-center min-h-screen p-8 bg-gradient-to-br from-slate-50 to-slate-100\",\n className,\n )}\n role=\"status\"\n aria-live=\"polite\"\n aria-label={message}\n >\n <motion.div\n animate={{ rotate: 360 }}\n transition={{ duration: 1, repeat: Infinity, ease: \"linear\" }}\n >\n <Loader2 size={48} className=\"text-blue-500\" aria-hidden=\"true\" />\n </motion.div>\n <motion.p\n className=\"mt-4 text-slate-600 text-lg font-medium\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ delay: 0.2 }}\n >\n {message}\n </motion.p>\n </div>\n );\n }\n\n if (variant === \"cards\") {\n return (\n <div\n className={clsx(\n \"flex flex-col items-center justify-center min-h-screen p-4 sm:p-8\",\n className,\n )}\n role=\"status\"\n aria-live=\"polite\"\n aria-label={message}\n >\n <div className=\"flex gap-2 sm:gap-4 mb-8\">\n {CARD_SKELETON_KEYS.map((key, i) => (\n <motion.div\n key={key}\n initial={{ opacity: 0, y: 20 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ delay: i * 0.1 }}\n >\n <CardSkeleton />\n </motion.div>\n ))}\n </div>\n <motion.p\n className=\"text-slate-600 text-sm sm:text-base\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ delay: 0.5 }}\n >\n {message}\n </motion.p>\n </div>\n );\n }\n\n if (variant === \"players\") {\n return (\n <div\n className={clsx(\n \"flex flex-col items-center justify-center min-h-screen p-4 sm:p-8\",\n className,\n )}\n role=\"status\"\n aria-live=\"polite\"\n aria-label={message}\n >\n <div className=\"w-full max-w-md space-y-4 mb-8\">\n {PLAYER_SKELETON_KEYS.map((key, i) => (\n <motion.div\n key={key}\n initial={{ opacity: 0, x: -20 }}\n animate={{ opacity: 1, x: 0 }}\n transition={{ delay: i * 0.1 }}\n >\n <PlayerSkeleton />\n </motion.div>\n ))}\n </div>\n <motion.p\n className=\"text-slate-600 text-sm sm:text-base\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ delay: 0.4 }}\n >\n {message}\n </motion.p>\n </div>\n );\n }\n\n // Default variant - complete game layout\n return (\n <div\n className={clsx(\n \"min-h-screen p-4 sm:p-8 bg-gradient-to-br from-slate-50 to-slate-100\",\n className,\n )}\n role=\"status\"\n aria-live=\"polite\"\n aria-label={message}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between mb-6 sm:mb-8\">\n <SkeletonBox className=\"h-8 w-32 sm:w-48\" />\n <SkeletonBox className=\"h-8 w-20 sm:w-32\" />\n </div>\n\n {/* Players */}\n <div className=\"grid grid-cols-2 lg:grid-cols-4 gap-3 sm:gap-4 mb-6 sm:mb-8\">\n {PLAYER_SKELETON_KEYS.map((key, i) => (\n <motion.div\n key={key}\n initial={{ opacity: 0, scale: 0.9 }}\n animate={{ opacity: 1, scale: 1 }}\n transition={{ delay: i * 0.1 }}\n >\n <PlayerSkeleton />\n </motion.div>\n ))}\n </div>\n\n {/* Play area */}\n <div className=\"mb-6 sm:mb-8\">\n <SkeletonBox className=\"w-full h-48 sm:h-64 rounded-2xl\" />\n </div>\n\n {/* Hand */}\n <div className=\"flex justify-center gap-2 sm:gap-4\">\n {HAND_SKELETON_KEYS.map((key, i) => (\n <motion.div\n key={key}\n initial={{ opacity: 0, y: 20 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ delay: 0.4 + i * 0.05 }}\n >\n <CardSkeleton />\n </motion.div>\n ))}\n </div>\n\n {/* Loading message */}\n <motion.div\n className=\"flex items-center justify-center mt-8\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ delay: 0.8 }}\n >\n <Loader2\n size={24}\n className=\"text-blue-500 animate-spin mr-3\"\n aria-hidden=\"true\"\n />\n <p className=\"text-slate-600 text-sm sm:text-base font-medium\">\n {message}\n </p>\n </motion.div>\n </div>\n );\n}\n","/**\n * Plugin-internal toast notification system.\n *\n * `<ToastProvider>` exposes `<Toast.Actions>` for game-specific feedback\n * (\"Resource gained\", \"Card discarded\", \"Tip: rotate the board with R\", …).\n * It is intentionally NOT wired to the host notification stream:\n * `YOUR_TURN`, `PROMPT_OPENED` and `ACTION_REJECTED` events are owned\n * by the product host runtime's `<HostFeedbackToaster>` and must\n * not be mirrored from inside the plugin tree.\n */\n\nimport { motion, AnimatePresence } from \"framer-motion\";\nimport { X, CheckCircle, AlertCircle, Info, AlertTriangle } from \"lucide-react\";\nimport { Alert, AlertDescription } from \"../internal/ui/alert.js\";\nimport {\n createContext,\n useContext,\n useState,\n useCallback,\n type ReactNode,\n} from \"react\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\nimport { intentForVariant, type ButtonVariant } from \"../theme/derive.js\";\nimport type { Theme } from \"../theme/tokens.js\";\nimport { ThemedButton } from \"./ThemedButton.js\";\n\nexport type ToastType = \"success\" | \"error\" | \"info\" | \"warning\";\n\nexport interface ToastNotification {\n id: string;\n type: ToastType;\n message: string;\n duration?: number;\n}\n\ninterface ToastContextValue {\n toasts: ToastNotification[];\n show: (message: string, type?: ToastType, duration?: number) => void;\n dismiss: (id: string) => void;\n success: (message: string, duration?: number) => void;\n error: (message: string, duration?: number) => void;\n info: (message: string, duration?: number) => void;\n warning: (message: string, duration?: number) => void;\n}\n\nconst ToastContext = createContext<ToastContextValue | null>(null);\n\nexport type ToastActionsValue = ToastContextValue;\n\nexport interface ToastProviderProps {\n children: ReactNode;\n}\n\nexport function ToastProvider({ children }: ToastProviderProps) {\n const [toasts, setToasts] = useState<ToastNotification[]>([]);\n\n const show = useCallback(\n (message: string, type: ToastType = \"info\", duration = 3000) => {\n const id = `toast-${Date.now()}-${Math.random()}`;\n const toast: ToastNotification = { id, type, message, duration };\n\n setToasts((prev) => {\n // Dedup by `(type, message)` so a fast burst of identical\n // toasts collapses to one visible toast instead of stacking\n // and producing the flicker effect (toast-1 dismisses while\n // toast-2 mounts → user sees a flash). Keep the existing\n // entry untouched so its dismiss timer continues.\n if (\n prev.some((item) => item.type === type && item.message === message)\n ) {\n return prev;\n }\n return [...prev, toast];\n });\n\n if (duration > 0) {\n setTimeout(() => {\n setToasts((prev) => prev.filter((t) => t.id !== id));\n }, duration);\n }\n },\n [],\n );\n\n const dismiss = useCallback((id: string) => {\n setToasts((prev) => prev.filter((t) => t.id !== id));\n }, []);\n\n const success = useCallback(\n (message: string, duration?: number) => show(message, \"success\", duration),\n [show],\n );\n const error = useCallback(\n (message: string, duration?: number) => show(message, \"error\", duration),\n [show],\n );\n const info = useCallback(\n (message: string, duration?: number) => show(message, \"info\", duration),\n [show],\n );\n const warning = useCallback(\n (message: string, duration?: number) => show(message, \"warning\", duration),\n [show],\n );\n\n return (\n <ToastContext.Provider\n value={{ toasts, show, dismiss, success, error, info, warning }}\n >\n {children}\n <ToastContainer toasts={toasts} onDismiss={dismiss} />\n </ToastContext.Provider>\n );\n}\n\nexport function useToast() {\n const context = useContext(ToastContext);\n if (!context) {\n throw new Error(\"useToast must be used within ToastProvider\");\n }\n return context;\n}\n\nexport interface ToastActionsProps {\n children: (actions: ToastActionsValue) => ReactNode;\n}\n\nexport function ToastActions({ children }: ToastActionsProps) {\n return <>{children(useToast())}</>;\n}\n\nexport const Toast = {\n Actions: ToastActions,\n} as const;\n\nfunction ToastContainer({\n toasts,\n onDismiss,\n}: {\n toasts: ToastNotification[];\n onDismiss: (id: string) => void;\n}) {\n return (\n <div\n className=\"fixed bottom-4 right-4 z-50 flex flex-col gap-2 pointer-events-none\"\n role=\"region\"\n aria-live=\"polite\"\n aria-label=\"Notifications\"\n >\n <AnimatePresence>\n {toasts.map((toast) => (\n <ToastItem key={toast.id} toast={toast} onDismiss={onDismiss} />\n ))}\n </AnimatePresence>\n </div>\n );\n}\n\nconst TOAST_ICONS = {\n success: CheckCircle,\n error: AlertCircle,\n info: Info,\n warning: AlertTriangle,\n} as const satisfies Record<ToastType, unknown>;\n\nconst TOAST_VARIANT: Record<\n ToastType,\n Exclude<ButtonVariant, \"ghost\" | \"secondary\">\n> = {\n success: \"success\",\n error: \"danger\",\n info: \"info\",\n warning: \"warning\",\n};\n\nfunction toastSurfaceStyle(theme: Theme, type: ToastType): React.CSSProperties {\n const intent = intentForVariant(theme, TOAST_VARIANT[type]);\n return {\n minWidth: 280,\n maxWidth: 400,\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: theme.space[3],\n padding: theme.space[4],\n background: intent.soft,\n color: intent.onSoft,\n border: `2px solid ${intent.border}`,\n borderRadius: theme.radius.lg,\n boxShadow: theme.elevation.lifted,\n backdropFilter: \"blur(4px)\",\n WebkitBackdropFilter: \"blur(4px)\",\n fontFamily: theme.typography.fontFamily.body,\n };\n}\n\nfunction ToastItem({\n toast,\n onDismiss,\n}: {\n toast: ToastNotification;\n onDismiss: (id: string) => void;\n}) {\n const theme = useTheme();\n const reducedMotion = theme.motion.reducedMotion === \"true\";\n const Icon = TOAST_ICONS[toast.type];\n const intent = intentForVariant(theme, TOAST_VARIANT[toast.type]);\n const surfaceStyle = toastSurfaceStyle(theme, toast.type);\n\n return (\n <motion.div\n style={{ pointerEvents: \"auto\" }}\n initial={\n reducedMotion ? { opacity: 0 } : { opacity: 0, y: 20, scale: 0.9 }\n }\n animate={reducedMotion ? { opacity: 1 } : { opacity: 1, y: 0, scale: 1 }}\n exit={reducedMotion ? { opacity: 0 } : { opacity: 0, x: 100, scale: 0.9 }}\n transition={{ type: \"spring\", stiffness: 300, damping: 25 }}\n >\n <Alert\n variant={toast.type === \"error\" ? \"destructive\" : \"default\"}\n style={surfaceStyle}\n >\n <Icon\n size={20}\n style={{\n marginTop: 2,\n flexShrink: 0,\n color: intent.solid,\n }}\n aria-hidden=\"true\"\n />\n\n <AlertDescription\n style={{\n flex: 1,\n fontSize: theme.typography.fontSize.sm,\n fontWeight: theme.typography.fontWeight.medium,\n lineHeight: theme.typography.lineHeight.relaxed,\n color: intent.onSoft,\n }}\n >\n {toast.message}\n </AlertDescription>\n\n <ThemedButton\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => onDismiss(toast.id)}\n style={{\n height: 28,\n width: 28,\n flexShrink: 0,\n borderRadius: theme.radius.pill,\n color: intent.onSoft,\n }}\n aria-label=\"Close notification\"\n >\n <X size={16} aria-hidden=\"true\" />\n </ThemedButton>\n </Alert>\n </motion.div>\n );\n}\n","import * as React from \"react\";\nimport { cn } from \"./utils.js\";\n\nexport interface AlertProps extends React.ComponentProps<\"div\"> {\n variant?: \"default\" | \"destructive\";\n}\n\nexport function Alert({\n className,\n variant = \"default\",\n ...props\n}: AlertProps) {\n return (\n <div\n data-slot=\"alert\"\n role=\"alert\"\n className={cn(\n \"relative grid w-full grid-cols-[0_1fr] items-start gap-y-0.5 rounded-lg border px-4 py-3 text-sm has-[>svg]:grid-cols-[1rem_1fr] has-[>svg]:gap-x-3 [&>svg]:translate-y-0.5\",\n variant === \"destructive\" && \"border-red-300 text-red-800\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport function AlertTitle({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-title\"\n className={cn(\"col-start-2 font-medium tracking-tight\", className)}\n {...props}\n />\n );\n}\n\nexport function AlertDescription({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-description\"\n className={cn(\"col-start-2 text-sm opacity-90\", className)}\n {...props}\n />\n );\n}\n","/**\n * ErrorBoundary component\n *\n * Catches React errors and displays a fallback UI.\n *\n * Visuals are sourced from the public `--db-*` theme variables so that\n * mounting under {@link ThemeProvider} reskins the fallback automatically.\n * Fallback values match the calm `tabletop` preset, so the surface still\n * reads correctly when the boundary catches an error before any provider\n * could mount (a common case during startup).\n */\n\nimport {\n Component,\n type CSSProperties,\n type ReactNode,\n type ErrorInfo,\n} from \"react\";\nimport { AlertTriangle, RefreshCw } from \"lucide-react\";\nimport { cssVarOr } from \"../theme/css-vars.js\";\n\nexport interface ErrorBoundaryProps {\n children: ReactNode;\n fallback?: (error: Error, reset: () => void) => ReactNode;\n onError?: (error: Error, errorInfo: ErrorInfo) => void;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n}\n\nexport class ErrorBoundary extends Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false, error: null };\n }\n\n static getDerivedStateFromError(error: Error): ErrorBoundaryState {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo): void {\n // eslint-disable-next-line no-console\n console.error(\"[ErrorBoundary] Caught error:\", error, errorInfo);\n this.props.onError?.(error, errorInfo);\n }\n\n handleReset = (): void => {\n this.setState({ hasError: false, error: null });\n };\n\n render(): ReactNode {\n if (this.state.hasError && this.state.error) {\n if (this.props.fallback) {\n return this.props.fallback(this.state.error, this.handleReset);\n }\n\n return (\n <DefaultErrorFallback\n error={this.state.error}\n onReset={this.handleReset}\n />\n );\n }\n\n return this.props.children;\n }\n}\n\n/**\n * Stable, theme-driven default tokens for the fallback UI.\n *\n * Each value resolves through `--db-*` theme variables when a\n * {@link ThemeProvider} ancestor is present, and falls back to the\n * tabletop preset's calm baseline when the boundary renders standalone.\n */\nconst FALLBACK_TOKENS = {\n appSurface: cssVarOr(\"#fdfbf7\", \"semantic\", \"surface\", \"app\"),\n panelSurface: cssVarOr(\"#ffffff\", \"semantic\", \"surface\", \"card\"),\n insetSurface: cssVarOr(\"#f8fafc\", \"semantic\", \"surface\", \"inset\"),\n textPrimary: cssVarOr(\"#1f2937\", \"semantic\", \"text\", \"primary\"),\n textMuted: cssVarOr(\"#475569\", \"semantic\", \"text\", \"muted\"),\n textDisabled: cssVarOr(\"#94a3b8\", \"semantic\", \"text\", \"disabled\"),\n borderSubtle: cssVarOr(\"#e2e8f0\", \"semantic\", \"border\", \"subtle\"),\n borderDefault: cssVarOr(\"#cbd5e1\", \"semantic\", \"border\", \"default\"),\n dangerSoft: cssVarOr(\"#fee2e2\", \"semantic\", \"intent\", \"danger\", \"soft\"),\n dangerBorder: cssVarOr(\"#991b1b\", \"semantic\", \"intent\", \"danger\", \"border\"),\n dangerOnSoft: cssVarOr(\"#991b1b\", \"semantic\", \"intent\", \"danger\", \"onSoft\"),\n primarySolid: cssVarOr(\"#0f172a\", \"semantic\", \"intent\", \"primary\", \"solid\"),\n primaryOn: cssVarOr(\"#ffffff\", \"semantic\", \"intent\", \"primary\", \"on\"),\n primaryBorder: cssVarOr(\"#0f172a\", \"semantic\", \"intent\", \"primary\", \"border\"),\n fontBody: cssVarOr(\n \"system-ui, -apple-system, Segoe UI, Roboto, sans-serif\",\n \"typography\",\n \"fontFamily\",\n \"body\",\n ),\n fontDisplay: cssVarOr(\n \"system-ui, -apple-system, Segoe UI, Roboto, sans-serif\",\n \"typography\",\n \"fontFamily\",\n \"display\",\n ),\n fontMono: cssVarOr(\n \"ui-monospace, SFMono-Regular, monospace\",\n \"typography\",\n \"fontFamily\",\n \"mono\",\n ),\n radiusMd: cssVarOr(\"8px\", \"radius\", \"md\"),\n radiusLg: cssVarOr(\"12px\", \"radius\", \"lg\"),\n radiusPill: cssVarOr(\"999px\", \"radius\", \"pill\"),\n elevationRest: cssVarOr(\n \"0 4px 12px rgba(15, 23, 42, 0.08)\",\n \"elevation\",\n \"rest\",\n ),\n} as const;\n\nexport function DefaultErrorFallback({\n error,\n onReset,\n}: {\n error: Error;\n onReset: () => void;\n}) {\n const t = FALLBACK_TOKENS;\n const styles = {\n shell: {\n alignItems: \"center\",\n background: t.appSurface,\n boxSizing: \"border-box\",\n color: t.textPrimary,\n display: \"flex\",\n fontFamily: t.fontBody,\n justifyContent: \"center\",\n minHeight: \"100vh\",\n padding: \"24px\",\n },\n panel: {\n background: t.panelSurface,\n border: `1px solid ${t.borderSubtle}`,\n borderRadius: t.radiusLg,\n boxShadow: t.elevationRest,\n boxSizing: \"border-box\",\n maxWidth: \"520px\",\n padding: \"28px\",\n width: \"100%\",\n },\n iconWrap: {\n alignItems: \"center\",\n background: t.dangerSoft,\n border: `1px solid ${t.dangerBorder}`,\n borderRadius: t.radiusPill,\n display: \"flex\",\n height: \"56px\",\n justifyContent: \"center\",\n marginBottom: \"18px\",\n width: \"56px\",\n },\n eyebrow: {\n color: t.dangerOnSoft,\n fontSize: \"12px\",\n fontWeight: 700,\n letterSpacing: \"0.08em\",\n margin: \"0 0 8px\",\n textTransform: \"uppercase\",\n },\n title: {\n color: t.textPrimary,\n fontFamily: t.fontDisplay,\n fontSize: \"28px\",\n fontWeight: 800,\n lineHeight: 1.1,\n margin: \"0 0 12px\",\n },\n body: {\n color: t.textMuted,\n fontSize: \"15px\",\n lineHeight: 1.5,\n margin: \"0 0 20px\",\n },\n details: {\n marginBottom: \"22px\",\n },\n summary: {\n color: t.textPrimary,\n cursor: \"pointer\",\n fontSize: \"14px\",\n fontWeight: 600,\n marginBottom: \"8px\",\n },\n pre: {\n background: t.insetSurface,\n border: `1px solid ${t.borderDefault}`,\n borderRadius: t.radiusMd,\n color: t.textMuted,\n fontFamily: t.fontMono,\n fontSize: \"12px\",\n lineHeight: 1.45,\n margin: 0,\n maxHeight: \"180px\",\n overflow: \"auto\",\n padding: \"12px\",\n whiteSpace: \"pre-wrap\",\n },\n button: {\n alignItems: \"center\",\n background: t.primarySolid,\n border: `1px solid ${t.primaryBorder}`,\n borderRadius: t.radiusMd,\n color: t.primaryOn,\n cursor: \"pointer\",\n display: \"inline-flex\",\n fontFamily: t.fontBody,\n fontSize: \"15px\",\n fontWeight: 700,\n gap: \"8px\",\n justifyContent: \"center\",\n padding: \"12px 16px\",\n width: \"100%\",\n },\n } satisfies Record<string, CSSProperties>;\n\n return (\n <div\n data-dreamboard-error-fallback=\"\"\n style={styles.shell}\n role=\"alert\"\n aria-live=\"assertive\"\n >\n <div style={styles.panel}>\n <div style={styles.iconWrap}>\n <AlertTriangle\n size={28}\n color={t.dangerBorder}\n strokeWidth={2.25}\n aria-hidden=\"true\"\n />\n </div>\n\n <p style={styles.eyebrow}>Runtime error</p>\n\n <h1 style={styles.title}>Game failed to start</h1>\n\n <p style={styles.body}>\n The game encountered an error and couldn't continue. You can try\n reloading to start fresh.\n </p>\n\n <details style={styles.details}>\n <summary style={styles.summary}>Technical details</summary>\n <pre style={styles.pre}>\n {error.message}\n {error.stack && (\n <>\n {\"\\n\\n\"}\n {error.stack}\n </>\n )}\n </pre>\n </details>\n\n <button type=\"button\" onClick={onReset} style={styles.button}>\n <RefreshCw size={18} aria-hidden=\"true\" />\n Try again\n </button>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { XIcon } from \"lucide-react\";\nimport { cn } from \"./utils.js\";\n\nexport function Dialog(\n props: React.ComponentProps<typeof DialogPrimitive.Root>,\n) {\n return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />;\n}\n\nexport function DialogTrigger(\n props: React.ComponentProps<typeof DialogPrimitive.Trigger>,\n) {\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />;\n}\n\nexport function DialogPortal(\n props: React.ComponentProps<typeof DialogPrimitive.Portal>,\n) {\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />;\n}\n\nexport function DialogClose(\n props: React.ComponentProps<typeof DialogPrimitive.Close>,\n) {\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />;\n}\n\nexport function DialogOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n return (\n <DialogPrimitive.Overlay\n data-slot=\"dialog-overlay\"\n className={cn(\"fixed inset-0 z-50 bg-black/50\", className)}\n {...props}\n />\n );\n}\n\nexport function DialogContent({\n className,\n children,\n showCloseButton = true,\n overlayClassName,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content> & {\n showCloseButton?: boolean;\n overlayClassName?: string;\n}) {\n return (\n <DialogPortal>\n <DialogOverlay className={overlayClassName} />\n <DialogPrimitive.Content\n data-slot=\"dialog-content\"\n className={cn(\n \"fixed left-1/2 top-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-lg border bg-white p-6 shadow-lg sm:max-w-lg\",\n className,\n )}\n {...props}\n >\n {children}\n {showCloseButton ? (\n <DialogPrimitive.Close\n data-slot=\"dialog-close\"\n className=\"absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-slate-400\"\n >\n <XIcon aria-hidden=\"true\" className=\"size-4\" />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n ) : null}\n </DialogPrimitive.Content>\n </DialogPortal>\n );\n}\n\nexport function DialogHeader({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-header\"\n className={cn(\"flex flex-col gap-2 text-center sm:text-left\", className)}\n {...props}\n />\n );\n}\n\nexport function DialogFooter({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-footer\"\n className={cn(\n \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport function DialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n return (\n <DialogPrimitive.Title\n data-slot=\"dialog-title\"\n className={cn(\"text-lg font-semibold leading-none\", className)}\n {...props}\n />\n );\n}\n\nexport function DialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n return (\n <DialogPrimitive.Description\n data-slot=\"dialog-description\"\n className={cn(\"text-sm text-slate-600\", className)}\n {...props}\n />\n );\n}\n","import * as React from \"react\";\nimport { cn } from \"./utils.js\";\n\nexport function Input({\n className,\n type,\n ...props\n}: React.ComponentProps<\"input\">) {\n return (\n <input\n type={type}\n data-slot=\"input\"\n className={cn(\n \"h-10 w-full min-w-0 rounded-md border border-slate-300 bg-white px-3 py-2 text-base outline-none disabled:cursor-not-allowed disabled:opacity-50\",\n \"focus-visible:border-slate-600 focus-visible:ring-2 focus-visible:ring-slate-300\",\n className,\n )}\n {...props}\n />\n );\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as LabelPrimitive from \"@radix-ui/react-label\";\nimport { cn } from \"./utils.js\";\n\nexport function Label({\n className,\n ...props\n}: React.ComponentProps<typeof LabelPrimitive.Root>) {\n return (\n <LabelPrimitive.Root\n data-slot=\"label\"\n className={cn(\n \"flex items-center gap-2 text-sm font-medium leading-none\",\n className,\n )}\n {...props}\n />\n );\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as SelectPrimitive from \"@radix-ui/react-select\";\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\";\nimport { cn } from \"./utils.js\";\n\nexport function Select(\n props: React.ComponentProps<typeof SelectPrimitive.Root>,\n) {\n return <SelectPrimitive.Root data-slot=\"select\" {...props} />;\n}\n\nexport function SelectTrigger({\n className,\n size = \"default\",\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n size?: \"sm\" | \"default\";\n}) {\n return (\n <SelectPrimitive.Trigger\n data-slot=\"select-trigger\"\n data-size={size}\n className={cn(\n \"flex w-fit items-center justify-between gap-2 rounded-md border border-slate-300 bg-white px-3 py-2 text-sm outline-none disabled:cursor-not-allowed disabled:opacity-50\",\n \"focus-visible:border-slate-600 focus-visible:ring-2 focus-visible:ring-slate-300\",\n size === \"default\" ? \"h-9\" : \"h-8\",\n className,\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDownIcon className=\"size-4 opacity-50\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n );\n}\n\nexport function SelectContent({\n className,\n children,\n position = \"popper\",\n align = \"center\",\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n return (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n data-slot=\"select-content\"\n className={cn(\n \"relative z-50 max-h-[var(--radix-select-content-available-height)] min-w-32 overflow-x-hidden overflow-y-auto rounded-md border bg-white text-slate-950 shadow-md\",\n className,\n )}\n position={position}\n align={align}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport className=\"p-1\">\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n );\n}\n\nexport function SelectItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n return (\n <SelectPrimitive.Item\n data-slot=\"select-item\"\n className={cn(\n \"relative flex w-full cursor-default select-none items-center gap-2 rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-slate-100 data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n className,\n )}\n {...props}\n >\n <span className=\"absolute right-2 flex size-3.5 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n );\n}\n\nfunction SelectScrollUpButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n return (\n <SelectPrimitive.ScrollUpButton\n data-slot=\"select-scroll-up-button\"\n className={cn(\n \"flex cursor-default items-center justify-center py-1\",\n className,\n )}\n {...props}\n >\n <ChevronUpIcon className=\"size-4\" />\n </SelectPrimitive.ScrollUpButton>\n );\n}\n\nfunction SelectScrollDownButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n return (\n <SelectPrimitive.ScrollDownButton\n data-slot=\"select-scroll-down-button\"\n className={cn(\n \"flex cursor-default items-center justify-center py-1\",\n className,\n )}\n {...props}\n >\n <ChevronDownIcon className=\"size-4\" />\n </SelectPrimitive.ScrollDownButton>\n );\n}\n","import {\n createContext,\n createElement,\n useContext,\n useMemo,\n type ComponentType,\n type HTMLAttributes,\n type ReactElement,\n type ReactNode,\n} from \"react\";\nimport {\n composeEventHandlers,\n renderPrimitive,\n type PrimitiveCommonProps,\n} from \"../primitives/primitive-props.js\";\n\nexport type ResourceId = string;\n\nexport interface ResourceDisplayConfig<Resource extends string = ResourceId> {\n type: Resource;\n label: string;\n icon:\n | ReactNode\n | ComponentType<{\n className?: string;\n strokeWidth?: number;\n \"aria-hidden\"?: boolean | \"true\" | \"false\";\n }>;\n iconColor?: string;\n bgColor?: string;\n textColor?: string;\n}\n\nexport interface ResourceCounterItemState<\n Resource extends string = ResourceId,\n> {\n type: Resource;\n label: string;\n icon: ResourceDisplayConfig<Resource>[\"icon\"];\n iconColor?: string;\n bgColor?: string;\n textColor?: string;\n count: number;\n isZero: boolean;\n interactive: boolean;\n select: () => void;\n renderIcon: (props?: ResourceIconProps) => ReactNode;\n dataAttributes: {\n \"data-resource-id\": Resource;\n \"data-resource-count\": number;\n \"data-resource-zero\": boolean | undefined;\n \"data-interactive\": boolean | undefined;\n };\n}\n\nexport interface ResourceIconProps {\n className?: string;\n strokeWidth?: number;\n \"aria-hidden\"?: boolean | \"true\" | \"false\";\n}\n\nexport type ResourceCounterRootProps<Resource extends string = ResourceId> =\n Omit<PrimitiveCommonProps, \"children\"> &\n Omit<HTMLAttributes<HTMLElement>, \"children\"> & {\n resources: ReadonlyArray<ResourceDisplayConfig<Resource>>;\n counts: Partial<Record<Resource, number>>;\n zero?: \"show\" | \"hide\";\n onResourceClick?: (resourceType: Resource) => void;\n children: ReactNode;\n };\n\nexport type BoundResourceCounterRootProps<\n Resource extends string = ResourceId,\n> = Omit<ResourceCounterRootProps<Resource>, \"resources\">;\n\nexport type ResourceCounterProps<Resource extends string = ResourceId> =\n ResourceCounterRootProps<Resource>;\n\nexport type ResourceCounterPartProps<Resource extends string = ResourceId> =\n Omit<PrimitiveCommonProps, \"children\"> &\n Omit<HTMLAttributes<HTMLElement>, \"children\"> & {\n children?:\n | ReactNode\n | ((resource: ResourceCounterItemState<Resource>) => ReactNode);\n };\n\nconst ResourceCounterItemContext =\n createContext<ResourceCounterItemState<string> | null>(null);\n\nfunction useResourceCounterItemContext<Resource extends string>() {\n const value = useContext(ResourceCounterItemContext);\n if (!value) {\n throw new Error(\n \"ResourceCounter item primitives must be rendered inside <ResourceCounter.Item>.\",\n );\n }\n return value as ResourceCounterItemState<Resource>;\n}\n\nfunction renderResourceIcon(\n icon: ResourceDisplayConfig<string>[\"icon\"],\n props: ResourceIconProps = {},\n) {\n if (typeof icon === \"function\") {\n return createElement(icon, {\n \"aria-hidden\": true,\n strokeWidth: 2.5,\n ...props,\n });\n }\n const {\n strokeWidth: _strokeWidth,\n \"aria-hidden\": ariaHidden,\n ...spanProps\n } = props;\n return (\n <span\n aria-hidden={ariaHidden === undefined ? true : ariaHidden !== \"false\"}\n {...spanProps}\n >\n {icon}\n </span>\n );\n}\n\nfunction resolveResourceChildren<Resource extends string>(\n children: ResourceCounterPartProps<Resource>[\"children\"],\n resource: ResourceCounterItemState<Resource>,\n) {\n return typeof children === \"function\" ? children(resource) : children;\n}\n\nexport function ResourceCounterRoot<Resource extends string = ResourceId>({\n resources,\n counts,\n zero = \"show\",\n onResourceClick,\n children,\n \"aria-label\": ariaLabel,\n ...props\n}: ResourceCounterRootProps<Resource>) {\n const items = useMemo(\n () =>\n resources\n .map((resource) => {\n const count = counts[resource.type] ?? 0;\n return {\n ...resource,\n count,\n isZero: count === 0,\n interactive: Boolean(onResourceClick),\n select: () => onResourceClick?.(resource.type),\n renderIcon: (iconProps) =>\n renderResourceIcon(resource.icon, iconProps),\n dataAttributes: {\n \"data-resource-id\": resource.type,\n \"data-resource-count\": count,\n \"data-resource-zero\": count === 0 || undefined,\n \"data-interactive\": onResourceClick ? true : undefined,\n },\n } satisfies ResourceCounterItemState<Resource>;\n })\n .filter((resource) => zero === \"show\" || !resource.isZero),\n [counts, onResourceClick, resources, zero],\n );\n\n return renderPrimitive(\"div\", {\n role: \"list\",\n \"aria-label\": ariaLabel ?? \"Resource counts\",\n \"data-dreamboard-resource-counter\": \"\",\n ...props,\n children: items.map((resource) => (\n <ResourceCounterItemContext.Provider key={resource.type} value={resource}>\n {children}\n </ResourceCounterItemContext.Provider>\n )),\n });\n}\n\nexport function ResourceCounterItem<Resource extends string = ResourceId>({\n children,\n onClick,\n \"aria-label\": ariaLabel,\n ...props\n}: ResourceCounterPartProps<Resource>) {\n const resource = useResourceCounterItemContext<Resource>();\n return renderPrimitive(\"span\", {\n role: \"listitem\",\n \"aria-label\": ariaLabel ?? `${resource.label}: ${resource.count}`,\n ...resource.dataAttributes,\n ...props,\n onClick: composeEventHandlers(\n onClick,\n resource.interactive ? resource.select : undefined,\n ),\n children: resolveResourceChildren(children, resource),\n });\n}\n\nexport function ResourceCounterIcon<Resource extends string = ResourceId>({\n className,\n strokeWidth,\n \"aria-hidden\": ariaHidden,\n}: ResourceIconProps): ReactNode {\n const resource = useResourceCounterItemContext<Resource>();\n return resource.renderIcon({\n className,\n strokeWidth,\n \"aria-hidden\": ariaHidden,\n });\n}\n\nexport function ResourceCounterCount<Resource extends string = ResourceId>({\n children,\n ...props\n}: ResourceCounterPartProps<Resource>) {\n const resource = useResourceCounterItemContext<Resource>();\n return renderPrimitive(\"span\", {\n ...props,\n \"data-dreamboard-resource-count\": \"\",\n children: resolveResourceChildren(children ?? resource.count, resource),\n });\n}\n\nexport function ResourceCounterLabel<Resource extends string = ResourceId>({\n children,\n ...props\n}: ResourceCounterPartProps<Resource>) {\n const resource = useResourceCounterItemContext<Resource>();\n return renderPrimitive(\"span\", {\n ...props,\n \"data-dreamboard-resource-label\": \"\",\n children: resolveResourceChildren(children ?? resource.label, resource),\n });\n}\n\nexport interface ResourceCounterComponents<\n Resource extends string = ResourceId,\n> {\n Root(props: BoundResourceCounterRootProps<Resource>): ReactElement;\n Item(props: ResourceCounterPartProps<Resource>): ReactElement;\n Icon(props: ResourceIconProps): ReactNode;\n Count(props: ResourceCounterPartProps<Resource>): ReactElement;\n Label(props: ResourceCounterPartProps<Resource>): ReactElement;\n}\n\nexport function createResourceCounter<Resource extends string>(\n resources: ReadonlyArray<ResourceDisplayConfig<Resource>>,\n): ResourceCounterComponents<Resource> {\n return {\n Root(props) {\n return createElement(ResourceCounterRoot<Resource>, {\n ...props,\n resources,\n });\n },\n Item: ResourceCounterItem,\n Icon: ResourceCounterIcon,\n Count: ResourceCounterCount,\n Label: ResourceCounterLabel,\n } satisfies ResourceCounterComponents<Resource>;\n}\n\nexport const ResourceCounter = {\n Root: ResourceCounterRoot,\n Item: ResourceCounterItem,\n Icon: ResourceCounterIcon,\n Count: ResourceCounterCount,\n Label: ResourceCounterLabel,\n};\n","/** Shows resource costs with affordability indication (green/red). */\n\nimport { clsx } from \"clsx\";\nimport type { ComponentType } from \"react\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"../internal/ui/tooltip.js\";\n\nexport interface ResourceDefinition {\n type: string;\n label: string;\n icon?: ComponentType<{ className?: string }>;\n color?: string;\n}\n\nexport interface CostDisplayProps {\n /** Cost requirements keyed by resource type */\n cost: Record<string, number>;\n /** Current resources to check affordability */\n currentResources?: Record<string, number>;\n resourceDefs: ResourceDefinition[];\n size?: \"sm\" | \"md\";\n layout?: \"inline\" | \"stacked\";\n className?: string;\n}\nexport function CostDisplay({\n cost,\n currentResources,\n resourceDefs,\n size = \"sm\",\n layout = \"inline\",\n className,\n}: CostDisplayProps) {\n const resourceMap = Object.fromEntries(resourceDefs.map((r) => [r.type, r]));\n\n const sizeClasses = {\n sm: { icon: \"w-3 h-3\", text: \"text-xs\", gap: \"gap-0.5\" },\n md: { icon: \"w-4 h-4\", text: \"text-sm\", gap: \"gap-1\" },\n };\n\n const styles = sizeClasses[size];\n\n // Calculate total affordability for aria label\n const canAffordAll =\n !currentResources ||\n Object.entries(cost).every(\n ([type, amount]) => (currentResources[type] ?? 0) >= amount,\n );\n\n const costEntries = Object.entries(cost).filter(\n ([, amount]) => amount !== undefined && amount > 0,\n );\n\n if (costEntries.length === 0) {\n return null;\n }\n\n return (\n <div\n className={clsx(\n \"flex\",\n styles.gap,\n layout === \"stacked\" && \"flex-col\",\n layout === \"inline\" && \"flex-row flex-wrap items-center\",\n className,\n )}\n role=\"list\"\n aria-label={`Cost: ${costEntries.map(([type, amount]) => `${amount} ${resourceMap[type]?.label || type}`).join(\", \")}${currentResources ? (canAffordAll ? \" (affordable)\" : \" (cannot afford)\") : \"\"}`}\n >\n <TooltipProvider delayDuration={200}>\n {costEntries.map(([type, amount]) => {\n const def = resourceMap[type];\n const have = currentResources?.[type] ?? Infinity;\n const canAfford = have >= amount;\n const Icon = def?.icon;\n const label = def?.label || type;\n\n return (\n <Tooltip key={type}>\n <TooltipTrigger asChild>\n <div\n className={clsx(\n \"flex cursor-help items-center rounded-sm outline-none focus-visible:ring-2 focus-visible:ring-white/70\",\n styles.gap,\n styles.text,\n currentResources && !canAfford && \"text-red-400\",\n currentResources && canAfford && \"text-green-400\",\n !currentResources && \"text-slate-300\",\n )}\n role=\"listitem\"\n tabIndex={0}\n >\n {Icon && <Icon className={styles.icon} aria-hidden=\"true\" />}\n <span className=\"font-semibold\">{amount}</span>\n {!Icon && (\n <span className=\"text-[10px] opacity-70\">\n {def?.label?.slice(0, 3) || type.slice(0, 3)}\n </span>\n )}\n </div>\n </TooltipTrigger>\n <TooltipContent\n side=\"top\"\n sideOffset={6}\n className=\"max-w-xs text-left\"\n >\n <p className=\"font-sans text-sm font-bold\">{label}</p>\n <p className=\"font-sans mt-1 text-xs font-normal opacity-90\">\n {formatCostAvailability({\n amount,\n canAfford,\n have,\n })}\n </p>\n </TooltipContent>\n </Tooltip>\n );\n })}\n </TooltipProvider>\n </div>\n );\n}\n\n/** Second line under the resource name — avoids repeating {@link label} in the tooltip. */\nfunction formatCostAvailability({\n amount,\n canAfford,\n have,\n}: {\n amount: number;\n canAfford: boolean;\n have: number;\n}) {\n if (!Number.isFinite(have)) {\n return `Cost: ${amount}.`;\n }\n\n const missing = Math.max(0, amount - have);\n return canAfford\n ? `Cost: ${amount}. You have ${have}.`\n : `Cost: ${amount}. You have ${have}; short by ${missing}.`;\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\nimport { cn } from \"./utils.js\";\n\nexport function TooltipProvider({\n delayDuration = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delayDuration={delayDuration}\n {...props}\n />\n );\n}\n\nexport function Tooltip(\n props: React.ComponentProps<typeof TooltipPrimitive.Root>,\n) {\n return (\n <TooltipProvider>\n <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n </TooltipProvider>\n );\n}\n\nexport function TooltipTrigger(\n props: React.ComponentProps<typeof TooltipPrimitive.Trigger>,\n) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />;\n}\n\nexport function TooltipContent({\n className,\n sideOffset = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n \"z-50 w-fit rounded-md border border-slate-900 bg-white px-3 py-2 text-sm font-semibold text-slate-950 shadow-md\",\n className,\n )}\n {...props}\n />\n </TooltipPrimitive.Portal>\n );\n}\n","import type {\n ButtonHTMLAttributes,\n ElementType,\n MouseEvent,\n ReactNode,\n} from \"react\";\nimport type { ButtonSize, ButtonVariant } from \"../theme/derive.js\";\nimport type { InteractionVisualState } from \"../types/visual-state.js\";\nimport { CostDisplay, type ResourceDefinition } from \"./CostDisplay.js\";\nimport { ThemedButton } from \"./ThemedButton.js\";\n\nexport interface ActionButtonProps\n extends\n Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\">,\n InteractionVisualState {\n label?: ReactNode;\n description?: ReactNode;\n icon?: ElementType<{ className?: string }>;\n cost?: Record<string, number>;\n currentResources?: Record<string, number>;\n resourceDefs?: ResourceDefinition[];\n available?: boolean;\n disabledReason?: string;\n loading?: boolean;\n variant?: ButtonVariant;\n size?: ButtonSize;\n children?: ReactNode;\n}\n\nexport function ActionButton({\n label,\n description,\n icon,\n cost,\n currentResources,\n resourceDefs,\n available = true,\n disabledReason,\n loading = false,\n disabled,\n eligible,\n selected,\n invalid,\n submitted,\n previewing,\n intentProgress,\n title,\n variant = \"secondary\",\n size = \"md\",\n children,\n onClick,\n ...rest\n}: ActionButtonProps) {\n const isDisabled = disabled || loading || !available;\n const Icon = icon;\n const resolvedTitle = title ?? (!available ? disabledReason : undefined);\n\n function handleClick(event: MouseEvent<HTMLButtonElement>) {\n if (isDisabled) return;\n onClick?.(event);\n }\n\n return (\n <ThemedButton\n type=\"button\"\n variant={variant}\n size={size}\n disabled={isDisabled}\n eligible={eligible ?? (available && !isDisabled ? undefined : undefined)}\n selected={selected}\n invalid={invalid}\n submitted={submitted}\n previewing={previewing}\n intentProgress={intentProgress}\n loading={loading}\n title={resolvedTitle}\n onClick={handleClick}\n {...rest}\n >\n {Icon ? <Icon className=\"h-4 w-4\" aria-hidden=\"true\" /> : null}\n <span className=\"inline-flex min-w-0 flex-col items-start gap-0.5\">\n <span>{children ?? label ?? \"Action\"}</span>\n {description ? (\n <span className=\"text-xs font-normal opacity-75\">{description}</span>\n ) : null}\n {cost && resourceDefs ? (\n <CostDisplay\n cost={cost}\n currentResources={currentResources}\n resourceDefs={resourceDefs}\n />\n ) : null}\n </span>\n {loading ? <span aria-hidden=\"true\">...</span> : null}\n </ThemedButton>\n );\n}\n","/**\n * Minimally-styled primary action button.\n *\n * Visual styling now flows through {@link buttonStyle}: the background,\n * border, foreground, radius, typography and elevation all derive from\n * the active {@link useTheme}'s `intent.primary` slot. Override the\n * variant when a non-primary call site needs a different emphasis (the\n * underlying `<DefaultInteractionButton>` is the canonical button for\n * interaction-bound submission).\n */\n\nimport type { ButtonHTMLAttributes } from \"react\";\nimport type { ButtonSize, ButtonVariant } from \"../theme/derive.js\";\nimport type { InteractionVisualState } from \"../types/visual-state.js\";\nimport { ThemedButton } from \"./ThemedButton.js\";\n\nexport interface PrimaryButtonProps\n extends ButtonHTMLAttributes<HTMLButtonElement>, InteractionVisualState {\n /** Intent slot — defaults to `primary`. */\n variant?: ButtonVariant;\n /** Sizing token — defaults to `md`. */\n size?: ButtonSize;\n}\n\nexport function PrimaryButton({\n children,\n disabled,\n style,\n variant = \"primary\",\n size = \"md\",\n ...rest\n}: PrimaryButtonProps) {\n return (\n <ThemedButton\n type=\"button\"\n disabled={disabled}\n variant={variant}\n size={size}\n style={style}\n {...rest}\n >\n {children}\n </ThemedButton>\n );\n}\n","/**\n * Theme-aware controlled primary CTA button — the dominant call-to-action on\n * the screen at any given moment (\"Roll dice\", \"End turn\", \"Confirm\n * trade\", \"Place settlement\").\n *\n * Visual contract (Laws of UX cross-references):\n *\n * - **Fitts** — defaults to `lg` size (min 56px tall, generous\n * horizontal padding) so the dock target is easy to land on.\n * Authors can opt down to `md`.\n * - **Von Restorff (isolation)** — uses `intent.primary.solid` with\n * `elevation.lifted` and an animated halo when `attention=\"auto\"`\n * and `available` is true, so the button outranks every other\n * element in its peripheral neighbourhood.\n * - **Peak-end** — when the action becomes available, the halo pulses for one breath cycle\n * so the eye finds the change without re-scanning the screen.\n * - **Doherty / responsiveness** — clicks set an internal `pending`\n * flag the moment submit fires so the button visibly absorbs the\n * tap, even on slow networks. Throwing submitters are swallowed\n * here for the same reason `<DefaultInteractionButton>` does:\n * descriptor availability is authoritative.\n * - **Accessibility** — minimum 56×56 hit area satisfies WCAG 2.5.5.\n * `prefers-reduced-motion` zeroes out the halo and press\n * transitions through the theme's `motion.reducedMotion` token.\n */\n\nimport {\n useEffect,\n useRef,\n useState,\n type CSSProperties,\n type MouseEvent,\n type ReactNode,\n} from \"react\";\nimport { motion } from \"framer-motion\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\nimport {\n intentForVariant,\n type ButtonSize,\n type ButtonVariant,\n} from \"../theme/derive.js\";\nimport type { InteractionVisualState } from \"../types/visual-state.js\";\nimport { ThemedButton } from \"./ThemedButton.js\";\n\n/** Attention-pulse policy for the trailing halo. */\nexport type PrimaryActionAttention = \"auto\" | \"always\" | \"off\";\n\nexport interface SubmittedActionConfig {\n label?: ReactNode;\n icon?: ReactNode;\n variant?: ButtonVariant;\n}\n\nexport interface PrimaryActionButtonProps extends InteractionVisualState {\n /**\n * Override the visual variant. Defaults to `primary` (which maps\n * to `intent.primary` regardless of the descriptor's `emphasis`\n * hint — the shell's primary slot is, by definition, primary).\n */\n variant?: ButtonVariant;\n /**\n * Sizing. Defaults to `lg` so the dock target is comfortable on\n * touch and visually outranks panel buttons sized `md`.\n */\n size?: ButtonSize;\n /**\n * Override the label inferred from `descriptor.label`. Use only\n * when the descriptor's label needs phase-specific copy that the\n * authoring layer can't express.\n */\n label?: ReactNode;\n /** Client-side draft readiness. Reducer availability remains authoritative. */\n ready?: boolean;\n /** Whether the action is currently available according to the caller. */\n available?: boolean;\n /** Optional reason rendered as the disabled tooltip. */\n unavailableReason?: string;\n /** External submission state. */\n submitting?: boolean;\n /** External submitted state. */\n submitted?: boolean;\n /** Copy and visual overrides once this interaction has been submitted. */\n whenSubmitted?: SubmittedActionConfig;\n /**\n * Optional leading icon override. When omitted, falls back to\n * `descriptor.icon` (an emoji glyph from the authoring spec).\n */\n icon?: ReactNode;\n /** Stable identifier for diagnostics and tests. */\n actionId?: string;\n /** Called when the controlled action is activated. */\n onAction?: () => void | Promise<void>;\n /**\n * Attention-halo policy. `auto` (default) pulses the halo for one\n * breath when the button transitions from disabled → enabled (so\n * the user sees the moment the action becomes available), then\n * settles into a slow ambient breath while the action remains\n * available. `always` keeps the breath running unconditionally.\n * `off` suppresses the halo entirely.\n *\n * Ignored when `theme.motion.reducedMotion === \"true\"`.\n */\n attention?: PrimaryActionAttention;\n /** Additional inline style merged after the resolved button style. */\n style?: CSSProperties;\n /** Optional className for downstream styling hooks. */\n className?: string;\n}\n\n/**\n * @see PrimaryActionButtonProps\n */\nexport function PrimaryActionButton({\n variant = \"primary\",\n size = \"lg\",\n label = \"Action\",\n ready = true,\n available: availableProp = true,\n unavailableReason,\n submitting: submittingProp = false,\n submitted = false,\n whenSubmitted,\n icon,\n actionId,\n onAction,\n attention = \"auto\",\n style,\n className,\n}: PrimaryActionButtonProps) {\n const theme = useTheme();\n const reducedMotion = theme.motion.reducedMotion === \"true\";\n const [pending, setPending] = useState(false);\n\n const submitting = submittingProp || pending;\n const available = availableProp && ready && !submitted && !submitting;\n const resolvedVariant = submitted\n ? (whenSubmitted?.variant ?? \"submitted\")\n : variant;\n const disabled = !available;\n const intent = intentForVariant(theme, resolvedVariant);\n\n // Pulse the halo for one breath when availability flips on. After\n // the breath we settle into the ambient cadence (or stop, when\n // `attention` is `off`). Tracking the previous availability lets\n // us catch the transition without re-mounting the component.\n const previouslyAvailableRef = useRef(available);\n const [pulseKey, setPulseKey] = useState(0);\n useEffect(() => {\n if (!previouslyAvailableRef.current && available) {\n setPulseKey((n) => n + 1);\n }\n previouslyAvailableRef.current = available;\n }, [available]);\n\n const haloEnabled =\n !reducedMotion && available && attention !== \"off\" && !submitted;\n\n const tooltip = available\n ? undefined\n : formatUnavailableReason(unavailableReason);\n\n const resolvedLabel: ReactNode = submitted\n ? (whenSubmitted?.label ?? label)\n : label;\n const resolvedIcon: ReactNode =\n submitted && whenSubmitted?.icon ? (\n <span aria-hidden style={{ fontSize: \"1.15em\" }}>\n {whenSubmitted.icon}\n </span>\n ) : (\n (icon ?? null)\n );\n\n return (\n <span\n data-dreamboard-primary-action\n data-available={available ? \"true\" : \"false\"}\n data-pending={submitting ? \"true\" : undefined}\n data-action-state={\n submitted\n ? \"submitted\"\n : submitting\n ? \"submitting\"\n : available\n ? \"available\"\n : \"unavailable\"\n }\n style={{\n position: \"relative\",\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n // The halo overflows the button bounds; the wrapper reserves\n // a transparent buffer so it doesn't get clipped by the\n // dock's safe-area frame.\n padding: theme.space[1],\n }}\n >\n {haloEnabled ? (\n <>\n {/*\n Ambient breath — slow, low-amplitude, runs as long as the\n action is available. The outer `haloEnabled` already\n short-circuits when `attention === \"off\"`, so this layer\n is gated purely on the availability + reduced-motion\n checks.\n */}\n <motion.span\n aria-hidden\n style={{\n position: \"absolute\",\n inset: 0,\n borderRadius: theme.radius.md,\n background: intent.soft,\n opacity: 0.55,\n pointerEvents: \"none\",\n }}\n animate={{\n scale: [1, 1.06, 1],\n opacity: [0.45, 0.18, 0.45],\n }}\n transition={{\n repeat: Infinity,\n duration: 2.4,\n ease: \"easeInOut\",\n }}\n />\n {/*\n One-shot announce pulse keyed on `pulseKey` — re-mounts\n (and thus re-runs) every time availability flips on so the\n eye registers the change. We use a separate layer (rather\n than retriggering the ambient breath) so the announce is\n visibly louder than the steady-state cadence.\n */}\n <motion.span\n key={pulseKey}\n aria-hidden\n style={{\n position: \"absolute\",\n inset: 0,\n borderRadius: theme.radius.md,\n boxShadow: `0 0 0 0 ${intent.solid}`,\n pointerEvents: \"none\",\n }}\n initial={{ opacity: 0.7 }}\n animate={{\n boxShadow: [\n `0 0 0 0 ${withAlpha(intent.solid, 0.55)}`,\n `0 0 0 14px ${withAlpha(intent.solid, 0)}`,\n ],\n opacity: [0.7, 0],\n }}\n transition={{ duration: 0.9, ease: \"easeOut\" }}\n />\n </>\n ) : null}\n <ThemedButton\n type=\"button\"\n variant={resolvedVariant}\n size={size}\n pressed={submitting}\n className={className}\n aria-label={\n typeof resolvedLabel === \"string\" ? resolvedLabel : \"Primary action\"\n }\n aria-disabled={disabled || undefined}\n data-interaction-id={actionId}\n data-emphasis=\"primary\"\n title={tooltip}\n disabled={disabled}\n style={{\n // Sit above the halo so clicks land on the button.\n position: \"relative\",\n zIndex: 1,\n boxShadow: disabled || submitted ? undefined : theme.elevation.lifted,\n ...style,\n }}\n onClick={async (event: MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n if (disabled) return;\n setPending(true);\n try {\n await onAction?.();\n } finally {\n setPending(false);\n }\n }}\n >\n {resolvedIcon}\n <span>{resolvedLabel}</span>\n </ThemedButton>\n </span>\n );\n}\n\nfunction formatUnavailableReason(\n reason: string | undefined,\n): string | undefined {\n if (reason === \"INSUFFICIENT_RESOURCES\") {\n return \"Insufficient resources\";\n }\n return reason;\n}\n\n/**\n * Add an alpha channel to a CSS colour string. Supports `#rgb`,\n * `#rrggbb`, and any colour the browser can paint via a fallback to\n * `color-mix` (modern Safari/Chrome/Firefox all support this; older\n * runtimes get the original colour without alpha which is still\n * visible — the halo is decorative).\n */\nfunction withAlpha(color: string, alpha: number): string {\n const trimmed = color.trim();\n if (trimmed.startsWith(\"#\")) {\n const hex = trimmed.slice(1);\n if (hex.length === 3) {\n // `String.prototype.slice` always returns a string (possibly\n // empty) — never `undefined` — so duplicating each digit is\n // safe to feed to `parseInt` without further narrowing.\n const r = parseInt(hex.slice(0, 1).repeat(2), 16);\n const g = parseInt(hex.slice(1, 2).repeat(2), 16);\n const b = parseInt(hex.slice(2, 3).repeat(2), 16);\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n }\n if (hex.length === 6) {\n const r = parseInt(hex.slice(0, 2), 16);\n const g = parseInt(hex.slice(2, 4), 16);\n const b = parseInt(hex.slice(4, 6), 16);\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n }\n }\n // Best-effort fallback for non-hex colours (rgb/hsl/named): use\n // `color-mix` with transparent. Safe to land in inline style — the\n // halo is purely decorative and will gracefully degrade.\n return `color-mix(in srgb, ${trimmed} ${Math.round(alpha * 100)}%, transparent)`;\n}\n","/**\n * Collapsible panel for grouping game actions with state-based visibility.\n *\n * Visual styling is sourced entirely from the active {@link useTheme}.\n * The previous bespoke \"wobbly notebook\" treatment (`wobbly-border-lg` /\n * `hard-shadow-lg` / hardcoded `#fff9c4` / `#fdfbf7`) has been retired\n * in favour of `surfaceStyle` + `chipStyle` so the panel re-skins\n * uniformly when authors swap themes.\n */\n\nimport { useId, useState, type ReactNode } from \"react\";\nimport { motion, AnimatePresence } from \"framer-motion\";\nimport { ChevronUp } from \"lucide-react\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\nimport {\n chipStyle,\n intentForVariant,\n surfaceStyle,\n type ButtonVariant,\n} from \"../theme/derive.js\";\n\nexport interface ActionPanelProps {\n title?: string;\n /** Current game state/phase for context display */\n state?: string;\n /** Human-readable state labels */\n stateLabels?: Record<string, string>;\n collapsible?: boolean;\n defaultExpanded?: boolean;\n children: ReactNode;\n className?: string;\n}\n\nexport function ActionPanel({\n title = \"Actions\",\n state,\n stateLabels,\n collapsible = true,\n defaultExpanded = true,\n children,\n className,\n}: ActionPanelProps) {\n const theme = useTheme();\n const reducedMotion = theme.motion.reducedMotion === \"true\";\n const contentId = useId();\n const [isExpanded, setIsExpanded] = useState(defaultExpanded);\n const [isHovered, setIsHovered] = useState(false);\n\n const stateLabel = state\n ? stateLabels?.[state] || state.replace(/([A-Z])/g, \" $1\").trim()\n : undefined;\n\n return (\n <motion.div\n initial={reducedMotion ? { opacity: 0 } : { opacity: 0, y: 20 }}\n animate={reducedMotion ? { opacity: 1 } : { opacity: 1, y: 0 }}\n className={className}\n data-dreamboard-action-panel=\"\"\n data-state={isExpanded ? \"open\" : \"closed\"}\n data-collapsible={collapsible ? \"true\" : undefined}\n style={{\n ...surfaceStyle(theme, { tone: \"card\", radius: \"hud\" }),\n boxShadow: theme.elevation.rest,\n overflow: \"hidden\",\n }}\n role=\"region\"\n aria-label={title}\n >\n <button\n type=\"button\"\n onClick={() => collapsible && setIsExpanded(!isExpanded)}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n disabled={!collapsible}\n aria-expanded={isExpanded}\n aria-controls={contentId}\n style={{\n width: \"100%\",\n padding: `${theme.space[3]} ${theme.space[4]}`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: theme.space[3],\n borderBottom: isExpanded\n ? `1px dashed ${theme.semantic.border.subtle}`\n : \"1px solid transparent\",\n background:\n collapsible && isHovered\n ? theme.semantic.surface.inset\n : theme.semantic.surface.hud,\n color: theme.semantic.text.primary,\n fontFamily: theme.typography.fontFamily.body,\n cursor: collapsible ? \"pointer\" : \"default\",\n transition: `background ${theme.motion.duration.fast} ${theme.motion.easing.out}`,\n // Reset native button look.\n border: \"none\",\n textAlign: \"left\",\n appearance: \"none\",\n }}\n >\n <div>\n <h2\n style={{\n margin: 0,\n fontFamily: theme.typography.fontFamily.display,\n fontSize: theme.typography.fontSize.xl,\n fontWeight: theme.typography.fontWeight.bold,\n color: theme.semantic.text.primary,\n lineHeight: theme.typography.lineHeight.tight,\n }}\n >\n {title}\n </h2>\n {stateLabel && (\n <p\n style={{\n margin: 0,\n marginTop: theme.space[1],\n fontSize: theme.typography.fontSize.sm,\n fontWeight: theme.typography.fontWeight.medium,\n color: theme.semantic.text.muted,\n display: \"flex\",\n alignItems: \"center\",\n gap: theme.space[2],\n }}\n >\n <span\n style={{\n width: 8,\n height: 8,\n borderRadius: theme.radius.pill,\n background: theme.semantic.intent.primary.solid,\n border: `1px solid ${theme.semantic.intent.primary.border}`,\n display: \"inline-block\",\n }}\n />\n Phase: {stateLabel}\n </p>\n )}\n </div>\n {collapsible && (\n <motion.div\n animate={\n reducedMotion ? undefined : { rotate: isExpanded ? 0 : 180 }\n }\n transition={{ duration: 0.2 }}\n style={{\n padding: theme.space[1],\n borderRadius: theme.radius.md,\n border: `1px solid ${theme.semantic.border.default}`,\n background: theme.semantic.surface.card,\n color: theme.semantic.text.primary,\n display: \"inline-flex\",\n }}\n >\n <ChevronUp\n size={20}\n strokeWidth={2.5}\n aria-hidden=\"true\"\n style={{ display: \"block\" }}\n />\n </motion.div>\n )}\n </button>\n\n <AnimatePresence initial={false}>\n {isExpanded && (\n <motion.div\n id={contentId}\n initial={reducedMotion ? { opacity: 0 } : { height: 0, opacity: 0 }}\n animate={\n reducedMotion ? { opacity: 1 } : { height: \"auto\", opacity: 1 }\n }\n exit={reducedMotion ? { opacity: 0 } : { height: 0, opacity: 0 }}\n transition={{ duration: 0.2, ease: \"easeInOut\" }}\n style={{\n overflow: \"hidden\",\n background: theme.semantic.surface.card,\n }}\n >\n <div\n style={{\n padding: theme.space[4],\n display: \"flex\",\n flexDirection: \"column\",\n gap: theme.space[6],\n }}\n >\n {children}\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </motion.div>\n );\n}\n\nexport interface ActionGroupProps {\n title: string;\n description?: string;\n visible?: boolean;\n /** Highlight style for special phases. Maps directly onto theme intent slots. */\n variant?: \"default\" | \"warning\" | \"danger\" | \"success\";\n children: ReactNode;\n className?: string;\n}\n\nconst VARIANT_TO_INTENT: Record<\n ActionGroupProps[\"variant\"] & string,\n ButtonVariant | null\n> = {\n default: null,\n warning: \"warning\",\n danger: \"danger\",\n success: \"success\",\n};\n\nexport function ActionGroup({\n title,\n description,\n visible = true,\n variant = \"default\",\n children,\n className,\n}: ActionGroupProps) {\n const theme = useTheme();\n const reducedMotion = theme.motion.reducedMotion === \"true\";\n\n if (!visible) return null;\n\n const intentVariant = VARIANT_TO_INTENT[variant];\n const intent = intentVariant ? intentForVariant(theme, intentVariant) : null;\n\n const containerStyle: React.CSSProperties = intent\n ? {\n background: intent.soft,\n color: intent.onSoft,\n border: `1px solid ${intent.border}`,\n borderRadius: theme.radius.lg,\n boxShadow: theme.elevation.rest,\n }\n : {\n background: theme.semantic.surface.card,\n color: theme.semantic.text.primary,\n border: `1px solid ${theme.semantic.border.subtle}`,\n borderRadius: theme.radius.lg,\n boxShadow: theme.elevation.rest,\n };\n\n return (\n <motion.div\n initial={reducedMotion ? { opacity: 0 } : { opacity: 0, x: -10 }}\n animate={reducedMotion ? { opacity: 1 } : { opacity: 1, x: 0 }}\n className={className}\n data-dreamboard-action-group=\"\"\n data-variant={variant}\n style={{\n position: \"relative\",\n padding: theme.space[4],\n fontFamily: theme.typography.fontFamily.body,\n ...containerStyle,\n }}\n role=\"group\"\n aria-labelledby={`action-group-${title.toLowerCase().replace(/\\s+/g, \"-\")}`}\n >\n <span\n style={{\n position: \"absolute\",\n top: -10,\n left: theme.space[3],\n ...chipStyle(theme, { variant: \"secondary\", size: \"sm\" }),\n background: theme.semantic.surface.card,\n }}\n >\n Group\n </span>\n <h3\n id={`action-group-${title.toLowerCase().replace(/\\s+/g, \"-\")}`}\n style={{\n margin: 0,\n fontFamily: theme.typography.fontFamily.display,\n fontSize: theme.typography.fontSize.lg,\n fontWeight: theme.typography.fontWeight.bold,\n color: intent?.onSoft ?? theme.semantic.text.primary,\n marginBottom: description ? theme.space[2] : theme.space[3],\n }}\n >\n {title}\n </h3>\n {description && (\n <p\n style={{\n margin: 0,\n marginBottom: theme.space[4],\n fontSize: theme.typography.fontSize.sm,\n fontWeight: theme.typography.fontWeight.medium,\n color: intent?.onSoft ?? theme.semantic.text.muted,\n opacity: 0.85,\n }}\n >\n {description}\n </p>\n )}\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: theme.space[3],\n }}\n >\n {children}\n </div>\n </motion.div>\n );\n}\n","/**\n * Disclosure that hides a list of low-salience actions behind a single\n * \"More\" toggle. Sized and styled by the active theme so it looks\n * consistent with neighbouring `<DefaultInteractionButton>` rows.\n *\n * Why not a popover or dropdown? Two reasons:\n *\n * 1. **Layout safety.** The default panel surface lives directly above\n * the hand strip; a floating popover would be obscured by the\n * hand's `overflow-x: auto` clipping. An inline expansion stays\n * inside the panel container and pushes neighbouring rows down.\n * 2. **Discoverability.** Players miss menus that hide behind triple\n * dots / chevrons. An expanded inline list still looks like a row\n * of buttons (Jakob — same affordance as the always-visible row).\n *\n * The toggle reports its open state via `aria-expanded` and labels\n * the disclosed region via `aria-controls` so screen readers announce\n * \"Expanded — More actions, region containing 3 buttons\" naturally.\n */\n\nimport { useId, useState, type CSSProperties, type ReactNode } from \"react\";\nimport { ChevronDown, MoreHorizontal } from \"lucide-react\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\nimport { ThemedButton } from \"./ThemedButton.js\";\n\nexport interface MoreActionsProps {\n /**\n * Items rendered inside the disclosure when expanded. Typically\n * `<DefaultInteractionButton>` instances for `salience: \"tertiary\"`\n * descriptors, but any `ReactNode` works (custom panel cards, etc.).\n */\n children: ReactNode;\n /**\n * Toggle label. Defaults to `\"More\"`. The descriptor count gets\n * appended automatically when {@link count} is supplied.\n */\n label?: string;\n /**\n * Number of hidden items, used to render the trailing \"(N)\" badge.\n * Omit when the count is irrelevant or already implied (e.g. when\n * the panel only has a fixed set of disclosed items).\n */\n count?: number;\n /**\n * Initial open state. Defaults to `false` — the disclosure is the\n * point. Authors who want it open by default for a specific seat\n * (e.g. tutorial mode) should pass `true`.\n */\n defaultOpen?: boolean;\n /** Additional inline style merged after the default container. */\n style?: CSSProperties;\n}\n\nexport function MoreActions({\n children,\n label = \"More\",\n count,\n defaultOpen = false,\n style,\n}: MoreActionsProps) {\n const theme = useTheme();\n const [open, setOpen] = useState(defaultOpen);\n // `useId` keeps the aria pairing stable across re-renders even when\n // many `<MoreActions>` exist on screen (rare, but easy to break).\n const regionId = `more-actions-${useId().replace(/:/g, \"\")}`;\n\n const showCount = typeof count === \"number\" && count > 0;\n\n return (\n <div\n data-shell-slot=\"more-actions\"\n data-more-actions-open={open ? \"true\" : \"false\"}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: theme.space[2],\n alignItems: \"stretch\",\n // The disclosure is its own block so wrap behaviour upstream\n // doesn't interleave the toggle and the disclosed items.\n flex: \"1 1 100%\",\n minWidth: 0,\n }}\n >\n <ThemedButton\n type=\"button\"\n variant=\"secondary\"\n size=\"md\"\n aria-expanded={open}\n aria-controls={regionId}\n onClick={() => setOpen((value) => !value)}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: theme.space[1],\n ...style,\n }}\n >\n <MoreHorizontal size={16} aria-hidden />\n <span>{label}</span>\n {showCount ? (\n <span\n aria-hidden\n style={{\n fontVariantNumeric: \"tabular-nums\",\n opacity: 0.78,\n }}\n >\n ({count})\n </span>\n ) : null}\n <ChevronDown\n size={14}\n aria-hidden\n style={{\n transform: open ? \"rotate(180deg)\" : \"rotate(0deg)\",\n transition: `transform ${theme.motion.duration.fast} ${theme.motion.easing.out}`,\n }}\n />\n </ThemedButton>\n {open ? (\n <div\n id={regionId}\n role=\"region\"\n aria-label={label}\n style={{\n display: \"flex\",\n flexDirection: \"row\",\n flexWrap: \"wrap\",\n gap: theme.space[2],\n // Inset visually so the disclosed cluster reads as a\n // sub-region rather than a continuation of the main panel.\n paddingInline: theme.space[3],\n paddingBlock: theme.space[2],\n background: theme.semantic.surface.inset,\n borderRadius: theme.radius.lg,\n }}\n >\n {children}\n </div>\n ) : null}\n </div>\n );\n}\n","import { clsx } from \"clsx\";\nimport { motion } from \"framer-motion\";\nimport {\n useCallback,\n useEffect,\n useRef,\n useState,\n type CSSProperties,\n type ReactNode,\n} from \"react\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from \"../internal/ui/dialog.js\";\nimport { surfaceStyle } from \"../theme/derive.js\";\nimport { useTheme, useThemeCssVars } from \"../theme/ThemeProvider.js\";\nimport { normalizeDiceState, type DiceValue } from \"../primitives/dice.js\";\nimport { ThemedButton } from \"./ThemedButton.js\";\n\nexport interface DiceRollerRenderProps {\n values: ReadonlyArray<number | undefined> | undefined;\n /** Undefined if any die hasn't been rolled */\n sum: number | undefined;\n diceCount: number;\n allRolled: boolean;\n}\n\nexport interface DiceRollerRollAction {\n /** Controlled action callback supplied by the runtime or application. */\n onRoll?: () => void | Promise<void>;\n available?: boolean;\n disabledReason?: string;\n title?: ReactNode;\n description?: ReactNode;\n rollLabel?: ReactNode;\n resultLabel?: ReactNode;\n minSpinMs?: number;\n revealHoldMs?: number;\n}\n\nexport interface DiceRollerProps {\n values?: readonly DiceValue[] | null;\n /** Used when values not provided */\n diceCount?: number;\n render?: (props: DiceRollerRenderProps) => ReactNode;\n /** Optional controlled dialog flow for actions such as `rollDice`. */\n rollAction?: DiceRollerRollAction;\n className?: string;\n}\n\ntype RollPhase = \"idle\" | \"rolling\" | \"revealed\";\n\nconst DEFAULT_MIN_SPIN_MS = 1200;\nconst DEFAULT_REVEAL_HOLD_MS = 1400;\nconst FACE_SEQUENCE = [1, 2, 3, 4, 5, 6] as const;\n\nexport function DiceRoller({\n values,\n diceCount = 2,\n render,\n rollAction,\n className,\n}: DiceRollerProps) {\n const renderProps = normalizeDiceState({ values, count: diceCount });\n\n return (\n <div\n className={clsx(\"flex flex-col items-center gap-4\", className)}\n role=\"region\"\n aria-label=\"Dice roller\"\n >\n {render ? render(renderProps) : <DefaultDiceReadout {...renderProps} />}\n\n {rollAction ? (\n <DiceRollDialog\n action={rollAction}\n values={renderProps.values}\n diceCount={renderProps.diceCount}\n />\n ) : null}\n\n {/* Screen reader only: dice info */}\n <div className=\"sr-only\" aria-live=\"polite\">\n {renderProps.allRolled && renderProps.values\n ? `Rolled ${renderProps.values.join(\", \")}. Total: ${renderProps.sum}`\n : \"Dice not rolled yet\"}\n </div>\n </div>\n );\n}\n\nfunction DefaultDiceReadout({\n values,\n sum,\n diceCount,\n allRolled,\n}: DiceRollerRenderProps) {\n const theme = useTheme();\n const dice = values ?? Array(diceCount).fill(undefined);\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: theme.space[2],\n }}\n >\n {allRolled ? (\n <strong\n style={{\n fontFamily: theme.typography.fontFamily.display,\n fontSize: theme.typography.fontSize.lg,\n color: theme.semantic.text.primary,\n fontVariantNumeric: \"tabular-nums\",\n }}\n >\n Total {sum}\n </strong>\n ) : null}\n <DiceRow values={dice} size={44} rolling={false} />\n </div>\n );\n}\n\nfunction DiceRollDialog({\n action,\n values,\n diceCount,\n}: {\n action: DiceRollerRollAction;\n values: ReadonlyArray<number | undefined> | undefined;\n diceCount: number;\n}) {\n const theme = useTheme();\n const themeCssVars = useThemeCssVars();\n const reducedMotion = theme.motion.reducedMotion === \"true\";\n const [open, setOpen] = useState(false);\n const [phase, setPhase] = useState<RollPhase>(\"idle\");\n const [error, setError] = useState<string | null>(null);\n const [animatedValues, setAnimatedValues] = useState<number[]>(() =>\n nextAnimatedValues(diceCount),\n );\n const [revealedValues, setRevealedValues] = useState<\n Array<number | undefined> | undefined\n >(undefined);\n const startedAtRef = useRef(0);\n const revealedRollKeyRef = useRef<string | null>(null);\n\n const shouldPresentDialog = Boolean(action.onRoll);\n const minSpinMs = reducedMotion\n ? 0\n : (action.minSpinMs ?? DEFAULT_MIN_SPIN_MS);\n const revealHoldMs = action.revealHoldMs ?? DEFAULT_REVEAL_HOLD_MS;\n const rolledValuesKey = values?.join(\",\") ?? \"\";\n const valuesAreReady =\n values !== undefined &&\n values.length > 0 &&\n values.every((value) => typeof value === \"number\");\n\n useEffect(() => {\n if (!shouldPresentDialog) {\n setOpen(false);\n return;\n }\n if (!valuesAreReady) {\n revealedRollKeyRef.current = null;\n setOpen(true);\n if (phase !== \"rolling\") {\n setPhase(\"idle\");\n setRevealedValues(undefined);\n setError(null);\n }\n return;\n }\n if (\n open &&\n phase === \"idle\" &&\n revealedRollKeyRef.current !== rolledValuesKey\n ) {\n startedAtRef.current = Date.now();\n setPhase(\"rolling\");\n setAnimatedValues(nextAnimatedValues(diceCount));\n }\n }, [\n diceCount,\n open,\n phase,\n rolledValuesKey,\n shouldPresentDialog,\n valuesAreReady,\n ]);\n\n useEffect(() => {\n if (phase !== \"rolling\") return;\n if (reducedMotion) return;\n const interval = setInterval(() => {\n setAnimatedValues(nextAnimatedValues(diceCount));\n }, 120);\n return () => clearInterval(interval);\n }, [diceCount, phase, reducedMotion]);\n\n useEffect(() => {\n if (phase !== \"rolling\" || !valuesAreReady || !values) return;\n const remaining = Math.max(\n 0,\n minSpinMs - (Date.now() - startedAtRef.current),\n );\n const timeout = setTimeout(() => {\n setRevealedValues([...values]);\n revealedRollKeyRef.current = rolledValuesKey;\n setPhase(\"revealed\");\n }, remaining);\n return () => clearTimeout(timeout);\n }, [minSpinMs, phase, rolledValuesKey, values, valuesAreReady]);\n\n useEffect(() => {\n if (phase !== \"revealed\") return;\n const timeout = setTimeout(() => {\n setOpen(false);\n setPhase(\"idle\");\n }, revealHoldMs);\n return () => clearTimeout(timeout);\n }, [phase, revealHoldMs]);\n\n const roll = useCallback(async () => {\n if (!action.onRoll || action.available === false || phase === \"rolling\") {\n return;\n }\n startedAtRef.current = Date.now();\n setOpen(true);\n setPhase(\"rolling\");\n setError(null);\n setRevealedValues(undefined);\n setAnimatedValues(nextAnimatedValues(diceCount));\n try {\n await action.onRoll();\n } catch (caught) {\n setPhase(\"idle\");\n setError(\n caught instanceof Error ? caught.message : \"Unable to roll dice.\",\n );\n }\n }, [action, diceCount, phase]);\n\n const displayValues =\n phase === \"rolling\"\n ? animatedValues\n : (revealedValues ?? values ?? Array(diceCount).fill(undefined));\n const displaySum = sumValues(displayValues);\n const title = action.title ?? \"Roll dice\";\n const description = action.description ?? \"Roll to resolve the current turn.\";\n const resultLabel = action.resultLabel ?? \"Roll result\";\n const rollLabel = action.rollLabel ?? \"Roll dice\";\n const disabled = action.available === false || phase === \"rolling\";\n const canClose = true;\n\n return (\n <Dialog open={open} onOpenChange={canClose ? setOpen : undefined}>\n <DialogContent\n data-dismiss-behavior=\"dismiss\"\n showCloseButton={canClose}\n className=\"max-h-[calc(100vh-2rem)] overflow-y-auto p-4 sm:max-w-md sm:p-6\"\n style={{\n ...themeCssVars,\n ...surfaceStyle(theme, { tone: \"sheet\", radius: \"lg\" }),\n width: \"min(100%, 28rem)\",\n fontFamily: theme.typography.fontFamily.body,\n }}\n onEscapeKeyDown={\n canClose ? undefined : (event: Event) => event.preventDefault()\n }\n onInteractOutside={\n canClose ? undefined : (event: Event) => event.preventDefault()\n }\n >\n <DialogHeader className=\"text-center sm:text-center\">\n <DialogTitle\n style={{\n fontFamily: theme.typography.fontFamily.display,\n fontSize: theme.typography.fontSize.xl,\n }}\n >\n {title}\n </DialogTitle>\n <DialogDescription>{description}</DialogDescription>\n </DialogHeader>\n\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: theme.space[4],\n }}\n >\n <RollResult label={resultLabel} sum={displaySum} phase={phase} />\n <DiceRow\n values={displayValues}\n size={76}\n rolling={phase === \"rolling\"}\n />\n {error ? (\n <span\n role=\"alert\"\n style={{\n color: theme.semantic.intent.danger.solid,\n fontSize: theme.typography.fontSize.sm,\n textAlign: \"center\",\n }}\n >\n {error}\n </span>\n ) : null}\n <ThemedButton\n type=\"button\"\n variant=\"primary\"\n size=\"lg\"\n disabled={disabled}\n pressed={phase === \"rolling\"}\n onClick={(event) => {\n event.preventDefault();\n void roll();\n }}\n >\n {phase === \"rolling\" ? \"Rolling...\" : rollLabel}\n </ThemedButton>\n </div>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction RollResult({\n label,\n sum,\n phase,\n}: {\n label: ReactNode;\n sum: number | undefined;\n phase: RollPhase;\n}) {\n const theme = useTheme();\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n style={{\n ...surfaceStyle(theme, { tone: \"inset\", radius: \"lg\" }),\n width: \"100%\",\n padding: `${theme.space[3]} ${theme.space[4]}`,\n textAlign: \"center\",\n }}\n >\n <div\n style={{\n color: theme.semantic.text.muted,\n fontSize: theme.typography.fontSize.xs,\n fontWeight: theme.typography.fontWeight.bold,\n letterSpacing: theme.typography.letterSpacing.wide,\n textTransform: \"uppercase\",\n }}\n >\n {label}\n </div>\n <div\n style={{\n fontFamily: theme.typography.fontFamily.display,\n fontSize: \"clamp(2.75rem, 12vw, 4.5rem)\",\n fontWeight: theme.typography.fontWeight.bold,\n lineHeight: 1,\n color: theme.semantic.text.primary,\n fontVariantNumeric: \"tabular-nums\",\n }}\n >\n {sum ?? (phase === \"rolling\" ? \"...\" : \"?\")}\n </div>\n </div>\n );\n}\n\nfunction DiceRow({\n values,\n size,\n rolling,\n}: {\n values: ReadonlyArray<number | undefined>;\n size: number;\n rolling: boolean;\n}) {\n const gap = Math.max(8, Math.round(size * 0.18));\n return (\n <div\n role=\"list\"\n aria-label=\"Dice values\"\n style={{\n display: \"flex\",\n justifyContent: \"center\",\n gap,\n flexWrap: \"wrap\",\n }}\n >\n {values.map((value, index) => (\n <DieFace\n key={index}\n value={value}\n size={size}\n rolling={rolling}\n index={index}\n />\n ))}\n </div>\n );\n}\n\nfunction DieFace({\n value,\n size,\n rolling,\n index,\n}: {\n value: number | undefined;\n size: number;\n rolling: boolean;\n index: number;\n}) {\n const theme = useTheme();\n const reducedMotion = theme.motion.reducedMotion === \"true\";\n const showPips = typeof value === \"number\" && value >= 1 && value <= 6;\n const style: CSSProperties = {\n position: \"relative\",\n width: size,\n height: size,\n borderRadius: Math.max(10, Math.round(size * 0.2)),\n border: `1px solid ${theme.semantic.border.default}`,\n background: `linear-gradient(145deg, ${theme.semantic.surface.card}, ${theme.semantic.surface.inset})`,\n boxShadow: `${theme.elevation.lifted}, inset 0 1px 0 rgba(255,255,255,0.45)`,\n color: theme.semantic.text.primary,\n display: \"grid\",\n placeItems: \"center\",\n flex: \"0 0 auto\",\n overflow: \"hidden\",\n };\n return (\n <motion.div\n role=\"listitem\"\n aria-label={\n typeof value === \"number\"\n ? `Die ${index + 1}: ${value}`\n : `Die ${index + 1}: not rolled`\n }\n style={style}\n animate={\n rolling && !reducedMotion\n ? {\n rotate: [0, 12, -10, 0],\n y: [0, -8, 0],\n scale: [1, 1.04, 1],\n }\n : { rotate: 0, y: 0, scale: 1 }\n }\n transition={\n rolling && !reducedMotion\n ? {\n repeat: Infinity,\n duration: 0.42,\n delay: index * 0.06,\n ease: \"easeInOut\",\n }\n : { duration: 0.2 }\n }\n >\n {showPips ? (\n <PipFace value={value} />\n ) : (\n <span\n style={{\n fontFamily: theme.typography.fontFamily.display,\n fontSize: Math.round(size * 0.42),\n fontWeight: theme.typography.fontWeight.bold,\n fontVariantNumeric: \"tabular-nums\",\n }}\n >\n {value ?? \"?\"}\n </span>\n )}\n </motion.div>\n );\n}\n\nfunction PipFace({ value }: { value: number }) {\n const theme = useTheme();\n const pips = pipPositions(value);\n return (\n <span\n aria-hidden\n style={{\n position: \"absolute\",\n inset: \"18%\",\n }}\n >\n {pips.map(([left, top], index) => (\n <span\n key={`${left}-${top}-${index}`}\n style={{\n position: \"absolute\",\n left: `${left}%`,\n top: `${top}%`,\n width: \"22%\",\n height: \"22%\",\n borderRadius: \"9999px\",\n transform: \"translate(-50%, -50%)\",\n background: theme.semantic.text.primary,\n boxShadow: \"0 1px 2px rgba(0,0,0,0.25)\",\n }}\n />\n ))}\n </span>\n );\n}\n\nfunction pipPositions(value: number): Array<[number, number]> {\n switch (value) {\n case 1:\n return [[50, 50]];\n case 2:\n return [\n [28, 28],\n [72, 72],\n ];\n case 3:\n return [\n [28, 28],\n [50, 50],\n [72, 72],\n ];\n case 4:\n return [\n [28, 28],\n [72, 28],\n [28, 72],\n [72, 72],\n ];\n case 5:\n return [\n [28, 28],\n [72, 28],\n [50, 50],\n [28, 72],\n [72, 72],\n ];\n case 6:\n return [\n [28, 25],\n [72, 25],\n [28, 50],\n [72, 50],\n [28, 75],\n [72, 75],\n ];\n default:\n return [];\n }\n}\n\nfunction nextAnimatedValues(count: number): number[] {\n return Array.from({ length: count }, (_, index) => {\n const offset = Math.floor(Math.random() * FACE_SEQUENCE.length);\n return FACE_SEQUENCE[(offset + index) % FACE_SEQUENCE.length] ?? 1;\n });\n}\n\nfunction sumValues(\n values: ReadonlyArray<number | undefined>,\n): number | undefined {\n if (!values.every((value) => typeof value === \"number\")) return undefined;\n return values.reduce((total, value) => total + (value ?? 0), 0);\n}\n","import { createContext, useContext, type ReactNode } from \"react\";\n\nexport type DiceValue = number | null | undefined;\n\nexport interface DiceState {\n values: ReadonlyArray<number | undefined> | undefined;\n /** Undefined if any die has not been rolled yet. */\n sum: number | undefined;\n diceCount: number;\n allRolled: boolean;\n}\n\nexport interface DiceRootProps {\n values?: readonly DiceValue[] | null;\n /** Used when values are not provided. */\n count?: number;\n children: ReactNode;\n}\n\nexport interface DiceValuesProps {\n children: (state: DiceState) => ReactNode;\n}\n\nexport interface DiceComponents {\n Root(props: DiceRootProps): ReactNode;\n Values(props: DiceValuesProps): ReactNode;\n}\n\nconst DiceContext = createContext<DiceState | null>(null);\n\nexport function normalizeDiceState({\n values,\n count = 2,\n}: {\n values?: readonly DiceValue[] | null;\n count?: number;\n}): DiceState {\n const normalizedValues = values?.map((value) => value ?? undefined);\n const allRolled =\n normalizedValues?.every((value) => value !== undefined) ?? false;\n const sum = allRolled\n ? normalizedValues?.reduce<number>(\n (total, value) => total + (value ?? 0),\n 0,\n )\n : undefined;\n\n return {\n values: normalizedValues,\n sum,\n diceCount: normalizedValues?.length ?? count,\n allRolled,\n };\n}\n\nexport function DiceRoot({ values, count, children }: DiceRootProps) {\n return (\n <DiceContext.Provider value={normalizeDiceState({ values, count })}>\n {children}\n </DiceContext.Provider>\n );\n}\n\nexport function useDicePrimitiveContext(): DiceState {\n const value = useContext(DiceContext);\n if (!value) {\n throw new Error(\"Dice primitives must be rendered inside <Dice.Root>.\");\n }\n return value;\n}\n\nexport function DiceValues({ children }: DiceValuesProps) {\n return children(useDicePrimitiveContext());\n}\n\nexport const Dice: DiceComponents = {\n Root: DiceRoot,\n Values: DiceValues,\n};\n","/**\n * Surfaces the dominant turn-state question — \"is this me?\" / \"who am I\n * waiting for?\" — as a single headline, with the phase label demoted to\n * secondary copy underneath.\n *\n * The previous design rendered three peer chips (`Waiting`, `Roll dice`,\n * `Player 3`) which fragmented one piece of information across three\n * UI atoms. The redesign collapses them into a single status line:\n *\n * ◐ Waiting for Player 3…\n * Roll dice\n *\n * ● Your turn\n * Build, trade, or end your turn.\n *\n * Both states get a leading status indicator that animates so the eye\n * picks up the \"live\" cue immediately. Animations are skipped when the\n * theme reports `motion.reducedMotion === \"true\"`.\n *\n * Prop API is unchanged so existing callers (Catan, Things-in-Rings,\n * tests) keep working without edits. The `variant` knob still toggles\n * surface treatment (`badge` is layout-only, `bar` wraps the headline\n * in an inset HUD strip, `minimal` collapses to a single underlined\n * label for tight HUDs).\n */\n\nimport { motion } from \"framer-motion\";\nimport { clsx } from \"clsx\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\nimport { surfaceStyle } from \"../theme/derive.js\";\nimport type { Theme } from \"../theme/tokens.js\";\n\nexport interface PhaseIndicatorProps {\n currentPhase: string;\n phaseLabels?: Record<string, string>;\n isMyTurn?: boolean;\n activePlayerNames?: string[];\n variant?: \"badge\" | \"bar\" | \"minimal\";\n className?: string;\n}\n\nexport function PhaseIndicator({\n currentPhase,\n phaseLabels,\n isMyTurn,\n activePlayerNames,\n variant = \"badge\",\n className,\n}: PhaseIndicatorProps) {\n const theme = useTheme();\n const reducedMotion = theme.motion.reducedMotion === \"true\";\n\n const label = phaseLabels?.[currentPhase] ?? formatPhase(currentPhase);\n\n if (variant === \"minimal\") {\n return (\n <span\n className={className}\n style={{\n fontFamily: theme.typography.fontFamily.body,\n fontSize: theme.typography.fontSize.sm,\n fontWeight: theme.typography.fontWeight.bold,\n color: theme.semantic.text.muted,\n textDecoration: \"underline\",\n textDecorationStyle: \"wavy\",\n textDecorationColor: theme.semantic.border.subtle,\n textUnderlineOffset: \"4px\",\n }}\n role=\"status\"\n aria-label={`Current phase: ${label}`}\n >\n {label}\n </span>\n );\n }\n\n // Decide which state we're in. Only one is active at a time so the\n // headline is unambiguous.\n const state: \"your-turn\" | \"waiting\" | \"phase-only\" =\n isMyTurn === true\n ? \"your-turn\"\n : isMyTurn === false && activePlayerNames && activePlayerNames.length > 0\n ? \"waiting\"\n : \"phase-only\";\n\n const containerStyle: React.CSSProperties =\n variant === \"bar\"\n ? {\n ...surfaceStyle(theme, { tone: \"inset\", radius: \"hud\" }),\n padding: theme.space[3],\n boxShadow: theme.elevation.inset,\n fontFamily: theme.typography.fontFamily.body,\n }\n : { fontFamily: theme.typography.fontFamily.body };\n\n const headline = renderHeadline({\n state,\n activePlayerNames,\n label,\n theme,\n reducedMotion,\n });\n const ariaLabel =\n state === \"your-turn\"\n ? `Your turn — ${label}`\n : state === \"waiting\"\n ? `Waiting for ${formatPlayerList(activePlayerNames ?? [])} — ${label}`\n : label;\n\n return (\n <div\n className={clsx(\"flex items-center gap-3 flex-wrap\", className)}\n style={containerStyle}\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n aria-label={ariaLabel}\n >\n {headline}\n </div>\n );\n}\n\nfunction formatPhase(phase: string): string {\n const formatted = phase\n .replace(/([A-Z])/g, \" $1\")\n .replace(/_/g, \" \")\n .trim()\n .replace(/^\\w/, (c) => c.toUpperCase());\n return formatted === \"Player Turn\" ? \"Turn\" : formatted;\n}\n\nfunction formatPlayerList(names: readonly string[]): string {\n if (names.length === 0) return \"\";\n if (names.length === 1) return names[0]!;\n if (names.length === 2) return `${names[0]} and ${names[1]}`;\n return `${names.slice(0, -1).join(\", \")}, and ${names[names.length - 1]}`;\n}\n\ninterface HeadlineArgs {\n state: \"your-turn\" | \"waiting\" | \"phase-only\";\n activePlayerNames: readonly string[] | undefined;\n label: string;\n theme: Theme;\n reducedMotion: boolean;\n}\n\nfunction renderHeadline({\n state,\n activePlayerNames,\n label,\n theme,\n reducedMotion,\n}: HeadlineArgs) {\n if (state === \"phase-only\") {\n return (\n <div style={textBlockStyle(theme)}>\n <span style={titleTextStyle(theme)}>{label}</span>\n </div>\n );\n }\n\n const isYourTurn = state === \"your-turn\";\n const intent = isYourTurn\n ? theme.semantic.intent.success\n : theme.semantic.intent.info;\n const titleText = isYourTurn\n ? \"Your turn\"\n : `Waiting for ${formatPlayerList(activePlayerNames ?? [])}…`;\n\n return (\n <motion.div\n initial={reducedMotion ? { opacity: 0 } : { opacity: 0, y: -4 }}\n animate={reducedMotion ? { opacity: 1 } : { opacity: 1, y: 0 }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: theme.space[3],\n }}\n >\n <StatusIndicator\n intent={intent}\n kind={isYourTurn ? \"pulse\" : \"spinner\"}\n reducedMotion={reducedMotion}\n />\n <div style={textBlockStyle(theme)}>\n <span style={titleTextStyle(theme)}>{titleText}</span>\n <span style={subtitleTextStyle(theme)}>{label}</span>\n </div>\n </motion.div>\n );\n}\n\nfunction textBlockStyle(theme: Theme): React.CSSProperties {\n return {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n gap: theme.space[0.5],\n minWidth: 0,\n };\n}\n\nfunction titleTextStyle(theme: Theme): React.CSSProperties {\n return {\n fontFamily: theme.typography.fontFamily.body,\n fontSize: theme.typography.fontSize.lg,\n fontWeight: theme.typography.fontWeight.bold,\n letterSpacing: theme.typography.letterSpacing.tight,\n lineHeight: theme.typography.lineHeight.tight,\n color: theme.semantic.text.primary,\n };\n}\n\nfunction subtitleTextStyle(theme: Theme): React.CSSProperties {\n return {\n fontFamily: theme.typography.fontFamily.body,\n fontSize: theme.typography.fontSize.xs,\n fontWeight: theme.typography.fontWeight.medium,\n letterSpacing: theme.typography.letterSpacing.caps,\n textTransform: \"uppercase\",\n color: theme.semantic.text.muted,\n };\n}\n\ninterface StatusIndicatorProps {\n intent: Theme[\"semantic\"][\"intent\"][\"success\"];\n kind: \"pulse\" | \"spinner\";\n reducedMotion: boolean;\n}\n\n/**\n * Animated status indicator sized to sit next to a body-font headline.\n *\n * Kept intentionally chip-less so it shares the chrome strip's\n * understated treatment (the rest of the chrome uses bare typography\n * and lets intent colour live in chips, dots, and borders — not in\n * full-saturation surfaces). The colour comes from one\n * {@link Theme}-supplied intent ramp so swapping themes keeps the\n * indicator consistent with chips, toasts, and buttons that use the\n * same intent.\n *\n * - `pulse` — soft halo radiating outward from a solid centre dot.\n * Used for the player's own active turn.\n * - `spinner` — thin partial ring rotating around a soft-filled\n * centre. Reads as the standard \"in flight / live\" affordance.\n */\nfunction StatusIndicator({\n intent,\n kind,\n reducedMotion,\n}: StatusIndicatorProps) {\n const size = 16;\n\n if (kind === \"pulse\") {\n return (\n <span\n aria-hidden=\"true\"\n style={{\n position: \"relative\",\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: size,\n height: size,\n flexShrink: 0,\n }}\n >\n <motion.span\n style={{\n position: \"absolute\",\n inset: 2,\n borderRadius: \"9999px\",\n background: intent.soft,\n }}\n animate={\n reducedMotion\n ? undefined\n : { scale: [1, 1.6, 1], opacity: [0.7, 0, 0.7] }\n }\n transition={{\n repeat: reducedMotion ? 0 : Infinity,\n duration: 1.6,\n ease: \"easeOut\",\n }}\n />\n <span\n style={{\n position: \"relative\",\n display: \"inline-block\",\n width: 8,\n height: 8,\n borderRadius: \"9999px\",\n background: intent.solid,\n }}\n />\n </span>\n );\n }\n\n // \"spinner\" — partial ring rotating around an inset soft fill.\n return (\n <span\n aria-hidden=\"true\"\n style={{\n position: \"relative\",\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: size,\n height: size,\n flexShrink: 0,\n }}\n >\n <span\n style={{\n position: \"absolute\",\n inset: 4,\n borderRadius: \"9999px\",\n background: intent.soft,\n }}\n />\n <motion.span\n style={{\n position: \"absolute\",\n inset: 0,\n borderRadius: \"9999px\",\n border: \"2px solid transparent\",\n borderTopColor: intent.solid,\n borderRightColor: intent.solid,\n }}\n animate={reducedMotion ? undefined : { rotate: 360 }}\n transition={{\n repeat: reducedMotion ? 0 : Infinity,\n duration: 1.2,\n ease: \"linear\",\n }}\n />\n </span>\n );\n}\n","/**\n * End-of-game winner display and scoreboard overlay.\n *\n * Visual styling derives entirely from the active {@link useTheme}\n * (semantic + intent + elevation tokens). The win moment is the\n * Peak-end anchor of the session, so the surface intentionally pushes\n * the loudest theme signals (display typeface, primary intent,\n * elevation.overlay) without inventing one-off colours.\n */\n\nimport { motion } from \"framer-motion\";\nimport { Trophy, Home, Crown, Medal } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport { Dialog, DialogContent, DialogTitle } from \"../internal/ui/dialog.js\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\nimport {\n chipStyle,\n intentForVariant,\n surfaceStyle,\n type ButtonVariant,\n} from \"../theme/derive.js\";\nimport type { Theme } from \"../theme/tokens.js\";\nimport { ThemedButton } from \"./ThemedButton.js\";\n\nexport interface PlayerScore {\n playerId: string;\n name: string;\n score: number;\n isWinner?: boolean;\n details?: Record<string, number>;\n}\n\nexport interface GameEndDisplayProps {\n isGameOver: boolean;\n /** Sorted by rank */\n scores: PlayerScore[];\n winnerMessage?: string;\n showDetails?: boolean;\n onReturnToLobby?: () => void;\n className?: string;\n}\n\nfunction rankIntent(rank: number): ButtonVariant {\n if (rank === 1) return \"warning\"; // gold\n if (rank === 2) return \"secondary\"; // silver\n if (rank === 3) return \"info\"; // bronze-ish (no bronze in palette)\n return \"secondary\";\n}\n\nfunction RankIcon({ rank, theme }: { rank: number; theme: Theme }) {\n const intent = intentForVariant(theme, rankIntent(rank));\n if (rank === 1) {\n return (\n <Trophy\n width={20}\n height={20}\n strokeWidth={3}\n aria-hidden=\"true\"\n style={{ color: intent.solid }}\n />\n );\n }\n if (rank === 2 || rank === 3) {\n return (\n <Medal\n width={20}\n height={20}\n strokeWidth={2.5}\n aria-hidden=\"true\"\n style={{ color: intent.solid }}\n />\n );\n }\n return (\n <span\n style={{\n width: 20,\n textAlign: \"center\",\n color: theme.semantic.text.muted,\n fontFamily: theme.typography.fontFamily.tabular,\n fontWeight: theme.typography.fontWeight.bold,\n }}\n >\n #{rank}\n </span>\n );\n}\n\nexport function GameEndDisplay({\n isGameOver,\n scores,\n winnerMessage,\n showDetails = false,\n onReturnToLobby,\n className,\n}: GameEndDisplayProps) {\n const theme = useTheme();\n const reducedMotion = theme.motion.reducedMotion === \"true\";\n const [isOpen, setIsOpen] = useState(isGameOver);\n\n useEffect(() => {\n setIsOpen(isGameOver);\n }, [isGameOver]);\n\n if (!isGameOver) return null;\n\n const winner = scores.find((s) => s.isWinner) || scores[0];\n const sortedScores = [...scores].sort((a, b) => b.score - a.score);\n const winningIntent = theme.semantic.intent.warning;\n const title = `${winner?.name ?? \"Game\"} Wins!`;\n\n return (\n <Dialog open={isOpen} onOpenChange={setIsOpen}>\n <DialogContent\n className={`border-0 p-6 text-center shadow-none sm:max-w-lg ${className ?? \"\"}`}\n overlayClassName=\"bg-black/50 backdrop-blur-md\"\n aria-describedby={undefined}\n style={{\n ...surfaceStyle(theme, { tone: \"sheet\", radius: \"hud\" }),\n width: \"100%\",\n maxWidth: 480,\n padding: `${theme.space[8]} ${theme.space[6]}`,\n textAlign: \"center\",\n boxShadow: theme.elevation.overlay,\n overflow: \"hidden\",\n backgroundImage: `radial-gradient(circle at top, ${winningIntent.soft} 0%, ${theme.semantic.surface.sheet} 60%)`,\n fontFamily: theme.typography.fontFamily.body,\n }}\n >\n <DialogTitle className=\"sr-only\">{title}</DialogTitle>\n\n {/* Trophy badge */}\n <motion.div\n initial={\n reducedMotion\n ? { scale: 1 }\n : { scale: 0.95, rotate: -180, opacity: 0 }\n }\n animate={\n reducedMotion ? { scale: 1 } : { scale: 1, rotate: 0, opacity: 1 }\n }\n transition={{\n type: \"spring\",\n stiffness: 200,\n damping: 15,\n delay: reducedMotion ? 0 : 0.2,\n }}\n style={{\n marginBottom: theme.space[6],\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: 96,\n height: 96,\n borderRadius: theme.radius.pill,\n background: winningIntent.soft,\n border: `3px solid ${winningIntent.border}`,\n boxShadow: theme.elevation.lifted,\n }}\n >\n <Trophy\n width={48}\n height={48}\n strokeWidth={2.5}\n aria-hidden=\"true\"\n style={{ color: winningIntent.solid }}\n />\n </motion.div>\n\n <motion.div\n initial={reducedMotion ? { opacity: 0 } : { opacity: 0, y: 10 }}\n animate={reducedMotion ? { opacity: 1 } : { opacity: 1, y: 0 }}\n transition={{ delay: reducedMotion ? 0 : 0.4 }}\n >\n <h2\n aria-hidden=\"true\"\n style={{\n margin: 0,\n fontFamily: theme.typography.fontFamily.display,\n fontSize: theme.typography.fontSize[\"3xl\"],\n fontWeight: theme.typography.fontWeight.bold,\n color: theme.semantic.text.primary,\n marginBottom: theme.space[2],\n lineHeight: theme.typography.lineHeight.tight,\n }}\n >\n {title}\n </h2>\n {winnerMessage && (\n <p\n style={{\n margin: 0,\n marginBottom: theme.space[6],\n display: \"inline-block\",\n ...chipStyle(theme, { variant: \"warning\", size: \"md\" }),\n fontSize: theme.typography.fontSize.sm,\n }}\n >\n {winnerMessage}\n </p>\n )}\n </motion.div>\n\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ delay: reducedMotion ? 0 : 0.6 }}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: theme.space[3],\n marginBottom: theme.space[8],\n textAlign: \"left\",\n }}\n role=\"list\"\n aria-label=\"Final scores\"\n >\n {sortedScores.map((player, index) => {\n const rank = index + 1;\n const intent = intentForVariant(theme, rankIntent(rank));\n const isWinner = player.isWinner ?? rank === 1;\n return (\n <motion.div\n key={player.playerId}\n initial={\n reducedMotion ? { opacity: 0 } : { opacity: 0, x: -20 }\n }\n animate={reducedMotion ? { opacity: 1 } : { opacity: 1, x: 0 }}\n transition={{\n delay: reducedMotion ? 0 : 0.6 + index * 0.1,\n }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n padding: theme.space[3],\n background: isWinner\n ? intent.soft\n : theme.semantic.surface.card,\n border: `1px solid ${\n isWinner ? intent.border : theme.semantic.border.subtle\n }`,\n borderRadius: theme.radius.lg,\n boxShadow: isWinner\n ? theme.elevation.hover\n : theme.elevation.rest,\n }}\n role=\"listitem\"\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: theme.space[3],\n }}\n >\n <RankIcon rank={rank} theme={theme} />\n <span\n style={{\n fontFamily: theme.typography.fontFamily.body,\n fontSize: theme.typography.fontSize.lg,\n fontWeight: theme.typography.fontWeight.bold,\n color: isWinner\n ? intent.onSoft\n : theme.semantic.text.primary,\n }}\n >\n {player.name}\n </span>\n {isWinner && (\n <Crown\n width={20}\n height={20}\n strokeWidth={3}\n aria-label=\"Winner\"\n style={{ color: intent.solid }}\n />\n )}\n </div>\n <span\n style={{\n fontFamily: theme.typography.fontFamily.tabular,\n fontSize: theme.typography.fontSize[\"2xl\"],\n fontWeight: theme.typography.fontWeight.bold,\n color: isWinner\n ? intent.onSoft\n : theme.semantic.text.primary,\n paddingInline: theme.space[2],\n paddingBlock: theme.space[0.5],\n background: theme.semantic.surface.inset,\n borderRadius: theme.radius.md,\n border: `1px solid ${theme.semantic.border.subtle}`,\n }}\n >\n {player.score}\n </span>\n </motion.div>\n );\n })}\n </motion.div>\n\n {showDetails && winner?.details && (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ delay: reducedMotion ? 0 : 0.8 }}\n style={{\n marginBottom: theme.space[8],\n padding: theme.space[4],\n background: theme.semantic.surface.inset,\n border: `1px dashed ${theme.semantic.border.default}`,\n borderRadius: theme.radius.lg,\n textAlign: \"left\",\n }}\n >\n <h3\n style={{\n margin: 0,\n marginBottom: theme.space[3],\n fontFamily: theme.typography.fontFamily.display,\n fontSize: theme.typography.fontSize.md,\n fontWeight: theme.typography.fontWeight.bold,\n color: theme.semantic.text.primary,\n display: \"flex\",\n alignItems: \"center\",\n gap: theme.space[2],\n }}\n >\n <span\n style={{\n width: 8,\n height: 8,\n background: theme.semantic.intent.primary.solid,\n borderRadius: theme.radius.pill,\n display: \"inline-block\",\n }}\n />\n Score Breakdown\n </h3>\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: theme.space[2],\n }}\n >\n {Object.entries(winner.details).map(([key, value]) => (\n <div\n key={key}\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n fontSize: theme.typography.fontSize.md,\n color: theme.semantic.text.primary,\n }}\n >\n <span style={{ textTransform: \"capitalize\" }}>\n {key.replace(/([A-Z])/g, \" $1\")}\n </span>\n <span\n style={{\n fontFamily: theme.typography.fontFamily.tabular,\n fontWeight: theme.typography.fontWeight.bold,\n }}\n >\n {value}\n </span>\n </div>\n ))}\n </div>\n </motion.div>\n )}\n\n {onReturnToLobby && (\n <motion.div\n initial={reducedMotion ? { opacity: 0 } : { opacity: 0, y: 10 }}\n animate={reducedMotion ? { opacity: 1 } : { opacity: 1, y: 0 }}\n transition={{ delay: reducedMotion ? 0 : 1 }}\n style={{ display: \"flex\", justifyContent: \"center\" }}\n >\n <ThemedButton\n type=\"button\"\n variant=\"primary\"\n size=\"lg\"\n onClick={onReturnToLobby}\n style={{\n gap: theme.space[2],\n }}\n >\n <Home size={20} strokeWidth={3} aria-hidden=\"true\" />\n Return to Lobby\n </ThemedButton>\n </motion.div>\n )}\n </DialogContent>\n </Dialog>\n );\n}\n","/**\n * SVG-based network/graph visualization for route-building games\n * (Ticket to Ride, Pandemic, Power Grid, Brass).\n */\n\nimport { useMemo, type ReactNode } from \"react\";\nimport { clsx } from \"clsx\";\nimport { usePanZoom, calculateViewBox } from \"../../hooks/usePanZoom.js\";\nimport { handleKeyboardActivation } from \"./interaction-accessibility.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface NetworkNode {\n id: string;\n label?: string;\n position: { x: number; y: number };\n type?: string;\n data?: Record<string, unknown>;\n}\n\nexport interface NetworkEdge {\n id: string;\n from: string;\n to: string;\n label?: string | number;\n owner?: string;\n type?: string;\n data?: Record<string, unknown>;\n}\n\nexport interface NetworkPiece {\n id: string;\n nodeId: string;\n owner?: string;\n type?: string;\n data?: Record<string, unknown>;\n}\n\nexport interface NetworkGraphProps {\n nodes: NetworkNode[];\n edges: NetworkEdge[];\n pieces: NetworkPiece[];\n /** Receives node centered at its position */\n renderNode: (node: NetworkNode, pieces: NetworkPiece[]) => ReactNode;\n renderEdge: (\n edge: NetworkEdge,\n fromNode: NetworkNode,\n toNode: NetworkNode,\n ) => ReactNode;\n renderPiece: (\n piece: NetworkPiece,\n position: { x: number; y: number },\n ) => ReactNode;\n width?: number | string;\n height?: number | string;\n nodeRadius?: number;\n enablePanZoom?: boolean;\n initialZoom?: number;\n minZoom?: number;\n maxZoom?: number;\n padding?: number;\n className?: string;\n}\n\nconst EMPTY_NETWORK_EDGES: NetworkEdge[] = [];\nconst EMPTY_NETWORK_PIECES: NetworkPiece[] = [];\n\n// ============================================================================\n// Pre-built Helper Components\n// ============================================================================\n\nexport interface DefaultNetworkNodeProps {\n radius?: number;\n fill?: string;\n stroke?: string;\n strokeWidth?: number;\n isSelected?: boolean;\n isHighlighted?: boolean;\n label?: string;\n maxLabelLength?: number;\n onClick?: () => void;\n onPointerEnter?: () => void;\n onPointerLeave?: () => void;\n className?: string;\n}\n\n/** Pre-built network node for use in `renderNode`. */\nexport function DefaultNetworkNode({\n radius = 20,\n fill = \"#1e293b\",\n stroke = \"#475569\",\n strokeWidth = 2,\n isSelected = false,\n isHighlighted = false,\n label,\n maxLabelLength = 6,\n onClick,\n onPointerEnter,\n onPointerLeave,\n className,\n}: DefaultNetworkNodeProps) {\n const effectiveFill = isSelected\n ? \"#3b82f6\"\n : isHighlighted\n ? \"#22c55e\"\n : fill;\n\n const effectiveStroke = isSelected\n ? \"#60a5fa\"\n : isHighlighted\n ? \"#4ade80\"\n : stroke;\n\n const effectiveStrokeWidth = isSelected || isHighlighted ? 3 : strokeWidth;\n\n const displayLabel = label\n ? label.length > maxLabelLength\n ? label.slice(0, maxLabelLength - 1) + \"…\"\n : label\n : undefined;\n\n return (\n <g\n onClick={onClick}\n onPointerEnter={onPointerEnter}\n onPointerLeave={onPointerLeave}\n onKeyDown={(event) => handleKeyboardActivation(event, onClick)}\n className={clsx(\n \"transition-all duration-150\",\n onClick && \"cursor-pointer\",\n className,\n )}\n role={onClick ? \"button\" : undefined}\n tabIndex={onClick ? 0 : undefined}\n aria-label={onClick ? (label ?? \"Network node\") : undefined}\n >\n <circle\n r={radius}\n fill={effectiveFill}\n stroke={effectiveStroke}\n strokeWidth={effectiveStrokeWidth}\n />\n {displayLabel && (\n <text\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n fill=\"white\"\n fontSize={10}\n fontWeight=\"bold\"\n >\n {displayLabel}\n </text>\n )}\n </g>\n );\n}\n\nexport interface DefaultNetworkEdgeProps {\n from: { x: number; y: number };\n to: { x: number; y: number };\n color?: string;\n strokeWidth?: number;\n isSelected?: boolean;\n isHighlighted?: boolean;\n /** Displayed at midpoint */\n label?: string | number;\n onClick?: () => void;\n onPointerEnter?: () => void;\n onPointerLeave?: () => void;\n className?: string;\n}\n\n/** Pre-built network edge for use in `renderEdge`. */\nexport function DefaultNetworkEdge({\n from,\n to,\n color = \"#64748b\",\n strokeWidth = 3,\n isSelected = false,\n isHighlighted = false,\n label,\n onClick,\n onPointerEnter,\n onPointerLeave,\n className,\n}: DefaultNetworkEdgeProps) {\n const effectiveColor = isSelected\n ? \"#3b82f6\"\n : isHighlighted\n ? \"#22c55e\"\n : color;\n\n const effectiveWidth =\n isSelected || isHighlighted ? strokeWidth + 2 : strokeWidth;\n\n const midX = (from.x + to.x) / 2;\n const midY = (from.y + to.y) / 2;\n\n return (\n <g\n onClick={onClick}\n onPointerEnter={onPointerEnter}\n onPointerLeave={onPointerLeave}\n onKeyDown={(event) => handleKeyboardActivation(event, onClick)}\n className={clsx(\n \"transition-all duration-150\",\n onClick && \"cursor-pointer\",\n className,\n )}\n role={onClick ? \"button\" : undefined}\n tabIndex={onClick ? 0 : undefined}\n aria-label={\n onClick\n ? label !== undefined\n ? `Network edge ${label}`\n : \"Network edge\"\n : undefined\n }\n >\n <line\n x1={from.x}\n y1={from.y}\n x2={to.x}\n y2={to.y}\n stroke={effectiveColor}\n strokeWidth={effectiveWidth}\n strokeLinecap=\"round\"\n />\n {label !== undefined && (\n <>\n <circle\n cx={midX}\n cy={midY}\n r={12}\n fill=\"#1e293b\"\n stroke=\"#475569\"\n strokeWidth={1}\n />\n <text\n x={midX}\n y={midY}\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n fill=\"white\"\n fontSize={10}\n fontWeight=\"bold\"\n >\n {label}\n </text>\n </>\n )}\n </g>\n );\n}\n\nexport interface DefaultNetworkPieceProps {\n color?: string;\n radius?: number;\n shape?: \"circle\" | \"square\";\n onClick?: () => void;\n className?: string;\n}\nexport function DefaultNetworkPiece({\n color = \"#f59e0b\",\n radius = 6,\n shape = \"circle\",\n onClick,\n className,\n}: DefaultNetworkPieceProps) {\n return (\n <g\n onClick={onClick}\n onKeyDown={(event) => handleKeyboardActivation(event, onClick)}\n className={clsx(onClick && \"cursor-pointer\", className)}\n role={onClick ? \"button\" : undefined}\n tabIndex={onClick ? 0 : undefined}\n aria-label={onClick ? \"Network piece\" : undefined}\n >\n {shape === \"square\" ? (\n <rect\n x={-radius}\n y={-radius}\n width={radius * 2}\n height={radius * 2}\n fill={color}\n stroke=\"white\"\n strokeWidth={1.5}\n />\n ) : (\n <circle r={radius} fill={color} stroke=\"white\" strokeWidth={1.5} />\n )}\n </g>\n );\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport function NetworkGraph({\n nodes,\n edges = EMPTY_NETWORK_EDGES,\n pieces = EMPTY_NETWORK_PIECES,\n renderNode,\n renderEdge,\n renderPiece,\n width = 800,\n height = 600,\n nodeRadius = 20,\n enablePanZoom = false,\n initialZoom = 1,\n minZoom = 0.5,\n maxZoom = 3,\n padding = 40,\n className,\n}: NetworkGraphProps) {\n // Use the unified pan/zoom hook\n const { transform, bind, isDragging } = usePanZoom({\n enabled: enablePanZoom,\n initialZoom,\n minZoom,\n maxZoom,\n mode: \"viewbox\",\n });\n\n // Group pieces by node\n const piecesByNode = useMemo(() => {\n const map: Record<string, NetworkPiece[]> = {};\n pieces.forEach((p) => {\n const nodeId = p.nodeId;\n const existing = map[nodeId];\n if (existing) {\n existing.push(p);\n } else {\n map[nodeId] = [p];\n }\n });\n return map;\n }, [pieces]);\n\n // Create node lookup map\n const nodeMap = useMemo(() => {\n return Object.fromEntries(nodes.map((n) => [n.id, n]));\n }, [nodes]);\n\n // Calculate bounds for viewBox\n const bounds = useMemo(() => {\n if (nodes.length === 0) {\n return { minX: 0, minY: 0, width: 400, height: 300 };\n }\n\n let minX = Infinity,\n minY = Infinity,\n maxX = -Infinity,\n maxY = -Infinity;\n nodes.forEach((node) => {\n minX = Math.min(minX, node.position.x - nodeRadius);\n minY = Math.min(minY, node.position.y - nodeRadius);\n maxX = Math.max(maxX, node.position.x + nodeRadius);\n maxY = Math.max(maxY, node.position.y + nodeRadius);\n });\n\n return {\n minX: minX - padding,\n minY: minY - padding,\n width: maxX - minX + padding * 2,\n height: maxY - minY + padding * 2,\n };\n }, [nodes, nodeRadius, padding]);\n\n // Calculate viewBox with pan and zoom\n const viewBox = calculateViewBox(bounds, transform);\n\n // Parse viewBox for zoom indicator positioning\n const viewBoxParts = viewBox.split(\" \").map(Number);\n const viewBoxX = viewBoxParts[0] ?? 0;\n const viewBoxY = viewBoxParts[1] ?? 0;\n const viewBoxHeight = viewBoxParts[3] ?? 0;\n\n return (\n <svg\n width={width}\n height={height}\n viewBox={viewBox}\n className={clsx(\n \"overflow-visible\",\n enablePanZoom && \"touch-none\",\n isDragging && \"cursor-grabbing\",\n enablePanZoom && !isDragging && \"cursor-grab\",\n className,\n )}\n {...bind()}\n role=\"img\"\n aria-label=\"Network graph\"\n >\n {/* Render edges first (below nodes) */}\n <g className=\"network-edges\" role=\"list\" aria-label=\"Network connections\">\n {edges.map((edge) => {\n const fromNode = nodeMap[edge.from];\n const toNode = nodeMap[edge.to];\n if (!fromNode || !toNode) return null;\n\n return (\n <g\n key={edge.id}\n role=\"listitem\"\n aria-label={`Edge from ${fromNode.label ?? fromNode.id} to ${toNode.label ?? toNode.id}`}\n >\n {renderEdge(edge, fromNode, toNode)}\n </g>\n );\n })}\n </g>\n\n {/* Render nodes */}\n <g className=\"network-nodes\" role=\"list\" aria-label=\"Network nodes\">\n {nodes.map((node) => {\n const nodePieces = piecesByNode[node.id] ?? [];\n\n return (\n <g\n key={node.id}\n transform={`translate(${node.position.x}, ${node.position.y})`}\n role=\"listitem\"\n aria-label={node.label ?? node.id}\n >\n {renderNode(node, nodePieces)}\n\n {/* Render pieces around the node */}\n {nodePieces.length > 0 && (\n <g className=\"node-pieces\">\n {nodePieces.map((piece, i) => {\n const angle =\n (i / nodePieces.length) * 2 * Math.PI - Math.PI / 2;\n const pieceX = Math.cos(angle) * (nodeRadius + 8);\n const pieceY = Math.sin(angle) * (nodeRadius + 8);\n\n return (\n <g\n key={piece.id}\n transform={`translate(${pieceX}, ${pieceY})`}\n >\n {renderPiece(piece, { x: pieceX, y: pieceY })}\n </g>\n );\n })}\n </g>\n )}\n </g>\n );\n })}\n </g>\n\n {/* Zoom indicator */}\n {enablePanZoom && transform.zoom !== 1 && (\n <g\n transform={`translate(${viewBoxX + 10}, ${viewBoxY + viewBoxHeight - 30})`}\n >\n <rect\n x={0}\n y={0}\n width={60}\n height={20}\n rx={4}\n fill=\"rgba(0,0,0,0.6)\"\n />\n <text x={30} y={14} textAnchor=\"middle\" fill=\"white\" fontSize={12}>\n {Math.round(transform.zoom * 100)}%\n </text>\n </g>\n )}\n </svg>\n );\n}\n","import type { KeyboardEvent } from \"react\";\n\nexport function handleKeyboardActivation(\n event: KeyboardEvent,\n onActivate: (() => void) | undefined,\n options?: { stopPropagation?: boolean },\n): void {\n if (!onActivate) {\n return;\n }\n\n if (event.key !== \"Enter\" && event.key !== \" \") {\n return;\n }\n\n event.preventDefault();\n if (options?.stopPropagation) {\n event.stopPropagation();\n }\n onActivate();\n}\n","/**\n * SVG-based area control visualization for territory games (Risk, Small World, Diplomacy).\n */\n\nimport { useMemo, type ReactNode } from \"react\";\nimport { clsx } from \"clsx\";\nimport { usePanZoom } from \"../../hooks/usePanZoom.js\";\nimport { handleKeyboardActivation } from \"./interaction-accessibility.js\";\n\nexport interface ZoneShape {\n type: \"polygon\" | \"path\" | \"circle\";\n points?: Array<{ x: number; y: number }>;\n /** SVG path data */\n path?: string;\n center?: { x: number; y: number };\n radius?: number;\n}\n\nexport interface ZoneDefinition {\n id: string;\n name: string;\n adjacentTo: string[];\n shape?: ZoneShape;\n value?: number;\n type?: string;\n data?: Record<string, unknown>;\n}\n\nexport interface ZonePiece {\n id: string;\n zoneId: string;\n type: string;\n owner?: string;\n /** Count for stackable pieces (armies) */\n count?: number;\n data?: Record<string, unknown>;\n}\n\nexport interface ZoneMapProps {\n zones: ZoneDefinition[];\n pieces: ZonePiece[];\n renderZone: (zone: ZoneDefinition, pieces: ZonePiece[]) => ReactNode;\n backgroundImage?: string;\n width?: number | string;\n height?: number | string;\n enablePanZoom?: boolean;\n initialZoom?: number;\n minZoom?: number;\n maxZoom?: number;\n className?: string;\n}\n\n// ============================================================================\n// Helper Components\n// ============================================================================\n\nexport type ZoneHighlightType =\n | \"valid\"\n | \"selected\"\n | \"attack\"\n | \"defend\"\n | \"neutral\";\n\n// Highlight colors by type\nconst HIGHLIGHT_COLORS: Record<ZoneHighlightType, string> = {\n valid: \"rgba(34, 197, 94, 0.4)\", // Green\n selected: \"rgba(59, 130, 246, 0.4)\", // Blue\n attack: \"rgba(239, 68, 68, 0.4)\", // Red\n defend: \"rgba(234, 179, 8, 0.4)\", // Yellow\n neutral: \"rgba(148, 163, 184, 0.4)\", // Slate\n};\n\nconst HIGHLIGHT_STROKES: Record<ZoneHighlightType, string> = {\n valid: \"#22c55e\",\n selected: \"#3b82f6\",\n attack: \"#ef4444\",\n defend: \"#eab308\",\n neutral: \"#94a3b8\",\n};\n\nconst EMPTY_PLAYER_COLORS: Record<string, string> = {};\n\nexport interface DefaultZoneProps {\n zone: ZoneDefinition;\n fill?: string;\n stroke?: string;\n strokeWidth?: number;\n isHighlighted?: boolean;\n highlightType?: ZoneHighlightType;\n isSelected?: boolean;\n showLabel?: boolean;\n showValue?: boolean;\n onClick?: () => void;\n onHover?: (hovering: boolean) => void;\n className?: string;\n children?: ReactNode;\n}\nexport function DefaultZone({\n zone,\n fill = \"rgba(100, 116, 139, 0.2)\",\n stroke = \"#475569\",\n strokeWidth = 1,\n isHighlighted = false,\n highlightType,\n isSelected = false,\n showLabel = true,\n showValue = false,\n onClick,\n onHover,\n className,\n children,\n}: DefaultZoneProps) {\n // Calculate colors based on state\n let computedFill = fill;\n let computedStroke = stroke;\n let computedStrokeWidth = strokeWidth;\n\n if (isHighlighted && highlightType && HIGHLIGHT_COLORS[highlightType]) {\n computedFill = HIGHLIGHT_COLORS[highlightType];\n computedStroke = HIGHLIGHT_STROKES[highlightType];\n computedStrokeWidth = 3;\n } else if (isSelected) {\n computedFill = HIGHLIGHT_COLORS.selected;\n computedStroke = HIGHLIGHT_STROKES.selected;\n computedStrokeWidth = 3;\n }\n\n // Render zone shape\n const renderShape = () => {\n if (!zone.shape) return null;\n\n switch (zone.shape.type) {\n case \"polygon\":\n if (!zone.shape.points) return null;\n return (\n <polygon\n points={zone.shape.points.map((p) => `${p.x},${p.y}`).join(\" \")}\n fill={computedFill}\n stroke={computedStroke}\n strokeWidth={computedStrokeWidth}\n />\n );\n\n case \"path\":\n if (!zone.shape.path) return null;\n return (\n <path\n d={zone.shape.path}\n fill={computedFill}\n stroke={computedStroke}\n strokeWidth={computedStrokeWidth}\n />\n );\n\n case \"circle\":\n if (!zone.shape.center) return null;\n return (\n <circle\n cx={zone.shape.center.x}\n cy={zone.shape.center.y}\n r={zone.shape.radius || 30}\n fill={computedFill}\n stroke={computedStroke}\n strokeWidth={computedStrokeWidth}\n />\n );\n\n default:\n return null;\n }\n };\n\n return (\n <g\n onClick={onClick}\n onMouseEnter={() => onHover?.(true)}\n onMouseLeave={() => onHover?.(false)}\n onKeyDown={(event) => handleKeyboardActivation(event, onClick)}\n className={clsx(onClick && \"cursor-pointer\", className)}\n role={onClick ? \"button\" : \"listitem\"}\n aria-label={zone.name}\n tabIndex={onClick ? 0 : undefined}\n >\n {/* Zone shape */}\n {renderShape()}\n\n {/* Zone label */}\n {showLabel && zone.shape?.center && (\n <text\n x={zone.shape.center.x}\n y={zone.shape.center.y - (showValue ? 8 : 0)}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n fill=\"white\"\n fontSize={12}\n fontWeight=\"bold\"\n style={{ textShadow: \"1px 1px 2px rgba(0,0,0,0.8)\" }}\n >\n {zone.name}\n </text>\n )}\n\n {/* Zone value */}\n {showValue && zone.value !== undefined && zone.shape?.center && (\n <text\n x={zone.shape.center.x}\n y={zone.shape.center.y + 8}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n fill=\"#fbbf24\"\n fontSize={10}\n fontWeight=\"bold\"\n style={{ textShadow: \"1px 1px 2px rgba(0,0,0,0.8)\" }}\n >\n +{zone.value}\n </text>\n )}\n\n {/* Children (pieces) */}\n {children}\n </g>\n );\n}\n\nexport interface DefaultZonePiecesProps {\n pieces: ZonePiece[];\n zone: ZoneDefinition;\n playerColors?: Record<string, string>;\n radius?: number;\n spacing?: number;\n yOffset?: number;\n className?: string;\n}\nexport function DefaultZonePieces({\n pieces,\n zone,\n playerColors = EMPTY_PLAYER_COLORS,\n radius = 14,\n spacing = 25,\n yOffset = 20,\n className,\n}: DefaultZonePiecesProps) {\n if (pieces.length === 0 || !zone.shape?.center) return null;\n\n const centerX = zone.shape.center.x;\n const centerY = zone.shape.center.y;\n\n // Group pieces by owner\n const piecesByOwner: Record<string, ZonePiece[]> = {};\n pieces.forEach((p) => {\n const owner = p.owner || \"neutral\";\n const existing = piecesByOwner[owner];\n if (existing) {\n existing.push(p);\n } else {\n piecesByOwner[owner] = [p];\n }\n });\n\n const owners = Object.keys(piecesByOwner);\n const startOffset = -((owners.length - 1) * spacing) / 2;\n\n return (\n <g className={clsx(\"zone-pieces\", className)}>\n {owners.map((owner, i) => {\n const ownerPieces = piecesByOwner[owner] || [];\n const totalCount = ownerPieces.reduce(\n (sum, p) => sum + (p.count || 1),\n 0,\n );\n const offsetX = startOffset + i * spacing;\n\n return (\n <g\n key={owner}\n transform={`translate(${centerX + offsetX}, ${centerY + yOffset})`}\n >\n {/* Piece circle */}\n <circle\n r={radius}\n fill={playerColors[owner] || \"#64748b\"}\n stroke=\"white\"\n strokeWidth={2}\n />\n {/* Count */}\n <text\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n fill=\"white\"\n fontSize={10}\n fontWeight=\"bold\"\n >\n {totalCount}\n </text>\n </g>\n );\n })}\n </g>\n );\n}\n\nexport interface DefaultZonePieceProps {\n piece: ZonePiece;\n x?: number;\n y?: number;\n radius?: number;\n color?: string;\n onClick?: () => void;\n className?: string;\n}\nexport function DefaultZonePiece({\n piece,\n x = 0,\n y = 0,\n radius = 14,\n color = \"#64748b\",\n onClick,\n className,\n}: DefaultZonePieceProps) {\n const count = piece.count || 1;\n\n return (\n <g\n transform={`translate(${x}, ${y})`}\n onClick={(e) => {\n e.stopPropagation();\n onClick?.();\n }}\n onKeyDown={(event) =>\n handleKeyboardActivation(event, onClick, { stopPropagation: true })\n }\n className={clsx(onClick && \"cursor-pointer\", className)}\n role={onClick ? \"button\" : undefined}\n tabIndex={onClick ? 0 : undefined}\n aria-label={`Piece ${piece.id}`}\n >\n <circle r={radius} fill={color} stroke=\"white\" strokeWidth={2} />\n <text\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n fill=\"white\"\n fontSize={10}\n fontWeight=\"bold\"\n >\n {count}\n </text>\n </g>\n );\n}\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\nexport function ZoneMap({\n zones,\n pieces,\n renderZone,\n backgroundImage,\n width = 800,\n height = 600,\n enablePanZoom = false,\n initialZoom = 1,\n minZoom = 0.5,\n maxZoom = 3,\n className,\n}: ZoneMapProps) {\n // Use the unified pan/zoom hook\n const { transform, bind, isDragging } = usePanZoom({\n enabled: enablePanZoom,\n initialZoom,\n minZoom,\n maxZoom,\n mode: \"viewbox\",\n });\n\n // Group pieces by zone\n const piecesByZone = useMemo(() => {\n const map: Record<string, ZonePiece[]> = {};\n pieces.forEach((p) => {\n const existing = map[p.zoneId];\n if (existing) {\n existing.push(p);\n } else {\n map[p.zoneId] = [p];\n }\n });\n return map;\n }, [pieces]);\n\n // Calculate viewBox dimensions\n const baseWidth = typeof width === \"number\" ? width : 800;\n const baseHeight = typeof height === \"number\" ? height : 600;\n const viewBoxWidth = baseWidth / transform.zoom;\n const viewBoxHeight = baseHeight / transform.zoom;\n const viewBoxX = (baseWidth - viewBoxWidth) / 2 - transform.pan.x;\n const viewBoxY = (baseHeight - viewBoxHeight) / 2 - transform.pan.y;\n\n return (\n <svg\n width={width}\n height={height}\n viewBox={`${viewBoxX} ${viewBoxY} ${viewBoxWidth} ${viewBoxHeight}`}\n className={clsx(\n \"overflow-visible\",\n enablePanZoom && \"touch-none\",\n isDragging && \"cursor-grabbing\",\n enablePanZoom && !isDragging && \"cursor-grab\",\n className,\n )}\n {...bind()}\n role=\"img\"\n aria-label=\"Zone map\"\n >\n {/* Background image */}\n {backgroundImage && (\n <image href={backgroundImage} width={width} height={height} />\n )}\n\n {/* Zones */}\n <g className=\"zones\" role=\"list\" aria-label=\"Map zones\">\n {zones.map((zone) => {\n const zonePieces = piecesByZone[zone.id] || [];\n return <g key={zone.id}>{renderZone(zone, zonePieces)}</g>;\n })}\n </g>\n\n {/* Zoom indicator */}\n {enablePanZoom && transform.zoom !== 1 && (\n <g\n transform={`translate(${viewBoxX + 10}, ${viewBoxY + viewBoxHeight - 30})`}\n >\n <rect\n x={0}\n y={0}\n width={60}\n height={20}\n rx={4}\n fill=\"rgba(0,0,0,0.6)\"\n />\n <text x={30} y={14} textAnchor=\"middle\" fill=\"white\" fontSize={12}>\n {Math.round(transform.zoom * 100)}%\n </text>\n </g>\n )}\n </svg>\n );\n}\n","/**\n * SVG-based track visualization for racing and path games\n * (Monopoly, Game of Life, Snakes & Ladders). Supports linear, circular, and branching tracks.\n */\n\nimport { useMemo, type ReactNode } from \"react\";\nimport { clsx } from \"clsx\";\nimport { usePanZoom } from \"../../hooks/usePanZoom.js\";\nimport { handleKeyboardActivation } from \"./interaction-accessibility.js\";\n\nexport interface TrackSpace<\n SpaceIdValue extends string = string,\n Data = unknown,\n> {\n id: SpaceIdValue;\n index: number;\n name?: string;\n type?: string;\n /** Override next spaces (for branching) */\n nextSpaces?: readonly SpaceIdValue[];\n /** Jump to another space (snakes/ladders) */\n jumpTo?: SpaceIdValue;\n position: { x: number; y: number };\n data?: Data;\n}\n\nexport interface TrackPiece<\n PieceIdValue extends string = string,\n SpaceIdValue extends string = string,\n OwnerIdValue extends string = string,\n Data = unknown,\n> {\n id: PieceIdValue;\n spaceId: SpaceIdValue;\n owner: OwnerIdValue;\n type?: string;\n data?: Data;\n}\n\nexport interface TrackBoardProps {\n spaces: TrackSpace[];\n pieces: TrackPiece[];\n type?: \"linear\" | \"circular\" | \"branching\";\n renderSpace: (space: TrackSpace, pieces: TrackPiece[]) => ReactNode;\n renderConnection?: (\n from: { x: number; y: number },\n to: { x: number; y: number },\n fromSpace: TrackSpace,\n toSpace: TrackSpace,\n ) => ReactNode;\n renderJump?: (\n from: { x: number; y: number },\n to: { x: number; y: number },\n fromSpace: TrackSpace,\n toSpace: TrackSpace,\n isUp: boolean,\n ) => ReactNode;\n width?: number | string;\n height?: number | string;\n enablePanZoom?: boolean;\n initialZoom?: number;\n minZoom?: number;\n maxZoom?: number;\n className?: string;\n}\n\n// ============================================================================\n// Helper Components\n// ============================================================================\n\nexport interface DefaultTrackSpaceProps {\n space: TrackSpace;\n size?: number;\n fill?: string;\n stroke?: string;\n strokeWidth?: number;\n isHighlighted?: boolean;\n isSelected?: boolean;\n showJumpIndicator?: boolean;\n onClick?: () => void;\n onHover?: (hovering: boolean) => void;\n className?: string;\n children?: ReactNode;\n}\nexport function DefaultTrackSpace({\n space,\n size = 50,\n fill = \"#1e293b\",\n stroke = \"#475569\",\n strokeWidth = 1,\n isHighlighted = false,\n isSelected = false,\n showJumpIndicator = true,\n onClick,\n onHover,\n className,\n children,\n}: DefaultTrackSpaceProps) {\n const halfSize = size / 2;\n\n const computedFill = isHighlighted ? \"rgba(59, 130, 246, 0.3)\" : fill;\n const computedStroke = isSelected\n ? \"#3b82f6\"\n : isHighlighted\n ? \"#60a5fa\"\n : stroke;\n const computedStrokeWidth = isHighlighted || isSelected ? 3 : strokeWidth;\n\n return (\n <g\n onClick={onClick}\n onMouseEnter={() => onHover?.(true)}\n onMouseLeave={() => onHover?.(false)}\n onKeyDown={(event) => handleKeyboardActivation(event, onClick)}\n className={clsx(onClick && \"cursor-pointer\", className)}\n role={onClick ? \"button\" : \"listitem\"}\n aria-label={space.name || `Space ${space.index}`}\n tabIndex={onClick ? 0 : undefined}\n >\n {/* Space background */}\n <rect\n x={-halfSize}\n y={-halfSize}\n width={size}\n height={size}\n rx={8}\n fill={computedFill}\n stroke={computedStroke}\n strokeWidth={computedStrokeWidth}\n />\n\n {/* Space name or index */}\n {space.name ? (\n <text\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n fill=\"white\"\n fontSize={space.name.length > 4 ? 8 : 10}\n fontWeight=\"bold\"\n >\n {space.name.length > 8 ? space.name.slice(0, 7) + \"…\" : space.name}\n </text>\n ) : (\n <text\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n fill=\"#94a3b8\"\n fontSize={12}\n fontWeight=\"bold\"\n >\n {space.index}\n </text>\n )}\n\n {/* Jump indicator */}\n {showJumpIndicator && space.jumpTo && (\n <g transform={`translate(${halfSize - 6}, ${-halfSize + 6})`}>\n <circle r={6} fill=\"#fbbf24\" />\n <text\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n fill=\"black\"\n fontSize={8}\n fontWeight=\"bold\"\n >\n ↗\n </text>\n </g>\n )}\n\n {/* Pieces */}\n {children}\n </g>\n );\n}\n\nexport interface DefaultTrackPieceProps {\n piece: TrackPiece;\n index?: number;\n total?: number;\n radius?: number;\n color?: string;\n onClick?: () => void;\n className?: string;\n}\nexport function DefaultTrackPiece({\n piece,\n index = 0,\n total = 1,\n radius = 8,\n color = \"#f59e0b\",\n onClick,\n className,\n}: DefaultTrackPieceProps) {\n // Arrange pieces in a circle around the space center\n const spacing = radius * 2.2;\n const angle = (index / total) * 2 * Math.PI - Math.PI / 2;\n const offset = total > 1 ? spacing : 0;\n const px = Math.cos(angle) * offset;\n const py = Math.sin(angle) * offset;\n\n return (\n <circle\n cx={px}\n cy={py}\n r={radius}\n fill={color}\n stroke=\"white\"\n strokeWidth={2}\n onClick={(e) => {\n e.stopPropagation();\n onClick?.();\n }}\n onKeyDown={(event) =>\n handleKeyboardActivation(event, onClick, { stopPropagation: true })\n }\n className={clsx(onClick && \"cursor-pointer\", className)}\n role={onClick ? \"button\" : undefined}\n tabIndex={onClick ? 0 : undefined}\n aria-label={`Piece ${piece.id} owned by ${piece.owner}`}\n />\n );\n}\n\nexport interface DefaultTrackConnectionProps {\n from: { x: number; y: number };\n to: { x: number; y: number };\n stroke?: string;\n strokeWidth?: number;\n className?: string;\n}\nexport function DefaultTrackConnection({\n from,\n to,\n stroke = \"#475569\",\n strokeWidth = 2,\n className,\n}: DefaultTrackConnectionProps) {\n return (\n <line\n x1={from.x}\n y1={from.y}\n x2={to.x}\n y2={to.y}\n stroke={stroke}\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n className={className}\n />\n );\n}\n\nexport interface DefaultTrackJumpProps {\n from: { x: number; y: number };\n to: { x: number; y: number };\n /** Whether the jump goes forward or backward */\n isUp: boolean;\n spaceSize?: number;\n upColor?: string;\n downColor?: string;\n strokeWidth?: number;\n className?: string;\n}\nexport function DefaultTrackJump({\n from,\n to,\n isUp,\n spaceSize = 50,\n upColor = \"#22c55e\",\n downColor = \"#ef4444\",\n strokeWidth = 3,\n className,\n}: DefaultTrackJumpProps) {\n const color = isUp ? upColor : downColor;\n\n // Calculate arrow direction\n const dx = to.x - from.x;\n const dy = to.y - from.y;\n const len = Math.sqrt(dx * dx + dy * dy);\n const unitX = dx / len;\n const unitY = dy / len;\n\n // Offset start and end points\n const startX = from.x + unitX * (spaceSize / 2 + 5);\n const startY = from.y + unitY * (spaceSize / 2 + 5);\n const endX = to.x - unitX * (spaceSize / 2 + 5);\n const endY = to.y - unitY * (spaceSize / 2 + 5);\n\n // Generate unique marker IDs\n const markerId = `arrow-${isUp ? \"up\" : \"down\"}-${from.x}-${from.y}`;\n\n return (\n <g className={className}>\n <defs>\n <marker\n id={markerId}\n markerWidth=\"10\"\n markerHeight=\"7\"\n refX=\"9\"\n refY=\"3.5\"\n orient=\"auto\"\n >\n <polygon points=\"0 0, 10 3.5, 0 7\" fill={color} />\n </marker>\n </defs>\n <line\n x1={startX}\n y1={startY}\n x2={endX}\n y2={endY}\n stroke={color}\n strokeWidth={strokeWidth}\n strokeDasharray=\"6,4\"\n markerEnd={`url(#${markerId})`}\n />\n </g>\n );\n}\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\nexport function TrackBoard({\n spaces,\n pieces,\n type = \"linear\",\n renderSpace,\n renderConnection,\n renderJump,\n width = 800,\n height = 600,\n enablePanZoom = false,\n initialZoom = 1,\n minZoom = 0.5,\n maxZoom = 3,\n className,\n}: TrackBoardProps) {\n // Use the unified pan/zoom hook\n const { transform, bind, isDragging } = usePanZoom({\n enabled: enablePanZoom,\n initialZoom,\n minZoom,\n maxZoom,\n mode: \"viewbox\",\n });\n\n // Group pieces by space\n const piecesBySpace = useMemo(() => {\n const map: Record<string, TrackPiece[]> = {};\n pieces.forEach((p) => {\n const existing = map[p.spaceId];\n if (existing) {\n existing.push(p);\n } else {\n map[p.spaceId] = [p];\n }\n });\n return map;\n }, [pieces]);\n\n // Sort spaces by index for drawing connections\n const sortedSpaces = useMemo(() => {\n return [...spaces].sort((a, b) => a.index - b.index);\n }, [spaces]);\n\n // Create space lookup\n const spaceMap = useMemo(() => {\n return new Map(spaces.map((s) => [s.id, s]));\n }, [spaces]);\n\n // Render connections between spaces\n const renderConnections = () => {\n if (!renderConnection) return null;\n\n return sortedSpaces.map((space, i) => {\n const nextSpace = sortedSpaces[i + 1];\n const firstSpace = sortedSpaces[0];\n const nextSpaceIds =\n space.nextSpaces ||\n (i < sortedSpaces.length - 1 && nextSpace\n ? [nextSpace.id]\n : type === \"circular\" && firstSpace\n ? [firstSpace.id]\n : []);\n\n return nextSpaceIds.map((nextId) => {\n const targetSpace = spaceMap.get(nextId);\n if (!targetSpace) return null;\n\n return (\n <g key={`${space.id}-${nextId}`}>\n {renderConnection(\n space.position,\n targetSpace.position,\n space,\n targetSpace,\n )}\n </g>\n );\n });\n });\n };\n\n // Render jump arrows (snakes/ladders)\n const renderJumps = () => {\n if (!renderJump) return null;\n\n return spaces.flatMap((space) => {\n if (!space.jumpTo) return [];\n const targetSpace = spaceMap.get(space.jumpTo);\n if (!targetSpace) return [];\n\n const isUp = targetSpace.index > space.index;\n\n return [\n <g key={`jump-${space.id}`}>\n {renderJump(\n space.position,\n targetSpace.position,\n space,\n targetSpace,\n isUp,\n )}\n </g>,\n ];\n });\n };\n\n // Calculate viewBox dimensions\n const baseWidth = typeof width === \"number\" ? width : 800;\n const baseHeight = typeof height === \"number\" ? height : 600;\n const viewBoxWidth = baseWidth / transform.zoom;\n const viewBoxHeight = baseHeight / transform.zoom;\n const viewBoxX = (baseWidth - viewBoxWidth) / 2 - transform.pan.x;\n const viewBoxY = (baseHeight - viewBoxHeight) / 2 - transform.pan.y;\n\n return (\n <svg\n width={width}\n height={height}\n viewBox={`${viewBoxX} ${viewBoxY} ${viewBoxWidth} ${viewBoxHeight}`}\n className={clsx(\n \"overflow-visible\",\n enablePanZoom && \"touch-none\",\n isDragging && \"cursor-grabbing\",\n enablePanZoom && !isDragging && \"cursor-grab\",\n className,\n )}\n {...bind()}\n role=\"img\"\n aria-label=\"Track board\"\n >\n {/* Connections layer */}\n <g className=\"track-connections\">{renderConnections()}</g>\n\n {/* Jump arrows layer */}\n <g className=\"track-jumps\">{renderJumps()}</g>\n\n {/* Spaces layer */}\n <g className=\"track-spaces\" role=\"list\" aria-label=\"Track spaces\">\n {spaces.map((space) => {\n const spacePieces = piecesBySpace[space.id] || [];\n\n return (\n <g\n key={space.id}\n transform={`translate(${space.position.x}, ${space.position.y})`}\n >\n {renderSpace(space, spacePieces)}\n </g>\n );\n })}\n </g>\n\n {/* Zoom indicator */}\n {enablePanZoom && transform.zoom !== 1 && (\n <g\n transform={`translate(${viewBoxX + 10}, ${viewBoxY + viewBoxHeight - 30})`}\n >\n <rect\n x={0}\n y={0}\n width={60}\n height={20}\n rx={4}\n fill=\"rgba(0,0,0,0.6)\"\n />\n <text x={30} y={14} textAnchor=\"middle\" fill=\"white\" fontSize={12}>\n {Math.round(transform.zoom * 100)}%\n </text>\n </g>\n )}\n </svg>\n );\n}\n","/**\n * Worker placement visualization for Euro games (Agricola, Viticulture, Lords of Waterdeep).\n */\n\nimport { useMemo, type ReactNode } from \"react\";\nimport { clsx } from \"clsx\";\nimport { Users, Lock, Gift, Coins } from \"lucide-react\";\nimport type { ViewSlotOccupant } from \"../../../types/index.js\";\nimport { useTheme } from \"../../theme/ThemeProvider.js\";\nimport { handleKeyboardActivation } from \"./interaction-accessibility.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface SlotDefinition {\n id: string;\n name: string;\n description?: string;\n capacity: number;\n /** One player per round */\n exclusive?: boolean;\n /** Personal action space owner */\n owner?: string;\n group?: string;\n cost?: Record<string, number>;\n reward?: Record<string, number>;\n type?: string;\n position?: { x: number; y: number };\n data?: Record<string, unknown>;\n}\n\nexport type SlotOccupant = ViewSlotOccupant;\n\nexport interface SlotSystemProps {\n slots: readonly SlotDefinition[];\n occupants: readonly SlotOccupant[];\n renderSlot: (\n slot: SlotDefinition,\n occupants: readonly SlotOccupant[],\n ) => ReactNode;\n layout?: \"grid\" | \"list\" | \"grouped\";\n width?: number | string;\n height?: number | string;\n /** Minimum slot width for responsive grid */\n minSlotWidth?: number;\n className?: string;\n}\n\nconst EMPTY_SLOT_OCCUPANTS: readonly SlotOccupant[] = [];\n\n// ============================================================================\n// Pre-built Helper Components\n// ============================================================================\n\nexport interface DefaultSlotItemProps {\n name: string;\n description?: string;\n capacity: number;\n occupantCount: number;\n isExclusive?: boolean;\n isAvailable?: boolean;\n isHighlighted?: boolean;\n isSelected?: boolean;\n costLabel?: string;\n rewardLabel?: string;\n renderOccupants?: () => ReactNode;\n onClick?: () => void;\n onPointerEnter?: () => void;\n onPointerLeave?: () => void;\n className?: string;\n}\n\n/** Pre-built slot item for use in `renderSlot`. */\nexport function DefaultSlotItem({\n name,\n description,\n capacity,\n occupantCount,\n isExclusive = false,\n isAvailable = true,\n isHighlighted = false,\n isSelected = false,\n costLabel,\n rewardLabel,\n renderOccupants,\n onClick,\n onPointerEnter,\n onPointerLeave,\n className,\n}: DefaultSlotItemProps) {\n const theme = useTheme();\n const isFull = occupantCount >= capacity;\n const borderColor = isSelected\n ? theme.semantic.intent.primary.border\n : isFull\n ? theme.semantic.border.strong\n : isAvailable\n ? theme.semantic.border.default\n : theme.semantic.border.subtle;\n const background = isSelected\n ? theme.semantic.intent.primary.soft\n : isFull\n ? theme.semantic.surface.inset\n : theme.semantic.surface.card;\n const ringColor = isSelected\n ? theme.semantic.intent.primary.border\n : isHighlighted\n ? theme.semantic.intent.warning.border\n : undefined;\n\n return (\n <div\n onClick={isAvailable ? onClick : undefined}\n onPointerEnter={onPointerEnter}\n onPointerLeave={onPointerLeave}\n onKeyDown={(event) =>\n handleKeyboardActivation(event, isAvailable ? onClick : undefined)\n }\n className={clsx(\n \"p-4 rounded-lg border-2 transition-all\",\n isAvailable && onClick && \"cursor-pointer hover:opacity-90\",\n className,\n )}\n style={{\n borderColor,\n background,\n boxShadow: ringColor ? `0 0 0 2px ${ringColor}` : undefined,\n }}\n role={isAvailable && onClick ? \"button\" : undefined}\n aria-label={name}\n aria-disabled={!isAvailable}\n tabIndex={isAvailable && onClick ? 0 : undefined}\n >\n {/* Header */}\n <div className=\"flex items-start justify-between gap-2\">\n <div>\n <h3\n className=\"font-bold\"\n style={{ color: theme.semantic.text.primary }}\n >\n {name}\n </h3>\n {description && (\n <p\n className=\"text-xs mt-0.5\"\n style={{ color: theme.semantic.text.muted }}\n >\n {description}\n </p>\n )}\n </div>\n\n {/* Status indicators */}\n <div className=\"flex items-center gap-1\">\n {isExclusive && (\n <Lock\n className=\"w-4 h-4\"\n style={{ color: theme.semantic.intent.warning.solid }}\n aria-label=\"Exclusive slot\"\n />\n )}\n {capacity > 1 && (\n <div\n className=\"flex items-center gap-0.5 text-xs\"\n style={{ color: theme.semantic.text.muted }}\n title={`Capacity: ${capacity}`}\n >\n <Users className=\"w-3 h-3\" />\n <span>{capacity}</span>\n </div>\n )}\n </div>\n </div>\n\n {/* Cost/Reward */}\n {(costLabel || rewardLabel) && (\n <div className=\"mt-2 flex flex-wrap gap-2 text-xs\">\n {costLabel && (\n <div\n className=\"flex items-center gap-1\"\n style={{ color: theme.semantic.intent.danger.solid }}\n >\n <Coins className=\"w-3 h-3\" aria-hidden=\"true\" />\n <span>{costLabel}</span>\n </div>\n )}\n {rewardLabel && (\n <div\n className=\"flex items-center gap-1\"\n style={{ color: theme.semantic.intent.success.solid }}\n >\n <Gift className=\"w-3 h-3\" aria-hidden=\"true\" />\n <span>{rewardLabel}</span>\n </div>\n )}\n </div>\n )}\n\n {/* Occupants */}\n {renderOccupants && <div className=\"mt-2\">{renderOccupants()}</div>}\n\n {/* Availability indicator */}\n {!isAvailable && !isFull && (\n <div\n className=\"mt-2 text-xs\"\n style={{ color: theme.semantic.text.disabled }}\n >\n Not available\n </div>\n )}\n </div>\n );\n}\n\nexport interface DefaultSlotOccupantProps {\n color?: string;\n size?: number;\n shape?: \"circle\" | \"square\";\n label?: string;\n onClick?: () => void;\n className?: string;\n}\nexport function DefaultSlotOccupant({\n color = \"#3b82f6\",\n size = 24,\n shape = \"circle\",\n label,\n onClick,\n className,\n}: DefaultSlotOccupantProps) {\n return (\n <div\n onClick={onClick}\n onKeyDown={(event) => handleKeyboardActivation(event, onClick)}\n className={clsx(\n \"transition-all\",\n shape === \"circle\" ? \"rounded-full\" : \"rounded\",\n onClick && \"cursor-pointer hover:scale-110\",\n className,\n )}\n style={{\n width: size,\n height: size,\n backgroundColor: color,\n }}\n title={label}\n role={onClick ? \"button\" : \"img\"}\n aria-label={label ?? \"Occupant\"}\n tabIndex={onClick ? 0 : undefined}\n />\n );\n}\n\nexport interface DefaultEmptySlotProps {\n size?: number;\n className?: string;\n}\nexport function DefaultEmptySlot({\n size = 24,\n className,\n}: DefaultEmptySlotProps) {\n const theme = useTheme();\n\n return (\n <div\n className={clsx(\"rounded-full border-2 border-dashed\", className)}\n style={{\n width: size,\n height: size,\n borderColor: theme.semantic.border.default,\n }}\n title=\"Empty slot\"\n role=\"img\"\n aria-label=\"Empty slot\"\n />\n );\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport function SlotSystem({\n slots,\n occupants = EMPTY_SLOT_OCCUPANTS,\n renderSlot,\n layout = \"grid\",\n width,\n height,\n minSlotWidth = 280,\n className,\n}: SlotSystemProps) {\n const theme = useTheme();\n\n // Group occupants by slot\n const occupantsBySlot = useMemo(() => {\n const map: Record<string, SlotOccupant[]> = {};\n occupants.forEach((o) => {\n const slotId = o.slotId;\n const existing = map[slotId];\n if (existing) {\n existing.push(o);\n } else {\n map[slotId] = [o];\n }\n });\n return map;\n }, [occupants]);\n\n // Group slots by group property for grouped layout\n const slotGroups = useMemo(() => {\n if (layout !== \"grouped\") return null;\n\n const groups: Record<string, SlotDefinition[]> = {};\n slots.forEach((slot) => {\n const group = slot.group ?? \"Other\";\n const existing = groups[group];\n if (existing) {\n existing.push(slot);\n } else {\n groups[group] = [slot];\n }\n });\n return groups;\n }, [slots, layout]);\n\n // Render a single slot\n const renderSlotItem = (slot: SlotDefinition) => {\n const slotOccupants = occupantsBySlot[slot.id] ?? [];\n\n return (\n <div key={slot.id} role=\"listitem\" aria-label={slot.name}>\n {renderSlot(slot, slotOccupants)}\n </div>\n );\n };\n\n // Responsive grid style - uses auto-fit to stack items when they don't fit\n const responsiveGridStyle = {\n display: \"grid\",\n gridTemplateColumns: `repeat(auto-fit, minmax(${minSlotWidth}px, 1fr))`,\n gap: \"1rem\",\n };\n\n // Container wrapper\n const wrapContent = (content: ReactNode) => (\n <div style={{ width, height }} className={clsx(\"slot-system\", className)}>\n {content}\n </div>\n );\n\n // Render based on layout\n if (layout === \"grouped\" && slotGroups) {\n return wrapContent(\n <div className=\"space-y-6\" role=\"list\">\n {Object.entries(slotGroups).map(([groupName, groupSlots]) => (\n <div key={groupName}>\n <h3\n className=\"text-lg font-semibold mb-3\"\n style={{ color: theme.semantic.text.primary }}\n >\n {groupName}\n </h3>\n <div style={responsiveGridStyle}>\n {groupSlots.map(renderSlotItem)}\n </div>\n </div>\n ))}\n </div>,\n );\n }\n\n if (layout === \"list\") {\n return wrapContent(\n <div className=\"flex flex-col gap-2\" role=\"list\">\n {slots.map(renderSlotItem)}\n </div>,\n );\n }\n\n // Default grid layout - responsive by default\n return wrapContent(\n <div style={responsiveGridStyle} role=\"list\">\n {slots.map(renderSlotItem)}\n </div>,\n );\n}\n","/**\n * SVG-based square grid for grid-based games (Chess, Checkers, Go, Scrabble, Battleship).\n * All rendering controlled by parent via required render functions.\n */\n\nimport { useMemo, useState, type ReactNode } from \"react\";\nimport { clsx } from \"clsx\";\nimport { usePanZoom } from \"../../hooks/usePanZoom.js\";\nimport { handleKeyboardActivation } from \"./interaction-accessibility.js\";\nimport {\n interactiveTargetRenderState,\n isInteractiveTargetSelectable,\n type InteractiveTargetLayer,\n type InteractiveTargetRenderState,\n} from \"./target-layer.js\";\nimport type { SquarePieceState } from \"../../types/player-state.js\";\nimport {\n type AuthoredSquareBoardInput,\n type AnySquareBoardInput,\n type GeneratedSquareBoardInput,\n type NormalizedSquareBoard,\n type NormalizedSquareCellOf,\n type NormalizedSquareEdgeOf,\n type NormalizedSquarePieceOf,\n type NormalizedSquareVertexOf,\n normalizeSquareBoardInput,\n} from \"../../types/tiled-board.js\";\n\nexport type {\n InteractiveTargetLayer,\n InteractiveTargetRenderState,\n} from \"./target-layer.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface SquareCellWithId {\n id: string;\n row: number;\n col: number;\n}\n\nexport interface SquareEdgePosition {\n x1: number;\n y1: number;\n x2: number;\n y2: number;\n midX: number;\n midY: number;\n angle: number;\n}\n\nexport interface SquareVertexPosition {\n x: number;\n y: number;\n}\n\nexport interface InteractiveSquareEdge<\n TBoard extends AnySquareBoardInput = AnySquareBoardInput,\n> extends NormalizedSquareEdgeOf<TBoard> {\n position: SquareEdgePosition;\n}\n\nexport interface InteractiveSquareVertex<\n TBoard extends AnySquareBoardInput = AnySquareBoardInput,\n> extends NormalizedSquareVertexOf<TBoard> {\n position: SquareVertexPosition;\n}\n\nexport type InteractiveSquareSpace<\n TBoard extends AnySquareBoardInput = AnySquareBoardInput,\n> = NormalizedSquareCellOf<TBoard>;\n\ninterface SquareGeneratedGridInputProps {\n id?: string;\n layout?: \"square\";\n spaces: Extract<AnySquareBoardInput, { spaces: unknown }>[\"spaces\"];\n pieces?: AnySquareBoardInput[\"pieces\"];\n edges?: AnySquareBoardInput[\"edges\"];\n vertices?: AnySquareBoardInput[\"vertices\"];\n}\n\ninterface SquareAuthoredGridInputProps {\n id?: string;\n layout?: \"square\";\n rows?: number;\n cols?: number;\n cells: Extract<AnySquareBoardInput, { cells: unknown }>[\"cells\"];\n pieces?: readonly SquarePieceState[];\n edges?: AnySquareBoardInput[\"edges\"];\n vertices?: AnySquareBoardInput[\"vertices\"];\n}\n\ntype SquareGridInputProps =\n | SquareGeneratedGridInputProps\n | SquareAuthoredGridInputProps;\n\ntype ResolvedSquareArrayProp<Value> =\n Exclude<Value, undefined> extends readonly unknown[]\n ? Exclude<Value, undefined>\n : readonly [];\n\ntype SquareBoardLikeOfProps<TProps extends SquareGridInputProps> =\n TProps extends {\n id?: infer Id;\n layout?: infer Layout;\n spaces: infer Spaces;\n pieces?: infer Pieces;\n edges?: infer Edges;\n vertices?: infer Vertices;\n }\n ? {\n id: Extract<Id, string> extends never ? string : Extract<Id, string>;\n layout?: Extract<Layout, \"square\">;\n spaces: Spaces;\n pieces: ResolvedSquareArrayProp<Pieces>;\n edges: ResolvedSquareArrayProp<Edges>;\n vertices: ResolvedSquareArrayProp<Vertices>;\n } & GeneratedSquareBoardInput\n : TProps extends {\n id?: infer Id;\n layout?: infer Layout;\n rows?: infer Rows;\n cols?: infer Cols;\n cells: infer Cells;\n pieces?: infer Pieces;\n edges?: infer Edges;\n vertices?: infer Vertices;\n }\n ? {\n id: Extract<Id, string> extends never ? string : Extract<Id, string>;\n layout?: Extract<Layout, \"square\">;\n rows: Extract<Rows, number> extends never\n ? number\n : Extract<Rows, number>;\n cols: Extract<Cols, number> extends never\n ? number\n : Extract<Cols, number>;\n cells: Cells;\n pieces: ResolvedSquareArrayProp<Pieces>;\n edges: ResolvedSquareArrayProp<Edges>;\n vertices: ResolvedSquareArrayProp<Vertices>;\n } & AuthoredSquareBoardInput\n : never;\n\nexport type SquareGridProps<\n TProps extends SquareGridInputProps = SquareGridInputProps,\n> = TProps & {\n cellSize?: number;\n /** Receives row/col with transform centered at cell position */\n renderCell: (row: number, col: number) => ReactNode;\n /** Receives piece with transform centered at cell center */\n renderPiece: (\n piece: NormalizedSquarePieceOf<NoInfer<SquareBoardLikeOfProps<TProps>>>,\n ) => ReactNode;\n renderEdge?: (\n edge: NormalizedSquareEdgeOf<NoInfer<SquareBoardLikeOfProps<TProps>>>,\n position: SquareEdgePosition,\n ) => ReactNode;\n renderVertex?: (\n vertex: NormalizedSquareVertexOf<NoInfer<SquareBoardLikeOfProps<TProps>>>,\n position: SquareVertexPosition,\n ) => ReactNode;\n showCoordinates?: boolean;\n coordinateStyle?: \"algebraic\" | \"numeric\" | \"none\";\n width?: number | string;\n height?: number | string;\n enablePanZoom?: boolean;\n initialZoom?: number;\n minZoom?: number;\n maxZoom?: number;\n className?: string;\n interactiveSpaces?: InteractiveTargetLayer;\n interactiveEdges?: InteractiveTargetLayer;\n interactiveVertices?: InteractiveTargetLayer;\n renderInteractiveSpace?: (\n space: InteractiveSquareSpace<NoInfer<SquareBoardLikeOfProps<TProps>>>,\n state: InteractiveTargetRenderState,\n ) => ReactNode;\n renderInteractiveEdge?: (\n edge: InteractiveSquareEdge<NoInfer<SquareBoardLikeOfProps<TProps>>>,\n position: SquareEdgePosition,\n state: InteractiveTargetRenderState,\n ) => ReactNode;\n renderInteractiveVertex?: (\n vertex: InteractiveSquareVertex<NoInfer<SquareBoardLikeOfProps<TProps>>>,\n position: SquareVertexPosition,\n state: InteractiveTargetRenderState,\n ) => ReactNode;\n};\n\nexport interface SquareGridBoardProps<\n TBoard extends AnySquareBoardInput = AnySquareBoardInput,\n> {\n board: TBoard;\n cellSize?: number;\n renderCell: (row: number, col: number) => ReactNode;\n renderPiece: (piece: NormalizedSquarePieceOf<NoInfer<TBoard>>) => ReactNode;\n renderEdge?: (\n edge: NormalizedSquareEdgeOf<NoInfer<TBoard>>,\n position: SquareEdgePosition,\n ) => ReactNode;\n renderVertex?: (\n vertex: NormalizedSquareVertexOf<NoInfer<TBoard>>,\n position: SquareVertexPosition,\n ) => ReactNode;\n showCoordinates?: boolean;\n coordinateStyle?: \"algebraic\" | \"numeric\" | \"none\";\n width?: number | string;\n height?: number | string;\n enablePanZoom?: boolean;\n initialZoom?: number;\n minZoom?: number;\n maxZoom?: number;\n className?: string;\n interactiveSpaces?: InteractiveTargetLayer;\n interactiveEdges?: InteractiveTargetLayer;\n interactiveVertices?: InteractiveTargetLayer;\n renderInteractiveSpace?: (\n space: InteractiveSquareSpace<NoInfer<TBoard>>,\n state: InteractiveTargetRenderState,\n ) => ReactNode;\n renderInteractiveEdge?: (\n edge: InteractiveSquareEdge<NoInfer<TBoard>>,\n position: SquareEdgePosition,\n state: InteractiveTargetRenderState,\n ) => ReactNode;\n renderInteractiveVertex?: (\n vertex: InteractiveSquareVertex<NoInfer<TBoard>>,\n position: SquareVertexPosition,\n state: InteractiveTargetRenderState,\n ) => ReactNode;\n}\n\n// ============================================================================\n// Pre-built Helper Components\n// ============================================================================\n\nexport interface DefaultGridCellProps {\n size: number;\n isLight?: boolean;\n lightColor?: string;\n darkColor?: string;\n isHighlighted?: boolean;\n highlightColor?: string;\n isSelected?: boolean;\n selectedColor?: string;\n isValidMove?: boolean;\n isCapture?: boolean;\n onClick?: () => void;\n onPointerEnter?: () => void;\n onPointerLeave?: () => void;\n className?: string;\n}\n\n/** Pre-built grid cell component for use in `renderCell`. */\nexport function DefaultGridCell({\n size,\n isLight = true,\n lightColor = \"#f0d9b5\",\n darkColor = \"#b58863\",\n isHighlighted = false,\n highlightColor = \"rgba(250, 204, 21, 0.4)\",\n isSelected = false,\n selectedColor = \"rgba(59, 130, 246, 0.5)\",\n isValidMove = false,\n isCapture = false,\n onClick,\n onPointerEnter,\n onPointerLeave,\n className,\n}: DefaultGridCellProps) {\n const baseColor = isLight ? lightColor : darkColor;\n\n return (\n <g\n onClick={onClick}\n onPointerEnter={onPointerEnter}\n onPointerLeave={onPointerLeave}\n onKeyDown={(event) => handleKeyboardActivation(event, onClick)}\n className={clsx(\n \"transition-colors duration-100\",\n onClick && \"cursor-pointer\",\n className,\n )}\n role={onClick ? \"button\" : undefined}\n tabIndex={onClick ? 0 : undefined}\n aria-label={onClick ? \"Grid cell\" : undefined}\n >\n {/* Base cell */}\n <rect width={size} height={size} fill={baseColor} />\n\n {/* Selected overlay */}\n {isSelected && (\n <rect\n width={size}\n height={size}\n fill={selectedColor}\n pointerEvents=\"none\"\n />\n )}\n\n {/* Highlight overlay */}\n {isHighlighted && !isSelected && (\n <rect\n width={size}\n height={size}\n fill={highlightColor}\n pointerEvents=\"none\"\n />\n )}\n\n {/* Valid move indicator (dot) */}\n {isValidMove && !isCapture && (\n <circle\n cx={size / 2}\n cy={size / 2}\n r={size * 0.15}\n fill=\"rgba(34, 197, 94, 0.6)\"\n pointerEvents=\"none\"\n />\n )}\n\n {/* Capture indicator (ring) */}\n {isCapture && (\n <circle\n cx={size / 2}\n cy={size / 2}\n r={size * 0.42}\n fill=\"none\"\n stroke=\"rgba(239, 68, 68, 0.8)\"\n strokeWidth={size * 0.08}\n pointerEvents=\"none\"\n />\n )}\n </g>\n );\n}\n\nexport interface DefaultGridPieceProps {\n size: number;\n color?: string;\n strokeColor?: string;\n label?: string;\n isDragging?: boolean;\n onClick?: () => void;\n onPointerDown?: (e: React.PointerEvent) => void;\n className?: string;\n}\n\n/** Pre-built grid piece component for use in `renderPiece`. */\nexport function DefaultGridPiece({\n size,\n color = \"#94a3b8\",\n strokeColor,\n label,\n isDragging = false,\n onClick,\n onPointerDown,\n className,\n}: DefaultGridPieceProps) {\n const radius = size * 0.38;\n const effectiveStroke =\n strokeColor ??\n (color === \"#f8fafc\" || color === \"#ffffff\" ? \"#1e293b\" : \"#f8fafc\");\n\n return (\n <g\n onClick={onClick}\n onPointerDown={onPointerDown}\n onKeyDown={(event) => handleKeyboardActivation(event, onClick)}\n className={clsx(\n \"transition-transform duration-150\",\n (onClick || onPointerDown) && \"cursor-pointer hover:scale-105\",\n className,\n )}\n opacity={isDragging ? 0.8 : 1}\n role={onClick ? \"button\" : undefined}\n tabIndex={onClick ? 0 : undefined}\n aria-label={onClick ? (label ?? \"Grid piece\") : undefined}\n >\n <circle\n r={isDragging ? radius * 1.1 : radius}\n fill={color}\n stroke={effectiveStroke}\n strokeWidth={2}\n style={{ filter: \"drop-shadow(1px 2px 2px rgba(0,0,0,0.4))\" }}\n />\n {label && (\n <text\n y={4}\n textAnchor=\"middle\"\n fill={effectiveStroke}\n fontSize={size * 0.35}\n fontWeight=\"bold\"\n pointerEvents=\"none\"\n >\n {label}\n </text>\n )}\n </g>\n );\n}\n\nexport interface DefaultChessPieceProps {\n size: number;\n type: string;\n owner: \"white\" | \"black\";\n onClick?: () => void;\n onPointerDown?: (e: React.PointerEvent) => void;\n className?: string;\n}\n\nconst CHESS_SYMBOLS: Record<string, Record<string, string>> = {\n white: {\n king: \"♔\",\n queen: \"♕\",\n rook: \"♖\",\n bishop: \"♗\",\n knight: \"♘\",\n pawn: \"♙\",\n },\n black: {\n king: \"♚\",\n queen: \"♛\",\n rook: \"♜\",\n bishop: \"♝\",\n knight: \"♞\",\n pawn: \"♟\",\n },\n};\n\n/** Pre-built chess piece component using Unicode symbols. */\nexport function DefaultChessPiece({\n size,\n type,\n owner,\n onClick,\n onPointerDown,\n className,\n}: DefaultChessPieceProps) {\n const symbol = CHESS_SYMBOLS[owner]?.[type] ?? \"?\";\n const textColor = owner === \"white\" ? \"#f8fafc\" : \"#1e293b\";\n const shadowFilter =\n owner === \"white\"\n ? \"drop-shadow(1px 1px 1px rgba(0,0,0,0.5))\"\n : \"drop-shadow(1px 1px 1px rgba(255,255,255,0.3))\";\n\n return (\n <g\n onClick={onClick}\n onPointerDown={onPointerDown}\n onKeyDown={(event) => handleKeyboardActivation(event, onClick)}\n className={clsx(\n (onClick || onPointerDown) && \"cursor-pointer\",\n className,\n )}\n role={onClick ? \"button\" : undefined}\n tabIndex={onClick ? 0 : undefined}\n aria-label={onClick ? `${owner} ${type}` : undefined}\n >\n <text\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n fontSize={size * 0.7}\n fill={textColor}\n style={{ filter: shadowFilter }}\n >\n {symbol}\n </text>\n </g>\n );\n}\n\n// ============================================================================\n// Utilities\n// ============================================================================\n\n/**\n * Convert row/col to algebraic notation (a1, b2, etc.)\n */\nexport function toAlgebraic(\n row: number,\n col: number,\n totalRows: number,\n): string {\n const file = String.fromCharCode(97 + col); // a, b, c, ...\n const rank = totalRows - row; // 8, 7, 6, ... (bottom to top)\n return `${file}${rank}`;\n}\n\n/**\n * Convert row/col to numeric notation (1,1, 2,3, etc.)\n */\nexport function toNumeric(row: number, col: number): string {\n return `${row + 1},${col + 1}`;\n}\n\nfunction getCellId(cell: { id: string }): string {\n return cell.id;\n}\n\nfunction edgePositionForCells(\n firstCell: { row: number; col: number },\n secondCell: { row: number; col: number },\n cellSize: number,\n labelMargin: number,\n): SquareEdgePosition | null {\n if (\n Math.abs(firstCell.row - secondCell.row) +\n Math.abs(firstCell.col - secondCell.col) !==\n 1\n ) {\n return null;\n }\n\n const minRow = Math.min(firstCell.row, secondCell.row);\n const minCol = Math.min(firstCell.col, secondCell.col);\n\n if (firstCell.row === secondCell.row) {\n const x = labelMargin + (minCol + 1) * cellSize;\n const y1 = minRow * cellSize;\n const y2 = y1 + cellSize;\n return {\n x1: x,\n y1,\n x2: x,\n y2,\n midX: x,\n midY: (y1 + y2) / 2,\n angle: 90,\n };\n }\n\n const y = (minRow + 1) * cellSize;\n const x1 = labelMargin + minCol * cellSize;\n const x2 = x1 + cellSize;\n return {\n x1,\n y1: y,\n x2,\n y2: y,\n midX: (x1 + x2) / 2,\n midY: y,\n angle: 0,\n };\n}\n\nfunction cornerKeysForCell(cell: {\n row: number;\n col: number;\n}): Record<string, SquareVertexPosition> {\n return {\n [`${cell.col},${cell.row}`]: { x: cell.col, y: cell.row },\n [`${cell.col + 1},${cell.row}`]: { x: cell.col + 1, y: cell.row },\n [`${cell.col + 1},${cell.row + 1}`]: {\n x: cell.col + 1,\n y: cell.row + 1,\n },\n [`${cell.col},${cell.row + 1}`]: { x: cell.col, y: cell.row + 1 },\n };\n}\n\nfunction vertexPositionForCells(\n cells: readonly SquareCellWithId[],\n cellSize: number,\n labelMargin: number,\n): SquareVertexPosition | null {\n if (cells.length === 0) {\n return null;\n }\n\n const candidateKeys = cells.map(\n (cell) => new Set(Object.keys(cornerKeysForCell(cell))),\n );\n const firstKeySet = candidateKeys[0];\n if (firstKeySet === undefined) {\n return null;\n }\n const sharedKeys = [...firstKeySet].filter((key) =>\n candidateKeys.every((keySet) => keySet.has(key)),\n );\n if (sharedKeys.length !== 1) {\n return null;\n }\n\n const sharedKey = sharedKeys[0];\n if (!sharedKey) {\n return null;\n }\n const [colToken, rowToken] = sharedKey.split(\",\");\n if (colToken === undefined || rowToken === undefined) {\n return null;\n }\n const col = Number(colToken);\n const row = Number(rowToken);\n if (!Number.isFinite(col) || !Number.isFinite(row)) {\n return null;\n }\n\n return {\n x: labelMargin + col * cellSize,\n y: row * cellSize,\n };\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport interface SquareGridComponent {\n <const TBoard extends AnySquareBoardInput>(\n props: SquareGridBoardProps<TBoard>,\n ): ReactNode;\n <const TProps extends SquareGeneratedGridInputProps>(\n props: SquareGridProps<TProps>,\n ): ReactNode;\n <const TProps extends SquareAuthoredGridInputProps>(\n props: SquareGridProps<TProps>,\n ): ReactNode;\n}\n\nfunction SquareGridImpl(\n props:\n | SquareGridBoardProps<AnySquareBoardInput>\n | SquareGridProps<SquareGridInputProps>,\n) {\n const {\n cellSize = 60,\n renderCell,\n renderPiece,\n renderEdge,\n renderVertex,\n showCoordinates = true,\n coordinateStyle = \"algebraic\",\n width,\n height,\n enablePanZoom = false,\n initialZoom = 1,\n minZoom = 0.5,\n maxZoom = 3,\n className,\n interactiveSpaces,\n interactiveEdges,\n interactiveVertices,\n renderInteractiveSpace,\n renderInteractiveEdge,\n renderInteractiveVertex,\n } = props;\n const board =\n \"board\" in props\n ? props.board\n : ((\"spaces\" in props\n ? {\n id: \"__square-grid__\",\n spaces: props.spaces,\n pieces: props.pieces ?? [],\n edges: props.edges ?? [],\n vertices: props.vertices ?? [],\n }\n : {\n id: \"__square-grid__\",\n rows: props.rows ?? 0,\n cols: props.cols ?? 0,\n cells: props.cells,\n pieces: props.pieces ?? [],\n edges: props.edges ?? [],\n vertices: props.vertices ?? [],\n }) satisfies AnySquareBoardInput);\n const [hoveredInteractiveSpaceId, setHoveredInteractiveSpaceId] = useState<\n string | null\n >(null);\n const [hoveredInteractiveEdgeId, setHoveredInteractiveEdgeId] = useState<\n string | null\n >(null);\n const [hoveredInteractiveVertexId, setHoveredInteractiveVertexId] = useState<\n string | null\n >(null);\n\n // Use the unified pan/zoom hook\n const {\n transform,\n bind,\n isDragging: isPanning,\n } = usePanZoom({\n enabled: enablePanZoom,\n initialZoom,\n minZoom,\n maxZoom,\n mode: \"viewbox\",\n });\n\n // Coordinate label margin\n const labelMargin = showCoordinates && coordinateStyle !== \"none\" ? 24 : 0;\n\n const normalizedBoard = useMemo<NormalizedSquareBoard<AnySquareBoardInput>>(\n () => normalizeSquareBoardInput(board),\n [board],\n );\n\n const rows = normalizedBoard.rows;\n const cols = normalizedBoard.cols;\n const resolvedEdges = normalizedBoard.edges as Array<\n NormalizedSquareEdgeOf<AnySquareBoardInput>\n >;\n const resolvedVertices = normalizedBoard.vertices as Array<\n NormalizedSquareVertexOf<AnySquareBoardInput>\n >;\n const resolvedPieces = normalizedBoard.pieces as Array<\n NormalizedSquarePieceOf<AnySquareBoardInput>\n >;\n\n // Calculate grid dimensions\n const gridWidth = cols * cellSize;\n const gridHeight = rows * cellSize;\n const totalWidth = gridWidth + labelMargin;\n const totalHeight = gridHeight + labelMargin;\n\n const renderableCells = useMemo(() => {\n const result: Array<{ row: number; col: number }> = [];\n for (let row = 0; row < rows; row++) {\n for (let col = 0; col < cols; col++) {\n result.push({ row, col });\n }\n }\n return result;\n }, [rows, cols]);\n\n const resolvedCells = useMemo<SquareCellWithId[]>(() => {\n if (normalizedBoard.cells.length > 0) {\n return normalizedBoard.cells.map((cell) => ({\n ...cell,\n id: getCellId(cell),\n }));\n }\n\n return renderableCells.map(({ row, col }) => ({\n id: `${row},${col}`,\n row,\n col,\n }));\n }, [normalizedBoard.cells, renderableCells]);\n\n const cellsById = useMemo(\n () => new Map(resolvedCells.map((cell) => [cell.id, cell] as const)),\n [resolvedCells],\n );\n\n const resolvedEdgePositions = useMemo(\n () =>\n resolvedEdges.flatMap((edge) => {\n if (edge.spaceIds.length < 2) {\n return [];\n }\n const firstCell = cellsById.get(edge.spaceIds[0] ?? \"\");\n const secondCell = cellsById.get(edge.spaceIds[1] ?? \"\");\n if (!firstCell || !secondCell) {\n return [];\n }\n const position = edgePositionForCells(\n firstCell,\n secondCell,\n cellSize,\n labelMargin,\n );\n return position\n ? [\n {\n edge,\n interactiveEdge: {\n ...edge,\n position,\n } as InteractiveSquareEdge<AnySquareBoardInput>,\n },\n ]\n : [];\n }),\n [cellSize, cellsById, resolvedEdges, labelMargin],\n );\n\n const resolvedVertexPositions = useMemo(\n () =>\n resolvedVertices.flatMap((vertex) => {\n const vertexCells = vertex.spaceIds.flatMap((spaceId) => {\n const cell = cellsById.get(spaceId);\n return cell ? [cell] : [];\n });\n const position = vertexPositionForCells(\n vertexCells,\n cellSize,\n labelMargin,\n );\n return position\n ? [\n {\n vertex,\n interactiveVertex: {\n ...vertex,\n position,\n } as InteractiveSquareVertex<AnySquareBoardInput>,\n },\n ]\n : [];\n }),\n [cellSize, cellsById, labelMargin, resolvedVertices],\n );\n\n // Calculate viewBox for pan/zoom\n const viewBoxWidth = totalWidth / transform.zoom;\n const viewBoxHeight = totalHeight / transform.zoom;\n const viewBoxX = (totalWidth - viewBoxWidth) / 2 - transform.pan.x;\n const viewBoxY = (totalHeight - viewBoxHeight) / 2 - transform.pan.y;\n\n // Determine SVG dimensions\n const svgWidth = width ?? totalWidth;\n const svgHeight = height ?? totalHeight;\n\n return (\n <svg\n width={svgWidth}\n height={svgHeight}\n viewBox={\n enablePanZoom\n ? `${viewBoxX} ${viewBoxY} ${viewBoxWidth} ${viewBoxHeight}`\n : `0 0 ${totalWidth} ${totalHeight}`\n }\n className={clsx(\n \"square-grid\",\n enablePanZoom && \"touch-none\",\n isPanning && \"cursor-grabbing\",\n enablePanZoom && !isPanning && \"cursor-grab\",\n className,\n )}\n {...bind()}\n role=\"img\"\n aria-label={`${rows}x${cols} game grid`}\n >\n <defs>\n {/* Drop shadow for pieces */}\n <filter id=\"pieceShadow\" x=\"-20%\" y=\"-20%\" width=\"140%\" height=\"140%\">\n <feDropShadow dx=\"1\" dy=\"2\" stdDeviation=\"2\" floodOpacity=\"0.4\" />\n </filter>\n </defs>\n\n {/* Cells layer */}\n <g className=\"cells\" role=\"list\" aria-label=\"Grid cells\">\n {renderableCells.map(({ row, col }) => {\n const x = labelMargin + col * cellSize;\n const y = row * cellSize;\n\n return (\n <g\n key={`${row}-${col}`}\n transform={`translate(${x}, ${y})`}\n role=\"listitem\"\n aria-label={\n coordinateStyle === \"algebraic\"\n ? toAlgebraic(row, col, rows)\n : toNumeric(row, col)\n }\n >\n {renderCell(row, col)}\n </g>\n );\n })}\n </g>\n\n {interactiveSpaces && (\n <g className=\"interactive-spaces\" aria-label=\"Interactive spaces\">\n {resolvedCells.map((space) => {\n const state = interactiveTargetRenderState(\n interactiveSpaces,\n space.id,\n hoveredInteractiveSpaceId === space.id,\n );\n const isSelectable = isInteractiveTargetSelectable(\n interactiveSpaces,\n state,\n );\n const x = labelMargin + space.col * cellSize;\n const y = space.row * cellSize;\n return (\n <g\n key={space.id}\n transform={`translate(${x}, ${y})`}\n onClick={\n isSelectable\n ? () => {\n void interactiveSpaces.selectTargetId?.(space.id);\n }\n : undefined\n }\n onKeyDown={(event) =>\n handleKeyboardActivation(\n event,\n isSelectable\n ? () => {\n void interactiveSpaces.selectTargetId?.(space.id);\n }\n : undefined,\n )\n }\n onPointerEnter={() => setHoveredInteractiveSpaceId(space.id)}\n onPointerLeave={() =>\n setHoveredInteractiveSpaceId((currentId) =>\n currentId === space.id ? null : currentId,\n )\n }\n className={clsx(isSelectable && \"cursor-pointer\")}\n role={isSelectable ? \"button\" : undefined}\n tabIndex={isSelectable ? 0 : undefined}\n aria-label={\n isSelectable ? `Select space ${space.id}` : undefined\n }\n >\n {isSelectable && (\n <rect\n x={0}\n y={0}\n width={cellSize}\n height={cellSize}\n fill=\"rgba(255,255,255,0.001)\"\n pointerEvents=\"all\"\n />\n )}\n {renderInteractiveSpace\n ? renderInteractiveSpace(space, state)\n : null}\n </g>\n );\n })}\n </g>\n )}\n\n {renderEdge && resolvedEdgePositions.length > 0 && (\n <g className=\"edges\" aria-label=\"Board edges\">\n {resolvedEdgePositions.map(({ edge, interactiveEdge }) => (\n <g key={edge.id}>{renderEdge(edge, interactiveEdge.position)}</g>\n ))}\n </g>\n )}\n\n {interactiveEdges && (\n <g className=\"interactive-edges\" aria-label=\"Interactive edges\">\n {resolvedEdgePositions.map(({ interactiveEdge: edge }) => {\n const state = interactiveTargetRenderState(\n interactiveEdges,\n edge.id,\n hoveredInteractiveEdgeId === edge.id,\n );\n const isSelectable = isInteractiveTargetSelectable(\n interactiveEdges,\n state,\n );\n return (\n <g\n key={edge.id}\n onClick={\n isSelectable\n ? () => {\n void interactiveEdges.selectTargetId?.(edge.id);\n }\n : undefined\n }\n onKeyDown={(event) =>\n handleKeyboardActivation(\n event,\n isSelectable\n ? () => {\n void interactiveEdges.selectTargetId?.(edge.id);\n }\n : undefined,\n )\n }\n onPointerEnter={() => setHoveredInteractiveEdgeId(edge.id)}\n onPointerLeave={() =>\n setHoveredInteractiveEdgeId((currentId) =>\n currentId === edge.id ? null : currentId,\n )\n }\n className={clsx(isSelectable && \"cursor-pointer\")}\n role={isSelectable ? \"button\" : undefined}\n tabIndex={isSelectable ? 0 : undefined}\n aria-label={isSelectable ? `Select edge ${edge.id}` : undefined}\n >\n {renderInteractiveEdge ? (\n renderInteractiveEdge(edge, edge.position, state)\n ) : state.isEnabled && state.isEligible ? (\n <line\n x1={edge.position.x1}\n y1={edge.position.y1}\n x2={edge.position.x2}\n y2={edge.position.y2}\n stroke=\"rgba(255,255,255,0.001)\"\n strokeWidth={Math.max(12, cellSize * 0.18)}\n pointerEvents=\"stroke\"\n />\n ) : null}\n </g>\n );\n })}\n </g>\n )}\n\n {renderVertex && resolvedVertexPositions.length > 0 && (\n <g className=\"vertices\" aria-label=\"Board vertices\">\n {resolvedVertexPositions.map(({ vertex, interactiveVertex }) => (\n <g key={vertex.id}>\n {renderVertex(vertex, interactiveVertex.position)}\n </g>\n ))}\n </g>\n )}\n\n {interactiveVertices && (\n <g className=\"interactive-vertices\" aria-label=\"Interactive vertices\">\n {resolvedVertexPositions.map(({ interactiveVertex: vertex }) => {\n const state = interactiveTargetRenderState(\n interactiveVertices,\n vertex.id,\n hoveredInteractiveVertexId === vertex.id,\n );\n const isSelectable = isInteractiveTargetSelectable(\n interactiveVertices,\n state,\n );\n return (\n <g\n key={vertex.id}\n onClick={\n isSelectable\n ? () => {\n void interactiveVertices.selectTargetId?.(vertex.id);\n }\n : undefined\n }\n onKeyDown={(event) =>\n handleKeyboardActivation(\n event,\n isSelectable\n ? () => {\n void interactiveVertices.selectTargetId?.(vertex.id);\n }\n : undefined,\n )\n }\n onPointerEnter={() => setHoveredInteractiveVertexId(vertex.id)}\n onPointerLeave={() =>\n setHoveredInteractiveVertexId((currentId) =>\n currentId === vertex.id ? null : currentId,\n )\n }\n className={clsx(isSelectable && \"cursor-pointer\")}\n role={isSelectable ? \"button\" : undefined}\n tabIndex={isSelectable ? 0 : undefined}\n aria-label={\n isSelectable ? `Select vertex ${vertex.id}` : undefined\n }\n >\n {renderInteractiveVertex ? (\n renderInteractiveVertex(vertex, vertex.position, state)\n ) : state.isEnabled && state.isEligible ? (\n <circle\n cx={vertex.position.x}\n cy={vertex.position.y}\n r={Math.max(8, cellSize * 0.12)}\n fill=\"rgba(255,255,255,0.001)\"\n pointerEvents=\"all\"\n />\n ) : null}\n </g>\n );\n })}\n </g>\n )}\n\n {/* Coordinate labels */}\n {showCoordinates && coordinateStyle !== \"none\" && (\n <g className=\"coordinates\" aria-hidden=\"true\">\n {/* File labels (a-h) - bottom */}\n {Array.from({ length: cols }).map((_, col) => {\n const label =\n coordinateStyle === \"algebraic\"\n ? String.fromCharCode(97 + col)\n : String(col + 1);\n return (\n <text\n key={`file-${col}`}\n x={labelMargin + col * cellSize + cellSize / 2}\n y={gridHeight + 16}\n textAnchor=\"middle\"\n fill=\"#64748b\"\n fontSize={12}\n fontWeight=\"500\"\n >\n {label}\n </text>\n );\n })}\n {/* Rank labels (1-8) - left */}\n {Array.from({ length: rows }).map((_, row) => {\n const label =\n coordinateStyle === \"algebraic\"\n ? String(rows - row)\n : String(row + 1);\n return (\n <text\n key={`rank-${row}`}\n x={10}\n y={row * cellSize + cellSize / 2 + 4}\n textAnchor=\"middle\"\n fill=\"#64748b\"\n fontSize={12}\n fontWeight=\"500\"\n >\n {label}\n </text>\n );\n })}\n </g>\n )}\n\n {/* Pieces layer */}\n <g className=\"pieces\" role=\"list\" aria-label=\"Game pieces\">\n {resolvedPieces.map((piece) => {\n const x = labelMargin + piece.col * cellSize + cellSize / 2;\n const y = piece.row * cellSize + cellSize / 2;\n\n return (\n <g\n key={piece.id}\n transform={`translate(${x}, ${y})`}\n role=\"listitem\"\n aria-label={`${piece.owner ?? \"\"} ${piece.typeId}`}\n >\n {renderPiece(piece)}\n </g>\n );\n })}\n </g>\n\n {/* Zoom indicator */}\n {enablePanZoom && transform.zoom !== 1 && (\n <g\n transform={`translate(${viewBoxX + 10}, ${viewBoxY + viewBoxHeight - 30})`}\n >\n <rect\n x={0}\n y={0}\n width={60}\n height={20}\n rx={4}\n fill=\"rgba(0,0,0,0.6)\"\n />\n <text x={30} y={14} textAnchor=\"middle\" fill=\"white\" fontSize={12}>\n {Math.round(transform.zoom * 100)}%\n </text>\n </g>\n )}\n </svg>\n );\n}\n\nexport const SquareGrid = SquareGridImpl as SquareGridComponent;\n","export type BoardTargetKind = \"edge\" | \"vertex\" | \"space\" | \"tile\";\n\nexport interface InteractiveTargetState {\n kind?: BoardTargetKind;\n id: string;\n eligible: boolean;\n selectable: boolean;\n hovered: boolean;\n pending: boolean;\n conflict: boolean;\n unavailableReason?: string;\n select?: () => unknown | Promise<unknown>;\n}\n\nexport interface InteractiveTargetLayer {\n enabled?: boolean;\n eligible?: ReadonlySet<string>;\n selectTargetId?: (targetId: string) => unknown | Promise<unknown>;\n targetState?: (targetId: string) => Partial<InteractiveTargetState>;\n}\n\nexport interface InteractiveTargetRenderState extends InteractiveTargetState {\n isEnabled: boolean;\n isEligible: boolean;\n isHovered: boolean;\n}\n\nexport function interactiveTargetRenderState(\n layer: InteractiveTargetLayer,\n targetId: string,\n isHovered: boolean,\n): InteractiveTargetRenderState {\n const enabled = layer.enabled !== false;\n const eligible = layer.eligible?.has(targetId) ?? true;\n const extra = layer.targetState?.(targetId) ?? {};\n const selectable =\n extra.selectable ?? (enabled && eligible && !!layer.selectTargetId);\n return {\n id: targetId,\n ...extra,\n eligible: extra.eligible ?? eligible,\n selectable,\n hovered: isHovered,\n pending: extra.pending ?? false,\n conflict: extra.conflict ?? false,\n select:\n extra.select ??\n (layer.selectTargetId\n ? () => layer.selectTargetId?.(targetId)\n : undefined),\n isEnabled: enabled,\n isEligible: extra.eligible ?? eligible,\n isHovered,\n };\n}\n\nexport function isInteractiveTargetSelectable(\n layer: InteractiveTargetLayer,\n state: InteractiveTargetRenderState,\n): boolean {\n return (\n state.isEnabled &&\n state.selectable &&\n !!(state.select ?? layer.selectTargetId)\n );\n}\n","/**\n * SVG-based hex grid for hex-based games (Catan, wargames, Hive, Twilight Imperium).\n * Supports tiles, edges (roads), vertices (settlements), and interactive placement overlays.\n * Pan/zoom enabled on mobile via @use-gesture.\n */\n\nimport { useMemo, useState, type ReactNode } from \"react\";\nimport { clsx } from \"clsx\";\nimport { usePanZoom, calculateViewBox } from \"../../hooks/usePanZoom.js\";\nimport { useIsMobile } from \"../../hooks/useIsMobile.js\";\nimport { handleKeyboardActivation } from \"./interaction-accessibility.js\";\nimport {\n interactiveTargetRenderState,\n isInteractiveTargetSelectable,\n type InteractiveTargetLayer,\n type InteractiveTargetRenderState,\n} from \"./target-layer.js\";\nimport {\n type AuthoredHexBoardInput,\n type AnyHexBoardInput,\n type BoardSpaceIdOf,\n type GeneratedHexBoardInput,\n type NormalizedHexBoard,\n type NormalizedHexEdgeOf,\n type NormalizedHexTileOf,\n type NormalizedHexVertexOf,\n normalizeHexBoardInput,\n} from \"../../types/tiled-board.js\";\n\nexport type {\n InteractiveTargetLayer,\n InteractiveTargetRenderState,\n} from \"./target-layer.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type HexOrientation = \"pointy-top\" | \"flat-top\";\n\n/**\n * Geometry context passed to `renderTile`.\n *\n * `corners`, `points`, and `bounds` are expressed in tile-local\n * coordinates because each tile is rendered inside a `<g>` translated\n * to its center. Use `position` if you need the resolved center in the\n * board's absolute SVG coordinates.\n *\n * The `inset` option shrinks the polygon toward the center by that many\n * pixels, which is useful for layered effects such as borders, frames,\n * or inner highlights without re-deriving the hex math yourself.\n */\nexport interface HexTileGeometry {\n size: number;\n orientation: HexOrientation;\n center: { x: 0; y: 0 };\n position: { x: number; y: number };\n corners: (options?: { inset?: number }) => Array<{ x: number; y: number }>;\n points: (options?: { inset?: number }) => string;\n bounds: {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n width: number;\n height: number;\n };\n}\n\nexport interface EdgePosition {\n /** Absolute SVG start point of the visible edge line. */\n x1: number;\n y1: number;\n /** Absolute SVG end point of the visible edge line. */\n x2: number;\n y2: number;\n /** Absolute SVG midpoint of the edge. */\n midX: number;\n midY: number;\n /**\n * Angle in degrees from hex1 center to hex2 center.\n * This is perpendicular to the visible edge line.\n */\n centerAngle: number;\n /** Angle in degrees of the visible edge line itself. */\n edgeAngle: number;\n}\n\nexport interface InteractiveHexVertex<\n TBoard extends AnyHexBoardInput = AnyHexBoardInput,\n> extends NormalizedHexVertexOf<TBoard> {\n position: { x: number; y: number };\n spaceIds: ReadonlyArray<BoardSpaceIdOf<TBoard>>;\n}\n\nexport interface InteractiveHexEdge<\n TBoard extends AnyHexBoardInput = AnyHexBoardInput,\n> extends NormalizedHexEdgeOf<TBoard> {\n position: EdgePosition;\n spaceIds: ReadonlyArray<BoardSpaceIdOf<TBoard>>;\n}\n\nexport type InteractiveHexSpace<\n TBoard extends AnyHexBoardInput = AnyHexBoardInput,\n> = NormalizedHexTileOf<TBoard>;\n\ninterface HexGeneratedGridInputProps {\n id?: string;\n layout?: \"hex\";\n orientation?: HexOrientation;\n spaces: Extract<AnyHexBoardInput, { spaces: unknown }>[\"spaces\"];\n edges?: AnyHexBoardInput[\"edges\"];\n vertices?: AnyHexBoardInput[\"vertices\"];\n}\n\ninterface HexAuthoredGridInputProps {\n id?: string;\n layout?: \"hex\";\n orientation?: HexOrientation;\n tiles: Extract<AnyHexBoardInput, { tiles: unknown }>[\"tiles\"];\n edges?: AnyHexBoardInput[\"edges\"];\n vertices?: AnyHexBoardInput[\"vertices\"];\n}\n\ntype HexGridInputProps = HexGeneratedGridInputProps | HexAuthoredGridInputProps;\n\ntype ResolvedArrayProp<Value> =\n Exclude<Value, undefined> extends readonly unknown[]\n ? Exclude<Value, undefined>\n : readonly [];\n\ntype HexBoardLikeOfProps<TProps extends HexGridInputProps> = TProps extends {\n id?: infer Id;\n layout?: infer Layout;\n orientation?: infer Orientation;\n spaces: infer Spaces;\n edges?: infer Edges;\n vertices?: infer Vertices;\n}\n ? {\n id: Extract<Id, string> extends never ? string : Extract<Id, string>;\n layout?: Extract<Layout, \"hex\">;\n orientation?: Extract<Orientation, HexOrientation>;\n spaces: Spaces;\n edges: ResolvedArrayProp<Edges>;\n vertices: ResolvedArrayProp<Vertices>;\n } & GeneratedHexBoardInput\n : TProps extends {\n id?: infer Id;\n layout?: infer Layout;\n orientation?: infer Orientation;\n tiles: infer Tiles;\n edges?: infer Edges;\n vertices?: infer Vertices;\n }\n ? {\n id: Extract<Id, string> extends never ? string : Extract<Id, string>;\n layout?: Extract<Layout, \"hex\">;\n orientation?: Extract<Orientation, HexOrientation>;\n tiles: Tiles;\n edges: ResolvedArrayProp<Edges>;\n vertices: ResolvedArrayProp<Vertices>;\n } & AuthoredHexBoardInput\n : never;\n\nexport type HexGridProps<TProps extends HexGridInputProps = HexGridInputProps> =\n TProps & {\n orientation?: HexOrientation;\n /** Hex radius in pixels */\n hexSize?: number;\n /**\n * Receives tile data centered at (0,0) plus a `HexTileGeometry`\n * helper. Use `geometry.points({ inset })` to draw custom polygons\n * without duplicating `hexSize` / orientation in the consumer.\n */\n renderTile: (\n tile: NormalizedHexTileOf<NoInfer<HexBoardLikeOfProps<TProps>>>,\n geometry: HexTileGeometry,\n ) => ReactNode;\n /**\n * Receives edge geometry in absolute SVG coordinates.\n * Use `position.edgeAngle` to align artwork with the visible edge.\n */\n renderEdge: (\n edge: NormalizedHexEdgeOf<NoInfer<HexBoardLikeOfProps<TProps>>>,\n position: EdgePosition,\n ) => ReactNode;\n renderVertex: (\n vertex: NormalizedHexVertexOf<NoInfer<HexBoardLikeOfProps<TProps>>>,\n position: { x: number; y: number },\n ) => ReactNode;\n width?: number | string;\n height?: number | string;\n enablePanZoom?: boolean;\n initialZoom?: number;\n minZoom?: number;\n maxZoom?: number;\n className?: string;\n\n // Interactive board target layers.\n\n /** Reducer-aware space target layer from `board.targetLayers.space(...)`. */\n interactiveSpaces?: InteractiveTargetLayer;\n /** Reducer-aware vertex target layer from `board.targetLayers.vertex(...)`. */\n interactiveVertices?: InteractiveTargetLayer;\n /** Reducer-aware edge target layer from `board.targetLayers.edge(...)`. */\n interactiveEdges?: InteractiveTargetLayer;\n /** Receives space geometry centered at (0,0). */\n renderInteractiveSpace?: (\n space: InteractiveHexSpace<NoInfer<HexBoardLikeOfProps<TProps>>>,\n state: InteractiveTargetRenderState,\n ) => ReactNode;\n /**\n * Receives vertex geometry in absolute SVG coordinates.\n */\n renderInteractiveVertex?: (\n vertex: InteractiveHexVertex<NoInfer<HexBoardLikeOfProps<TProps>>>,\n position: { x: number; y: number },\n state: InteractiveTargetRenderState,\n ) => ReactNode;\n /**\n * Receives edge geometry in the same absolute SVG coordinates as `renderEdge`.\n */\n renderInteractiveEdge?: (\n edge: InteractiveHexEdge<NoInfer<HexBoardLikeOfProps<TProps>>>,\n position: EdgePosition,\n state: InteractiveTargetRenderState,\n ) => ReactNode;\n interactiveVertexSize?: number;\n interactiveEdgeSize?: number;\n };\n\nexport interface HexGridBoardProps<\n TBoard extends AnyHexBoardInput = AnyHexBoardInput,\n> {\n board: TBoard;\n orientation?: HexOrientation;\n hexSize?: number;\n /**\n * Receives tile data centered at (0,0) plus a `HexTileGeometry`\n * helper. Use `geometry.points({ inset })` to draw custom polygons\n * without duplicating `hexSize` / orientation in the consumer.\n */\n renderTile: (\n tile: NormalizedHexTileOf<NoInfer<TBoard>>,\n geometry: HexTileGeometry,\n ) => ReactNode;\n /**\n * Receives edge geometry in absolute SVG coordinates.\n * Use `position.edgeAngle` to align artwork with the visible edge.\n */\n renderEdge: (\n edge: NormalizedHexEdgeOf<NoInfer<TBoard>>,\n position: EdgePosition,\n ) => ReactNode;\n renderVertex: (\n vertex: NormalizedHexVertexOf<NoInfer<TBoard>>,\n position: { x: number; y: number },\n ) => ReactNode;\n width?: number | string;\n height?: number | string;\n enablePanZoom?: boolean;\n initialZoom?: number;\n minZoom?: number;\n maxZoom?: number;\n className?: string;\n interactiveSpaces?: InteractiveTargetLayer;\n interactiveVertices?: InteractiveTargetLayer;\n interactiveEdges?: InteractiveTargetLayer;\n /** Receives space geometry centered at (0,0). */\n renderInteractiveSpace?: (\n space: InteractiveHexSpace<NoInfer<TBoard>>,\n state: InteractiveTargetRenderState,\n ) => ReactNode;\n /**\n * Receives vertex geometry in absolute SVG coordinates.\n */\n renderInteractiveVertex?: (\n vertex: InteractiveHexVertex<NoInfer<TBoard>>,\n position: { x: number; y: number },\n state: InteractiveTargetRenderState,\n ) => ReactNode;\n /**\n * Receives edge geometry in the same absolute SVG coordinates as `renderEdge`.\n */\n renderInteractiveEdge?: (\n edge: InteractiveHexEdge<NoInfer<TBoard>>,\n position: EdgePosition,\n state: InteractiveTargetRenderState,\n ) => ReactNode;\n interactiveVertexSize?: number;\n interactiveEdgeSize?: number;\n}\n\n// ============================================================================\n// Pre-built Helper Components\n// ============================================================================\n\nexport interface DefaultHexTileProps {\n /** Should match hexSize from HexGrid */\n size: number;\n fill: string;\n stroke?: string;\n strokeWidth?: number;\n isSelected?: boolean;\n isHighlighted?: boolean;\n label?: string;\n showCoordinates?: boolean;\n coordinates?: { q: number; r: number };\n orientation?: HexOrientation;\n onClick?: () => void;\n onPointerEnter?: () => void;\n onPointerLeave?: () => void;\n className?: string;\n}\n\n/** Pre-built hexagon tile for use in `renderTile`. */\nexport function DefaultHexTile({\n size,\n fill,\n stroke = \"#1e293b\",\n strokeWidth = 1.5,\n isSelected = false,\n isHighlighted = false,\n label,\n showCoordinates = false,\n coordinates,\n orientation = \"pointy-top\",\n onClick,\n onPointerEnter,\n onPointerLeave,\n className,\n}: DefaultHexTileProps) {\n const effectiveFill = isSelected\n ? \"rgba(59, 130, 246, 0.5)\"\n : isHighlighted\n ? \"rgba(34, 197, 94, 0.4)\"\n : fill;\n\n const effectiveStroke = isSelected\n ? \"#3b82f6\"\n : isHighlighted\n ? \"#22c55e\"\n : stroke;\n\n const effectiveStrokeWidth = isSelected || isHighlighted ? 3 : strokeWidth;\n\n const points = hexUtils.getHexPoints(0, 0, size * 0.95, orientation);\n\n return (\n <g\n onClick={onClick}\n onPointerEnter={onPointerEnter}\n onPointerLeave={onPointerLeave}\n onKeyDown={(event) => handleKeyboardActivation(event, onClick)}\n className={clsx(\n \"transition-all duration-150\",\n onClick && \"cursor-pointer hover:brightness-110\",\n className,\n )}\n role={onClick ? \"button\" : undefined}\n tabIndex={onClick ? 0 : undefined}\n aria-label={onClick ? (label ?? \"Hex tile\") : undefined}\n >\n <polygon\n points={points}\n fill={effectiveFill}\n stroke={effectiveStroke}\n strokeWidth={effectiveStrokeWidth}\n filter=\"url(#hexShadow)\"\n />\n\n {label && (\n <text\n x={0}\n y={showCoordinates ? -8 : 0}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n fill=\"white\"\n fontSize={size * 0.28}\n fontWeight=\"bold\"\n style={{ textShadow: \"1px 1px 2px rgba(0,0,0,0.8)\" }}\n pointerEvents=\"none\"\n >\n {label}\n </text>\n )}\n\n {showCoordinates && coordinates && (\n <text\n x={0}\n y={label ? 10 : 0}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n fill=\"rgba(255,255,255,0.7)\"\n fontSize={size * 0.2}\n pointerEvents=\"none\"\n >\n {coordinates.q},{coordinates.r}\n </text>\n )}\n </g>\n );\n}\n\nexport interface DefaultHexEdgeProps {\n position: EdgePosition;\n color: string;\n hasOwner?: boolean;\n strokeWidth?: number;\n touchTargetSize?: number;\n onClick?: () => void;\n className?: string;\n}\n\n/** Pre-built edge/road component for use in `renderEdge`. */\nexport function DefaultHexEdge({\n position,\n color,\n hasOwner = true,\n strokeWidth = 6,\n touchTargetSize = 20,\n onClick,\n className,\n}: DefaultHexEdgeProps) {\n const touchTargetLength = Math.hypot(\n position.x2 - position.x1,\n position.y2 - position.y1,\n );\n\n return (\n <g\n onClick={onClick}\n onKeyDown={(event) => handleKeyboardActivation(event, onClick)}\n className={clsx(\n \"transition-all duration-150\",\n onClick && \"cursor-pointer\",\n className,\n )}\n role={onClick ? \"button\" : undefined}\n tabIndex={onClick ? 0 : undefined}\n aria-label={onClick ? \"Hex edge\" : undefined}\n >\n {/* Invisible touch target */}\n <rect\n x={position.midX - touchTargetLength / 2}\n y={position.midY - touchTargetSize / 2}\n width={touchTargetLength}\n height={touchTargetSize}\n rx={touchTargetSize / 2}\n fill=\"rgba(255,255,255,0.001)\"\n transform={`rotate(${position.edgeAngle} ${position.midX} ${position.midY})`}\n pointerEvents=\"all\"\n />\n {/* Visible edge */}\n <line\n x1={position.x1}\n y1={position.y1}\n x2={position.x2}\n y2={position.y2}\n stroke={color}\n strokeWidth={hasOwner ? strokeWidth : strokeWidth / 2}\n strokeLinecap=\"round\"\n className={hasOwner ? \"\" : \"opacity-30\"}\n />\n </g>\n );\n}\n\nexport interface DefaultHexVertexProps {\n position: { x: number; y: number };\n color: string;\n stroke?: string;\n strokeWidth?: number;\n hasOwner?: boolean;\n isSelected?: boolean;\n isHighlighted?: boolean;\n size?: number;\n touchTargetSize?: number;\n shape?: \"circle\" | \"square\";\n onClick?: () => void;\n onPointerEnter?: () => void;\n onPointerLeave?: () => void;\n className?: string;\n}\n\n/** Pre-built vertex/settlement component for use in `renderVertex`. */\nexport function DefaultHexVertex({\n position,\n color,\n stroke = \"#1e293b\",\n strokeWidth = 1.5,\n hasOwner = true,\n isSelected = false,\n isHighlighted = false,\n size = 10,\n touchTargetSize = 22,\n shape = \"circle\",\n onClick,\n onPointerEnter,\n onPointerLeave,\n className,\n}: DefaultHexVertexProps) {\n const effectiveColor = isSelected\n ? \"rgba(59, 130, 246, 0.8)\"\n : isHighlighted\n ? \"rgba(34, 197, 94, 0.8)\"\n : color;\n\n const effectiveStroke = isSelected\n ? \"#3b82f6\"\n : isHighlighted\n ? \"#22c55e\"\n : stroke;\n\n const effectiveStrokeWidth = isSelected || isHighlighted ? 3 : strokeWidth;\n\n return (\n <g\n onClick={onClick}\n onPointerEnter={onPointerEnter}\n onPointerLeave={onPointerLeave}\n onKeyDown={(event) => handleKeyboardActivation(event, onClick)}\n className={clsx(\n \"transition-all duration-150\",\n onClick && \"cursor-pointer hover:scale-110\",\n className,\n )}\n style={{ transformOrigin: `${position.x}px ${position.y}px` }}\n role={onClick ? \"button\" : undefined}\n tabIndex={onClick ? 0 : undefined}\n aria-label={onClick ? \"Hex vertex\" : undefined}\n >\n {/* Invisible touch target */}\n <circle\n cx={position.x}\n cy={position.y}\n r={touchTargetSize}\n fill=\"rgba(255,255,255,0.001)\"\n pointerEvents=\"all\"\n />\n {/* Visible vertex */}\n {shape === \"square\" ? (\n <rect\n x={position.x - size}\n y={position.y - size}\n width={size * 2}\n height={size * 2}\n fill={effectiveColor}\n stroke={effectiveStroke}\n strokeWidth={effectiveStrokeWidth}\n className={hasOwner ? \"\" : \"opacity-30\"}\n />\n ) : (\n <circle\n cx={position.x}\n cy={position.y}\n r={hasOwner ? size : size * 0.5}\n fill={effectiveColor}\n stroke={effectiveStroke}\n strokeWidth={effectiveStrokeWidth}\n className={hasOwner ? \"\" : \"opacity-30\"}\n />\n )}\n </g>\n );\n}\n\n// ============================================================================\n// Interactive Helper Components (for placement UI)\n// ============================================================================\n\nexport interface DefaultInteractiveVertexProps {\n position: { x: number; y: number };\n isHovered: boolean;\n size?: number;\n color?: string;\n hoverColor?: string;\n className?: string;\n}\nexport function DefaultInteractiveVertex({\n position,\n isHovered,\n size = 8,\n color = \"rgba(255, 255, 255, 0.2)\",\n hoverColor = \"rgba(34, 197, 94, 0.8)\",\n className,\n}: DefaultInteractiveVertexProps) {\n return (\n <circle\n cx={position.x}\n cy={position.y}\n r={isHovered ? size * 1.5 : size}\n fill={isHovered ? hoverColor : color}\n stroke={isHovered ? \"#22c55e\" : \"rgba(255,255,255,0.4)\"}\n strokeWidth={isHovered ? 2 : 1}\n className={clsx(\"transition-all duration-150\", className)}\n />\n );\n}\n\nexport interface DefaultInteractiveEdgeProps {\n position: EdgePosition;\n isHovered: boolean;\n strokeWidth?: number;\n color?: string;\n hoverColor?: string;\n className?: string;\n}\nexport function DefaultInteractiveEdge({\n position,\n isHovered,\n strokeWidth = 4,\n color = \"rgba(255, 255, 255, 0.15)\",\n hoverColor = \"rgba(251, 146, 60, 0.8)\",\n className,\n}: DefaultInteractiveEdgeProps) {\n return (\n <line\n x1={position.x1}\n y1={position.y1}\n x2={position.x2}\n y2={position.y2}\n stroke={isHovered ? hoverColor : color}\n strokeWidth={isHovered ? strokeWidth * 1.5 : strokeWidth}\n strokeLinecap=\"round\"\n className={clsx(\"transition-all duration-150\", className)}\n />\n );\n}\n\n// ============================================================================\n// Hex Math Utilities\n// ============================================================================\n\nexport const hexUtils = {\n /** Convert axial coordinates to pixel position. */\n axialToPixel(\n q: number,\n r: number,\n size: number,\n orientation: HexOrientation,\n ): { x: number; y: number } {\n if (orientation === \"pointy-top\") {\n const x = size * (Math.sqrt(3) * q + (Math.sqrt(3) / 2) * r);\n const y = size * ((3 / 2) * r);\n return { x, y };\n } else {\n const x = size * ((3 / 2) * q);\n const y = size * ((Math.sqrt(3) / 2) * q + Math.sqrt(3) * r);\n return { x, y };\n }\n },\n\n getNeighbors(q: number, r: number): Array<{ q: number; r: number }> {\n return [\n { q: q + 1, r: r },\n { q: q + 1, r: r - 1 },\n { q: q, r: r - 1 },\n { q: q - 1, r: r },\n { q: q - 1, r: r + 1 },\n { q: q, r: r + 1 },\n ];\n },\n\n getDistance(q1: number, r1: number, q2: number, r2: number): number {\n return (\n (Math.abs(q1 - q2) + Math.abs(q1 + r1 - q2 - r2) + Math.abs(r1 - r2)) / 2\n );\n },\n\n getHexCorners(\n centerX: number,\n centerY: number,\n size: number,\n orientation: HexOrientation,\n ): Array<{ x: number; y: number }> {\n const corners: Array<{ x: number; y: number }> = [];\n const startAngle = orientation === \"pointy-top\" ? 30 : 0;\n\n for (let i = 0; i < 6; i++) {\n const angleDeg = startAngle + 60 * i;\n const angleRad = (Math.PI / 180) * angleDeg;\n corners.push({\n x: centerX + size * Math.cos(angleRad),\n y: centerY + size * Math.sin(angleRad),\n });\n }\n return corners;\n },\n\n getHexPoints(\n centerX: number,\n centerY: number,\n size: number,\n orientation: HexOrientation,\n ): string {\n const corners = this.getHexCorners(centerX, centerY, size, orientation);\n return corners.map((c) => `${c.x},${c.y}`).join(\" \");\n },\n\n getEdgePosition(\n hex1Pos: { x: number; y: number },\n hex2Pos: { x: number; y: number },\n size: number,\n ): EdgePosition {\n const midX = (hex1Pos.x + hex2Pos.x) / 2;\n const midY = (hex1Pos.y + hex2Pos.y) / 2;\n const centerAngleRad = Math.atan2(\n hex2Pos.y - hex1Pos.y,\n hex2Pos.x - hex1Pos.x,\n );\n\n // Calculate edge endpoints perpendicular to the line between hex centers\n const edgeAngleRad = centerAngleRad + Math.PI / 2;\n const edgeLength = size * 0.8;\n const centerAngle = (centerAngleRad * 180) / Math.PI;\n const edgeAngle = (edgeAngleRad * 180) / Math.PI;\n\n return {\n x1: midX - (edgeLength / 2) * Math.cos(edgeAngleRad),\n y1: midY - (edgeLength / 2) * Math.sin(edgeAngleRad),\n x2: midX + (edgeLength / 2) * Math.cos(edgeAngleRad),\n y2: midY + (edgeLength / 2) * Math.sin(edgeAngleRad),\n midX,\n midY,\n centerAngle,\n edgeAngle,\n };\n },\n\n getVertexPosition(\n hex1Pos: { x: number; y: number },\n hex2Pos: { x: number; y: number },\n hex3Pos: { x: number; y: number },\n ): { x: number; y: number } {\n return {\n x: (hex1Pos.x + hex2Pos.x + hex3Pos.x) / 3,\n y: (hex1Pos.y + hex2Pos.y + hex3Pos.y) / 3,\n };\n },\n};\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport interface HexGridComponent {\n <const TBoard extends AnyHexBoardInput>(\n props: HexGridBoardProps<TBoard>,\n ): ReactNode;\n <const TProps extends HexGeneratedGridInputProps>(\n props: HexGridProps<TProps>,\n ): ReactNode;\n <const TProps extends HexAuthoredGridInputProps>(\n props: HexGridProps<TProps>,\n ): ReactNode;\n}\n\nfunction HexGridImpl(\n props: HexGridBoardProps<AnyHexBoardInput> | HexGridProps<HexGridInputProps>,\n) {\n const {\n orientation = \"pointy-top\",\n hexSize = 50,\n renderTile,\n renderEdge,\n renderVertex,\n width = 800,\n height = 600,\n enablePanZoom = true,\n initialZoom = 1,\n minZoom = 0.5,\n maxZoom = 3,\n className,\n interactiveSpaces,\n interactiveVertices,\n interactiveEdges,\n renderInteractiveSpace,\n renderInteractiveVertex,\n renderInteractiveEdge,\n interactiveVertexSize = 12,\n interactiveEdgeSize = 10,\n } = props;\n const board =\n \"board\" in props\n ? props.board\n : ((\"spaces\" in props\n ? {\n id: \"__hex-grid__\",\n orientation,\n spaces: props.spaces,\n edges: props.edges ?? [],\n vertices: props.vertices ?? [],\n }\n : {\n id: \"__hex-grid__\",\n orientation,\n tiles: props.tiles,\n edges: props.edges ?? [],\n vertices: props.vertices ?? [],\n }) satisfies AnyHexBoardInput);\n // Pan/zoom is only enabled on mobile devices when the prop is true\n const isMobile = useIsMobile();\n const effectivePanZoom = enablePanZoom && isMobile;\n const normalizedBoard = useMemo<NormalizedHexBoard<AnyHexBoardInput>>(\n () => normalizeHexBoardInput(board),\n [board],\n );\n const resolvedTiles = normalizedBoard.tiles;\n const resolvedEdges = normalizedBoard.edges;\n const resolvedVertices = normalizedBoard.vertices;\n const resolvedOrientation = normalizedBoard.orientation ?? orientation;\n\n // Hover state for interactive elements\n const [hoveredSpaceId, setHoveredSpaceId] = useState<string | null>(null);\n const [hoveredVertexId, setHoveredVertexId] = useState<string | null>(null);\n const [hoveredEdgeId, setHoveredEdgeId] = useState<string | null>(null);\n\n // Use the unified pan/zoom hook\n const { transform, bind, isDragging } = usePanZoom({\n enabled: effectivePanZoom,\n initialZoom,\n minZoom,\n maxZoom,\n mode: \"viewbox\",\n });\n\n // Pre-compute tile positions\n const tilePositions = useMemo(() => {\n const positions = new Map<string, { x: number; y: number }>();\n resolvedTiles.forEach((tile) => {\n positions.set(\n tile.id,\n hexUtils.axialToPixel(tile.q, tile.r, hexSize, resolvedOrientation),\n );\n });\n return positions;\n }, [resolvedTiles, hexSize, resolvedOrientation]);\n\n // Build a `HexTileGeometry` for a tile centered at `position`.\n //\n // The closures intentionally re-derive corners on demand so callers\n // can pass a per-call `inset` without the grid pre-computing every\n // possible inset. Hex math is cheap (six trig calls).\n const buildTileGeometry = useMemo(\n () =>\n (position: { x: number; y: number }): HexTileGeometry => {\n const corners = (options?: { inset?: number }) => {\n const inset = options?.inset ?? 0;\n const radius = Math.max(0, hexSize - inset);\n return hexUtils.getHexCorners(0, 0, radius, resolvedOrientation);\n };\n const points = (options?: { inset?: number }) =>\n corners(options)\n .map((corner) => `${corner.x},${corner.y}`)\n .join(\" \");\n const outer = corners();\n const xs = outer.map((corner) => corner.x);\n const ys = outer.map((corner) => corner.y);\n const minX = Math.min(...xs);\n const maxX = Math.max(...xs);\n const minY = Math.min(...ys);\n const maxY = Math.max(...ys);\n return {\n size: hexSize,\n orientation: resolvedOrientation,\n center: { x: 0, y: 0 },\n position,\n corners,\n points,\n bounds: {\n minX,\n minY,\n maxX,\n maxY,\n width: maxX - minX,\n height: maxY - minY,\n },\n };\n },\n [hexSize, resolvedOrientation],\n );\n\n const resolvedEdgePositions = useMemo(\n () =>\n resolvedEdges.flatMap((edge) => {\n const pos1 = tilePositions.get(edge.hex1);\n const pos2 = tilePositions.get(edge.hex2);\n if (!pos1 || !pos2) {\n return [];\n }\n return [\n {\n edge,\n interactiveEdge: {\n ...edge,\n spaceIds: [edge.hex1, edge.hex2] as const,\n position: hexUtils.getEdgePosition(pos1, pos2, hexSize),\n } as InteractiveHexEdge<AnyHexBoardInput>,\n },\n ];\n }),\n [hexSize, resolvedEdges, tilePositions],\n );\n\n const resolvedVertexPositions = useMemo(\n () =>\n resolvedVertices.flatMap((vertex) => {\n const [hex0, hex1, hex2] = vertex.hexes;\n if (!hex0 || !hex1 || !hex2) {\n return [];\n }\n\n const pos0 = tilePositions.get(hex0);\n const pos1 = tilePositions.get(hex1);\n const pos2 = tilePositions.get(hex2);\n if (!pos0 || !pos1 || !pos2) {\n return [];\n }\n\n return [\n {\n vertex,\n interactiveVertex: {\n ...vertex,\n spaceIds: vertex.hexes,\n position: hexUtils.getVertexPosition(pos0, pos1, pos2),\n } as InteractiveHexVertex<AnyHexBoardInput>,\n },\n ];\n }),\n [resolvedVertices, tilePositions],\n );\n\n // Calculate bounds for viewBox\n const bounds = useMemo(() => {\n if (resolvedTiles.length === 0) {\n return { minX: 0, minY: 0, width: 400, height: 300 };\n }\n\n let minX = Infinity,\n minY = Infinity,\n maxX = -Infinity,\n maxY = -Infinity;\n resolvedTiles.forEach((tile) => {\n const pos = tilePositions.get(tile.id);\n if (pos) {\n minX = Math.min(minX, pos.x - hexSize);\n minY = Math.min(minY, pos.y - hexSize);\n maxX = Math.max(maxX, pos.x + hexSize);\n maxY = Math.max(maxY, pos.y + hexSize);\n }\n });\n\n const padding = hexSize;\n return {\n minX: minX - padding,\n minY: minY - padding,\n width: maxX - minX + padding * 2,\n height: maxY - minY + padding * 2,\n };\n }, [resolvedTiles, tilePositions, hexSize]);\n\n // Calculate viewBox with pan and zoom\n const viewBox = calculateViewBox(bounds, transform);\n\n // Parse viewBox for zoom indicator positioning\n const viewBoxParts = viewBox.split(\" \").map(Number);\n const viewBoxX = viewBoxParts[0] ?? 0;\n const viewBoxY = viewBoxParts[1] ?? 0;\n const viewBoxHeight = viewBoxParts[3] ?? 0;\n\n return (\n <svg\n width={width}\n height={height}\n viewBox={viewBox}\n className={clsx(\n \"hex-grid\",\n effectivePanZoom && \"touch-none\",\n isDragging && \"cursor-grabbing\",\n effectivePanZoom && !isDragging && \"cursor-grab\",\n className,\n )}\n {...bind()}\n role=\"img\"\n aria-label=\"Hex grid game board\"\n >\n <defs>\n {/* Gradient for ocean tiles */}\n <linearGradient id=\"oceanGradient\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor=\"#0ea5e9\" />\n <stop offset=\"100%\" stopColor=\"#0284c7\" />\n </linearGradient>\n {/* Drop shadow filter */}\n <filter id=\"hexShadow\" x=\"-20%\" y=\"-20%\" width=\"140%\" height=\"140%\">\n <feDropShadow dx=\"1\" dy=\"1\" stdDeviation=\"2\" floodOpacity=\"0.3\" />\n </filter>\n </defs>\n\n {/* Tiles layer */}\n <g className=\"tiles\" role=\"list\" aria-label=\"Hex tiles\">\n {resolvedTiles.map((tile) => {\n const pos = tilePositions.get(tile.id);\n if (!pos) return null;\n\n const geometry = buildTileGeometry(pos);\n return (\n <g\n key={tile.id}\n transform={`translate(${pos.x}, ${pos.y})`}\n role=\"listitem\"\n aria-label={tile.label ?? `Tile ${tile.id}`}\n >\n {renderTile(tile, geometry)}\n </g>\n );\n })}\n </g>\n\n {/* Interactive spaces layer */}\n {interactiveSpaces && resolvedTiles.length > 0 && (\n <g\n className=\"interactive-spaces\"\n role=\"list\"\n aria-label=\"Interactive spaces\"\n >\n {resolvedTiles.map((space) => {\n const pos = tilePositions.get(space.id);\n if (!pos) return null;\n const state = interactiveTargetRenderState(\n interactiveSpaces,\n space.id,\n hoveredSpaceId === space.id,\n );\n const isSelectable = isInteractiveTargetSelectable(\n interactiveSpaces,\n state,\n );\n return (\n <g\n key={space.id}\n transform={`translate(${pos.x}, ${pos.y})`}\n role={isSelectable ? \"button\" : undefined}\n className={clsx(isSelectable && \"cursor-pointer\")}\n onPointerEnter={() => setHoveredSpaceId(space.id)}\n onPointerLeave={() =>\n setHoveredSpaceId((currentId) =>\n currentId === space.id ? null : currentId,\n )\n }\n onClick={\n isSelectable\n ? () => {\n void state.select?.();\n }\n : undefined\n }\n onKeyDown={(event) =>\n handleKeyboardActivation(\n event,\n isSelectable\n ? () => {\n void state.select?.();\n }\n : undefined,\n )\n }\n tabIndex={isSelectable ? 0 : undefined}\n aria-label={\n isSelectable ? `Select space ${space.id}` : undefined\n }\n >\n {isSelectable && (\n <polygon\n points={buildTileGeometry(pos).points({\n inset: hexSize * 0.05,\n })}\n fill=\"rgba(255,255,255,0.001)\"\n pointerEvents=\"all\"\n />\n )}\n {renderInteractiveSpace\n ? renderInteractiveSpace(space, state)\n : null}\n </g>\n );\n })}\n </g>\n )}\n\n {/* Edges layer (for roads) */}\n {resolvedEdges.length > 0 && (\n <g className=\"edges\" role=\"list\" aria-label=\"Hex edges\">\n {resolvedEdgePositions.map(({ edge, interactiveEdge }) => {\n return (\n <g key={edge.id} role=\"listitem\">\n {renderEdge(edge, interactiveEdge.position)}\n </g>\n );\n })}\n </g>\n )}\n\n {/* Vertices layer (for settlements) */}\n {resolvedVertices.length > 0 && (\n <g className=\"vertices\" role=\"list\" aria-label=\"Hex vertices\">\n {resolvedVertexPositions.map(({ vertex, interactiveVertex }) => {\n return (\n <g key={vertex.id} role=\"listitem\">\n {renderVertex(vertex, interactiveVertex.position)}\n </g>\n );\n })}\n </g>\n )}\n\n {/* Interactive edges layer (for road placement) */}\n {interactiveEdges && resolvedEdgePositions.length > 0 && (\n <g\n className=\"interactive-edges\"\n role=\"list\"\n aria-label=\"Interactive edges for placement\"\n >\n {resolvedEdgePositions.map(({ interactiveEdge: edge }) => {\n const state = interactiveTargetRenderState(\n interactiveEdges,\n edge.id,\n hoveredEdgeId === edge.id,\n );\n const isSelectable = isInteractiveTargetSelectable(\n interactiveEdges,\n state,\n );\n const touchTargetLength = Math.hypot(\n edge.position.x2 - edge.position.x1,\n edge.position.y2 - edge.position.y1,\n );\n return (\n <g\n key={edge.id}\n role={isSelectable ? \"button\" : undefined}\n className={clsx(isSelectable && \"cursor-pointer\")}\n onPointerEnter={() => setHoveredEdgeId(edge.id)}\n onPointerLeave={() =>\n setHoveredEdgeId((currentId) =>\n currentId === edge.id ? null : currentId,\n )\n }\n onClick={\n isSelectable\n ? () => {\n void state.select?.();\n }\n : undefined\n }\n onKeyDown={(event) =>\n handleKeyboardActivation(\n event,\n isSelectable\n ? () => {\n void state.select?.();\n }\n : undefined,\n )\n }\n tabIndex={isSelectable ? 0 : undefined}\n aria-label={isSelectable ? `Select edge ${edge.id}` : undefined}\n >\n {isSelectable && (\n <rect\n x={edge.position.midX - touchTargetLength / 2}\n y={edge.position.midY - interactiveEdgeSize}\n width={touchTargetLength}\n height={interactiveEdgeSize * 2}\n rx={interactiveEdgeSize}\n fill=\"rgba(255,255,255,0.001)\"\n transform={`rotate(${edge.position.edgeAngle} ${edge.position.midX} ${edge.position.midY})`}\n pointerEvents=\"all\"\n />\n )}\n {renderInteractiveEdge ? (\n renderInteractiveEdge(edge, edge.position, state)\n ) : state.isEnabled && state.isEligible ? (\n <DefaultInteractiveEdge\n position={edge.position}\n isHovered={state.isHovered}\n strokeWidth={interactiveEdgeSize * 0.6}\n />\n ) : null}\n </g>\n );\n })}\n </g>\n )}\n\n {/* Interactive vertices layer (for settlement placement) */}\n {interactiveVertices && resolvedVertexPositions.length > 0 && (\n <g\n className=\"interactive-vertices\"\n role=\"list\"\n aria-label=\"Interactive vertices for placement\"\n >\n {resolvedVertexPositions.map(({ interactiveVertex: vertex }) => {\n const state = interactiveTargetRenderState(\n interactiveVertices,\n vertex.id,\n hoveredVertexId === vertex.id,\n );\n const isSelectable = isInteractiveTargetSelectable(\n interactiveVertices,\n state,\n );\n return (\n <g\n key={vertex.id}\n role={isSelectable ? \"button\" : undefined}\n className={clsx(isSelectable && \"cursor-pointer\")}\n onPointerEnter={() => setHoveredVertexId(vertex.id)}\n onPointerLeave={() =>\n setHoveredVertexId((currentId) =>\n currentId === vertex.id ? null : currentId,\n )\n }\n onClick={\n isSelectable\n ? () => {\n void state.select?.();\n }\n : undefined\n }\n onKeyDown={(event) =>\n handleKeyboardActivation(\n event,\n isSelectable\n ? () => {\n void state.select?.();\n }\n : undefined,\n )\n }\n tabIndex={isSelectable ? 0 : undefined}\n aria-label={\n isSelectable ? `Select vertex ${vertex.id}` : undefined\n }\n >\n {isSelectable && (\n <circle\n cx={vertex.position.x}\n cy={vertex.position.y}\n r={interactiveVertexSize * 1.5}\n fill=\"rgba(255,255,255,0.001)\"\n pointerEvents=\"all\"\n />\n )}\n {renderInteractiveVertex ? (\n renderInteractiveVertex(vertex, vertex.position, state)\n ) : state.isEnabled && state.isEligible ? (\n <DefaultInteractiveVertex\n position={vertex.position}\n isHovered={state.isHovered}\n size={interactiveVertexSize * 0.6}\n />\n ) : null}\n </g>\n );\n })}\n </g>\n )}\n\n {/* Zoom indicator (for mobile) */}\n {effectivePanZoom && transform.zoom !== 1 && (\n <g\n transform={`translate(${viewBoxX + 10}, ${viewBoxY + viewBoxHeight - 30})`}\n >\n <rect\n x={0}\n y={0}\n width={60}\n height={20}\n rx={4}\n fill=\"rgba(0,0,0,0.6)\"\n />\n <text x={30} y={14} textAnchor=\"middle\" fill=\"white\" fontSize={12}>\n {Math.round(transform.zoom * 100)}%\n </text>\n </g>\n )}\n </svg>\n );\n}\n\nexport const HexGrid = HexGridImpl as HexGridComponent;\n","/**\n * Typed adapter for joining static hex-board topology with a dynamic\n * per-space view overlay. Use this to feed `HexGrid` a single board\n * value whose tiles carry both static geometry (`q`, `r`, `id`) and\n * the projected view fields the UI cares about (e.g. `terrain`,\n * `numberToken`).\n *\n * The runtime is intentionally strict: every static space must have\n * exactly one overlay, duplicates throw, and overlays for ids that\n * are not on the board throw. There is no relaxed fallback in v1 —\n * silent merge bugs are far more expensive than a loud throw at\n * dev/CI time.\n */\n\nimport type {\n AnyHexBoardInput,\n BoardIdOf,\n BoardSpaceIdOf,\n NormalizedHexTileOf,\n} from \"../../types/tiled-board.js\";\nimport { normalizeHexBoardInput } from \"../../types/tiled-board.js\";\n\n/**\n * Per-tile result produced by {@link createHexBoardView}. Each tile\n * carries the static topology (`id`, `q`, `r`) plus the matched\n * overlay row in `view`.\n *\n * Static board fields/properties are preserved from `TBoard`.\n * Consumers should use `tile.properties` for authored static space\n * fields and `tile.view` for dynamic per-space projection data.\n */\nexport type HexBoardViewTile<\n TBoard extends AnyHexBoardInput,\n TSpaceView extends { id: BoardSpaceIdOf<TBoard> },\n> = Omit<NormalizedHexTileOf<TBoard>, \"view\"> & { view: TSpaceView };\n\n/**\n * Result of {@link createHexBoardView}. Shaped like an authored hex\n * board so it can be passed straight to `<HexGrid board={...} />`\n * without any further adapter work.\n *\n * The type-level board id and space id are preserved from `TBoard`,\n * so `tile.id` stays narrow inside `renderTile`. `tile.view` is the\n * authored overlay row, fully typed.\n */\nexport interface HexBoardView<\n TBoard extends AnyHexBoardInput,\n TSpaceView extends { id: BoardSpaceIdOf<TBoard> },\n> {\n id: BoardIdOf<TBoard>;\n layout?: \"hex\";\n orientation?: \"pointy-top\" | \"flat-top\";\n tiles: ReadonlyArray<HexBoardViewTile<TBoard, TSpaceView>>;\n edges: TBoard[\"edges\"];\n vertices: TBoard[\"vertices\"];\n}\n\ninterface CreateHexBoardViewOptions<TSpaceView> {\n spaces: readonly TSpaceView[];\n}\n\n/**\n * Join a static hex board topology with a dynamic per-space overlay.\n *\n * The result is suitable for direct use as the `board` prop on\n * `<HexGrid>`. Every overlay is enforced 1-to-1 against the board's\n * spaces:\n *\n * - missing overlay for a board space → throws\n * - duplicate overlay (same `id` twice) → throws\n * - overlay `id` not present on the board → throws\n *\n * Each tile in the result carries a `view` field with the matched\n * overlay row.\n */\nexport function createHexBoardView<\n const TBoard extends AnyHexBoardInput,\n const TSpaceView extends { id: BoardSpaceIdOf<TBoard> },\n>(\n board: TBoard,\n options: CreateHexBoardViewOptions<TSpaceView>,\n): HexBoardView<TBoard, TSpaceView> {\n const overlayById = new Map<string, TSpaceView>();\n for (const overlay of options.spaces) {\n if (overlayById.has(overlay.id)) {\n throw new Error(\n `createHexBoardView: duplicate overlay for space '${overlay.id}'.`,\n );\n }\n overlayById.set(overlay.id, overlay);\n }\n\n const consumed = new Set<string>();\n const normalizedBoard = normalizeHexBoardInput(board);\n const tiles: Array<HexBoardViewTile<TBoard, TSpaceView>> =\n normalizedBoard.tiles.map((tile) => {\n const overlay = overlayById.get(tile.id);\n if (!overlay) {\n throw new Error(\n `createHexBoardView: missing overlay for space '${tile.id}'.`,\n );\n }\n consumed.add(tile.id);\n return { ...tile, view: overlay };\n });\n\n for (const id of overlayById.keys()) {\n if (!consumed.has(id)) {\n throw new Error(\n `createHexBoardView: overlay '${id}' is not on the board.`,\n );\n }\n }\n\n return {\n id: normalizedBoard.id,\n layout: \"hex\",\n orientation: board.orientation,\n tiles,\n edges: board.edges,\n vertices: board.vertices,\n };\n}\n"],"mappings":";;;;;;AA2CA,SAAS,UAAU,aAAa,WAAW,eAAe;AAC1D,SAAS,kBAAgC;AAwDlC,SAAS,WAAW,UAA6B,CAAC,GAAqB;AAC5E,QAAM;AAAA,IACJ,UAAU;AAAA,IACV,cAAc;AAAA,IACd,UAAU;AAAA,IACV,UAAU;AAAA,IACV,aAAa,EAAE,GAAG,GAAG,GAAG,EAAE;AAAA,IAC1B,OAAO;AAAA,IACP,mBAAmB;AAAA,IACnB;AAAA,EACF,IAAI;AAEJ,QAAM,CAAC,MAAM,YAAY,IAAI,SAAS,WAAW;AACjD,QAAM,CAAC,KAAK,WAAW,IAAI,SAAS,UAAU;AAC9C,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAClD,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAGlD,QAAM,YAAY;AAAA,IAChB,CAAC,MAAc,KAAK,IAAI,SAAS,KAAK,IAAI,SAAS,CAAC,CAAC;AAAA,IACrD,CAAC,SAAS,OAAO;AAAA,EACnB;AAGA,QAAM,kBAAkB;AAAA,IACtB,CAAC,SAAiB,WAAqC;AACrD,YAAM,cAAc,UAAU,OAAO;AACrC,mBAAa,WAAW;AACxB,kBAAY,MAAM;AAClB,0BAAoB,EAAE,MAAM,aAAa,KAAK,OAAO,CAAC;AAAA,IACxD;AAAA,IACA,CAAC,WAAW,iBAAiB;AAAA,EAC/B;AAGA,QAAM,OAAO;AAAA,IACX;AAAA,MACE,SAAS,CAAC;AAAA,QACR,OAAO,CAAC,IAAI,EAAE;AAAA,QACd;AAAA,QACA;AAAA,MACF,MAAsC;AACpC,YAAI,CAAC,WAAW,SAAU;AAE1B,sBAAc,MAAM;AAEpB,YAAI,QAAQ;AAGV,gBAAM,cAAc,SAAS,YAAY,IAAI,OAAO;AACpD,sBAAY,CAAC,UAAU;AAAA,YACrB,GAAG,KAAK,IAAI,KAAK;AAAA,YACjB,GAAG,KAAK,IAAI,KAAK;AAAA,UACnB,EAAE;AAAA,QACJ;AAAA,MACF;AAAA,MACA,UAAU,CAAC;AAAA,QACT,QAAQ,CAAC,KAAK;AAAA,QACd;AAAA,MACF,MAAuC;AACrC,YAAI,CAAC,QAAS;AAEd,sBAAc,MAAM;AAEpB,YAAI,QAAQ;AACV,gBAAM,UAAU,UAAU,KAAK;AAC/B,uBAAa,OAAO;AACpB,8BAAoB,EAAE,MAAM,SAAS,IAAI,CAAC;AAAA,QAC5C;AAAA,MACF;AAAA,MACA,UAAU,CAAC,EAAE,OAAO,CAAC,EAAE,EAAE,GAAG,MAAM,MAAuC;AACvE,YAAI,CAAC,QAAS;AAEd,cAAM,eAAe;AACrB,cAAM,UAAU,UAAU,OAAO,KAAK,gBAAgB;AACtD,qBAAa,OAAO;AACpB,4BAAoB,EAAE,MAAM,SAAS,IAAI,CAAC;AAAA,MAC5C;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,QACJ;AAAA,QACA,YAAY;AAAA,MACd;AAAA,MACA,OAAO;AAAA,QACL;AAAA,QACA,aAAa,EAAE,KAAK,SAAS,KAAK,QAAQ;AAAA,QAC1C,MAAM,MAAM,CAAC,MAAM,CAAC;AAAA,MACtB;AAAA,MACA,OAAO;AAAA,QACL;AAAA,QACA,cAAc,EAAE,SAAS,MAAM;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAGA,QAAM,iBAAiB,YAAY,MAAM;AACvC,oBAAgB,aAAa,UAAU;AAAA,EACzC,GAAG,CAAC,aAAa,YAAY,eAAe,CAAC;AAE7C,YAAU,MAAM;AACd,oBAAgB,aAAa,UAAU;AAAA,EACzC,GAAG,CAAC,aAAa,WAAW,GAAG,WAAW,GAAG,eAAe,CAAC;AAG7D,QAAM,UAAU;AAAA,IACd,CAAC,YAAoB;AACnB,sBAAgB,UAAU,OAAO,GAAG,GAAG;AAAA,IACzC;AAAA,IACA,CAAC,KAAK,WAAW,eAAe;AAAA,EAClC;AAEA,QAAM,SAAS;AAAA,IACb,CAAC,WAAqC;AACpC,sBAAgB,MAAM,MAAM;AAAA,IAC9B;AAAA,IACA,CAAC,MAAM,eAAe;AAAA,EACxB;AAGA,QAAM,QAAQ;AAAA,IACZ,MACE,SAAS,QACL;AAAA,MACE,WAAW,aAAa,IAAI,CAAC,OAAO,IAAI,CAAC,aAAa,IAAI;AAAA,MAC1D,iBAAiB;AAAA,IACnB,IACA,CAAC;AAAA,IACP,CAAC,MAAM,IAAI,GAAG,IAAI,GAAG,IAAI;AAAA,EAC3B;AAGA,QAAM,YAAY;AAAA,IAChB,OAAO,EAAE,MAAM,IAAI;AAAA,IACnB,CAAC,MAAM,GAAG;AAAA,EACZ;AAIA,QAAM,WAAgC,YAAY,MAAM;AACtD,UAAM,SAAS,KAAK;AAIpB,UAAM,EAAE,KAAK,MAAM,GAAG,gBAAgB,IAAK,UACzC,CAAC;AACH,WAAO;AAAA,EACT,GAAG,CAAC,IAAI,CAAC;AAET,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAKO,SAAS,iBACd,QACA,WACQ;AACR,QAAM,eAAe,OAAO,QAAQ,UAAU;AAC9C,QAAM,gBAAgB,OAAO,SAAS,UAAU;AAChD,QAAM,WACJ,OAAO,QAAQ,OAAO,QAAQ,gBAAgB,IAAI,UAAU,IAAI;AAClE,QAAM,WACJ,OAAO,QAAQ,OAAO,SAAS,iBAAiB,IAAI,UAAU,IAAI;AAEpE,SAAO,GAAG,QAAQ,IAAI,QAAQ,IAAI,YAAY,IAAI,aAAa;AACjE;;;ACrRA,SAAS,YAAAA,WAAU,aAAAC,kBAAiB;AAEpC,IAAM,oBAAoB;AAOnB,SAAS,YAAY,aAAqB,mBAA4B;AAC3E,QAAM,CAAC,UAAU,WAAW,IAAID,UAAS,MAAM;AAE7C,QAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,WAAO,OAAO,aAAa;AAAA,EAC7B,CAAC;AAED,EAAAC,WAAU,MAAM;AACd,QAAI,OAAO,WAAW,YAAa;AAEnC,UAAM,aAAa,OAAO,WAAW,eAAe,aAAa,CAAC,KAAK;AAEvE,UAAM,eAAe,CAAC,MAA4C;AAChE,kBAAY,EAAE,OAAO;AAAA,IACvB;AAGA,iBAAa,UAAU;AAGvB,eAAW,iBAAiB,UAAU,YAAY;AAClD,WAAO,MAAM,WAAW,oBAAoB,UAAU,YAAY;AAAA,EACpE,GAAG,CAAC,UAAU,CAAC;AAEf,SAAO;AACT;;;ACuUO,SAAS,WAAW,MAAa,UAAiC;AACvE,MAAI,CAAC,SAAU,QAAO;AACtB,SAAO,UAAU,MAAM,QAAQ;AACjC;AAEA,SAAS,UAAa,MAAS,UAAsB;AACnD,MAAI,MAAM,QAAQ,QAAQ,GAAG;AAE3B,WAAO;AAAA,EACT;AACA,MACE,QACA,OAAO,SAAS,YAChB,YACA,OAAO,aAAa,YACpB,CAAC,MAAM,QAAQ,IAAI,GACnB;AACA,UAAM,SAAkC;AAAA,MACtC,GAAI;AAAA,IACN;AACA,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO;AAAA,MAChC;AAAA,IACF,GAAG;AACD,UAAI,UAAU,OAAW;AACzB,YAAM,YAAa,KAAiC,GAAG;AACvD,aAAO,GAAG,IAAI,UAAU,WAAW,KAAK;AAAA,IAC1C;AACA,WAAO;AAAA,EACT;AACA,SAAO,aAAa,SAAY,OAAQ;AAC1C;;;ACzXO,IAAM,gBAAuB;AAAA,EAClC,MAAM;AAAA,IACJ,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,OAAO;AAAA,IACL,SAAS;AAAA,MACP,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,IACA,OAAO;AAAA,MACL,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,IACA,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,IACA,SAAS;AAAA,MACP,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,IACA,SAAS;AAAA,MACP,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,IACA,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,IACA,MAAM;AAAA,MACJ,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EACA,UAAU;AAAA,IACR,SAAS;AAAA,MACP,KAAK;AAAA,MACL,OAAO;AAAA,MACP,KAAK;AAAA,MACL,MAAM;AAAA,MACN,OAAO;AAAA,MACP,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAAA,IACA,MAAM;AAAA,MACJ,SAAS;AAAA,MACT,OAAO;AAAA,MACP,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,UAAU;AAAA,IACZ;AAAA,IACA,QAAQ;AAAA,MACN,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA,QAAQ;AAAA,MACN,SAAS;AAAA,QACP,OAAO;AAAA,QACP,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,MACA,WAAW;AAAA,QACT,OAAO;AAAA,QACP,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,MACA,SAAS;AAAA,QACP,OAAO;AAAA,QACP,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,MACA,QAAQ;AAAA,QACN,OAAO;AAAA,QACP,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,MACA,SAAS;AAAA,QACP,OAAO;AAAA,QACP,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,MACA,MAAM;AAAA,QACJ,OAAO;AAAA,QACP,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AAAA,EACA,OAAO;AAAA,IACL,GAAG;AAAA,IACH,KAAK;AAAA,IACL,GAAG;AAAA,IACH,KAAK;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,IAAI;AAAA,EACN;AAAA,EACA,YAAY;AAAA,IACV,YAAY;AAAA,MACV,SACE;AAAA,MACF,MAAM;AAAA,MACN,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AAAA,IACA,UAAU;AAAA,MACR,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,IACA,YAAY;AAAA,MACV,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,MAAM;AAAA,IACR;AAAA,IACA,YAAY;AAAA,MACV,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AAAA,IACA,eAAe;AAAA,MACb,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EACA,WAAW;AAAA,IACT,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QACE;AAAA,IACF,SAAS;AAAA,IACT,OAAO;AAAA,EACT;AAAA,EACA,QAAQ;AAAA,IACN,UAAU;AAAA,MACR,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA,QAAQ;AAAA,MACN,KAAK;AAAA,MACL,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,QAAQ;AAAA,IACV;AAAA,IACA,eAAe;AAAA,EACjB;AAAA,EACA,QAAQ;AAAA,IACN,EAAE,OAAO,WAAW,MAAM,WAAW,IAAI,UAAU;AAAA,IACnD,EAAE,OAAO,WAAW,MAAM,WAAW,IAAI,UAAU;AAAA,IACnD,EAAE,OAAO,WAAW,MAAM,WAAW,IAAI,UAAU;AAAA,IACnD,EAAE,OAAO,WAAW,MAAM,WAAW,IAAI,UAAU;AAAA,IACnD,EAAE,OAAO,WAAW,MAAM,WAAW,IAAI,UAAU;AAAA,IACnD,EAAE,OAAO,WAAW,MAAM,WAAW,IAAI,UAAU;AAAA,EACrD;AAAA,EACA,WAAW;AAAA,IACT,OAAO;AAAA,MACL,aAAa;AAAA,MACb,iBAAiB;AAAA,MACjB,WAAW;AAAA,MACX,cAAc;AAAA,IAChB;AAAA,IACA,MAAM;AAAA,MACJ,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,cAAc;AAAA,IAChB;AAAA,IACA,YAAY;AAAA,MACV,kBAAkB;AAAA,MAClB,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,oBAAoB;AAAA,MACpB,oBAAoB;AAAA,IACtB;AAAA,IACA,OAAO;AAAA,MACL,mBAAmB;AAAA,MACnB,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,YAAY;AAAA,IACd;AAAA,EACF;AACF;;;AChQO,IAAM,cAAqB;AAAA,EAChC,MAAM;AAAA,IACJ,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,OAAO;AAAA,IACL,SAAS;AAAA,MACP,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,IACA,OAAO;AAAA,MACL,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,IACA,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,IACA,SAAS;AAAA,MACP,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,IACA,SAAS;AAAA,MACP,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,IACA,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,IACA,MAAM;AAAA,MACJ,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EACA,UAAU;AAAA,IACR,SAAS;AAAA,MACP,KAAK;AAAA,MACL,OAAO;AAAA,MACP,KAAK;AAAA,MACL,MAAM;AAAA,MACN,OAAO;AAAA,MACP,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAAA,IACA,MAAM;AAAA,MACJ,SAAS;AAAA,MACT,OAAO;AAAA,MACP,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,UAAU;AAAA,IACZ;AAAA,IACA,QAAQ;AAAA,MACN,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA,QAAQ;AAAA,MACN,SAAS;AAAA,QACP,OAAO;AAAA,QACP,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,MACA,WAAW;AAAA,QACT,OAAO;AAAA,QACP,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,MACA,SAAS;AAAA,QACP,OAAO;AAAA,QACP,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,MACA,QAAQ;AAAA,QACN,OAAO;AAAA,QACP,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,MACA,SAAS;AAAA,QACP,OAAO;AAAA,QACP,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,MACA,MAAM;AAAA,QACJ,OAAO;AAAA,QACP,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AAAA,EACA,OAAO;AAAA,IACL,GAAG;AAAA,IACH,KAAK;AAAA,IACL,GAAG;AAAA,IACH,KAAK;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,IAAI;AAAA,EACN;AAAA,EACA,YAAY;AAAA,IACV,YAAY;AAAA,MACV,SAAS;AAAA,MACT,MAAM;AAAA,MACN,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AAAA,IACA,UAAU;AAAA,MACR,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,IACA,YAAY;AAAA,MACV,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,MAAM;AAAA,IACR;AAAA,IACA,YAAY;AAAA,MACV,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AAAA,IACA,eAAe;AAAA,MACb,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EACA,WAAW;AAAA,IACT,MAAM;AAAA,IACN,OACE;AAAA,IACF,QACE;AAAA,IACF,SAAS;AAAA,IACT,OAAO;AAAA,EACT;AAAA,EACA,QAAQ;AAAA,IACN,UAAU;AAAA,MACR,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA,QAAQ;AAAA,MACN,KAAK;AAAA,MACL,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,QAAQ;AAAA,IACV;AAAA,IACA,eAAe;AAAA,EACjB;AAAA,EACA,QAAQ;AAAA,IACN,EAAE,OAAO,WAAW,MAAM,2BAA2B,IAAI,UAAU;AAAA,IACnE,EAAE,OAAO,WAAW,MAAM,2BAA2B,IAAI,UAAU;AAAA,IACnE,EAAE,OAAO,WAAW,MAAM,2BAA2B,IAAI,UAAU;AAAA,IACnE,EAAE,OAAO,WAAW,MAAM,2BAA2B,IAAI,UAAU;AAAA,IACnE,EAAE,OAAO,WAAW,MAAM,2BAA2B,IAAI,UAAU;AAAA,IACnE,EAAE,OAAO,WAAW,MAAM,2BAA2B,IAAI,UAAU;AAAA,EACrE;AAAA,EACA,WAAW;AAAA,IACT,OAAO;AAAA,MACL,aAAa;AAAA,MACb,iBAAiB;AAAA,MACjB,WAAW;AAAA,MACX,cAAc;AAAA,IAChB;AAAA,IACA,MAAM;AAAA,MACJ,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,cAAc;AAAA,IAChB;AAAA,IACA,YAAY;AAAA,MACV,kBAAkB;AAAA,MAClB,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,oBAAoB;AAAA,MACpB,oBAAoB;AAAA,IACtB;AAAA,IACA,OAAO;AAAA,MACL,mBAAmB;AAAA,MACnB,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,YAAY;AAAA,IACd;AAAA,EACF;AACF;;;AC3PO,IAAM,cAAqB;AAAA,EAChC,MAAM;AAAA,IACJ,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,OAAO;AAAA,IACL,SAAS;AAAA,MACP,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,IACA,OAAO;AAAA,MACL,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,IACA,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,IACA,SAAS;AAAA,MACP,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,IACA,SAAS;AAAA,MACP,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,IACA,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,IACA,MAAM;AAAA,MACJ,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EACA,UAAU;AAAA,IACR,SAAS;AAAA,MACP,KAAK;AAAA,MACL,OAAO;AAAA,MACP,KAAK;AAAA,MACL,MAAM;AAAA,MACN,OAAO;AAAA,MACP,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAAA,IACA,MAAM;AAAA,MACJ,SAAS;AAAA,MACT,OAAO;AAAA,MACP,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,UAAU;AAAA,IACZ;AAAA,IACA,QAAQ;AAAA,MACN,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA,QAAQ;AAAA,MACN,SAAS;AAAA,QACP,OAAO;AAAA,QACP,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,MACA,WAAW;AAAA,QACT,OAAO;AAAA,QACP,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,MACA,SAAS;AAAA,QACP,OAAO;AAAA,QACP,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,MACA,QAAQ;AAAA,QACN,OAAO;AAAA,QACP,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,MACA,SAAS;AAAA,QACP,OAAO;AAAA,QACP,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,MACA,MAAM;AAAA,QACJ,OAAO;AAAA,QACP,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AAAA,EACA,OAAO;AAAA,IACL,GAAG;AAAA,IACH,KAAK;AAAA,IACL,GAAG;AAAA,IACH,KAAK;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,IAAI;AAAA,EACN;AAAA,EACA,YAAY;AAAA,IACV,YAAY;AAAA,MACV,SACE;AAAA,MACF,MAAM;AAAA,MACN,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AAAA,IACA,UAAU;AAAA,MACR,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,IACA,YAAY;AAAA,MACV,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,MAAM;AAAA,IACR;AAAA,IACA,YAAY;AAAA,MACV,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AAAA,IACA,eAAe;AAAA,MACb,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EACA,WAAW;AAAA,IACT,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QACE;AAAA,IACF,SAAS;AAAA,IACT,OAAO;AAAA,EACT;AAAA,EACA,QAAQ;AAAA,IACN,UAAU;AAAA,MACR,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA,QAAQ;AAAA,MACN,KAAK;AAAA,MACL,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,QAAQ;AAAA,IACV;AAAA,IACA,eAAe;AAAA,EACjB;AAAA,EACA,QAAQ;AAAA,IACN,EAAE,OAAO,WAAW,MAAM,WAAW,IAAI,UAAU;AAAA,IACnD,EAAE,OAAO,WAAW,MAAM,WAAW,IAAI,UAAU;AAAA,IACnD,EAAE,OAAO,WAAW,MAAM,WAAW,IAAI,UAAU;AAAA,IACnD,EAAE,OAAO,WAAW,MAAM,WAAW,IAAI,UAAU;AAAA,IACnD,EAAE,OAAO,WAAW,MAAM,WAAW,IAAI,UAAU;AAAA,IACnD,EAAE,OAAO,WAAW,MAAM,WAAW,IAAI,UAAU;AAAA,EACrD;AAAA,EACA,WAAW;AAAA,IACT,OAAO;AAAA,MACL,aAAa;AAAA,MACb,iBAAiB;AAAA,MACjB,WAAW;AAAA,MACX,cAAc;AAAA,IAChB;AAAA,IACA,MAAM;AAAA,MACJ,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,cAAc;AAAA,IAChB;AAAA,IACA,YAAY;AAAA,MACV,kBAAkB;AAAA,MAClB,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,oBAAoB;AAAA,MACpB,oBAAoB;AAAA,IACtB;AAAA,IACA,OAAO;AAAA,MACL,mBAAmB;AAAA,MACnB,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,YAAY;AAAA,IACd;AAAA,EACF;AACF;;;AC1OA,IAAM,SAAS;AAGf,SAAS,UAAU,OAA+C;AAChE,QAAM,OAAO,MACV,IAAI,CAAC,SAAS,OAAO,IAAI,CAAC,EAC1B,KAAK,GAAG,EACR,QAAQ,kBAAkB,GAAG,EAC7B,QAAQ,OAAO,GAAG;AACrB,SAAO,GAAG,MAAM,IAAI,IAAI;AAC1B;AAOO,SAAS,eAAe,OAA6B;AAC1D,QAAM,MAA8B,CAAC;AACrC,OAAK,OAA6C,CAAC,GAAG,GAAG;AACzD,SAAO;AACT;AAEA,SAAS,KACP,MACA,MACA,KACM;AACN,MAAI,SAAS,QAAQ,SAAS,OAAW;AACzC,MAAI,OAAO,SAAS,YAAY,OAAO,SAAS,UAAU;AACxD,QAAI,UAAU,IAAI,CAAC,IAAI,OAAO,IAAI;AAClC;AAAA,EACF;AACA,MAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,SAAK,QAAQ,CAAC,OAAO,QAAQ;AAE3B,WAAK,OAAO,CAAC,GAAG,MAAM,MAAM,CAAC,GAAG,GAAG;AAAA,IACrC,CAAC;AACD;AAAA,EACF;AACA,MAAI,OAAO,SAAS,UAAU;AAC5B,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO;AAAA,MAChC;AAAA,IACF,GAAG;AACD,WAAK,OAAO,CAAC,GAAG,MAAM,GAAG,GAAG,GAAG;AAAA,IACjC;AAAA,EACF;AACF;AAaO,SAAS,UAAU,MAAsC;AAC9D,SAAO,OAAO,UAAU,IAAI,CAAC;AAC/B;AAWO,SAAS,SACd,aACG,MACK;AACR,SAAO,OAAO,UAAU,IAAI,CAAC,KAAK,QAAQ;AAC5C;;;ACxGA;AAAA,EACE;AAAA,EACA;AAAA,EACA,aAAAC;AAAA,EACA,WAAAC;AAAA,EACA,YAAAC;AAAA,OAGK;AAgKI;AAlJX,IAAM,UAAkD;AAAA,EACtD,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,QAAQ;AACV;AASO,SAAS,aAAa,OAAiD;AAC5E,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,SAAS,QAAQ,KAAK;AAC5B,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI;AAAA,QACR,kCAAkC,KAAK,0CAA0C,OAAO;AAAA,UACtF;AAAA,QACF,EAAE,KAAK,IAAI,CAAC;AAAA,MACd;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAGO,SAAS,eAAe,IAAsC;AACnE,SAAO,QAAQ,EAAE;AACnB;AAcA,IAAM,WAAW,cAAwC,IAAI;AAuC7D,SAAS,0BAAmC;AAC1C,QAAM,CAAC,SAAS,UAAU,IAAIC,UAAS,KAAK;AAC5C,EAAAC,WAAU,MAAM;AACd,QAAI,OAAO,WAAW,eAAe,CAAC,OAAO,WAAY;AACzD,UAAM,QAAQ,OAAO,WAAW,kCAAkC;AAClE,eAAW,MAAM,OAAO;AACxB,UAAM,SAAS,CAAC,UAA+B,WAAW,MAAM,OAAO;AACvE,UAAM,iBAAiB,UAAU,MAAM;AACvC,WAAO,MAAM,MAAM,oBAAoB,UAAU,MAAM;AAAA,EACzD,GAAG,CAAC,CAAC;AACL,SAAO;AACT;AAiBO,SAAS,cAAc;AAAA,EAC5B,OAAO;AAAA,EACP;AAAA,EACA,gBAAgB;AAAA,EAChB,KAAK;AAAA,EACL;AAAA,EACA;AAAA,EACA;AACF,GAAuB;AACrB,QAAM,iBAAiB,wBAAwB;AAE/C,QAAM,QAAQC,SAA2B,MAAM;AAC7C,UAAM,OAAO,aAAa,UAAU;AACpC,UAAM,SAAS,WAAW,MAAM,QAAQ;AACxC,UAAM,iBACJ,kBAAkB,UACd,SACA,kBAAkB,WAChB,OAAO,OAAO,gBACd,iBACE,SACA,OAAO,OAAO;AACxB,UAAM,QACJ,mBAAmB,OAAO,OAAO,gBAC7B,SACA;AAAA,MACE,GAAG;AAAA,MACH,QAAQ,EAAE,GAAG,OAAO,QAAQ,eAAe,eAAe;AAAA,IAC5D;AACN,WAAO,EAAE,OAAO,OAAO,SAAS,eAAe,KAAK,EAAE;AAAA,EACxD,GAAG,CAAC,YAAY,UAAU,eAAe,cAAc,CAAC;AAExD,MAAI,OAAO,QAAQ;AACjB,WAAO,oBAAC,SAAS,UAAT,EAAkB,OAAe,UAAS;AAAA,EACpD;AAEA,QAAM,eAA8B;AAAA,IAClC,GAAG,kBAAkB,MAAM,KAAK;AAAA,IAChC,GAAG,MAAM;AAAA,IACT,YAAY,MAAM,MAAM,WAAW,WAAW;AAAA,IAC9C,GAAG;AAAA,EACL;AAEA,SACE,oBAAC,SAAS,UAAT,EAAkB,OACjB;AAAA,IAAC;AAAA;AAAA,MACC,yBAAuB,MAAM,MAAM,KAAK;AAAA,MACxC,wBAAsB,MAAM,MAAM,KAAK;AAAA,MACvC,kCAAgC,MAAM,MAAM,OAAO;AAAA,MACnD;AAAA,MACA,OAAO;AAAA,MAEN;AAAA;AAAA,EACH,GACF;AAEJ;AASO,SAAS,WAAkB;AAChC,QAAM,MAAM,WAAW,QAAQ;AAC/B,SAAO,KAAK,SAAS;AACvB;AAOO,SAAS,kBAAiC;AAC/C,QAAM,MAAM,WAAW,QAAQ;AAC/B,MAAI,IAAK,QAAO,EAAE,GAAG,kBAAkB,IAAI,KAAK,GAAG,GAAG,IAAI,QAAQ;AAElE,SAAO;AAAA,IACL,GAAG,kBAAkB,aAAa;AAAA,IAClC,GAAG,eAAe,aAAa;AAAA,EACjC;AACF;AAQA,SAAS,kBAAkB,OAA6B;AACtD,QAAM,OAAyB;AAAA,IAC7B,gBAAgB,MAAM,SAAS,QAAQ;AAAA,IACvC,gBAAgB,MAAM,SAAS,KAAK;AAAA,IACpC,UAAU,MAAM,SAAS,QAAQ;AAAA,IACjC,qBAAqB,MAAM,SAAS,KAAK;AAAA,IACzC,aAAa,MAAM,SAAS,QAAQ;AAAA,IACpC,wBAAwB,MAAM,SAAS,KAAK;AAAA,IAC5C,aAAa,MAAM,SAAS,OAAO,QAAQ;AAAA,IAC3C,wBAAwB,MAAM,SAAS,OAAO,QAAQ;AAAA,IACtD,eAAe,MAAM,SAAS,OAAO,UAAU;AAAA,IAC/C,0BAA0B,MAAM,SAAS,OAAO,UAAU;AAAA,IAC1D,WAAW,MAAM,SAAS,QAAQ;AAAA,IAClC,sBAAsB,MAAM,SAAS,KAAK;AAAA,IAC1C,YAAY,MAAM,SAAS,OAAO,KAAK;AAAA,IACvC,uBAAuB,MAAM,SAAS,OAAO,KAAK;AAAA,IAClD,iBAAiB,MAAM,SAAS,OAAO,OAAO;AAAA,IAC9C,4BAA4B,MAAM,SAAS,OAAO,OAAO;AAAA,IACzD,YAAY,MAAM,SAAS,OAAO;AAAA,IAClC,WAAW,MAAM,SAAS,OAAO;AAAA,IACjC,UAAU,MAAM,SAAS,OAAO;AAAA,IAChC,eAAe,MAAM,WAAW,WAAW;AAAA,IAC3C,kBAAkB,MAAM,WAAW,WAAW;AAAA,EAChD;AACA,SAAO;AACT;;;ACrNO,SAAS,YACd,OACA,UAKI,CAAC,GACU;AACf,QAAM,EAAE,UAAU,WAAW,OAAO,MAAM,UAAU,QAAQ,IAAI;AAChE,QAAM,SAAS,iBAAiB,OAAO,OAAO;AAC9C,QAAM,SAAS,YAAY,IAAI;AAC/B,QAAM,mBAAmB,YAAY,YAAY;AAEjD,QAAM,aACJ,YAAY,UACR,SACA,UACE,MAAM,UAAU,OAChB,MAAM,UAAU;AAExB,SAAO;AAAA,IACL,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,KAAK,MAAM,MAAM,CAAC;AAAA,IAClB,WAAW,OAAO;AAAA,IAClB,cAAc,OAAO;AAAA,IACrB,eAAe,OAAO;AAAA,IACtB,cAAc,MAAM,OAAO;AAAA,IAC3B,QACE,YAAY,UACR,0BACA,aAAa,mBAAmB,MAAM,SAAS,OAAO,SAAS,OAAO,MAAM;AAAA,IAClF,YACE,YAAY,UACR,gBACA,mBACE,MAAM,SAAS,QAAQ,QACvB,OAAO;AAAA,IACf,OAAO,mBACH,MAAM,SAAS,KAAK,WACpB,YAAY,UACV,MAAM,SAAS,KAAK,UACpB,OAAO;AAAA,IACb,YAAY,MAAM,WAAW,WAAW;AAAA,IACxC,UAAU,OAAO;AAAA,IACjB,YAAY,MAAM,WAAW,WAAW;AAAA,IACxC,YAAY,MAAM,WAAW,WAAW;AAAA,IACxC,eAAe,MAAM,WAAW,cAAc;AAAA,IAC9C,QAAQ,WAAW,gBAAgB;AAAA,IACnC,WAAW,WAAW,SAAS;AAAA,IAC/B,YAAY,oBAAoB,MAAM,OAAO,SAAS,IAAI,IAAI,MAAM,OAAO,OAAO,GAAG,eAAe,MAAM,OAAO,SAAS,IAAI,IAAI,MAAM,OAAO,OAAO,GAAG,gBAAgB,MAAM,OAAO,SAAS,MAAM,IAAI,MAAM,OAAO,OAAO,GAAG;AAAA,IAChO,YAAY;AAAA,IACZ,yBAAyB;AAAA,EAC3B;AACF;AAEA,IAAM,cAQF;AAAA,EACF,IAAI;AAAA,IACF,WAAW;AAAA,IACX,cAAc;AAAA,IACd,eAAe;AAAA,IACf,UAAU;AAAA,EACZ;AAAA,EACA,IAAI;AAAA,IACF,WAAW;AAAA,IACX,cAAc;AAAA,IACd,eAAe;AAAA,IACf,UAAU;AAAA,EACZ;AAAA,EACA,IAAI;AAAA,IACF,WAAW;AAAA,IACX,cAAc;AAAA,IACd,eAAe;AAAA,IACf,UAAU;AAAA,EACZ;AACF;AAMO,SAAS,UACd,OACA,UAGI,CAAC,GACU;AACf,QAAM,EAAE,UAAU,aAAa,OAAO,KAAK,IAAI;AAC/C,QAAM,SAAS,iBAAiB,OAAO,OAAO;AAC9C,SAAO;AAAA,IACL,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,KAAK,MAAM,MAAM,CAAC;AAAA,IAClB,cAAc,SAAS,OAAO,YAAY;AAAA,IAC1C,eAAe,SAAS,OAAO,aAAa;AAAA,IAC5C,cAAc,MAAM,OAAO;AAAA,IAC3B,QAAQ,aAAa,OAAO,MAAM;AAAA,IAClC,YAAY,OAAO;AAAA,IACnB,OAAO,OAAO;AAAA,IACd,YAAY,MAAM,WAAW,WAAW;AAAA,IACxC,UACE,SAAS,OACL,MAAM,WAAW,SAAS,KAC1B,MAAM,WAAW,SAAS;AAAA,IAChC,YAAY,MAAM,WAAW,WAAW;AAAA,IACxC,eAAe,MAAM,WAAW,cAAc;AAAA,IAC9C,eAAe;AAAA,IACf,YAAY;AAAA,EACd;AACF;AAOO,SAAS,aACd,OACA,UAKI,CAAC,GACU;AACf,QAAM,EAAE,OAAO,QAAQ,aAAa,SAAS,KAAK,IAAI;AACtD,SAAO;AAAA,IACL,YAAY,MAAM,SAAS,QAAQ,IAAI;AAAA,IACvC,OAAO,MAAM,SAAS,KAAK;AAAA,IAC3B,QAAQ,aAAa,MAAM,SAAS,OAAO,MAAM;AAAA,IACjD,cAAc,MAAM,OAAO,MAAM;AAAA,IACjC,WAAW,MAAM,UAAU;AAAA,IAC3B,YAAY,cACR,cAAc,MAAM,OAAO,SAAS,MAAM,IAAI,MAAM,OAAO,OAAO,GAAG,eAAe,MAAM,OAAO,SAAS,MAAM,IAAI,MAAM,OAAO,OAAO,GAAG,KAC3I;AAAA,EACN;AACF;AAGO,SAAS,iBACd,OACA,SACa;AACb,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO,MAAM,SAAS,OAAO;AAAA,IAC/B,KAAK;AACH,aAAO,MAAM,SAAS,OAAO;AAAA,IAC/B,KAAK;AACH,aAAO,MAAM,SAAS,OAAO;AAAA,IAC/B,KAAK;AACH,aAAO,MAAM,SAAS,OAAO;AAAA,IAC/B,KAAK;AACH,aAAO,MAAM,SAAS,OAAO;AAAA,IAC/B,KAAK;AACH,aAAO,MAAM,SAAS,OAAO;AAAA,IAC/B,KAAK;AACH,aAAO,MAAM,SAAS,OAAO;AAAA,IAC/B,KAAK;AACH,aAAO,MAAM,SAAS,OAAO;AAAA,EACjC;AACF;AAOO,SAAS,YAAY,OAAc,MAAc;AACtD,QAAM,SAAS,MAAM,OAAO;AAC5B,QAAM,OAAQ,OAAO,SAAU,UAAU;AAMzC,SAAO,MAAM,OAAO,GAAG,KAAK,MAAM,OAAO,CAAC;AAC5C;AAOO,SAAS,eACd,OACA,KACQ;AACR,MAAI,MAAM,OAAO,kBAAkB,OAAQ,QAAO;AAClD,SAAO,MAAM,OAAO,SAAS,GAAG;AAClC;;;ACyOA,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAEA,SAAS,WAAW,QAAoD;AACtE,QAAM,CAAC,KAAK,IAAI,OAAO,OAAO,MAAM;AACpC,SAAO;AACT;AAEA,SAAS,kBACP,OACsB;AACtB,SAAQ,SAAS;AACnB;AAEO,SAAS,yBAGd,OACyE;AACzE,MAAI,CAAC,SAAS,KAAK,KAAK,EAAE,YAAY,UAAU,CAAC,SAAS,MAAM,MAAM,GAAG;AACvE,WAAO;AAAA,EACT;AACA,MAAI,WAAW,SAAS,WAAW,OAAO;AACxC,WAAO;AAAA,EACT;AACA,MAAI,MAAM,WAAW,OAAO;AAC1B,WAAO;AAAA,EACT;AACA,QAAM,aAAa;AAAA,IACjB,MAAM;AAAA,EACR;AACA,SACE,SAAS,UAAU,KACnB,OAAO,WAAW,MAAM,YACxB,OAAO,WAAW,MAAM;AAE5B;AAEO,SAAS,4BAGd,OACyE;AACzE,MAAI,CAAC,SAAS,KAAK,KAAK,EAAE,YAAY,UAAU,CAAC,SAAS,MAAM,MAAM,GAAG;AACvE,WAAO;AAAA,EACT;AACA,MAAI,WAAW,SAAS,WAAW,OAAO;AACxC,WAAO;AAAA,EACT;AACA,MAAI,MAAM,WAAW,UAAU;AAC7B,WAAO;AAAA,EACT;AACA,QAAM,aAAa;AAAA,IACjB,MAAM;AAAA,EACR;AACA,SACE,SAAS,UAAU,KACnB,OAAO,WAAW,QAAQ,YAC1B,OAAO,WAAW,QAAQ;AAE9B;AAEA,SAAS,iBACP,MAC6B;AAC7B,SAAO;AAAA,IACL,IAAI,KAAK;AAAA,IACT,GAAG,KAAK;AAAA,IACR,GAAG,KAAK;AAAA,IACR,QAAQ,kBAAkB,KAAK,MAAwC;AAAA,IACvE,OAAO,kBAAkB,KAAK,KAAkC;AAAA,IAChE,OAAO,kBAAkB,KAAK,OAAsC;AAAA,IACpE,YAAa,KAAK,UAAU;AAAA,IAC5B,MAAM;AAAA,EACR;AACF;AAEA,SAAS,iBACP,MAC6B;AAC7B,MAAI,UAAU,QAAQ,UAAU,MAAM;AACpC,WAAO;AAAA,MACL,GAAG;AAAA,MACH,OAAO,kBAAkB,KAAK,KAAK;AAAA,MACnC,OAAO,kBAAkB,KAAK,KAAK;AAAA,MACnC,QAAQ,kBAAkB,KAAK,MAAM;AAAA,MACrC,YAAY,KAAK;AAAA,IACnB;AAAA,EACF;AAEA,QAAM,CAAC,OAAO,IAAI,OAAO,EAAE,IAAI,KAAK;AACpC,SAAO;AAAA,IACL,IAAI,KAAK;AAAA,IACT;AAAA,IACA;AAAA,IACA,QAAQ,kBAAkB,KAAK,MAAM;AAAA,IACrC,OAAO,kBAAkB,KAAK,KAAK;AAAA,IACnC,OAAO,kBAAkB,KAAK,OAAO;AAAA,IACrC,YAAa,KAAK,UAAU;AAAA,EAC9B;AACF;AAEA,SAAS,mBACP,QAC+B;AAC/B,MAAI,WAAW,QAAQ;AACrB,WAAO;AAAA,MACL,GAAG;AAAA,MACH,OAAO,kBAAkB,OAAO,KAAK;AAAA,MACrC,OAAO,kBAAkB,OAAO,KAAK;AAAA,MACrC,QAAQ,kBAAkB,OAAO,MAAM;AAAA,MACvC,YAAY,OAAO;AAAA,IACrB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,IAAI,OAAO;AAAA,IACX,OAAO,OAAO;AAAA,IACd,QAAQ,kBAAkB,OAAO,MAAM;AAAA,IACvC,OAAO,kBAAkB,OAAO,KAAK;AAAA,IACrC,OAAO,kBAAkB,OAAO,OAAO;AAAA,IACvC,YAAa,OAAO,UAAU;AAAA,EAChC;AACF;AAEA,SAAS,oBACP,MACgC;AAChC,SAAO;AAAA,IACL,IAAI,KAAK;AAAA,IACT,KAAK,KAAK;AAAA,IACV,KAAK,KAAK;AAAA,IACV,QAAQ,kBAAkB,KAAK,MAAwC;AAAA,IACvE,OAAO,kBAAkB,KAAK,KAAkC;AAAA,IAChE,OAAO,kBAAkB,KAAK,OAAsC;AAAA,IACpE,YAAa,KAAK,UAAU;AAAA,EAC9B;AACF;AAEA,SAAS,oBACP,MACgC;AAChC,MAAI,aAAa,QAAQ,YAAY,MAAM;AACzC,WAAO;AAAA,MACL,IAAI,KAAK;AAAA,MACT,UAAU,KAAK;AAAA,MACf,QAAQ,kBAAkB,KAAK,MAAM;AAAA,MACrC,OAAO,kBAAkB,KAAK,KAAK;AAAA,MACnC,OAAO,kBAAkB,KAAK,OAAO;AAAA,MACrC,YAAa,KAAK,UAAU;AAAA,IAC9B;AAAA,EACF;AAEA,SAAO;AAAA,IACL,IAAI,KAAK;AAAA,IACT,UAAU,KAAK;AAAA,IACf,QAAQ,kBAAkB,KAAK,MAAM;AAAA,IACrC,OAAO,kBAAkB,KAAK,KAAK;AAAA,IACnC,OAAO;AAAA,MACJ,KAAwD;AAAA,IAC3D;AAAA,IACA,YAAa,KACV;AAAA,EACL;AACF;AAEA,SAAS,sBACP,QACkC;AAClC,MAAI,aAAa,UAAU,YAAY,QAAQ;AAC7C,WAAO;AAAA,MACL,IAAI,OAAO;AAAA,MACX,UAAU,OAAO;AAAA,MACjB,QAAQ,kBAAkB,OAAO,MAAM;AAAA,MACvC,OAAO,kBAAkB,OAAO,KAAK;AAAA,MACrC,OAAO,kBAAkB,OAAO,OAAO;AAAA,MACvC,YAAa,OAAO,UAClB;AAAA,IACJ;AAAA,EACF;AAEA,SAAO;AAAA,IACL,IAAI,OAAO;AAAA,IACX,UAAU,OAAO;AAAA,IACjB,QAAQ,kBAAkB,OAAO,MAAM;AAAA,IACvC,OAAO,kBAAkB,OAAO,KAAK;AAAA,IACrC,OAAO;AAAA,MACJ,OAA4D;AAAA,IAC/D;AAAA,IACA,YAAa,OACV;AAAA,EACL;AACF;AAEA,SAAS,wBACP,OACmE;AACnE,SAAO,WAAW;AACpB;AAEA,SAAS,2BACP,OACsE;AACtE,SAAO,WAAW;AACpB;AAEO,SAAS,uBACd,OAC4B;AAC5B,MAAI,yBAAyB,KAAK,GAAG;AACnC,WAAO;AAAA,MACL,IAAI,MAAM;AAAA,MACV,aAAa,MAAM;AAAA,MACnB,OAAO,OAAO,OAAO,MAAM,MAAM,EAAE;AAAA,QAAI,CAAC,SACtC,iBAAyB,IAAkC;AAAA,MAC7D;AAAA,MACA,OAAO,MAAM,MAAM;AAAA,QAAI,CAAC,SACtB,iBAAyB,IAA2B;AAAA,MACtD;AAAA,MACA,UAAU,MAAM,SAAS;AAAA,QAAI,CAAC,WAC5B,mBAA2B,MAA+B;AAAA,MAC5D;AAAA,IACF;AAAA,EACF;AAEA,MAAI,CAAC,wBAAwB,KAAK,GAAG;AACnC,UAAM,IAAI,MAAM,oCAAoC;AAAA,EACtD;AACA,QAAM,gBAAgB;AACtB,SAAO;AAAA,IACL,IAAI,cAAc;AAAA,IAClB,aAAa,cAAc;AAAA,IAC3B,OAAO,cAAc,MAAM,IAAI,CAAC,UAAU;AAAA,MACxC,GAAG;AAAA,MACH,OAAO,kBAAkB,KAAK,KAAK;AAAA,MACnC,OAAO,kBAAkB,KAAK,KAAK;AAAA,MACnC,QAAQ,kBAAkB,KAAK,MAAM;AAAA,MACrC,YAAY,KAAK;AAAA,MACjB,MAAM,KAAK;AAAA,IACb,EAAE;AAAA,IACF,OAAO,cAAc,MAAM;AAAA,MAAI,CAAC,SAC9B,iBAAyB,IAA2B;AAAA,IACtD;AAAA,IACA,UAAU,cAAc,SAAS;AAAA,MAAI,CAAC,WACpC,mBAA2B,MAA+B;AAAA,IAC5D;AAAA,EACF;AACF;AAEO,SAAS,0BACd,OAC+B;AAC/B,MAAI,4BAA4B,KAAK,GAAG;AACtC,UAAM,QAAQ,OAAO,OAAO,MAAM,MAAM,EAAE;AAAA,MAAI,CAAC,SAC7C,oBAA4B,IAAkC;AAAA,IAChE;AACA,UAAM,OACJ,MAAM,WAAW,IAAI,IAAI,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,KAAK,GAAG,CAAC,IAAI;AACxE,UAAM,OACJ,MAAM,WAAW,IAAI,IAAI,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,KAAK,GAAG,CAAC,IAAI;AAExE,WAAO;AAAA,MACL,IAAI,MAAM;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO,MAAM,MAAM;AAAA,QAAI,CAAC,SACtB,oBAA4B,IAA2B;AAAA,MACzD;AAAA,MACA,UAAU,MAAM,SAAS;AAAA,QAAI,CAAC,WAC5B,sBAA8B,MAA+B;AAAA,MAC/D;AAAA,MACA,SACG,MAAM,UAAU,CAAC,GAClB,IAAI,CAAC,WAAW;AAAA,QAChB,GAAG;AAAA,QACH,OAAO,kBAAkB,MAAM,KAAK;AAAA,QACpC,QAAQ,MAAM;AAAA,QACd,YAAY,MAAM;AAAA,MACpB,EAAE;AAAA,IACJ;AAAA,EACF;AAEA,MAAI,CAAC,2BAA2B,KAAK,GAAG;AACtC,UAAM,IAAI,MAAM,uCAAuC;AAAA,EACzD;AACA,QAAM,gBAAgB;AACtB,SAAO;AAAA,IACL,IAAI,cAAc;AAAA,IAClB,MAAM,cAAc;AAAA,IACpB,MAAM,cAAc;AAAA,IACpB,OAAO,cAAc,MAAM,IAAI,CAAC,UAAU;AAAA,MACxC,GAAG;AAAA,MACH,OAAO,kBAAkB,KAAK,KAAK;AAAA,MACnC,OAAO,kBAAkB,KAAK,KAAK;AAAA,MACnC,QAAQ,kBAAkB,KAAK,MAAM;AAAA,MACrC,YAAY,KAAK;AAAA,IACnB,EAAE;AAAA,IACF,OAAO,cAAc,MAAM;AAAA,MAAI,CAAC,SAC9B,oBAA4B,IAA2B;AAAA,IACzD;AAAA,IACA,UAAU,cAAc,SAAS;AAAA,MAAI,CAAC,WACpC,sBAA8B,MAA+B;AAAA,IAC/D;AAAA,IACA,SAAS,cAAc,UAAU,CAAC,GAAG,IAAI,CAAC,WAAW;AAAA,MACnD,GAAG;AAAA,MACH,OAAO,kBAAkB,MAAM,KAAK;AAAA,MACpC,QAAQ,MAAM;AAAA,MACd,YAAY,MAAM;AAAA,IACpB,EAAE;AAAA,EACJ;AACF;;;ACxqBO,SAAS,0BACd,OAC8C;AAC9C,MAAI,CAAC,MAAO,QAAO,CAAC;AACpB,SAAO;AAAA,IACL,iBAAiB,MAAM,WAAW,SAAS;AAAA,IAC3C,4BAA4B,MAAM,qBAAqB,SAAS;AAAA,IAChE,iBAAiB,MAAM,WAAW,SAAS;AAAA,IAC3C,iBAAiB,MAAM,WAAW,SAAS;AAAA,IAC3C,gBAAgB,MAAM,UAAU,SAAS;AAAA,IACzC,kBAAkB,MAAM,YAAY,SAAS;AAAA,IAC7C,mBAAmB,MAAM,aAAa,SAAS;AAAA,IAC/C,wBACE,OAAO,MAAM,mBAAmB,WAC5B,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,MAAM,cAAc,CAAC,CAAC,IACrD;AAAA,EACR;AACF;AAKO,SAAS,oCACd,OAC8C;AAC9C,QAAM,OAAO,0BAA0B,KAAK;AAC5C,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO;AAAA,IACL,GAAG;AAAA,IACH,oBAAoB,MAAM,SAAS,SAAS;AAAA,IAC5C,kBAAkB,MAAM,OAAO,SAAS;AAAA,EAC1C;AACF;;;AC7HA,SAAS,YAAY;AAqGb,gBAAAC,MAmGM,YAnGN;AA5DR,IAAM,wBAAwB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIA,IAAM,mBAAwC,IAAI,IAAI,qBAAqB;AAE3E,SAAS,aACP,OACA,KACoB;AACpB,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,MAAM,MAAM,GAAG;AACrB,MAAI,QAAQ,UAAa,QAAQ,KAAM,QAAO;AAC9C,SAAO,OAAO,GAAG;AACnB;AAGA,SAAS,mBAAmB;AAAA,EAC1B;AAAA,EACA;AACF,GAGG;AACD,QAAM,QAAQ,SAAS;AACvB,QAAM,QAAQ,KAAK;AACnB,QAAM,OAAO,aAAa,OAAO,MAAM;AACvC,QAAM,QAAQ,aAAa,OAAO,OAAO,KAAK,KAAK;AACnD,QAAM,WAAW,aAAa,OAAO,UAAU;AAC/C,QAAM,SAAS,aAAa,OAAO,QAAQ;AAC3C,QAAM,OAAO,aAAa,OAAO,MAAM;AACvC,QAAM,QAAQ,QACV,OAAO,QAAQ,KAAK,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,iBAAiB,IAAI,GAAG,CAAC,IAClE,CAAC;AAEL,QAAM,iBAAiB,QAAQ,SAAS,YAAY,UAAU;AAC9D,QAAM,UAAU,SAAS;AAEzB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,WAAW;AAAA,QACX,WAAW;AAAA,QACX,UAAU;AAAA,QACV,WAAW;AAAA,QACX,SAAS,UAAU,MAAM,MAAM,CAAC,IAAI,MAAM,MAAM,CAAC;AAAA,QACjD,KAAK,UAAU,MAAM,MAAM,GAAG,IAAI,MAAM,MAAM,CAAC;AAAA,MACjD;AAAA,MAEC;AAAA,eACC,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,eAAW;AAAA,YACX,OAAO;AAAA,cACL,YAAY;AAAA,cACZ,UAAU,UACN,MAAM,WAAW,SAAS,KAC1B,MAAM,WAAW,SAAS,KAAK;AAAA,cACnC,YAAY;AAAA,YACd;AAAA,YAEC;AAAA;AAAA,QACH,IACE;AAAA,QACH,QACC,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,YAAY;AAAA,cACZ,YAAY,MAAM,WAAW,WAAW;AAAA,cACxC,UAAU,MAAM,WAAW,SAAS;AAAA,cACpC,YAAY,MAAM,WAAW,WAAW;AAAA,cACxC,OAAO,MAAM,SAAS,KAAK;AAAA,cAC3B,YAAY,MAAM,WAAW,WAAW;AAAA,cACxC,UAAU;AAAA,cACV,cAAc;AAAA,cACd,SAAS;AAAA,cACT,iBAAiB;AAAA,cACjB,iBAAiB;AAAA,cACjB,WAAW;AAAA,YACb;AAAA,YAEC;AAAA;AAAA,QACH,IACE;AAAA,QACH,WACC,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,YAAY;AAAA,cACZ,YAAY,MAAM,WAAW,WAAW;AAAA,cACxC,UAAU,MAAM,WAAW,SAAS;AAAA,cACpC,YAAY,MAAM,WAAW,WAAW;AAAA,cACxC,OAAO,MAAM,SAAS,KAAK;AAAA,cAC3B,eAAe,MAAM,WAAW,cAAc;AAAA,cAC9C,eAAe;AAAA,YACjB;AAAA,YAEC;AAAA;AAAA,QACH,IACE;AAAA,QACH,SACC,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,MAAM;AAAA,cACN,WAAW;AAAA,cACX,YAAY,MAAM,WAAW,WAAW;AAAA,cACxC,UAAU,MAAM,WAAW,SAAS;AAAA,cACpC,OAAO,MAAM,SAAS,KAAK;AAAA,cAC3B,YAAY,MAAM,WAAW,WAAW;AAAA,cACxC,SAAS;AAAA,cACT,iBAAiB,UAAU,IAAI,SAAS,OAAO,IAAI;AAAA,cACnD,iBAAiB;AAAA,cACjB,UAAU;AAAA,YACZ;AAAA,YAEC;AAAA;AAAA,QACH,IACE;AAAA,QACH,OACC,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,YAAY;AAAA,cACZ,KAAK,MAAM,MAAM,CAAC;AAAA,cAClB,cAAc,MAAM,MAAM,GAAG;AAAA,cAC7B,eAAe,MAAM,MAAM,CAAC;AAAA,cAC5B,cAAc,MAAM,OAAO;AAAA,cAC3B,YAAY,MAAM,SAAS,QAAQ;AAAA,cACnC,QAAQ,aAAa,MAAM,SAAS,OAAO,MAAM;AAAA,cACjD,YAAY,MAAM,WAAW,WAAW;AAAA,cACxC,UAAU,MAAM,WAAW,SAAS;AAAA,cACpC,YAAY,MAAM,WAAW,WAAW;AAAA,cACxC,OAAO,MAAM,SAAS,KAAK;AAAA,cAC3B,WAAW;AAAA,YACb;AAAA,YAEC;AAAA;AAAA,QACH,IACE;AAAA,QACH,CAAC,kBAAkB,MAAM,SAAS,IAC/B,MAAM,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAChC;AAAA,UAAC;AAAA;AAAA,YAEC,OAAO;AAAA,cACL,YAAY;AAAA,cACZ,YAAY,MAAM,WAAW,WAAW;AAAA,cACxC,UAAU,MAAM,WAAW,SAAS;AAAA,cACpC,OAAO,MAAM,SAAS,KAAK;AAAA,YAC7B;AAAA,YAEA;AAAA,mCAAC,UAAK,OAAO,EAAE,OAAO,MAAM,SAAS,KAAK,MAAM,GAAI;AAAA;AAAA,gBAAI;AAAA,iBAAC;AAAA,cAAQ;AAAA,cACjE,gBAAAA,KAAC,UAAK,OAAO,EAAE,YAAY,MAAM,WAAW,WAAW,KAAK,GACzD,iBAAO,KAAK,GACf;AAAA;AAAA;AAAA,UAXK;AAAA,QAYP,CACD,IACD;AAAA,QACH,CAAC,kBAAkB,MAAM,WAAW,IACnC,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,YAAY;AAAA,cACZ,YAAY,MAAM,WAAW,WAAW;AAAA,cACxC,UAAU,MAAM,WAAW,SAAS;AAAA,cACpC,OAAO,MAAM,SAAS,KAAK;AAAA,YAC7B;AAAA,YAEC,eAAK,GAAG,MAAM,GAAG,CAAC;AAAA;AAAA,QACrB,IACE;AAAA;AAAA;AAAA,EACN;AAEJ;AAEA,IAAM,oBAAoB;AAAA,EACxB,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAEO,SAAS,SAA+C;AAAA,EAC7D;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAA4B;AAC1B,QAAM,QAAQ,SAAS;AACvB,QAAM,mBAAmB,MAAM,OAAO;AACtC,QAAM,qBAAqB,GAAG,MAAM,OAAO,EAAE,IAAI,MAAM,OAAO,EAAE,IAAI,MAAM,OAAO,EAAE,IAAI,MAAM,OAAO,EAAE,MAAM,MAAM,OAAO,EAAE,IAAI,MAAM,OAAO,EAAE,IAAI,MAAM,OAAO,EAAE,IAAI,MAAM,OAAO,EAAE;AACpL,QAAM,qBAAqB,MAAM,UAAU,KAAK;AAChD,QAAM,oBAAoB,MAAM,SAAS,OAAO,QAAQ;AACxD,QAAM,mBAAmB,MAAM,SAAS,OAAO,OAAO;AACtD,QAAM,qBAAqB,MAAM,SAAS,OAAO,QAAQ;AACzD,QAAM,kBAAkB,MAAM,UAAU,KAAK;AAC7C,QAAM,iBAAiB,0BAA0B;AAAA,IAC/C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAID,QAAM,cAAc,UAChB,mBACA,YACE,qBACA,WACE,qBACA,aACE,qBACA,WACE,oBACA;AACZ,QAAM,aAAa,QAAQ,WAAW;AACtC,QAAM,eAAe,WACjB,mBAAmB,kBAAkB,KACrC,aACE,mBAAmB,kBAAkB,KACrC,UACE,mBAAmB,gBAAgB,KACnC,YACE,mBAAmB,kBAAkB,KACrC,WACE,mBAAmB,iBAAiB,KACpC;AACZ,QAAM,aAAa,MAAM,UAAU;AAEnC,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACH,GAAG;AAAA,MACJ,6BAA0B;AAAA,MAC1B,iBAAe,aAAa,SAAS;AAAA,MACrC,kBAAgB,WAAW,SAAS;AAAA,MACpC,WAAW,KAAK,YAAY,kBAAkB,IAAI,GAAG,SAAS;AAAA,MAC9D,OAAO;AAAA,QACL,SAAS,WAAW,MAAM,YAAY,OAAO;AAAA,QAC7C,oBAAoB;AAAA,QACpB,oBAAoB,eAAe,OAAO,QAAQ;AAAA,QAClD,0BAA0B,MAAM,OAAO,OAAO;AAAA,QAC9C,WAAW,aAAa,iCAAiC;AAAA,QACzD,GAAG;AAAA,MACL;AAAA,MAEC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAOC,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO;AAAA,cACL,YAAY,MAAM,UAAU,KAAK;AAAA,cACjC,aAAa;AAAA,cACb,aAAa,aAAa,IAAI;AAAA,cAC9B,aAAa,eAAe;AAAA,cAC5B,cAAc,aAAa,qBAAqB;AAAA,cAChD,WAAW,gBAAgB;AAAA,YAC7B;AAAA,YAEA,0BAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,OAAO;AAAA,kBACL,cAAc;AAAA,kBACd,YACE;AAAA,gBACJ;AAAA;AAAA,YACF;AAAA;AAAA,QACF;AAAA,UAEA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO;AAAA,YACL,YAAY,YACR,MAAM,SAAS,OAAO,QAAQ,OAC9B,MAAM,SAAS,QAAQ;AAAA,YAC3B,aAAa;AAAA,YACb,aAAa,aAAa,IAAI;AAAA,YAC9B,aAAa,eAAe;AAAA,YAC5B,cAAc,aAAa,qBAAqB;AAAA,YAChD,WAAW,gBAAgB;AAAA,YAC3B,SACE,YAAY,UACR,aAAa,eAAe,kBAAkB,KAC9C;AAAA,YACN,eAAe,YAAY,UAAU,QAAQ;AAAA,UAC/C;AAAA,UAEC,uBACE,gBACC,cAAc,IAAI,IAElB,gBAAAA,KAAC,sBAAmB,MAAY,MAAY;AAAA;AAAA,MAElD;AAAA;AAAA,EAEJ;AAEJ;;;ACpXA,SAAS,UAAU,uBAAuB;AAC1C,SAAS,QAAAC,aAAY;AAKZ,gBAAAC,MA+DH,QAAAC,aA/DG;AAHT,SAAS,OAAO;AAAA,EACd,GAAG;AACL,GAAsD;AACpD,SAAO,gBAAAD,KAAC,gBAAgB,MAAhB,EAAqB,aAAU,UAAU,GAAG,OAAO;AAC7D;AAEA,SAAS,cAAc;AAAA,EACrB,GAAG;AACL,GAAyD;AACvD,SAAO,gBAAAA,KAAC,gBAAgB,SAAhB,EAAwB,aAAU,kBAAkB,GAAG,OAAO;AACxE;AAEA,SAAS,aAAa;AAAA,EACpB,GAAG;AACL,GAAwD;AACtD,SAAO,gBAAAA,KAAC,gBAAgB,QAAhB,EAAuB,aAAU,iBAAiB,GAAG,OAAO;AACtE;AAEA,SAAS,YAAY;AAAA,EACnB,GAAG;AACL,GAAuD;AACrD,SAAO,gBAAAA,KAAC,gBAAgB,OAAhB,EAAsB,aAAU,gBAAgB,GAAG,OAAO;AACpE;AAEA,SAAS,cAAc;AAAA,EACrB;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAyD;AACvD,SACE,gBAAAA;AAAA,IAAC,gBAAgB;AAAA,IAAhB;AAAA,MACC,aAAU;AAAA,MACV,WAAWD;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,OAAO;AAAA,QACL,UAAU;AAAA,QACV,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,GAAG;AAAA,MACL;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AASA,SAAS,cAAc;AAAA,EACrB;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb,GAAG;AACL,GAAuB;AACrB,SACE,gBAAAE,MAAC,gBAAa,aAAU,iBACtB;AAAA,oBAAAD,KAAC,iBAAc;AAAA,IACf,gBAAAC;AAAA,MAAC,gBAAgB;AAAA,MAAhB;AAAA,QACC,aAAU;AAAA,QACV,WAAWF;AAAA,UACT;AAAA;AAAA,UAEA;AAAA,UACA;AAAA,UACA;AAAA;AAAA,UAEA;AAAA,UACA;AAAA,UACA;AAAA;AAAA,UAEA;AAAA,UACA;AAAA,UACA;AAAA;AAAA,UAEA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAGH;AAAA,wBACC,gBAAAC;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO;AAAA,gBACL,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACR,QAAQ;AAAA,gBACR,YAAY;AAAA,gBACZ,cAAc;AAAA,gBACd,YAAY;AAAA,cACd;AAAA;AAAA,UACF;AAAA,UAED;AAAA;AAAA;AAAA,IACH;AAAA,KACF;AAEJ;AAEA,SAAS,aAAa;AAAA,EACpB;AAAA,EACA,GAAG;AACL,GAA0C;AACxC,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAWD,MAAK,6BAA6B,SAAS;AAAA,MACrD,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,aAAa;AAAA,EACpB;AAAA,EACA,GAAG;AACL,GAA0C;AACxC,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAWD,MAAK,mCAAmC,SAAS;AAAA,MAC3D,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,YAAY;AAAA,EACnB;AAAA,EACA,GAAG;AACL,GAAuD;AACrD,SACE,gBAAAC;AAAA,IAAC,gBAAgB;AAAA,IAAhB;AAAA,MACC,aAAU;AAAA,MACV,WAAWD,MAAK,wCAAwC,SAAS;AAAA,MAChE,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,kBAAkB;AAAA,EACzB;AAAA,EACA,GAAG;AACL,GAA6D;AAC3D,SACE,gBAAAC;AAAA,IAAC,gBAAgB;AAAA,IAAhB;AAAA,MACC,aAAU;AAAA,MACV,WAAWD,MAAK,0BAA0B,SAAS;AAAA,MAClD,GAAG;AAAA;AAAA,EACN;AAEJ;;;ACtKA;AAAA,EACE,iBAAAG;AAAA,EACA,eAAAC;AAAA,EACA,cAAAC;AAAA,EACA,aAAAC;AAAA,EACA,WAAAC;AAAA,EACA,YAAAC;AAAA,OAEK;AAmCH,gBAAAC,YAAA;AA/BJ,IAAM,2BACJN,eAAoD,IAAI;AAEnD,SAAS,0BAA0B;AAAA,EACxC;AAAA,EACA;AACF,GAGG;AACD,QAAM,CAAC,mBAAmB,oBAAoB,IAAIK,UAEhD,MAAM,oBAAI,IAAI,CAAC;AAEjB,QAAM,WAAWJ;AAAA,IACf,CAAC,IAAIM,gBAAe;AAClB;AAAA,QAAqB,CAAC,YACpB,wBAAwB,SAAS,IAAIA,WAAU;AAAA,MACjD;AAAA,IACF;AAAA,IACA,CAAC;AAAA,EACH;AACA,QAAM,aAAa,kBAAkB,OAAO;AAE5C,EAAAJ,WAAU,MAAM;AACd,uBAAmB,UAAU;AAAA,EAC/B,GAAG,CAAC,oBAAoB,UAAU,CAAC;AAEnC,QAAM,QAAQC,SAAQ,MAAM,UAAU,CAAC,QAAQ,CAAC;AAEhD,SACE,gBAAAE,KAAC,yBAAyB,UAAzB,EAAkC,OAChC,UACH;AAEJ;AAEO,SAAS,qBAAqB,IAAY,YAAqB;AACpE,QAAM,WAAWJ,YAAW,wBAAwB;AAEpD,EAAAC,WAAU,MAAM;AACd,QAAI,CAAC,SAAU;AACf,aAAS,IAAI,UAAU;AACvB,WAAO,MAAM,SAAS,IAAI,KAAK;AAAA,EACjC,GAAG,CAAC,IAAI,UAAU,UAAU,CAAC;AAC/B;AAEA,SAAS,wBACP,SACA,IACA,YACA;AACA,MAAI,QAAQ,IAAI,EAAE,MAAM,WAAY,QAAO;AAC3C,QAAM,OAAO,IAAI,IAAI,OAAO;AAC5B,MAAI,WAAY,MAAK,IAAI,EAAE;AAAA,MACtB,MAAK,OAAO,EAAE;AACnB,SAAO;AACT;;;ACpEA,SAAS,QAAAK,aAAY;;;ACArB,SAAS,YAAY;;;ACDrB,SAAS,QAAAC,aAA6B;AAE/B,SAAS,MAAM,QAAsB;AAC1C,SAAOA,MAAK,MAAM;AACpB;;;ADyCI,gBAAAC,YAAA;AAzBJ,IAAM,eAA8C;AAAA,EAClD,SAAS;AAAA,EACT,aAAa;AAAA,EACb,SAAS;AAAA,EACT,WAAW;AAAA,EACX,OAAO;AAAA,EACP,MAAM;AACR;AAEA,IAAM,YAAwC;AAAA,EAC5C,SAAS;AAAA,EACT,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,MAAM;AACR;AAEO,SAAS,OAAO;AAAA,EACrB;AAAA,EACA,UAAU;AAAA,EACV,OAAO;AAAA,EACP,UAAU;AAAA,EACV,GAAG;AACL,GAAgB;AACd,QAAM,OAAO,UAAU,OAAO;AAC9B,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA,aAAa,OAAO;AAAA,QACpB,UAAU,IAAI;AAAA,QACd;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;;;ADHI,gBAAAC,YAAA;AA5BG,SAAS,aAAa;AAAA,EAC3B,UAAU;AAAA,EACV,OAAO;AAAA,EACP,UAAU;AAAA,EACV,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAsB;AACpB,QAAM,QAAQ,SAAS;AACvB,QAAM,aAAa,YAAY,WAAW;AAC1C,QAAM,iBAAiB,0BAA0B;AAAA,IAC/C;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,SAAS,gBAAgB,YAAY,cAAc,OAAO;AAAA,MAC1D,MAAM,aAAa,IAAI;AAAA,MACvB,UAAU;AAAA,MACV,0BAAsB;AAAA,MACtB,kCAAgC,YAAY,cAAc;AAAA,MAC1D,+BAA6B;AAAA,MAC7B,gBAAc,UAAU,SAAS;AAAA,MACjC,gBAAc,UAAU,SAAS;AAAA,MACjC,aAAW,WAAW;AAAA,MACtB,gBAAc,WAAW,OAAO,UAAU,OAAO;AAAA,MACjD,gBAAc,WAAW;AAAA,MACxB,GAAG;AAAA,MACJ,WAAWC,MAAK,aAAa,SAAS;AAAA,MACtC,OAAO;AAAA,QACL,GAAG,YAAY,OAAO;AAAA,UACpB,SAAS,YAAY,cAAc;AAAA,UACnC;AAAA,UACA,UAAU;AAAA,UACV;AAAA,QACF,CAAC;AAAA,QACD,GAAG;AAAA,MACL;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,gBACP,SAC2C;AAC3C,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,EACX;AACF;AAEA,SAAS,aACP,MACwC;AACxC,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,EACX;AACF;;;AGhHA,SAAS,OAAO,YAAAC,iBAAoD;AACpE,SAAS,eAAe;AAqIQ,0BAAAC,MAqC1B,QAAAC,aArC0B;AAjFhC,IAAM,oBAAoB;AAC1B,IAAM,qBAAqB;AAE3B,SAAS,eAAe,WAA6C;AACnE,QAAM,OAAsB;AAAA,IAC1B,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AACA,UAAQ,WAAW;AAAA,IACjB,KAAK;AACH,aAAO;AAAA,QACL,GAAG;AAAA,QACH,MAAM;AAAA,QACN,WAAW;AAAA,MACb;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,GAAG;AAAA,QACH,OAAO;AAAA,MACT;AAAA,IACF,KAAK;AAAA,IACL;AACE,aAAO;AAAA,QACL,GAAG;AAAA,QACH,MAAM;AAAA,MACR;AAAA,EACJ;AACF;AAEA,SAAS,iBACP,WAC4B;AAC5B,UAAQ,WAAW;AAAA,IACjB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL;AACE,aAAO;AAAA,EACX;AACF;AAEA,SAAS,kBACP,OACA,OACA,MACA,UACA;AACA,MAAI,OAAO,aAAa,WAAY,QAAO,SAAS,EAAE,OAAO,OAAO,KAAK,CAAC;AAC1E,MAAI,aAAa,OAAW,QAAO;AACnC,SAAO,GAAG,KAAK,KAAK,KAAK;AAC3B;AAEO,SAAS,SAAS;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAkB;AAChB,QAAM,OAAO,cAAc,QAAQ;AACnC,QAAM,CAAC,MAAM,OAAO,IAAIC,UAAS,cAAc,eAAe,KAAK;AACnE,QAAM,YAAY,MAAM;AACxB,QAAM,eAAe,gBAAgB;AACrC,uBAAqB,WAAW,SAAS,YAAY,IAAI;AAKzD,QAAM,WAAW;AAAA,IACf,CAAC,EAAE,UAAU,CAAC,EAAE,EAAE,GAAG,UAAU,CAAC,EAAE,EAAE,GAAG,KAAK,MAAM;AAEhD,UAAI,QAAQ,KAAK,OAAO,KAAK,KAAK;AAChC,gBAAQ,IAAI;AAAA,MACd;AAAA,IACF;AAAA,IACA,EAAE,MAAM,KAAK,YAAY,KAAK;AAAA,EAChC;AAEA,MAAI,SAAS,SAAU,QAAO;AAC9B,MAAI,SAAS,SAAU,QAAO,gBAAAF,KAAA,YAAG,UAAS;AAE1C,QAAM,YAAY,cAAc,aAAa;AAC7C,QAAM,cAAc;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,EAChB;AAEA,QAAM,uBAAsC;AAAA,IAC1C,WAAW,cAAc,aAAa;AAAA,IACtC,UAAU;AAAA,IACV,SAAS;AAAA,IACT,eAAe;AAAA,EACjB;AACA,QAAM,eAA8B;AAAA,IAClC,WAAW,iBAAiB,SAAS;AAAA,IACrC,WAAW;AAAA,IACX,eAAe;AAAA,IACf,YAAY,OAAO,WAAW;AAAA,EAChC;AACA,QAAM,eAAe,OAAO,aAAa;AACzC,QAAM,oBACJ,CAAC,gBAAgB,OACf,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,IAAI;AAAA,MACJ,MAAK;AAAA,MACL,cAAY;AAAA,MACZ,OAAO;AAAA,MAEN;AAAA;AAAA,EACH,IACE;AAEN,SACE,gBAAAC,MAAC,UAAO,MAAY,cAAc,SAAS,WAAU,UACnD;AAAA,oBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,kBAAgB;AAAA,QAChB,cAAY,OAAO,SAAS;AAAA,QAC5B,OAAO;AAAA,UACL,GAAG,eAAe,SAAS;AAAA,UAC3B,SAAS;AAAA,UACT,UAAU,cAAc,YAAY;AAAA,UACpC,OAAO,cAAc,YAAY;AAAA,UACjC,eAAe;AAAA,UACf,YAAY;AAAA,UACZ,KAAK;AAAA,UACL,eAAe;AAAA,UACf,GAAG,cAAc;AAAA,QACnB;AAAA,QAEC;AAAA;AAAA,UAIA,CAAC,QACA,gBAAAD;AAAA,YAAC;AAAA;AAAA,cACE,GAAG,SAAS;AAAA,cACb,eAAW;AAAA,cACX,MAAK;AAAA,cACL,OAAO;AAAA,gBACL,WAAW,iBAAiB,SAAS;AAAA,gBACrC,SAAS;AAAA,gBACT,QAAQ;AAAA,gBACR,aAAa;AAAA,gBACb,eAAe;AAAA,gBACf,SAAS;AAAA,gBACT,gBAAgB;AAAA,cAClB;AAAA,cAEA,0BAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,OAAO;AAAA,oBACP,QAAQ;AAAA,oBACR,cAAc;AAAA,oBACd,YAAY;AAAA,kBACd;AAAA;AAAA,cACF;AAAA;AAAA,UACF;AAAA,UAEF,gBAAAA,KAAC,iBAAc,SAAO,MACpB,0BAAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,cAAY,OAAO,SAAS;AAAA,cAC5B,iBAAe;AAAA,cACf,iBAAe,OAAO,YAAY;AAAA,cAClC,WAAU;AAAA,cACV,OAAO;AAAA,cAEN;AAAA;AAAA,UACH,GACF;AAAA;AAAA;AAAA,IACF;AAAA,IACC,eACC,gBAAAC;AAAA,MAAC;AAAA;AAAA,QACC,IAAI;AAAA,QACJ,oBAAkB;AAAA,QAClB,WAAU;AAAA,QACV,OAAO;AAAA,UACL,GAAG;AAAA,UACH,UAAU;AAAA,UACV,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,WAAW;AAAA,UACX,eAAe;AAAA,UACf,UAAU;AAAA,UACV,WAAW;AAAA,UACX,qBAAqB;AAAA,UACrB,sBAAsB;AAAA,UACtB,YAAY;AAAA,UACZ,OAAO;AAAA,UACP,YAAY;AAAA,UACZ,WAAW;AAAA,UACX,gBAAgB;AAAA,QAClB;AAAA,QAEA;AAAA,0BAAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO;AAAA,gBACL,SAAS;AAAA,gBACT,eAAe;AAAA,gBACf,KAAK;AAAA,gBACL,cAAc;AAAA,gBACd,SAAS;AAAA,gBACT,WAAW;AAAA,cACb;AAAA,cAEA;AAAA,gCAAAD;AAAA,kBAAC;AAAA;AAAA,oBACC,WAAU;AAAA,oBACV,OAAO,EAAE,UAAU,IAAI,YAAY,KAAK,YAAY,KAAK;AAAA,oBAExD;AAAA;AAAA,gBACH;AAAA,gBACA,gBAAAC,MAAC,qBACE;AAAA;AAAA,kBAAM;AAAA,kBAAM,UAAU,IAAI,KAAK;AAAA,kBAAI;AAAA,mBACtC;AAAA;AAAA;AAAA,UACF;AAAA,UACA,gBAAAD;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,cAAY;AAAA,cACZ,OAAO;AAAA,gBACL,WAAW,cAAc,aAAa;AAAA,gBACtC,UAAU,cAAc,YAAY;AAAA,gBACpC,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACR,UAAU;AAAA,gBACV,SACE;AAAA,gBACF,WAAW;AAAA,cACb;AAAA,cACA,WAAU;AAAA,cAET;AAAA;AAAA,UACH;AAAA;AAAA;AAAA,IACF,IACE;AAAA,KACN;AAEJ;;;ACrSA,SAAS,QAAAG,aAAY;AACrB,SAAS,eAAAC,cAAa,YAAAC,iBAAgB;;;ACNtC,SAAS,YAAAC,WAAU,QAAQ,aAAAC,YAAW,WAAAC,UAAS,eAAAC,oBAAmB;AAUlE,IAAM,kBAAkB;AAAA,EACtB,IAAI,EAAE,OAAO,IAAI,QAAQ,IAAI;AAAA,EAC7B,IAAI,EAAE,OAAO,IAAI,QAAQ,IAAI;AAAA,EAC7B,IAAI,EAAE,OAAO,KAAK,QAAQ,IAAI;AAChC;AAEA,IAAM,sBAAsB;AAC5B,IAAM,aAAa;AACnB,IAAM,gBAAgB;AACtB,IAAM,yBAAyB;AAgIxB,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA,WAAW;AAAA,EACX,SAAS;AAAA,EACT,mBAAmB;AACrB,GAA8C;AAC5C,QAAM,eAAe,OAAuB,IAAI;AAChD,QAAM,oBAAoB,OAAuB,IAAI;AACrD,QAAM,CAAC,gBAAgB,iBAAiB,IAAIH,UAAS,CAAC;AACtD,QAAM,CAAC,cAAc,eAAe,IAAIA,UAAwB,IAAI;AAEpE,QAAM,iBAAiB,gBAAgB,QAAQ;AAG/C,EAAAC,WAAU,MAAM;AACd,UAAM,cAAc,MAAM;AACxB,UAAI,aAAa,SAAS;AACxB,0BAAkB,aAAa,QAAQ,cAAc,gBAAgB;AAAA,MACvE;AAAA,IACF;AAEA,gBAAY;AACZ,UAAM,WAAW,IAAI,eAAe,WAAW;AAC/C,QAAI,aAAa,SAAS;AACxB,eAAS,QAAQ,aAAa,OAAO;AAAA,IACvC;AAEA,WAAO,MAAM,SAAS,WAAW;AAAA,EACnC,GAAG,CAAC,gBAAgB,CAAC;AAGrB,QAAM,EAAE,YAAY,YAAY,cAAc,IAAIC,SAAQ,MAAM;AAC9D,QAAI,WAAW,WAAW;AACxB,aAAO;AAAA,QACL,YAAY,eAAe;AAAA,QAC3B,YAAY;AAAA,QACZ,eAAe;AAAA,MACjB;AAAA,IACF;AAEA,QAAI,cAAc,GAAG;AACnB,aAAO,EAAE,YAAY,GAAG,YAAY,GAAG,eAAe,MAAM;AAAA,IAC9D;AACA,QAAI,cAAc,GAAG;AACnB,aAAO;AAAA,QACL,YAAY,eAAe;AAAA,QAC3B,YAAY,eAAe;AAAA,QAC3B,eAAe;AAAA,MACjB;AAAA,IACF;AAGA,UAAM,iBAAiB;AACvB,QAAI,kBAAkB,GAAG;AACvB,aAAO;AAAA,QACL,YAAY,eAAe;AAAA,QAC3B,YAAY,eAAe,QAAQ;AAAA,QACnC,eAAe;AAAA,MACjB;AAAA,IACF;AAKA,UAAM,eACH,iBAAiB,eAAe,UAAU,YAAY;AAGzD,UAAM,gBAAgB,KAAK;AAAA,MACzB;AAAA,MACA,KAAK,IAAI,eAAe,OAAO,WAAW;AAAA,IAC5C;AAGA,UAAM,QAAQ,eAAe,SAAS,YAAY,KAAK;AAIvD,UAAM,iBAAiB,gBAAgB,eAAe;AACtD,UAAM,kBACJ,iBAAiB,0BAA0B,YAAY;AAEzD,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,eAAe;AAAA,IACjB;AAAA,EACF,GAAG,CAAC,WAAW,gBAAgB,QAAQ,eAAe,KAAK,CAAC;AAI5D,QAAM,6BAA6BC;AAAA,IACjC,CAAC,YAAmC;AAClC,UAAI,CAAC,kBAAkB,QAAS,QAAO;AACvC,YAAM,OAAO,kBAAkB,QAAQ,sBAAsB;AAC7D,YAAM,SAAS,UAAU,KAAK;AAE9B,UAAI,kBAAiC;AAIrC,eAAS,IAAI,YAAY,GAAG,KAAK,GAAG,KAAK;AACvC,cAAM,WAAW,IAAI;AACrB,cAAM,YACJ,MAAM,YAAY,IACd,WAAW,eAAe,SACzB,IAAI,KAAK;AAEhB,YAAI,UAAU,YAAY,SAAS,WAAW;AAC5C,4BAAkB;AAClB;AAAA,QACF;AAAA,MACF;AAGA,UAAI,oBAAoB,QAAQ,UAAU,KAAK,SAAS,YAAY;AAClE,cAAM,gBAAgB,YAAY,KAAK;AACvC,YAAI,UAAU,cAAc;AAC1B,4BAAkB,YAAY;AAAA,QAChC;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAAA,IACA,CAAC,WAAW,YAAY,YAAY,eAAe,KAAK;AAAA,EAC1D;AAIA,QAAM,kBAAkBA;AAAA,IACtB,CAAC,MAAwC;AACvC,UAAI,cAAc,KAAK,WAAW,YAAY,WAAW,SAAS;AAChE;AAAA,MACF;AACA,sBAAgB,2BAA2B,EAAE,OAAO,CAAC;AAAA,IACvD;AAAA,IACA,CAAC,WAAW,QAAQ,0BAA0B;AAAA,EAChD;AAEA,QAAM,mBAAmBA,aAAY,MAAM;AACzC,oBAAgB,IAAI;AAAA,EACtB,GAAG,CAAC,CAAC;AAIL,QAAM,kBAAkBA;AAAA,IACtB,CAAC,MAAwC;AACvC,UAAI,cAAc,KAAK,WAAW,YAAY,WAAW,SAAS;AAChE;AAAA,MACF;AACA,YAAM,QAAQ,EAAE,QAAQ,CAAC;AACzB,UAAI,CAAC,MAAO;AACZ,sBAAgB,2BAA2B,MAAM,OAAO,CAAC;AAAA,IAC3D;AAAA,IACA,CAAC,WAAW,QAAQ,0BAA0B;AAAA,EAChD;AAEA,QAAM,iBAAiBA,aAAY,MAAM;AACvC,oBAAgB,IAAI;AAAA,EACtB,GAAG,CAAC,CAAC;AAGL,QAAM,YAAYA;AAAA,IAChB,CAAC,OAAe,WAAoB,eAAwB;AAC1D,UAAI,UAAW,QAAO;AACtB,UAAI,WAAY,QAAO,MAAM;AAC7B,aAAO;AAAA,IACT;AAAA,IACA,CAAC;AAAA,EACH;AAGA,QAAM,kBAAkBA;AAAA,IACtB,CACE,OACA,WACA,eACsB;AACtB,YAAM,SAAS,UAAU,OAAO,WAAW,UAAU;AAErD,UAAI,WAAW,SAAS;AACtB,eAAO;AAAA,UACL,GAAG,QAAQ;AAAA,UACX,GAAG;AAAA,UACH;AAAA,UACA,iBAAiB;AAAA,QACnB;AAAA,MACF;AAEA,UAAI,WAAW,UAAU;AACvB,eAAO;AAAA,UACL,GAAG;AAAA,UACH,GAAG;AAAA,UACH;AAAA,UACA,iBAAiB;AAAA,QACnB;AAAA,MACF;AAGA,YAAM,UAAU,YAAY,CAAC,aAAa,aAAa,CAAC,gBAAgB;AAExE,aAAO;AAAA,QACL,GAAG,QAAQ;AAAA,QACX,GAAG;AAAA,QACH;AAAA,QACA,iBAAiB;AAAA,MACnB;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,YAAY,SAAS;AAAA,EAChC;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,MACT,WAAW;AAAA,MACX,cAAc;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ADjSI,gBAAAC,YAAA;AAVJ,IAAM,qBAAwC,CAAC;AAO/C,SAAS,eAA0B;AACjC,QAAM,QAAQ,SAAS;AACvB,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,YAAY,MAAM,WAAW,WAAW;AAAA,QACxC,UAAU,MAAM,WAAW,SAAS;AAAA,QACpC,OAAO,MAAM,SAAS,KAAK;AAAA,MAC7B;AAAA,MACD;AAAA;AAAA,EAED;AAEJ;AAWA,SAAS,kBAAwD;AAAA,EAC/D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAqC;AACnC,QAAM,cAAc,CAAC,YAAY,QAAQ,WAAW;AACpD,QAAM,iBAAiB,MAAM;AAC3B,QAAI,CAAC,YAAa;AAClB,kBAAc,KAAK,EAAE;AAAA,EACvB;AAEA,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL;AAAA,MACA,gBAAc,WAAW,OAAO;AAAA,MAChC,iBAAe,YAAY;AAAA,MAC3B,UAAU,WAAW,KAAK;AAAA,MAC1B,SAAS;AAAA,MACT,WAAW,CAAC,UAAU;AACpB,YAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAK;AAC9C,gBAAM,eAAe;AACrB,yBAAe;AAAA,QACjB;AAAA,MACF;AAAA,MACA,WAAWC;AAAA,QACT;AAAA,QACA;AAAA,QACA,cAAc,mBAAmB;AAAA,MACnC;AAAA,MACA,OAAO,EAAE,KAAK,QAAQ;AAAA,MAEtB,0BAAAD;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;AA4BO,SAAS,KAA2C;AAAA,EACzD;AAAA,EACA,cAAc;AAAA,EACd,WAAW;AAAA,EACX,WAAW;AAAA,EACX,SAAS;AAAA,EACT,cAAc,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAwB;AACtB,QAAM,oBAAoBE;AAAA,IACxB,CAAC,UACC,gBAAAF;AAAA,MAAC;AAAA;AAAA,QAEC,WAAU;AAAA,QACV,OAAO;AAAA,UACL,MAAM,MAAM;AAAA,UACZ,QAAQ,MAAM;AAAA,UACd,WAAW,cAAc,MAAM,CAAC;AAAA,QAClC;AAAA,QAEA,0BAAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,MAAM;AAAA,YACZ,UAAU,MAAM;AAAA,YAChB;AAAA,YACA,MAAM;AAAA,YACN;AAAA,YACA,eAAe;AAAA;AAAA,QACjB;AAAA;AAAA,MAfK,MAAM,KAAK;AAAA,IAgBlB;AAAA,IAEF,CAAC,UAAU,UAAU,aAAa,iBAAiB;AAAA,EACrD;AACA,QAAM,sBAAsB,cAAc;AAC1C,QAAM,uBAAuB,eAAe;AAC5C,QAAM,YAAY,MAAM;AACxB,QAAM,CAAC,cAAc,eAAe,IAAIG,UAAS,EAAE;AAEnD,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,cAAc;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,gBAAgB,MAAM,OAAO,CAAC,MAAM,YAAY,SAAS,EAAE,EAAE,CAAC,EAAE;AAEtE,QAAM,gBAAgBD;AAAA,IACpB,CAAC,MAA2B;AAC1B,UAAI,cAAc,EAAG;AACrB,cAAQ,EAAE,KAAK;AAAA,QACb,KAAK;AACH,YAAE,eAAe;AACjB,0BAAgB,CAAC,SAAU,QAAQ,IAAI,YAAY,IAAI,OAAO,CAAE;AAChE;AAAA,QACF,KAAK;AACH,YAAE,eAAe;AACjB,0BAAgB,CAAC,SAAU,QAAQ,YAAY,IAAI,IAAI,OAAO,CAAE;AAChE;AAAA,QACF,KAAK;AACH,YAAE,eAAe;AACjB,0BAAgB,CAAC;AACjB;AAAA,QACF,KAAK;AACH,YAAE,eAAe;AACjB,0BAAgB,YAAY,CAAC;AAC7B;AAAA,MACJ;AAAA,IACF;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAMA,MAAI,iBAAiB,WAAW,aAAa,YAAY,GAAG;AAC1D,QAAI,cAAc;AAChB,aACE,gBAAAF;AAAA,QAAC;AAAA;AAAA,UACC,KAAK;AAAA,UACL,WAAWC;AAAA,YACT;AAAA,YACA;AAAA,UACF;AAAA,UACA,MAAK;AAAA,UACL,cAAY,GAAG,SAAS,MAAM,SAAS,QAAQ,cAAc,IAAI,MAAM,EAAE;AAAA,UAExE,uBAAa;AAAA,YACZ;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF,CAAC;AAAA;AAAA,MACH;AAAA,IAEJ;AAKA,WACE,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,WAAWC;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACA,MAAK;AAAA,QACL,cAAY,GAAG,SAAS,MAAM,SAAS,QAAQ,cAAc,IAAI,MAAM,EAAE;AAAA,QAEzE,0BAAAD;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,YACP,OAAO;AAAA,YACP,cAAc,EAAE,MAAM,UAAU,WAAW,gBAAgB;AAAA,YAE3D,0BAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,kBACL,SAAS;AAAA,kBACT,UAAU;AAAA,kBACV,KAAK;AAAA,kBACL,SAAS;AAAA,kBACT,gBAAgB;AAAA,gBAClB;AAAA,gBAEC,gBAAM,IAAI,CAAC,SACV,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBAEC;AAAA,oBACA,UAAU,YAAY,SAAS,KAAK,EAAE;AAAA,oBACtC;AAAA,oBACA,MAAM;AAAA,oBACN;AAAA,oBACA,eAAe;AAAA;AAAA,kBANV,KAAK;AAAA,gBAOZ,CACD;AAAA;AAAA,YACH;AAAA;AAAA,QACF;AAAA;AAAA,IACF;AAAA,EAEJ;AAGA,MAAI,cAAc,GAAG;AACnB,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,WAAWC;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACA,MAAK;AAAA,QACL,cAAY,GAAG,SAAS;AAAA,QAEvB,+BAAqB,EAAE,OAAO,CAAC;AAAA;AAAA,IAClC;AAAA,EAEJ;AAEA,QAAM,gBAAgB,MAAM,IAAI,CAAC,MAAM,UAAU;AAC/C,UAAM,aAAa,YAAY,SAAS,KAAK,EAAE;AAC/C,UAAM,YAAY,iBAAiB;AACnC,UAAM,YAAY,iBAAiB,SAAS;AAC5C,UAAM,WAAW,gBAAgB,OAAO,WAAW,UAAU;AAE7D,WAAO,oBAAoB;AAAA,MACzB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG,SAAS;AAAA,MACZ,GAAG,SAAS;AAAA,MACZ,QAAQ,SAAS;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAED,MAAI,WAAW,UAAU;AACvB,WACE,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,WAAWC;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACA,MAAK;AAAA,QACL,cAAY,GAAG,SAAS,MAAM,SAAS,QAAQ,cAAc,IAAI,MAAM,EAAE;AAAA,QACzE,UAAU;AAAA,QACV,WAAW;AAAA,QACX,QAAQ,MAAM,gBAAgB,EAAE;AAAA,QAEhC,0BAAAD,KAAC,SAAI,WAAU,uCACZ,yBACH;AAAA;AAAA,IACF;AAAA,EAEJ;AAGA,QAAM,cAAc,eAAe,SAAS,UAAU,YAAY;AAElE,QAAM,iBAA2C;AAAA,IAC/C;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV,aAAa;AAAA,IACb,cAAc;AAAA,EAChB;AAGA,MAAI,iBAAiB;AACnB,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,WAAWC;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACA,MAAK;AAAA,QACL,cAAY,GAAG,SAAS,MAAM,SAAS,QAAQ,cAAc,IAAI,MAAM,EAAE;AAAA,QAExE,0BAAgB,cAAc;AAAA;AAAA,IACjC;AAAA,EAEJ;AAEA,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,WAAWC;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACA,MAAK;AAAA,MACL,cAAY,GAAG,SAAS,MAAM,SAAS,QAAQ,cAAc,IAAI,MAAM,EAAE;AAAA,MACzE,UAAU;AAAA,MACV,WAAW;AAAA,MACX,QAAQ,MAAM,gBAAgB,EAAE;AAAA,MAEhC,0BAAAD;AAAA,QAAC;AAAA;AAAA,UACC,KAAK;AAAA,UACL,WAAU;AAAA,UACV,OAAO;AAAA,YACL,OAAO,WAAW,YAAY,aAAa;AAAA,YAC3C,QAAQ;AAAA,UACV;AAAA,UACA,aAAa;AAAA,UACb,cAAc;AAAA,UACd,aAAa;AAAA,UACb,YAAY;AAAA,UAEX;AAAA;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;;;AE3bA,SAAS,QAAAI,aAAY;AAiDjB,SAeI,OAAAC,MAfJ,QAAAC,aAAA;AAvBJ,IAAM,kBAAsD;AAAA,EAC1D,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAEO,SAAS,YAAkD;AAAA,EAChE;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc,YAAY;AAAA,EAC1B;AACF,GAA+B;AAC7B,QAAM,QAAQ,SAAS;AACvB,QAAM,QAAQ,KAAK,IAAI,GAAG,WAAW,MAAM,MAAM;AACjD,QAAM,YAAY,gBAAgB,IAAI;AACtC,QAAM,cAAc,QAAQ,QAAQ;AAEpC,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,gCAA6B;AAAA,MAC7B,qBAAmB,MAAM;AAAA,MACzB,MAAK;AAAA,MACL,cAAY;AAAA,MACZ,WAAWC;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACA,OAAO;AAAA,QACL,YAAY,MAAM,SAAS,QAAQ;AAAA,QACnC,QAAQ,aAAa,MAAM,SAAS,OAAO,MAAM;AAAA,MACnD;AAAA,MAEC;AAAA,iBAAS,OACR,gBAAAF;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO,EAAE,OAAO,MAAM,SAAS,KAAK,MAAM;AAAA,YAEzC;AAAA;AAAA,QACH,IACE;AAAA,QACJ,gBAAAA,KAAC,SAAI,WAAU,uCACZ,gBAAM,KAAK,EAAE,QAAQ,MAAM,GAAG,CAAC,GAAG,UAAU;AAC3C,gBAAM,OAAO,MAAM,KAAK;AACxB,cAAI,CAAC,MAAM;AACT,mBACE,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBAEC,gCAA6B;AAAA,gBAC7B,eAAW;AAAA,gBACX,WAAWE;AAAA,kBACT;AAAA,kBACA;AAAA,gBACF;AAAA,gBACA,OAAO;AAAA,kBACL,QAAQ,cAAc,MAAM,SAAS,OAAO,MAAM;AAAA,kBAClD,OAAO,MAAM,SAAS,KAAK;AAAA,gBAC7B;AAAA,gBAEC,4BAAkB,gBAAgB,KAAK,IAAI;AAAA;AAAA,cAZvC,SAAS,KAAK;AAAA,YAarB;AAAA,UAEJ;AACA,gBAAM,SAAS,KAAK;AACpB,iBACE,gBAAAF;AAAA,YAAC;AAAA;AAAA,cAEC,MAAK;AAAA,cACL,gCAA6B;AAAA,cAC7B,gBAAc;AAAA,cACd,UAAU,CAAC;AAAA,cACX,cACE,cAAc,UAAU,KAAK,QAAQ,MAAM,KAAK;AAAA,cAElD,SAAS,cAAc,MAAM,WAAW,MAAM,IAAI;AAAA,cAClD,WAAWE;AAAA,gBACT;AAAA,gBACA;AAAA,gBACA,cACI,wCACA;AAAA,cACN;AAAA,cAEC,qBAAW,IAAI;AAAA;AAAA,YAjBX;AAAA,UAkBP;AAAA,QAEJ,CAAC,GACH;AAAA;AAAA;AAAA,EACF;AAEJ;;;AC3GA;AAAA,EACE,iBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,cAAAC;AAAA,EACA,aAAAC;AAAA,EACA,SAAAC;AAAA,EACA,WAAAC;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,OAIK;AACP,SAAS,oBAAoB;AAC7B,SAAS,QAAAC,aAAY;AACrB,SAAS,iBAAiB,cAA+B;AAupBrD,gBAAAC,OAqCQ,QAAAC,aArCR;AAxeJ,IAAM,yBACJC,eAAkD,IAAI;AAEjD,SAAS,qBAAyD;AACvE,SAAOC,YAAW,sBAAsB;AAC1C;AAmBA,IAAM,oBAAgC;AAAA,EACpC,MAAM;AAAA,EACN,WAAW;AAAA,EACX,SAAS;AAAA,EACT,MAAM;AACR;AACA,IAAM,oBAAgC;AAAA,EACpC,MAAM;AAAA,EACN,WAAW;AAAA,EACX,SAAS;AAAA,EACT,MAAM;AACR;AACA,IAAM,qBAAiC,EAAE,UAAU,EAAE;AAE9C,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA,iBAAiB;AAAA,EACjB,2BAA2B;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAyB;AACvB,QAAM,QAAQ,SAAS;AACvB,QAAM,gBAAgB,MAAM,OAAO,kBAAkB;AACrD,QAAM,eAAeC,OAAM;AAC3B,QAAM,aAAaC,QAAO,oBAAI,IAAkC,CAAC;AACjE,QAAM,kBAAkBA,QAAO,CAAC;AAChC,QAAM,gBAAgBA,QAA+B,IAAI;AACzD,QAAM,gBAAgBA,QAAsB,IAAI;AAChD,QAAM,CAAC,YAAY,aAAa,IAAIC,UAAiC,IAAI;AACzE,QAAM,CAAC,kBAAkB,mBAAmB,IAAIA,UAAwB,IAAI;AAC5E,QAAM,CAAC,eAAe,gBAAgB,IAAIA;AAAA,IACxC;AAAA,EACF;AACA,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA;AAAA,IAC1C;AAAA,EACF;AACA,QAAM,cAAcD,QAAO,YAAY;AACvC,cAAY,UAAU;AAEtB,QAAM,mBAAmB,oBAAoB;AAC7C,QAAM,mBAAmB,oBAAoB;AAE7C,QAAM,YAAYE,aAAY,CAAC,SAAiC;AAC9D,kBAAc,UAAU;AACxB,kBAAc,IAAI;AAAA,EACpB,GAAG,CAAC,CAAC;AAEL,QAAM,gBAAgBA,aAAY,CAAC,SAAwB;AACzD,kBAAc,UAAU;AACxB,wBAAoB,IAAI;AAAA,EAC1B,GAAG,CAAC,CAAC;AAEL,QAAM,sBAAsBA,aAAY,CAAC,gBAAoC;AAC3E,QAAI,aAAa;AAEf,qBAAe,MAAM;AACnB,YAAI;AACF,sBAAY,MAAM,EAAE,eAAe,KAAK,CAAC;AAAA,QAC3C,QAAQ;AAAA,QAER;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,iBAAiBA;AAAA,IACrB,CAAC,WAAiC;AAChC,iBAAW,QAAQ,IAAI,OAAO,UAAU;AAAA,QACtC,GAAG;AAAA,QACH,OAAO,OAAO,SAAS,EAAE,gBAAgB;AAAA,MAC3C,CAAC;AACD,aAAO,MAAM;AACX,mBAAW,QAAQ,OAAO,OAAO,QAAQ;AACzC,cAAM,SAAS,cAAc;AAC7B,YAAI,UAAU,OAAO,4BAA4B,OAAO,UAAU;AAChE,oBAAU,EAAE,GAAG,QAAQ,yBAAyB,KAAK,CAAC;AAAA,QACxD;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAEA,QAAM,eAAeA;AAAA,IACnB,CACE,UACA,UACG;AACH,YAAM,WAAW,WAAW,QAAQ,IAAI,QAAQ;AAChD,UAAI,CAAC,SAAU;AACf,iBAAW,QAAQ,IAAI,UAAU,EAAE,GAAG,UAAU,GAAG,MAAM,CAAC;AAAA,IAC5D;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,iBAAiBA,aAAY,CAAC,WAAiC;AACnE,WAAO,CAAC,OAAO,YAAY,OAAO,aAAa;AAAA,EACjD,GAAG,CAAC,CAAC;AAEL,QAAM,oBAAoBA;AAAA,IACxB,CAAC,UAAmD;AAClD,iBAAW,UAAU,WAAW,QAAQ,OAAO,GAAG;AAChD,YAAI,CAAC,eAAe,MAAM,EAAG;AAC7B,cAAM,OAAO,OAAO,QAAQ,sBAAsB;AAClD,YACE,MAAM,KAAK,KAAK,OAAO,kBACvB,MAAM,KAAK,KAAK,QAAQ,kBACxB,MAAM,KAAK,KAAK,MAAM,kBACtB,MAAM,KAAK,KAAK,SAAS,gBACzB;AACA,iBAAO,OAAO;AAAA,QAChB;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,IACA,CAAC,gBAAgB,cAAc;AAAA,EACjC;AAEA,QAAM,wBAAwBA,aAAY,MAAgB;AACxD,UAAM,UAAU,MAAM,KAAK,WAAW,QAAQ,OAAO,CAAC,EAAE;AAAA,MAAO,CAAC,MAC9D,eAAe,CAAC;AAAA,IAClB;AACA,YAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AACxC,WAAO,QAAQ,IAAI,CAAC,MAAM,EAAE,QAAQ;AAAA,EACtC,GAAG,CAAC,cAAc,CAAC;AAEnB,QAAM,YAAYA;AAAA,IAChB,CAAC,UAAoB;AACnB,UAAI,MAAM,gBAAgB,CAAC,MAAM,aAAc;AAM/C,oBAAc,MAAM,MAAM;AAAA,IAC5B;AAAA,IACA,CAAC,aAAa;AAAA,EAChB;AAEA,QAAM,qBAAqBA,aAAY,CAAC,WAAmB;AACzD,gBAAY,UAAU,EAAE,MAAM,gBAAgB,OAAO,CAAC;AAAA,EACxD,GAAG,CAAC,CAAC;AAEL,QAAM,mBAAmBA,aAAY,CAAC,WAAmB;AACvD,gBAAY,UAAU,EAAE,MAAM,cAAc,OAAO,CAAC;AAAA,EACtD,GAAG,CAAC,CAAC;AAEL,QAAM,iBAAiBA;AAAA,IACrB,CAAC,QAAgB,WAA+B;AAC9C,kBAAY,UAAU,EAAE,MAAM,YAAY,QAAQ,OAAO,CAAC;AAAA,IAC5D;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,eAAeA,aAAY,MAAM;AACrC,QAAI,cAAc,YAAY,KAAM,eAAc,IAAI;AAAA,EACxD,GAAG,CAAC,aAAa,CAAC;AAElB,QAAM,mBAAmBA;AAAA,IACvB,CAAC,UAAqC;AACpC,UAAI,cAAc,QAAS,QAAO;AAClC,UAAI,cAAc,QAAS,eAAc,IAAI;AAC7C,YAAM,eAAe,kBAAkB;AAAA,QACrC,GAAG,MAAM;AAAA,QACT,GAAG,MAAM;AAAA,MACX,CAAC;AACD,YAAM,OAAwB;AAAA,QAC5B,QAAQ,MAAM;AAAA,QACd,WAAW,MAAM,aAAa;AAAA,QAC9B,QAAQ;AAAA,QACR,WAAW,MAAM;AAAA,QACjB,UAAU,MAAM;AAAA,QAChB,UAAU,MAAM;AAAA,QAChB,aAAa,MAAM;AAAA,QACnB,aAAa,MAAM;AAAA,QACnB,YAAY,MAAM;AAAA,QAClB,SAAS,MAAM;AAAA,QACf;AAAA,QACA,yBAAyB;AAAA,QACzB,aAAa,MAAM,eAAe;AAAA,MACpC;AACA,gBAAU,IAAI;AACd,aAAO;AAAA,IACT;AAAA,IACA,CAAC,mBAAmB,WAAW,aAAa;AAAA,EAC9C;AAEA,QAAM,gBAAgBA;AAAA,IACpB,CAAC,UAAoC;AACnC,YAAM,SAAS,cAAc;AAC7B,UAAI,CAAC,UAAU,OAAO,WAAW,UAAW;AAC5C,YAAM,eAAe,kBAAkB,KAAK;AAC5C,gBAAU;AAAA,QACR,GAAG;AAAA,QACH,UAAU,MAAM;AAAA,QAChB,UAAU,MAAM;AAAA,QAChB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,CAAC,mBAAmB,SAAS;AAAA,EAC/B;AAEA,QAAM,mBAAmBA;AAAA,IACvB,CACE,QACA,UACA,UACA,aACG;AACH,YAAM,SAAS,WAAW,QAAQ,IAAI,QAAQ;AAC9C,YAAM,aAAa,QAAQ,QAAQ,sBAAsB;AACzD,YAAM,WAA0B;AAAA,QAC9B,QAAQ,OAAO;AAAA,QACf,QAAQ,OAAO;AAAA,QACf,UAAU;AAAA,QACV,UAAU;AAAA,QACV,aAAa,OAAO;AAAA,QACpB,aAAa,OAAO;AAAA,QACpB,YAAY,OAAO;AAAA,QACnB,YAAY,aACR;AAAA,UACE,MAAM,WAAW;AAAA,UACjB,KAAK,WAAW;AAAA,UAChB,OAAO,WAAW;AAAA,UAClB,QAAQ,WAAW;AAAA,QACrB,IACA,OAAO;AAAA,QACX,SAAS,OAAO;AAAA,MAClB;AACA,kBAAY,UAAU;AAAA,QACpB,MAAM;AAAA,QACN,QAAQ,OAAO;AAAA,QACf;AAAA,QACA,QAAQ,OAAO,WAAW,aAAa,aAAa;AAAA,MACtD,CAAC;AACD,uBAAiB,QAAQ;AACzB,wBAAkB,IAAI;AACtB,gBAAU,IAAI;AACd,0BAAoB,OAAO,WAAW;AAAA,IACxC;AAAA,IACA,CAAC,qBAAqB,SAAS;AAAA,EACjC;AAEA,QAAM,qBAAqBA;AAAA,IACzB,CAAC,QAAyB,UAAkB,aAAqB;AAC/D,YAAM,YAA4B;AAAA,QAChC,QAAQ,OAAO;AAAA,QACf,QAAQ,OAAO;AAAA,QACf,UAAU;AAAA,QACV,UAAU;AAAA,QACV,aAAa,OAAO;AAAA,QACpB,aAAa,OAAO;AAAA,QACpB,YAAY,OAAO;AAAA,QACnB,SAAS,OAAO;AAAA,MAClB;AACA,wBAAkB,SAAS;AAC3B,uBAAiB,IAAI;AACrB,gBAAU,IAAI;AACd,0BAAoB,OAAO,WAAW;AAAA,IACxC;AAAA,IACA,CAAC,qBAAqB,SAAS;AAAA,EACjC;AAEA,QAAM,iBAAiBA;AAAA,IACrB,CAAC,UAAoC;AACnC,YAAM,SAAS,cAAc;AAC7B,UAAI,CAAC,UAAU,OAAO,WAAW,UAAW;AAC5C,YAAM,eAAe,kBAAkB,KAAK;AAC5C,UAAI,cAAc;AAChB,yBAAiB,QAAQ,cAAc,MAAM,GAAG,MAAM,CAAC;AACvD;AAAA,MACF;AACA,yBAAmB,QAAQ,MAAM,GAAG,MAAM,CAAC;AAAA,IAC7C;AAAA,IACA,CAAC,kBAAkB,oBAAoB,iBAAiB;AAAA,EAC1D;AAEA,QAAM,aAAaA,aAAY,MAAM;AACnC,UAAM,SAAS,cAAc;AAC7B,QAAI,CAAC,OAAQ;AACb,uBAAmB,QAAQ,OAAO,UAAU,OAAO,QAAQ;AAAA,EAC7D,GAAG,CAAC,kBAAkB,CAAC;AAEvB,QAAM,oBAAoBA;AAAA,IACxB,CAAC,UAAsC;AACrC,UAAI,cAAc,QAAS,QAAO;AAClC,UAAI,CAAC,MAAM,aAAc,QAAO;AAChC,UAAI,cAAc,QAAS,eAAc,IAAI;AAC7C,YAAM,MAAM,sBAAsB;AAClC,UAAI,IAAI,WAAW,EAAG,QAAO;AAC7B,YAAM,aAAa,IAAI,CAAC;AACxB,YAAM,cAAc,WAAW,QAAQ,IAAI,UAAU;AACrD,YAAM,YAAY,aAAa,QAAQ,sBAAsB;AAC7D,YAAM,OAAwB;AAAA,QAC5B,QAAQ,MAAM;AAAA,QACd,WAAW,MAAM,aAAa;AAAA,QAC9B,QAAQ;AAAA,QACR,WAAW;AAAA,QACX,UAAU,YAAY,UAAU,OAAO,UAAU,QAAQ,IAAI;AAAA,QAC7D,UAAU,YAAY,UAAU,MAAM,UAAU,SAAS,IAAI;AAAA,QAC7D,aAAa;AAAA,QACb,aAAa;AAAA,QACb,YAAY,MAAM;AAAA,QAClB,SAAS,MAAM;AAAA,QACf,cAAc;AAAA,QACd,yBAAyB;AAAA,QACzB,aAAa,MAAM,eAAe;AAAA,MACpC;AACA,gBAAU,IAAI;AAId,aAAO;AAAA,IACT;AAAA,IACA,CAAC,WAAW,eAAe,qBAAqB;AAAA,EAClD;AAEA,QAAM,oBAAoBA;AAAA,IACxB,CAAC,cAA+B;AAC9B,YAAM,SAAS,cAAc;AAC7B,UAAI,CAAC,UAAU,OAAO,WAAW,WAAY;AAC7C,YAAM,MAAM,sBAAsB;AAClC,UAAI,IAAI,WAAW,EAAG;AACtB,YAAM,aAAa,OAAO,0BACtB,IAAI,QAAQ,OAAO,uBAAuB,IAC1C;AACJ,YAAM,UACJ,cAAc,UACT,aAAa,KAAK,IAAI,UACtB,aAAa,IAAI,IAAI,UAAU,IAAI;AAC1C,YAAM,SAAS,IAAI,OAAO;AAC1B,YAAM,SAAS,WAAW,QAAQ,IAAI,MAAM;AAC5C,YAAM,OAAO,QAAQ,QAAQ,sBAAsB;AACnD,gBAAU;AAAA,QACR,GAAG;AAAA,QACH,yBAAyB;AAAA,QACzB,cAAc;AAAA,QACd,UAAU,OAAO,KAAK,OAAO,KAAK,QAAQ,IAAI,OAAO;AAAA,QACrD,UAAU,OAAO,KAAK,MAAM,KAAK,SAAS,IAAI,OAAO;AAAA,MACvD,CAAC;AAAA,IAEH;AAAA,IACA,CAAC,WAAW,qBAAqB;AAAA,EACnC;AAEA,QAAM,qBAAqBA,aAAY,MAAM;AAC3C,UAAM,SAAS,cAAc;AAC7B,QAAI,CAAC,UAAU,OAAO,WAAW,WAAY;AAC7C,UAAM,WAAW,OAAO;AACxB,QAAI,CAAC,SAAU;AACf,UAAM,SAAS,WAAW,QAAQ,IAAI,QAAQ;AAC9C,QAAI,CAAC,UAAU,CAAC,eAAe,MAAM,EAAG;AACxC,UAAM,OAAO,OAAO,QAAQ,sBAAsB;AAClD;AAAA,MACE;AAAA,MACA;AAAA,MACA,KAAK,OAAO,KAAK,QAAQ;AAAA,MACzB,KAAK,MAAM,KAAK,SAAS;AAAA,IAC3B;AAAA,EACF,GAAG,CAAC,kBAAkB,cAAc,CAAC;AAErC,QAAM,QAAmBC,SAAQ,MAAM;AACrC,QAAI,WAAY,QAAO;AACvB,QAAI,cAAe,QAAO;AAC1B,QAAI,eAAgB,QAAO;AAC3B,QAAI,iBAAkB,QAAO;AAC7B,WAAO;AAAA,EACT,GAAG,CAAC,YAAY,kBAAkB,gBAAgB,aAAa,CAAC;AAEhE,QAAM,sBAAsBA;AAAA,IAC1B,MAAM,sBAAsB,EAAE;AAAA;AAAA;AAAA;AAAA,IAI9B,CAAC,YAAY,qBAAqB;AAAA,EACpC;AAEA,QAAM,aAAwCA;AAAA,IAC5C,OAAO;AAAA,MACL,cACE,YAAY,UACZ,eAAe,UACf,gBAAgB,WACf,mBAAmB,mBAAmB;AAAA,MACzC,cAAc,YAAY,UAAU;AAAA,MACpC;AAAA,MACA,cAAc,YAAY,gBAAgB;AAAA,MAC1C,yBAAyB,YAAY,2BAA2B;AAAA,MAChE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,eAA4CA;AAAA,IAChD,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA,cAAc,WAAW;AAAA,MACzB,cAAc,YAAY,gBAAgB;AAAA,MAC1C,YAAY,eAAe;AAAA,MAC3B,yBAAyB,YAAY,2BAA2B;AAAA,IAClE;AAAA,IACA,CAAC,YAAY,YAAY,gBAAgB,YAAY;AAAA,EACvD;AAEA,EAAAC,WAAU,MAAM;AACd,QAAI,CAAC,WAAY;AACjB,aAAS,UAAU,OAAiC;AAClD,UAAI,MAAM,QAAQ,UAAU;AAC1B,cAAM,eAAe;AACrB,mBAAW;AAAA,MACb;AAAA,IACF;AACA,WAAO,iBAAiB,WAAW,SAAS;AAC5C,WAAO,MAAM,OAAO,oBAAoB,WAAW,SAAS;AAAA,EAC9D,GAAG,CAAC,YAAY,UAAU,CAAC;AAE3B,QAAM,eAAeD,SAAQ,MAAM;AACjC,QAAI,CAAC,WAAY,QAAO;AACxB,UAAM,aAAa,WAAW,eAC1B,WAAW,QAAQ,IAAI,WAAW,YAAY,IAC9C;AACJ,UAAM,YAAY,YAAY,SAAS;AACvC,UAAM,YAAY,WAAW,aAAa;AAC1C,QAAI,WAAW;AACb,aAAO,GAAG,SAAS,SAAS,SAAS;AAAA,IACvC;AACA,WAAO,GAAG,SAAS;AAAA,EACrB,GAAG,CAAC,UAAU,CAAC;AAEf,QAAM,iBAAiB,aACrB,gBAAAR,MAAC,eAAY,SAAS,YAAY,eAA8B,IAC9D;AAEJ,QAAM,gBAAgB,gBACpB,gBAAAA;AAAA,IAAC;AAAA;AAAA,MAEC,SAAS;AAAA,MACT,YAAY,gBAAgB,qBAAqB;AAAA,MACjD,QAAQ,MAAM,iBAAiB,IAAI;AAAA;AAAA,IAH9B,UAAU,cAAc,MAAM;AAAA,EAIrC,IACE;AAEJ,QAAM,gBAAgB,iBACpB,gBAAAA;AAAA,IAAC;AAAA;AAAA,MAEC,SAAS;AAAA,MACT,YAAY,gBAAgB,qBAAqB;AAAA,MACjD,QAAQ,MAAM,kBAAkB,IAAI;AAAA;AAAA,IAH/B,UAAU,eAAe,MAAM;AAAA,EAItC,IACE;AAEJ,QAAM,aAAa,OAAO,aAAa,cAAc,SAAS,OAAO;AAErE,SACE,gBAAAC,MAAC,uBAAuB,UAAvB,EAAgC,OAAO,cACtC;AAAA,oBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,qCAAkC;AAAA,QAClC,oBAAkB,aAAa,SAAS;AAAA,QACxC,oBAAkB,YAAY;AAAA,QAC9B,mBAAiB;AAAA,QACjB,WAAWU,MAAK,YAAY,SAAS;AAAA,QACrC;AAAA,QAEC;AAAA;AAAA,IACH;AAAA,IACC,aACG;AAAA,MACE,gBAAAT,MAAC,mBAAgB,SAAS,OACvB;AAAA;AAAA,QACA;AAAA,QACA;AAAA,SACH;AAAA,MACA;AAAA,IACF,IACA;AAAA,IACH,CAAC,2BACA,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,IAAI;AAAA,QACJ,MAAK;AAAA,QACL,aAAU;AAAA,QACV,WAAU;AAAA,QACV,0CAAuC;AAAA,QACvC,OAAO;AAAA,UACL,UAAU;AAAA,UACV,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,UAAU;AAAA,UACV,MAAM;AAAA,UACN,YAAY;AAAA,UACZ,QAAQ;AAAA,QACV;AAAA,QAEC,0BAAgB;AAAA;AAAA,IACnB,IACE;AAAA,KACN;AAEJ;AAOA,SAAS,YAAY,EAAE,SAAS,cAAc,GAAqB;AACjE,MAAI,QAAQ,WAAW,YAAY;AACjC,WACE,gBAAAA;AAAA,MAAC,OAAO;AAAA,MAAP;AAAA,QAEC,qCAAkC;AAAA,QAClC,eAAY;AAAA,QACZ,SAAS,EAAE,SAAS,EAAE;AAAA,QACtB,SAAS,EAAE,SAAS,EAAE;AAAA,QACtB,MAAM,EAAE,SAAS,EAAE;AAAA,QACnB,YAAY,gBAAgB,qBAAqB,EAAE,UAAU,KAAK;AAAA,QAClE,OAAO;AAAA,UACL,UAAU;AAAA,UACV,MAAM,QAAQ,WAAW;AAAA,UACzB,KAAK,QAAQ,WAAW;AAAA,UACxB,OAAO,QAAQ,WAAW;AAAA,UAC1B,QAAQ,QAAQ,WAAW;AAAA,UAC3B,eAAe;AAAA,UACf,QAAQ;AAAA,UACR,WAAW,gBAAgB,SAAS;AAAA,UACpC,cAAc;AAAA,QAChB;AAAA,QAEC,kBAAQ;AAAA;AAAA,MAnBL;AAAA,IAoBN;AAAA,EAEJ;AAEA,QAAM,gBAAgB,gBAClB;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV,IACA;AAAA,IACE,OAAO,CAAC,GAAG,MAAM,IAAI;AAAA,IACrB,QAAQ,CAAC,GAAG,IAAI,GAAG,MAAM,KAAK,CAAC;AAAA,IAC/B,QAAQ;AAAA,MACN;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACJ,QAAM,mBAA+B,gBACjC,qBACA;AAAA,IACE,OAAO,EAAE,MAAM,UAAU,WAAW,KAAK,SAAS,IAAI,MAAM,IAAI;AAAA,IAChE,QAAQ,EAAE,UAAU,MAAM,MAAM,YAAY;AAAA,IAC5C,QAAQ,EAAE,UAAU,MAAM,MAAM,UAAU;AAAA,EAC5C;AACJ,SACE,gBAAAA;AAAA,IAAC,OAAO;AAAA,IAAP;AAAA,MAEC,qCAAkC;AAAA,MAClC,eAAY;AAAA,MACZ,SAAS;AAAA,QACP,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,QAAQ;AAAA,MACV;AAAA,MACA,SAAS;AAAA,MACT,MAAM,EAAE,SAAS,EAAE;AAAA,MACnB,YAAY;AAAA,MACZ,OAAO;AAAA,QACL,UAAU;AAAA,QACV,MAAM,QAAQ,WAAW,QAAQ,WAAW,QAAQ;AAAA,QACpD,KAAK,QAAQ,WAAW,QAAQ,WAAW,SAAS;AAAA,QACpD,OAAO,QAAQ,WAAW;AAAA,QAC1B,QAAQ,QAAQ,WAAW;AAAA,QAC3B,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,aAAa;AAAA,QACb,iBAAiB;AAAA,QACjB,YAAY;AAAA,MACd;AAAA,MAEC,kBAAQ;AAAA;AAAA,IAzBL;AAAA,EA0BN;AAEJ;AAQA,SAAS,cAAc,EAAE,SAAS,YAAY,OAAO,GAAuB;AAC1E,QAAM,YAAY,QAAQ,WAAW,QAAQ,WAAW,QAAQ;AAChE,QAAM,WAAW,QAAQ,WAAW,QAAQ,WAAW,SAAS;AAChE,QAAM,UACJ,QAAQ,WAAW,OACnB,QAAQ,WAAW,QAAQ,IAC3B,QAAQ,WAAW,QAAQ;AAC7B,QAAM,SACJ,QAAQ,WAAW,MACnB,QAAQ,WAAW,SAAS,IAC5B,QAAQ,WAAW,SAAS;AAC9B,SACE,gBAAAA;AAAA,IAAC,OAAO;AAAA,IAAP;AAAA,MACC,qCAAkC;AAAA,MAClC,eAAa,QAAQ;AAAA,MACrB,mBAAgB;AAAA,MAChB,SAAS,EAAE,MAAM,WAAW,KAAK,UAAU,OAAO,MAAM,SAAS,EAAE;AAAA,MACnE,SAAS,EAAE,MAAM,SAAS,KAAK,QAAQ,OAAO,MAAM,SAAS,EAAE;AAAA,MAC/D;AAAA,MACA,qBAAqB;AAAA,MACrB,OAAO;AAAA,QACL,UAAU;AAAA,QACV,OAAO,QAAQ,WAAW;AAAA,QAC1B,QAAQ,QAAQ,WAAW;AAAA,QAC3B,QAAQ;AAAA,QACR,eAAe;AAAA,MACjB;AAAA,MAEC,kBAAQ;AAAA;AAAA,EACX;AAEJ;AAQA,SAAS,cAAc,EAAE,SAAS,YAAY,OAAO,GAAuB;AAC1E,QAAM,YAAY,QAAQ,WAAW,QAAQ,WAAW,QAAQ;AAChE,QAAM,WAAW,QAAQ,WAAW,QAAQ,WAAW,SAAS;AAChE,SACE,gBAAAA;AAAA,IAAC,OAAO;AAAA,IAAP;AAAA,MACC,qCAAkC;AAAA,MAClC,eAAa,QAAQ;AAAA,MACrB,mBAAgB;AAAA,MAChB,SAAS,EAAE,MAAM,WAAW,KAAK,UAAU,OAAO,MAAM,SAAS,EAAE;AAAA,MACnE,SAAS;AAAA,QACP,MAAM,QAAQ,WAAW;AAAA,QACzB,KAAK,QAAQ,WAAW;AAAA,QACxB,OAAO;AAAA,QACP,SAAS;AAAA,MACX;AAAA,MACA,MAAM,EAAE,SAAS,EAAE;AAAA,MACnB;AAAA,MACA,qBAAqB;AAAA,MACrB,OAAO;AAAA,QACL,UAAU;AAAA,QACV,OAAO,QAAQ,WAAW;AAAA,QAC1B,QAAQ,QAAQ,WAAW;AAAA,QAC3B,QAAQ;AAAA,QACR,eAAe;AAAA,MACjB;AAAA,MAEC,kBAAQ;AAAA;AAAA,EACX;AAEJ;AAgBO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AACT,GAA4B;AAC1B,QAAM,UAAU,mBAAmB;AACnC,QAAM,MAAMK,QAA8B,IAAI;AAC9C,QAAM,WAAW,OAAO,YAAY;AACpC,QAAM,eAAe,OAAO,YAAY;AACxC,QAAM,YAAY,SAAS;AAC3B,QAAM,YAAY,SAAS;AAE3B,QAAM,oBAAoBA,QAAO,SAAS,cAAc;AACxD,oBAAkB,UAAU,SAAS;AACrC,QAAM,kBAAkBA,QAAO,SAAS,YAAY;AACpD,kBAAgB,UAAU,SAAS;AAKnC,EAAAI,WAAU,MAAM;AACd,UAAM,UAAU,IAAI;AACpB,UAAM,WAAW,kBAAkB;AACnC,QAAI,CAAC,YAAY,CAAC,QAAS;AAC3B,UAAM,aAAa,SAAS;AAAA,MAC1B;AAAA,MACA;AAAA,MACA,UAAU;AAAA,MACV;AAAA,MACA,OAAO;AAAA,MACP,OAAO;AAAA,IACT,CAAC;AACD,WAAO;AAAA,EAET,GAAG,CAAC,QAAQ,CAAC;AAEb,EAAAA,WAAU,MAAM;AACd,oBAAgB,UAAU,UAAU;AAAA,MAClC;AAAA,MACA,UAAU;AAAA,MACV,OAAO;AAAA,MACP,OAAO;AAAA,IACT,CAAC;AAAA,EACH,GAAG,CAAC,UAAU,UAAU,cAAc,WAAW,SAAS,CAAC;AAE3D,QAAM,aAAa,SAAS,cAAc;AAC1C,QAAM,eAAe,SAAS,gBAAgB;AAC9C,QAAM,kBAAkB,SAAS,4BAA4B;AAM7D,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,gBAAiB;AACtB,UAAM,KAAK,IAAI;AACf,QAAI,CAAC,GAAI;AACT,QAAI,SAAS,kBAAkB,GAAI;AACnC,QAAI;AACF,SAAG,MAAM,EAAE,eAAe,KAAK,CAAC;AAAA,IAClC,QAAQ;AAAA,IAER;AAAA,EACF,GAAG,CAAC,iBAAiB,QAAQ,CAAC;AAE9B,QAAM,gBAA2C;AAAA,IAC/C,GAAG;AAAA,IACH,UAAU;AAAA,IACV,QAAQ,aAAa,OAAO,OAAO;AAAA,IACnC,MACE,iBAAiB,YAAY,eAAe,OAAQ,OAAO,QAAQ;AAAA,EACvE;AAEA,QAAM,gBAAgBF;AAAA,IACpB,CAAC,UAAyC;AACxC,UAAI,CAAC,QAAS;AACd,YAAM,aAAa,QAAQ;AAC3B,UAAI,WAAW,iBAAiB,WAAY;AAC5C,UAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAK;AAC9C,cAAM,eAAe;AACrB,mBAAW,mBAAmB;AAC9B;AAAA,MACF;AACA,UAAI,MAAM,QAAQ,gBAAgB,MAAM,QAAQ,aAAa;AAC3D,cAAM,eAAe;AACrB,mBAAW,kBAAkB,MAAM;AACnC;AAAA,MACF;AACA,UAAI,MAAM,QAAQ,eAAe,MAAM,QAAQ,WAAW;AACxD,cAAM,eAAe;AACrB,mBAAW,kBAAkB,MAAM;AACnC;AAAA,MACF;AACA,UAAI,MAAM,QAAQ,UAAU;AAC1B,cAAM,eAAe;AACrB,mBAAW,WAAW;AAAA,MACxB;AAAA,IACF;AAAA,IACA,CAAC,OAAO;AAAA,EACV;AAEA,SACE,gBAAAP;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,oCAAiC;AAAA,MACjC,kBAAgB;AAAA,MAChB,yBAAuB,kBAAkB,SAAS;AAAA,MAClD;AAAA,MACA,UAAU,YAAY,CAAC,eAAe,KAAK;AAAA,MAC3C,iBAAe,YAAY,CAAC,gBAAgB;AAAA,MAC5C,cAAY;AAAA,MACZ,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACC,GAAG,oCAAoC,aAAa;AAAA,MAEpD,uBAAa,aAAa;AAAA;AAAA,EAC7B;AAEJ;;;ACxhCA;AAAA,EACE,eAAAW;AAAA,EACA,SAAAC;AAAA,EACA,WAAAC;AAAA,OAGK;AACP,SAAS,QAAAC,aAAY;;;AC1BrB,SAAS,aAAAC,YAAW,WAAAC,UAAS,UAAAC,SAAQ,YAAAC,iBAAgB;;;ACkC9C,SAAS,iBAAiB,SAA4C;AAC3E,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AACJ,MAAI,SAAS,GAAG;AACd,WAAO,EAAE,WAAW,CAAC,GAAG,MAAM,GAAG,YAAY,GAAG,cAAc,UAAU;AAAA,EAC1E;AACA,MAAI,UAAU,GAAG;AACf,WAAO;AAAA,MACL,WAAW,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,YAAY,GAAG,QAAQ,EAAE,CAAC;AAAA,MAC5D,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,EACF;AAEA,QAAM,YACJ,iBAAiB,aACZ,iBAAiB,cAAc,QAAQ,KACxC;AACN,QAAM,OAAO,KAAK,IAAI,iBAAiB,KAAK,IAAI,WAAW,SAAS,CAAC;AACrE,QAAM,UAAU,QAAQ,KAAK;AAE7B,QAAM,YAA+B,MAAM;AAAA,IACzC,EAAE,QAAQ,MAAM;AAAA,IAChB,CAAC,GAAG,UAAU;AACZ,YAAM,IAAI,WAAW,IAAI,KAAK,QAAQ,UAAU;AAChD,aAAO;AAAA,QACL,MAAM,QAAQ;AAAA,QACd,QAAQ,IAAI;AAAA,QACZ,YAAY,KAAK,IAAI,CAAC,IAAI;AAAA,QAC1B,QAAQ,QAAQ;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,YAAY,aAAa,QAAQ,KAAK;AAAA,IACtC,cAAc;AAAA,EAChB;AACF;AA8BO,SAAS,qBAAqB;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,mBAAmB,mBAAmB,IAAI;AAAA,EAC1C,kBAAkB,mBAAmB,gBAAgB,EAAE;AACzD,GAAsD;AACpD,MAAI,aAAa,EAAG,QAAO;AAC3B,MAAI,kBAAkB,EAAG,QAAO;AAEhC,QAAM,aAAa,iBAAiB,cAAc,YAAY;AAC9D,QAAM,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,WAAW,SAAS,CAAC;AAEvD,QAAM,mBAAmB,YAAY,SAAS,YAAY;AAC1D,MAAI,CAAC,kBAAkB;AACrB,QAAI,kBAAkB,YAAY,UAAW,QAAO;AACpD,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,kBAAkB;AAC5B,WAAO,YAAY,mBAAmB,mBAAmB;AAAA,EAC3D;AACA,MAAI,QAAQ,iBAAiB;AAC3B,WAAO;AAAA,EACT;AACA,SAAO;AACT;AASO,IAAM,qBAGT;AAAA,EACF,KAAK,EAAE,iBAAiB,IAAI,UAAU,GAAG,UAAU,GAAG;AAAA,EACtD,kBAAkB,EAAE,iBAAiB,IAAI,UAAU,GAAG,UAAU,EAAE;AACpE;;;AD3HA,IAAM,kBAAkB;AAEjB,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,SAAS;AAAA,EACT,mBAAmB;AACrB,GAAoD;AAClD,QAAM,eAAeC,QAAuB,IAAI;AAChD,QAAM,CAAC,gBAAgB,iBAAiB,IAAIC,UAAS,CAAC;AAEtD,EAAAC,WAAU,MAAM;AACd,UAAM,OAAO,aAAa;AAC1B,QAAI,CAAC,KAAM;AACX,QAAI,QAAQ;AAMZ,UAAM,QAAQ,MAAM;AAClB,YAAMC,QAAO,aAAa;AAC1B,UAAI,CAACA,MAAM;AACX,YAAM,OAAO,KAAK;AAAA,QAChB;AAAA,QACA,KAAK,MAAMA,MAAK,sBAAsB,EAAE,KAAK,IAAI;AAAA,MACnD;AACA,wBAAkB,CAAC,SAAU,SAAS,OAAO,OAAO,IAAK;AAAA,IAC3D;AACA,UAAM;AACN,QAAI,OAAO,mBAAmB,YAAa;AAC3C,UAAM,WAAW,IAAI,eAAe,MAAM;AACxC,2BAAqB,KAAK;AAC1B,cAAQ,sBAAsB,KAAK;AAAA,IACrC,CAAC;AACD,aAAS,QAAQ,IAAI;AACrB,WAAO,MAAM;AACX,2BAAqB,KAAK;AAC1B,eAAS,WAAW;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,gBAAgB,CAAC;AAErB,SAAOC,SAAgC,MAAM;AAC3C,UAAM,OAAO,qBAAqB;AAAA,MAChC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,QAAI,SAAS,SAAS,SAAS,kBAAkB;AAC/C,YAAM,WAAW,mBAAmB,IAAI;AACxC,YAAM,SAAS,iBAAiB;AAAA,QAC9B,gBAAgB,kBAAkB,YAAY;AAAA,QAC9C;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP,GAAG;AAAA,MACL,CAAC;AACD,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc,OAAO;AAAA,QACrB,SAAS,OAAO;AAAA,QAChB,YAAY,OAAO;AAAA,QACnB,cAAc,OAAO;AAAA,MACvB;AAAA,IACF;AACA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA,cAAc,CAAC;AAAA,MACf,SAAS;AAAA,MACT,YAAY,YAAY;AAAA,MACxB,cAAc;AAAA,IAChB;AAAA,EACF,GAAG,CAAC,WAAW,YAAY,WAAW,gBAAgB,SAAS,MAAM,CAAC;AACxE;;;AErGA,SAAS,eAAAC,cAAa,aAAAC,YAAW,WAAAC,UAAS,UAAAC,SAAQ,YAAAC,kBAAgB;;;AC2B3D,IAAM,6BAAsD;AAAA,EACjE,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,oBAAoB;AACtB;AAIO,SAAS,YACd,IACA,IACA,aAAsC,4BACxB;AACd,MACE,KAAK,IAAI,EAAE,IAAI,WAAW,kBAC1B,KAAK,IAAI,EAAE,IAAI,WAAW,gBAC1B;AACA,WAAO;AAAA,EACT;AACA,MAAI,KAAK,IAAI,EAAE,IAAI,KAAK,IAAI,EAAE,IAAI,WAAW;AAC3C,WAAO;AACT,MAAI,CAAC,KAAK,KAAK,IAAI,EAAE,IAAI,WAAW,cAAe,QAAO;AAC1D,SAAO;AACT;AA8EO,IAAM,oBAAN,MAAwB;AAAA,EACZ;AAAA,EACA;AAAA,EACT,SAA+B;AAAA,EAC/B,QAA0B,EAAE,MAAM,OAAO;AAAA,EACzC,eAAqD;AAAA,EACrD;AAAA,EAER,YACE,WACA,aAAsC,4BACtC,MAAoB,MAAM,KAAK,IAAI,GACnC;AACA,SAAK,YAAY;AACjB,SAAK,aAAa;AAClB,SAAK,MAAM;AAAA,EACb;AAAA;AAAA,EAGA,WAA6B;AAC3B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,UAAgB;AACd,SAAK,kBAAkB;AACvB,QAAI,KAAK,MAAM,SAAS,UAAU;AAChC,WAAK,UAAU,eAAe,KAAK,MAAM,MAAM;AAAA,IACjD;AACA,SAAK,SAAS;AACd,SAAK,WAAW,EAAE,MAAM,OAAO,CAAC;AAChC,SAAK,UAAU,eAAe,KAAK;AAAA,EACrC;AAAA,EAEA,kBACE,MACA,OACM;AACN,QAAI,KAAK,OAAQ;AACjB,QAAI,KAAK,SAAU;AAEnB,UAAM,YAAY,KAAK,IAAI;AAC3B,SAAK,SAAS;AAAA,MACZ,QAAQ,KAAK;AAAA,MACb,WAAW,MAAM;AAAA,MACjB;AAAA,MACA,QAAQ,MAAM;AAAA,MACd,QAAQ,MAAM;AAAA,MACd,OAAO,MAAM;AAAA,MACb,OAAO,MAAM;AAAA,MACb,MAAM;AAAA,MACN,eAAe;AAAA,IACjB;AACA,SAAK,WAAW;AAAA,MACd,MAAM;AAAA,MACN,WAAW,MAAM;AAAA,MACjB,QAAQ,KAAK;AAAA,MACb;AAAA,IACF,CAAC;AACD,SAAK,gBAAgB,IAAI;AAAA,EAC3B;AAAA,EAEA,kBACE,MACA,OACM;AACN,UAAM,UAAU,KAAK;AACrB,QAAI,CAAC,WAAW,QAAQ,cAAc,MAAM,UAAW;AACvD,QAAI,QAAQ,WAAW,KAAK,OAAQ;AAEpC,YAAQ,QAAQ,MAAM;AACtB,YAAQ,QAAQ,MAAM;AAEtB,UAAM,KAAK,MAAM,UAAU,QAAQ;AACnC,UAAM,KAAK,MAAM,UAAU,QAAQ;AACnC,UAAM,OAAO,YAAY,IAAI,IAAI,KAAK,UAAU;AAChD,QAAI,SAAS,YAAa,SAAQ,OAAO;AAEzC,QAAI,KAAK,MAAM,SAAS,UAAU;AAChC,WAAK,UAAU,aAAa;AAAA,QAC1B,QAAQ,QAAQ;AAAA,QAChB,WAAW,QAAQ;AAAA,QACnB,UAAU,MAAM;AAAA,QAChB,UAAU,MAAM;AAAA,MAClB,CAAC;AACD;AAAA,IACF;AAEA,QAAI,KAAK,MAAM,SAAS,YAAY;AAClC,UAAI,SAAS,cAAc;AACzB,aAAK,kBAAkB;AACvB,aAAK,WAAW;AAAA,UACd,MAAM;AAAA,UACN,WAAW,QAAQ;AAAA,UACnB,QAAQ,QAAQ;AAAA,QAClB,CAAC;AACD,aAAK,UAAU,qBAAqB,QAAQ,MAAM;AAClD;AAAA,MACF;AACA,UACE,SAAS,YACT,KAAK,YACL,CAAC,MAAM,KAAK,WAAW,oBACvB;AACA,aAAK,kBAAkB;AACvB,aAAK,UAAU,SAAS,MAAM,SAAS,MAAM,OAAO;AACpD;AAAA,MACF;AACA;AAAA,IACF;AAEA,QAAI,KAAK,MAAM,SAAS,WAAW;AACjC,UACE,SAAS,YACT,KAAK,YACL,CAAC,MAAM,KAAK,WAAW,oBACvB;AACA,aAAK,UAAU,eAAe,KAAK,MAAM;AACzC,gBAAQ,gBAAgB;AACxB,aAAK,UAAU,SAAS,MAAM,SAAS,MAAM,OAAO;AACpD;AAAA,MACF;AACA,UAAI,SAAS,cAAc;AACzB,aAAK,UAAU,eAAe,KAAK,MAAM;AACzC,gBAAQ,gBAAgB;AACxB,aAAK,WAAW;AAAA,UACd,MAAM;AAAA,UACN,WAAW,QAAQ;AAAA,UACnB,QAAQ,QAAQ;AAAA,QAClB,CAAC;AACD,aAAK,UAAU,qBAAqB,QAAQ,MAAM;AAClD;AAAA,MACF;AACA;AAAA,IACF;AAAA,EAGF;AAAA,EAEA,gBACE,MACA,OACM;AACN,UAAM,UAAU,KAAK;AACrB,QAAI,CAAC,WAAW,QAAQ,cAAc,MAAM,UAAW;AACvD,QAAI,QAAQ,WAAW,KAAK,OAAQ;AACpC,SAAK,kBAAkB;AAEvB,UAAM,KAAK,MAAM,UAAU,QAAQ;AACnC,UAAM,KAAK,MAAM,UAAU,QAAQ;AACnC,UAAM,QACJ,QAAQ,SAAS,eACjB,CAAC,QAAQ,iBACT,KAAK,IAAI,EAAE,IAAI,KAAK,WAAW,kBAC/B,KAAK,IAAI,EAAE,IAAI,KAAK,WAAW;AAEjC,QAAI,KAAK,MAAM,SAAS,UAAU;AAChC,WAAK,UAAU,YAAY;AAAA,QACzB,QAAQ,QAAQ;AAAA,QAChB,WAAW,QAAQ;AAAA,QACnB,UAAU,MAAM;AAAA,QAChB,UAAU,MAAM;AAAA,MAClB,CAAC;AACD,WAAK,MAAM;AACX;AAAA,IACF;AAEA,QAAI,OAAO;AACT,UAAI,KAAK,YAAY,CAAC,KAAK,UAAU;AACnC,aAAK,UAAU,QAAQ,KAAK,MAAM;AAAA,MACpC;AACA,WAAK,MAAM;AACX;AAAA,IACF;AAEA,QAAI,QAAQ,eAAe;AACzB,WAAK,UAAU,eAAe,KAAK,MAAM;AAAA,IAC3C;AACA,SAAK,MAAM;AAAA,EACb;AAAA,EAEA,oBAAoB,MAAuC;AACzD,UAAM,UAAU,KAAK;AACrB,QAAI,CAAC,WAAW,QAAQ,WAAW,KAAK,OAAQ;AAChD,SAAK,kBAAkB;AACvB,QAAI,KAAK,MAAM,SAAS,UAAU;AAChC,WAAK,UAAU,eAAe,KAAK,MAAM;AACzC,WAAK,MAAM;AACX;AAAA,IACF;AACA,QAAI,QAAQ,eAAe;AACzB,WAAK,UAAU,eAAe,KAAK,MAAM;AAAA,IAC3C;AACA,SAAK,MAAM;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,mBAAyB;AACvB,SAAK,kBAAkB;AACvB,SAAK,SAAS;AACd,SAAK,UAAU,eAAe,KAAK;AACnC,SAAK,WAAW,EAAE,MAAM,OAAO,CAAC;AAAA,EAClC;AAAA,EAEQ,UACN,SACA,SACA,SACM;AACN,SAAK,UAAU,eAAe,IAAI;AAClC,UAAM,cAAc,UAAU,QAAQ;AACtC,UAAM,cAAc,UAAU,QAAQ;AACtC,SAAK,WAAW;AAAA,MACd,MAAM;AAAA,MACN,WAAW,QAAQ;AAAA,MACnB,QAAQ,QAAQ;AAAA,IAClB,CAAC;AACD,SAAK,UAAU,cAAc;AAAA,MAC3B,QAAQ,QAAQ;AAAA,MAChB,WAAW,QAAQ;AAAA,MACnB,QAAQ,QAAQ;AAAA,MAChB,QAAQ,QAAQ;AAAA,MAChB,UAAU;AAAA,MACV,UAAU;AAAA,MACV;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,gBAAgB,MAAuC;AAC7D,SAAK,kBAAkB;AACvB,SAAK,eAAe,WAAW,MAAM;AACnC,YAAM,UAAU,KAAK;AACrB,UAAI,CAAC,WAAW,QAAQ,WAAW,KAAK,OAAQ;AAChD,UAAI,QAAQ,SAAS,YAAa;AAClC,cAAQ,gBAAgB;AACxB,WAAK,UAAU,iBAAiB,KAAK,MAAM;AAC3C,WAAK,WAAW;AAAA,QACd,MAAM;AAAA,QACN,WAAW,QAAQ;AAAA,QACnB,QAAQ,KAAK;AAAA,MACf,CAAC;AAAA,IACH,GAAG,KAAK,WAAW,cAAc;AAAA,EACnC;AAAA,EAEQ,oBAA0B;AAChC,QAAI,KAAK,iBAAiB,MAAM;AAC9B,mBAAa,KAAK,YAAY;AAC9B,WAAK,eAAe;AAAA,IACtB;AAAA,EACF;AAAA,EAEQ,QAAc;AACpB,SAAK,SAAS;AACd,SAAK,UAAU,eAAe,KAAK;AACnC,SAAK,WAAW,EAAE,MAAM,OAAO,CAAC;AAAA,EAClC;AAAA,EAEQ,WAAW,MAA8B;AAC/C,SAAK,QAAQ;AACb,SAAK,UAAU,gBAAgB,IAAI;AAAA,EACrC;AACF;;;AD1UO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA,aAAa;AAAA,EACb,SAAS;AAAA,EACT,UAAU;AAAA,EACV;AAAA,EACA;AACF,IAA+B,CAAC,GAA4B;AAC1D,QAAM,YAAYC,QAAO,QAAQ;AACjC,YAAU,UAAU;AACpB,QAAM,YAAYA,QAAO,MAAM;AAC/B,YAAU,UAAU;AACpB,QAAM,aAAaA,QAAyC,OAAO;AACnE,aAAW,UAAU;AACrB,QAAM,sBAAsBA,QAAO,gBAAgB;AACnD,sBAAoB,UAAU;AAC9B,QAAM,sBAAsBA,QAAO,gBAAgB;AACnD,sBAAoB,UAAU;AAE9B,QAAM,kBAAkBA,QAAO,oBAAI,IAAyB,CAAC;AAC7D,QAAM,cAAcA;AAAA,IAClB,oBAAI,IAAmD;AAAA,EACzD;AAEA,QAAM,aAAaC,aAAY,CAAC,WAAmB;AACjD,QAAI,SAAS,YAAY,QAAQ,IAAI,MAAM;AAC3C,QAAI,CAAC,QAAQ;AACX,eAAS,CAAC,YAAgC;AACxC,YAAI,SAAS;AACX,0BAAgB,QAAQ,IAAI,QAAQ,OAAO;AAAA,QAC7C,OAAO;AACL,0BAAgB,QAAQ,OAAO,MAAM;AAAA,QACvC;AAAA,MACF;AACA,kBAAY,QAAQ,IAAI,QAAQ,MAAM;AAAA,IACxC;AACA,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AAEL,QAAM,CAAC,cAAc,eAAe,IAAIC,WAAwB,IAAI;AACpE,QAAM,CAAC,kBAAkB,mBAAmB,IAAIA,WAA2B;AAAA,IACzE,MAAM;AAAA,EACR,CAAC;AACD,QAAM,CAAC,cAAc,eAAe,IAAIA,WAAS,KAAK;AAEtD,QAAM,oBAAoBD,aAAY,CAAC,WAAmB;AACxD,UAAM,KAAK,gBAAgB,QAAQ,IAAI,MAAM;AAC7C,QAAI,CAAC,GAAI,QAAO,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,EAAE;AACvD,UAAM,OAAO,GAAG,sBAAsB;AACtC,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,KAAK,KAAK;AAAA,MACV,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK;AAAA,IACf;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,SAASE;AAAA,IACb,MACE,IAAI;AAAA,MACF;AAAA,QACE,OAAO,CAAC,WAAW;AACjB,gBAAM,SAAS,gBAAgB,QAAQ,IAAI,MAAM;AACjD,cAAI,UAAU,YAAY,oBAAoB,WAAW,SAAS;AAChE,uBAAW,QAAQ,UAAU;AAAA,cAC3B;AAAA,cACA,cAAc;AAAA,cACd,cAAc;AAAA,cACd,aAAa,UAAU;AAAA,YACzB,CAAC;AACD;AAAA,UACF;AACA,cAAI,WAAW,SAAS;AACtB,uBAAW,QAAQ,eAAe,QAAQ,KAAK;AAC/C;AAAA,UACF;AACA,oBAAU,UAAU;AAAA,YAClB,MAAM;AAAA,YACN;AAAA,YACA,QAAQ;AAAA,UACV,CAAC;AAAA,QACH;AAAA,QACA,gBAAgB,CAAC,WAAW;AAI1B,cAAI,WAAW,SAAS;AACtB,uBAAW,QAAQ,mBAAmB,MAAM;AAC5C;AAAA,UACF;AACA,oBAAU,UAAU,EAAE,MAAM,gBAAgB,OAAO,CAAC;AAAA,QACtD;AAAA,QACA,cAAc,CAAC,WAAW;AACxB,cAAI,WAAW,SAAS;AACtB,uBAAW,QAAQ,iBAAiB,MAAM;AAC1C;AAAA,UACF;AACA,oBAAU,UAAU,EAAE,MAAM,cAAc,OAAO,CAAC;AAAA,QACpD;AAAA,QACA,aAAa,CAAC,UAAU;AACtB,cAAI,UAAU,YAAY,iBAAkB;AAC5C,gBAAM,oBAAoB,WAAW;AACrC,cAAI,CAAC,kBAAmB;AACxB,gBAAM,UAAU,oBAAoB,UAAU,MAAM,MAAM,KAAK;AAC/D,gBAAM,QAAQ,oBAAoB,UAAU,MAAM,MAAM,KAAK;AAC7D,gBAAM,aAAa,kBAAkB,MAAM,MAAM;AACjD,gBAAM,SAAS,gBAAgB,QAAQ,IAAI,MAAM,MAAM,KAAK;AAC5D,4BAAkB,iBAAiB;AAAA,YACjC,QAAQ,MAAM;AAAA,YACd,WAAW;AAAA,YACX,WAAW,MAAM;AAAA,YACjB,QAAQ,MAAM;AAAA,YACd,QAAQ,MAAM;AAAA,YACd,UAAU,MAAM;AAAA,YAChB,UAAU,MAAM;AAAA,YAChB,aAAa,MAAM;AAAA,YACnB,aAAa,MAAM;AAAA,YACnB;AAAA,YACA;AAAA,YACA,aAAa;AAAA,UACf,CAAC;AAAA,QACH;AAAA,QACA,YAAY,CAAC,UAAU;AACrB,qBAAW,SAAS,cAAc;AAAA,YAChC,GAAG,MAAM;AAAA,YACT,GAAG,MAAM;AAAA,UACX,CAAC;AAAA,QACH;AAAA,QACA,WAAW,CAAC,UAAU;AACpB,qBAAW,SAAS,eAAe;AAAA,YACjC,GAAG,MAAM;AAAA,YACT,GAAG,MAAM;AAAA,UACX,CAAC;AAAA,QACH;AAAA,QACA,cAAc,MAAM;AAClB,qBAAW,SAAS,WAAW;AAAA,QACjC;AAAA,QACA,cAAc;AAAA,QACd,eAAe,CAAC,SAAS;AACvB,8BAAoB,IAAI;AACxB,cAAI,KAAK,SAAS,QAAQ;AACxB,4BAAgB,IAAI;AAAA,UACtB,OAAO;AACL,4BAAgB,KAAK,MAAM;AAAA,UAC7B;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,IACF,CAAC,mBAAmB,UAAU;AAAA,EAChC;AAEA,EAAAC,WAAU,MAAM,MAAM,OAAO,QAAQ,GAAG,CAAC,MAAM,CAAC;AAEhD,QAAM,WAAWH;AAAA,IACf,CAAC,SAA0D;AACzD,YAAM,WAAW,iBAAiB,KAAK;AACvC,YAAM,mBAA6C,WAC/C,iBAAiB,OACjB;AACJ,aAAO;AAAA,QACL,KAAK,WAAW,KAAK,MAAM;AAAA,QAC3B,OAAO;AAAA,UACL,aAAa,YAAY,eAAe,SAAS;AAAA,UACjD,YAAY;AAAA,UACZ,kBAAkB;AAAA,QACpB;AAAA,QACA,sBAAsB;AAAA,QACtB,eAAe,CAAC,UAAU;AACxB,cAAI,MAAM,WAAW,UAAa,MAAM,WAAW,EAAG;AACtD,cAAI,KAAK,SAAU;AACnB,cAAI;AACF,YAAC,MAAM,cAA8B;AAAA,cACnC,MAAM;AAAA,YACR;AAAA,UACF,QAAQ;AAAA,UAIR;AACA,iBAAO,kBAAkB,MAAM;AAAA,YAC7B,WAAW,MAAM;AAAA,YACjB,SAAS,MAAM;AAAA,YACf,SAAS,MAAM;AAAA,UACjB,CAAC;AAAA,QACH;AAAA,QACA,eAAe,CAAC,UAAU;AACxB,iBAAO,kBAAkB,MAAM;AAAA,YAC7B,WAAW,MAAM;AAAA,YACjB,SAAS,MAAM;AAAA,YACf,SAAS,MAAM;AAAA,UACjB,CAAC;AAAA,QACH;AAAA,QACA,aAAa,CAAC,UAAU;AACtB,cAAI;AACF,YAAC,MAAM,cAA8B;AAAA,cACnC,MAAM;AAAA,YACR;AAAA,UACF,QAAQ;AAAA,UAER;AACA,iBAAO,gBAAgB,MAAM;AAAA,YAC3B,WAAW,MAAM;AAAA,YACjB,SAAS,MAAM;AAAA,YACf,SAAS,MAAM;AAAA,UACjB,CAAC;AAAA,QACH;AAAA,QACA,iBAAiB,MAAM;AACrB,iBAAO,oBAAoB,IAAI;AAAA,QACjC;AAAA,QACA,sBAAsB,MAAM;AAC1B,iBAAO,oBAAoB,IAAI;AAAA,QACjC;AAAA,QACA,WAAW,CAAC,UAAU;AACpB,cAAI,MAAM,QAAQ,UAAU;AAC1B,kBAAM,eAAe;AACrB,uBAAW,SAAS,WAAW;AAC/B;AAAA,UACF;AACA,cAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAK;AAC9C,kBAAM,eAAe;AACrB,gBAAI,KAAK,YAAY,CAAC,KAAK,SAAU;AACrC,gBAAI,UAAU,YAAY,kBAAkB;AAC1C,oBAAM,oBAAoB,WAAW;AACrC,kBAAI,CAAC,kBAAmB;AACxB,oBAAM,SAAS,gBAAgB,QAAQ,IAAI,KAAK,MAAM,KAAK;AAC3D,oBAAM,UACJ,oBAAoB,UAAU,KAAK,MAAM,KAAK;AAChD,oBAAM,QAAQ,oBAAoB,UAAU,KAAK,MAAM,KAAK;AAC5D,oBAAM,aAAa,kBAAkB,KAAK,MAAM;AAChD,oBAAM,UAAU,kBAAkB,kBAAkB;AAAA,gBAClD,QAAQ,KAAK;AAAA,gBACb,WAAW;AAAA,gBACX,cAAc,KAAK;AAAA,gBACnB;AAAA,gBACA;AAAA,gBACA,aAAa;AAAA,cACf,CAAC;AACD,kBAAI,CAAC,SAAS;AAIZ,kCAAkB,UAAU;AAAA,kBAC1B,QAAQ,KAAK;AAAA,kBACb,cAAc,KAAK;AAAA,kBACnB,cAAc,KAAK;AAAA,kBACnB,aAAa;AAAA,gBACf,CAAC;AAAA,cACH;AACA;AAAA,YACF;AACA,gBAAI,WAAW,SAAS;AACtB,yBAAW,QAAQ,eAAe,KAAK,QAAQ,UAAU;AACzD;AAAA,YACF;AACA,sBAAU,UAAU;AAAA,cAClB,MAAM;AAAA,cACN,QAAQ,KAAK;AAAA,cACb,QAAQ;AAAA,YACV,CAAC;AAAA,UACH;AAAA,QACF;AAAA,QACA,SAAS,MAAM;AAAA,QAEf;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,iBAAiB;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,mBAAmBA,aAAY,CAAC,SAAoC;AACxE,QAAI,KAAK,YAAY,CAAC,KAAK,SAAU;AACrC,QAAI,UAAU,YAAY,iBAAkB;AAC5C,QAAI,WAAW,SAAS;AACtB,iBAAW,QAAQ,eAAe,KAAK,QAAQ,UAAU;AACzD;AAAA,IACF;AACA,cAAU,UAAU;AAAA,MAClB,MAAM;AAAA,MACN,QAAQ,KAAK;AAAA,MACb,QAAQ;AAAA,IACV,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AHzKM,gBAAAI,aAAA;AArHN,IAAMC,mBAAkB;AAAA,EACtB,IAAI,EAAE,OAAO,IAAI,QAAQ,IAAI;AAAA,EAC7B,IAAI,EAAE,OAAO,IAAI,QAAQ,IAAI;AAAA,EAC7B,IAAI,EAAE,OAAO,KAAK,QAAQ,IAAI;AAChC;AAEA,IAAM,cAAsC,CAAC;AAS7C,SAAS,oBACP,QACsB;AACtB,MAAI,CAAC,QAAQ;AACX,WAAO,EAAE,SAAS,OAAO,QAAQ,QAAQ,UAAU,MAAM;AAAA,EAC3D;AACA,MAAI,OAAO,WAAW,UAAU;AAC9B,QAAI,WAAW,SAAS;AACtB,aAAO,EAAE,SAAS,SAAS,QAAQ,SAAS,UAAU,QAAQ;AAAA,IAChE;AACA,WAAO,EAAE,SAAS,QAAQ,QAAQ,QAAQ,UAAU,OAAO;AAAA,EAC7D;AACA,QAAM,UACJ,OAAO,YAAY,UAAU,UAAW,OAAO,WAAW;AAC5D,QAAM,SACJ,OAAO,WAAW,UAAU,UAAW,OAAO,UAAU;AAC1D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,UAAW,OAAO,WAAW,OAAO,UAAU;AAAA,EAChD;AACF;AAEO,SAAS,SAA+C;AAAA,EAC7D;AAAA,EACA;AAAA,EACA,oBAAoB;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA,cAAc,YAAY;AAAA,EAC1B;AAAA,EACA;AACF,GAA4B;AAC1B,QAAM,SAASC,SAAQ,MAAM,oBAAoB,MAAM,GAAG,CAAC,MAAM,CAAC;AAClE,QAAM,OAAOD,iBAAgB,QAAQ;AACrC,QAAM,WAAWE,OAAM;AACvB,QAAM,QAAQ,SAAS;AACvB,QAAM,gBAAgB,MAAM,OAAO,kBAAkB;AAErD,QAAM,eAAe,oBAAoB;AAAA,IACvC,WAAW,MAAM;AAAA,IACjB,WAAW,KAAK;AAAA,IAChB,YAAY,KAAK;AAAA,IACjB,SAAS,OAAO;AAAA,IAChB,QAAQ,OAAO;AAAA,EACjB,CAAC;AAED,QAAM,UAAU,mBAAmB;AACnC,QAAM,oBAAoB,SAAS,cAAc;AAEjD,QAAM,OAAOC;AAAA,IACX,CAAC,WAAgD;AAC/C,qBAAe,MAAM;AAAA,IACvB;AAAA,IACA,CAAC,YAAY;AAAA,EACf;AAEA,QAAM,QAAQF;AAAA,IACZ,MACE,MAAM,IAAI,CAAC,MAAM,UAAU;AACzB,YAAM,YAAY,eAAe,MAAM,KAAK,KAAK;AACjD,aAAO,EAAE,MAAM,OAAO,UAAU;AAAA,IAClC,CAAC;AAAA,IACH,CAAC,OAAO,YAAY;AAAA,EACtB;AAEA,QAAM,mBAAmBE;AAAA,IACvB,CAAC,WAA8B;AAC7B,YAAM,QAAQ,MAAM,KAAK,CAAC,SAAU,KAAK,KAAK,OAAkB,MAAM;AACtE,UAAI,CAAC,MAAO,QAAO;AACnB,aAAO,WAAW,MAAM,MAAM,MAAM,WAAW,MAAM,KAAK;AAAA,IAC5D;AAAA,IACA,CAAC,OAAO,UAAU;AAAA,EACpB;AAEA,QAAM,mBAAmBA;AAAA,IACvB,CAAC,WAAkC;AACjC,YAAM,QAAQ,MAAM,KAAK,CAAC,SAAU,KAAK,KAAK,OAAkB,MAAM;AACtE,UAAI,CAAC,MAAO,QAAO;AACnB,YAAM,OAAO,MAAM;AACnB,aACE,KAAK,QACJ,KAAK,YAA+C,SACrD;AAAA,IAEJ;AAAA,IACA,CAAC,KAAK;AAAA,EACR;AAEA,QAAM,UAAU,mBAAmB;AAAA,IACjC,UAAU,CAAC,WAAW,KAAK,MAA6C;AAAA,IACxE,QAAQ;AAAA,IACR,SAAS;AAAA,IACT;AAAA,IACA;AAAA,EACF,CAAC;AAED,MAAI,MAAM,WAAW,GAAG;AACtB,WACE,gBAAAJ;AAAA,MAAC;AAAA;AAAA,QACC,KAAK,aAAa;AAAA,QAClB,6BAA0B;AAAA,QAC1B,eAAa,OAAO;AAAA,QACpB,aAAU;AAAA,QACV,cAAW;AAAA,QACX,2BAAyB;AAAA,QACzB,MAAK;AAAA,QACL,cAAY,GAAG,SAAS;AAAA,QACxB,WAAWK;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,QAEC,wBAAc,YAAY,IAAI;AAAA;AAAA,IACjC;AAAA,EAEJ;AAEA,QAAM,YAAY,GAAG,SAAS,MAAM,MAAM,MAAM,QAAQ,MAAM,WAAW,IAAI,KAAK,GAAG;AAErF,QAAM,eAAe,mBAAmB,SAAS;AACjD,QAAM,sBAAsB,mBAAmB,gBAAgB;AAE/D,QAAM,aAAa,CACjB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,EACF,GACA,QAA0C,CAAC,MACxC;AACH,UAAM,SAAS,KAAK;AACpB,UAAM,kBAAkB,QAAQ,iBAAiB;AACjD,UAAM,kBAAkB,wBAAwB;AAChD,UAAM,aACJ,mBAAmB,QAAQ,iBAAiB,SAAS,YACjD,OACA,UAAU;AAChB,UAAM,eAAe,mBAAmB,iBAAiB;AACzD,UAAM,aAAa,mBAAmB,iBAAiB;AACvD,UAAM,aAAa,mBAAmB,iBAAiB;AACvD,UAAM,cAAc,mBAAmB,iBAAiB;AAIxD,UAAM,WAAW,cAAc,cAAc;AAC7C,UAAM,QAAgC;AAAA,MACpC,GAAG;AAAA,MACH;AAAA,IACF;AACA,UAAM,WAAW,MAAM,YAAY;AACnC,UAAM,WAAW,MAAM,YAAY;AACnC,UAAM,WAAW,QAAQ,SAAS;AAAA,MAChC;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,UAAM,aAAa,MAAM;AACzB,UAAM,iBAA2B,CAAC;AAClC,QAAI,YAAY;AACd,qBAAe,KAAK,cAAc,WAAW,UAAU,KAAK;AAC5D,qBAAe,KAAK,UAAU,WAAW,MAAM,MAAM;AAAA,IACvD;AACA,QAAI,gBAAgB,CAAC,eAAe;AAClC,qBAAe,KAAK,qBAAqB,aAAa;AAAA,IACxD;AACA,UAAM,YAAY,eAAe,SAC7B,eAAe,KAAK,GAAG,IACvB;AACJ,UAAM,oBAAoB,WAAW,OAAO;AAC5C,UAAM,gBACJ,gBAAgB,CAAC,gBACb,iCACA;AACN,WACE,gBAAAL;AAAA,MAAC;AAAA;AAAA,QAEC,MAAK;AAAA,QACL,iBAAe;AAAA,QACf,iBAAe,QAAQ;AAAA,QACvB,IAAI,GAAG,QAAQ,IAAI,KAAK;AAAA,QACxB,UAAU,WAAW,KAAK;AAAA,QAC1B,eAAa,WAAW,SAAS;AAAA,QACjC,kBAAgB,cAAc,SAAS;AAAA,QACvC,mBAAiB,eAAe,SAAS;AAAA,QACxC,GAAG;AAAA,QACJ,OAAO;AAAA,UACL,GAAG,SAAS;AAAA,UACZ,SAAS;AAAA,UACT,WAAW;AAAA,UACX,GAAI,aACA;AAAA,YACE,UAAU;AAAA,YACV,MAAM,WAAW;AAAA,YACjB,QAAQ;AAAA,YACR,QAAQ,eAAe,KAAK,WAAW;AAAA,YACvC;AAAA,YACA,iBAAiB;AAAA,YACjB,YAAY,gBACR,SACA;AAAA,UACN,IACA,YACE;AAAA,YACE;AAAA,YACA,iBAAiB;AAAA,YACjB,YAAY,gBACR,SACA;AAAA,UACN,IACA;AAAA,QACR;AAAA,QAEC,qBAAW,MAAM,OAAO,KAAK;AAAA;AAAA,MArCzB,KAAK;AAAA,IAsCZ;AAAA,EAEJ;AAEA,MAAI,aAAa,SAAS,SAAS,aAAa,SAAS,kBAAkB;AACzE,UAAM,cAAc,KAAK,SAAS;AAClC,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,KAAK,aAAa;AAAA,QAClB,6BAA0B;AAAA,QAC1B,eAAa,OAAO;AAAA,QACpB,aAAW,aAAa;AAAA,QACxB,2BAAyB;AAAA,QACzB,uBAAqB,gBAAgB,SAAS;AAAA,QAC9C,MAAK;AAAA,QACL,cAAY;AAAA,QACZ,iBAAe;AAAA,QACf,iBAAe,MAAM;AAAA,QACrB,WAAWK;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACA,OAAO;AAAA,UACL,aAAa;AAAA,UACb,GAAG;AAAA,QACL;AAAA,QAEA,0BAAAL;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,OAAO;AAAA,cACL,OAAO,aAAa;AAAA,cACpB,QAAQ;AAAA,YACV;AAAA,YAEC,gBAAM;AAAA,cAAI,CAAC,MAAM,UAChB,WAAW,MAAM;AAAA,gBACf,YAAY,aAAa,aAAa,KAAK;AAAA,cAC7C,CAAC;AAAA,YACH;AAAA;AAAA,QACF;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,MAAI,aAAa,SAAS,QAAQ;AAChC,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,KAAK,aAAa;AAAA,QAClB,6BAA0B;AAAA,QAC1B,eAAa,OAAO;AAAA,QACpB,aAAU;AAAA,QACV,2BAAyB;AAAA,QACzB,uBAAqB,gBAAgB,SAAS;AAAA,QAC9C,MAAK;AAAA,QACL,cAAY;AAAA,QACZ,iBAAe;AAAA,QACf,iBAAe,MAAM;AAAA,QACrB,WAAWK,MAAK,2BAA2B,SAAS;AAAA,QACpD;AAAA,QAEA,0BAAAL;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAWK;AAAA,cACT;AAAA,cACA;AAAA,YACF;AAAA,YACA,OAAO;AAAA,cACL,aAAa,QAAQ,eAAe,SAAS;AAAA,cAC7C,YAAY;AAAA,cACZ,eAAe;AAAA,cACf,gBAAgB,gBAAgB,SAAS;AAAA,YAC3C;AAAA,YAEC,gBAAM,IAAI,CAAC,SACV,gBAAAL;AAAA,cAAC;AAAA;AAAA,gBAEC,WAAU;AAAA,gBACV,MAAK;AAAA,gBAEJ,qBAAW,IAAI;AAAA;AAAA,cAJX,KAAK,KAAK;AAAA,YAKjB,CACD;AAAA;AAAA,QACH;AAAA;AAAA,IACF;AAAA,EAEJ;AAIA,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,KAAK,aAAa;AAAA,MAClB,6BAA0B;AAAA,MAC1B,eAAa,OAAO;AAAA,MACpB,aAAW,aAAa;AAAA,MACxB,2BAAyB;AAAA,MACzB,uBAAqB,gBAAgB,SAAS;AAAA,MAC9C,MAAK;AAAA,MACL,cAAY;AAAA,MACZ,iBAAe;AAAA,MACf,iBAAe,MAAM;AAAA,MACrB,WAAWK;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACA,OAAO,EAAE,aAAa,SAAS,GAAG,MAAM;AAAA,MAExC,0BAAAL,MAAC,SAAI,MAAK,OAAM,WAAU,uCACvB,gBAAM,IAAI,CAAC,SAAS,WAAW,IAAI,CAAC,GACvC;AAAA;AAAA,EACF;AAEJ;;;AKxbA;AAAA,EACE,iBAAAM;AAAA,EACA,eAAAC;AAAA,EACA,cAAAC;AAAA,EACA,aAAAC;AAAA,EACA,WAAAC;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,OAEK;AACP,SAAS,WAAAC,gBAAe;AACxB,SAAS,QAAAC,aAAY;AA2Gf,SACE,OAAAC,OADF,QAAAC,aAAA;AApFN,IAAM,wBAAwBC;AAAA,EAC5B;AACF;AAMA,IAAM,6BAA6BA,eAAmC;AAAA,EACpE,QAAQ;AACV,CAAC;AAED,IAAM,gBAA0C;AAAA,EAC9C,MAAM;AAAA,EACN,SAAS;AAAA,EACT,WAAW;AACb;AAEA,IAAM,kBAAkB;AAGxB,IAAM,aAAa,CAAC,QAAQ,UAAU,UAAU;AAEhD,IAAM,uBAA0D;AAAA,EAC9D,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,UAAU;AACZ;AAEO,SAAS,uBAAuB,EAAE,SAAS,GAA4B;AAC5E,QAAM,CAAC,WAAW,YAAY,IAAIC,WAEhC,MAAM,oBAAI,IAAI,CAAC;AACjB,QAAM,WAAW,YAAY;AAC7B,QAAM,eAAeC,aAAY,CAAC,SAAiC;AACjE,iBAAa,CAAC,YAAY;AACxB,YAAM,WAAW,QAAQ,IAAI,KAAK,EAAE;AACpC,UACE,YACA,SAAS,SAAS,KAAK,QACvB,SAAS,UAAU,KAAK,SACxB,SAAS,SAAS,KAAK,QACvB,SAAS,UAAU,KAAK,SACxB,SAAS,YAAY,KAAK,WAC1B,SAAS,UAAU,KAAK,SACxB,SAAS,WAAW,KAAK,UACzB,SAAS,aAAa,KAAK,UAC3B;AACA,eAAO;AAAA,MACT;AACA,YAAM,OAAO,IAAI,IAAI,OAAO;AAC5B,WAAK,IAAI,KAAK,IAAI,IAAI;AACtB,aAAO;AAAA,IACT,CAAC;AACD,WAAO,MAAM;AACX,mBAAa,CAAC,YAAY;AACxB,YAAI,CAAC,QAAQ,IAAI,KAAK,EAAE,EAAG,QAAO;AAClC,cAAM,OAAO,IAAI,IAAI,OAAO;AAC5B,aAAK,OAAO,KAAK,EAAE;AACnB,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,CAAC;AACL,QAAM,QAAQC;AAAA,IACZ,OAAO,EAAE,aAAa;AAAA,IACtB,CAAC,YAAY;AAAA,EACf;AACA,QAAM,QAAQA;AAAA,IACZ,MACE,CAAC,GAAG,UAAU,OAAO,CAAC,EAAE;AAAA,MACtB,CAAC,GAAG,OACD,EAAE,SAAS,cAAc,EAAE,IAAI,MAC7B,EAAE,SAAS,cAAc,EAAE,IAAI,MAClC,cAAc,EAAE,IAAI,IAAI,cAAc,EAAE,IAAI,KAC5C,EAAE,MAAM,cAAc,EAAE,KAAK;AAAA,IACjC;AAAA,IACF,CAAC,SAAS;AAAA,EACZ;AAEA,QAAM,aAAa,YAAY,MAAM,SAAS;AAC9C,QAAM,aAAaA,SAAQ,OAAO,EAAE,QAAQ,WAAW,IAAI,CAAC,UAAU,CAAC;AAEvE,SACE,gBAAAL,MAAC,sBAAsB,UAAtB,EAA+B,OAC9B,0BAAAC,MAAC,2BAA2B,UAA3B,EAAoC,OAAO,YAC1C;AAAA,oBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,qCAAkC;AAAA,QAClC,0BAAwB,MAAM;AAAA,QAC9B,gCAA8B,aAAa,SAAS;AAAA,QACpD,OAAO;AAAA,UACL,WAAW;AAAA,UACX,eAAe,aACX,kDACA;AAAA,QACN;AAAA,QAEC;AAAA;AAAA,IACH;AAAA,IACC,aAAa,gBAAAA,MAAC,kBAAe,OAAc,IAAK;AAAA,KACnD,GACF;AAEJ;AAEO,SAAS,sBAAsB,MAAoC;AACxE,QAAM,UAAUM,YAAW,qBAAqB;AAChD,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,EAAAC,WAAU,MAAM,QAAQ,aAAa,IAAI,GAAG,CAAC,SAAS,IAAI,CAAC;AAC7D;AASO,SAAS,0BAAmC;AACjD,SAAOD,YAAW,0BAA0B,EAAE;AAChD;AAEA,SAAS,eAAe;AAAA,EACtB;AACF,GAEG;AAMD,QAAM,CAAC,MAAM,OAAO,IAAIH,WAAmB,MAAM;AACjD,QAAM,OAAO,SAAS;AACtB,QAAM,cAAcC,aAAY,CAAC,cAAsB;AACrD,YAAQ,CAAC,YAAY;AACnB,YAAM,QAAQ,WAAW,QAAQ,OAAO;AACxC,YAAM,OAAO,KAAK;AAAA,QAChB,WAAW,SAAS;AAAA,QACpB,KAAK,IAAI,GAAG,QAAQ,SAAS;AAAA,MAC/B;AACA,aAAO,WAAW,IAAI,KAAK;AAAA,IAC7B,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AACL,QAAM,CAAC,UAAU,WAAW,IAAID,WAAwB,IAAI;AAC5D,QAAM,eAAe,gBAAgB;AAErC,QAAM,gBACJ,MAAM,KAAK,CAAC,SAAS,KAAK,OAAO,QAAQ,KACzC,MAAM,KAAK,CAAC,SAAS,KAAK,MAAM,KAChC,MAAM,KAAK,CAAC,SAAS,KAAK,SAAS,SAAS,KAC5C,MAAM,CAAC,KACP;AACF,QAAM,eACJ,MAAM,KAAK,CAAC,SAAS,KAAK,OAAO,QAAQ,KAAK;AAEhD,EAAAI,WAAU,MAAM;AACd,QAAI,CAAC,eAAe;AAClB,kBAAY,IAAI;AAChB;AAAA,IACF;AACA;AAAA,MAAY,CAAC,YACX,WAAW,MAAM,KAAK,CAAC,SAAS,KAAK,OAAO,OAAO,IAC/C,UACA,cAAc;AAAA,IACpB;AAAA,EACF,GAAG,CAAC,OAAO,aAAa,CAAC;AAMzB,QAAM,SAAS,cAAc,UAAU;AACvC,QAAM,gBAAgBC,QAAO,KAAK;AAClC,EAAAD,WAAU,MAAM;AACd,QAAI,WAAW,cAAc,SAAS;AACpC,oBAAc,UAAU;AACxB,cAAQ,SAAS,WAAW,MAAM;AAAA,IACpC;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAKX,QAAM,WAAWE;AAAA,IACf,CAAC,EAAE,UAAU,CAAC,EAAE,EAAE,GAAG,UAAU,CAAC,EAAE,EAAE,GAAG,KAAK,MAAM;AAChD,UAAI,CAAC,KAAM;AACX,UAAI,KAAK,OAAQ,KAAK,KAAK,KAAK,IAAM,aAAY,CAAC;AAAA,eAC1C,KAAK,MAAO,KAAK,KAAK,KAAK,IAAM,aAAY,EAAE;AAAA,IAC1D;AAAA,IACA,EAAE,MAAM,KAAK,YAAY,KAAK;AAAA,EAChC;AAEA,MAAI,CAAC,aAAc,QAAO;AAE1B,QAAM,eAAe,MAAM;AAAA,IACzB,CAAC,SAAS,KAAK,OAAO,aAAa,MAAM,KAAK;AAAA,EAChD;AAEA,SACE,gBAAAT;AAAA,IAAC;AAAA;AAAA,MACC,oCAAiC;AAAA,MACjC,cAAY;AAAA,MACZ,oBAAkB,aAAa;AAAA,MAC/B,OAAO;AAAA,QACL,GAAG;AAAA,QACH,UAAU;AAAA,QACV,MAAM;AAAA,QACN,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,gBAAgB;AAAA;AAAA;AAAA,QAGhB,eAAe;AAAA,MACjB;AAAA,MAEA,0BAAAC;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO;AAAA,YACL,eAAe;AAAA,YACf,UAAU;AAAA,YACV,YAAY;AAAA,YACZ,OAAO;AAAA,YACP,WAAW;AAAA,YACX,YAAY;AAAA,YACZ,aAAa;AAAA,YACb,WACE;AAAA,UACJ;AAAA,UAGA;AAAA,4BAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACJ,GAAG,SAAS;AAAA,gBACb,SAAS,MACP,QAAQ,CAAC,UAAW,UAAU,SAAS,WAAW,MAAO;AAAA,gBAE3D,iBAAe;AAAA,gBACf,iBAAe;AAAA,gBACf,uCAAoC;AAAA,gBACpC,kBAAgB,aAAa;AAAA,gBAC7B,sBAAoB,aAAa,UAAU;AAAA,gBAC3C,WAAU;AAAA,gBACV,OAAO;AAAA,kBACL,aAAa;AAAA,kBACb,YAAY;AAAA,kBACZ,QAAQ;AAAA,kBACR,QAAQ;AAAA,gBACV;AAAA,gBAEA;AAAA,kCAAAD;AAAA,oBAAC;AAAA;AAAA,sBACC,eAAW;AAAA,sBACX,WAAU;AAAA,sBACV,OAAO,EAAE,YAAY,sBAAsB;AAAA;AAAA,kBAC7C;AAAA,kBACA,gBAAAC,MAAC,UAAK,WAAU,2CACd;AAAA,oCAAAA,MAAC,UAAK,WAAU,yDACd;AAAA,sCAAAD,MAAC,UAAK,WAAU,YAAY,uBAAa,OAAM;AAAA,sBAC/C,gBAAAA;AAAA,wBAAC;AAAA;AAAA,0BACC,WAAU;AAAA,0BACV,OAAO,EAAE,YAAY,sBAAsB;AAAA,0BAE1C,uBAAa;AAAA;AAAA,sBAChB;AAAA,sBACC,SACC,gBAAAA,MAAC,UAAK,WAAU,sGAAqG,uBAErH,IACE;AAAA,uBACN;AAAA,oBACC,aAAa,SAAS,IACrB,gBAAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,cAAY,GAAG,aAAa,MAAM;AAAA,wBAClC,WAAU;AAAA,wBAET,uBAAa;AAAA;AAAA,oBAChB,IACE;AAAA,qBACN;AAAA;AAAA;AAAA,YACF;AAAA,YAOA,gBAAAC;AAAA,cAAC;AAAA;AAAA,gBACC,IAAI;AAAA,gBACJ,MAAK;AAAA,gBACL,cAAY,aAAa;AAAA,gBACzB,cAAY;AAAA,gBACZ,OAAO,OAAO,SAAY;AAAA,gBAC1B,WAAU;AAAA,gBACV,OAAO;AAAA,kBACL,WAAW,qBAAqB,IAAI;AAAA,kBACpC,WAAW,OAAO,SAAS;AAAA,kBAC3B,YAAY;AAAA,gBACd;AAAA,gBAEC;AAAA,wBAAM,SAAS,IACd,gBAAAD;AAAA,oBAAC;AAAA;AAAA,sBACC,MAAK;AAAA,sBACL,cAAW;AAAA,sBACX,WAAU;AAAA,sBAET,gBAAM,IAAI,CAAC,SACV,gBAAAC;AAAA,wBAAC;AAAA;AAAA,0BAEC,MAAK;AAAA,0BACL,MAAK;AAAA,0BACL,iBAAe,KAAK,OAAO,aAAa;AAAA,0BACxC,eAAa,KAAK,UAAU;AAAA,0BAC5B,kBAAgB,KAAK;AAAA,0BACrB,SAAS,MAAM,YAAY,KAAK,EAAE;AAAA,0BAClC,WAAWS;AAAA,4BACT;AAAA,4BACA,KAAK,OAAO,aAAa,KACrB,6CACA;AAAA,4BACJ,KAAK,UAAU,KAAK,OAAO,aAAa,KACpC,wBACA;AAAA,0BACN;AAAA,0BAEC;AAAA,iCAAK;AAAA,4BAAM;AAAA,4BAAG,KAAK;AAAA,4BAAM;AAAA;AAAA;AAAA,wBAjBrB,KAAK;AAAA,sBAkBZ,CACD;AAAA;AAAA,kBACH,IACE;AAAA,kBACJ,gBAAAV;AAAA,oBAAC;AAAA;AAAA,sBACC,WAAU;AAAA,sBACV,OAAO;AAAA,wBACL,eAAe;AAAA,sBACjB;AAAA,sBAEC,uBAAa;AAAA;AAAA,kBAChB;AAAA;AAAA;AAAA,YACF;AAAA;AAAA;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;;;ACnXA,SAAS,UAAAW,SAAQ,mBAAAC,wBAAuB;AACxC,SAAS,QAAAC,cAAY;AAqET,gBAAAC,aAAA;AA9CL,SAAS,SAA+C;AAAA,EAC7D;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA,SAAS;AAAA,EACT,cAAc;AAAA,EACd;AAAA,EACA,cAAc,YAAY;AAAA,EAC1B;AACF,GAA4B;AAC1B,QAAM,QAAQ,SAAS;AACvB,QAAM,gBAAgB,MAAM,OAAO,kBAAkB;AACrD,QAAM,eAAe,SAAS,MAAM,OAAO,MAAM,IAAI;AAErD,QAAM,gBAAgB;AAAA,IACpB,MAAM;AAAA,IACN,KAAK;AAAA,EACP;AAEA,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAWC;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACA,OAAO;AAAA,QACL,YAAY,MAAM,SAAS,QAAQ;AAAA,QACnC,QAAQ,cAAc,MAAM,SAAS,OAAO,OAAO;AAAA,QACnD,cAAc,MAAM,OAAO;AAAA,QAC3B,YAAY,MAAM,WAAW,WAAW;AAAA,QACxC,OAAO,MAAM,SAAS,KAAK;AAAA,MAC7B;AAAA,MACA,MAAK;AAAA,MACL,cAAY,GAAG,SAAS,MAAM,aAAa,MAAM,QAAQ,aAAa,WAAW,IAAI,MAAM,EAAE;AAAA,MAE7F,0BAAAD,MAACE,kBAAA,EAAgB,MAAK,aACnB,uBAAa,WAAW,IACvB,gBAAAF;AAAA,QAACG,QAAO;AAAA,QAAP;AAAA,UACC,WAAU;AAAA,UACV,SAAS,EAAE,SAAS,EAAE;AAAA,UACtB,SAAS,EAAE,SAAS,EAAE;AAAA,UACtB,MAAM,EAAE,SAAS,EAAE;AAAA,UACnB,MAAK;AAAA,UACL,aAAU;AAAA,UAEV,0BAAAH;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,GAAG,UAAU,OAAO,EAAE,SAAS,WAAW,MAAM,KAAK,CAAC;AAAA,gBACtD,UAAU,MAAM,WAAW,SAAS;AAAA,gBACpC,cAAc,MAAM,MAAM,CAAC;AAAA,gBAC3B,eAAe,MAAM,MAAM,CAAC;AAAA,cAC9B;AAAA,cACD;AAAA;AAAA,UAED;AAAA;AAAA,MACF,IAEA,gBAAAA,MAAC,SAAI,WAAW,cAAc,MAAM,GACjC,uBAAa,IAAI,CAAC,MAAM,UACvB,gBAAAA;AAAA,QAACG,QAAO;AAAA,QAAP;AAAA,UAEC,QAAQ,CAAC;AAAA,UACT,SACE,gBACI,EAAE,SAAS,GAAG,OAAO,EAAE,IACvB,EAAE,SAAS,GAAG,OAAO,IAAI;AAAA,UAE/B,SAAS,EAAE,SAAS,GAAG,OAAO,EAAE;AAAA,UAChC,MAAM,EAAE,SAAS,GAAG,OAAO,IAAI;AAAA,UAC/B,YAAY;AAAA,YACV,MAAM;AAAA,YACN,WAAW;AAAA,YACX,SAAS;AAAA,YACT,OAAO,gBAAgB,IAAI,QAAQ;AAAA,UACrC;AAAA,UAEC,yBAAe,cACd,gBAAAH;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,cAAY,KAAK,QAAQ,QAAQ,KAAK,EAAE;AAAA,cACxC,SAAS,MAAM,YAAY,KAAK,EAAE;AAAA,cAClC,WAAW,CAAC,UAAU;AACpB,oBAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAK;AAC9C,wBAAM,eAAe;AACrB,8BAAY,KAAK,EAAE;AAAA,gBACrB;AAAA,cACF;AAAA,cACA,WAAU;AAAA,cACV,OAAO,EAAE,KAAK,SAAS,QAAQ,UAAU;AAAA,cAEzC,0BAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC;AAAA,kBACA,MAAM;AAAA,kBACN,eAAe;AAAA;AAAA,cACjB;AAAA;AAAA,UACF,IAEA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC;AAAA,cACA,MAAM;AAAA,cACN,eAAe;AAAA,cACf,UAAU,CAAC;AAAA;AAAA,UACb;AAAA;AAAA,QA1CG,KAAK;AAAA,MA4CZ,CACD,GACH,GAEJ;AAAA;AAAA,EACF;AAEJ;;;AC3IA,SAAS,UAAAI,eAAc;AACvB,SAAS,QAAAC,cAAY;AACrB,SAAS,eAAe;AA0BpB,gBAAAC,OA6CE,QAAAC,aA7CF;AAxBJ,IAAM,qBAAqB,CAAC,UAAU,UAAU,UAAU,UAAU,QAAQ;AAC5E,IAAM,uBAAuB,CAAC,YAAY,YAAY,YAAY,UAAU;AAC5E,IAAM,qBAAqB;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAOA,SAAS,YAAY;AAAA,EACnB;AAAA,EACA,UAAU;AACZ,GAGG;AACD,SACE,gBAAAD;AAAA,IAACF,QAAO;AAAA,IAAP;AAAA,MACC,WAAWC,OAAK,wBAAwB,SAAS;AAAA,MACjD,SACE,UACI;AAAA,QACE,SAAS,CAAC,KAAK,GAAG,GAAG;AAAA,MACvB,IACA;AAAA,MAEN,YAAY;AAAA,QACV,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,MAAM;AAAA,MACR;AAAA,MACA,eAAY;AAAA;AAAA,EACd;AAEJ;AAEA,SAAS,aAAa,EAAE,OAAO,KAAK,GAAkC;AACpE,QAAM,cAAc;AAAA,IAClB,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EACN;AAEA,SACE,gBAAAC;AAAA,IAACF,QAAO;AAAA,IAAP;AAAA,MACC,WAAWC;AAAA,QACT;AAAA,QACA,YAAY,IAAI;AAAA,MAClB;AAAA,MACA,SAAS,EAAE,SAAS,GAAG,GAAG,GAAG;AAAA,MAC7B,SAAS,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,MAC5B,YAAY,EAAE,MAAM,UAAU,WAAW,KAAK,SAAS,GAAG;AAAA,MAE1D,0BAAAC,MAAC,eAAY,WAAU,iBAAgB;AAAA;AAAA,EACzC;AAEJ;AAEA,SAAS,iBAAiB;AACxB,SACE,gBAAAC,MAAC,SAAI,WAAU,gFACb;AAAA,oBAAAD,MAAC,eAAY,WAAU,0CAAyC;AAAA,IAChE,gBAAAC,MAAC,SAAI,WAAU,oBACb;AAAA,sBAAAD,MAAC,eAAY,WAAU,oBAAmB;AAAA,MAC1C,gBAAAA,MAAC,eAAY,WAAU,oBAAmB;AAAA,OAC5C;AAAA,KACF;AAEJ;AAEO,SAAS,aAAa;AAAA,EAC3B,UAAU;AAAA,EACV,UAAU;AAAA,EACV;AACF,GAAsB;AACpB,MAAI,YAAY,WAAW;AACzB,WACE,gBAAAC;AAAA,MAAC;AAAA;AAAA,QACC,WAAWF;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACA,MAAK;AAAA,QACL,aAAU;AAAA,QACV,cAAY;AAAA,QAEZ;AAAA,0BAAAC;AAAA,YAACF,QAAO;AAAA,YAAP;AAAA,cACC,SAAS,EAAE,QAAQ,IAAI;AAAA,cACvB,YAAY,EAAE,UAAU,GAAG,QAAQ,UAAU,MAAM,SAAS;AAAA,cAE5D,0BAAAE,MAAC,WAAQ,MAAM,IAAI,WAAU,iBAAgB,eAAY,QAAO;AAAA;AAAA,UAClE;AAAA,UACA,gBAAAA;AAAA,YAACF,QAAO;AAAA,YAAP;AAAA,cACC,WAAU;AAAA,cACV,SAAS,EAAE,SAAS,EAAE;AAAA,cACtB,SAAS,EAAE,SAAS,EAAE;AAAA,cACtB,YAAY,EAAE,OAAO,IAAI;AAAA,cAExB;AAAA;AAAA,UACH;AAAA;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,MAAI,YAAY,SAAS;AACvB,WACE,gBAAAG;AAAA,MAAC;AAAA;AAAA,QACC,WAAWF;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACA,MAAK;AAAA,QACL,aAAU;AAAA,QACV,cAAY;AAAA,QAEZ;AAAA,0BAAAC,MAAC,SAAI,WAAU,4BACZ,6BAAmB,IAAI,CAAC,KAAK,MAC5B,gBAAAA;AAAA,YAACF,QAAO;AAAA,YAAP;AAAA,cAEC,SAAS,EAAE,SAAS,GAAG,GAAG,GAAG;AAAA,cAC7B,SAAS,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,cAC5B,YAAY,EAAE,OAAO,IAAI,IAAI;AAAA,cAE7B,0BAAAE,MAAC,gBAAa;AAAA;AAAA,YALT;AAAA,UAMP,CACD,GACH;AAAA,UACA,gBAAAA;AAAA,YAACF,QAAO;AAAA,YAAP;AAAA,cACC,WAAU;AAAA,cACV,SAAS,EAAE,SAAS,EAAE;AAAA,cACtB,SAAS,EAAE,SAAS,EAAE;AAAA,cACtB,YAAY,EAAE,OAAO,IAAI;AAAA,cAExB;AAAA;AAAA,UACH;AAAA;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,MAAI,YAAY,WAAW;AACzB,WACE,gBAAAG;AAAA,MAAC;AAAA;AAAA,QACC,WAAWF;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACA,MAAK;AAAA,QACL,aAAU;AAAA,QACV,cAAY;AAAA,QAEZ;AAAA,0BAAAC,MAAC,SAAI,WAAU,kCACZ,+BAAqB,IAAI,CAAC,KAAK,MAC9B,gBAAAA;AAAA,YAACF,QAAO;AAAA,YAAP;AAAA,cAEC,SAAS,EAAE,SAAS,GAAG,GAAG,IAAI;AAAA,cAC9B,SAAS,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,cAC5B,YAAY,EAAE,OAAO,IAAI,IAAI;AAAA,cAE7B,0BAAAE,MAAC,kBAAe;AAAA;AAAA,YALX;AAAA,UAMP,CACD,GACH;AAAA,UACA,gBAAAA;AAAA,YAACF,QAAO;AAAA,YAAP;AAAA,cACC,WAAU;AAAA,cACV,SAAS,EAAE,SAAS,EAAE;AAAA,cACtB,SAAS,EAAE,SAAS,EAAE;AAAA,cACtB,YAAY,EAAE,OAAO,IAAI;AAAA,cAExB;AAAA;AAAA,UACH;AAAA;AAAA;AAAA,IACF;AAAA,EAEJ;AAGA,SACE,gBAAAG;AAAA,IAAC;AAAA;AAAA,MACC,WAAWF;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACA,MAAK;AAAA,MACL,aAAU;AAAA,MACV,cAAY;AAAA,MAGZ;AAAA,wBAAAE,MAAC,SAAI,WAAU,kDACb;AAAA,0BAAAD,MAAC,eAAY,WAAU,oBAAmB;AAAA,UAC1C,gBAAAA,MAAC,eAAY,WAAU,oBAAmB;AAAA,WAC5C;AAAA,QAGA,gBAAAA,MAAC,SAAI,WAAU,+DACZ,+BAAqB,IAAI,CAAC,KAAK,MAC9B,gBAAAA;AAAA,UAACF,QAAO;AAAA,UAAP;AAAA,YAEC,SAAS,EAAE,SAAS,GAAG,OAAO,IAAI;AAAA,YAClC,SAAS,EAAE,SAAS,GAAG,OAAO,EAAE;AAAA,YAChC,YAAY,EAAE,OAAO,IAAI,IAAI;AAAA,YAE7B,0BAAAE,MAAC,kBAAe;AAAA;AAAA,UALX;AAAA,QAMP,CACD,GACH;AAAA,QAGA,gBAAAA,MAAC,SAAI,WAAU,gBACb,0BAAAA,MAAC,eAAY,WAAU,mCAAkC,GAC3D;AAAA,QAGA,gBAAAA,MAAC,SAAI,WAAU,sCACZ,6BAAmB,IAAI,CAAC,KAAK,MAC5B,gBAAAA;AAAA,UAACF,QAAO;AAAA,UAAP;AAAA,YAEC,SAAS,EAAE,SAAS,GAAG,GAAG,GAAG;AAAA,YAC7B,SAAS,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,YAC5B,YAAY,EAAE,OAAO,MAAM,IAAI,KAAK;AAAA,YAEpC,0BAAAE,MAAC,gBAAa;AAAA;AAAA,UALT;AAAA,QAMP,CACD,GACH;AAAA,QAGA,gBAAAC;AAAA,UAACH,QAAO;AAAA,UAAP;AAAA,YACC,WAAU;AAAA,YACV,SAAS,EAAE,SAAS,EAAE;AAAA,YACtB,SAAS,EAAE,SAAS,EAAE;AAAA,YACtB,YAAY,EAAE,OAAO,IAAI;AAAA,YAEzB;AAAA,8BAAAE;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAM;AAAA,kBACN,WAAU;AAAA,kBACV,eAAY;AAAA;AAAA,cACd;AAAA,cACA,gBAAAA,MAAC,OAAE,WAAU,mDACV,mBACH;AAAA;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF;AAEJ;;;ACxPA,SAAS,UAAAE,SAAQ,mBAAAC,wBAAuB;AACxC,SAAS,GAAG,aAAa,aAAa,MAAM,qBAAqB;;;ACC7D,gBAAAC,aAAA;AANG,SAAS,MAAM;AAAA,EACpB;AAAA,EACA,UAAU;AAAA,EACV,GAAG;AACL,GAAe;AACb,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,MAAK;AAAA,MACL,WAAW;AAAA,QACT;AAAA,QACA,YAAY,iBAAiB;AAAA,QAC7B;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAeO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA,GAAG;AACL,GAAgC;AAC9B,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,kCAAkC,SAAS;AAAA,MACxD,GAAG;AAAA;AAAA,EACN;AAEJ;;;ADpCA;AAAA,EACE,iBAAAC;AAAA,EACA,cAAAC;AAAA,EACA,YAAAC;AAAA,EACA,eAAAC;AAAA,OAEK;AAsFH,SAsBK,YAAAC,WAlBH,OAAAC,OAJF,QAAAC,aAAA;AA7DJ,IAAM,eAAeC,eAAwC,IAAI;AAQ1D,SAAS,cAAc,EAAE,SAAS,GAAuB;AAC9D,QAAM,CAAC,QAAQ,SAAS,IAAIC,WAA8B,CAAC,CAAC;AAE5D,QAAM,OAAOC;AAAA,IACX,CAAC,SAAiB,OAAkB,QAAQ,WAAW,QAAS;AAC9D,YAAM,KAAK,SAAS,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC;AAC/C,YAAM,QAA2B,EAAE,IAAI,MAAM,SAAS,SAAS;AAE/D,gBAAU,CAAC,SAAS;AAMlB,YACE,KAAK,KAAK,CAAC,SAAS,KAAK,SAAS,QAAQ,KAAK,YAAY,OAAO,GAClE;AACA,iBAAO;AAAA,QACT;AACA,eAAO,CAAC,GAAG,MAAM,KAAK;AAAA,MACxB,CAAC;AAED,UAAI,WAAW,GAAG;AAChB,mBAAW,MAAM;AACf,oBAAU,CAAC,SAAS,KAAK,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;AAAA,QACrD,GAAG,QAAQ;AAAA,MACb;AAAA,IACF;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,UAAUA,aAAY,CAAC,OAAe;AAC1C,cAAU,CAAC,SAAS,KAAK,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;AAAA,EACrD,GAAG,CAAC,CAAC;AAEL,QAAM,UAAUA;AAAA,IACd,CAAC,SAAiB,aAAsB,KAAK,SAAS,WAAW,QAAQ;AAAA,IACzE,CAAC,IAAI;AAAA,EACP;AACA,QAAM,QAAQA;AAAA,IACZ,CAAC,SAAiB,aAAsB,KAAK,SAAS,SAAS,QAAQ;AAAA,IACvE,CAAC,IAAI;AAAA,EACP;AACA,QAAM,OAAOA;AAAA,IACX,CAAC,SAAiB,aAAsB,KAAK,SAAS,QAAQ,QAAQ;AAAA,IACtE,CAAC,IAAI;AAAA,EACP;AACA,QAAM,UAAUA;AAAA,IACd,CAAC,SAAiB,aAAsB,KAAK,SAAS,WAAW,QAAQ;AAAA,IACzE,CAAC,IAAI;AAAA,EACP;AAEA,SACE,gBAAAH;AAAA,IAAC,aAAa;AAAA,IAAb;AAAA,MACC,OAAO,EAAE,QAAQ,MAAM,SAAS,SAAS,OAAO,MAAM,QAAQ;AAAA,MAE7D;AAAA;AAAA,QACD,gBAAAD,MAAC,kBAAe,QAAgB,WAAW,SAAS;AAAA;AAAA;AAAA,EACtD;AAEJ;AAEO,SAAS,WAAW;AACzB,QAAM,UAAUK,YAAW,YAAY;AACvC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,4CAA4C;AAAA,EAC9D;AACA,SAAO;AACT;AAMO,SAAS,aAAa,EAAE,SAAS,GAAsB;AAC5D,SAAO,gBAAAL,MAAAD,WAAA,EAAG,mBAAS,SAAS,CAAC,GAAE;AACjC;AAEO,IAAM,QAAQ;AAAA,EACnB,SAAS;AACX;AAEA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA;AACF,GAGG;AACD,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,MAAK;AAAA,MACL,aAAU;AAAA,MACV,cAAW;AAAA,MAEX,0BAAAA,MAACM,kBAAA,EACE,iBAAO,IAAI,CAAC,UACX,gBAAAN,MAAC,aAAyB,OAAc,aAAxB,MAAM,EAAwC,CAC/D,GACH;AAAA;AAAA,EACF;AAEJ;AAEA,IAAM,cAAc;AAAA,EAClB,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AAAA,EACN,SAAS;AACX;AAEA,IAAM,gBAGF;AAAA,EACF,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AAAA,EACN,SAAS;AACX;AAEA,SAAS,kBAAkB,OAAc,MAAsC;AAC7E,QAAM,SAAS,iBAAiB,OAAO,cAAc,IAAI,CAAC;AAC1D,SAAO;AAAA,IACL,UAAU;AAAA,IACV,UAAU;AAAA,IACV,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,KAAK,MAAM,MAAM,CAAC;AAAA,IAClB,SAAS,MAAM,MAAM,CAAC;AAAA,IACtB,YAAY,OAAO;AAAA,IACnB,OAAO,OAAO;AAAA,IACd,QAAQ,aAAa,OAAO,MAAM;AAAA,IAClC,cAAc,MAAM,OAAO;AAAA,IAC3B,WAAW,MAAM,UAAU;AAAA,IAC3B,gBAAgB;AAAA,IAChB,sBAAsB;AAAA,IACtB,YAAY,MAAM,WAAW,WAAW;AAAA,EAC1C;AACF;AAEA,SAAS,UAAU;AAAA,EACjB;AAAA,EACA;AACF,GAGG;AACD,QAAM,QAAQ,SAAS;AACvB,QAAM,gBAAgB,MAAM,OAAO,kBAAkB;AACrD,QAAMO,QAAO,YAAY,MAAM,IAAI;AACnC,QAAM,SAAS,iBAAiB,OAAO,cAAc,MAAM,IAAI,CAAC;AAChE,QAAMC,gBAAe,kBAAkB,OAAO,MAAM,IAAI;AAExD,SACE,gBAAAR;AAAA,IAACS,QAAO;AAAA,IAAP;AAAA,MACC,OAAO,EAAE,eAAe,OAAO;AAAA,MAC/B,SACE,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,GAAG,IAAI,OAAO,IAAI;AAAA,MAEnE,SAAS,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,GAAG,GAAG,OAAO,EAAE;AAAA,MACvE,MAAM,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,GAAG,KAAK,OAAO,IAAI;AAAA,MACxE,YAAY,EAAE,MAAM,UAAU,WAAW,KAAK,SAAS,GAAG;AAAA,MAE1D,0BAAAR;AAAA,QAAC;AAAA;AAAA,UACC,SAAS,MAAM,SAAS,UAAU,gBAAgB;AAAA,UAClD,OAAOO;AAAA,UAEP;AAAA,4BAAAR;AAAA,cAACO;AAAA,cAAA;AAAA,gBACC,MAAM;AAAA,gBACN,OAAO;AAAA,kBACL,WAAW;AAAA,kBACX,YAAY;AAAA,kBACZ,OAAO,OAAO;AAAA,gBAChB;AAAA,gBACA,eAAY;AAAA;AAAA,YACd;AAAA,YAEA,gBAAAP;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,kBACL,MAAM;AAAA,kBACN,UAAU,MAAM,WAAW,SAAS;AAAA,kBACpC,YAAY,MAAM,WAAW,WAAW;AAAA,kBACxC,YAAY,MAAM,WAAW,WAAW;AAAA,kBACxC,OAAO,OAAO;AAAA,gBAChB;AAAA,gBAEC,gBAAM;AAAA;AAAA,YACT;AAAA,YAEA,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,SAAS,MAAM,UAAU,MAAM,EAAE;AAAA,gBACjC,OAAO;AAAA,kBACL,QAAQ;AAAA,kBACR,OAAO;AAAA,kBACP,YAAY;AAAA,kBACZ,cAAc,MAAM,OAAO;AAAA,kBAC3B,OAAO,OAAO;AAAA,gBAChB;AAAA,gBACA,cAAW;AAAA,gBAEX,0BAAAA,MAAC,KAAE,MAAM,IAAI,eAAY,QAAO;AAAA;AAAA,YAClC;AAAA;AAAA;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;;;AE3PA;AAAA,EACE;AAAA,OAIK;AACP,SAAS,iBAAAU,gBAAe,iBAAiB;AA4CjC,SAqMM,YAAAC,WArMN,OAAAC,OAqMM,QAAAC,aArMN;AA9BD,IAAM,gBAAN,cAA4B,UAGjC;AAAA,EACA,YAAY,OAA2B;AACrC,UAAM,KAAK;AACX,SAAK,QAAQ,EAAE,UAAU,OAAO,OAAO,KAAK;AAAA,EAC9C;AAAA,EAEA,OAAO,yBAAyB,OAAkC;AAChE,WAAO,EAAE,UAAU,MAAM,MAAM;AAAA,EACjC;AAAA,EAEA,kBAAkB,OAAc,WAA4B;AAE1D,YAAQ,MAAM,iCAAiC,OAAO,SAAS;AAC/D,SAAK,MAAM,UAAU,OAAO,SAAS;AAAA,EACvC;AAAA,EAEA,cAAc,MAAY;AACxB,SAAK,SAAS,EAAE,UAAU,OAAO,OAAO,KAAK,CAAC;AAAA,EAChD;AAAA,EAEA,SAAoB;AAClB,QAAI,KAAK,MAAM,YAAY,KAAK,MAAM,OAAO;AAC3C,UAAI,KAAK,MAAM,UAAU;AACvB,eAAO,KAAK,MAAM,SAAS,KAAK,MAAM,OAAO,KAAK,WAAW;AAAA,MAC/D;AAEA,aACE,gBAAAD;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,KAAK,MAAM;AAAA,UAClB,SAAS,KAAK;AAAA;AAAA,MAChB;AAAA,IAEJ;AAEA,WAAO,KAAK,MAAM;AAAA,EACpB;AACF;AASA,IAAM,kBAAkB;AAAA,EACtB,YAAY,SAAS,WAAW,YAAY,WAAW,KAAK;AAAA,EAC5D,cAAc,SAAS,WAAW,YAAY,WAAW,MAAM;AAAA,EAC/D,cAAc,SAAS,WAAW,YAAY,WAAW,OAAO;AAAA,EAChE,aAAa,SAAS,WAAW,YAAY,QAAQ,SAAS;AAAA,EAC9D,WAAW,SAAS,WAAW,YAAY,QAAQ,OAAO;AAAA,EAC1D,cAAc,SAAS,WAAW,YAAY,QAAQ,UAAU;AAAA,EAChE,cAAc,SAAS,WAAW,YAAY,UAAU,QAAQ;AAAA,EAChE,eAAe,SAAS,WAAW,YAAY,UAAU,SAAS;AAAA,EAClE,YAAY,SAAS,WAAW,YAAY,UAAU,UAAU,MAAM;AAAA,EACtE,cAAc,SAAS,WAAW,YAAY,UAAU,UAAU,QAAQ;AAAA,EAC1E,cAAc,SAAS,WAAW,YAAY,UAAU,UAAU,QAAQ;AAAA,EAC1E,cAAc,SAAS,WAAW,YAAY,UAAU,WAAW,OAAO;AAAA,EAC1E,WAAW,SAAS,WAAW,YAAY,UAAU,WAAW,IAAI;AAAA,EACpE,eAAe,SAAS,WAAW,YAAY,UAAU,WAAW,QAAQ;AAAA,EAC5E,UAAU;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,aAAa;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,UAAU;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,UAAU,SAAS,OAAO,UAAU,IAAI;AAAA,EACxC,UAAU,SAAS,QAAQ,UAAU,IAAI;AAAA,EACzC,YAAY,SAAS,SAAS,UAAU,MAAM;AAAA,EAC9C,eAAe;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,qBAAqB;AAAA,EACnC;AAAA,EACA;AACF,GAGG;AACD,QAAM,IAAI;AACV,QAAM,SAAS;AAAA,IACb,OAAO;AAAA,MACL,YAAY;AAAA,MACZ,YAAY,EAAE;AAAA,MACd,WAAW;AAAA,MACX,OAAO,EAAE;AAAA,MACT,SAAS;AAAA,MACT,YAAY,EAAE;AAAA,MACd,gBAAgB;AAAA,MAChB,WAAW;AAAA,MACX,SAAS;AAAA,IACX;AAAA,IACA,OAAO;AAAA,MACL,YAAY,EAAE;AAAA,MACd,QAAQ,aAAa,EAAE,YAAY;AAAA,MACnC,cAAc,EAAE;AAAA,MAChB,WAAW,EAAE;AAAA,MACb,WAAW;AAAA,MACX,UAAU;AAAA,MACV,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAAA,IACA,UAAU;AAAA,MACR,YAAY;AAAA,MACZ,YAAY,EAAE;AAAA,MACd,QAAQ,aAAa,EAAE,YAAY;AAAA,MACnC,cAAc,EAAE;AAAA,MAChB,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,gBAAgB;AAAA,MAChB,cAAc;AAAA,MACd,OAAO;AAAA,IACT;AAAA,IACA,SAAS;AAAA,MACP,OAAO,EAAE;AAAA,MACT,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,QAAQ;AAAA,MACR,eAAe;AAAA,IACjB;AAAA,IACA,OAAO;AAAA,MACL,OAAO,EAAE;AAAA,MACT,YAAY,EAAE;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,QAAQ;AAAA,IACV;AAAA,IACA,MAAM;AAAA,MACJ,OAAO,EAAE;AAAA,MACT,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,QAAQ;AAAA,IACV;AAAA,IACA,SAAS;AAAA,MACP,cAAc;AAAA,IAChB;AAAA,IACA,SAAS;AAAA,MACP,OAAO,EAAE;AAAA,MACT,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,IACA,KAAK;AAAA,MACH,YAAY,EAAE;AAAA,MACd,QAAQ,aAAa,EAAE,aAAa;AAAA,MACpC,cAAc,EAAE;AAAA,MAChB,OAAO,EAAE;AAAA,MACT,YAAY,EAAE;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,UAAU;AAAA,MACV,SAAS;AAAA,MACT,YAAY;AAAA,IACd;AAAA,IACA,QAAQ;AAAA,MACN,YAAY;AAAA,MACZ,YAAY,EAAE;AAAA,MACd,QAAQ,aAAa,EAAE,aAAa;AAAA,MACpC,cAAc,EAAE;AAAA,MAChB,OAAO,EAAE;AAAA,MACT,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,YAAY,EAAE;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,KAAK;AAAA,MACL,gBAAgB;AAAA,MAChB,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAAA,EACF;AAEA,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,kCAA+B;AAAA,MAC/B,OAAO,OAAO;AAAA,MACd,MAAK;AAAA,MACL,aAAU;AAAA,MAEV,0BAAAC,MAAC,SAAI,OAAO,OAAO,OACjB;AAAA,wBAAAD,MAAC,SAAI,OAAO,OAAO,UACjB,0BAAAA;AAAA,UAACE;AAAA,UAAA;AAAA,YACC,MAAM;AAAA,YACN,OAAO,EAAE;AAAA,YACT,aAAa;AAAA,YACb,eAAY;AAAA;AAAA,QACd,GACF;AAAA,QAEA,gBAAAF,MAAC,OAAE,OAAO,OAAO,SAAS,2BAAa;AAAA,QAEvC,gBAAAA,MAAC,QAAG,OAAO,OAAO,OAAO,kCAAoB;AAAA,QAE7C,gBAAAA,MAAC,OAAE,OAAO,OAAO,MAAM,wGAGvB;AAAA,QAEA,gBAAAC,MAAC,aAAQ,OAAO,OAAO,SACrB;AAAA,0BAAAD,MAAC,aAAQ,OAAO,OAAO,SAAS,+BAAiB;AAAA,UACjD,gBAAAC,MAAC,SAAI,OAAO,OAAO,KAChB;AAAA,kBAAM;AAAA,YACN,MAAM,SACL,gBAAAA,MAAAF,WAAA,EACG;AAAA;AAAA,cACA,MAAM;AAAA,eACT;AAAA,aAEJ;AAAA,WACF;AAAA,QAEA,gBAAAE,MAAC,YAAO,MAAK,UAAS,SAAS,SAAS,OAAO,OAAO,QACpD;AAAA,0BAAAD,MAAC,aAAU,MAAM,IAAI,eAAY,QAAO;AAAA,UAAE;AAAA,WAE5C;AAAA,SACF;AAAA;AAAA,EACF;AAEJ;;;AC/QA,YAAY,qBAAqB;AACjC,SAAS,aAAa;AAMb,gBAAAG,OAyDC,QAAAC,cAzDD;AAHF,SAAS,OACd,OACA;AACA,SAAO,gBAAAD,MAAiB,sBAAhB,EAAqB,aAAU,UAAU,GAAG,OAAO;AAC7D;AAEO,SAAS,cACd,OACA;AACA,SAAO,gBAAAA,MAAiB,yBAAhB,EAAwB,aAAU,kBAAkB,GAAG,OAAO;AACxE;AAEO,SAAS,aACd,OACA;AACA,SAAO,gBAAAA,MAAiB,wBAAhB,EAAuB,aAAU,iBAAiB,GAAG,OAAO;AACtE;AAEO,SAAS,YACd,OACA;AACA,SAAO,gBAAAA,MAAiB,uBAAhB,EAAsB,aAAU,gBAAgB,GAAG,OAAO;AACpE;AAEO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA,GAAG;AACL,GAAyD;AACvD,SACE,gBAAAA;AAAA,IAAiB;AAAA,IAAhB;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,kCAAkC,SAAS;AAAA,MACxD,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA,kBAAkB;AAAA,EAClB;AAAA,EACA,GAAG;AACL,GAGG;AACD,SACE,gBAAAC,OAAC,gBACC;AAAA,oBAAAD,MAAC,iBAAc,WAAW,kBAAkB;AAAA,IAC5C,gBAAAC;AAAA,MAAiB;AAAA,MAAhB;AAAA,QACC,aAAU;AAAA,QACV,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEH;AAAA;AAAA,UACA,kBACC,gBAAAA;AAAA,YAAiB;AAAA,YAAhB;AAAA,cACC,aAAU;AAAA,cACV,WAAU;AAAA,cAEV;AAAA,gCAAAD,MAAC,SAAM,eAAY,QAAO,WAAU,UAAS;AAAA,gBAC7C,gBAAAA,MAAC,UAAK,WAAU,WAAU,mBAAK;AAAA;AAAA;AAAA,UACjC,IACE;AAAA;AAAA;AAAA,IACN;AAAA,KACF;AAEJ;AAEO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA,GAAG;AACL,GAAgC;AAC9B,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,gDAAgD,SAAS;AAAA,MACtE,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA,GAAG;AACL,GAAgC;AAC9B,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA,GAAG;AACL,GAAuD;AACrD,SACE,gBAAAA;AAAA,IAAiB;AAAA,IAAhB;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,sCAAsC,SAAS;AAAA,MAC5D,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA,GAAG;AACL,GAA6D;AAC3D,SACE,gBAAAA;AAAA,IAAiB;AAAA,IAAhB;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,0BAA0B,SAAS;AAAA,MAChD,GAAG;AAAA;AAAA,EACN;AAEJ;;;AC5HI,gBAAAE,aAAA;AANG,SAAS,MAAM;AAAA,EACpB;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAkC;AAChC,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;;;ACjBA,YAAY,oBAAoB;AAQ5B,gBAAAC,aAAA;AALG,SAAS,MAAM;AAAA,EACpB;AAAA,EACA,GAAG;AACL,GAAqD;AACnD,SACE,gBAAAA;AAAA,IAAgB;AAAA,IAAf;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;;;ACjBA,YAAY,qBAAqB;AACjC,SAAS,WAAW,iBAAiB,qBAAqB;AAMjD,gBAAAC,OAYL,QAAAC,cAZK;AAHF,SAAS,OACd,OACA;AACA,SAAO,gBAAAD,MAAiB,sBAAhB,EAAqB,aAAU,UAAU,GAAG,OAAO;AAC7D;AAEO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA,GAAG;AACL,GAEG;AACD,SACE,gBAAAC;AAAA,IAAiB;AAAA,IAAhB;AAAA,MACC,aAAU;AAAA,MACV,aAAW;AAAA,MACX,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA,SAAS,YAAY,QAAQ;AAAA,QAC7B;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,QACD,gBAAAD,MAAiB,sBAAhB,EAAqB,SAAO,MAC3B,0BAAAA,MAAC,mBAAgB,WAAU,qBAAoB,GACjD;AAAA;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,GAAG;AACL,GAAyD;AACvD,SACE,gBAAAA,MAAiB,wBAAhB,EACC,0BAAAC;AAAA,IAAiB;AAAA,IAAhB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,MACC,GAAG;AAAA,MAEJ;AAAA,wBAAAD,MAAC,wBAAqB;AAAA,QACtB,gBAAAA,MAAiB,0BAAhB,EAAyB,WAAU,OACjC,UACH;AAAA,QACA,gBAAAA,MAAC,0BAAuB;AAAA;AAAA;AAAA,EAC1B,GACF;AAEJ;AAEO,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAsD;AACpD,SACE,gBAAAC;AAAA,IAAiB;AAAA,IAAhB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEJ;AAAA,wBAAAD,MAAC,UAAK,WAAU,8DACd,0BAAAA,MAAiB,+BAAhB,EACC,0BAAAA,MAAC,aAAU,WAAU,UAAS,GAChC,GACF;AAAA,QACA,gBAAAA,MAAiB,0BAAhB,EAA0B,UAAS;AAAA;AAAA;AAAA,EACtC;AAEJ;AAEA,SAAS,qBAAqB;AAAA,EAC5B;AAAA,EACA,GAAG;AACL,GAAgE;AAC9D,SACE,gBAAAA;AAAA,IAAiB;AAAA,IAAhB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEJ,0BAAAA,MAAC,iBAAc,WAAU,UAAS;AAAA;AAAA,EACpC;AAEJ;AAEA,SAAS,uBAAuB;AAAA,EAC9B;AAAA,EACA,GAAG;AACL,GAAkE;AAChE,SACE,gBAAAA;AAAA,IAAiB;AAAA,IAAhB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEJ,0BAAAA,MAAC,mBAAgB,WAAU,UAAS;AAAA;AAAA,EACtC;AAEJ;;;AChIA;AAAA,EACE,iBAAAE;AAAA,EACA;AAAA,EACA,cAAAC;AAAA,EACA,WAAAC;AAAA,OAKK;AA2GH,gBAAAC,aAAA;AA9BJ,IAAM,6BACJC,eAAuD,IAAI;AAE7D,SAAS,gCAAyD;AAChE,QAAM,QAAQC,YAAW,0BAA0B;AACnD,MAAI,CAAC,OAAO;AACV,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,mBACP,MACA,QAA2B,CAAC,GAC5B;AACA,MAAI,OAAO,SAAS,YAAY;AAC9B,WAAO,cAAc,MAAM;AAAA,MACzB,eAAe;AAAA,MACf,aAAa;AAAA,MACb,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AACA,QAAM;AAAA,IACJ,aAAa;AAAA,IACb,eAAe;AAAA,IACf,GAAG;AAAA,EACL,IAAI;AACJ,SACE,gBAAAF;AAAA,IAAC;AAAA;AAAA,MACC,eAAa,eAAe,SAAY,OAAO,eAAe;AAAA,MAC7D,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;AAEA,SAAS,wBACP,UACA,UACA;AACA,SAAO,OAAO,aAAa,aAAa,SAAS,QAAQ,IAAI;AAC/D;AAEO,SAAS,oBAA0D;AAAA,EACxE;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,GAAG;AACL,GAAuC;AACrC,QAAM,QAAQG;AAAA,IACZ,MACE,UACG,IAAI,CAAC,aAAa;AACjB,YAAM,QAAQ,OAAO,SAAS,IAAI,KAAK;AACvC,aAAO;AAAA,QACL,GAAG;AAAA,QACH;AAAA,QACA,QAAQ,UAAU;AAAA,QAClB,aAAa,QAAQ,eAAe;AAAA,QACpC,QAAQ,MAAM,kBAAkB,SAAS,IAAI;AAAA,QAC7C,YAAY,CAAC,cACX,mBAAmB,SAAS,MAAM,SAAS;AAAA,QAC7C,gBAAgB;AAAA,UACd,oBAAoB,SAAS;AAAA,UAC7B,uBAAuB;AAAA,UACvB,sBAAsB,UAAU,KAAK;AAAA,UACrC,oBAAoB,kBAAkB,OAAO;AAAA,QAC/C;AAAA,MACF;AAAA,IACF,CAAC,EACA,OAAO,CAAC,aAAa,SAAS,UAAU,CAAC,SAAS,MAAM;AAAA,IAC7D,CAAC,QAAQ,iBAAiB,WAAW,IAAI;AAAA,EAC3C;AAEA,SAAO,gBAAgB,OAAO;AAAA,IAC5B,MAAM;AAAA,IACN,cAAc,aAAa;AAAA,IAC3B,oCAAoC;AAAA,IACpC,GAAG;AAAA,IACH,UAAU,MAAM,IAAI,CAAC,aACnB,gBAAAH,MAAC,2BAA2B,UAA3B,EAAwD,OAAO,UAC7D,YADuC,SAAS,IAEnD,CACD;AAAA,EACH,CAAC;AACH;AAEO,SAAS,oBAA0D;AAAA,EACxE;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,GAAG;AACL,GAAuC;AACrC,QAAM,WAAW,8BAAwC;AACzD,SAAO,gBAAgB,QAAQ;AAAA,IAC7B,MAAM;AAAA,IACN,cAAc,aAAa,GAAG,SAAS,KAAK,KAAK,SAAS,KAAK;AAAA,IAC/D,GAAG,SAAS;AAAA,IACZ,GAAG;AAAA,IACH,SAAS;AAAA,MACP;AAAA,MACA,SAAS,cAAc,SAAS,SAAS;AAAA,IAC3C;AAAA,IACA,UAAU,wBAAwB,UAAU,QAAQ;AAAA,EACtD,CAAC;AACH;AAEO,SAAS,oBAA0D;AAAA,EACxE;AAAA,EACA;AAAA,EACA,eAAe;AACjB,GAAiC;AAC/B,QAAM,WAAW,8BAAwC;AACzD,SAAO,SAAS,WAAW;AAAA,IACzB;AAAA,IACA;AAAA,IACA,eAAe;AAAA,EACjB,CAAC;AACH;AAEO,SAAS,qBAA2D;AAAA,EACzE;AAAA,EACA,GAAG;AACL,GAAuC;AACrC,QAAM,WAAW,8BAAwC;AACzD,SAAO,gBAAgB,QAAQ;AAAA,IAC7B,GAAG;AAAA,IACH,kCAAkC;AAAA,IAClC,UAAU,wBAAwB,YAAY,SAAS,OAAO,QAAQ;AAAA,EACxE,CAAC;AACH;AAEO,SAAS,qBAA2D;AAAA,EACzE;AAAA,EACA,GAAG;AACL,GAAuC;AACrC,QAAM,WAAW,8BAAwC;AACzD,SAAO,gBAAgB,QAAQ;AAAA,IAC7B,GAAG;AAAA,IACH,kCAAkC;AAAA,IAClC,UAAU,wBAAwB,YAAY,SAAS,OAAO,QAAQ;AAAA,EACxE,CAAC;AACH;AAYO,SAAS,sBACd,WACqC;AACrC,SAAO;AAAA,IACL,KAAK,OAAO;AACV,aAAO,cAAc,qBAA+B;AAAA,QAClD,GAAG;AAAA,QACH;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AACF;AAEO,IAAM,kBAAkB;AAAA,EAC7B,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AACT;;;AC3QA,SAAS,QAAAI,cAAY;;;ACCrB,YAAY,sBAAsB;AAQ9B,gBAAAC,aAAA;AALG,SAAS,gBAAgB;AAAA,EAC9B,gBAAgB;AAAA,EAChB,GAAG;AACL,GAA2D;AACzD,SACE,gBAAAA;AAAA,IAAkB;AAAA,IAAjB;AAAA,MACC,aAAU;AAAA,MACV;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,QACd,OACA;AACA,SACE,gBAAAA,MAAC,mBACC,0BAAAA,MAAkB,uBAAjB,EAAsB,aAAU,WAAW,GAAG,OAAO,GACxD;AAEJ;AAEO,SAAS,eACd,OACA;AACA,SAAO,gBAAAA,MAAkB,0BAAjB,EAAyB,aAAU,mBAAmB,GAAG,OAAO;AAC1E;AAEO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA,aAAa;AAAA,EACb,GAAG;AACL,GAA0D;AACxD,SACE,gBAAAA,MAAkB,yBAAjB,EACC,0BAAAA;AAAA,IAAkB;AAAA,IAAjB;AAAA,MACC,aAAU;AAAA,MACV;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN,GACF;AAEJ;;;AD8BgB,SAYW,OAAAC,OAZX,QAAAC,cAAA;AAvDT,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,SAAS;AAAA,EACT;AACF,GAAqB;AACnB,QAAM,cAAc,OAAO,YAAY,aAAa,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAE3E,QAAM,cAAc;AAAA,IAClB,IAAI,EAAE,MAAM,WAAW,MAAM,WAAW,KAAK,UAAU;AAAA,IACvD,IAAI,EAAE,MAAM,WAAW,MAAM,WAAW,KAAK,QAAQ;AAAA,EACvD;AAEA,QAAM,SAAS,YAAY,IAAI;AAG/B,QAAM,eACJ,CAAC,oBACD,OAAO,QAAQ,IAAI,EAAE;AAAA,IACnB,CAAC,CAAC,MAAM,MAAM,OAAO,iBAAiB,IAAI,KAAK,MAAM;AAAA,EACvD;AAEF,QAAM,cAAc,OAAO,QAAQ,IAAI,EAAE;AAAA,IACvC,CAAC,CAAC,EAAE,MAAM,MAAM,WAAW,UAAa,SAAS;AAAA,EACnD;AAEA,MAAI,YAAY,WAAW,GAAG;AAC5B,WAAO;AAAA,EACT;AAEA,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,WAAWE;AAAA,QACT;AAAA,QACA,OAAO;AAAA,QACP,WAAW,aAAa;AAAA,QACxB,WAAW,YAAY;AAAA,QACvB;AAAA,MACF;AAAA,MACA,MAAK;AAAA,MACL,cAAY,SAAS,YAAY,IAAI,CAAC,CAAC,MAAM,MAAM,MAAM,GAAG,MAAM,IAAI,YAAY,IAAI,GAAG,SAAS,IAAI,EAAE,EAAE,KAAK,IAAI,CAAC,GAAG,mBAAoB,eAAe,kBAAkB,qBAAsB,EAAE;AAAA,MAEpM,0BAAAF,MAAC,mBAAgB,eAAe,KAC7B,sBAAY,IAAI,CAAC,CAAC,MAAM,MAAM,MAAM;AACnC,cAAM,MAAM,YAAY,IAAI;AAC5B,cAAM,OAAO,mBAAmB,IAAI,KAAK;AACzC,cAAM,YAAY,QAAQ;AAC1B,cAAMG,QAAO,KAAK;AAClB,cAAM,QAAQ,KAAK,SAAS;AAE5B,eACE,gBAAAF,OAAC,WACC;AAAA,0BAAAD,MAAC,kBAAe,SAAO,MACrB,0BAAAC;AAAA,YAAC;AAAA;AAAA,cACC,WAAWC;AAAA,gBACT;AAAA,gBACA,OAAO;AAAA,gBACP,OAAO;AAAA,gBACP,oBAAoB,CAAC,aAAa;AAAA,gBAClC,oBAAoB,aAAa;AAAA,gBACjC,CAAC,oBAAoB;AAAA,cACvB;AAAA,cACA,MAAK;AAAA,cACL,UAAU;AAAA,cAET;AAAA,gBAAAC,SAAQ,gBAAAH,MAACG,OAAA,EAAK,WAAW,OAAO,MAAM,eAAY,QAAO;AAAA,gBAC1D,gBAAAH,MAAC,UAAK,WAAU,iBAAiB,kBAAO;AAAA,gBACvC,CAACG,SACA,gBAAAH,MAAC,UAAK,WAAU,0BACb,eAAK,OAAO,MAAM,GAAG,CAAC,KAAK,KAAK,MAAM,GAAG,CAAC,GAC7C;AAAA;AAAA;AAAA,UAEJ,GACF;AAAA,UACA,gBAAAC;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,YAAY;AAAA,cACZ,WAAU;AAAA,cAEV;AAAA,gCAAAD,MAAC,OAAE,WAAU,+BAA+B,iBAAM;AAAA,gBAClD,gBAAAA,MAAC,OAAE,WAAU,iDACV,iCAAuB;AAAA,kBACtB;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF,CAAC,GACH;AAAA;AAAA;AAAA,UACF;AAAA,aApCY,IAqCd;AAAA,MAEJ,CAAC,GACH;AAAA;AAAA,EACF;AAEJ;AAGA,SAAS,uBAAuB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,MAAI,CAAC,OAAO,SAAS,IAAI,GAAG;AAC1B,WAAO,SAAS,MAAM;AAAA,EACxB;AAEA,QAAM,UAAU,KAAK,IAAI,GAAG,SAAS,IAAI;AACzC,SAAO,YACH,SAAS,MAAM,cAAc,IAAI,MACjC,SAAS,MAAM,cAAc,IAAI,cAAc,OAAO;AAC5D;;;AEjEc,gBAAAI,OACR,QAAAC,cADQ;AAlDP,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAsB;AACpB,QAAM,aAAa,YAAY,WAAW,CAAC;AAC3C,QAAMC,QAAO;AACb,QAAM,gBAAgB,UAAU,CAAC,YAAY,iBAAiB;AAE9D,WAAS,YAAY,OAAsC;AACzD,QAAI,WAAY;AAChB,cAAU,KAAK;AAAA,EACjB;AAEA,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA,UAAU;AAAA,MACV,UAAU,aAAa,aAAa,CAAC,aAAa,SAAY;AAAA,MAC9D;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP,SAAS;AAAA,MACR,GAAG;AAAA,MAEH;AAAA,QAAAC,QAAO,gBAAAF,MAACE,OAAA,EAAK,WAAU,WAAU,eAAY,QAAO,IAAK;AAAA,QAC1D,gBAAAD,OAAC,UAAK,WAAU,oDACd;AAAA,0BAAAD,MAAC,UAAM,sBAAY,SAAS,UAAS;AAAA,UACpC,cACC,gBAAAA,MAAC,UAAK,WAAU,kCAAkC,uBAAY,IAC5D;AAAA,UACH,QAAQ,eACP,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC;AAAA,cACA;AAAA,cACA;AAAA;AAAA,UACF,IACE;AAAA,WACN;AAAA,QACC,UAAU,gBAAAA,MAAC,UAAK,eAAY,QAAO,iBAAG,IAAU;AAAA;AAAA;AAAA,EACnD;AAEJ;;;AC/DI,gBAAAG,aAAA;AATG,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,OAAO;AAAA,EACP,GAAG;AACL,GAAuB;AACrB,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;;;AClBA;AAAA,EACE,aAAAC;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,OAIK;AACP,SAAS,UAAAC,eAAc;AAoIjB,SAiCE,YAAAC,WAjCF,OAAAC,OAiCE,QAAAC,cAjCF;AAtDC,SAAS,oBAAoB;AAAA,EAClC,UAAU;AAAA,EACV,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,WAAW,gBAAgB;AAAA,EAC3B;AAAA,EACA,YAAY,iBAAiB;AAAA,EAC7B,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA;AACF,GAA6B;AAC3B,QAAM,QAAQ,SAAS;AACvB,QAAM,gBAAgB,MAAM,OAAO,kBAAkB;AACrD,QAAM,CAAC,SAAS,UAAU,IAAIC,WAAS,KAAK;AAE5C,QAAM,aAAa,kBAAkB;AACrC,QAAM,YAAY,iBAAiB,SAAS,CAAC,aAAa,CAAC;AAC3D,QAAM,kBAAkB,YACnB,eAAe,WAAW,cAC3B;AACJ,QAAM,WAAW,CAAC;AAClB,QAAM,SAAS,iBAAiB,OAAO,eAAe;AAMtD,QAAM,yBAAyBC,QAAO,SAAS;AAC/C,QAAM,CAAC,UAAU,WAAW,IAAID,WAAS,CAAC;AAC1C,EAAAE,YAAU,MAAM;AACd,QAAI,CAAC,uBAAuB,WAAW,WAAW;AAChD,kBAAY,CAAC,MAAM,IAAI,CAAC;AAAA,IAC1B;AACA,2BAAuB,UAAU;AAAA,EACnC,GAAG,CAAC,SAAS,CAAC;AAEd,QAAM,cACJ,CAAC,iBAAiB,aAAa,cAAc,SAAS,CAAC;AAEzD,QAAM,UAAU,YACZ,SACA,wBAAwB,iBAAiB;AAE7C,QAAM,gBAA2B,YAC5B,eAAe,SAAS,QACzB;AACJ,QAAM,eACJ,aAAa,eAAe,OAC1B,gBAAAJ,MAAC,UAAK,eAAW,MAAC,OAAO,EAAE,UAAU,SAAS,GAC3C,wBAAc,MACjB,IAEC,QAAQ;AAGb,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC,kCAA8B;AAAA,MAC9B,kBAAgB,YAAY,SAAS;AAAA,MACrC,gBAAc,aAAa,SAAS;AAAA,MACpC,qBACE,YACI,cACA,aACE,eACA,YACE,cACA;AAAA,MAEV,OAAO;AAAA,QACL,UAAU;AAAA,QACV,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,gBAAgB;AAAA;AAAA;AAAA;AAAA,QAIhB,SAAS,MAAM,MAAM,CAAC;AAAA,MACxB;AAAA,MAEC;AAAA,sBACC,gBAAAA,OAAAF,WAAA,EAQE;AAAA,0BAAAC;AAAA,YAACK,QAAO;AAAA,YAAP;AAAA,cACC,eAAW;AAAA,cACX,OAAO;AAAA,gBACL,UAAU;AAAA,gBACV,OAAO;AAAA,gBACP,cAAc,MAAM,OAAO;AAAA,gBAC3B,YAAY,OAAO;AAAA,gBACnB,SAAS;AAAA,gBACT,eAAe;AAAA,cACjB;AAAA,cACA,SAAS;AAAA,gBACP,OAAO,CAAC,GAAG,MAAM,CAAC;AAAA,gBAClB,SAAS,CAAC,MAAM,MAAM,IAAI;AAAA,cAC5B;AAAA,cACA,YAAY;AAAA,gBACV,QAAQ;AAAA,gBACR,UAAU;AAAA,gBACV,MAAM;AAAA,cACR;AAAA;AAAA,UACF;AAAA,UAQA,gBAAAL;AAAA,YAACK,QAAO;AAAA,YAAP;AAAA,cAEC,eAAW;AAAA,cACX,OAAO;AAAA,gBACL,UAAU;AAAA,gBACV,OAAO;AAAA,gBACP,cAAc,MAAM,OAAO;AAAA,gBAC3B,WAAW,WAAW,OAAO,KAAK;AAAA,gBAClC,eAAe;AAAA,cACjB;AAAA,cACA,SAAS,EAAE,SAAS,IAAI;AAAA,cACxB,SAAS;AAAA,gBACP,WAAW;AAAA,kBACT,WAAW,UAAU,OAAO,OAAO,IAAI,CAAC;AAAA,kBACxC,cAAc,UAAU,OAAO,OAAO,CAAC,CAAC;AAAA,gBAC1C;AAAA,gBACA,SAAS,CAAC,KAAK,CAAC;AAAA,cAClB;AAAA,cACA,YAAY,EAAE,UAAU,KAAK,MAAM,UAAU;AAAA;AAAA,YAjBxC;AAAA,UAkBP;AAAA,WACF,IACE;AAAA,QACJ,gBAAAJ;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS;AAAA,YACT;AAAA,YACA,SAAS;AAAA,YACT;AAAA,YACA,cACE,OAAO,kBAAkB,WAAW,gBAAgB;AAAA,YAEtD,iBAAe,YAAY;AAAA,YAC3B,uBAAqB;AAAA,YACrB,iBAAc;AAAA,YACd,OAAO;AAAA,YACP;AAAA,YACA,OAAO;AAAA;AAAA,cAEL,UAAU;AAAA,cACV,QAAQ;AAAA,cACR,WAAW,YAAY,YAAY,SAAY,MAAM,UAAU;AAAA,cAC/D,GAAG;AAAA,YACL;AAAA,YACA,SAAS,OAAO,UAAyC;AACvD,oBAAM,eAAe;AACrB,kBAAI,SAAU;AACd,yBAAW,IAAI;AACf,kBAAI;AACF,sBAAM,WAAW;AAAA,cACnB,UAAE;AACA,2BAAW,KAAK;AAAA,cAClB;AAAA,YACF;AAAA,YAEC;AAAA;AAAA,cACD,gBAAAD,MAAC,UAAM,yBAAc;AAAA;AAAA;AAAA,QACvB;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,SAAS,wBACP,QACoB;AACpB,MAAI,WAAW,0BAA0B;AACvC,WAAO;AAAA,EACT;AACA,SAAO;AACT;AASA,SAAS,UAAU,OAAe,OAAuB;AACvD,QAAM,UAAU,MAAM,KAAK;AAC3B,MAAI,QAAQ,WAAW,GAAG,GAAG;AAC3B,UAAM,MAAM,QAAQ,MAAM,CAAC;AAC3B,QAAI,IAAI,WAAW,GAAG;AAIpB,YAAM,IAAI,SAAS,IAAI,MAAM,GAAG,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE;AAChD,YAAM,IAAI,SAAS,IAAI,MAAM,GAAG,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE;AAChD,YAAM,IAAI,SAAS,IAAI,MAAM,GAAG,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE;AAChD,aAAO,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,KAAK;AAAA,IACxC;AACA,QAAI,IAAI,WAAW,GAAG;AACpB,YAAM,IAAI,SAAS,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE;AACtC,YAAM,IAAI,SAAS,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE;AACtC,YAAM,IAAI,SAAS,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE;AACtC,aAAO,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,KAAK;AAAA,IACxC;AAAA,EACF;AAIA,SAAO,sBAAsB,OAAO,IAAI,KAAK,MAAM,QAAQ,GAAG,CAAC;AACjE;;;ACrUA,SAAS,SAAAM,QAAO,YAAAC,kBAAgC;AAChD,SAAS,UAAAC,SAAQ,mBAAAC,wBAAuB;AACxC,SAAS,iBAAiB;AAyFhB,gBAAAC,OAaE,QAAAC,cAbF;AApEH,SAAS,YAAY;AAAA,EAC1B,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB;AAAA,EACA;AACF,GAAqB;AACnB,QAAM,QAAQ,SAAS;AACvB,QAAM,gBAAgB,MAAM,OAAO,kBAAkB;AACrD,QAAM,YAAYC,OAAM;AACxB,QAAM,CAAC,YAAY,aAAa,IAAIC,WAAS,eAAe;AAC5D,QAAM,CAAC,WAAW,YAAY,IAAIA,WAAS,KAAK;AAEhD,QAAM,aAAa,QACf,cAAc,KAAK,KAAK,MAAM,QAAQ,YAAY,KAAK,EAAE,KAAK,IAC9D;AAEJ,SACE,gBAAAF;AAAA,IAACG,QAAO;AAAA,IAAP;AAAA,MACC,SAAS,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,GAAG,GAAG;AAAA,MAC9D,SAAS,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,MAC7D;AAAA,MACA,gCAA6B;AAAA,MAC7B,cAAY,aAAa,SAAS;AAAA,MAClC,oBAAkB,cAAc,SAAS;AAAA,MACzC,OAAO;AAAA,QACL,GAAG,aAAa,OAAO,EAAE,MAAM,QAAQ,QAAQ,MAAM,CAAC;AAAA,QACtD,WAAW,MAAM,UAAU;AAAA,QAC3B,UAAU;AAAA,MACZ;AAAA,MACA,MAAK;AAAA,MACL,cAAY;AAAA,MAEZ;AAAA,wBAAAH;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS,MAAM,eAAe,cAAc,CAAC,UAAU;AAAA,YACvD,cAAc,MAAM,aAAa,IAAI;AAAA,YACrC,cAAc,MAAM,aAAa,KAAK;AAAA,YACtC,UAAU,CAAC;AAAA,YACX,iBAAe;AAAA,YACf,iBAAe;AAAA,YACf,OAAO;AAAA,cACL,OAAO;AAAA,cACP,SAAS,GAAG,MAAM,MAAM,CAAC,CAAC,IAAI,MAAM,MAAM,CAAC,CAAC;AAAA,cAC5C,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,gBAAgB;AAAA,cAChB,KAAK,MAAM,MAAM,CAAC;AAAA,cAClB,cAAc,aACV,cAAc,MAAM,SAAS,OAAO,MAAM,KAC1C;AAAA,cACJ,YACE,eAAe,YACX,MAAM,SAAS,QAAQ,QACvB,MAAM,SAAS,QAAQ;AAAA,cAC7B,OAAO,MAAM,SAAS,KAAK;AAAA,cAC3B,YAAY,MAAM,WAAW,WAAW;AAAA,cACxC,QAAQ,cAAc,YAAY;AAAA,cAClC,YAAY,cAAc,MAAM,OAAO,SAAS,IAAI,IAAI,MAAM,OAAO,OAAO,GAAG;AAAA;AAAA,cAE/E,QAAQ;AAAA,cACR,WAAW;AAAA,cACX,YAAY;AAAA,YACd;AAAA,YAEA;AAAA,8BAAAA,OAAC,SACC;AAAA,gCAAAD;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO;AAAA,sBACL,QAAQ;AAAA,sBACR,YAAY,MAAM,WAAW,WAAW;AAAA,sBACxC,UAAU,MAAM,WAAW,SAAS;AAAA,sBACpC,YAAY,MAAM,WAAW,WAAW;AAAA,sBACxC,OAAO,MAAM,SAAS,KAAK;AAAA,sBAC3B,YAAY,MAAM,WAAW,WAAW;AAAA,oBAC1C;AAAA,oBAEC;AAAA;AAAA,gBACH;AAAA,gBACC,cACC,gBAAAC;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO;AAAA,sBACL,QAAQ;AAAA,sBACR,WAAW,MAAM,MAAM,CAAC;AAAA,sBACxB,UAAU,MAAM,WAAW,SAAS;AAAA,sBACpC,YAAY,MAAM,WAAW,WAAW;AAAA,sBACxC,OAAO,MAAM,SAAS,KAAK;AAAA,sBAC3B,SAAS;AAAA,sBACT,YAAY;AAAA,sBACZ,KAAK,MAAM,MAAM,CAAC;AAAA,oBACpB;AAAA,oBAEA;AAAA,sCAAAD;AAAA,wBAAC;AAAA;AAAA,0BACC,OAAO;AAAA,4BACL,OAAO;AAAA,4BACP,QAAQ;AAAA,4BACR,cAAc,MAAM,OAAO;AAAA,4BAC3B,YAAY,MAAM,SAAS,OAAO,QAAQ;AAAA,4BAC1C,QAAQ,aAAa,MAAM,SAAS,OAAO,QAAQ,MAAM;AAAA,4BACzD,SAAS;AAAA,0BACX;AAAA;AAAA,sBACF;AAAA,sBAAE;AAAA,sBACM;AAAA;AAAA;AAAA,gBACV;AAAA,iBAEJ;AAAA,cACC,eACC,gBAAAA;AAAA,gBAACI,QAAO;AAAA,gBAAP;AAAA,kBACC,SACE,gBAAgB,SAAY,EAAE,QAAQ,aAAa,IAAI,IAAI;AAAA,kBAE7D,YAAY,EAAE,UAAU,IAAI;AAAA,kBAC5B,OAAO;AAAA,oBACL,SAAS,MAAM,MAAM,CAAC;AAAA,oBACtB,cAAc,MAAM,OAAO;AAAA,oBAC3B,QAAQ,aAAa,MAAM,SAAS,OAAO,OAAO;AAAA,oBAClD,YAAY,MAAM,SAAS,QAAQ;AAAA,oBACnC,OAAO,MAAM,SAAS,KAAK;AAAA,oBAC3B,SAAS;AAAA,kBACX;AAAA,kBAEA,0BAAAJ;AAAA,oBAAC;AAAA;AAAA,sBACC,MAAM;AAAA,sBACN,aAAa;AAAA,sBACb,eAAY;AAAA,sBACZ,OAAO,EAAE,SAAS,QAAQ;AAAA;AAAA,kBAC5B;AAAA;AAAA,cACF;AAAA;AAAA;AAAA,QAEJ;AAAA,QAEA,gBAAAA,MAACK,kBAAA,EAAgB,SAAS,OACvB,wBACC,gBAAAL;AAAA,UAACI,QAAO;AAAA,UAAP;AAAA,YACC,IAAI;AAAA,YACJ,SAAS,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,GAAG,SAAS,EAAE;AAAA,YAClE,SACE,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,QAAQ,SAAS,EAAE;AAAA,YAEhE,MAAM,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,GAAG,SAAS,EAAE;AAAA,YAC/D,YAAY,EAAE,UAAU,KAAK,MAAM,YAAY;AAAA,YAC/C,OAAO;AAAA,cACL,UAAU;AAAA,cACV,YAAY,MAAM,SAAS,QAAQ;AAAA,YACrC;AAAA,YAEA,0BAAAJ;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,kBACL,SAAS,MAAM,MAAM,CAAC;AAAA,kBACtB,SAAS;AAAA,kBACT,eAAe;AAAA,kBACf,KAAK,MAAM,MAAM,CAAC;AAAA,gBACpB;AAAA,gBAEC;AAAA;AAAA,YACH;AAAA;AAAA,QACF,GAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;AAYA,IAAM,oBAGF;AAAA,EACF,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AACX;AAEO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,UAAU;AAAA,EACV;AAAA,EACA;AACF,GAAqB;AACnB,QAAM,QAAQ,SAAS;AACvB,QAAM,gBAAgB,MAAM,OAAO,kBAAkB;AAErD,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,gBAAgB,kBAAkB,OAAO;AAC/C,QAAM,SAAS,gBAAgB,iBAAiB,OAAO,aAAa,IAAI;AAExE,QAAM,iBAAsC,SACxC;AAAA,IACE,YAAY,OAAO;AAAA,IACnB,OAAO,OAAO;AAAA,IACd,QAAQ,aAAa,OAAO,MAAM;AAAA,IAClC,cAAc,MAAM,OAAO;AAAA,IAC3B,WAAW,MAAM,UAAU;AAAA,EAC7B,IACA;AAAA,IACE,YAAY,MAAM,SAAS,QAAQ;AAAA,IACnC,OAAO,MAAM,SAAS,KAAK;AAAA,IAC3B,QAAQ,aAAa,MAAM,SAAS,OAAO,MAAM;AAAA,IACjD,cAAc,MAAM,OAAO;AAAA,IAC3B,WAAW,MAAM,UAAU;AAAA,EAC7B;AAEJ,SACE,gBAAAC;AAAA,IAACG,QAAO;AAAA,IAAP;AAAA,MACC,SAAS,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,GAAG,IAAI;AAAA,MAC/D,SAAS,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,MAC7D;AAAA,MACA,gCAA6B;AAAA,MAC7B,gBAAc;AAAA,MACd,OAAO;AAAA,QACL,UAAU;AAAA,QACV,SAAS,MAAM,MAAM,CAAC;AAAA,QACtB,YAAY,MAAM,WAAW,WAAW;AAAA,QACxC,GAAG;AAAA,MACL;AAAA,MACA,MAAK;AAAA,MACL,mBAAiB,gBAAgB,MAAM,YAAY,EAAE,QAAQ,QAAQ,GAAG,CAAC;AAAA,MAEzE;AAAA,wBAAAJ;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,KAAK;AAAA,cACL,MAAM,MAAM,MAAM,CAAC;AAAA,cACnB,GAAG,UAAU,OAAO,EAAE,SAAS,aAAa,MAAM,KAAK,CAAC;AAAA,cACxD,YAAY,MAAM,SAAS,QAAQ;AAAA,YACrC;AAAA,YACD;AAAA;AAAA,QAED;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,IAAI,gBAAgB,MAAM,YAAY,EAAE,QAAQ,QAAQ,GAAG,CAAC;AAAA,YAC5D,OAAO;AAAA,cACL,QAAQ;AAAA,cACR,YAAY,MAAM,WAAW,WAAW;AAAA,cACxC,UAAU,MAAM,WAAW,SAAS;AAAA,cACpC,YAAY,MAAM,WAAW,WAAW;AAAA,cACxC,OAAO,QAAQ,UAAU,MAAM,SAAS,KAAK;AAAA,cAC7C,cAAc,cAAc,MAAM,MAAM,CAAC,IAAI,MAAM,MAAM,CAAC;AAAA,YAC5D;AAAA,YAEC;AAAA;AAAA,QACH;AAAA,QACC,eACC,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,QAAQ;AAAA,cACR,cAAc,MAAM,MAAM,CAAC;AAAA,cAC3B,UAAU,MAAM,WAAW,SAAS;AAAA,cACpC,YAAY,MAAM,WAAW,WAAW;AAAA,cACxC,OAAO,QAAQ,UAAU,MAAM,SAAS,KAAK;AAAA,cAC7C,SAAS;AAAA,YACX;AAAA,YAEC;AAAA;AAAA,QACH;AAAA,QAEF,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,SAAS;AAAA,cACT,eAAe;AAAA,cACf,KAAK,MAAM,MAAM,CAAC;AAAA,YACpB;AAAA,YAEC;AAAA;AAAA,QACH;AAAA;AAAA;AAAA,EACF;AAEJ;;;ACtSA,SAAS,SAAAM,QAAO,YAAAC,kBAAoD;AACpE,SAAS,aAAa,sBAAsB;AA4EpC,gBAAAC,OAGE,QAAAC,cAHF;AA5CD,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA,QAAQ;AAAA,EACR;AAAA,EACA,cAAc;AAAA,EACd;AACF,GAAqB;AACnB,QAAM,QAAQ,SAAS;AACvB,QAAM,CAAC,MAAM,OAAO,IAAIC,WAAS,WAAW;AAG5C,QAAM,WAAW,gBAAgBC,OAAM,EAAE,QAAQ,MAAM,EAAE,CAAC;AAE1D,QAAM,YAAY,OAAO,UAAU,YAAY,QAAQ;AAEvD,SACE,gBAAAF;AAAA,IAAC;AAAA;AAAA,MACC,mBAAgB;AAAA,MAChB,0BAAwB,OAAO,SAAS;AAAA,MACxC,OAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,QACf,KAAK,MAAM,MAAM,CAAC;AAAA,QAClB,YAAY;AAAA;AAAA;AAAA,QAGZ,MAAM;AAAA,QACN,UAAU;AAAA,MACZ;AAAA,MAEA;AAAA,wBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,iBAAe;AAAA,YACf,iBAAe;AAAA,YACf,SAAS,MAAM,QAAQ,CAAC,UAAU,CAAC,KAAK;AAAA,YACxC,OAAO;AAAA,cACL,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,KAAK,MAAM,MAAM,CAAC;AAAA,cAClB,GAAG;AAAA,YACL;AAAA,YAEA;AAAA,8BAAAD,MAAC,kBAAe,MAAM,IAAI,eAAW,MAAC;AAAA,cACtC,gBAAAA,MAAC,UAAM,iBAAM;AAAA,cACZ,YACC,gBAAAC;AAAA,gBAAC;AAAA;AAAA,kBACC,eAAW;AAAA,kBACX,OAAO;AAAA,oBACL,oBAAoB;AAAA,oBACpB,SAAS;AAAA,kBACX;AAAA,kBACD;AAAA;AAAA,oBACG;AAAA,oBAAM;AAAA;AAAA;AAAA,cACV,IACE;AAAA,cACJ,gBAAAD;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAM;AAAA,kBACN,eAAW;AAAA,kBACX,OAAO;AAAA,oBACL,WAAW,OAAO,mBAAmB;AAAA,oBACrC,YAAY,aAAa,MAAM,OAAO,SAAS,IAAI,IAAI,MAAM,OAAO,OAAO,GAAG;AAAA,kBAChF;AAAA;AAAA,cACF;AAAA;AAAA;AAAA,QACF;AAAA,QACC,OACC,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,IAAI;AAAA,YACJ,MAAK;AAAA,YACL,cAAY;AAAA,YACZ,OAAO;AAAA,cACL,SAAS;AAAA,cACT,eAAe;AAAA,cACf,UAAU;AAAA,cACV,KAAK,MAAM,MAAM,CAAC;AAAA;AAAA;AAAA,cAGlB,eAAe,MAAM,MAAM,CAAC;AAAA,cAC5B,cAAc,MAAM,MAAM,CAAC;AAAA,cAC3B,YAAY,MAAM,SAAS,QAAQ;AAAA,cACnC,cAAc,MAAM,OAAO;AAAA,YAC7B;AAAA,YAEC;AAAA;AAAA,QACH,IACE;AAAA;AAAA;AAAA,EACN;AAEJ;;;AC9IA,SAAS,QAAAI,cAAY;AACrB,SAAS,UAAAC,eAAc;AACvB;AAAA,EACE,eAAAC;AAAA,EACA,aAAAC;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,OAGK;;;ACTP,SAAS,iBAAAC,gBAAe,cAAAC,mBAAkC;AAyDtD,gBAAAC,aAAA;AA7BJ,IAAM,cAAcF,eAAgC,IAAI;AAEjD,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA,QAAQ;AACV,GAGc;AACZ,QAAM,mBAAmB,QAAQ,IAAI,CAAC,UAAU,SAAS,MAAS;AAClE,QAAM,YACJ,kBAAkB,MAAM,CAAC,UAAU,UAAU,MAAS,KAAK;AAC7D,QAAM,MAAM,YACR,kBAAkB;AAAA,IAChB,CAAC,OAAO,UAAU,SAAS,SAAS;AAAA,IACpC;AAAA,EACF,IACA;AAEJ,SAAO;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,IACA,WAAW,kBAAkB,UAAU;AAAA,IACvC;AAAA,EACF;AACF;;;ADgBI,SAKkC,OAAAG,OALlC,QAAAC,cAAA;AAdJ,IAAM,sBAAsB;AAC5B,IAAM,yBAAyB;AAC/B,IAAM,gBAAgB,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAEhC,SAAS,WAAW;AAAA,EACzB;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AACF,GAAoB;AAClB,QAAM,cAAc,mBAAmB,EAAE,QAAQ,OAAO,UAAU,CAAC;AAEnE,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAWC,OAAK,oCAAoC,SAAS;AAAA,MAC7D,MAAK;AAAA,MACL,cAAW;AAAA,MAEV;AAAA,iBAAS,OAAO,WAAW,IAAI,gBAAAF,MAAC,sBAAoB,GAAG,aAAa;AAAA,QAEpE,aACC,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,QAAQ;AAAA,YACR,QAAQ,YAAY;AAAA,YACpB,WAAW,YAAY;AAAA;AAAA,QACzB,IACE;AAAA,QAGJ,gBAAAA,MAAC,SAAI,WAAU,WAAU,aAAU,UAChC,sBAAY,aAAa,YAAY,SAClC,UAAU,YAAY,OAAO,KAAK,IAAI,CAAC,YAAY,YAAY,GAAG,KAClE,uBACN;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,SAAS,mBAAmB;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA0B;AACxB,QAAM,QAAQ,SAAS;AACvB,QAAM,OAAO,UAAU,MAAM,SAAS,EAAE,KAAK,MAAS;AACtD,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,KAAK,MAAM,MAAM,CAAC;AAAA,MACpB;AAAA,MAEC;AAAA,oBACC,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,YAAY,MAAM,WAAW,WAAW;AAAA,cACxC,UAAU,MAAM,WAAW,SAAS;AAAA,cACpC,OAAO,MAAM,SAAS,KAAK;AAAA,cAC3B,oBAAoB;AAAA,YACtB;AAAA,YACD;AAAA;AAAA,cACQ;AAAA;AAAA;AAAA,QACT,IACE;AAAA,QACJ,gBAAAD,MAAC,WAAQ,QAAQ,MAAM,MAAM,IAAI,SAAS,OAAO;AAAA;AAAA;AAAA,EACnD;AAEJ;AAEA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,QAAQ,SAAS;AACvB,QAAM,eAAe,gBAAgB;AACrC,QAAM,gBAAgB,MAAM,OAAO,kBAAkB;AACrD,QAAM,CAAC,MAAM,OAAO,IAAIG,WAAS,KAAK;AACtC,QAAM,CAAC,OAAO,QAAQ,IAAIA,WAAoB,MAAM;AACpD,QAAM,CAAC,OAAO,QAAQ,IAAIA,WAAwB,IAAI;AACtD,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA;AAAA,IAAmB,MAC7D,mBAAmB,SAAS;AAAA,EAC9B;AACA,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,WAE1C,MAAS;AACX,QAAM,eAAeC,QAAO,CAAC;AAC7B,QAAM,qBAAqBA,QAAsB,IAAI;AAErD,QAAM,sBAAsB,QAAQ,OAAO,MAAM;AACjD,QAAM,YAAY,gBACd,IACC,OAAO,aAAa;AACzB,QAAM,eAAe,OAAO,gBAAgB;AAC5C,QAAM,kBAAkB,QAAQ,KAAK,GAAG,KAAK;AAC7C,QAAM,iBACJ,WAAW,UACX,OAAO,SAAS,KAChB,OAAO,MAAM,CAAC,UAAU,OAAO,UAAU,QAAQ;AAEnD,EAAAC,YAAU,MAAM;AACd,QAAI,CAAC,qBAAqB;AACxB,cAAQ,KAAK;AACb;AAAA,IACF;AACA,QAAI,CAAC,gBAAgB;AACnB,yBAAmB,UAAU;AAC7B,cAAQ,IAAI;AACZ,UAAI,UAAU,WAAW;AACvB,iBAAS,MAAM;AACf,0BAAkB,MAAS;AAC3B,iBAAS,IAAI;AAAA,MACf;AACA;AAAA,IACF;AACA,QACE,QACA,UAAU,UACV,mBAAmB,YAAY,iBAC/B;AACA,mBAAa,UAAU,KAAK,IAAI;AAChC,eAAS,SAAS;AAClB,wBAAkB,mBAAmB,SAAS,CAAC;AAAA,IACjD;AAAA,EACF,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,EAAAA,YAAU,MAAM;AACd,QAAI,UAAU,UAAW;AACzB,QAAI,cAAe;AACnB,UAAM,WAAW,YAAY,MAAM;AACjC,wBAAkB,mBAAmB,SAAS,CAAC;AAAA,IACjD,GAAG,GAAG;AACN,WAAO,MAAM,cAAc,QAAQ;AAAA,EACrC,GAAG,CAAC,WAAW,OAAO,aAAa,CAAC;AAEpC,EAAAA,YAAU,MAAM;AACd,QAAI,UAAU,aAAa,CAAC,kBAAkB,CAAC,OAAQ;AACvD,UAAM,YAAY,KAAK;AAAA,MACrB;AAAA,MACA,aAAa,KAAK,IAAI,IAAI,aAAa;AAAA,IACzC;AACA,UAAM,UAAU,WAAW,MAAM;AAC/B,wBAAkB,CAAC,GAAG,MAAM,CAAC;AAC7B,yBAAmB,UAAU;AAC7B,eAAS,UAAU;AAAA,IACrB,GAAG,SAAS;AACZ,WAAO,MAAM,aAAa,OAAO;AAAA,EACnC,GAAG,CAAC,WAAW,OAAO,iBAAiB,QAAQ,cAAc,CAAC;AAE9D,EAAAA,YAAU,MAAM;AACd,QAAI,UAAU,WAAY;AAC1B,UAAM,UAAU,WAAW,MAAM;AAC/B,cAAQ,KAAK;AACb,eAAS,MAAM;AAAA,IACjB,GAAG,YAAY;AACf,WAAO,MAAM,aAAa,OAAO;AAAA,EACnC,GAAG,CAAC,OAAO,YAAY,CAAC;AAExB,QAAM,OAAOC,cAAY,YAAY;AACnC,QAAI,CAAC,OAAO,UAAU,OAAO,cAAc,SAAS,UAAU,WAAW;AACvE;AAAA,IACF;AACA,iBAAa,UAAU,KAAK,IAAI;AAChC,YAAQ,IAAI;AACZ,aAAS,SAAS;AAClB,aAAS,IAAI;AACb,sBAAkB,MAAS;AAC3B,sBAAkB,mBAAmB,SAAS,CAAC;AAC/C,QAAI;AACF,YAAM,OAAO,OAAO;AAAA,IACtB,SAAS,QAAQ;AACf,eAAS,MAAM;AACf;AAAA,QACE,kBAAkB,QAAQ,OAAO,UAAU;AAAA,MAC7C;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,WAAW,KAAK,CAAC;AAE7B,QAAM,gBACJ,UAAU,YACN,iBACC,kBAAkB,UAAU,MAAM,SAAS,EAAE,KAAK,MAAS;AAClE,QAAM,aAAa,UAAU,aAAa;AAC1C,QAAM,QAAQ,OAAO,SAAS;AAC9B,QAAM,cAAc,OAAO,eAAe;AAC1C,QAAM,cAAc,OAAO,eAAe;AAC1C,QAAM,YAAY,OAAO,aAAa;AACtC,QAAM,WAAW,OAAO,cAAc,SAAS,UAAU;AACzD,QAAM,WAAW;AAEjB,SACE,gBAAAN,MAAC,UAAO,MAAY,cAAc,WAAW,UAAU,QACrD,0BAAAC;AAAA,IAAC;AAAA;AAAA,MACC,yBAAsB;AAAA,MACtB,iBAAiB;AAAA,MACjB,WAAU;AAAA,MACV,OAAO;AAAA,QACL,GAAG;AAAA,QACH,GAAG,aAAa,OAAO,EAAE,MAAM,SAAS,QAAQ,KAAK,CAAC;AAAA,QACtD,OAAO;AAAA,QACP,YAAY,MAAM,WAAW,WAAW;AAAA,MAC1C;AAAA,MACA,iBACE,WAAW,SAAY,CAAC,UAAiB,MAAM,eAAe;AAAA,MAEhE,mBACE,WAAW,SAAY,CAAC,UAAiB,MAAM,eAAe;AAAA,MAGhE;AAAA,wBAAAA,OAAC,gBAAa,WAAU,8BACtB;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,YAAY,MAAM,WAAW,WAAW;AAAA,gBACxC,UAAU,MAAM,WAAW,SAAS;AAAA,cACtC;AAAA,cAEC;AAAA;AAAA,UACH;AAAA,UACA,gBAAAA,MAAC,qBAAmB,uBAAY;AAAA,WAClC;AAAA,QAEA,gBAAAC;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,SAAS;AAAA,cACT,eAAe;AAAA,cACf,YAAY;AAAA,cACZ,KAAK,MAAM,MAAM,CAAC;AAAA,YACpB;AAAA,YAEA;AAAA,8BAAAD,MAAC,cAAW,OAAO,aAAa,KAAK,YAAY,OAAc;AAAA,cAC/D,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,QAAQ;AAAA,kBACR,MAAM;AAAA,kBACN,SAAS,UAAU;AAAA;AAAA,cACrB;AAAA,cACC,QACC,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,OAAO;AAAA,oBACL,OAAO,MAAM,SAAS,OAAO,OAAO;AAAA,oBACpC,UAAU,MAAM,WAAW,SAAS;AAAA,oBACpC,WAAW;AAAA,kBACb;AAAA,kBAEC;AAAA;AAAA,cACH,IACE;AAAA,cACJ,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,SAAQ;AAAA,kBACR,MAAK;AAAA,kBACL;AAAA,kBACA,SAAS,UAAU;AAAA,kBACnB,SAAS,CAAC,UAAU;AAClB,0BAAM,eAAe;AACrB,yBAAK,KAAK;AAAA,kBACZ;AAAA,kBAEC,oBAAU,YAAY,eAAe;AAAA;AAAA,cACxC;AAAA;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF,GACF;AAEJ;AAEA,SAAS,WAAW;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,QAAQ,SAAS;AACvB,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,aAAU;AAAA,MACV,OAAO;AAAA,QACL,GAAG,aAAa,OAAO,EAAE,MAAM,SAAS,QAAQ,KAAK,CAAC;AAAA,QACtD,OAAO;AAAA,QACP,SAAS,GAAG,MAAM,MAAM,CAAC,CAAC,IAAI,MAAM,MAAM,CAAC,CAAC;AAAA,QAC5C,WAAW;AAAA,MACb;AAAA,MAEA;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,OAAO,MAAM,SAAS,KAAK;AAAA,cAC3B,UAAU,MAAM,WAAW,SAAS;AAAA,cACpC,YAAY,MAAM,WAAW,WAAW;AAAA,cACxC,eAAe,MAAM,WAAW,cAAc;AAAA,cAC9C,eAAe;AAAA,YACjB;AAAA,YAEC;AAAA;AAAA,QACH;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,YAAY,MAAM,WAAW,WAAW;AAAA,cACxC,UAAU;AAAA,cACV,YAAY,MAAM,WAAW,WAAW;AAAA,cACxC,YAAY;AAAA,cACZ,OAAO,MAAM,SAAS,KAAK;AAAA,cAC3B,oBAAoB;AAAA,YACtB;AAAA,YAEC,kBAAQ,UAAU,YAAY,QAAQ;AAAA;AAAA,QACzC;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,SAAS,QAAQ;AAAA,EACf;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,MAAM,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,IAAI,CAAC;AAC/C,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,cAAW;AAAA,MACX,OAAO;AAAA,QACL,SAAS;AAAA,QACT,gBAAgB;AAAA,QAChB;AAAA,QACA,UAAU;AAAA,MACZ;AAAA,MAEC,iBAAO,IAAI,CAAC,OAAO,UAClB,gBAAAA;AAAA,QAAC;AAAA;AAAA,UAEC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA;AAAA,QAJK;AAAA,MAKP,CACD;AAAA;AAAA,EACH;AAEJ;AAEA,SAAS,QAAQ;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,QAAM,QAAQ,SAAS;AACvB,QAAM,gBAAgB,MAAM,OAAO,kBAAkB;AACrD,QAAM,WAAW,OAAO,UAAU,YAAY,SAAS,KAAK,SAAS;AACrE,QAAM,QAAuB;AAAA,IAC3B,UAAU;AAAA,IACV,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,cAAc,KAAK,IAAI,IAAI,KAAK,MAAM,OAAO,GAAG,CAAC;AAAA,IACjD,QAAQ,aAAa,MAAM,SAAS,OAAO,OAAO;AAAA,IAClD,YAAY,2BAA2B,MAAM,SAAS,QAAQ,IAAI,KAAK,MAAM,SAAS,QAAQ,KAAK;AAAA,IACnG,WAAW,GAAG,MAAM,UAAU,MAAM;AAAA,IACpC,OAAO,MAAM,SAAS,KAAK;AAAA,IAC3B,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AACA,SACE,gBAAAA;AAAA,IAACO,QAAO;AAAA,IAAP;AAAA,MACC,MAAK;AAAA,MACL,cACE,OAAO,UAAU,WACb,OAAO,QAAQ,CAAC,KAAK,KAAK,KAC1B,OAAO,QAAQ,CAAC;AAAA,MAEtB;AAAA,MACA,SACE,WAAW,CAAC,gBACR;AAAA,QACE,QAAQ,CAAC,GAAG,IAAI,KAAK,CAAC;AAAA,QACtB,GAAG,CAAC,GAAG,IAAI,CAAC;AAAA,QACZ,OAAO,CAAC,GAAG,MAAM,CAAC;AAAA,MACpB,IACA,EAAE,QAAQ,GAAG,GAAG,GAAG,OAAO,EAAE;AAAA,MAElC,YACE,WAAW,CAAC,gBACR;AAAA,QACE,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,OAAO,QAAQ;AAAA,QACf,MAAM;AAAA,MACR,IACA,EAAE,UAAU,IAAI;AAAA,MAGrB,qBACC,gBAAAP,MAAC,WAAQ,OAAc,IAEvB,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO;AAAA,YACL,YAAY,MAAM,WAAW,WAAW;AAAA,YACxC,UAAU,KAAK,MAAM,OAAO,IAAI;AAAA,YAChC,YAAY,MAAM,WAAW,WAAW;AAAA,YACxC,oBAAoB;AAAA,UACtB;AAAA,UAEC,mBAAS;AAAA;AAAA,MACZ;AAAA;AAAA,EAEJ;AAEJ;AAEA,SAAS,QAAQ,EAAE,MAAM,GAAsB;AAC7C,QAAM,QAAQ,SAAS;AACvB,QAAM,OAAO,aAAa,KAAK;AAC/B,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,eAAW;AAAA,MACX,OAAO;AAAA,QACL,UAAU;AAAA,QACV,OAAO;AAAA,MACT;AAAA,MAEC,eAAK,IAAI,CAAC,CAAC,MAAM,GAAG,GAAG,UACtB,gBAAAA;AAAA,QAAC;AAAA;AAAA,UAEC,OAAO;AAAA,YACL,UAAU;AAAA,YACV,MAAM,GAAG,IAAI;AAAA,YACb,KAAK,GAAG,GAAG;AAAA,YACX,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,cAAc;AAAA,YACd,WAAW;AAAA,YACX,YAAY,MAAM,SAAS,KAAK;AAAA,YAChC,WAAW;AAAA,UACb;AAAA;AAAA,QAXK,GAAG,IAAI,IAAI,GAAG,IAAI,KAAK;AAAA,MAY9B,CACD;AAAA;AAAA,EACH;AAEJ;AAEA,SAAS,aAAa,OAAwC;AAC5D,UAAQ,OAAO;AAAA,IACb,KAAK;AACH,aAAO,CAAC,CAAC,IAAI,EAAE,CAAC;AAAA,IAClB,KAAK;AACH,aAAO;AAAA,QACL,CAAC,IAAI,EAAE;AAAA,QACP,CAAC,IAAI,EAAE;AAAA,MACT;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,CAAC,IAAI,EAAE;AAAA,QACP,CAAC,IAAI,EAAE;AAAA,QACP,CAAC,IAAI,EAAE;AAAA,MACT;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,CAAC,IAAI,EAAE;AAAA,QACP,CAAC,IAAI,EAAE;AAAA,QACP,CAAC,IAAI,EAAE;AAAA,QACP,CAAC,IAAI,EAAE;AAAA,MACT;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,CAAC,IAAI,EAAE;AAAA,QACP,CAAC,IAAI,EAAE;AAAA,QACP,CAAC,IAAI,EAAE;AAAA,QACP,CAAC,IAAI,EAAE;AAAA,QACP,CAAC,IAAI,EAAE;AAAA,MACT;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,CAAC,IAAI,EAAE;AAAA,QACP,CAAC,IAAI,EAAE;AAAA,QACP,CAAC,IAAI,EAAE;AAAA,QACP,CAAC,IAAI,EAAE;AAAA,QACP,CAAC,IAAI,EAAE;AAAA,QACP,CAAC,IAAI,EAAE;AAAA,MACT;AAAA,IACF;AACE,aAAO,CAAC;AAAA,EACZ;AACF;AAEA,SAAS,mBAAmB,OAAyB;AACnD,SAAO,MAAM,KAAK,EAAE,QAAQ,MAAM,GAAG,CAAC,GAAG,UAAU;AACjD,UAAM,SAAS,KAAK,MAAM,KAAK,OAAO,IAAI,cAAc,MAAM;AAC9D,WAAO,eAAe,SAAS,SAAS,cAAc,MAAM,KAAK;AAAA,EACnE,CAAC;AACH;AAEA,SAAS,UACP,QACoB;AACpB,MAAI,CAAC,OAAO,MAAM,CAAC,UAAU,OAAO,UAAU,QAAQ,EAAG,QAAO;AAChE,SAAO,OAAO,OAAO,CAAC,OAAO,UAAU,SAAS,SAAS,IAAI,CAAC;AAChE;;;AE1iBA,SAAS,UAAAQ,eAAc;AACvB,SAAS,QAAAC,cAAY;AA6Bf,gBAAAC,OAiIA,QAAAC,cAjIA;AAfC,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV;AACF,GAAwB;AACtB,QAAM,QAAQ,SAAS;AACvB,QAAM,gBAAgB,MAAM,OAAO,kBAAkB;AAErD,QAAM,QAAQ,cAAc,YAAY,KAAK,YAAY,YAAY;AAErE,MAAI,YAAY,WAAW;AACzB,WACE,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,OAAO;AAAA,UACL,YAAY,MAAM,WAAW,WAAW;AAAA,UACxC,UAAU,MAAM,WAAW,SAAS;AAAA,UACpC,YAAY,MAAM,WAAW,WAAW;AAAA,UACxC,OAAO,MAAM,SAAS,KAAK;AAAA,UAC3B,gBAAgB;AAAA,UAChB,qBAAqB;AAAA,UACrB,qBAAqB,MAAM,SAAS,OAAO;AAAA,UAC3C,qBAAqB;AAAA,QACvB;AAAA,QACA,MAAK;AAAA,QACL,cAAY,kBAAkB,KAAK;AAAA,QAElC;AAAA;AAAA,IACH;AAAA,EAEJ;AAIA,QAAM,QACJ,aAAa,OACT,cACA,aAAa,SAAS,qBAAqB,kBAAkB,SAAS,IACpE,YACA;AAER,QAAM,iBACJ,YAAY,QACR;AAAA,IACE,GAAG,aAAa,OAAO,EAAE,MAAM,SAAS,QAAQ,MAAM,CAAC;AAAA,IACvD,SAAS,MAAM,MAAM,CAAC;AAAA,IACtB,WAAW,MAAM,UAAU;AAAA,IAC3B,YAAY,MAAM,WAAW,WAAW;AAAA,EAC1C,IACA,EAAE,YAAY,MAAM,WAAW,WAAW,KAAK;AAErD,QAAM,WAAW,eAAe;AAAA,IAC9B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,YACJ,UAAU,cACN,oBAAe,KAAK,KACpB,UAAU,YACR,eAAe,iBAAiB,qBAAqB,CAAC,CAAC,CAAC,WAAM,KAAK,KACnE;AAER,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAWE,OAAK,qCAAqC,SAAS;AAAA,MAC9D,OAAO;AAAA,MACP,MAAK;AAAA,MACL,aAAU;AAAA,MACV,eAAY;AAAA,MACZ,cAAY;AAAA,MAEX;AAAA;AAAA,EACH;AAEJ;AAEA,SAAS,YAAY,OAAuB;AAC1C,QAAM,YAAY,MACf,QAAQ,YAAY,KAAK,EACzB,QAAQ,MAAM,GAAG,EACjB,KAAK,EACL,QAAQ,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC;AACxC,SAAO,cAAc,gBAAgB,SAAS;AAChD;AAEA,SAAS,iBAAiB,OAAkC;AAC1D,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,MAAI,MAAM,WAAW,EAAG,QAAO,MAAM,CAAC;AACtC,MAAI,MAAM,WAAW,EAAG,QAAO,GAAG,MAAM,CAAC,CAAC,QAAQ,MAAM,CAAC,CAAC;AAC1D,SAAO,GAAG,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC,SAAS,MAAM,MAAM,SAAS,CAAC,CAAC;AACzE;AAUA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAiB;AACf,MAAI,UAAU,cAAc;AAC1B,WACE,gBAAAF,MAAC,SAAI,OAAO,eAAe,KAAK,GAC9B,0BAAAA,MAAC,UAAK,OAAO,eAAe,KAAK,GAAI,iBAAM,GAC7C;AAAA,EAEJ;AAEA,QAAM,aAAa,UAAU;AAC7B,QAAM,SAAS,aACX,MAAM,SAAS,OAAO,UACtB,MAAM,SAAS,OAAO;AAC1B,QAAM,YAAY,aACd,cACA,eAAe,iBAAiB,qBAAqB,CAAC,CAAC,CAAC;AAE5D,SACE,gBAAAC;AAAA,IAACE,QAAO;AAAA,IAAP;AAAA,MACC,SAAS,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,GAAG,GAAG;AAAA,MAC9D,SAAS,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,MAC7D,OAAO;AAAA,QACL,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,KAAK,MAAM,MAAM,CAAC;AAAA,MACpB;AAAA,MAEA;AAAA,wBAAAH;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,MAAM,aAAa,UAAU;AAAA,YAC7B;AAAA;AAAA,QACF;AAAA,QACA,gBAAAC,OAAC,SAAI,OAAO,eAAe,KAAK,GAC9B;AAAA,0BAAAD,MAAC,UAAK,OAAO,eAAe,KAAK,GAAI,qBAAU;AAAA,UAC/C,gBAAAA,MAAC,UAAK,OAAO,kBAAkB,KAAK,GAAI,iBAAM;AAAA,WAChD;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,SAAS,eAAe,OAAmC;AACzD,SAAO;AAAA,IACL,SAAS;AAAA,IACT,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,KAAK,MAAM,MAAM,GAAG;AAAA,IACpB,UAAU;AAAA,EACZ;AACF;AAEA,SAAS,eAAe,OAAmC;AACzD,SAAO;AAAA,IACL,YAAY,MAAM,WAAW,WAAW;AAAA,IACxC,UAAU,MAAM,WAAW,SAAS;AAAA,IACpC,YAAY,MAAM,WAAW,WAAW;AAAA,IACxC,eAAe,MAAM,WAAW,cAAc;AAAA,IAC9C,YAAY,MAAM,WAAW,WAAW;AAAA,IACxC,OAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AACF;AAEA,SAAS,kBAAkB,OAAmC;AAC5D,SAAO;AAAA,IACL,YAAY,MAAM,WAAW,WAAW;AAAA,IACxC,UAAU,MAAM,WAAW,SAAS;AAAA,IACpC,YAAY,MAAM,WAAW,WAAW;AAAA,IACxC,eAAe,MAAM,WAAW,cAAc;AAAA,IAC9C,eAAe;AAAA,IACf,OAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AACF;AAwBA,SAAS,gBAAgB;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AACF,GAAyB;AACvB,QAAM,OAAO;AAEb,MAAI,SAAS,SAAS;AACpB,WACE,gBAAAC;AAAA,MAAC;AAAA;AAAA,QACC,eAAY;AAAA,QACZ,OAAO;AAAA,UACL,UAAU;AAAA,UACV,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,gBAAgB;AAAA,UAChB,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,YAAY;AAAA,QACd;AAAA,QAEA;AAAA,0BAAAD;AAAA,YAACG,QAAO;AAAA,YAAP;AAAA,cACC,OAAO;AAAA,gBACL,UAAU;AAAA,gBACV,OAAO;AAAA,gBACP,cAAc;AAAA,gBACd,YAAY,OAAO;AAAA,cACrB;AAAA,cACA,SACE,gBACI,SACA,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,GAAG,SAAS,CAAC,KAAK,GAAG,GAAG,EAAE;AAAA,cAEnD,YAAY;AAAA,gBACV,QAAQ,gBAAgB,IAAI;AAAA,gBAC5B,UAAU;AAAA,gBACV,MAAM;AAAA,cACR;AAAA;AAAA,UACF;AAAA,UACA,gBAAAH;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,UAAU;AAAA,gBACV,SAAS;AAAA,gBACT,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACR,cAAc;AAAA,gBACd,YAAY,OAAO;AAAA,cACrB;AAAA;AAAA,UACF;AAAA;AAAA;AAAA,IACF;AAAA,EAEJ;AAGA,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC,eAAY;AAAA,MACZ,OAAO;AAAA,QACL,UAAU;AAAA,QACV,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,YAAY;AAAA,MACd;AAAA,MAEA;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,OAAO;AAAA,cACP,cAAc;AAAA,cACd,YAAY,OAAO;AAAA,YACrB;AAAA;AAAA,QACF;AAAA,QACA,gBAAAA;AAAA,UAACG,QAAO;AAAA,UAAP;AAAA,YACC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,OAAO;AAAA,cACP,cAAc;AAAA,cACd,QAAQ;AAAA,cACR,gBAAgB,OAAO;AAAA,cACvB,kBAAkB,OAAO;AAAA,YAC3B;AAAA,YACA,SAAS,gBAAgB,SAAY,EAAE,QAAQ,IAAI;AAAA,YACnD,YAAY;AAAA,cACV,QAAQ,gBAAgB,IAAI;AAAA,cAC5B,UAAU;AAAA,cACV,MAAM;AAAA,YACR;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF;AAEJ;;;AC1UA,SAAS,UAAAC,eAAc;AACvB,SAAS,QAAQ,MAAM,OAAO,aAAa;AAC3C,SAAS,aAAAC,aAAW,YAAAC,kBAAgB;AAyC9B,gBAAAC,OAqBF,QAAAC,cArBE;AAXN,SAAS,WAAW,MAA6B;AAC/C,MAAI,SAAS,EAAG,QAAO;AACvB,MAAI,SAAS,EAAG,QAAO;AACvB,MAAI,SAAS,EAAG,QAAO;AACvB,SAAO;AACT;AAEA,SAAS,SAAS,EAAE,MAAM,MAAM,GAAmC;AACjE,QAAM,SAAS,iBAAiB,OAAO,WAAW,IAAI,CAAC;AACvD,MAAI,SAAS,GAAG;AACd,WACE,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,aAAa;AAAA,QACb,eAAY;AAAA,QACZ,OAAO,EAAE,OAAO,OAAO,MAAM;AAAA;AAAA,IAC/B;AAAA,EAEJ;AACA,MAAI,SAAS,KAAK,SAAS,GAAG;AAC5B,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,aAAa;AAAA,QACb,eAAY;AAAA,QACZ,OAAO,EAAE,OAAO,OAAO,MAAM;AAAA;AAAA,IAC/B;AAAA,EAEJ;AACA,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,OAAO;AAAA,QACP,WAAW;AAAA,QACX,OAAO,MAAM,SAAS,KAAK;AAAA,QAC3B,YAAY,MAAM,WAAW,WAAW;AAAA,QACxC,YAAY,MAAM,WAAW,WAAW;AAAA,MAC1C;AAAA,MACD;AAAA;AAAA,QACG;AAAA;AAAA;AAAA,EACJ;AAEJ;AAEO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA;AACF,GAAwB;AACtB,QAAM,QAAQ,SAAS;AACvB,QAAM,gBAAgB,MAAM,OAAO,kBAAkB;AACrD,QAAM,CAAC,QAAQ,SAAS,IAAIC,WAAS,UAAU;AAE/C,EAAAC,YAAU,MAAM;AACd,cAAU,UAAU;AAAA,EACtB,GAAG,CAAC,UAAU,CAAC;AAEf,MAAI,CAAC,WAAY,QAAO;AAExB,QAAM,SAAS,OAAO,KAAK,CAAC,MAAM,EAAE,QAAQ,KAAK,OAAO,CAAC;AACzD,QAAM,eAAe,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AACjE,QAAM,gBAAgB,MAAM,SAAS,OAAO;AAC5C,QAAM,QAAQ,GAAG,QAAQ,QAAQ,MAAM;AAEvC,SACE,gBAAAH,MAAC,UAAO,MAAM,QAAQ,cAAc,WAClC,0BAAAC;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,oDAAoD,aAAa,EAAE;AAAA,MAC9E,kBAAiB;AAAA,MACjB,oBAAkB;AAAA,MAClB,OAAO;AAAA,QACL,GAAG,aAAa,OAAO,EAAE,MAAM,SAAS,QAAQ,MAAM,CAAC;AAAA,QACvD,OAAO;AAAA,QACP,UAAU;AAAA,QACV,SAAS,GAAG,MAAM,MAAM,CAAC,CAAC,IAAI,MAAM,MAAM,CAAC,CAAC;AAAA,QAC5C,WAAW;AAAA,QACX,WAAW,MAAM,UAAU;AAAA,QAC3B,UAAU;AAAA,QACV,iBAAiB,kCAAkC,cAAc,IAAI,QAAQ,MAAM,SAAS,QAAQ,KAAK;AAAA,QACzG,YAAY,MAAM,WAAW,WAAW;AAAA,MAC1C;AAAA,MAEA;AAAA,wBAAAD,MAAC,eAAY,WAAU,WAAW,iBAAM;AAAA,QAGxC,gBAAAA;AAAA,UAACI,QAAO;AAAA,UAAP;AAAA,YACC,SACE,gBACI,EAAE,OAAO,EAAE,IACX,EAAE,OAAO,MAAM,QAAQ,MAAM,SAAS,EAAE;AAAA,YAE9C,SACE,gBAAgB,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,EAAE;AAAA,YAEnE,YAAY;AAAA,cACV,MAAM;AAAA,cACN,WAAW;AAAA,cACX,SAAS;AAAA,cACT,OAAO,gBAAgB,IAAI;AAAA,YAC7B;AAAA,YACA,OAAO;AAAA,cACL,cAAc,MAAM,MAAM,CAAC;AAAA,cAC3B,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,gBAAgB;AAAA,cAChB,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,cAAc,MAAM,OAAO;AAAA,cAC3B,YAAY,cAAc;AAAA,cAC1B,QAAQ,aAAa,cAAc,MAAM;AAAA,cACzC,WAAW,MAAM,UAAU;AAAA,YAC7B;AAAA,YAEA,0BAAAJ;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACR,aAAa;AAAA,gBACb,eAAY;AAAA,gBACZ,OAAO,EAAE,OAAO,cAAc,MAAM;AAAA;AAAA,YACtC;AAAA;AAAA,QACF;AAAA,QAEA,gBAAAC;AAAA,UAACG,QAAO;AAAA,UAAP;AAAA,YACC,SAAS,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,GAAG,GAAG;AAAA,YAC9D,SAAS,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,YAC7D,YAAY,EAAE,OAAO,gBAAgB,IAAI,IAAI;AAAA,YAE7C;AAAA,8BAAAJ;AAAA,gBAAC;AAAA;AAAA,kBACC,eAAY;AAAA,kBACZ,OAAO;AAAA,oBACL,QAAQ;AAAA,oBACR,YAAY,MAAM,WAAW,WAAW;AAAA,oBACxC,UAAU,MAAM,WAAW,SAAS,KAAK;AAAA,oBACzC,YAAY,MAAM,WAAW,WAAW;AAAA,oBACxC,OAAO,MAAM,SAAS,KAAK;AAAA,oBAC3B,cAAc,MAAM,MAAM,CAAC;AAAA,oBAC3B,YAAY,MAAM,WAAW,WAAW;AAAA,kBAC1C;AAAA,kBAEC;AAAA;AAAA,cACH;AAAA,cACC,iBACC,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,QAAQ;AAAA,oBACR,cAAc,MAAM,MAAM,CAAC;AAAA,oBAC3B,SAAS;AAAA,oBACT,GAAG,UAAU,OAAO,EAAE,SAAS,WAAW,MAAM,KAAK,CAAC;AAAA,oBACtD,UAAU,MAAM,WAAW,SAAS;AAAA,kBACtC;AAAA,kBAEC;AAAA;AAAA,cACH;AAAA;AAAA;AAAA,QAEJ;AAAA,QAEA,gBAAAA;AAAA,UAACI,QAAO;AAAA,UAAP;AAAA,YACC,SAAS,EAAE,SAAS,EAAE;AAAA,YACtB,SAAS,EAAE,SAAS,EAAE;AAAA,YACtB,YAAY,EAAE,OAAO,gBAAgB,IAAI,IAAI;AAAA,YAC7C,OAAO;AAAA,cACL,SAAS;AAAA,cACT,eAAe;AAAA,cACf,KAAK,MAAM,MAAM,CAAC;AAAA,cAClB,cAAc,MAAM,MAAM,CAAC;AAAA,cAC3B,WAAW;AAAA,YACb;AAAA,YACA,MAAK;AAAA,YACL,cAAW;AAAA,YAEV,uBAAa,IAAI,CAAC,QAAQ,UAAU;AACnC,oBAAM,OAAO,QAAQ;AACrB,oBAAM,SAAS,iBAAiB,OAAO,WAAW,IAAI,CAAC;AACvD,oBAAM,WAAW,OAAO,YAAY,SAAS;AAC7C,qBACE,gBAAAH;AAAA,gBAACG,QAAO;AAAA,gBAAP;AAAA,kBAEC,SACE,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,GAAG,IAAI;AAAA,kBAExD,SAAS,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,kBAC7D,YAAY;AAAA,oBACV,OAAO,gBAAgB,IAAI,MAAM,QAAQ;AAAA,kBAC3C;AAAA,kBACA,OAAO;AAAA,oBACL,SAAS;AAAA,oBACT,YAAY;AAAA,oBACZ,gBAAgB;AAAA,oBAChB,SAAS,MAAM,MAAM,CAAC;AAAA,oBACtB,YAAY,WACR,OAAO,OACP,MAAM,SAAS,QAAQ;AAAA,oBAC3B,QAAQ,aACN,WAAW,OAAO,SAAS,MAAM,SAAS,OAAO,MACnD;AAAA,oBACA,cAAc,MAAM,OAAO;AAAA,oBAC3B,WAAW,WACP,MAAM,UAAU,QAChB,MAAM,UAAU;AAAA,kBACtB;AAAA,kBACA,MAAK;AAAA,kBAEL;AAAA,oCAAAH;AAAA,sBAAC;AAAA;AAAA,wBACC,OAAO;AAAA,0BACL,SAAS;AAAA,0BACT,YAAY;AAAA,0BACZ,KAAK,MAAM,MAAM,CAAC;AAAA,wBACpB;AAAA,wBAEA;AAAA,0CAAAD,MAAC,YAAS,MAAY,OAAc;AAAA,0BACpC,gBAAAA;AAAA,4BAAC;AAAA;AAAA,8BACC,OAAO;AAAA,gCACL,YAAY,MAAM,WAAW,WAAW;AAAA,gCACxC,UAAU,MAAM,WAAW,SAAS;AAAA,gCACpC,YAAY,MAAM,WAAW,WAAW;AAAA,gCACxC,OAAO,WACH,OAAO,SACP,MAAM,SAAS,KAAK;AAAA,8BAC1B;AAAA,8BAEC,iBAAO;AAAA;AAAA,0BACV;AAAA,0BACC,YACC,gBAAAA;AAAA,4BAAC;AAAA;AAAA,8BACC,OAAO;AAAA,8BACP,QAAQ;AAAA,8BACR,aAAa;AAAA,8BACb,cAAW;AAAA,8BACX,OAAO,EAAE,OAAO,OAAO,MAAM;AAAA;AAAA,0BAC/B;AAAA;AAAA;AAAA,oBAEJ;AAAA,oBACA,gBAAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,OAAO;AAAA,0BACL,YAAY,MAAM,WAAW,WAAW;AAAA,0BACxC,UAAU,MAAM,WAAW,SAAS,KAAK;AAAA,0BACzC,YAAY,MAAM,WAAW,WAAW;AAAA,0BACxC,OAAO,WACH,OAAO,SACP,MAAM,SAAS,KAAK;AAAA,0BACxB,eAAe,MAAM,MAAM,CAAC;AAAA,0BAC5B,cAAc,MAAM,MAAM,GAAG;AAAA,0BAC7B,YAAY,MAAM,SAAS,QAAQ;AAAA,0BACnC,cAAc,MAAM,OAAO;AAAA,0BAC3B,QAAQ,aAAa,MAAM,SAAS,OAAO,MAAM;AAAA,wBACnD;AAAA,wBAEC,iBAAO;AAAA;AAAA,oBACV;AAAA;AAAA;AAAA,gBAxEK,OAAO;AAAA,cAyEd;AAAA,YAEJ,CAAC;AAAA;AAAA,QACH;AAAA,QAEC,eAAe,QAAQ,WACtB,gBAAAC;AAAA,UAACG,QAAO;AAAA,UAAP;AAAA,YACC,SAAS,EAAE,SAAS,EAAE;AAAA,YACtB,SAAS,EAAE,SAAS,EAAE;AAAA,YACtB,YAAY,EAAE,OAAO,gBAAgB,IAAI,IAAI;AAAA,YAC7C,OAAO;AAAA,cACL,cAAc,MAAM,MAAM,CAAC;AAAA,cAC3B,SAAS,MAAM,MAAM,CAAC;AAAA,cACtB,YAAY,MAAM,SAAS,QAAQ;AAAA,cACnC,QAAQ,cAAc,MAAM,SAAS,OAAO,OAAO;AAAA,cACnD,cAAc,MAAM,OAAO;AAAA,cAC3B,WAAW;AAAA,YACb;AAAA,YAEA;AAAA,8BAAAH;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,QAAQ;AAAA,oBACR,cAAc,MAAM,MAAM,CAAC;AAAA,oBAC3B,YAAY,MAAM,WAAW,WAAW;AAAA,oBACxC,UAAU,MAAM,WAAW,SAAS;AAAA,oBACpC,YAAY,MAAM,WAAW,WAAW;AAAA,oBACxC,OAAO,MAAM,SAAS,KAAK;AAAA,oBAC3B,SAAS;AAAA,oBACT,YAAY;AAAA,oBACZ,KAAK,MAAM,MAAM,CAAC;AAAA,kBACpB;AAAA,kBAEA;AAAA,oCAAAD;AAAA,sBAAC;AAAA;AAAA,wBACC,OAAO;AAAA,0BACL,OAAO;AAAA,0BACP,QAAQ;AAAA,0BACR,YAAY,MAAM,SAAS,OAAO,QAAQ;AAAA,0BAC1C,cAAc,MAAM,OAAO;AAAA,0BAC3B,SAAS;AAAA,wBACX;AAAA;AAAA,oBACF;AAAA,oBAAE;AAAA;AAAA;AAAA,cAEJ;AAAA,cACA,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,SAAS;AAAA,oBACT,eAAe;AAAA,oBACf,KAAK,MAAM,MAAM,CAAC;AAAA,kBACpB;AAAA,kBAEC,iBAAO,QAAQ,OAAO,OAAO,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAC9C,gBAAAC;AAAA,oBAAC;AAAA;AAAA,sBAEC,OAAO;AAAA,wBACL,SAAS;AAAA,wBACT,gBAAgB;AAAA,wBAChB,UAAU,MAAM,WAAW,SAAS;AAAA,wBACpC,OAAO,MAAM,SAAS,KAAK;AAAA,sBAC7B;AAAA,sBAEA;AAAA,wCAAAD,MAAC,UAAK,OAAO,EAAE,eAAe,aAAa,GACxC,cAAI,QAAQ,YAAY,KAAK,GAChC;AAAA,wBACA,gBAAAA;AAAA,0BAAC;AAAA;AAAA,4BACC,OAAO;AAAA,8BACL,YAAY,MAAM,WAAW,WAAW;AAAA,8BACxC,YAAY,MAAM,WAAW,WAAW;AAAA,4BAC1C;AAAA,4BAEC;AAAA;AAAA,wBACH;AAAA;AAAA;AAAA,oBAlBK;AAAA,kBAmBP,CACD;AAAA;AAAA,cACH;AAAA;AAAA;AAAA,QACF;AAAA,QAGD,mBACC,gBAAAA;AAAA,UAACI,QAAO;AAAA,UAAP;AAAA,YACC,SAAS,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,GAAG,GAAG;AAAA,YAC9D,SAAS,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,YAC7D,YAAY,EAAE,OAAO,gBAAgB,IAAI,EAAE;AAAA,YAC3C,OAAO,EAAE,SAAS,QAAQ,gBAAgB,SAAS;AAAA,YAEnD,0BAAAH;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,SAAS;AAAA,gBACT,OAAO;AAAA,kBACL,KAAK,MAAM,MAAM,CAAC;AAAA,gBACpB;AAAA,gBAEA;AAAA,kCAAAD,MAAC,QAAK,MAAM,IAAI,aAAa,GAAG,eAAY,QAAO;AAAA,kBAAE;AAAA;AAAA;AAAA,YAEvD;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EAEJ,GACF;AAEJ;;;ACxYA,SAAS,WAAAK,iBAA+B;AACxC,SAAS,QAAAC,cAAY;;;ACJd,SAAS,yBACd,OACA,YACA,SACM;AACN,MAAI,CAAC,YAAY;AACf;AAAA,EACF;AAEA,MAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAK;AAC9C;AAAA,EACF;AAEA,QAAM,eAAe;AACrB,MAAI,SAAS,iBAAiB;AAC5B,UAAM,gBAAgB;AAAA,EACxB;AACA,aAAW;AACb;;;ADwGI,SA2GI,YAAAC,WA7FF,OAAAC,OAdF,QAAAC,cAAA;AA1DJ,IAAM,sBAAqC,CAAC;AAC5C,IAAM,uBAAuC,CAAC;AAsBvC,SAAS,mBAAmB;AAAA,EACjC,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AAAA,EACT,cAAc;AAAA,EACd,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB;AAAA,EACA,iBAAiB;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4B;AAC1B,QAAM,gBAAgB,aAClB,YACA,gBACE,YACA;AAEN,QAAM,kBAAkB,aACpB,YACA,gBACE,YACA;AAEN,QAAM,uBAAuB,cAAc,gBAAgB,IAAI;AAE/D,QAAM,eAAe,QACjB,MAAM,SAAS,iBACb,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,WACrC,QACF;AAEJ,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,CAAC,UAAU,yBAAyB,OAAO,OAAO;AAAA,MAC7D,WAAWC;AAAA,QACT;AAAA,QACA,WAAW;AAAA,QACX;AAAA,MACF;AAAA,MACA,MAAM,UAAU,WAAW;AAAA,MAC3B,UAAU,UAAU,IAAI;AAAA,MACxB,cAAY,UAAW,SAAS,iBAAkB;AAAA,MAElD;AAAA,wBAAAF;AAAA,UAAC;AAAA;AAAA,YACC,GAAG;AAAA,YACH,MAAM;AAAA,YACN,QAAQ;AAAA,YACR,aAAa;AAAA;AAAA,QACf;AAAA,QACC,gBACC,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,YAAW;AAAA,YACX,kBAAiB;AAAA,YACjB,MAAK;AAAA,YACL,UAAU;AAAA,YACV,YAAW;AAAA,YAEV;AAAA;AAAA,QACH;AAAA;AAAA;AAAA,EAEJ;AAEJ;AAkBO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4B;AAC1B,QAAM,iBAAiB,aACnB,YACA,gBACE,YACA;AAEN,QAAM,iBACJ,cAAc,gBAAgB,cAAc,IAAI;AAElD,QAAM,QAAQ,KAAK,IAAI,GAAG,KAAK;AAC/B,QAAM,QAAQ,KAAK,IAAI,GAAG,KAAK;AAE/B,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,CAAC,UAAU,yBAAyB,OAAO,OAAO;AAAA,MAC7D,WAAWC;AAAA,QACT;AAAA,QACA,WAAW;AAAA,QACX;AAAA,MACF;AAAA,MACA,MAAM,UAAU,WAAW;AAAA,MAC3B,UAAU,UAAU,IAAI;AAAA,MACxB,cACE,UACI,UAAU,SACR,gBAAgB,KAAK,KACrB,iBACF;AAAA,MAGN;AAAA,wBAAAF;AAAA,UAAC;AAAA;AAAA,YACC,IAAI,KAAK;AAAA,YACT,IAAI,KAAK;AAAA,YACT,IAAI,GAAG;AAAA,YACP,IAAI,GAAG;AAAA,YACP,QAAQ;AAAA,YACR,aAAa;AAAA,YACb,eAAc;AAAA;AAAA,QAChB;AAAA,QACC,UAAU,UACT,gBAAAC,OAAAF,WAAA,EACE;AAAA,0BAAAC;AAAA,YAAC;AAAA;AAAA,cACC,IAAI;AAAA,cACJ,IAAI;AAAA,cACJ,GAAG;AAAA,cACH,MAAK;AAAA,cACL,QAAO;AAAA,cACP,aAAa;AAAA;AAAA,UACf;AAAA,UACA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,GAAG;AAAA,cACH,GAAG;AAAA,cACH,YAAW;AAAA,cACX,kBAAiB;AAAA,cACjB,MAAK;AAAA,cACL,UAAU;AAAA,cACV,YAAW;AAAA,cAEV;AAAA;AAAA,UACH;AAAA,WACF;AAAA;AAAA;AAAA,EAEJ;AAEJ;AASO,SAAS,oBAAoB;AAAA,EAClC,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR;AAAA,EACA;AACF,GAA6B;AAC3B,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAW,CAAC,UAAU,yBAAyB,OAAO,OAAO;AAAA,MAC7D,WAAWE,OAAK,WAAW,kBAAkB,SAAS;AAAA,MACtD,MAAM,UAAU,WAAW;AAAA,MAC3B,UAAU,UAAU,IAAI;AAAA,MACxB,cAAY,UAAU,kBAAkB;AAAA,MAEvC,oBAAU,WACT,gBAAAF;AAAA,QAAC;AAAA;AAAA,UACC,GAAG,CAAC;AAAA,UACJ,GAAG,CAAC;AAAA,UACJ,OAAO,SAAS;AAAA,UAChB,QAAQ,SAAS;AAAA,UACjB,MAAM;AAAA,UACN,QAAO;AAAA,UACP,aAAa;AAAA;AAAA,MACf,IAEA,gBAAAA,MAAC,YAAO,GAAG,QAAQ,MAAM,OAAO,QAAO,SAAQ,aAAa,KAAK;AAAA;AAAA,EAErE;AAEJ;AAMO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA,QAAQ;AAAA,EACR,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV;AACF,GAAsB;AAEpB,QAAM,EAAE,WAAW,MAAM,WAAW,IAAI,WAAW;AAAA,IACjD,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,EACR,CAAC;AAGD,QAAM,eAAeG,UAAQ,MAAM;AACjC,UAAM,MAAsC,CAAC;AAC7C,WAAO,QAAQ,CAAC,MAAM;AACpB,YAAM,SAAS,EAAE;AACjB,YAAM,WAAW,IAAI,MAAM;AAC3B,UAAI,UAAU;AACZ,iBAAS,KAAK,CAAC;AAAA,MACjB,OAAO;AACL,YAAI,MAAM,IAAI,CAAC,CAAC;AAAA,MAClB;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT,GAAG,CAAC,MAAM,CAAC;AAGX,QAAM,UAAUA,UAAQ,MAAM;AAC5B,WAAO,OAAO,YAAY,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAAA,EACvD,GAAG,CAAC,KAAK,CAAC;AAGV,QAAM,SAASA,UAAQ,MAAM;AAC3B,QAAI,MAAM,WAAW,GAAG;AACtB,aAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,KAAK,QAAQ,IAAI;AAAA,IACrD;AAEA,QAAI,OAAO,UACT,OAAO,UACP,OAAO,WACP,OAAO;AACT,UAAM,QAAQ,CAAC,SAAS;AACtB,aAAO,KAAK,IAAI,MAAM,KAAK,SAAS,IAAI,UAAU;AAClD,aAAO,KAAK,IAAI,MAAM,KAAK,SAAS,IAAI,UAAU;AAClD,aAAO,KAAK,IAAI,MAAM,KAAK,SAAS,IAAI,UAAU;AAClD,aAAO,KAAK,IAAI,MAAM,KAAK,SAAS,IAAI,UAAU;AAAA,IACpD,CAAC;AAED,WAAO;AAAA,MACL,MAAM,OAAO;AAAA,MACb,MAAM,OAAO;AAAA,MACb,OAAO,OAAO,OAAO,UAAU;AAAA,MAC/B,QAAQ,OAAO,OAAO,UAAU;AAAA,IAClC;AAAA,EACF,GAAG,CAAC,OAAO,YAAY,OAAO,CAAC;AAG/B,QAAM,UAAU,iBAAiB,QAAQ,SAAS;AAGlD,QAAM,eAAe,QAAQ,MAAM,GAAG,EAAE,IAAI,MAAM;AAClD,QAAM,WAAW,aAAa,CAAC,KAAK;AACpC,QAAM,WAAW,aAAa,CAAC,KAAK;AACpC,QAAM,gBAAgB,aAAa,CAAC,KAAK;AAEzC,SACE,gBAAAF;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAWC;AAAA,QACT;AAAA,QACA,iBAAiB;AAAA,QACjB,cAAc;AAAA,QACd,iBAAiB,CAAC,cAAc;AAAA,QAChC;AAAA,MACF;AAAA,MACC,GAAG,KAAK;AAAA,MACT,MAAK;AAAA,MACL,cAAW;AAAA,MAGX;AAAA,wBAAAF,MAAC,OAAE,WAAU,iBAAgB,MAAK,QAAO,cAAW,uBACjD,gBAAM,IAAI,CAAC,SAAS;AACnB,gBAAM,WAAW,QAAQ,KAAK,IAAI;AAClC,gBAAM,SAAS,QAAQ,KAAK,EAAE;AAC9B,cAAI,CAAC,YAAY,CAAC,OAAQ,QAAO;AAEjC,iBACE,gBAAAA;AAAA,YAAC;AAAA;AAAA,cAEC,MAAK;AAAA,cACL,cAAY,aAAa,SAAS,SAAS,SAAS,EAAE,OAAO,OAAO,SAAS,OAAO,EAAE;AAAA,cAErF,qBAAW,MAAM,UAAU,MAAM;AAAA;AAAA,YAJ7B,KAAK;AAAA,UAKZ;AAAA,QAEJ,CAAC,GACH;AAAA,QAGA,gBAAAA,MAAC,OAAE,WAAU,iBAAgB,MAAK,QAAO,cAAW,iBACjD,gBAAM,IAAI,CAAC,SAAS;AACnB,gBAAM,aAAa,aAAa,KAAK,EAAE,KAAK,CAAC;AAE7C,iBACE,gBAAAC;AAAA,YAAC;AAAA;AAAA,cAEC,WAAW,aAAa,KAAK,SAAS,CAAC,KAAK,KAAK,SAAS,CAAC;AAAA,cAC3D,MAAK;AAAA,cACL,cAAY,KAAK,SAAS,KAAK;AAAA,cAE9B;AAAA,2BAAW,MAAM,UAAU;AAAA,gBAG3B,WAAW,SAAS,KACnB,gBAAAD,MAAC,OAAE,WAAU,eACV,qBAAW,IAAI,CAAC,OAAO,MAAM;AAC5B,wBAAM,QACH,IAAI,WAAW,SAAU,IAAI,KAAK,KAAK,KAAK,KAAK;AACpD,wBAAM,SAAS,KAAK,IAAI,KAAK,KAAK,aAAa;AAC/C,wBAAM,SAAS,KAAK,IAAI,KAAK,KAAK,aAAa;AAE/C,yBACE,gBAAAA;AAAA,oBAAC;AAAA;AAAA,sBAEC,WAAW,aAAa,MAAM,KAAK,MAAM;AAAA,sBAExC,sBAAY,OAAO,EAAE,GAAG,QAAQ,GAAG,OAAO,CAAC;AAAA;AAAA,oBAHvC,MAAM;AAAA,kBAIb;AAAA,gBAEJ,CAAC,GACH;AAAA;AAAA;AAAA,YAzBG,KAAK;AAAA,UA2BZ;AAAA,QAEJ,CAAC,GACH;AAAA,QAGC,iBAAiB,UAAU,SAAS,KACnC,gBAAAC;AAAA,UAAC;AAAA;AAAA,YACC,WAAW,aAAa,WAAW,EAAE,KAAK,WAAW,gBAAgB,EAAE;AAAA,YAEvE;AAAA,8BAAAD;AAAA,gBAAC;AAAA;AAAA,kBACC,GAAG;AAAA,kBACH,GAAG;AAAA,kBACH,OAAO;AAAA,kBACP,QAAQ;AAAA,kBACR,IAAI;AAAA,kBACJ,MAAK;AAAA;AAAA,cACP;AAAA,cACA,gBAAAC,OAAC,UAAK,GAAG,IAAI,GAAG,IAAI,YAAW,UAAS,MAAK,SAAQ,UAAU,IAC5D;AAAA,qBAAK,MAAM,UAAU,OAAO,GAAG;AAAA,gBAAE;AAAA,iBACpC;AAAA;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EAEJ;AAEJ;;;AEvdA,SAAS,WAAAG,iBAA+B;AACxC,SAAS,QAAAC,cAAY;AAkIX,gBAAAC,OAqEF,QAAAC,cArEE;AAvEV,IAAM,mBAAsD;AAAA,EAC1D,OAAO;AAAA;AAAA,EACP,UAAU;AAAA;AAAA,EACV,QAAQ;AAAA;AAAA,EACR,QAAQ;AAAA;AAAA,EACR,SAAS;AAAA;AACX;AAEA,IAAM,oBAAuD;AAAA,EAC3D,OAAO;AAAA,EACP,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AACX;AAEA,IAAM,sBAA8C,CAAC;AAiB9C,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA,OAAO;AAAA,EACP,SAAS;AAAA,EACT,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB;AAAA,EACA,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AAEnB,MAAI,eAAe;AACnB,MAAI,iBAAiB;AACrB,MAAI,sBAAsB;AAE1B,MAAI,iBAAiB,iBAAiB,iBAAiB,aAAa,GAAG;AACrE,mBAAe,iBAAiB,aAAa;AAC7C,qBAAiB,kBAAkB,aAAa;AAChD,0BAAsB;AAAA,EACxB,WAAW,YAAY;AACrB,mBAAe,iBAAiB;AAChC,qBAAiB,kBAAkB;AACnC,0BAAsB;AAAA,EACxB;AAGA,QAAM,cAAc,MAAM;AACxB,QAAI,CAAC,KAAK,MAAO,QAAO;AAExB,YAAQ,KAAK,MAAM,MAAM;AAAA,MACvB,KAAK;AACH,YAAI,CAAC,KAAK,MAAM,OAAQ,QAAO;AAC/B,eACE,gBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,QAAQ,KAAK,MAAM,OAAO,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,KAAK,GAAG;AAAA,YAC9D,MAAM;AAAA,YACN,QAAQ;AAAA,YACR,aAAa;AAAA;AAAA,QACf;AAAA,MAGJ,KAAK;AACH,YAAI,CAAC,KAAK,MAAM,KAAM,QAAO;AAC7B,eACE,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAG,KAAK,MAAM;AAAA,YACd,MAAM;AAAA,YACN,QAAQ;AAAA,YACR,aAAa;AAAA;AAAA,QACf;AAAA,MAGJ,KAAK;AACH,YAAI,CAAC,KAAK,MAAM,OAAQ,QAAO;AAC/B,eACE,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,IAAI,KAAK,MAAM,OAAO;AAAA,YACtB,IAAI,KAAK,MAAM,OAAO;AAAA,YACtB,GAAG,KAAK,MAAM,UAAU;AAAA,YACxB,MAAM;AAAA,YACN,QAAQ;AAAA,YACR,aAAa;AAAA;AAAA,QACf;AAAA,MAGJ;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAEA,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,cAAc,MAAM,UAAU,IAAI;AAAA,MAClC,cAAc,MAAM,UAAU,KAAK;AAAA,MACnC,WAAW,CAAC,UAAU,yBAAyB,OAAO,OAAO;AAAA,MAC7D,WAAWC,OAAK,WAAW,kBAAkB,SAAS;AAAA,MACtD,MAAM,UAAU,WAAW;AAAA,MAC3B,cAAY,KAAK;AAAA,MACjB,UAAU,UAAU,IAAI;AAAA,MAGvB;AAAA,oBAAY;AAAA,QAGZ,aAAa,KAAK,OAAO,UACxB,gBAAAF;AAAA,UAAC;AAAA;AAAA,YACC,GAAG,KAAK,MAAM,OAAO;AAAA,YACrB,GAAG,KAAK,MAAM,OAAO,KAAK,YAAY,IAAI;AAAA,YAC1C,YAAW;AAAA,YACX,kBAAiB;AAAA,YACjB,MAAK;AAAA,YACL,UAAU;AAAA,YACV,YAAW;AAAA,YACX,OAAO,EAAE,YAAY,8BAA8B;AAAA,YAElD,eAAK;AAAA;AAAA,QACR;AAAA,QAID,aAAa,KAAK,UAAU,UAAa,KAAK,OAAO,UACpD,gBAAAC;AAAA,UAAC;AAAA;AAAA,YACC,GAAG,KAAK,MAAM,OAAO;AAAA,YACrB,GAAG,KAAK,MAAM,OAAO,IAAI;AAAA,YACzB,YAAW;AAAA,YACX,kBAAiB;AAAA,YACjB,MAAK;AAAA,YACL,UAAU;AAAA,YACV,YAAW;AAAA,YACX,OAAO,EAAE,YAAY,8BAA8B;AAAA,YACpD;AAAA;AAAA,cACG,KAAK;AAAA;AAAA;AAAA,QACT;AAAA,QAID;AAAA;AAAA;AAAA,EACH;AAEJ;AAWO,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf,SAAS;AAAA,EACT,UAAU;AAAA,EACV,UAAU;AAAA,EACV;AACF,GAA2B;AACzB,MAAI,OAAO,WAAW,KAAK,CAAC,KAAK,OAAO,OAAQ,QAAO;AAEvD,QAAM,UAAU,KAAK,MAAM,OAAO;AAClC,QAAM,UAAU,KAAK,MAAM,OAAO;AAGlC,QAAM,gBAA6C,CAAC;AACpD,SAAO,QAAQ,CAAC,MAAM;AACpB,UAAM,QAAQ,EAAE,SAAS;AACzB,UAAM,WAAW,cAAc,KAAK;AACpC,QAAI,UAAU;AACZ,eAAS,KAAK,CAAC;AAAA,IACjB,OAAO;AACL,oBAAc,KAAK,IAAI,CAAC,CAAC;AAAA,IAC3B;AAAA,EACF,CAAC;AAED,QAAM,SAAS,OAAO,KAAK,aAAa;AACxC,QAAM,cAAc,GAAG,OAAO,SAAS,KAAK,WAAW;AAEvD,SACE,gBAAAD,MAAC,OAAE,WAAWE,OAAK,eAAe,SAAS,GACxC,iBAAO,IAAI,CAAC,OAAO,MAAM;AACxB,UAAM,cAAc,cAAc,KAAK,KAAK,CAAC;AAC7C,UAAM,aAAa,YAAY;AAAA,MAC7B,CAAC,KAAK,MAAM,OAAO,EAAE,SAAS;AAAA,MAC9B;AAAA,IACF;AACA,UAAM,UAAU,cAAc,IAAI;AAElC,WACE,gBAAAD;AAAA,MAAC;AAAA;AAAA,QAEC,WAAW,aAAa,UAAU,OAAO,KAAK,UAAU,OAAO;AAAA,QAG/D;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,GAAG;AAAA,cACH,MAAM,aAAa,KAAK,KAAK;AAAA,cAC7B,QAAO;AAAA,cACP,aAAa;AAAA;AAAA,UACf;AAAA,UAEA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,YAAW;AAAA,cACX,kBAAiB;AAAA,cACjB,MAAK;AAAA,cACL,UAAU;AAAA,cACV,YAAW;AAAA,cAEV;AAAA;AAAA,UACH;AAAA;AAAA;AAAA,MAnBK;AAAA,IAoBP;AAAA,EAEJ,CAAC,GACH;AAEJ;AAWO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,QAAQ;AAAA,EACR;AAAA,EACA;AACF,GAA0B;AACxB,QAAM,QAAQ,MAAM,SAAS;AAE7B,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,aAAa,CAAC,KAAK,CAAC;AAAA,MAC/B,SAAS,CAAC,MAAM;AACd,UAAE,gBAAgB;AAClB,kBAAU;AAAA,MACZ;AAAA,MACA,WAAW,CAAC,UACV,yBAAyB,OAAO,SAAS,EAAE,iBAAiB,KAAK,CAAC;AAAA,MAEpE,WAAWC,OAAK,WAAW,kBAAkB,SAAS;AAAA,MACtD,MAAM,UAAU,WAAW;AAAA,MAC3B,UAAU,UAAU,IAAI;AAAA,MACxB,cAAY,SAAS,MAAM,EAAE;AAAA,MAE7B;AAAA,wBAAAF,MAAC,YAAO,GAAG,QAAQ,MAAM,OAAO,QAAO,SAAQ,aAAa,GAAG;AAAA,QAC/D,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,YAAW;AAAA,YACX,kBAAiB;AAAA,YACjB,MAAK;AAAA,YACL,UAAU;AAAA,YACV,YAAW;AAAA,YAEV;AAAA;AAAA,QACH;AAAA;AAAA;AAAA,EACF;AAEJ;AAMO,SAAS,QAAQ;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,UAAU;AAAA,EACV,UAAU;AAAA,EACV;AACF,GAAiB;AAEf,QAAM,EAAE,WAAW,MAAM,WAAW,IAAI,WAAW;AAAA,IACjD,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,EACR,CAAC;AAGD,QAAM,eAAeG,UAAQ,MAAM;AACjC,UAAM,MAAmC,CAAC;AAC1C,WAAO,QAAQ,CAAC,MAAM;AACpB,YAAM,WAAW,IAAI,EAAE,MAAM;AAC7B,UAAI,UAAU;AACZ,iBAAS,KAAK,CAAC;AAAA,MACjB,OAAO;AACL,YAAI,EAAE,MAAM,IAAI,CAAC,CAAC;AAAA,MACpB;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT,GAAG,CAAC,MAAM,CAAC;AAGX,QAAM,YAAY,OAAO,UAAU,WAAW,QAAQ;AACtD,QAAM,aAAa,OAAO,WAAW,WAAW,SAAS;AACzD,QAAM,eAAe,YAAY,UAAU;AAC3C,QAAM,gBAAgB,aAAa,UAAU;AAC7C,QAAM,YAAY,YAAY,gBAAgB,IAAI,UAAU,IAAI;AAChE,QAAM,YAAY,aAAa,iBAAiB,IAAI,UAAU,IAAI;AAElE,SACE,gBAAAF;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,SAAS,GAAG,QAAQ,IAAI,QAAQ,IAAI,YAAY,IAAI,aAAa;AAAA,MACjE,WAAWC;AAAA,QACT;AAAA,QACA,iBAAiB;AAAA,QACjB,cAAc;AAAA,QACd,iBAAiB,CAAC,cAAc;AAAA,QAChC;AAAA,MACF;AAAA,MACC,GAAG,KAAK;AAAA,MACT,MAAK;AAAA,MACL,cAAW;AAAA,MAGV;AAAA,2BACC,gBAAAF,MAAC,WAAM,MAAM,iBAAiB,OAAc,QAAgB;AAAA,QAI9D,gBAAAA,MAAC,OAAE,WAAU,SAAQ,MAAK,QAAO,cAAW,aACzC,gBAAM,IAAI,CAAC,SAAS;AACnB,gBAAM,aAAa,aAAa,KAAK,EAAE,KAAK,CAAC;AAC7C,iBAAO,gBAAAA,MAAC,OAAiB,qBAAW,MAAM,UAAU,KAArC,KAAK,EAAkC;AAAA,QACxD,CAAC,GACH;AAAA,QAGC,iBAAiB,UAAU,SAAS,KACnC,gBAAAC;AAAA,UAAC;AAAA;AAAA,YACC,WAAW,aAAa,WAAW,EAAE,KAAK,WAAW,gBAAgB,EAAE;AAAA,YAEvE;AAAA,8BAAAD;AAAA,gBAAC;AAAA;AAAA,kBACC,GAAG;AAAA,kBACH,GAAG;AAAA,kBACH,OAAO;AAAA,kBACP,QAAQ;AAAA,kBACR,IAAI;AAAA,kBACJ,MAAK;AAAA;AAAA,cACP;AAAA,cACA,gBAAAC,OAAC,UAAK,GAAG,IAAI,GAAG,IAAI,YAAW,UAAS,MAAK,SAAQ,UAAU,IAC5D;AAAA,qBAAK,MAAM,UAAU,OAAO,GAAG;AAAA,gBAAE;AAAA,iBACpC;AAAA;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EAEJ;AAEJ;;;AC1bA,SAAS,WAAAG,iBAA+B;AACxC,SAAS,QAAAC,cAAY;AAkHf,gBAAAC,OAoCE,QAAAC,cApCF;AApCC,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA,OAAO;AAAA,EACP,OAAO;AAAA,EACP,SAAS;AAAA,EACT,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,oBAAoB;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA2B;AACzB,QAAM,WAAW,OAAO;AAExB,QAAM,eAAe,gBAAgB,4BAA4B;AACjE,QAAM,iBAAiB,aACnB,YACA,gBACE,YACA;AACN,QAAM,sBAAsB,iBAAiB,aAAa,IAAI;AAE9D,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,cAAc,MAAM,UAAU,IAAI;AAAA,MAClC,cAAc,MAAM,UAAU,KAAK;AAAA,MACnC,WAAW,CAAC,UAAU,yBAAyB,OAAO,OAAO;AAAA,MAC7D,WAAWC,OAAK,WAAW,kBAAkB,SAAS;AAAA,MACtD,MAAM,UAAU,WAAW;AAAA,MAC3B,cAAY,MAAM,QAAQ,SAAS,MAAM,KAAK;AAAA,MAC9C,UAAU,UAAU,IAAI;AAAA,MAGxB;AAAA,wBAAAF;AAAA,UAAC;AAAA;AAAA,YACC,GAAG,CAAC;AAAA,YACJ,GAAG,CAAC;AAAA,YACJ,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,IAAI;AAAA,YACJ,MAAM;AAAA,YACN,QAAQ;AAAA,YACR,aAAa;AAAA;AAAA,QACf;AAAA,QAGC,MAAM,OACL,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,YAAW;AAAA,YACX,kBAAiB;AAAA,YACjB,MAAK;AAAA,YACL,UAAU,MAAM,KAAK,SAAS,IAAI,IAAI;AAAA,YACtC,YAAW;AAAA,YAEV,gBAAM,KAAK,SAAS,IAAI,MAAM,KAAK,MAAM,GAAG,CAAC,IAAI,WAAM,MAAM;AAAA;AAAA,QAChE,IAEA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,YAAW;AAAA,YACX,kBAAiB;AAAA,YACjB,MAAK;AAAA,YACL,UAAU;AAAA,YACV,YAAW;AAAA,YAEV,gBAAM;AAAA;AAAA,QACT;AAAA,QAID,qBAAqB,MAAM,UAC1B,gBAAAC,OAAC,OAAE,WAAW,aAAa,WAAW,CAAC,KAAK,CAAC,WAAW,CAAC,KACvD;AAAA,0BAAAD,MAAC,YAAO,GAAG,GAAG,MAAK,WAAU;AAAA,UAC7B,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,YAAW;AAAA,cACX,kBAAiB;AAAA,cACjB,MAAK;AAAA,cACL,UAAU;AAAA,cACV,YAAW;AAAA,cACZ;AAAA;AAAA,UAED;AAAA,WACF;AAAA,QAID;AAAA;AAAA;AAAA,EACH;AAEJ;AAWO,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR;AAAA,EACA;AACF,GAA2B;AAEzB,QAAM,UAAU,SAAS;AACzB,QAAM,QAAS,QAAQ,QAAS,IAAI,KAAK,KAAK,KAAK,KAAK;AACxD,QAAM,SAAS,QAAQ,IAAI,UAAU;AACrC,QAAM,KAAK,KAAK,IAAI,KAAK,IAAI;AAC7B,QAAM,KAAK,KAAK,IAAI,KAAK,IAAI;AAE7B,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,GAAG;AAAA,MACH,MAAM;AAAA,MACN,QAAO;AAAA,MACP,aAAa;AAAA,MACb,SAAS,CAAC,MAAM;AACd,UAAE,gBAAgB;AAClB,kBAAU;AAAA,MACZ;AAAA,MACA,WAAW,CAAC,UACV,yBAAyB,OAAO,SAAS,EAAE,iBAAiB,KAAK,CAAC;AAAA,MAEpE,WAAWE,OAAK,WAAW,kBAAkB,SAAS;AAAA,MACtD,MAAM,UAAU,WAAW;AAAA,MAC3B,UAAU,UAAU,IAAI;AAAA,MACxB,cAAY,SAAS,MAAM,EAAE,aAAa,MAAM,KAAK;AAAA;AAAA,EACvD;AAEJ;AASO,SAAS,uBAAuB;AAAA,EACrC;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT,cAAc;AAAA,EACd;AACF,GAAgC;AAC9B,SACE,gBAAAF;AAAA,IAAC;AAAA;AAAA,MACC,IAAI,KAAK;AAAA,MACT,IAAI,KAAK;AAAA,MACT,IAAI,GAAG;AAAA,MACP,IAAI,GAAG;AAAA,MACP;AAAA,MACA;AAAA,MACA,eAAc;AAAA,MACd;AAAA;AAAA,EACF;AAEJ;AAaO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,cAAc;AAAA,EACd;AACF,GAA0B;AACxB,QAAM,QAAQ,OAAO,UAAU;AAG/B,QAAM,KAAK,GAAG,IAAI,KAAK;AACvB,QAAM,KAAK,GAAG,IAAI,KAAK;AACvB,QAAM,MAAM,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;AACvC,QAAM,QAAQ,KAAK;AACnB,QAAM,QAAQ,KAAK;AAGnB,QAAM,SAAS,KAAK,IAAI,SAAS,YAAY,IAAI;AACjD,QAAM,SAAS,KAAK,IAAI,SAAS,YAAY,IAAI;AACjD,QAAM,OAAO,GAAG,IAAI,SAAS,YAAY,IAAI;AAC7C,QAAM,OAAO,GAAG,IAAI,SAAS,YAAY,IAAI;AAG7C,QAAM,WAAW,SAAS,OAAO,OAAO,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC;AAElE,SACE,gBAAAC,OAAC,OAAE,WACD;AAAA,oBAAAD,MAAC,UACC,0BAAAA;AAAA,MAAC;AAAA;AAAA,QACC,IAAI;AAAA,QACJ,aAAY;AAAA,QACZ,cAAa;AAAA,QACb,MAAK;AAAA,QACL,MAAK;AAAA,QACL,QAAO;AAAA,QAEP,0BAAAA,MAAC,aAAQ,QAAO,oBAAmB,MAAM,OAAO;AAAA;AAAA,IAClD,GACF;AAAA,IACA,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,QAAQ;AAAA,QACR;AAAA,QACA,iBAAgB;AAAA,QAChB,WAAW,QAAQ,QAAQ;AAAA;AAAA,IAC7B;AAAA,KACF;AAEJ;AAMO,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,UAAU;AAAA,EACV,UAAU;AAAA,EACV;AACF,GAAoB;AAElB,QAAM,EAAE,WAAW,MAAM,WAAW,IAAI,WAAW;AAAA,IACjD,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,EACR,CAAC;AAGD,QAAM,gBAAgBG,UAAQ,MAAM;AAClC,UAAM,MAAoC,CAAC;AAC3C,WAAO,QAAQ,CAAC,MAAM;AACpB,YAAM,WAAW,IAAI,EAAE,OAAO;AAC9B,UAAI,UAAU;AACZ,iBAAS,KAAK,CAAC;AAAA,MACjB,OAAO;AACL,YAAI,EAAE,OAAO,IAAI,CAAC,CAAC;AAAA,MACrB;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT,GAAG,CAAC,MAAM,CAAC;AAGX,QAAM,eAAeA,UAAQ,MAAM;AACjC,WAAO,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAAA,EACrD,GAAG,CAAC,MAAM,CAAC;AAGX,QAAM,WAAWA,UAAQ,MAAM;AAC7B,WAAO,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAAA,EAC7C,GAAG,CAAC,MAAM,CAAC;AAGX,QAAM,oBAAoB,MAAM;AAC9B,QAAI,CAAC,iBAAkB,QAAO;AAE9B,WAAO,aAAa,IAAI,CAAC,OAAO,MAAM;AACpC,YAAM,YAAY,aAAa,IAAI,CAAC;AACpC,YAAM,aAAa,aAAa,CAAC;AACjC,YAAM,eACJ,MAAM,eACL,IAAI,aAAa,SAAS,KAAK,YAC5B,CAAC,UAAU,EAAE,IACb,SAAS,cAAc,aACrB,CAAC,WAAW,EAAE,IACd,CAAC;AAET,aAAO,aAAa,IAAI,CAAC,WAAW;AAClC,cAAM,cAAc,SAAS,IAAI,MAAM;AACvC,YAAI,CAAC,YAAa,QAAO;AAEzB,eACE,gBAAAH,MAAC,OACE;AAAA,UACC,MAAM;AAAA,UACN,YAAY;AAAA,UACZ;AAAA,UACA;AAAA,QACF,KANM,GAAG,MAAM,EAAE,IAAI,MAAM,EAO7B;AAAA,MAEJ,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAGA,QAAM,cAAc,MAAM;AACxB,QAAI,CAAC,WAAY,QAAO;AAExB,WAAO,OAAO,QAAQ,CAAC,UAAU;AAC/B,UAAI,CAAC,MAAM,OAAQ,QAAO,CAAC;AAC3B,YAAM,cAAc,SAAS,IAAI,MAAM,MAAM;AAC7C,UAAI,CAAC,YAAa,QAAO,CAAC;AAE1B,YAAM,OAAO,YAAY,QAAQ,MAAM;AAEvC,aAAO;AAAA,QACL,gBAAAA,MAAC,OACE;AAAA,UACC,MAAM;AAAA,UACN,YAAY;AAAA,UACZ;AAAA,UACA;AAAA,UACA;AAAA,QACF,KAPM,QAAQ,MAAM,EAAE,EAQxB;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAGA,QAAM,YAAY,OAAO,UAAU,WAAW,QAAQ;AACtD,QAAM,aAAa,OAAO,WAAW,WAAW,SAAS;AACzD,QAAM,eAAe,YAAY,UAAU;AAC3C,QAAM,gBAAgB,aAAa,UAAU;AAC7C,QAAM,YAAY,YAAY,gBAAgB,IAAI,UAAU,IAAI;AAChE,QAAM,YAAY,aAAa,iBAAiB,IAAI,UAAU,IAAI;AAElE,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,SAAS,GAAG,QAAQ,IAAI,QAAQ,IAAI,YAAY,IAAI,aAAa;AAAA,MACjE,WAAWC;AAAA,QACT;AAAA,QACA,iBAAiB;AAAA,QACjB,cAAc;AAAA,QACd,iBAAiB,CAAC,cAAc;AAAA,QAChC;AAAA,MACF;AAAA,MACC,GAAG,KAAK;AAAA,MACT,MAAK;AAAA,MACL,cAAW;AAAA,MAGX;AAAA,wBAAAF,MAAC,OAAE,WAAU,qBAAqB,4BAAkB,GAAE;AAAA,QAGtD,gBAAAA,MAAC,OAAE,WAAU,eAAe,sBAAY,GAAE;AAAA,QAG1C,gBAAAA,MAAC,OAAE,WAAU,gBAAe,MAAK,QAAO,cAAW,gBAChD,iBAAO,IAAI,CAAC,UAAU;AACrB,gBAAM,cAAc,cAAc,MAAM,EAAE,KAAK,CAAC;AAEhD,iBACE,gBAAAA;AAAA,YAAC;AAAA;AAAA,cAEC,WAAW,aAAa,MAAM,SAAS,CAAC,KAAK,MAAM,SAAS,CAAC;AAAA,cAE5D,sBAAY,OAAO,WAAW;AAAA;AAAA,YAH1B,MAAM;AAAA,UAIb;AAAA,QAEJ,CAAC,GACH;AAAA,QAGC,iBAAiB,UAAU,SAAS,KACnC,gBAAAC;AAAA,UAAC;AAAA;AAAA,YACC,WAAW,aAAa,WAAW,EAAE,KAAK,WAAW,gBAAgB,EAAE;AAAA,YAEvE;AAAA,8BAAAD;AAAA,gBAAC;AAAA;AAAA,kBACC,GAAG;AAAA,kBACH,GAAG;AAAA,kBACH,OAAO;AAAA,kBACP,QAAQ;AAAA,kBACR,IAAI;AAAA,kBACJ,MAAK;AAAA;AAAA,cACP;AAAA,cACA,gBAAAC,OAAC,UAAK,GAAG,IAAI,GAAG,IAAI,YAAW,UAAS,MAAK,SAAQ,UAAU,IAC5D;AAAA,qBAAK,MAAM,UAAU,OAAO,GAAG;AAAA,gBAAE;AAAA,iBACpC;AAAA;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EAEJ;AAEJ;;;AC3eA,SAAS,WAAAG,iBAA+B;AACxC,SAAS,QAAAC,cAAY;AACrB,SAAS,OAAO,MAAM,MAAM,aAAa;AAkIjC,SACE,OAAAC,OADF,QAAAC,cAAA;AAvFR,IAAM,uBAAgD,CAAC;AAyBhD,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAyB;AACvB,QAAM,QAAQ,SAAS;AACvB,QAAM,SAAS,iBAAiB;AAChC,QAAM,cAAc,aAChB,MAAM,SAAS,OAAO,QAAQ,SAC9B,SACE,MAAM,SAAS,OAAO,SACtB,cACE,MAAM,SAAS,OAAO,UACtB,MAAM,SAAS,OAAO;AAC9B,QAAM,aAAa,aACf,MAAM,SAAS,OAAO,QAAQ,OAC9B,SACE,MAAM,SAAS,QAAQ,QACvB,MAAM,SAAS,QAAQ;AAC7B,QAAM,YAAY,aACd,MAAM,SAAS,OAAO,QAAQ,SAC9B,gBACE,MAAM,SAAS,OAAO,QAAQ,SAC9B;AAEN,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,SAAS,cAAc,UAAU;AAAA,MACjC;AAAA,MACA;AAAA,MACA,WAAW,CAAC,UACV,yBAAyB,OAAO,cAAc,UAAU,MAAS;AAAA,MAEnE,WAAWC;AAAA,QACT;AAAA,QACA,eAAe,WAAW;AAAA,QAC1B;AAAA,MACF;AAAA,MACA,OAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,WAAW,YAAY,aAAa,SAAS,KAAK;AAAA,MACpD;AAAA,MACA,MAAM,eAAe,UAAU,WAAW;AAAA,MAC1C,cAAY;AAAA,MACZ,iBAAe,CAAC;AAAA,MAChB,UAAU,eAAe,UAAU,IAAI;AAAA,MAGvC;AAAA,wBAAAD,OAAC,SAAI,WAAU,0CACb;AAAA,0BAAAA,OAAC,SACC;AAAA,4BAAAD;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,OAAO,EAAE,OAAO,MAAM,SAAS,KAAK,QAAQ;AAAA,gBAE3C;AAAA;AAAA,YACH;AAAA,YACC,eACC,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,OAAO,EAAE,OAAO,MAAM,SAAS,KAAK,MAAM;AAAA,gBAEzC;AAAA;AAAA,YACH;AAAA,aAEJ;AAAA,UAGA,gBAAAC,OAAC,SAAI,WAAU,2BACZ;AAAA,2BACC,gBAAAD;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,OAAO,EAAE,OAAO,MAAM,SAAS,OAAO,QAAQ,MAAM;AAAA,gBACpD,cAAW;AAAA;AAAA,YACb;AAAA,YAED,WAAW,KACV,gBAAAC;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,OAAO,EAAE,OAAO,MAAM,SAAS,KAAK,MAAM;AAAA,gBAC1C,OAAO,aAAa,QAAQ;AAAA,gBAE5B;AAAA,kCAAAD,MAAC,SAAM,WAAU,WAAU;AAAA,kBAC3B,gBAAAA,MAAC,UAAM,oBAAS;AAAA;AAAA;AAAA,YAClB;AAAA,aAEJ;AAAA,WACF;AAAA,SAGE,aAAa,gBACb,gBAAAC,OAAC,SAAI,WAAU,qCACZ;AAAA,uBACC,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO,EAAE,OAAO,MAAM,SAAS,OAAO,OAAO,MAAM;AAAA,cAEnD;AAAA,gCAAAD,MAAC,SAAM,WAAU,WAAU,eAAY,QAAO;AAAA,gBAC9C,gBAAAA,MAAC,UAAM,qBAAU;AAAA;AAAA;AAAA,UACnB;AAAA,UAED,eACC,gBAAAC;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO,EAAE,OAAO,MAAM,SAAS,OAAO,QAAQ,MAAM;AAAA,cAEpD;AAAA,gCAAAD,MAAC,QAAK,WAAU,WAAU,eAAY,QAAO;AAAA,gBAC7C,gBAAAA,MAAC,UAAM,uBAAY;AAAA;AAAA;AAAA,UACrB;AAAA,WAEJ;AAAA,QAID,mBAAmB,gBAAAA,MAAC,SAAI,WAAU,QAAQ,0BAAgB,GAAE;AAAA,QAG5D,CAAC,eAAe,CAAC,UAChB,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO,EAAE,OAAO,MAAM,SAAS,KAAK,SAAS;AAAA,YAC9C;AAAA;AAAA,QAED;AAAA;AAAA;AAAA,EAEJ;AAEJ;AAUO,SAAS,oBAAoB;AAAA,EAClC,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA;AACF,GAA6B;AAC3B,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAW,CAAC,UAAU,yBAAyB,OAAO,OAAO;AAAA,MAC7D,WAAWE;AAAA,QACT;AAAA,QACA,UAAU,WAAW,iBAAiB;AAAA,QACtC,WAAW;AAAA,QACX;AAAA,MACF;AAAA,MACA,OAAO;AAAA,QACL,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,iBAAiB;AAAA,MACnB;AAAA,MACA,OAAO;AAAA,MACP,MAAM,UAAU,WAAW;AAAA,MAC3B,cAAY,SAAS;AAAA,MACrB,UAAU,UAAU,IAAI;AAAA;AAAA,EAC1B;AAEJ;AAMO,SAAS,iBAAiB;AAAA,EAC/B,OAAO;AAAA,EACP;AACF,GAA0B;AACxB,QAAM,QAAQ,SAAS;AAEvB,SACE,gBAAAF;AAAA,IAAC;AAAA;AAAA,MACC,WAAWE,OAAK,uCAAuC,SAAS;AAAA,MAChE,OAAO;AAAA,QACL,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,aAAa,MAAM,SAAS,OAAO;AAAA,MACrC;AAAA,MACA,OAAM;AAAA,MACN,MAAK;AAAA,MACL,cAAW;AAAA;AAAA,EACb;AAEJ;AAMO,SAAS,WAAW;AAAA,EACzB;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf;AACF,GAAoB;AAClB,QAAM,QAAQ,SAAS;AAGvB,QAAM,kBAAkBC,UAAQ,MAAM;AACpC,UAAM,MAAsC,CAAC;AAC7C,cAAU,QAAQ,CAAC,MAAM;AACvB,YAAM,SAAS,EAAE;AACjB,YAAM,WAAW,IAAI,MAAM;AAC3B,UAAI,UAAU;AACZ,iBAAS,KAAK,CAAC;AAAA,MACjB,OAAO;AACL,YAAI,MAAM,IAAI,CAAC,CAAC;AAAA,MAClB;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT,GAAG,CAAC,SAAS,CAAC;AAGd,QAAM,aAAaA,UAAQ,MAAM;AAC/B,QAAI,WAAW,UAAW,QAAO;AAEjC,UAAM,SAA2C,CAAC;AAClD,UAAM,QAAQ,CAAC,SAAS;AACtB,YAAM,QAAQ,KAAK,SAAS;AAC5B,YAAM,WAAW,OAAO,KAAK;AAC7B,UAAI,UAAU;AACZ,iBAAS,KAAK,IAAI;AAAA,MACpB,OAAO;AACL,eAAO,KAAK,IAAI,CAAC,IAAI;AAAA,MACvB;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT,GAAG,CAAC,OAAO,MAAM,CAAC;AAGlB,QAAM,iBAAiB,CAAC,SAAyB;AAC/C,UAAM,gBAAgB,gBAAgB,KAAK,EAAE,KAAK,CAAC;AAEnD,WACE,gBAAAH,MAAC,SAAkB,MAAK,YAAW,cAAY,KAAK,MACjD,qBAAW,MAAM,aAAa,KADvB,KAAK,EAEf;AAAA,EAEJ;AAGA,QAAM,sBAAsB;AAAA,IAC1B,SAAS;AAAA,IACT,qBAAqB,2BAA2B,YAAY;AAAA,IAC5D,KAAK;AAAA,EACP;AAGA,QAAM,cAAc,CAAC,YACnB,gBAAAA,MAAC,SAAI,OAAO,EAAE,OAAO,OAAO,GAAG,WAAWE,OAAK,eAAe,SAAS,GACpE,mBACH;AAIF,MAAI,WAAW,aAAa,YAAY;AACtC,WAAO;AAAA,MACL,gBAAAF,MAAC,SAAI,WAAU,aAAY,MAAK,QAC7B,iBAAO,QAAQ,UAAU,EAAE,IAAI,CAAC,CAAC,WAAW,UAAU,MACrD,gBAAAC,OAAC,SACC;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO,EAAE,OAAO,MAAM,SAAS,KAAK,QAAQ;AAAA,YAE3C;AAAA;AAAA,QACH;AAAA,QACA,gBAAAA,MAAC,SAAI,OAAO,qBACT,qBAAW,IAAI,cAAc,GAChC;AAAA,WATQ,SAUV,CACD,GACH;AAAA,IACF;AAAA,EACF;AAEA,MAAI,WAAW,QAAQ;AACrB,WAAO;AAAA,MACL,gBAAAA,MAAC,SAAI,WAAU,uBAAsB,MAAK,QACvC,gBAAM,IAAI,cAAc,GAC3B;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL,gBAAAA,MAAC,SAAI,OAAO,qBAAqB,MAAK,QACnC,gBAAM,IAAI,cAAc,GAC3B;AAAA,EACF;AACF;;;AC9XA,SAAS,WAAAI,WAAS,YAAAC,kBAAgC;AAClD,SAAS,QAAAC,cAAY;;;ACqBd,SAAS,6BACd,OACA,UACA,WAC8B;AAC9B,QAAM,UAAU,MAAM,YAAY;AAClC,QAAM,WAAW,MAAM,UAAU,IAAI,QAAQ,KAAK;AAClD,QAAM,QAAQ,MAAM,cAAc,QAAQ,KAAK,CAAC;AAChD,QAAM,aACJ,MAAM,eAAe,WAAW,YAAY,CAAC,CAAC,MAAM;AACtD,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,GAAG;AAAA,IACH,UAAU,MAAM,YAAY;AAAA,IAC5B;AAAA,IACA,SAAS;AAAA,IACT,SAAS,MAAM,WAAW;AAAA,IAC1B,UAAU,MAAM,YAAY;AAAA,IAC5B,QACE,MAAM,WACL,MAAM,iBACH,MAAM,MAAM,iBAAiB,QAAQ,IACrC;AAAA,IACN,WAAW;AAAA,IACX,YAAY,MAAM,YAAY;AAAA,IAC9B;AAAA,EACF;AACF;AAEO,SAAS,8BACd,OACA,OACS;AACT,SACE,MAAM,aACN,MAAM,cACN,CAAC,EAAE,MAAM,UAAU,MAAM;AAE7B;;;ADmNI,SAeE,OAAAC,OAfF,QAAAC,cAAA;AAnBG,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA,UAAU;AAAA,EACV,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAyB;AACvB,QAAM,YAAY,UAAU,aAAa;AAEzC,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,CAAC,UAAU,yBAAyB,OAAO,OAAO;AAAA,MAC7D,WAAWC;AAAA,QACT;AAAA,QACA,WAAW;AAAA,QACX;AAAA,MACF;AAAA,MACA,MAAM,UAAU,WAAW;AAAA,MAC3B,UAAU,UAAU,IAAI;AAAA,MACxB,cAAY,UAAU,cAAc;AAAA,MAGpC;AAAA,wBAAAF,MAAC,UAAK,OAAO,MAAM,QAAQ,MAAM,MAAM,WAAW;AAAA,QAGjD,cACC,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,MAAM;AAAA,YACN,eAAc;AAAA;AAAA,QAChB;AAAA,QAID,iBAAiB,CAAC,cACjB,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,MAAM;AAAA,YACN,eAAc;AAAA;AAAA,QAChB;AAAA,QAID,eAAe,CAAC,aACf,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,IAAI,OAAO;AAAA,YACX,IAAI,OAAO;AAAA,YACX,GAAG,OAAO;AAAA,YACV,MAAK;AAAA,YACL,eAAc;AAAA;AAAA,QAChB;AAAA,QAID,aACC,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,IAAI,OAAO;AAAA,YACX,IAAI,OAAO;AAAA,YACX,GAAG,OAAO;AAAA,YACV,MAAK;AAAA,YACL,QAAO;AAAA,YACP,aAAa,OAAO;AAAA,YACpB,eAAc;AAAA;AAAA,QAChB;AAAA;AAAA;AAAA,EAEJ;AAEJ;AAcO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA;AACF,GAA0B;AACxB,QAAM,SAAS,OAAO;AACtB,QAAM,kBACJ,gBACC,UAAU,aAAa,UAAU,YAAY,YAAY;AAE5D,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,WAAW,CAAC,UAAU,yBAAyB,OAAO,OAAO;AAAA,MAC7D,WAAWC;AAAA,QACT;AAAA,SACC,WAAW,kBAAkB;AAAA,QAC9B;AAAA,MACF;AAAA,MACA,SAAS,aAAa,MAAM;AAAA,MAC5B,MAAM,UAAU,WAAW;AAAA,MAC3B,UAAU,UAAU,IAAI;AAAA,MACxB,cAAY,UAAW,SAAS,eAAgB;AAAA,MAEhD;AAAA,wBAAAF;AAAA,UAAC;AAAA;AAAA,YACC,GAAG,aAAa,SAAS,MAAM;AAAA,YAC/B,MAAM;AAAA,YACN,QAAQ;AAAA,YACR,aAAa;AAAA,YACb,OAAO,EAAE,QAAQ,2CAA2C;AAAA;AAAA,QAC9D;AAAA,QACC,SACC,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAG;AAAA,YACH,YAAW;AAAA,YACX,MAAM;AAAA,YACN,UAAU,OAAO;AAAA,YACjB,YAAW;AAAA,YACX,eAAc;AAAA,YAEb;AAAA;AAAA,QACH;AAAA;AAAA;AAAA,EAEJ;AAEJ;AAWA,IAAM,gBAAwD;AAAA,EAC5D,OAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AACF;AAGO,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA2B;AACzB,QAAM,SAAS,cAAc,KAAK,IAAI,IAAI,KAAK;AAC/C,QAAM,YAAY,UAAU,UAAU,YAAY;AAClD,QAAM,eACJ,UAAU,UACN,6CACA;AAEN,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,WAAW,CAAC,UAAU,yBAAyB,OAAO,OAAO;AAAA,MAC7D,WAAWE;AAAA,SACR,WAAW,kBAAkB;AAAA,QAC9B;AAAA,MACF;AAAA,MACA,MAAM,UAAU,WAAW;AAAA,MAC3B,UAAU,UAAU,IAAI;AAAA,MACxB,cAAY,UAAU,GAAG,KAAK,IAAI,IAAI,KAAK;AAAA,MAE3C,0BAAAF;AAAA,QAAC;AAAA;AAAA,UACC,YAAW;AAAA,UACX,kBAAiB;AAAA,UACjB,UAAU,OAAO;AAAA,UACjB,MAAM;AAAA,UACN,OAAO,EAAE,QAAQ,aAAa;AAAA,UAE7B;AAAA;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;AASO,SAAS,YACd,KACA,KACA,WACQ;AACR,QAAM,OAAO,OAAO,aAAa,KAAK,GAAG;AACzC,QAAM,OAAO,YAAY;AACzB,SAAO,GAAG,IAAI,GAAG,IAAI;AACvB;AAKO,SAAS,UAAU,KAAa,KAAqB;AAC1D,SAAO,GAAG,MAAM,CAAC,IAAI,MAAM,CAAC;AAC9B;AAEA,SAAS,UAAU,MAA8B;AAC/C,SAAO,KAAK;AACd;AAEA,SAAS,qBACP,WACA,YACA,UACA,aAC2B;AAC3B,MACE,KAAK,IAAI,UAAU,MAAM,WAAW,GAAG,IACrC,KAAK,IAAI,UAAU,MAAM,WAAW,GAAG,MACzC,GACA;AACA,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,KAAK,IAAI,UAAU,KAAK,WAAW,GAAG;AACrD,QAAM,SAAS,KAAK,IAAI,UAAU,KAAK,WAAW,GAAG;AAErD,MAAI,UAAU,QAAQ,WAAW,KAAK;AACpC,UAAM,IAAI,eAAe,SAAS,KAAK;AACvC,UAAM,KAAK,SAAS;AACpB,UAAM,KAAK,KAAK;AAChB,WAAO;AAAA,MACL,IAAI;AAAA,MACJ;AAAA,MACA,IAAI;AAAA,MACJ;AAAA,MACA,MAAM;AAAA,MACN,OAAO,KAAK,MAAM;AAAA,MAClB,OAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,KAAK,SAAS,KAAK;AACzB,QAAM,KAAK,cAAc,SAAS;AAClC,QAAM,KAAK,KAAK;AAChB,SAAO;AAAA,IACL;AAAA,IACA,IAAI;AAAA,IACJ;AAAA,IACA,IAAI;AAAA,IACJ,OAAO,KAAK,MAAM;AAAA,IAClB,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AACF;AAEA,SAAS,kBAAkB,MAGc;AACvC,SAAO;AAAA,IACL,CAAC,GAAG,KAAK,GAAG,IAAI,KAAK,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,KAAK,GAAG,KAAK,IAAI;AAAA,IACxD,CAAC,GAAG,KAAK,MAAM,CAAC,IAAI,KAAK,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,MAAM,GAAG,GAAG,KAAK,IAAI;AAAA,IAChE,CAAC,GAAG,KAAK,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,EAAE,GAAG;AAAA,MACnC,GAAG,KAAK,MAAM;AAAA,MACd,GAAG,KAAK,MAAM;AAAA,IAChB;AAAA,IACA,CAAC,GAAG,KAAK,GAAG,IAAI,KAAK,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,KAAK,GAAG,KAAK,MAAM,EAAE;AAAA,EAClE;AACF;AAEA,SAAS,uBACP,OACA,UACA,aAC6B;AAC7B,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,EACT;AAEA,QAAM,gBAAgB,MAAM;AAAA,IAC1B,CAAC,SAAS,IAAI,IAAI,OAAO,KAAK,kBAAkB,IAAI,CAAC,CAAC;AAAA,EACxD;AACA,QAAM,cAAc,cAAc,CAAC;AACnC,MAAI,gBAAgB,QAAW;AAC7B,WAAO;AAAA,EACT;AACA,QAAM,aAAa,CAAC,GAAG,WAAW,EAAE;AAAA,IAAO,CAAC,QAC1C,cAAc,MAAM,CAAC,WAAW,OAAO,IAAI,GAAG,CAAC;AAAA,EACjD;AACA,MAAI,WAAW,WAAW,GAAG;AAC3B,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,WAAW,CAAC;AAC9B,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,EACT;AACA,QAAM,CAAC,UAAU,QAAQ,IAAI,UAAU,MAAM,GAAG;AAChD,MAAI,aAAa,UAAa,aAAa,QAAW;AACpD,WAAO;AAAA,EACT;AACA,QAAM,MAAM,OAAO,QAAQ;AAC3B,QAAM,MAAM,OAAO,QAAQ;AAC3B,MAAI,CAAC,OAAO,SAAS,GAAG,KAAK,CAAC,OAAO,SAAS,GAAG,GAAG;AAClD,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,GAAG,cAAc,MAAM;AAAA,IACvB,GAAG,MAAM;AAAA,EACX;AACF;AAkBA,SAAS,eACP,OAGA;AACA,QAAM;AAAA,IACJ,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,kBAAkB;AAAA,IAClB,kBAAkB;AAAA,IAClB;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,UAAU;AAAA,IACV,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AACJ,QAAM,QACJ,WAAW,QACP,MAAM,QACJ,YAAY,QACV;AAAA,IACE,IAAI;AAAA,IACJ,QAAQ,MAAM;AAAA,IACd,QAAQ,MAAM,UAAU,CAAC;AAAA,IACzB,OAAO,MAAM,SAAS,CAAC;AAAA,IACvB,UAAU,MAAM,YAAY,CAAC;AAAA,EAC/B,IACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,QAAQ;AAAA,IACpB,MAAM,MAAM,QAAQ;AAAA,IACpB,OAAO,MAAM;AAAA,IACb,QAAQ,MAAM,UAAU,CAAC;AAAA,IACzB,OAAO,MAAM,SAAS,CAAC;AAAA,IACvB,UAAU,MAAM,YAAY,CAAC;AAAA,EAC/B;AACV,QAAM,CAAC,2BAA2B,4BAA4B,IAAIG,WAEhE,IAAI;AACN,QAAM,CAAC,0BAA0B,2BAA2B,IAAIA,WAE9D,IAAI;AACN,QAAM,CAAC,4BAA4B,6BAA6B,IAAIA,WAElE,IAAI;AAGN,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,YAAY;AAAA,EACd,IAAI,WAAW;AAAA,IACb,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,EACR,CAAC;AAGD,QAAM,cAAc,mBAAmB,oBAAoB,SAAS,KAAK;AAEzE,QAAM,kBAAkBC;AAAA,IACtB,MAAM,0BAA0B,KAAK;AAAA,IACrC,CAAC,KAAK;AAAA,EACR;AAEA,QAAM,OAAO,gBAAgB;AAC7B,QAAM,OAAO,gBAAgB;AAC7B,QAAM,gBAAgB,gBAAgB;AAGtC,QAAM,mBAAmB,gBAAgB;AAGzC,QAAM,iBAAiB,gBAAgB;AAKvC,QAAM,YAAY,OAAO;AACzB,QAAM,aAAa,OAAO;AAC1B,QAAM,aAAa,YAAY;AAC/B,QAAM,cAAc,aAAa;AAEjC,QAAM,kBAAkBA,UAAQ,MAAM;AACpC,UAAM,SAA8C,CAAC;AACrD,aAAS,MAAM,GAAG,MAAM,MAAM,OAAO;AACnC,eAAS,MAAM,GAAG,MAAM,MAAM,OAAO;AACnC,eAAO,KAAK,EAAE,KAAK,IAAI,CAAC;AAAA,MAC1B;AAAA,IACF;AACA,WAAO;AAAA,EACT,GAAG,CAAC,MAAM,IAAI,CAAC;AAEf,QAAM,gBAAgBA,UAA4B,MAAM;AACtD,QAAI,gBAAgB,MAAM,SAAS,GAAG;AACpC,aAAO,gBAAgB,MAAM,IAAI,CAAC,UAAU;AAAA,QAC1C,GAAG;AAAA,QACH,IAAI,UAAU,IAAI;AAAA,MACpB,EAAE;AAAA,IACJ;AAEA,WAAO,gBAAgB,IAAI,CAAC,EAAE,KAAK,IAAI,OAAO;AAAA,MAC5C,IAAI,GAAG,GAAG,IAAI,GAAG;AAAA,MACjB;AAAA,MACA;AAAA,IACF,EAAE;AAAA,EACJ,GAAG,CAAC,gBAAgB,OAAO,eAAe,CAAC;AAE3C,QAAM,YAAYA;AAAA,IAChB,MAAM,IAAI,IAAI,cAAc,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,IAAI,CAAU,CAAC;AAAA,IACnE,CAAC,aAAa;AAAA,EAChB;AAEA,QAAM,wBAAwBA;AAAA,IAC5B,MACE,cAAc,QAAQ,CAAC,SAAS;AAC9B,UAAI,KAAK,SAAS,SAAS,GAAG;AAC5B,eAAO,CAAC;AAAA,MACV;AACA,YAAM,YAAY,UAAU,IAAI,KAAK,SAAS,CAAC,KAAK,EAAE;AACtD,YAAM,aAAa,UAAU,IAAI,KAAK,SAAS,CAAC,KAAK,EAAE;AACvD,UAAI,CAAC,aAAa,CAAC,YAAY;AAC7B,eAAO,CAAC;AAAA,MACV;AACA,YAAM,WAAW;AAAA,QACf;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,aAAO,WACH;AAAA,QACE;AAAA,UACE;AAAA,UACA,iBAAiB;AAAA,YACf,GAAG;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAAA,MACF,IACA,CAAC;AAAA,IACP,CAAC;AAAA,IACH,CAAC,UAAU,WAAW,eAAe,WAAW;AAAA,EAClD;AAEA,QAAM,0BAA0BA;AAAA,IAC9B,MACE,iBAAiB,QAAQ,CAAC,WAAW;AACnC,YAAM,cAAc,OAAO,SAAS,QAAQ,CAAC,YAAY;AACvD,cAAM,OAAO,UAAU,IAAI,OAAO;AAClC,eAAO,OAAO,CAAC,IAAI,IAAI,CAAC;AAAA,MAC1B,CAAC;AACD,YAAM,WAAW;AAAA,QACf;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,aAAO,WACH;AAAA,QACE;AAAA,UACE;AAAA,UACA,mBAAmB;AAAA,YACjB,GAAG;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAAA,MACF,IACA,CAAC;AAAA,IACP,CAAC;AAAA,IACH,CAAC,UAAU,WAAW,aAAa,gBAAgB;AAAA,EACrD;AAGA,QAAM,eAAe,aAAa,UAAU;AAC5C,QAAM,gBAAgB,cAAc,UAAU;AAC9C,QAAM,YAAY,aAAa,gBAAgB,IAAI,UAAU,IAAI;AACjE,QAAM,YAAY,cAAc,iBAAiB,IAAI,UAAU,IAAI;AAGnE,QAAM,WAAW,SAAS;AAC1B,QAAM,YAAY,UAAU;AAE5B,SACE,gBAAAH;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,SACE,gBACI,GAAG,QAAQ,IAAI,QAAQ,IAAI,YAAY,IAAI,aAAa,KACxD,OAAO,UAAU,IAAI,WAAW;AAAA,MAEtC,WAAWC;AAAA,QACT;AAAA,QACA,iBAAiB;AAAA,QACjB,aAAa;AAAA,QACb,iBAAiB,CAAC,aAAa;AAAA,QAC/B;AAAA,MACF;AAAA,MACC,GAAG,KAAK;AAAA,MACT,MAAK;AAAA,MACL,cAAY,GAAG,IAAI,IAAI,IAAI;AAAA,MAE3B;AAAA,wBAAAF,MAAC,UAEC,0BAAAA,MAAC,YAAO,IAAG,eAAc,GAAE,QAAO,GAAE,QAAO,OAAM,QAAO,QAAO,QAC7D,0BAAAA,MAAC,kBAAa,IAAG,KAAI,IAAG,KAAI,cAAa,KAAI,cAAa,OAAM,GAClE,GACF;AAAA,QAGA,gBAAAA,MAAC,OAAE,WAAU,SAAQ,MAAK,QAAO,cAAW,cACzC,0BAAgB,IAAI,CAAC,EAAE,KAAK,IAAI,MAAM;AACrC,gBAAM,IAAI,cAAc,MAAM;AAC9B,gBAAM,IAAI,MAAM;AAEhB,iBACE,gBAAAA;AAAA,YAAC;AAAA;AAAA,cAEC,WAAW,aAAa,CAAC,KAAK,CAAC;AAAA,cAC/B,MAAK;AAAA,cACL,cACE,oBAAoB,cAChB,YAAY,KAAK,KAAK,IAAI,IAC1B,UAAU,KAAK,GAAG;AAAA,cAGvB,qBAAW,KAAK,GAAG;AAAA;AAAA,YATf,GAAG,GAAG,IAAI,GAAG;AAAA,UAUpB;AAAA,QAEJ,CAAC,GACH;AAAA,QAEC,qBACC,gBAAAA,MAAC,OAAE,WAAU,sBAAqB,cAAW,sBAC1C,wBAAc,IAAI,CAAC,UAAU;AAC5B,gBAAM,QAAQ;AAAA,YACZ;AAAA,YACA,MAAM;AAAA,YACN,8BAA8B,MAAM;AAAA,UACtC;AACA,gBAAM,eAAe;AAAA,YACnB;AAAA,YACA;AAAA,UACF;AACA,gBAAM,IAAI,cAAc,MAAM,MAAM;AACpC,gBAAM,IAAI,MAAM,MAAM;AACtB,iBACE,gBAAAC;AAAA,YAAC;AAAA;AAAA,cAEC,WAAW,aAAa,CAAC,KAAK,CAAC;AAAA,cAC/B,SACE,eACI,MAAM;AACJ,qBAAK,kBAAkB,iBAAiB,MAAM,EAAE;AAAA,cAClD,IACA;AAAA,cAEN,WAAW,CAAC,UACV;AAAA,gBACE;AAAA,gBACA,eACI,MAAM;AACJ,uBAAK,kBAAkB,iBAAiB,MAAM,EAAE;AAAA,gBAClD,IACA;AAAA,cACN;AAAA,cAEF,gBAAgB,MAAM,6BAA6B,MAAM,EAAE;AAAA,cAC3D,gBAAgB,MACd;AAAA,gBAA6B,CAAC,cAC5B,cAAc,MAAM,KAAK,OAAO;AAAA,cAClC;AAAA,cAEF,WAAWC,OAAK,gBAAgB,gBAAgB;AAAA,cAChD,MAAM,eAAe,WAAW;AAAA,cAChC,UAAU,eAAe,IAAI;AAAA,cAC7B,cACE,eAAe,gBAAgB,MAAM,EAAE,KAAK;AAAA,cAG7C;AAAA,gCACC,gBAAAF;AAAA,kBAAC;AAAA;AAAA,oBACC,GAAG;AAAA,oBACH,GAAG;AAAA,oBACH,OAAO;AAAA,oBACP,QAAQ;AAAA,oBACR,MAAK;AAAA,oBACL,eAAc;AAAA;AAAA,gBAChB;AAAA,gBAED,yBACG,uBAAuB,OAAO,KAAK,IACnC;AAAA;AAAA;AAAA,YA5CC,MAAM;AAAA,UA6Cb;AAAA,QAEJ,CAAC,GACH;AAAA,QAGD,cAAc,sBAAsB,SAAS,KAC5C,gBAAAA,MAAC,OAAE,WAAU,SAAQ,cAAW,eAC7B,gCAAsB,IAAI,CAAC,EAAE,MAAM,gBAAgB,MAClD,gBAAAA,MAAC,OAAiB,qBAAW,MAAM,gBAAgB,QAAQ,KAAnD,KAAK,EAAgD,CAC9D,GACH;AAAA,QAGD,oBACC,gBAAAA,MAAC,OAAE,WAAU,qBAAoB,cAAW,qBACzC,gCAAsB,IAAI,CAAC,EAAE,iBAAiB,KAAK,MAAM;AACxD,gBAAM,QAAQ;AAAA,YACZ;AAAA,YACA,KAAK;AAAA,YACL,6BAA6B,KAAK;AAAA,UACpC;AACA,gBAAM,eAAe;AAAA,YACnB;AAAA,YACA;AAAA,UACF;AACA,iBACE,gBAAAA;AAAA,YAAC;AAAA;AAAA,cAEC,SACE,eACI,MAAM;AACJ,qBAAK,iBAAiB,iBAAiB,KAAK,EAAE;AAAA,cAChD,IACA;AAAA,cAEN,WAAW,CAAC,UACV;AAAA,gBACE;AAAA,gBACA,eACI,MAAM;AACJ,uBAAK,iBAAiB,iBAAiB,KAAK,EAAE;AAAA,gBAChD,IACA;AAAA,cACN;AAAA,cAEF,gBAAgB,MAAM,4BAA4B,KAAK,EAAE;AAAA,cACzD,gBAAgB,MACd;AAAA,gBAA4B,CAAC,cAC3B,cAAc,KAAK,KAAK,OAAO;AAAA,cACjC;AAAA,cAEF,WAAWE,OAAK,gBAAgB,gBAAgB;AAAA,cAChD,MAAM,eAAe,WAAW;AAAA,cAChC,UAAU,eAAe,IAAI;AAAA,cAC7B,cAAY,eAAe,eAAe,KAAK,EAAE,KAAK;AAAA,cAErD,kCACC,sBAAsB,MAAM,KAAK,UAAU,KAAK,IAC9C,MAAM,aAAa,MAAM,aAC3B,gBAAAF;AAAA,gBAAC;AAAA;AAAA,kBACC,IAAI,KAAK,SAAS;AAAA,kBAClB,IAAI,KAAK,SAAS;AAAA,kBAClB,IAAI,KAAK,SAAS;AAAA,kBAClB,IAAI,KAAK,SAAS;AAAA,kBAClB,QAAO;AAAA,kBACP,aAAa,KAAK,IAAI,IAAI,WAAW,IAAI;AAAA,kBACzC,eAAc;AAAA;AAAA,cAChB,IACE;AAAA;AAAA,YAzCC,KAAK;AAAA,UA0CZ;AAAA,QAEJ,CAAC,GACH;AAAA,QAGD,gBAAgB,wBAAwB,SAAS,KAChD,gBAAAA,MAAC,OAAE,WAAU,YAAW,cAAW,kBAChC,kCAAwB,IAAI,CAAC,EAAE,QAAQ,kBAAkB,MACxD,gBAAAA,MAAC,OACE,uBAAa,QAAQ,kBAAkB,QAAQ,KAD1C,OAAO,EAEf,CACD,GACH;AAAA,QAGD,uBACC,gBAAAA,MAAC,OAAE,WAAU,wBAAuB,cAAW,wBAC5C,kCAAwB,IAAI,CAAC,EAAE,mBAAmB,OAAO,MAAM;AAC9D,gBAAM,QAAQ;AAAA,YACZ;AAAA,YACA,OAAO;AAAA,YACP,+BAA+B,OAAO;AAAA,UACxC;AACA,gBAAM,eAAe;AAAA,YACnB;AAAA,YACA;AAAA,UACF;AACA,iBACE,gBAAAA;AAAA,YAAC;AAAA;AAAA,cAEC,SACE,eACI,MAAM;AACJ,qBAAK,oBAAoB,iBAAiB,OAAO,EAAE;AAAA,cACrD,IACA;AAAA,cAEN,WAAW,CAAC,UACV;AAAA,gBACE;AAAA,gBACA,eACI,MAAM;AACJ,uBAAK,oBAAoB,iBAAiB,OAAO,EAAE;AAAA,gBACrD,IACA;AAAA,cACN;AAAA,cAEF,gBAAgB,MAAM,8BAA8B,OAAO,EAAE;AAAA,cAC7D,gBAAgB,MACd;AAAA,gBAA8B,CAAC,cAC7B,cAAc,OAAO,KAAK,OAAO;AAAA,cACnC;AAAA,cAEF,WAAWE,OAAK,gBAAgB,gBAAgB;AAAA,cAChD,MAAM,eAAe,WAAW;AAAA,cAChC,UAAU,eAAe,IAAI;AAAA,cAC7B,cACE,eAAe,iBAAiB,OAAO,EAAE,KAAK;AAAA,cAG/C,oCACC,wBAAwB,QAAQ,OAAO,UAAU,KAAK,IACpD,MAAM,aAAa,MAAM,aAC3B,gBAAAF;AAAA,gBAAC;AAAA;AAAA,kBACC,IAAI,OAAO,SAAS;AAAA,kBACpB,IAAI,OAAO,SAAS;AAAA,kBACpB,GAAG,KAAK,IAAI,GAAG,WAAW,IAAI;AAAA,kBAC9B,MAAK;AAAA,kBACL,eAAc;AAAA;AAAA,cAChB,IACE;AAAA;AAAA,YAzCC,OAAO;AAAA,UA0Cd;AAAA,QAEJ,CAAC,GACH;AAAA,QAID,mBAAmB,oBAAoB,UACtC,gBAAAC,OAAC,OAAE,WAAU,eAAc,eAAY,QAEpC;AAAA,gBAAM,KAAK,EAAE,QAAQ,KAAK,CAAC,EAAE,IAAI,CAAC,GAAG,QAAQ;AAC5C,kBAAM,QACJ,oBAAoB,cAChB,OAAO,aAAa,KAAK,GAAG,IAC5B,OAAO,MAAM,CAAC;AACpB,mBACE,gBAAAD;AAAA,cAAC;AAAA;AAAA,gBAEC,GAAG,cAAc,MAAM,WAAW,WAAW;AAAA,gBAC7C,GAAG,aAAa;AAAA,gBAChB,YAAW;AAAA,gBACX,MAAK;AAAA,gBACL,UAAU;AAAA,gBACV,YAAW;AAAA,gBAEV;AAAA;AAAA,cARI,QAAQ,GAAG;AAAA,YASlB;AAAA,UAEJ,CAAC;AAAA,UAEA,MAAM,KAAK,EAAE,QAAQ,KAAK,CAAC,EAAE,IAAI,CAAC,GAAG,QAAQ;AAC5C,kBAAM,QACJ,oBAAoB,cAChB,OAAO,OAAO,GAAG,IACjB,OAAO,MAAM,CAAC;AACpB,mBACE,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBAEC,GAAG;AAAA,gBACH,GAAG,MAAM,WAAW,WAAW,IAAI;AAAA,gBACnC,YAAW;AAAA,gBACX,MAAK;AAAA,gBACL,UAAU;AAAA,gBACV,YAAW;AAAA,gBAEV;AAAA;AAAA,cARI,QAAQ,GAAG;AAAA,YASlB;AAAA,UAEJ,CAAC;AAAA,WACH;AAAA,QAIF,gBAAAA,MAAC,OAAE,WAAU,UAAS,MAAK,QAAO,cAAW,eAC1C,yBAAe,IAAI,CAAC,UAAU;AAC7B,gBAAM,IAAI,cAAc,MAAM,MAAM,WAAW,WAAW;AAC1D,gBAAM,IAAI,MAAM,MAAM,WAAW,WAAW;AAE5C,iBACE,gBAAAA;AAAA,YAAC;AAAA;AAAA,cAEC,WAAW,aAAa,CAAC,KAAK,CAAC;AAAA,cAC/B,MAAK;AAAA,cACL,cAAY,GAAG,MAAM,SAAS,EAAE,IAAI,MAAM,MAAM;AAAA,cAE/C,sBAAY,KAAK;AAAA;AAAA,YALb,MAAM;AAAA,UAMb;AAAA,QAEJ,CAAC,GACH;AAAA,QAGC,iBAAiB,UAAU,SAAS,KACnC,gBAAAC;AAAA,UAAC;AAAA;AAAA,YACC,WAAW,aAAa,WAAW,EAAE,KAAK,WAAW,gBAAgB,EAAE;AAAA,YAEvE;AAAA,8BAAAD;AAAA,gBAAC;AAAA;AAAA,kBACC,GAAG;AAAA,kBACH,GAAG;AAAA,kBACH,OAAO;AAAA,kBACP,QAAQ;AAAA,kBACR,IAAI;AAAA,kBACJ,MAAK;AAAA;AAAA,cACP;AAAA,cACA,gBAAAC,OAAC,UAAK,GAAG,IAAI,GAAG,IAAI,YAAW,UAAS,MAAK,SAAQ,UAAU,IAC5D;AAAA,qBAAK,MAAM,UAAU,OAAO,GAAG;AAAA,gBAAE;AAAA,iBACpC;AAAA;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EAEJ;AAEJ;AAEO,IAAM,aAAa;;;AEtoC1B,SAAS,WAAAI,WAAS,YAAAC,kBAAgC;AAClD,SAAS,QAAAC,cAAY;AAqWf,gBAAAC,OAyBE,QAAAC,cAzBF;AA/CC,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT,cAAc;AAAA,EACd,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB;AAAA,EACA,kBAAkB;AAAA,EAClB;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAwB;AACtB,QAAM,gBAAgB,aAClB,4BACA,gBACE,2BACA;AAEN,QAAM,kBAAkB,aACpB,YACA,gBACE,YACA;AAEN,QAAM,uBAAuB,cAAc,gBAAgB,IAAI;AAE/D,QAAM,SAAS,SAAS,aAAa,GAAG,GAAG,OAAO,MAAM,WAAW;AAEnE,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,CAAC,UAAU,yBAAyB,OAAO,OAAO;AAAA,MAC7D,WAAWC;AAAA,QACT;AAAA,QACA,WAAW;AAAA,QACX;AAAA,MACF;AAAA,MACA,MAAM,UAAU,WAAW;AAAA,MAC3B,UAAU,UAAU,IAAI;AAAA,MACxB,cAAY,UAAW,SAAS,aAAc;AAAA,MAE9C;AAAA,wBAAAF;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,MAAM;AAAA,YACN,QAAQ;AAAA,YACR,aAAa;AAAA,YACb,QAAO;AAAA;AAAA,QACT;AAAA,QAEC,SACC,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAG;AAAA,YACH,GAAG,kBAAkB,KAAK;AAAA,YAC1B,YAAW;AAAA,YACX,kBAAiB;AAAA,YACjB,MAAK;AAAA,YACL,UAAU,OAAO;AAAA,YACjB,YAAW;AAAA,YACX,OAAO,EAAE,YAAY,8BAA8B;AAAA,YACnD,eAAc;AAAA,YAEb;AAAA;AAAA,QACH;AAAA,QAGD,mBAAmB,eAClB,gBAAAC;AAAA,UAAC;AAAA;AAAA,YACC,GAAG;AAAA,YACH,GAAG,QAAQ,KAAK;AAAA,YAChB,YAAW;AAAA,YACX,kBAAiB;AAAA,YACjB,MAAK;AAAA,YACL,UAAU,OAAO;AAAA,YACjB,eAAc;AAAA,YAEb;AAAA,0BAAY;AAAA,cAAE;AAAA,cAAE,YAAY;AAAA;AAAA;AAAA,QAC/B;AAAA;AAAA;AAAA,EAEJ;AAEJ;AAaO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB;AAAA,EACA;AACF,GAAwB;AACtB,QAAM,oBAAoB,KAAK;AAAA,IAC7B,SAAS,KAAK,SAAS;AAAA,IACvB,SAAS,KAAK,SAAS;AAAA,EACzB;AAEA,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAW,CAAC,UAAU,yBAAyB,OAAO,OAAO;AAAA,MAC7D,WAAWC;AAAA,QACT;AAAA,QACA,WAAW;AAAA,QACX;AAAA,MACF;AAAA,MACA,MAAM,UAAU,WAAW;AAAA,MAC3B,UAAU,UAAU,IAAI;AAAA,MACxB,cAAY,UAAU,aAAa;AAAA,MAGnC;AAAA,wBAAAF;AAAA,UAAC;AAAA;AAAA,YACC,GAAG,SAAS,OAAO,oBAAoB;AAAA,YACvC,GAAG,SAAS,OAAO,kBAAkB;AAAA,YACrC,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,IAAI,kBAAkB;AAAA,YACtB,MAAK;AAAA,YACL,WAAW,UAAU,SAAS,SAAS,IAAI,SAAS,IAAI,IAAI,SAAS,IAAI;AAAA,YACzE,eAAc;AAAA;AAAA,QAChB;AAAA,QAEA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,IAAI,SAAS;AAAA,YACb,IAAI,SAAS;AAAA,YACb,IAAI,SAAS;AAAA,YACb,IAAI,SAAS;AAAA,YACb,QAAQ;AAAA,YACR,aAAa,WAAW,cAAc,cAAc;AAAA,YACpD,eAAc;AAAA,YACd,WAAW,WAAW,KAAK;AAAA;AAAA,QAC7B;AAAA;AAAA;AAAA,EACF;AAEJ;AAoBO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT,cAAc;AAAA,EACd,WAAW;AAAA,EACX,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,OAAO;AAAA,EACP,kBAAkB;AAAA,EAClB,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA0B;AACxB,QAAM,iBAAiB,aACnB,4BACA,gBACE,2BACA;AAEN,QAAM,kBAAkB,aACpB,YACA,gBACE,YACA;AAEN,QAAM,uBAAuB,cAAc,gBAAgB,IAAI;AAE/D,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,CAAC,UAAU,yBAAyB,OAAO,OAAO;AAAA,MAC7D,WAAWC;AAAA,QACT;AAAA,QACA,WAAW;AAAA,QACX;AAAA,MACF;AAAA,MACA,OAAO,EAAE,iBAAiB,GAAG,SAAS,CAAC,MAAM,SAAS,CAAC,KAAK;AAAA,MAC5D,MAAM,UAAU,WAAW;AAAA,MAC3B,UAAU,UAAU,IAAI;AAAA,MACxB,cAAY,UAAU,eAAe;AAAA,MAGrC;AAAA,wBAAAF;AAAA,UAAC;AAAA;AAAA,YACC,IAAI,SAAS;AAAA,YACb,IAAI,SAAS;AAAA,YACb,GAAG;AAAA,YACH,MAAK;AAAA,YACL,eAAc;AAAA;AAAA,QAChB;AAAA,QAEC,UAAU,WACT,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAG,SAAS,IAAI;AAAA,YAChB,GAAG,SAAS,IAAI;AAAA,YAChB,OAAO,OAAO;AAAA,YACd,QAAQ,OAAO;AAAA,YACf,MAAM;AAAA,YACN,QAAQ;AAAA,YACR,aAAa;AAAA,YACb,WAAW,WAAW,KAAK;AAAA;AAAA,QAC7B,IAEA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,IAAI,SAAS;AAAA,YACb,IAAI,SAAS;AAAA,YACb,GAAG,WAAW,OAAO,OAAO;AAAA,YAC5B,MAAM;AAAA,YACN,QAAQ;AAAA,YACR,aAAa;AAAA,YACb,WAAW,WAAW,KAAK;AAAA;AAAA,QAC7B;AAAA;AAAA;AAAA,EAEJ;AAEJ;AAcO,SAAS,yBAAyB;AAAA,EACvC;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,aAAa;AAAA,EACb;AACF,GAAkC;AAChC,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,SAAS;AAAA,MACb,GAAG,YAAY,OAAO,MAAM;AAAA,MAC5B,MAAM,YAAY,aAAa;AAAA,MAC/B,QAAQ,YAAY,YAAY;AAAA,MAChC,aAAa,YAAY,IAAI;AAAA,MAC7B,WAAWE,OAAK,+BAA+B,SAAS;AAAA;AAAA,EAC1D;AAEJ;AAUO,SAAS,uBAAuB;AAAA,EACrC;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,aAAa;AAAA,EACb;AACF,GAAgC;AAC9B,SACE,gBAAAF;AAAA,IAAC;AAAA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,SAAS;AAAA,MACb,IAAI,SAAS;AAAA,MACb,IAAI,SAAS;AAAA,MACb,QAAQ,YAAY,aAAa;AAAA,MACjC,aAAa,YAAY,cAAc,MAAM;AAAA,MAC7C,eAAc;AAAA,MACd,WAAWE,OAAK,+BAA+B,SAAS;AAAA;AAAA,EAC1D;AAEJ;AAMO,IAAM,WAAW;AAAA;AAAA,EAEtB,aACE,GACA,GACA,MACA,aAC0B;AAC1B,QAAI,gBAAgB,cAAc;AAChC,YAAM,IAAI,QAAQ,KAAK,KAAK,CAAC,IAAI,IAAK,KAAK,KAAK,CAAC,IAAI,IAAK;AAC1D,YAAM,IAAI,QAAS,IAAI,IAAK;AAC5B,aAAO,EAAE,GAAG,EAAE;AAAA,IAChB,OAAO;AACL,YAAM,IAAI,QAAS,IAAI,IAAK;AAC5B,YAAM,IAAI,QAAS,KAAK,KAAK,CAAC,IAAI,IAAK,IAAI,KAAK,KAAK,CAAC,IAAI;AAC1D,aAAO,EAAE,GAAG,EAAE;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,aAAa,GAAW,GAA4C;AAClE,WAAO;AAAA,MACL,EAAE,GAAG,IAAI,GAAG,EAAK;AAAA,MACjB,EAAE,GAAG,IAAI,GAAG,GAAG,IAAI,EAAE;AAAA,MACrB,EAAE,GAAM,GAAG,IAAI,EAAE;AAAA,MACjB,EAAE,GAAG,IAAI,GAAG,EAAK;AAAA,MACjB,EAAE,GAAG,IAAI,GAAG,GAAG,IAAI,EAAE;AAAA,MACrB,EAAE,GAAM,GAAG,IAAI,EAAE;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,YAAY,IAAY,IAAY,IAAY,IAAoB;AAClE,YACG,KAAK,IAAI,KAAK,EAAE,IAAI,KAAK,IAAI,KAAK,KAAK,KAAK,EAAE,IAAI,KAAK,IAAI,KAAK,EAAE,KAAK;AAAA,EAE5E;AAAA,EAEA,cACE,SACA,SACA,MACA,aACiC;AACjC,UAAM,UAA2C,CAAC;AAClD,UAAM,aAAa,gBAAgB,eAAe,KAAK;AAEvD,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAM,WAAW,aAAa,KAAK;AACnC,YAAM,WAAY,KAAK,KAAK,MAAO;AACnC,cAAQ,KAAK;AAAA,QACX,GAAG,UAAU,OAAO,KAAK,IAAI,QAAQ;AAAA,QACrC,GAAG,UAAU,OAAO,KAAK,IAAI,QAAQ;AAAA,MACvC,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAAA,EAEA,aACE,SACA,SACA,MACA,aACQ;AACR,UAAM,UAAU,KAAK,cAAc,SAAS,SAAS,MAAM,WAAW;AACtE,WAAO,QAAQ,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,KAAK,GAAG;AAAA,EACrD;AAAA,EAEA,gBACE,SACA,SACA,MACc;AACd,UAAM,QAAQ,QAAQ,IAAI,QAAQ,KAAK;AACvC,UAAM,QAAQ,QAAQ,IAAI,QAAQ,KAAK;AACvC,UAAM,iBAAiB,KAAK;AAAA,MAC1B,QAAQ,IAAI,QAAQ;AAAA,MACpB,QAAQ,IAAI,QAAQ;AAAA,IACtB;AAGA,UAAM,eAAe,iBAAiB,KAAK,KAAK;AAChD,UAAM,aAAa,OAAO;AAC1B,UAAM,cAAe,iBAAiB,MAAO,KAAK;AAClD,UAAM,YAAa,eAAe,MAAO,KAAK;AAE9C,WAAO;AAAA,MACL,IAAI,OAAQ,aAAa,IAAK,KAAK,IAAI,YAAY;AAAA,MACnD,IAAI,OAAQ,aAAa,IAAK,KAAK,IAAI,YAAY;AAAA,MACnD,IAAI,OAAQ,aAAa,IAAK,KAAK,IAAI,YAAY;AAAA,MACnD,IAAI,OAAQ,aAAa,IAAK,KAAK,IAAI,YAAY;AAAA,MACnD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,kBACE,SACA,SACA,SAC0B;AAC1B,WAAO;AAAA,MACL,IAAI,QAAQ,IAAI,QAAQ,IAAI,QAAQ,KAAK;AAAA,MACzC,IAAI,QAAQ,IAAI,QAAQ,IAAI,QAAQ,KAAK;AAAA,IAC3C;AAAA,EACF;AACF;AAkBA,SAAS,YACP,OACA;AACA,QAAM;AAAA,IACJ,cAAc;AAAA,IACd,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,UAAU;AAAA,IACV,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,wBAAwB;AAAA,IACxB,sBAAsB;AAAA,EACxB,IAAI;AACJ,QAAM,QACJ,WAAW,QACP,MAAM,QACJ,YAAY,QACV;AAAA,IACE,IAAI;AAAA,IACJ;AAAA,IACA,QAAQ,MAAM;AAAA,IACd,OAAO,MAAM,SAAS,CAAC;AAAA,IACvB,UAAU,MAAM,YAAY,CAAC;AAAA,EAC/B,IACA;AAAA,IACE,IAAI;AAAA,IACJ;AAAA,IACA,OAAO,MAAM;AAAA,IACb,OAAO,MAAM,SAAS,CAAC;AAAA,IACvB,UAAU,MAAM,YAAY,CAAC;AAAA,EAC/B;AAEV,QAAM,WAAW,YAAY;AAC7B,QAAM,mBAAmB,iBAAiB;AAC1C,QAAM,kBAAkBC;AAAA,IACtB,MAAM,uBAAuB,KAAK;AAAA,IAClC,CAAC,KAAK;AAAA,EACR;AACA,QAAM,gBAAgB,gBAAgB;AACtC,QAAM,gBAAgB,gBAAgB;AACtC,QAAM,mBAAmB,gBAAgB;AACzC,QAAM,sBAAsB,gBAAgB,eAAe;AAG3D,QAAM,CAAC,gBAAgB,iBAAiB,IAAIC,WAAwB,IAAI;AACxE,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA,WAAwB,IAAI;AAC1E,QAAM,CAAC,eAAe,gBAAgB,IAAIA,WAAwB,IAAI;AAGtE,QAAM,EAAE,WAAW,MAAM,WAAW,IAAI,WAAW;AAAA,IACjD,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,EACR,CAAC;AAGD,QAAM,gBAAgBD,UAAQ,MAAM;AAClC,UAAM,YAAY,oBAAI,IAAsC;AAC5D,kBAAc,QAAQ,CAAC,SAAS;AAC9B,gBAAU;AAAA,QACR,KAAK;AAAA,QACL,SAAS,aAAa,KAAK,GAAG,KAAK,GAAG,SAAS,mBAAmB;AAAA,MACpE;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT,GAAG,CAAC,eAAe,SAAS,mBAAmB,CAAC;AAOhD,QAAM,oBAAoBA;AAAA,IACxB,MACE,CAAC,aAAwD;AACvD,YAAM,UAAU,CAAC,YAAiC;AAChD,cAAM,QAAQ,SAAS,SAAS;AAChC,cAAM,SAAS,KAAK,IAAI,GAAG,UAAU,KAAK;AAC1C,eAAO,SAAS,cAAc,GAAG,GAAG,QAAQ,mBAAmB;AAAA,MACjE;AACA,YAAM,SAAS,CAAC,YACd,QAAQ,OAAO,EACZ,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,IAAI,OAAO,CAAC,EAAE,EACzC,KAAK,GAAG;AACb,YAAM,QAAQ,QAAQ;AACtB,YAAM,KAAK,MAAM,IAAI,CAAC,WAAW,OAAO,CAAC;AACzC,YAAM,KAAK,MAAM,IAAI,CAAC,WAAW,OAAO,CAAC;AACzC,YAAM,OAAO,KAAK,IAAI,GAAG,EAAE;AAC3B,YAAM,OAAO,KAAK,IAAI,GAAG,EAAE;AAC3B,YAAM,OAAO,KAAK,IAAI,GAAG,EAAE;AAC3B,YAAM,OAAO,KAAK,IAAI,GAAG,EAAE;AAC3B,aAAO;AAAA,QACL,MAAM;AAAA,QACN,aAAa;AAAA,QACb,QAAQ,EAAE,GAAG,GAAG,GAAG,EAAE;AAAA,QACrB;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,UACN;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,OAAO,OAAO;AAAA,UACd,QAAQ,OAAO;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AAAA,IACF,CAAC,SAAS,mBAAmB;AAAA,EAC/B;AAEA,QAAM,wBAAwBA;AAAA,IAC5B,MACE,cAAc,QAAQ,CAAC,SAAS;AAC9B,YAAM,OAAO,cAAc,IAAI,KAAK,IAAI;AACxC,YAAM,OAAO,cAAc,IAAI,KAAK,IAAI;AACxC,UAAI,CAAC,QAAQ,CAAC,MAAM;AAClB,eAAO,CAAC;AAAA,MACV;AACA,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA,iBAAiB;AAAA,YACf,GAAG;AAAA,YACH,UAAU,CAAC,KAAK,MAAM,KAAK,IAAI;AAAA,YAC/B,UAAU,SAAS,gBAAgB,MAAM,MAAM,OAAO;AAAA,UACxD;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,IACH,CAAC,SAAS,eAAe,aAAa;AAAA,EACxC;AAEA,QAAM,0BAA0BA;AAAA,IAC9B,MACE,iBAAiB,QAAQ,CAAC,WAAW;AACnC,YAAM,CAAC,MAAM,MAAM,IAAI,IAAI,OAAO;AAClC,UAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM;AAC3B,eAAO,CAAC;AAAA,MACV;AAEA,YAAM,OAAO,cAAc,IAAI,IAAI;AACnC,YAAM,OAAO,cAAc,IAAI,IAAI;AACnC,YAAM,OAAO,cAAc,IAAI,IAAI;AACnC,UAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM;AAC3B,eAAO,CAAC;AAAA,MACV;AAEA,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA,mBAAmB;AAAA,YACjB,GAAG;AAAA,YACH,UAAU,OAAO;AAAA,YACjB,UAAU,SAAS,kBAAkB,MAAM,MAAM,IAAI;AAAA,UACvD;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,IACH,CAAC,kBAAkB,aAAa;AAAA,EAClC;AAGA,QAAM,SAASA,UAAQ,MAAM;AAC3B,QAAI,cAAc,WAAW,GAAG;AAC9B,aAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,KAAK,QAAQ,IAAI;AAAA,IACrD;AAEA,QAAI,OAAO,UACT,OAAO,UACP,OAAO,WACP,OAAO;AACT,kBAAc,QAAQ,CAAC,SAAS;AAC9B,YAAM,MAAM,cAAc,IAAI,KAAK,EAAE;AACrC,UAAI,KAAK;AACP,eAAO,KAAK,IAAI,MAAM,IAAI,IAAI,OAAO;AACrC,eAAO,KAAK,IAAI,MAAM,IAAI,IAAI,OAAO;AACrC,eAAO,KAAK,IAAI,MAAM,IAAI,IAAI,OAAO;AACrC,eAAO,KAAK,IAAI,MAAM,IAAI,IAAI,OAAO;AAAA,MACvC;AAAA,IACF,CAAC;AAED,UAAM,UAAU;AAChB,WAAO;AAAA,MACL,MAAM,OAAO;AAAA,MACb,MAAM,OAAO;AAAA,MACb,OAAO,OAAO,OAAO,UAAU;AAAA,MAC/B,QAAQ,OAAO,OAAO,UAAU;AAAA,IAClC;AAAA,EACF,GAAG,CAAC,eAAe,eAAe,OAAO,CAAC;AAG1C,QAAM,UAAU,iBAAiB,QAAQ,SAAS;AAGlD,QAAM,eAAe,QAAQ,MAAM,GAAG,EAAE,IAAI,MAAM;AAClD,QAAM,WAAW,aAAa,CAAC,KAAK;AACpC,QAAM,WAAW,aAAa,CAAC,KAAK;AACpC,QAAM,gBAAgB,aAAa,CAAC,KAAK;AAEzC,SACE,gBAAAF;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAWC;AAAA,QACT;AAAA,QACA,oBAAoB;AAAA,QACpB,cAAc;AAAA,QACd,oBAAoB,CAAC,cAAc;AAAA,QACnC;AAAA,MACF;AAAA,MACC,GAAG,KAAK;AAAA,MACT,MAAK;AAAA,MACL,cAAW;AAAA,MAEX;AAAA,wBAAAD,OAAC,UAEC;AAAA,0BAAAA,OAAC,oBAAe,IAAG,iBAAgB,IAAG,MAAK,IAAG,MAAK,IAAG,QAAO,IAAG,QAC9D;AAAA,4BAAAD,MAAC,UAAK,QAAO,MAAK,WAAU,WAAU;AAAA,YACtC,gBAAAA,MAAC,UAAK,QAAO,QAAO,WAAU,WAAU;AAAA,aAC1C;AAAA,UAEA,gBAAAA,MAAC,YAAO,IAAG,aAAY,GAAE,QAAO,GAAE,QAAO,OAAM,QAAO,QAAO,QAC3D,0BAAAA,MAAC,kBAAa,IAAG,KAAI,IAAG,KAAI,cAAa,KAAI,cAAa,OAAM,GAClE;AAAA,WACF;AAAA,QAGA,gBAAAA,MAAC,OAAE,WAAU,SAAQ,MAAK,QAAO,cAAW,aACzC,wBAAc,IAAI,CAAC,SAAS;AAC3B,gBAAM,MAAM,cAAc,IAAI,KAAK,EAAE;AACrC,cAAI,CAAC,IAAK,QAAO;AAEjB,gBAAM,WAAW,kBAAkB,GAAG;AACtC,iBACE,gBAAAA;AAAA,YAAC;AAAA;AAAA,cAEC,WAAW,aAAa,IAAI,CAAC,KAAK,IAAI,CAAC;AAAA,cACvC,MAAK;AAAA,cACL,cAAY,KAAK,SAAS,QAAQ,KAAK,EAAE;AAAA,cAExC,qBAAW,MAAM,QAAQ;AAAA;AAAA,YALrB,KAAK;AAAA,UAMZ;AAAA,QAEJ,CAAC,GACH;AAAA,QAGC,qBAAqB,cAAc,SAAS,KAC3C,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,MAAK;AAAA,YACL,cAAW;AAAA,YAEV,wBAAc,IAAI,CAAC,UAAU;AAC5B,oBAAM,MAAM,cAAc,IAAI,MAAM,EAAE;AACtC,kBAAI,CAAC,IAAK,QAAO;AACjB,oBAAM,QAAQ;AAAA,gBACZ;AAAA,gBACA,MAAM;AAAA,gBACN,mBAAmB,MAAM;AAAA,cAC3B;AACA,oBAAM,eAAe;AAAA,gBACnB;AAAA,gBACA;AAAA,cACF;AACA,qBACE,gBAAAC;AAAA,gBAAC;AAAA;AAAA,kBAEC,WAAW,aAAa,IAAI,CAAC,KAAK,IAAI,CAAC;AAAA,kBACvC,MAAM,eAAe,WAAW;AAAA,kBAChC,WAAWC,OAAK,gBAAgB,gBAAgB;AAAA,kBAChD,gBAAgB,MAAM,kBAAkB,MAAM,EAAE;AAAA,kBAChD,gBAAgB,MACd;AAAA,oBAAkB,CAAC,cACjB,cAAc,MAAM,KAAK,OAAO;AAAA,kBAClC;AAAA,kBAEF,SACE,eACI,MAAM;AACJ,yBAAK,MAAM,SAAS;AAAA,kBACtB,IACA;AAAA,kBAEN,WAAW,CAAC,UACV;AAAA,oBACE;AAAA,oBACA,eACI,MAAM;AACJ,2BAAK,MAAM,SAAS;AAAA,oBACtB,IACA;AAAA,kBACN;AAAA,kBAEF,UAAU,eAAe,IAAI;AAAA,kBAC7B,cACE,eAAe,gBAAgB,MAAM,EAAE,KAAK;AAAA,kBAG7C;AAAA,oCACC,gBAAAF;AAAA,sBAAC;AAAA;AAAA,wBACC,QAAQ,kBAAkB,GAAG,EAAE,OAAO;AAAA,0BACpC,OAAO,UAAU;AAAA,wBACnB,CAAC;AAAA,wBACD,MAAK;AAAA,wBACL,eAAc;AAAA;AAAA,oBAChB;AAAA,oBAED,yBACG,uBAAuB,OAAO,KAAK,IACnC;AAAA;AAAA;AAAA,gBA3CC,MAAM;AAAA,cA4Cb;AAAA,YAEJ,CAAC;AAAA;AAAA,QACH;AAAA,QAID,cAAc,SAAS,KACtB,gBAAAA,MAAC,OAAE,WAAU,SAAQ,MAAK,QAAO,cAAW,aACzC,gCAAsB,IAAI,CAAC,EAAE,MAAM,gBAAgB,MAAM;AACxD,iBACE,gBAAAA,MAAC,OAAgB,MAAK,YACnB,qBAAW,MAAM,gBAAgB,QAAQ,KADpC,KAAK,EAEb;AAAA,QAEJ,CAAC,GACH;AAAA,QAID,iBAAiB,SAAS,KACzB,gBAAAA,MAAC,OAAE,WAAU,YAAW,MAAK,QAAO,cAAW,gBAC5C,kCAAwB,IAAI,CAAC,EAAE,QAAQ,kBAAkB,MAAM;AAC9D,iBACE,gBAAAA,MAAC,OAAkB,MAAK,YACrB,uBAAa,QAAQ,kBAAkB,QAAQ,KAD1C,OAAO,EAEf;AAAA,QAEJ,CAAC,GACH;AAAA,QAID,oBAAoB,sBAAsB,SAAS,KAClD,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,MAAK;AAAA,YACL,cAAW;AAAA,YAEV,gCAAsB,IAAI,CAAC,EAAE,iBAAiB,KAAK,MAAM;AACxD,oBAAM,QAAQ;AAAA,gBACZ;AAAA,gBACA,KAAK;AAAA,gBACL,kBAAkB,KAAK;AAAA,cACzB;AACA,oBAAM,eAAe;AAAA,gBACnB;AAAA,gBACA;AAAA,cACF;AACA,oBAAM,oBAAoB,KAAK;AAAA,gBAC7B,KAAK,SAAS,KAAK,KAAK,SAAS;AAAA,gBACjC,KAAK,SAAS,KAAK,KAAK,SAAS;AAAA,cACnC;AACA,qBACE,gBAAAC;AAAA,gBAAC;AAAA;AAAA,kBAEC,MAAM,eAAe,WAAW;AAAA,kBAChC,WAAWC,OAAK,gBAAgB,gBAAgB;AAAA,kBAChD,gBAAgB,MAAM,iBAAiB,KAAK,EAAE;AAAA,kBAC9C,gBAAgB,MACd;AAAA,oBAAiB,CAAC,cAChB,cAAc,KAAK,KAAK,OAAO;AAAA,kBACjC;AAAA,kBAEF,SACE,eACI,MAAM;AACJ,yBAAK,MAAM,SAAS;AAAA,kBACtB,IACA;AAAA,kBAEN,WAAW,CAAC,UACV;AAAA,oBACE;AAAA,oBACA,eACI,MAAM;AACJ,2BAAK,MAAM,SAAS;AAAA,oBACtB,IACA;AAAA,kBACN;AAAA,kBAEF,UAAU,eAAe,IAAI;AAAA,kBAC7B,cAAY,eAAe,eAAe,KAAK,EAAE,KAAK;AAAA,kBAErD;AAAA,oCACC,gBAAAF;AAAA,sBAAC;AAAA;AAAA,wBACC,GAAG,KAAK,SAAS,OAAO,oBAAoB;AAAA,wBAC5C,GAAG,KAAK,SAAS,OAAO;AAAA,wBACxB,OAAO;AAAA,wBACP,QAAQ,sBAAsB;AAAA,wBAC9B,IAAI;AAAA,wBACJ,MAAK;AAAA,wBACL,WAAW,UAAU,KAAK,SAAS,SAAS,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI;AAAA,wBACxF,eAAc;AAAA;AAAA,oBAChB;AAAA,oBAED,wBACC,sBAAsB,MAAM,KAAK,UAAU,KAAK,IAC9C,MAAM,aAAa,MAAM,aAC3B,gBAAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,UAAU,KAAK;AAAA,wBACf,WAAW,MAAM;AAAA,wBACjB,aAAa,sBAAsB;AAAA;AAAA,oBACrC,IACE;AAAA;AAAA;AAAA,gBAjDC,KAAK;AAAA,cAkDZ;AAAA,YAEJ,CAAC;AAAA;AAAA,QACH;AAAA,QAID,uBAAuB,wBAAwB,SAAS,KACvD,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,MAAK;AAAA,YACL,cAAW;AAAA,YAEV,kCAAwB,IAAI,CAAC,EAAE,mBAAmB,OAAO,MAAM;AAC9D,oBAAM,QAAQ;AAAA,gBACZ;AAAA,gBACA,OAAO;AAAA,gBACP,oBAAoB,OAAO;AAAA,cAC7B;AACA,oBAAM,eAAe;AAAA,gBACnB;AAAA,gBACA;AAAA,cACF;AACA,qBACE,gBAAAC;AAAA,gBAAC;AAAA;AAAA,kBAEC,MAAM,eAAe,WAAW;AAAA,kBAChC,WAAWC,OAAK,gBAAgB,gBAAgB;AAAA,kBAChD,gBAAgB,MAAM,mBAAmB,OAAO,EAAE;AAAA,kBAClD,gBAAgB,MACd;AAAA,oBAAmB,CAAC,cAClB,cAAc,OAAO,KAAK,OAAO;AAAA,kBACnC;AAAA,kBAEF,SACE,eACI,MAAM;AACJ,yBAAK,MAAM,SAAS;AAAA,kBACtB,IACA;AAAA,kBAEN,WAAW,CAAC,UACV;AAAA,oBACE;AAAA,oBACA,eACI,MAAM;AACJ,2BAAK,MAAM,SAAS;AAAA,oBACtB,IACA;AAAA,kBACN;AAAA,kBAEF,UAAU,eAAe,IAAI;AAAA,kBAC7B,cACE,eAAe,iBAAiB,OAAO,EAAE,KAAK;AAAA,kBAG/C;AAAA,oCACC,gBAAAF;AAAA,sBAAC;AAAA;AAAA,wBACC,IAAI,OAAO,SAAS;AAAA,wBACpB,IAAI,OAAO,SAAS;AAAA,wBACpB,GAAG,wBAAwB;AAAA,wBAC3B,MAAK;AAAA,wBACL,eAAc;AAAA;AAAA,oBAChB;AAAA,oBAED,0BACC,wBAAwB,QAAQ,OAAO,UAAU,KAAK,IACpD,MAAM,aAAa,MAAM,aAC3B,gBAAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,UAAU,OAAO;AAAA,wBACjB,WAAW,MAAM;AAAA,wBACjB,MAAM,wBAAwB;AAAA;AAAA,oBAChC,IACE;AAAA;AAAA;AAAA,gBAhDC,OAAO;AAAA,cAiDd;AAAA,YAEJ,CAAC;AAAA;AAAA,QACH;AAAA,QAID,oBAAoB,UAAU,SAAS,KACtC,gBAAAC;AAAA,UAAC;AAAA;AAAA,YACC,WAAW,aAAa,WAAW,EAAE,KAAK,WAAW,gBAAgB,EAAE;AAAA,YAEvE;AAAA,8BAAAD;AAAA,gBAAC;AAAA;AAAA,kBACC,GAAG;AAAA,kBACH,GAAG;AAAA,kBACH,OAAO;AAAA,kBACP,QAAQ;AAAA,kBACR,IAAI;AAAA,kBACJ,MAAK;AAAA;AAAA,cACP;AAAA,cACA,gBAAAC,OAAC,UAAK,GAAG,IAAI,GAAG,IAAI,YAAW,UAAS,MAAK,SAAQ,UAAU,IAC5D;AAAA,qBAAK,MAAM,UAAU,OAAO,GAAG;AAAA,gBAAE;AAAA,iBACpC;AAAA;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EAEJ;AAEJ;AAEO,IAAM,UAAU;;;AClsChB,SAAS,mBAId,OACA,SACkC;AAClC,QAAM,cAAc,oBAAI,IAAwB;AAChD,aAAW,WAAW,QAAQ,QAAQ;AACpC,QAAI,YAAY,IAAI,QAAQ,EAAE,GAAG;AAC/B,YAAM,IAAI;AAAA,QACR,oDAAoD,QAAQ,EAAE;AAAA,MAChE;AAAA,IACF;AACA,gBAAY,IAAI,QAAQ,IAAI,OAAO;AAAA,EACrC;AAEA,QAAM,WAAW,oBAAI,IAAY;AACjC,QAAM,kBAAkB,uBAAuB,KAAK;AACpD,QAAM,QACJ,gBAAgB,MAAM,IAAI,CAAC,SAAS;AAClC,UAAM,UAAU,YAAY,IAAI,KAAK,EAAE;AACvC,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI;AAAA,QACR,kDAAkD,KAAK,EAAE;AAAA,MAC3D;AAAA,IACF;AACA,aAAS,IAAI,KAAK,EAAE;AACpB,WAAO,EAAE,GAAG,MAAM,MAAM,QAAQ;AAAA,EAClC,CAAC;AAEH,aAAW,MAAM,YAAY,KAAK,GAAG;AACnC,QAAI,CAAC,SAAS,IAAI,EAAE,GAAG;AACrB,YAAM,IAAI;AAAA,QACR,gCAAgC,EAAE;AAAA,MACpC;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,IAAI,gBAAgB;AAAA,IACpB,QAAQ;AAAA,IACR,aAAa,MAAM;AAAA,IACnB;AAAA,IACA,OAAO,MAAM;AAAA,IACb,UAAU,MAAM;AAAA,EAClB;AACF;","names":["useState","useEffect","useEffect","useMemo","useState","useState","useEffect","useMemo","jsx","clsx","jsx","jsxs","createContext","useCallback","useContext","useEffect","useMemo","useState","jsx","suppressed","clsx","clsx","jsx","jsx","clsx","useState","jsx","jsxs","useState","clsx","useCallback","useState","useState","useEffect","useMemo","useCallback","jsx","clsx","useCallback","useState","clsx","jsx","jsxs","clsx","createContext","useCallback","useContext","useEffect","useId","useMemo","useRef","useState","clsx","jsx","jsxs","createContext","useContext","useId","useRef","useState","useCallback","useMemo","useEffect","clsx","useCallback","useId","useMemo","clsx","useEffect","useMemo","useRef","useState","useRef","useState","useEffect","node","useMemo","useCallback","useEffect","useMemo","useRef","useState","useRef","useCallback","useState","useMemo","useEffect","jsx","CARD_DIMENSIONS","useMemo","useId","useCallback","clsx","createContext","useCallback","useContext","useEffect","useMemo","useRef","useState","useDrag","clsx","jsx","jsxs","createContext","useState","useCallback","useMemo","useContext","useEffect","useRef","useDrag","clsx","motion","AnimatePresence","clsx","jsx","clsx","AnimatePresence","motion","motion","clsx","jsx","jsxs","motion","AnimatePresence","jsx","jsx","createContext","useContext","useState","useCallback","Fragment","jsx","jsxs","createContext","useState","useCallback","useContext","AnimatePresence","Icon","surfaceStyle","motion","AlertTriangle","Fragment","jsx","jsxs","AlertTriangle","jsx","jsxs","jsx","jsx","jsx","jsxs","createContext","useContext","useMemo","jsx","createContext","useContext","useMemo","clsx","jsx","jsx","jsxs","clsx","Icon","jsx","jsxs","Icon","jsx","useEffect","useRef","useState","motion","Fragment","jsx","jsxs","useState","useRef","useEffect","motion","useId","useState","motion","AnimatePresence","jsx","jsxs","useId","useState","motion","AnimatePresence","useId","useState","jsx","jsxs","useState","useId","clsx","motion","useCallback","useEffect","useRef","useState","createContext","useContext","jsx","jsx","jsxs","clsx","useState","useRef","useEffect","useCallback","motion","motion","clsx","jsx","jsxs","clsx","motion","motion","useEffect","useState","jsx","jsxs","useState","useEffect","motion","useMemo","clsx","Fragment","jsx","jsxs","clsx","useMemo","useMemo","clsx","jsx","jsxs","clsx","useMemo","useMemo","clsx","jsx","jsxs","clsx","useMemo","useMemo","clsx","jsx","jsxs","clsx","useMemo","useMemo","useState","clsx","jsx","jsxs","clsx","useState","useMemo","useMemo","useState","clsx","jsx","jsxs","clsx","useMemo","useState"]}
|
|
1
|
+
{"version":3,"sources":["../src/ui/hooks/usePanZoom.ts","../src/ui/hooks/useIsMobile.ts","../src/ui/theme/tokens.ts","../src/ui/theme/presets/tabletop.ts","../src/ui/theme/presets/arcade.ts","../src/ui/theme/presets/studio.ts","../src/ui/theme/css-vars.ts","../src/ui/theme/ThemeProvider.tsx","../src/ui/theme/derive.ts","../src/ui/types/tiled-board.ts","../src/ui/types/visual-state.ts","../src/ui/components/Card.tsx","../src/ui/components/Drawer.tsx","../src/ui/components/ChromeSuppressionContext.tsx","../src/ui/components/ThemedButton.tsx","../src/ui/internal/ui/button.tsx","../src/ui/internal/ui/utils.ts","../src/ui/components/HandDock.tsx","../src/ui/components/Hand.tsx","../src/ui/hooks/useHandLayout.ts","../src/ui/components/StagingZone.tsx","../src/ui/components/CardDragSurface.tsx","../src/ui/components/HandView.tsx","../src/ui/hooks/useHandPresentation.ts","../src/ui/components/hand-layout-math.ts","../src/ui/hooks/useHandCardPointer.ts","../src/ui/components/hand-pointer-engine.ts","../src/ui/components/MobileHandTray.tsx","../src/ui/components/PlayArea.tsx","../src/ui/components/GameSkeleton.tsx","../src/ui/components/Toast.tsx","../src/ui/internal/ui/alert.tsx","../src/ui/components/ErrorBoundary.tsx","../src/ui/internal/ui/dialog.tsx","../src/ui/internal/ui/input.tsx","../src/ui/internal/ui/label.tsx","../src/ui/internal/ui/select.tsx","../src/ui/components/ResourceCounter.tsx","../src/ui/components/CostDisplay.tsx","../src/ui/internal/ui/tooltip.tsx","../src/ui/components/ActionButton.tsx","../src/ui/components/PrimaryButton.tsx","../src/ui/components/PrimaryActionButton.tsx","../src/ui/components/ActionPanel.tsx","../src/ui/components/MoreActions.tsx","../src/ui/components/DiceRoller.tsx","../src/ui/primitives/dice.tsx","../src/ui/components/PhaseIndicator.tsx","../src/ui/components/GameEndDisplay.tsx","../src/ui/components/board/NetworkGraph.tsx","../src/ui/components/board/interaction-accessibility.ts","../src/ui/components/board/ZoneMap.tsx","../src/ui/components/board/TrackBoard.tsx","../src/ui/components/board/SlotSystem.tsx","../src/ui/components/board/SquareGrid.tsx","../src/ui/components/board/target-layer.ts","../src/ui/components/board/HexGrid.tsx","../src/ui/components/board/hex-board-view.ts"],"sourcesContent":["/**\n * usePanZoom hook - Unified pan and zoom gestures using @use-gesture/react\n *\n * Provides a declarative API for pan and zoom interactions on board components.\n * Works with both SVG (via viewBox) and HTML (via CSS transforms) elements.\n *\n * Features:\n * - Single finger/mouse drag for panning\n * - Pinch-to-zoom on touch devices\n * - Mouse wheel zoom on desktop\n * - Configurable zoom limits\n * - Optional momentum/inertia\n *\n * @example SVG usage (NetworkGraph, HexGrid, etc.)\n * ```tsx\n * const { transform, bind, resetTransform } = usePanZoom({\n * enabled: enablePanZoom,\n * minZoom: 0.5,\n * maxZoom: 3,\n * });\n *\n * // Apply to viewBox calculation\n * const viewBoxWidth = contentWidth / transform.zoom;\n * const viewBoxX = baseX - transform.pan.x;\n *\n * <svg {...bind()} style={{ touchAction: 'none' }}>\n * ...\n * </svg>\n * ```\n *\n * @example HTML usage (SlotSystem, etc.)\n * ```tsx\n * const { transform, bind, style } = usePanZoom({\n * enabled: enablePanZoom,\n * mode: 'css',\n * });\n *\n * <div {...bind()} style={{ ...style, touchAction: 'none' }}>\n * ...\n * </div>\n * ```\n */\n\nimport { useState, useCallback, useEffect, useMemo } from \"react\";\nimport { useGesture, type Handler } from \"@use-gesture/react\";\n\nexport interface PanZoomTransform {\n /** Current zoom level (1 = 100%) */\n zoom: number;\n /** Current pan offset */\n pan: { x: number; y: number };\n}\n\nexport interface UsePanZoomOptions {\n /** Whether pan/zoom is enabled */\n enabled?: boolean;\n /** Initial zoom level */\n initialZoom?: number;\n /** Minimum zoom level */\n minZoom?: number;\n /** Maximum zoom level */\n maxZoom?: number;\n /** Initial pan offset */\n initialPan?: { x: number; y: number };\n /** Transform mode: 'viewbox' for SVG, 'css' for HTML elements */\n mode?: \"viewbox\" | \"css\";\n /** Zoom sensitivity for wheel events (default: 0.002) */\n wheelSensitivity?: number;\n /** Called when transform changes */\n onTransformChange?: (transform: PanZoomTransform) => void;\n}\n\n/** Type for gesture bind function that returns props to spread on element\n * Note: We omit ref from the return type to avoid conflicts with explicit refs on elements.\n * The gesture library handles its own internal ref binding.\n */\ntype GestureBindFunction = () => Omit<React.HTMLAttributes<Element>, \"ref\">;\n\nexport interface UsePanZoomReturn {\n /** Current transform state */\n transform: PanZoomTransform;\n /** Gesture handlers to spread on the target element - always returns spreadable props */\n bind: GestureBindFunction;\n /** Reset transform to initial values */\n resetTransform: () => void;\n /** Set zoom programmatically */\n setZoom: (zoom: number) => void;\n /** Set pan programmatically */\n setPan: (pan: { x: number; y: number }) => void;\n /** CSS transform style (for mode: 'css') */\n style: React.CSSProperties;\n /** Whether currently dragging/panning */\n isDragging: boolean;\n /** Whether currently pinching */\n isPinching: boolean;\n}\n\n/**\n * Hook for pan and zoom gestures on board components\n */\nexport function usePanZoom(options: UsePanZoomOptions = {}): UsePanZoomReturn {\n const {\n enabled = true,\n initialZoom = 1,\n minZoom = 0.5,\n maxZoom = 3,\n initialPan = { x: 0, y: 0 },\n mode = \"viewbox\",\n wheelSensitivity = 0.002,\n onTransformChange,\n } = options;\n\n const [zoom, setZoomState] = useState(initialZoom);\n const [pan, setPanState] = useState(initialPan);\n const [isDragging, setIsDragging] = useState(false);\n const [isPinching, setIsPinching] = useState(false);\n\n // Clamp zoom to bounds\n const clampZoom = useCallback(\n (z: number) => Math.min(maxZoom, Math.max(minZoom, z)),\n [minZoom, maxZoom],\n );\n\n // Update transform and notify\n const updateTransform = useCallback(\n (newZoom: number, newPan: { x: number; y: number }) => {\n const clampedZoom = clampZoom(newZoom);\n setZoomState(clampedZoom);\n setPanState(newPan);\n onTransformChange?.({ zoom: clampedZoom, pan: newPan });\n },\n [clampZoom, onTransformChange],\n );\n\n // Gesture bindings\n const bind = useGesture(\n {\n onDrag: (({\n delta: [dx, dy],\n active,\n pinching,\n }: Parameters<Handler<\"drag\">>[0]) => {\n if (!enabled || pinching) return;\n\n setIsDragging(active);\n\n if (active) {\n // For viewbox mode, we invert and scale the delta\n // For CSS mode, we apply directly\n const scaleFactor = mode === \"viewbox\" ? 1 / zoom : 1;\n setPanState((prev) => ({\n x: prev.x + dx * scaleFactor,\n y: prev.y + dy * scaleFactor,\n }));\n }\n }) as Handler<\"drag\">,\n onPinch: (({\n offset: [scale],\n active,\n }: Parameters<Handler<\"pinch\">>[0]) => {\n if (!enabled) return;\n\n setIsPinching(active);\n\n if (active) {\n const newZoom = clampZoom(scale);\n setZoomState(newZoom);\n onTransformChange?.({ zoom: newZoom, pan });\n }\n }) as Handler<\"pinch\">,\n onWheel: (({ delta: [, dy], event }: Parameters<Handler<\"wheel\">>[0]) => {\n if (!enabled) return;\n\n event.preventDefault();\n const newZoom = clampZoom(zoom - dy * wheelSensitivity);\n setZoomState(newZoom);\n onTransformChange?.({ zoom: newZoom, pan });\n }) as Handler<\"wheel\">,\n },\n {\n drag: {\n enabled,\n filterTaps: true,\n },\n pinch: {\n enabled,\n scaleBounds: { min: minZoom, max: maxZoom },\n from: () => [zoom, 0],\n },\n wheel: {\n enabled,\n eventOptions: { passive: false },\n },\n },\n );\n\n // Reset to initial values\n const resetTransform = useCallback(() => {\n updateTransform(initialZoom, initialPan);\n }, [initialZoom, initialPan, updateTransform]);\n\n useEffect(() => {\n updateTransform(initialZoom, initialPan);\n }, [initialZoom, initialPan.x, initialPan.y, updateTransform]);\n\n // Programmatic setters\n const setZoom = useCallback(\n (newZoom: number) => {\n updateTransform(clampZoom(newZoom), pan);\n },\n [pan, clampZoom, updateTransform],\n );\n\n const setPan = useCallback(\n (newPan: { x: number; y: number }) => {\n updateTransform(zoom, newPan);\n },\n [zoom, updateTransform],\n );\n\n // CSS transform style for HTML mode\n const style = useMemo<React.CSSProperties>(\n () =>\n mode === \"css\"\n ? {\n transform: `translate(${pan.x}px, ${pan.y}px) scale(${zoom})`,\n transformOrigin: \"center center\",\n }\n : {},\n [mode, pan.x, pan.y, zoom],\n );\n\n // Current transform state\n const transform = useMemo<PanZoomTransform>(\n () => ({ zoom, pan }),\n [zoom, pan],\n );\n\n // Wrap bind to ensure it always returns spreadable props (never void)\n // We exclude 'ref' from the result to avoid type conflicts with explicit element refs\n const safeBind: GestureBindFunction = useCallback(() => {\n const result = bind();\n // If bind returns void (shouldn't happen with our config), return empty object\n // Destructure to omit ref, avoiding type conflicts with SVG/HTML element refs\n\n const { ref: _ref, ...propsWithoutRef } = (result ??\n {}) as React.HTMLAttributes<Element> & { ref?: unknown };\n return propsWithoutRef;\n }, [bind]);\n\n return {\n transform,\n bind: safeBind,\n resetTransform,\n setZoom,\n setPan,\n style,\n isDragging,\n isPinching,\n };\n}\n\n/**\n * Helper to calculate SVG viewBox with pan/zoom applied\n */\nexport function calculateViewBox(\n bounds: { minX: number; minY: number; width: number; height: number },\n transform: PanZoomTransform,\n): string {\n const viewBoxWidth = bounds.width / transform.zoom;\n const viewBoxHeight = bounds.height / transform.zoom;\n const viewBoxX =\n bounds.minX + (bounds.width - viewBoxWidth) / 2 - transform.pan.x;\n const viewBoxY =\n bounds.minY + (bounds.height - viewBoxHeight) / 2 - transform.pan.y;\n\n return `${viewBoxX} ${viewBoxY} ${viewBoxWidth} ${viewBoxHeight}`;\n}\n","import { useState, useEffect } from \"react\";\n\nconst MOBILE_BREAKPOINT = 768;\n\n/**\n * Hook to detect if the user is on a mobile/small screen device\n * @param breakpoint - The width threshold in pixels (default: 768)\n * @returns boolean indicating if the screen is mobile-sized\n */\nexport function useIsMobile(breakpoint: number = MOBILE_BREAKPOINT): boolean {\n const [isMobile, setIsMobile] = useState(() => {\n // SSR-safe: default to false if window is not available\n if (typeof window === \"undefined\") return false;\n return window.innerWidth < breakpoint;\n });\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n const mediaQuery = window.matchMedia(`(max-width: ${breakpoint - 1}px)`);\n\n const handleChange = (e: MediaQueryListEvent | MediaQueryList) => {\n setIsMobile(e.matches);\n };\n\n // Set initial value\n handleChange(mediaQuery);\n\n // Listen for changes\n mediaQuery.addEventListener(\"change\", handleChange);\n return () => mediaQuery.removeEventListener(\"change\", handleChange);\n }, [breakpoint]);\n\n return isMobile;\n}\n","/**\n * Token contract for `@dreamboard-games/sdk/ui`.\n *\n * The {@link Theme} object is the only thing components consume for\n * visual styling. Every preset (tabletop, arcade, studio) is just a\n * different fully-resolved {@link Theme}; every author override is a\n * deep partial of it. Components never inline hex codes, font stacks,\n * or shadow strings — they read from `useTheme()` (or, when written in\n * Tailwind, from CSS variables that the {@link ThemeProvider} writes\n * onto its wrapper element).\n *\n * Architectural rules:\n *\n * 1. **Foundation → Semantic → Component.** Foundation palette ramps\n * (`color.neutral`, `color.brand`, …) are never read directly by\n * components. Components read `semantic.*` (e.g. `surface.card`,\n * `intent.primary`) which the preset maps from foundation tokens.\n * 2. **No optional deep keys.** Presets must supply every leaf so\n * components don't need fallbacks. Author-supplied overrides are\n * `DeepPartial<Theme>` and merged before the provider mounts.\n * 3. **Scalar leaves only.** Every leaf is a string (CSS-ready) so the\n * serializer can emit a CSS variable for it without per-token\n * formatting logic.\n */\n\n/** Identity-only metadata. */\nexport interface ThemeMeta {\n /** Stable id used by `data-dreamboard-theme` and CSS-var scoping. */\n readonly id: string;\n /** Human-readable name for dev tools. */\n readonly name: string;\n /**\n * Render mode hint for components that need to choose between light\n * and dark sub-tokens. Presets pick one; authors don't toggle this.\n */\n readonly mode: \"light\" | \"dark\";\n}\n\n/** Foundation color ramp. Six stops keeps presets compact. */\nexport interface ColorRamp {\n readonly 50: string;\n readonly 100: string;\n readonly 200: string;\n readonly 400: string;\n readonly 600: string;\n readonly 800: string;\n readonly 950: string;\n}\n\n/**\n * Per-player color tokens. The {@link Theme.player} array is indexed by\n * 0-based seat slot (`player[0]` = first seat). Each entry carries a\n * `solid` brand color, a `soft` tint usable as a background, and `on`\n * — the recommended foreground when text sits on `solid`.\n */\nexport interface PlayerColor {\n readonly solid: string;\n readonly soft: string;\n readonly on: string;\n}\n\n/**\n * Foundation palette. Components never read this directly; presets map\n * these into {@link SemanticTokens}. Exposed so authors who write a\n * full theme can compose without inventing their own palette type.\n */\nexport interface FoundationColor {\n readonly neutral: ColorRamp;\n readonly brand: ColorRamp;\n readonly accent: ColorRamp;\n readonly success: ColorRamp;\n readonly warning: ColorRamp;\n readonly danger: ColorRamp;\n readonly info: ColorRamp;\n}\n\n/**\n * Semantic colors consumed by every component. These are the *only*\n * color tokens components should reference. Names describe role\n * (\"the surface a player card sits on\"), not appearance (\"light grey\").\n */\nexport interface SemanticColor {\n readonly surface: {\n /** Outermost shell background. */\n readonly app: string;\n /** Board canvas background (behind tiles). */\n readonly board: string;\n /** HUD chrome panels (top bar, action bar, side rails). */\n readonly hud: string;\n /** Standalone cards (player cards, action cards, hand cards). */\n readonly card: string;\n /** Modal/sheet body. */\n readonly sheet: string;\n /** Scrim behind a blocker overlay. */\n readonly overlay: string;\n /** Subtle inset (resource pills, count badges, …). */\n readonly inset: string;\n };\n readonly text: {\n /** Default body and headline text on light surfaces. */\n readonly primary: string;\n /** De-emphasised metadata, hint copy, captions. */\n readonly muted: string;\n /** Text used on `intent.primary` solid backgrounds. */\n readonly onIntent: string;\n /** Brand-tinted text for emphasis (links, key numbers). */\n readonly accent: string;\n /** Disabled text (button labels in disabled state). */\n readonly disabled: string;\n };\n readonly border: {\n /** Hairline divider between sibling rows. */\n readonly subtle: string;\n /** Standard card / panel border. */\n readonly default: string;\n /** Outlined emphasis (hovered tiles, selected card). */\n readonly strong: string;\n /** Focus ring (keyboard nav). */\n readonly focus: string;\n };\n /**\n * Intent colours map to action emphasis. Components pick a slot\n * (`primary` for \"do the main thing now\", `danger` for destructive\n * confirms, etc.) and read both the surface and on-color from it.\n */\n readonly intent: {\n readonly primary: IntentColor;\n readonly secondary: IntentColor;\n readonly success: IntentColor;\n readonly danger: IntentColor;\n readonly warning: IntentColor;\n readonly info: IntentColor;\n };\n}\n\n/** A semantic intent (button background + matching foreground + soft tint). */\nexport interface IntentColor {\n /** Solid fill (button bg, badge bg). */\n readonly solid: string;\n /** Recommended text/icon color sitting on `solid`. */\n readonly on: string;\n /** Subtle tint (e.g. badge bg with `text` for foreground). */\n readonly soft: string;\n /** Suitable foreground when sitting on `soft`. */\n readonly onSoft: string;\n /** Border tint matched to this intent (e.g. focus ring on intent). */\n readonly border: string;\n}\n\n/** Border-radius ramp. */\nexport interface Radius {\n readonly none: string;\n readonly sm: string;\n readonly md: string;\n readonly lg: string;\n /** HUD chrome (top bar pieces, action-bar bar). */\n readonly hud: string;\n /** Fully-round badges/pills. */\n readonly pill: string;\n}\n\n/** Spacing ramp (rem-based by default). */\nexport interface Space {\n readonly 0: string;\n readonly 0.5: string;\n readonly 1: string;\n readonly 1.5: string;\n readonly 2: string;\n readonly 3: string;\n readonly 4: string;\n readonly 6: string;\n readonly 8: string;\n readonly 12: string;\n}\n\n/** Typography tokens. */\nexport interface Typography {\n readonly fontFamily: {\n /** Hero text — phase name, scoreboard headline, winner banner. */\n readonly display: string;\n /** Default UI body text. */\n readonly body: string;\n /** Numeric runs (scores, counters, tabular data). Tabular figures preferred. */\n readonly tabular: string;\n /** Source/code/raw-id rendering. */\n readonly mono: string;\n };\n readonly fontSize: {\n readonly xs: string;\n readonly sm: string;\n readonly md: string;\n readonly lg: string;\n readonly xl: string;\n readonly \"2xl\": string;\n readonly \"3xl\": string;\n };\n readonly fontWeight: {\n readonly regular: string;\n readonly medium: string;\n readonly bold: string;\n };\n readonly lineHeight: {\n readonly tight: string;\n readonly normal: string;\n readonly relaxed: string;\n };\n readonly letterSpacing: {\n readonly tight: string;\n readonly normal: string;\n readonly wide: string;\n /** All-caps labels (\"YOUR TURN\"). */\n readonly caps: string;\n };\n}\n\n/** Drop-shadow elevation ramp. */\nexport interface Elevation {\n /** Resting state (cards, panels). */\n readonly rest: string;\n /** Hover-lift (interactive cards). */\n readonly hover: string;\n /** Selected / dragged element. */\n readonly lifted: string;\n /** Modal / overlay stack. */\n readonly overlay: string;\n /** Inner shadow (board canvas inset, resource pill well). */\n readonly inset: string;\n}\n\n/**\n * Motion tokens. Components import durations and easings from here so a\n * single `prefers-reduced-motion` switch zeroes everything out at the\n * provider, not per-component.\n */\nexport interface Motion {\n readonly duration: {\n /** Hover, focus, micro-press (~80ms). */\n readonly fast: string;\n /** Default — most state changes (~160ms). */\n readonly normal: string;\n /** Layout shifts, drawer open/close (~280ms). */\n readonly slow: string;\n /**\n * Looping ambient pulses — active-player breath, dice glow.\n * Components should respect `motion.reducedMotion` before kicking\n * off looping animations.\n */\n readonly ambient: string;\n };\n readonly easing: {\n /** Default for entering / settling. */\n readonly out: string;\n /** Default for exiting. */\n readonly in: string;\n /** Symmetric. */\n readonly inOut: string;\n /** Springy — selected card lift, active-player wobble. */\n readonly spring: string;\n };\n /**\n * `\"true\"` when the active client requests reduced motion. Components\n * should branch on this rather than forcing animations off via CSS,\n * because some animations (e.g. dice roll, shuffle) are critical for\n * conveying state and need a static fallback.\n */\n readonly reducedMotion: \"true\" | \"false\";\n}\n\n/**\n * Component-level token slots derived from semantic + foundation tokens.\n * Kept intentionally tiny — a slot is added here only when a component\n * needs to deviate from the semantic mapping in a way that authors\n * should be able to customise without re-skinning the whole intent\n * scale.\n */\nexport interface ComponentTokens {\n readonly board: {\n /** Outer ring around the board canvas. */\n readonly frameBorder: string;\n /** Inner board surface tint (overlays the canvas tile renderer). */\n readonly frameBackground: string;\n /** Highlight ring drawn on hovered interactive targets. */\n readonly hoverRing: string;\n /** Idle hint colour for eligible-but-unhovered targets. */\n readonly eligibleHint: string;\n };\n readonly card: {\n /** Border drawn around face-up cards. */\n readonly border: string;\n /** Border drawn around face-down cards. */\n readonly backBorder: string;\n /** Card-back fill colour. */\n readonly backBackground: string;\n /** Selected outline. */\n readonly selectedRing: string;\n };\n readonly playerCard: {\n /** Background of the active-player card. */\n readonly activeBackground: string;\n /** Border of the active-player card. */\n readonly activeBorder: string;\n /** Glow colour radiated by the active-player card. */\n readonly activeGlow: string;\n /** Background of the \"you\" badge. */\n readonly youBadgeBackground: string;\n /** Foreground of the \"you\" badge. */\n readonly youBadgeForeground: string;\n };\n readonly toast: {\n readonly successBackground: string;\n readonly errorBackground: string;\n readonly infoBackground: string;\n readonly foreground: string;\n };\n}\n\n/**\n * The complete theme contract. Every leaf is a CSS-ready string so the\n * provider can emit a CSS variable for each path without per-leaf\n * formatting. {@link DeepPartial} is exported for author overrides.\n */\nexport interface Theme {\n readonly meta: ThemeMeta;\n readonly color: FoundationColor;\n readonly semantic: SemanticColor;\n readonly radius: Radius;\n readonly space: Space;\n readonly typography: Typography;\n readonly elevation: Elevation;\n readonly motion: Motion;\n readonly player: readonly [\n PlayerColor,\n PlayerColor,\n PlayerColor,\n PlayerColor,\n PlayerColor,\n PlayerColor,\n ];\n readonly component: ComponentTokens;\n}\n\n/**\n * Recursive partial for theme overrides. Authors pass this to\n * `<ThemeProvider override={...}/>` (or to a preset's `extend`\n * helper) to tweak individual tokens without re-declaring the whole\n * tree.\n */\nexport type ThemeOverride = DeepPartial<Theme>;\n\ntype DeepPartial<T> =\n T extends ReadonlyArray<infer U>\n ? ReadonlyArray<DeepPartial<U>>\n : T extends object\n ? { readonly [K in keyof T]?: DeepPartial<T[K]> }\n : T;\n\n/**\n * Deep merge for {@link Theme} overrides. Arrays (notably\n * {@link Theme.player}) are *replaced* rather than merged so callers\n * can't accidentally end up with mixed-preset palettes.\n */\nexport function mergeTheme(base: Theme, override?: ThemeOverride): Theme {\n if (!override) return base;\n return mergeDeep(base, override) as Theme;\n}\n\nfunction mergeDeep<T>(base: T, override: unknown): T {\n if (Array.isArray(override)) {\n // Arrays replace wholesale — see contract docs.\n return override as T;\n }\n if (\n base &&\n typeof base === \"object\" &&\n override &&\n typeof override === \"object\" &&\n !Array.isArray(base)\n ) {\n const result: Record<string, unknown> = {\n ...(base as Record<string, unknown>),\n };\n for (const [key, value] of Object.entries(\n override as Record<string, unknown>,\n )) {\n if (value === undefined) continue;\n const baseValue = (base as Record<string, unknown>)[key];\n result[key] = mergeDeep(baseValue, value);\n }\n return result as T;\n }\n return override === undefined ? base : (override as T);\n}\n","import type { Theme } from \"../tokens.js\";\n\n/**\n * `tabletop` — the default Dreamboard theme.\n *\n * Visual identity: warm paper backgrounds, deep ink-blue brand,\n * confident type, rounded but disciplined corners. Designed to feel\n * like a polished hobby-game client (Splendor digital, modern Catan\n * apps) without leaning into a specific game's IP.\n *\n * Picked deliberately for the default: a board game UI sitting on\n * cool grey or pure white reads as \"spreadsheet\"; warm parchment\n * cues \"play\" without sliding into kitsch.\n */\nexport const tabletopTheme: Theme = {\n meta: {\n id: \"tabletop\",\n name: \"Tabletop\",\n mode: \"light\",\n },\n color: {\n neutral: {\n 50: \"#fbf8f1\",\n 100: \"#f4ecd8\",\n 200: \"#e7dcc1\",\n 400: \"#a89c84\",\n 600: \"#5f5547\",\n 800: \"#2f2a22\",\n 950: \"#15120d\",\n },\n brand: {\n 50: \"#eef3fb\",\n 100: \"#d3e0f3\",\n 200: \"#a7c1e7\",\n 400: \"#5780bf\",\n 600: \"#2d5da1\",\n 800: \"#1a3c6b\",\n 950: \"#0d1f37\",\n },\n accent: {\n 50: \"#fff5e0\",\n 100: \"#ffe5b3\",\n 200: \"#fcd07a\",\n 400: \"#f0a738\",\n 600: \"#c87a16\",\n 800: \"#7e4a08\",\n 950: \"#3c2103\",\n },\n success: {\n 50: \"#e8f6ec\",\n 100: \"#c4ecd0\",\n 200: \"#8fd6a3\",\n 400: \"#3fae62\",\n 600: \"#1f7d3e\",\n 800: \"#0d4a23\",\n 950: \"#062213\",\n },\n warning: {\n 50: \"#fff5dc\",\n 100: \"#ffe7a8\",\n 200: \"#fad164\",\n 400: \"#dca41a\",\n 600: \"#9c6f06\",\n 800: \"#5b4002\",\n 950: \"#2b1d00\",\n },\n danger: {\n 50: \"#fdecec\",\n 100: \"#f9c7c7\",\n 200: \"#f08e8e\",\n 400: \"#d53f3f\",\n 600: \"#a31d1d\",\n 800: \"#5e0d0d\",\n 950: \"#2a0404\",\n },\n info: {\n 50: \"#e6f5fb\",\n 100: \"#bfe3f4\",\n 200: \"#7ec5e6\",\n 400: \"#2f8fc4\",\n 600: \"#0d5e8a\",\n 800: \"#073650\",\n 950: \"#021a26\",\n },\n },\n semantic: {\n surface: {\n app: \"#f6efe0\",\n board: \"#1a3552\",\n hud: \"#fbf8f1\",\n card: \"#ffffff\",\n sheet: \"#fbf8f1\",\n overlay: \"rgba(15, 23, 42, 0.55)\",\n inset: \"#f4ecd8\",\n },\n text: {\n primary: \"#2f2a22\",\n muted: \"#5f5547\",\n onIntent: \"#ffffff\",\n accent: \"#1a3c6b\",\n disabled: \"#a89c84\",\n },\n border: {\n subtle: \"#e7dcc1\",\n default: \"#a89c84\",\n strong: \"#5f5547\",\n focus: \"#2d5da1\",\n },\n intent: {\n primary: {\n solid: \"#2d5da1\",\n on: \"#ffffff\",\n soft: \"#d3e0f3\",\n onSoft: \"#1a3c6b\",\n border: \"#1a3c6b\",\n },\n secondary: {\n solid: \"#fbf8f1\",\n on: \"#2f2a22\",\n soft: \"#f4ecd8\",\n onSoft: \"#2f2a22\",\n border: \"#a89c84\",\n },\n success: {\n solid: \"#1f7d3e\",\n on: \"#ffffff\",\n soft: \"#c4ecd0\",\n onSoft: \"#0d4a23\",\n border: \"#0d4a23\",\n },\n danger: {\n solid: \"#a31d1d\",\n on: \"#ffffff\",\n soft: \"#f9c7c7\",\n onSoft: \"#5e0d0d\",\n border: \"#5e0d0d\",\n },\n warning: {\n solid: \"#dca41a\",\n on: \"#2f2a22\",\n soft: \"#ffe7a8\",\n onSoft: \"#5b4002\",\n border: \"#9c6f06\",\n },\n info: {\n solid: \"#0d5e8a\",\n on: \"#ffffff\",\n soft: \"#bfe3f4\",\n onSoft: \"#073650\",\n border: \"#073650\",\n },\n },\n },\n radius: {\n none: \"0px\",\n sm: \"6px\",\n md: \"10px\",\n lg: \"16px\",\n hud: \"20px\",\n pill: \"9999px\",\n },\n space: {\n 0: \"0\",\n 0.5: \"0.125rem\",\n 1: \"0.25rem\",\n 1.5: \"0.375rem\",\n 2: \"0.5rem\",\n 3: \"0.75rem\",\n 4: \"1rem\",\n 6: \"1.5rem\",\n 8: \"2rem\",\n 12: \"3rem\",\n },\n typography: {\n fontFamily: {\n display:\n '\"Fraunces\", \"Iowan Old Style\", \"Source Serif Pro\", \"Georgia\", serif',\n body: '\"Inter\", \"SF Pro Text\", system-ui, -apple-system, sans-serif',\n tabular: '\"JetBrains Mono\", \"SF Mono\", \"ui-monospace\", monospace',\n mono: '\"JetBrains Mono\", \"SF Mono\", \"ui-monospace\", monospace',\n },\n fontSize: {\n xs: \"0.6875rem\",\n sm: \"0.8125rem\",\n md: \"0.9375rem\",\n lg: \"1.0625rem\",\n xl: \"1.25rem\",\n \"2xl\": \"1.5rem\",\n \"3xl\": \"2rem\",\n },\n fontWeight: {\n regular: \"400\",\n medium: \"500\",\n bold: \"700\",\n },\n lineHeight: {\n tight: \"1.15\",\n normal: \"1.4\",\n relaxed: \"1.6\",\n },\n letterSpacing: {\n tight: \"-0.01em\",\n normal: \"0\",\n wide: \"0.04em\",\n caps: \"0.14em\",\n },\n },\n elevation: {\n rest: \"0 1px 0 rgba(15, 18, 13, 0.06), 0 2px 6px rgba(15, 18, 13, 0.05)\",\n hover: \"0 4px 0 rgba(15, 18, 13, 0.05), 0 8px 18px rgba(15, 18, 13, 0.12)\",\n lifted:\n \"0 12px 0 rgba(15, 18, 13, 0.05), 0 18px 36px rgba(15, 18, 13, 0.18)\",\n overlay: \"0 24px 64px rgba(15, 18, 13, 0.32)\",\n inset: \"inset 0 1px 0 rgba(15, 18, 13, 0.08)\",\n },\n motion: {\n duration: {\n fast: \"80ms\",\n normal: \"160ms\",\n slow: \"280ms\",\n ambient: \"1800ms\",\n },\n easing: {\n out: \"cubic-bezier(0.16, 1, 0.3, 1)\",\n in: \"cubic-bezier(0.4, 0, 1, 0.4)\",\n inOut: \"cubic-bezier(0.65, 0, 0.35, 1)\",\n spring: \"cubic-bezier(0.34, 1.56, 0.64, 1)\",\n },\n reducedMotion: \"false\",\n },\n player: [\n { solid: \"#d04848\", soft: \"#fcdedd\", on: \"#ffffff\" },\n { solid: \"#2d5da1\", soft: \"#d3e0f3\", on: \"#ffffff\" },\n { solid: \"#1f7d3e\", soft: \"#c4ecd0\", on: \"#ffffff\" },\n { solid: \"#c87a16\", soft: \"#ffe5b3\", on: \"#2f2a22\" },\n { solid: \"#7d4a8a\", soft: \"#e6d6ee\", on: \"#ffffff\" },\n { solid: \"#0d5e8a\", soft: \"#bfe3f4\", on: \"#ffffff\" },\n ],\n component: {\n board: {\n frameBorder: \"#a89c84\",\n frameBackground: \"#1a3552\",\n hoverRing: \"#f0a738\",\n eligibleHint: \"rgba(240, 167, 56, 0.55)\",\n },\n card: {\n border: \"#2f2a22\",\n backBorder: \"#1a3c6b\",\n backBackground: \"#2d5da1\",\n selectedRing: \"#d04848\",\n },\n playerCard: {\n activeBackground: \"#fff5e0\",\n activeBorder: \"#f0a738\",\n activeGlow: \"rgba(240, 167, 56, 0.32)\",\n youBadgeBackground: \"#d3e0f3\",\n youBadgeForeground: \"#1a3c6b\",\n },\n toast: {\n successBackground: \"#1f7d3e\",\n errorBackground: \"#a31d1d\",\n infoBackground: \"#0d5e8a\",\n foreground: \"#ffffff\",\n },\n },\n};\n","import type { Theme } from \"../tokens.js\";\n\n/**\n * `arcade` — high-contrast neon theme for fast/competitive games.\n *\n * Visual identity: deep slate background, electric cyan/magenta\n * intents, square-ish corners, sharp drop shadows. Designed to evoke\n * action games and to keep critical CTAs popping at a glance.\n */\nexport const arcadeTheme: Theme = {\n meta: {\n id: \"arcade\",\n name: \"Arcade\",\n mode: \"dark\",\n },\n color: {\n neutral: {\n 50: \"#f5f7fb\",\n 100: \"#d6dde9\",\n 200: \"#a8b2c4\",\n 400: \"#5b6478\",\n 600: \"#2c3344\",\n 800: \"#161b27\",\n 950: \"#070912\",\n },\n brand: {\n 50: \"#e0fbff\",\n 100: \"#aef1fb\",\n 200: \"#62e0f0\",\n 400: \"#1bc4dc\",\n 600: \"#0d8ea1\",\n 800: \"#06525e\",\n 950: \"#03252b\",\n },\n accent: {\n 50: \"#ffe6f6\",\n 100: \"#ffb1de\",\n 200: \"#ff6cbf\",\n 400: \"#ff2891\",\n 600: \"#c80862\",\n 800: \"#73003a\",\n 950: \"#37001b\",\n },\n success: {\n 50: \"#dafdf2\",\n 100: \"#9af2cf\",\n 200: \"#52e1a3\",\n 400: \"#0fc171\",\n 600: \"#067a45\",\n 800: \"#024226\",\n 950: \"#001f10\",\n },\n warning: {\n 50: \"#fff4d8\",\n 100: \"#ffe198\",\n 200: \"#fbc739\",\n 400: \"#dba500\",\n 600: \"#9b7400\",\n 800: \"#5a4200\",\n 950: \"#291e00\",\n },\n danger: {\n 50: \"#ffdcdc\",\n 100: \"#ff9c9c\",\n 200: \"#ff5454\",\n 400: \"#e41e1e\",\n 600: \"#960a0a\",\n 800: \"#5a0202\",\n 950: \"#290000\",\n },\n info: {\n 50: \"#dceefe\",\n 100: \"#9ecdfb\",\n 200: \"#4f9ff5\",\n 400: \"#1d6fde\",\n 600: \"#0a4598\",\n 800: \"#03234f\",\n 950: \"#011024\",\n },\n },\n semantic: {\n surface: {\n app: \"#070912\",\n board: \"#0a0e1d\",\n hud: \"#161b27\",\n card: \"#1f2636\",\n sheet: \"#161b27\",\n overlay: \"rgba(7, 9, 18, 0.78)\",\n inset: \"#0a0e1d\",\n },\n text: {\n primary: \"#f5f7fb\",\n muted: \"#a8b2c4\",\n onIntent: \"#070912\",\n accent: \"#62e0f0\",\n disabled: \"#5b6478\",\n },\n border: {\n subtle: \"#2c3344\",\n default: \"#5b6478\",\n strong: \"#a8b2c4\",\n focus: \"#1bc4dc\",\n },\n intent: {\n primary: {\n solid: \"#1bc4dc\",\n on: \"#070912\",\n soft: \"rgba(27, 196, 220, 0.18)\",\n onSoft: \"#aef1fb\",\n border: \"#62e0f0\",\n },\n secondary: {\n solid: \"#1f2636\",\n on: \"#f5f7fb\",\n soft: \"#161b27\",\n onSoft: \"#a8b2c4\",\n border: \"#5b6478\",\n },\n success: {\n solid: \"#0fc171\",\n on: \"#070912\",\n soft: \"rgba(15, 193, 113, 0.18)\",\n onSoft: \"#9af2cf\",\n border: \"#52e1a3\",\n },\n danger: {\n solid: \"#e41e1e\",\n on: \"#ffffff\",\n soft: \"rgba(228, 30, 30, 0.18)\",\n onSoft: \"#ff9c9c\",\n border: \"#ff5454\",\n },\n warning: {\n solid: \"#fbc739\",\n on: \"#070912\",\n soft: \"rgba(251, 199, 57, 0.18)\",\n onSoft: \"#ffe198\",\n border: \"#dba500\",\n },\n info: {\n solid: \"#4f9ff5\",\n on: \"#070912\",\n soft: \"rgba(79, 159, 245, 0.18)\",\n onSoft: \"#9ecdfb\",\n border: \"#1d6fde\",\n },\n },\n },\n radius: {\n none: \"0px\",\n sm: \"2px\",\n md: \"4px\",\n lg: \"6px\",\n hud: \"10px\",\n pill: \"9999px\",\n },\n space: {\n 0: \"0\",\n 0.5: \"0.125rem\",\n 1: \"0.25rem\",\n 1.5: \"0.375rem\",\n 2: \"0.5rem\",\n 3: \"0.75rem\",\n 4: \"1rem\",\n 6: \"1.5rem\",\n 8: \"2rem\",\n 12: \"3rem\",\n },\n typography: {\n fontFamily: {\n display: '\"Space Grotesk\", \"Inter\", system-ui, -apple-system, sans-serif',\n body: '\"Inter\", \"SF Pro Text\", system-ui, -apple-system, sans-serif',\n tabular: '\"JetBrains Mono\", \"SF Mono\", ui-monospace, monospace',\n mono: '\"JetBrains Mono\", \"SF Mono\", ui-monospace, monospace',\n },\n fontSize: {\n xs: \"0.6875rem\",\n sm: \"0.8125rem\",\n md: \"0.9375rem\",\n lg: \"1.0625rem\",\n xl: \"1.25rem\",\n \"2xl\": \"1.5rem\",\n \"3xl\": \"2rem\",\n },\n fontWeight: {\n regular: \"400\",\n medium: \"500\",\n bold: \"700\",\n },\n lineHeight: {\n tight: \"1.1\",\n normal: \"1.35\",\n relaxed: \"1.55\",\n },\n letterSpacing: {\n tight: \"-0.01em\",\n normal: \"0\",\n wide: \"0.06em\",\n caps: \"0.18em\",\n },\n },\n elevation: {\n rest: \"0 1px 0 rgba(0, 0, 0, 0.4), 0 2px 0 rgba(27, 196, 220, 0.15)\",\n hover:\n \"0 0 0 1px rgba(27, 196, 220, 0.4), 0 6px 16px rgba(27, 196, 220, 0.35)\",\n lifted:\n \"0 0 0 2px rgba(27, 196, 220, 0.6), 0 14px 28px rgba(27, 196, 220, 0.45)\",\n overlay: \"0 20px 60px rgba(0, 0, 0, 0.7)\",\n inset: \"inset 0 0 0 1px rgba(27, 196, 220, 0.18)\",\n },\n motion: {\n duration: {\n fast: \"60ms\",\n normal: \"120ms\",\n slow: \"220ms\",\n ambient: \"1400ms\",\n },\n easing: {\n out: \"cubic-bezier(0.22, 1, 0.36, 1)\",\n in: \"cubic-bezier(0.36, 0, 1, 0.36)\",\n inOut: \"cubic-bezier(0.7, 0, 0.3, 1)\",\n spring: \"cubic-bezier(0.32, 1.6, 0.6, 1)\",\n },\n reducedMotion: \"false\",\n },\n player: [\n { solid: \"#1bc4dc\", soft: \"rgba(27, 196, 220, 0.2)\", on: \"#070912\" },\n { solid: \"#ff2891\", soft: \"rgba(255, 40, 145, 0.2)\", on: \"#ffffff\" },\n { solid: \"#0fc171\", soft: \"rgba(15, 193, 113, 0.2)\", on: \"#070912\" },\n { solid: \"#fbc739\", soft: \"rgba(251, 199, 57, 0.2)\", on: \"#070912\" },\n { solid: \"#9b59ff\", soft: \"rgba(155, 89, 255, 0.2)\", on: \"#ffffff\" },\n { solid: \"#ff7b3a\", soft: \"rgba(255, 123, 58, 0.2)\", on: \"#070912\" },\n ],\n component: {\n board: {\n frameBorder: \"#1bc4dc\",\n frameBackground: \"#0a0e1d\",\n hoverRing: \"#ff2891\",\n eligibleHint: \"rgba(27, 196, 220, 0.55)\",\n },\n card: {\n border: \"#1bc4dc\",\n backBorder: \"#ff2891\",\n backBackground: \"#161b27\",\n selectedRing: \"#ff2891\",\n },\n playerCard: {\n activeBackground: \"rgba(27, 196, 220, 0.18)\",\n activeBorder: \"#1bc4dc\",\n activeGlow: \"rgba(27, 196, 220, 0.5)\",\n youBadgeBackground: \"rgba(27, 196, 220, 0.22)\",\n youBadgeForeground: \"#aef1fb\",\n },\n toast: {\n successBackground: \"#0fc171\",\n errorBackground: \"#e41e1e\",\n infoBackground: \"#1bc4dc\",\n foreground: \"#070912\",\n },\n },\n};\n","import type { Theme } from \"../tokens.js\";\n\n/**\n * `studio` — clean monochrome theme for prototypes and design reviews.\n *\n * Visual identity: pure white surfaces, near-black text, single brand\n * accent, generous whitespace. Designed for screenshot-friendly demos\n * and games where the board art does the storytelling.\n */\nexport const studioTheme: Theme = {\n meta: {\n id: \"studio\",\n name: \"Studio\",\n mode: \"light\",\n },\n color: {\n neutral: {\n 50: \"#ffffff\",\n 100: \"#f5f5f5\",\n 200: \"#e5e5e5\",\n 400: \"#a3a3a3\",\n 600: \"#525252\",\n 800: \"#262626\",\n 950: \"#0a0a0a\",\n },\n brand: {\n 50: \"#eef2ff\",\n 100: \"#e0e7ff\",\n 200: \"#c7d2fe\",\n 400: \"#818cf8\",\n 600: \"#4f46e5\",\n 800: \"#3730a3\",\n 950: \"#1e1b4b\",\n },\n accent: {\n 50: \"#fdf4ff\",\n 100: \"#fae8ff\",\n 200: \"#f5d0fe\",\n 400: \"#e879f9\",\n 600: \"#a21caf\",\n 800: \"#701a75\",\n 950: \"#4a044e\",\n },\n success: {\n 50: \"#ecfdf5\",\n 100: \"#d1fae5\",\n 200: \"#a7f3d0\",\n 400: \"#34d399\",\n 600: \"#059669\",\n 800: \"#065f46\",\n 950: \"#022c22\",\n },\n warning: {\n 50: \"#fffbeb\",\n 100: \"#fef3c7\",\n 200: \"#fde68a\",\n 400: \"#facc15\",\n 600: \"#ca8a04\",\n 800: \"#854d0e\",\n 950: \"#422006\",\n },\n danger: {\n 50: \"#fef2f2\",\n 100: \"#fee2e2\",\n 200: \"#fecaca\",\n 400: \"#f87171\",\n 600: \"#dc2626\",\n 800: \"#991b1b\",\n 950: \"#450a0a\",\n },\n info: {\n 50: \"#eff6ff\",\n 100: \"#dbeafe\",\n 200: \"#bfdbfe\",\n 400: \"#60a5fa\",\n 600: \"#2563eb\",\n 800: \"#1e40af\",\n 950: \"#172554\",\n },\n },\n semantic: {\n surface: {\n app: \"#fafafa\",\n board: \"#ffffff\",\n hud: \"#ffffff\",\n card: \"#ffffff\",\n sheet: \"#ffffff\",\n overlay: \"rgba(10, 10, 10, 0.4)\",\n inset: \"#f5f5f5\",\n },\n text: {\n primary: \"#0a0a0a\",\n muted: \"#525252\",\n onIntent: \"#ffffff\",\n accent: \"#4f46e5\",\n disabled: \"#a3a3a3\",\n },\n border: {\n subtle: \"#f5f5f5\",\n default: \"#e5e5e5\",\n strong: \"#a3a3a3\",\n focus: \"#4f46e5\",\n },\n intent: {\n primary: {\n solid: \"#0a0a0a\",\n on: \"#ffffff\",\n soft: \"#f5f5f5\",\n onSoft: \"#0a0a0a\",\n border: \"#0a0a0a\",\n },\n secondary: {\n solid: \"#ffffff\",\n on: \"#0a0a0a\",\n soft: \"#f5f5f5\",\n onSoft: \"#0a0a0a\",\n border: \"#e5e5e5\",\n },\n success: {\n solid: \"#059669\",\n on: \"#ffffff\",\n soft: \"#d1fae5\",\n onSoft: \"#065f46\",\n border: \"#34d399\",\n },\n danger: {\n solid: \"#dc2626\",\n on: \"#ffffff\",\n soft: \"#fee2e2\",\n onSoft: \"#991b1b\",\n border: \"#f87171\",\n },\n warning: {\n solid: \"#ca8a04\",\n on: \"#ffffff\",\n soft: \"#fef3c7\",\n onSoft: \"#854d0e\",\n border: \"#facc15\",\n },\n info: {\n solid: \"#2563eb\",\n on: \"#ffffff\",\n soft: \"#dbeafe\",\n onSoft: \"#1e40af\",\n border: \"#60a5fa\",\n },\n },\n },\n radius: {\n none: \"0px\",\n sm: \"4px\",\n md: \"8px\",\n lg: \"12px\",\n hud: \"16px\",\n pill: \"9999px\",\n },\n space: {\n 0: \"0\",\n 0.5: \"0.125rem\",\n 1: \"0.25rem\",\n 1.5: \"0.375rem\",\n 2: \"0.5rem\",\n 3: \"0.75rem\",\n 4: \"1rem\",\n 6: \"1.5rem\",\n 8: \"2rem\",\n 12: \"3rem\",\n },\n typography: {\n fontFamily: {\n display:\n '\"Inter\", \"SF Pro Display\", system-ui, -apple-system, sans-serif',\n body: '\"Inter\", \"SF Pro Text\", system-ui, -apple-system, sans-serif',\n tabular: '\"Inter\", \"SF Pro Text\", system-ui, sans-serif',\n mono: '\"JetBrains Mono\", \"SF Mono\", ui-monospace, monospace',\n },\n fontSize: {\n xs: \"0.75rem\",\n sm: \"0.875rem\",\n md: \"1rem\",\n lg: \"1.125rem\",\n xl: \"1.25rem\",\n \"2xl\": \"1.5rem\",\n \"3xl\": \"2rem\",\n },\n fontWeight: {\n regular: \"400\",\n medium: \"500\",\n bold: \"600\",\n },\n lineHeight: {\n tight: \"1.2\",\n normal: \"1.5\",\n relaxed: \"1.65\",\n },\n letterSpacing: {\n tight: \"-0.015em\",\n normal: \"0\",\n wide: \"0.02em\",\n caps: \"0.08em\",\n },\n },\n elevation: {\n rest: \"0 1px 2px rgba(10, 10, 10, 0.05)\",\n hover: \"0 4px 8px rgba(10, 10, 10, 0.06), 0 1px 2px rgba(10, 10, 10, 0.04)\",\n lifted:\n \"0 12px 24px rgba(10, 10, 10, 0.08), 0 2px 4px rgba(10, 10, 10, 0.06)\",\n overlay: \"0 24px 48px rgba(10, 10, 10, 0.18)\",\n inset: \"inset 0 1px 0 rgba(10, 10, 10, 0.04)\",\n },\n motion: {\n duration: {\n fast: \"100ms\",\n normal: \"180ms\",\n slow: \"300ms\",\n ambient: \"2400ms\",\n },\n easing: {\n out: \"cubic-bezier(0.16, 1, 0.3, 1)\",\n in: \"cubic-bezier(0.4, 0, 1, 0.4)\",\n inOut: \"cubic-bezier(0.65, 0, 0.35, 1)\",\n spring: \"cubic-bezier(0.34, 1.56, 0.64, 1)\",\n },\n reducedMotion: \"false\",\n },\n player: [\n { solid: \"#4f46e5\", soft: \"#e0e7ff\", on: \"#ffffff\" },\n { solid: \"#dc2626\", soft: \"#fee2e2\", on: \"#ffffff\" },\n { solid: \"#059669\", soft: \"#d1fae5\", on: \"#ffffff\" },\n { solid: \"#ca8a04\", soft: \"#fef3c7\", on: \"#ffffff\" },\n { solid: \"#a21caf\", soft: \"#fae8ff\", on: \"#ffffff\" },\n { solid: \"#0891b2\", soft: \"#cffafe\", on: \"#ffffff\" },\n ],\n component: {\n board: {\n frameBorder: \"#e5e5e5\",\n frameBackground: \"#ffffff\",\n hoverRing: \"#4f46e5\",\n eligibleHint: \"rgba(79, 70, 229, 0.4)\",\n },\n card: {\n border: \"#e5e5e5\",\n backBorder: \"#0a0a0a\",\n backBackground: \"#0a0a0a\",\n selectedRing: \"#4f46e5\",\n },\n playerCard: {\n activeBackground: \"#f5f5f5\",\n activeBorder: \"#0a0a0a\",\n activeGlow: \"rgba(10, 10, 10, 0.06)\",\n youBadgeBackground: \"#0a0a0a\",\n youBadgeForeground: \"#ffffff\",\n },\n toast: {\n successBackground: \"#059669\",\n errorBackground: \"#dc2626\",\n infoBackground: \"#2563eb\",\n foreground: \"#ffffff\",\n },\n },\n};\n","import type { CSSProperties } from \"react\";\nimport type { Theme } from \"./tokens.js\";\n\n/**\n * CSS variable bridge for {@link Theme}.\n *\n * The {@link ThemeProvider} mounts a wrapper element and applies the\n * map returned by {@link themeToCssVars} as inline `style`, which\n * declares one CSS custom property per leaf token. Components inside\n * the provider can:\n *\n * 1. Read tokens via `useTheme()` (typed) and use them inline, or\n * 2. Read the CSS variable directly in Tailwind / className styling\n * via the helpers in {@link var()} below.\n *\n * The variable naming scheme is `--db-<dot.path>` with `.` and any\n * non-identifier characters replaced by `-`. Example:\n *\n * - `theme.semantic.intent.primary.solid` → `--db-semantic-intent-primary-solid`\n * - `theme.player[0].solid` → `--db-player-1-solid`\n * - `theme.color.brand.600` → `--db-color-brand-600`\n *\n * The 1-based player suffix (rather than 0-based) keeps the variable\n * name aligned with how seats are labelled in product UI (\"Player 1\").\n */\n\nconst PREFIX = \"--db\";\n\n/** Convert a token-tree path to a kebab-case CSS variable name. */\nfunction toVarName(parts: ReadonlyArray<string | number>): string {\n const tail = parts\n .map((part) => String(part))\n .join(\"-\")\n .replace(/[^a-zA-Z0-9-]/g, \"-\")\n .replace(/-+/g, \"-\");\n return `${PREFIX}-${tail}`;\n}\n\n/**\n * Walk the theme tree and produce a flat `{ \"--db-...\": value }` map.\n * Arrays are walked positionally with a 1-based index (so\n * `theme.player[0]` → `--db-player-1-...`).\n */\nexport function themeToCssVars(theme: Theme): CSSProperties {\n const out: Record<string, string> = {};\n walk(theme as unknown as Record<string, unknown>, [], out);\n return out as CSSProperties;\n}\n\nfunction walk(\n node: unknown,\n path: ReadonlyArray<string | number>,\n out: Record<string, string>,\n): void {\n if (node === null || node === undefined) return;\n if (typeof node === \"string\" || typeof node === \"number\") {\n out[toVarName(path)] = String(node);\n return;\n }\n if (Array.isArray(node)) {\n node.forEach((child, idx) => {\n // 1-based index for player slots, etc.\n walk(child, [...path, idx + 1], out);\n });\n return;\n }\n if (typeof node === \"object\") {\n for (const [key, value] of Object.entries(\n node as Record<string, unknown>,\n )) {\n walk(value, [...path, key], out);\n }\n }\n}\n\n/**\n * Build a `var(--db-...)` reference for a token path.\n *\n * @example\n * ```ts\n * cssVar(\"semantic\", \"intent\", \"primary\", \"solid\")\n * // => \"var(--db-semantic-intent-primary-solid)\"\n * cssVar(\"player\", 1, \"solid\")\n * // => \"var(--db-player-1-solid)\"\n * ```\n */\nexport function cssVar(...path: Array<string | number>): string {\n return `var(${toVarName(path)})`;\n}\n\n/**\n * Convenience for declaring a `var(--db-...)` with an inline fallback.\n *\n * @example\n * ```ts\n * cssVarOr(\"transparent\", \"semantic\", \"border\", \"default\")\n * // => \"var(--db-semantic-border-default, transparent)\"\n * ```\n */\nexport function cssVarOr(\n fallback: string,\n ...path: Array<string | number>\n): string {\n return `var(${toVarName(path)}, ${fallback})`;\n}\n","import {\n createContext,\n useContext,\n useEffect,\n useMemo,\n useState,\n type CSSProperties,\n type ReactNode,\n} from \"react\";\nimport { themeToCssVars } from \"./css-vars.js\";\nimport { arcadeTheme } from \"./presets/arcade.js\";\nimport { studioTheme } from \"./presets/studio.js\";\nimport { tabletopTheme } from \"./presets/tabletop.js\";\nimport { mergeTheme, type Theme, type ThemeOverride } from \"./tokens.js\";\n\n/**\n * The set of preset theme ids ships in `@dreamboard-games/sdk/ui`. Authors\n * may register additional ones by passing a fully-resolved {@link Theme}\n * instead of an id.\n */\nexport type ThemePresetId = \"tabletop\" | \"arcade\" | \"studio\";\n\nconst PRESETS: Readonly<Record<ThemePresetId, Theme>> = {\n tabletop: tabletopTheme,\n arcade: arcadeTheme,\n studio: studioTheme,\n};\n\n/**\n * Resolve a preset id (or a full theme) into a {@link Theme}.\n *\n * Used internally by {@link ThemeProvider}; exported so authors who\n * compose at the call site (e.g. for a side-by-side preview) can do\n * the same resolution without mounting a provider.\n */\nexport function resolveTheme(input: ThemePresetId | Theme | undefined): Theme {\n if (!input) return tabletopTheme;\n if (typeof input === \"string\") {\n const preset = PRESETS[input];\n if (!preset) {\n throw new Error(\n `[ui-sdk] Unknown theme preset \"${input}\". Pass a full Theme object or one of: ${Object.keys(\n PRESETS,\n ).join(\", \")}.`,\n );\n }\n return preset;\n }\n return input;\n}\n\n/** Look up a registered preset by id. Returns `undefined` if missing. */\nexport function getThemePreset(id: ThemePresetId): Theme | undefined {\n return PRESETS[id];\n}\n\n/**\n * Subset returned by {@link useTheme} — the resolved theme plus a\n * stable copy of its CSS-variable map so consumers can reuse it (for\n * example, to apply tokens to a portal that escapes the provider).\n */\nexport interface ThemeContextValue {\n /** Fully resolved theme. */\n readonly theme: Theme;\n /** CSS-var map consumable as `style` on a wrapper. */\n readonly cssVars: CSSProperties;\n}\n\nconst ThemeCtx = createContext<ThemeContextValue | null>(null);\n\nexport interface ThemeProviderProps {\n /**\n * Preset id, a full {@link Theme}, or omitted to use the `tabletop`\n * default.\n */\n theme?: ThemePresetId | Theme;\n /**\n * Deep-partial overrides merged onto the resolved base theme. Use\n * for one-off tweaks (e.g. swapping the player palette per game)\n * without writing a full theme.\n */\n override?: ThemeOverride;\n /**\n * Render mode for reduced-motion enforcement.\n *\n * - `auto` (default): respect the user's OS-level preference via\n * `prefers-reduced-motion: reduce`.\n * - `force`: force `motion.reducedMotion = \"true\"` regardless of the\n * OS preference (useful for screenshot CI).\n * - `ignore`: never override motion (use only when the embedding\n * shell already decides motion behaviour).\n */\n reducedMotion?: \"auto\" | \"force\" | \"ignore\";\n /**\n * Where to mount the wrapper. `block` (default) renders a `div` and\n * applies the CSS variables to it. `none` skips the wrapper entirely\n * — only useful when the parent is already a Dreamboard provider and\n * just needs to publish a different sub-tree (rare).\n */\n as?: \"block\" | \"none\";\n /** Extra style merged after the CSS-var map. */\n style?: CSSProperties;\n /** Extra className for the wrapper. */\n className?: string;\n children: ReactNode;\n}\n\nfunction usePrefersReducedMotion(): boolean {\n const [prefers, setPrefers] = useState(false);\n useEffect(() => {\n if (typeof window === \"undefined\" || !window.matchMedia) return;\n const media = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n setPrefers(media.matches);\n const handle = (event: MediaQueryListEvent) => setPrefers(event.matches);\n media.addEventListener(\"change\", handle);\n return () => media.removeEventListener(\"change\", handle);\n }, []);\n return prefers;\n}\n\n/**\n * Mounts a Dreamboard theme. The provider:\n *\n * 1. Resolves the preset (or accepts a full theme).\n * 2. Applies any deep-partial `override`.\n * 3. Optionally clamps `motion.reducedMotion` to `\"true\"` based on the\n * OS-level preference (or a forced override).\n * 4. Serialises the resolved theme into CSS variables on a wrapper\n * element so descendants can read tokens via `useTheme()` *or* via\n * `var(--db-...)` references in their own CSS / Tailwind.\n *\n * Defaults such as `<GameLayout>` mount this for you with the configured\n * theme; mount it manually only when you need a sub-tree to use a different\n * theme (e.g. a dark sheet over a light layout).\n */\nexport function ThemeProvider({\n theme: themeInput,\n override,\n reducedMotion = \"auto\",\n as = \"block\",\n style,\n className,\n children,\n}: ThemeProviderProps) {\n const prefersReduced = usePrefersReducedMotion();\n\n const value = useMemo<ThemeContextValue>(() => {\n const base = resolveTheme(themeInput);\n const merged = mergeTheme(base, override);\n const motionResolved =\n reducedMotion === \"force\"\n ? \"true\"\n : reducedMotion === \"ignore\"\n ? merged.motion.reducedMotion\n : prefersReduced\n ? \"true\"\n : merged.motion.reducedMotion;\n const final: Theme =\n motionResolved === merged.motion.reducedMotion\n ? merged\n : {\n ...merged,\n motion: { ...merged.motion, reducedMotion: motionResolved },\n };\n return { theme: final, cssVars: themeToCssVars(final) };\n }, [themeInput, override, reducedMotion, prefersReduced]);\n\n if (as === \"none\") {\n return <ThemeCtx.Provider value={value}>{children}</ThemeCtx.Provider>;\n }\n\n const wrapperStyle: CSSProperties = {\n ...themeToShadcnVars(value.theme),\n ...value.cssVars,\n fontFamily: value.theme.typography.fontFamily.body,\n ...style,\n };\n\n return (\n <ThemeCtx.Provider value={value}>\n <div\n data-dreamboard-theme={value.theme.meta.id}\n data-dreamboard-mode={value.theme.meta.mode}\n data-dreamboard-reduced-motion={value.theme.motion.reducedMotion}\n className={className}\n style={wrapperStyle}\n >\n {children}\n </div>\n </ThemeCtx.Provider>\n );\n}\n\n/**\n * Read the active {@link Theme} from a {@link ThemeProvider} ancestor.\n *\n * Falls back to the `tabletop` preset (with no overrides) when called\n * outside a provider — components remain renderable in isolated tests\n * and Storybook/Cosmos fixtures without a wrapping shell.\n */\nexport function useTheme(): Theme {\n const ctx = useContext(ThemeCtx);\n return ctx?.theme ?? tabletopTheme;\n}\n\n/**\n * Read the {@link CSSProperties} that publish the active theme as CSS\n * variables. Useful when porting a theme into a portal or drawer that\n * is rendered outside the provider's DOM subtree.\n */\nexport function useThemeCssVars(): CSSProperties {\n const ctx = useContext(ThemeCtx);\n if (ctx) return { ...themeToShadcnVars(ctx.theme), ...ctx.cssVars };\n // Match the fallback theme exposed by `useTheme()`.\n return {\n ...themeToShadcnVars(tabletopTheme),\n ...themeToCssVars(tabletopTheme),\n };\n}\n\nexport { ThemeCtx };\n\ntype CssVariableStyle = CSSProperties & {\n [K in `--${string}`]?: string | number;\n};\n\nfunction themeToShadcnVars(theme: Theme): CSSProperties {\n const vars: CssVariableStyle = {\n \"--background\": theme.semantic.surface.app,\n \"--foreground\": theme.semantic.text.primary,\n \"--card\": theme.semantic.surface.card,\n \"--card-foreground\": theme.semantic.text.primary,\n \"--popover\": theme.semantic.surface.sheet,\n \"--popover-foreground\": theme.semantic.text.primary,\n \"--primary\": theme.semantic.intent.primary.solid,\n \"--primary-foreground\": theme.semantic.intent.primary.on,\n \"--secondary\": theme.semantic.intent.secondary.solid,\n \"--secondary-foreground\": theme.semantic.intent.secondary.on,\n \"--muted\": theme.semantic.surface.inset,\n \"--muted-foreground\": theme.semantic.text.muted,\n \"--accent\": theme.semantic.intent.info.soft,\n \"--accent-foreground\": theme.semantic.intent.info.onSoft,\n \"--destructive\": theme.semantic.intent.danger.solid,\n \"--destructive-foreground\": theme.semantic.intent.danger.on,\n \"--border\": theme.semantic.border.default,\n \"--input\": theme.semantic.border.default,\n \"--ring\": theme.semantic.border.focus,\n \"--font-sans\": theme.typography.fontFamily.body,\n \"--font-display\": theme.typography.fontFamily.display,\n };\n return vars;\n}\n","import type { CSSProperties } from \"react\";\nimport type { IntentColor, Theme } from \"./tokens.js\";\n\n/**\n * Helpers that derive component-specific style fragments from a\n * resolved {@link Theme}. They live alongside the theme module (rather\n * than in each component) so that:\n *\n * - There is one canonical mapping of \"intent → button style\", \"intent →\n * chip style\", etc.\n * - Component visuals stay aligned automatically when an author tweaks\n * the theme; nobody has to remember to update a bespoke calc inside\n * `<CardFace>` or `<ThemedButton>`.\n *\n * Each helper returns a plain {@link CSSProperties} fragment so the\n * caller can spread it into an inline style (or pass it through to\n * Framer Motion's `style` prop).\n */\n\n/** Button visual variants derived from semantic intent slots. */\nexport type ButtonVariant =\n | \"primary\"\n | \"secondary\"\n | \"danger\"\n | \"submitted\"\n | \"success\"\n | \"warning\"\n | \"info\"\n | \"ghost\";\n\nexport type ButtonSize = \"sm\" | \"md\" | \"lg\";\n\n/**\n * Compute the inline style for a button in `variant`/`size` from the\n * theme. `disabled` and `pressed` are visual-only — they affect colour\n * intensity and elevation but never touch interactivity (the consuming\n * component owns `aria-disabled` and event wiring).\n */\nexport function buttonStyle(\n theme: Theme,\n options: {\n variant?: ButtonVariant;\n size?: ButtonSize;\n disabled?: boolean;\n pressed?: boolean;\n } = {},\n): CSSProperties {\n const { variant = \"primary\", size = \"md\", disabled, pressed } = options;\n const intent = intentForVariant(theme, variant);\n const sizing = BUTTON_SIZE[size];\n const visuallyDisabled = disabled && variant !== \"submitted\";\n\n const baseShadow =\n variant === \"ghost\"\n ? \"none\"\n : pressed\n ? theme.elevation.rest\n : theme.elevation.hover;\n\n return {\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: theme.space[2],\n minHeight: sizing.minHeight,\n paddingBlock: sizing.paddingBlock,\n paddingInline: sizing.paddingInline,\n borderRadius: theme.radius.md,\n border:\n variant === \"ghost\"\n ? \"1px solid transparent\"\n : `1px solid ${visuallyDisabled ? theme.semantic.border.subtle : intent.border}`,\n background:\n variant === \"ghost\"\n ? \"transparent\"\n : visuallyDisabled\n ? theme.semantic.surface.inset\n : intent.solid,\n color: visuallyDisabled\n ? theme.semantic.text.disabled\n : variant === \"ghost\"\n ? theme.semantic.text.primary\n : intent.on,\n fontFamily: theme.typography.fontFamily.body,\n fontSize: sizing.fontSize,\n fontWeight: theme.typography.fontWeight.bold,\n lineHeight: theme.typography.lineHeight.tight,\n letterSpacing: theme.typography.letterSpacing.normal,\n cursor: disabled ? \"not-allowed\" : \"pointer\",\n boxShadow: disabled ? \"none\" : baseShadow,\n transition: `background-color ${theme.motion.duration.fast} ${theme.motion.easing.out}, transform ${theme.motion.duration.fast} ${theme.motion.easing.out}, box-shadow ${theme.motion.duration.normal} ${theme.motion.easing.out}`,\n userSelect: \"none\",\n WebkitTapHighlightColor: \"transparent\",\n };\n}\n\nconst BUTTON_SIZE: Record<\n ButtonSize,\n {\n minHeight: number;\n paddingBlock: string;\n paddingInline: string;\n fontSize: string;\n }\n> = {\n sm: {\n minHeight: 32,\n paddingBlock: \"0.25rem\",\n paddingInline: \"0.625rem\",\n fontSize: \"0.8125rem\",\n },\n md: {\n minHeight: 40,\n paddingBlock: \"0.5rem\",\n paddingInline: \"0.875rem\",\n fontSize: \"0.9375rem\",\n },\n lg: {\n minHeight: 52,\n paddingBlock: \"0.75rem\",\n paddingInline: \"1.125rem\",\n fontSize: \"1.0625rem\",\n },\n};\n\n/**\n * Soft-intent chip (\"Your turn\", \"Largest army\", \"Waiting…\"). Reads\n * `intent.<variant>.soft` for background and `.onSoft` for text.\n */\nexport function chipStyle(\n theme: Theme,\n options: {\n variant?: Exclude<ButtonVariant, \"ghost\">;\n size?: \"sm\" | \"md\";\n } = {},\n): CSSProperties {\n const { variant = \"secondary\", size = \"sm\" } = options;\n const intent = intentForVariant(theme, variant);\n return {\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: theme.space[1],\n paddingBlock: size === \"md\" ? \"0.25rem\" : \"0.125rem\",\n paddingInline: size === \"md\" ? \"0.625rem\" : \"0.5rem\",\n borderRadius: theme.radius.pill,\n border: `1px solid ${intent.border}`,\n background: intent.soft,\n color: intent.onSoft,\n fontFamily: theme.typography.fontFamily.body,\n fontSize:\n size === \"md\"\n ? theme.typography.fontSize.sm\n : theme.typography.fontSize.xs,\n fontWeight: theme.typography.fontWeight.bold,\n letterSpacing: theme.typography.letterSpacing.wide,\n textTransform: \"uppercase\",\n whiteSpace: \"nowrap\",\n };\n}\n\n/**\n * Standard surface card (player card, action panel, hand drawer). The\n * `tone` selects which `surface.*` slot to read; `interactive` adds\n * the hover-elevation transition baseline.\n */\nexport function surfaceStyle(\n theme: Theme,\n options: {\n tone?: keyof Theme[\"semantic\"][\"surface\"];\n interactive?: boolean;\n /** Override radius to one of the theme tokens. Defaults to `lg`. */\n radius?: keyof Theme[\"radius\"];\n } = {},\n): CSSProperties {\n const { tone = \"card\", interactive, radius = \"lg\" } = options;\n return {\n background: theme.semantic.surface[tone],\n color: theme.semantic.text.primary,\n border: `1px solid ${theme.semantic.border.subtle}`,\n borderRadius: theme.radius[radius],\n boxShadow: theme.elevation.rest,\n transition: interactive\n ? `box-shadow ${theme.motion.duration.normal} ${theme.motion.easing.out}, transform ${theme.motion.duration.normal} ${theme.motion.easing.out}`\n : undefined,\n };\n}\n\n/** Resolve a {@link ButtonVariant} to its underlying {@link IntentColor}. */\nexport function intentForVariant(\n theme: Theme,\n variant: ButtonVariant,\n): IntentColor {\n switch (variant) {\n case \"primary\":\n return theme.semantic.intent.primary;\n case \"secondary\":\n return theme.semantic.intent.secondary;\n case \"danger\":\n return theme.semantic.intent.danger;\n case \"submitted\":\n return theme.semantic.intent.success;\n case \"success\":\n return theme.semantic.intent.success;\n case \"warning\":\n return theme.semantic.intent.warning;\n case \"info\":\n return theme.semantic.intent.info;\n case \"ghost\":\n return theme.semantic.intent.secondary;\n }\n}\n\n/**\n * Pick a {@link Theme.player} entry by 0-based seat slot, wrapping\n * around when there are more players than palette entries (so a\n * 7-player game cycles back to player 1's palette).\n */\nexport function playerColor(theme: Theme, slot: number) {\n const length = theme.player.length;\n const idx = ((slot % length) + length) % length;\n // The {@link Theme.player} contract pins length === 6 at the type\n // level, but indexing by a runtime-computed value widens the result\n // to `PlayerColor | undefined`. Falling back to slot 0 (also typed\n // `PlayerColor`) keeps the return type narrow without a non-null\n // assertion.\n return theme.player[idx] ?? theme.player[0];\n}\n\n/**\n * Returns `theme.motion.duration.<key>` zeroed out when the theme has\n * `motion.reducedMotion === \"true\"`. Use this in any component that\n * starts an animation so `prefers-reduced-motion` is honoured uniformly.\n */\nexport function motionDuration(\n theme: Theme,\n key: keyof Theme[\"motion\"][\"duration\"],\n): string {\n if (theme.motion.reducedMotion === \"true\") return \"0ms\";\n return theme.motion.duration[key];\n}\n","import type {\n BoardId,\n EdgeTypeId,\n PlayerId,\n SpaceTypeId,\n VertexTypeId,\n} from \"./player-state.js\";\nimport type {\n HexBoardState,\n HexEdgeState,\n HexTileState,\n HexVertexState,\n SquareBoardState,\n SquareCellState,\n SquareEdgeState,\n SquarePieceState,\n SquareVertexState,\n} from \"./player-state.js\";\n\ntype RuntimeFields = Record<string, unknown>;\n\ntype NormalizeOptional<T> = Exclude<T, null | undefined> | undefined;\n\nexport interface GeneratedTiledEdgeStateLike<\n SpaceIdValue extends string = string,\n EdgeIdValue extends string = string,\n Fields = RuntimeFields,\n> {\n id: EdgeIdValue;\n spaceIds: readonly SpaceIdValue[];\n typeId?: EdgeTypeId | null;\n label?: string | null;\n ownerId?: PlayerId | null;\n fields?: Fields;\n}\n\nexport interface GeneratedTiledVertexStateLike<\n SpaceIdValue extends string = string,\n VertexIdValue extends string = string,\n Fields = RuntimeFields,\n> {\n id: VertexIdValue;\n spaceIds: readonly SpaceIdValue[];\n typeId?: VertexTypeId | null;\n label?: string | null;\n ownerId?: PlayerId | null;\n fields?: Fields;\n}\n\nexport interface GeneratedHexSpaceStateLike<\n SpaceIdValue extends string = string,\n Fields = RuntimeFields,\n> {\n id: SpaceIdValue;\n q: number;\n r: number;\n typeId?: SpaceTypeId | null;\n label?: string | null;\n ownerId?: PlayerId | null;\n fields?: Fields;\n}\n\nexport interface GeneratedSquareSpaceStateLike<\n SpaceIdValue extends string = string,\n Fields = RuntimeFields,\n> {\n id: SpaceIdValue;\n row: number;\n col: number;\n typeId?: SpaceTypeId | null;\n label?: string | null;\n ownerId?: PlayerId | null;\n fields?: Fields;\n}\n\nexport interface GeneratedHexBoardInput<\n BoardIdValue extends string = BoardId,\n SpaceIdValue extends string = string,\n EdgeIdValue extends string = string,\n VertexIdValue extends string = string,\n SpaceFields = RuntimeFields,\n EdgeFields = RuntimeFields,\n VertexFields = RuntimeFields,\n> {\n id: BoardIdValue;\n layout?: \"hex\";\n orientation?: \"pointy-top\" | \"flat-top\";\n spaces: Readonly<\n Record<SpaceIdValue, GeneratedHexSpaceStateLike<SpaceIdValue, SpaceFields>>\n >;\n edges: ReadonlyArray<\n | HexEdgeState<BoardIdValue, SpaceIdValue, EdgeIdValue, EdgeFields>\n | GeneratedTiledEdgeStateLike<SpaceIdValue, EdgeIdValue, EdgeFields>\n >;\n vertices: ReadonlyArray<\n | HexVertexState<BoardIdValue, SpaceIdValue, VertexIdValue, VertexFields>\n | GeneratedTiledVertexStateLike<SpaceIdValue, VertexIdValue, VertexFields>\n >;\n}\n\nexport interface AuthoredHexBoardInput<\n BoardIdValue extends string = BoardId,\n SpaceIdValue extends string = string,\n EdgeIdValue extends string = string,\n VertexIdValue extends string = string,\n SpaceFields = RuntimeFields,\n EdgeFields = RuntimeFields,\n VertexFields = RuntimeFields,\n SpaceView = unknown,\n> {\n id: BoardIdValue;\n layout?: \"hex\";\n orientation?: \"pointy-top\" | \"flat-top\";\n tiles: ReadonlyArray<\n HexTileState<BoardIdValue, SpaceIdValue, SpaceFields, SpaceView>\n >;\n edges: ReadonlyArray<\n | HexEdgeState<BoardIdValue, SpaceIdValue, EdgeIdValue, EdgeFields>\n | GeneratedTiledEdgeStateLike<SpaceIdValue, EdgeIdValue, EdgeFields>\n >;\n vertices: ReadonlyArray<\n | HexVertexState<BoardIdValue, SpaceIdValue, VertexIdValue, VertexFields>\n | GeneratedTiledVertexStateLike<SpaceIdValue, VertexIdValue, VertexFields>\n >;\n}\n\nexport type HexBoardInput<\n BoardIdValue extends string = BoardId,\n SpaceIdValue extends string = string,\n EdgeIdValue extends string = string,\n VertexIdValue extends string = string,\n SpaceFields = RuntimeFields,\n EdgeFields = RuntimeFields,\n VertexFields = RuntimeFields,\n> =\n | AuthoredHexBoardInput<\n BoardIdValue,\n SpaceIdValue,\n EdgeIdValue,\n VertexIdValue,\n SpaceFields,\n EdgeFields,\n VertexFields\n >\n | GeneratedHexBoardInput<\n BoardIdValue,\n SpaceIdValue,\n EdgeIdValue,\n VertexIdValue,\n SpaceFields,\n EdgeFields,\n VertexFields\n >;\n\nexport interface GeneratedSquareBoardInput<\n BoardIdValue extends string = BoardId,\n SpaceIdValue extends string = string,\n EdgeIdValue extends string = string,\n VertexIdValue extends string = string,\n PieceIdValue extends string = string,\n SpaceFields = RuntimeFields,\n EdgeFields = RuntimeFields,\n VertexFields = RuntimeFields,\n PieceFields = RuntimeFields,\n> {\n id: BoardIdValue;\n layout?: \"square\";\n spaces: Readonly<\n Record<\n SpaceIdValue,\n GeneratedSquareSpaceStateLike<SpaceIdValue, SpaceFields>\n >\n >;\n edges: ReadonlyArray<\n | SquareEdgeState<SpaceIdValue, EdgeIdValue, EdgeFields>\n | GeneratedTiledEdgeStateLike<SpaceIdValue, EdgeIdValue, EdgeFields>\n >;\n vertices: ReadonlyArray<\n | SquareVertexState<SpaceIdValue, VertexIdValue, VertexFields>\n | GeneratedTiledVertexStateLike<SpaceIdValue, VertexIdValue, VertexFields>\n >;\n pieces?: ReadonlyArray<SquarePieceState<PieceIdValue, PieceFields>>;\n}\n\nexport interface AuthoredSquareBoardInput<\n BoardIdValue extends string = BoardId,\n SpaceIdValue extends string = string,\n EdgeIdValue extends string = string,\n VertexIdValue extends string = string,\n PieceIdValue extends string = string,\n SpaceFields = RuntimeFields,\n EdgeFields = RuntimeFields,\n VertexFields = RuntimeFields,\n PieceFields = RuntimeFields,\n> {\n id: BoardIdValue;\n layout?: \"square\";\n rows: number;\n cols: number;\n cells: ReadonlyArray<SquareCellState<SpaceIdValue, SpaceFields>>;\n edges: ReadonlyArray<\n | SquareEdgeState<SpaceIdValue, EdgeIdValue, EdgeFields>\n | GeneratedTiledEdgeStateLike<SpaceIdValue, EdgeIdValue, EdgeFields>\n >;\n vertices: ReadonlyArray<\n | SquareVertexState<SpaceIdValue, VertexIdValue, VertexFields>\n | GeneratedTiledVertexStateLike<SpaceIdValue, VertexIdValue, VertexFields>\n >;\n pieces: ReadonlyArray<SquarePieceState<PieceIdValue, PieceFields>>;\n}\n\nexport type SquareBoardInput<\n BoardIdValue extends string = BoardId,\n SpaceIdValue extends string = string,\n EdgeIdValue extends string = string,\n VertexIdValue extends string = string,\n PieceIdValue extends string = string,\n SpaceFields = RuntimeFields,\n EdgeFields = RuntimeFields,\n VertexFields = RuntimeFields,\n PieceFields = RuntimeFields,\n> =\n | AuthoredSquareBoardInput<\n BoardIdValue,\n SpaceIdValue,\n EdgeIdValue,\n VertexIdValue,\n PieceIdValue,\n SpaceFields,\n EdgeFields,\n VertexFields,\n PieceFields\n >\n | GeneratedSquareBoardInput<\n BoardIdValue,\n SpaceIdValue,\n EdgeIdValue,\n VertexIdValue,\n PieceIdValue,\n SpaceFields,\n EdgeFields,\n VertexFields,\n PieceFields\n >;\n\nexport type AnyHexBoardInput = HexBoardInput<\n string,\n string,\n string,\n string,\n RuntimeFields,\n RuntimeFields,\n RuntimeFields\n>;\nexport type AnySquareBoardInput = SquareBoardInput<\n string,\n string,\n string,\n string,\n string,\n RuntimeFields,\n RuntimeFields,\n RuntimeFields,\n RuntimeFields\n>;\n\nexport type BoardIdOf<TBoard> = TBoard extends { id: infer Id extends string }\n ? Id\n : string;\n\ntype SpaceRecordValueOf<TBoard> = TBoard extends {\n spaces: Readonly<Record<string, infer Space>>;\n}\n ? Space\n : never;\ntype TileValueOf<TBoard> = TBoard extends { tiles: ReadonlyArray<infer Tile> }\n ? Tile\n : never;\ntype CellValueOf<TBoard> = TBoard extends { cells: ReadonlyArray<infer Cell> }\n ? Cell\n : never;\ntype EdgeValueOf<TBoard> = TBoard extends { edges: ReadonlyArray<infer Edge> }\n ? Edge\n : never;\ntype VertexValueOf<TBoard> = TBoard extends {\n vertices: ReadonlyArray<infer Vertex>;\n}\n ? Vertex\n : never;\ntype PieceValueOf<TBoard> = TBoard extends {\n pieces?: ReadonlyArray<infer Piece>;\n}\n ? Piece\n : never;\n\nexport type BoardSpaceIdOf<TBoard> =\n SpaceRecordValueOf<TBoard> extends { id: infer Id extends string }\n ? Id\n : TileValueOf<TBoard> extends { id: infer Id extends string }\n ? Id\n : CellValueOf<TBoard> extends { id: infer Id extends string }\n ? Id\n : never;\n\nexport type BoardEdgeIdOf<TBoard> =\n EdgeValueOf<TBoard> extends {\n id: infer Id extends string;\n }\n ? Id\n : never;\n\nexport type BoardVertexIdOf<TBoard> =\n VertexValueOf<TBoard> extends {\n id: infer Id extends string;\n }\n ? Id\n : never;\n\ntype HexTilePropertiesOf<TBoard> =\n SpaceRecordValueOf<TBoard> extends { fields?: infer Fields }\n ? Fields\n : TileValueOf<TBoard> extends { properties?: infer Properties }\n ? Properties\n : RuntimeFields;\n\ntype HexTileViewOf<TBoard> =\n TileValueOf<TBoard> extends { view: infer View }\n ? View\n : TileValueOf<TBoard> extends { view?: infer View }\n ? View | undefined\n : unknown;\n\ntype HexEdgePropertiesOf<TBoard> =\n EdgeValueOf<TBoard> extends { fields?: infer Fields }\n ? Fields\n : EdgeValueOf<TBoard> extends { properties?: infer Properties }\n ? Properties\n : RuntimeFields;\n\ntype HexVertexPropertiesOf<TBoard> =\n VertexValueOf<TBoard> extends { fields?: infer Fields }\n ? Fields\n : VertexValueOf<TBoard> extends { properties?: infer Properties }\n ? Properties\n : RuntimeFields;\n\ntype SquareCellPropertiesOf<TBoard> =\n SpaceRecordValueOf<TBoard> extends { fields?: infer Fields }\n ? Fields\n : CellValueOf<TBoard> extends { properties?: infer Properties }\n ? Properties\n : RuntimeFields;\n\ntype SquareEdgePropertiesOf<TBoard> =\n EdgeValueOf<TBoard> extends { fields?: infer Fields }\n ? Fields\n : EdgeValueOf<TBoard> extends { properties?: infer Properties }\n ? Properties\n : RuntimeFields;\n\ntype SquareVertexPropertiesOf<TBoard> =\n VertexValueOf<TBoard> extends { fields?: infer Fields }\n ? Fields\n : VertexValueOf<TBoard> extends { properties?: infer Properties }\n ? Properties\n : RuntimeFields;\n\ntype SquarePiecePropertiesOf<TBoard> =\n PieceValueOf<TBoard> extends {\n properties?: infer Properties;\n }\n ? Properties\n : RuntimeFields;\n\n/**\n * Normalized hex tile shape for a given board input.\n *\n * `view` is always present (required) on the result so consumers can\n * read overlay fields without a null-check. For boards that do not\n * statically declare a `view` shape (the generic case), `view` falls\n * back to `unknown`, which still admits any value.\n *\n * The runtime normalizer injects `view: undefined` for inputs that\n * do not author a `view` field, keeping the runtime contract aligned\n * with this static shape.\n */\nexport type NormalizedHexTileOf<TBoard extends AnyHexBoardInput> = Omit<\n HexTileState<\n BoardIdOf<TBoard>,\n BoardSpaceIdOf<TBoard>,\n HexTilePropertiesOf<TBoard>,\n HexTileViewOf<TBoard>\n >,\n \"view\"\n> & { view: HexTileViewOf<TBoard> };\n\nexport type NormalizedHexEdgeOf<TBoard extends AnyHexBoardInput> = HexEdgeState<\n BoardIdOf<TBoard>,\n BoardSpaceIdOf<TBoard>,\n BoardEdgeIdOf<TBoard>,\n HexEdgePropertiesOf<TBoard>\n>;\n\nexport type NormalizedHexVertexOf<TBoard extends AnyHexBoardInput> =\n HexVertexState<\n BoardIdOf<TBoard>,\n BoardSpaceIdOf<TBoard>,\n BoardVertexIdOf<TBoard>,\n HexVertexPropertiesOf<TBoard>\n >;\n\nexport type NormalizedSquareCellOf<TBoard extends AnySquareBoardInput> =\n SquareCellState<BoardSpaceIdOf<TBoard>, SquareCellPropertiesOf<TBoard>>;\n\nexport type NormalizedSquareEdgeOf<TBoard extends AnySquareBoardInput> =\n SquareEdgeState<\n BoardSpaceIdOf<TBoard>,\n BoardEdgeIdOf<TBoard>,\n SquareEdgePropertiesOf<TBoard>\n >;\n\nexport type NormalizedSquareVertexOf<TBoard extends AnySquareBoardInput> =\n SquareVertexState<\n BoardSpaceIdOf<TBoard>,\n BoardVertexIdOf<TBoard>,\n SquareVertexPropertiesOf<TBoard>\n >;\n\nexport type NormalizedSquarePieceOf<TBoard extends AnySquareBoardInput> =\n SquarePieceState<\n PieceValueOf<TBoard> extends { id: infer PieceIdValue extends string }\n ? PieceIdValue\n : string,\n SquarePiecePropertiesOf<TBoard>\n >;\n\nexport type NormalizedHexBoard<TBoard extends AnyHexBoardInput> = Omit<\n Pick<\n HexBoardState<\n BoardIdOf<TBoard>,\n BoardSpaceIdOf<TBoard>,\n BoardEdgeIdOf<TBoard>,\n BoardVertexIdOf<TBoard>,\n HexTilePropertiesOf<TBoard>,\n HexEdgePropertiesOf<TBoard>,\n HexVertexPropertiesOf<TBoard>\n >,\n \"id\" | \"tiles\" | \"edges\" | \"vertices\"\n >,\n \"tiles\"\n> & {\n tiles: ReadonlyArray<NormalizedHexTileOf<TBoard>>;\n orientation?: \"pointy-top\" | \"flat-top\";\n};\n\nexport type NormalizedSquareBoard<TBoard extends AnySquareBoardInput> = Pick<\n SquareBoardState<\n BoardIdOf<TBoard>,\n BoardSpaceIdOf<TBoard>,\n BoardEdgeIdOf<TBoard>,\n BoardVertexIdOf<TBoard>,\n PieceValueOf<TBoard> extends { id: infer PieceIdValue extends string }\n ? PieceIdValue\n : string,\n SquareCellPropertiesOf<TBoard>,\n SquareEdgePropertiesOf<TBoard>,\n SquareVertexPropertiesOf<TBoard>,\n SquarePiecePropertiesOf<TBoard>\n >,\n \"id\" | \"rows\" | \"cols\" | \"cells\" | \"edges\" | \"vertices\" | \"pieces\"\n>;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction firstValue(record: Readonly<Record<string, unknown>>): unknown {\n const [first] = Object.values(record);\n return first;\n}\n\nfunction normalizeOptional<T>(\n value: T | null | undefined,\n): NormalizeOptional<T> {\n return (value ?? undefined) as NormalizeOptional<T>;\n}\n\nexport function isGeneratedHexBoardInput<\n TBoard extends AnyHexBoardInput | AnySquareBoardInput,\n>(\n board: TBoard,\n): board is Extract<TBoard, { spaces: Readonly<Record<string, unknown>> }> {\n if (!isRecord(board) || !(\"spaces\" in board) || !isRecord(board.spaces)) {\n return false;\n }\n if (\"tiles\" in board || \"cells\" in board) {\n return false;\n }\n if (board.layout === \"hex\") {\n return true;\n }\n const firstSpace = firstValue(\n board.spaces as Readonly<Record<string, unknown>>,\n );\n return (\n isRecord(firstSpace) &&\n typeof firstSpace.q === \"number\" &&\n typeof firstSpace.r === \"number\"\n );\n}\n\nexport function isGeneratedSquareBoardInput<\n TBoard extends AnyHexBoardInput | AnySquareBoardInput,\n>(\n board: TBoard,\n): board is Extract<TBoard, { spaces: Readonly<Record<string, unknown>> }> {\n if (!isRecord(board) || !(\"spaces\" in board) || !isRecord(board.spaces)) {\n return false;\n }\n if (\"tiles\" in board || \"cells\" in board) {\n return false;\n }\n if (board.layout === \"square\") {\n return true;\n }\n const firstSpace = firstValue(\n board.spaces as Readonly<Record<string, unknown>>,\n );\n return (\n isRecord(firstSpace) &&\n typeof firstSpace.row === \"number\" &&\n typeof firstSpace.col === \"number\"\n );\n}\n\nfunction normalizeHexTile<TBoard extends AnyHexBoardInput>(\n tile: SpaceRecordValueOf<TBoard>,\n): NormalizedHexTileOf<TBoard> {\n return {\n id: tile.id as BoardSpaceIdOf<TBoard>,\n q: tile.q as number,\n r: tile.r as number,\n typeId: normalizeOptional(tile.typeId as SpaceTypeId | null | undefined),\n label: normalizeOptional(tile.label as string | null | undefined),\n owner: normalizeOptional(tile.ownerId as PlayerId | null | undefined),\n properties: (tile.fields ?? undefined) as HexTilePropertiesOf<TBoard>,\n view: undefined,\n } as unknown as NormalizedHexTileOf<TBoard>;\n}\n\nfunction normalizeHexEdge<TBoard extends AnyHexBoardInput>(\n edge: EdgeValueOf<TBoard>,\n): NormalizedHexEdgeOf<TBoard> {\n if (\"hex1\" in edge && \"hex2\" in edge) {\n return {\n ...edge,\n label: normalizeOptional(edge.label),\n owner: normalizeOptional(edge.owner),\n typeId: normalizeOptional(edge.typeId),\n properties: edge.properties,\n } as NormalizedHexEdgeOf<TBoard>;\n }\n\n const [hex1 = \"\", hex2 = \"\"] = edge.spaceIds;\n return {\n id: edge.id as BoardEdgeIdOf<TBoard>,\n hex1: hex1 as BoardSpaceIdOf<TBoard>,\n hex2: hex2 as BoardSpaceIdOf<TBoard>,\n typeId: normalizeOptional(edge.typeId),\n label: normalizeOptional(edge.label),\n owner: normalizeOptional(edge.ownerId),\n properties: (edge.fields ?? undefined) as HexEdgePropertiesOf<TBoard>,\n };\n}\n\nfunction normalizeHexVertex<TBoard extends AnyHexBoardInput>(\n vertex: VertexValueOf<TBoard>,\n): NormalizedHexVertexOf<TBoard> {\n if (\"hexes\" in vertex) {\n return {\n ...vertex,\n label: normalizeOptional(vertex.label),\n owner: normalizeOptional(vertex.owner),\n typeId: normalizeOptional(vertex.typeId),\n properties: vertex.properties,\n } as NormalizedHexVertexOf<TBoard>;\n }\n\n return {\n id: vertex.id as BoardVertexIdOf<TBoard>,\n hexes: vertex.spaceIds as ReadonlyArray<BoardSpaceIdOf<TBoard>>,\n typeId: normalizeOptional(vertex.typeId),\n label: normalizeOptional(vertex.label),\n owner: normalizeOptional(vertex.ownerId),\n properties: (vertex.fields ?? undefined) as HexVertexPropertiesOf<TBoard>,\n };\n}\n\nfunction normalizeSquareCell<TBoard extends AnySquareBoardInput>(\n cell: SpaceRecordValueOf<TBoard>,\n): NormalizedSquareCellOf<TBoard> {\n return {\n id: cell.id as BoardSpaceIdOf<TBoard>,\n row: cell.row as number,\n col: cell.col as number,\n typeId: normalizeOptional(cell.typeId as SpaceTypeId | null | undefined),\n label: normalizeOptional(cell.label as string | null | undefined),\n owner: normalizeOptional(cell.ownerId as PlayerId | null | undefined),\n properties: (cell.fields ?? undefined) as SquareCellPropertiesOf<TBoard>,\n };\n}\n\nfunction normalizeSquareEdge<TBoard extends AnySquareBoardInput>(\n edge: EdgeValueOf<TBoard>,\n): NormalizedSquareEdgeOf<TBoard> {\n if (\"ownerId\" in edge || \"fields\" in edge) {\n return {\n id: edge.id as BoardEdgeIdOf<TBoard>,\n spaceIds: edge.spaceIds as ReadonlyArray<BoardSpaceIdOf<TBoard>>,\n typeId: normalizeOptional(edge.typeId),\n label: normalizeOptional(edge.label),\n owner: normalizeOptional(edge.ownerId),\n properties: (edge.fields ?? undefined) as SquareEdgePropertiesOf<TBoard>,\n };\n }\n\n return {\n id: edge.id as BoardEdgeIdOf<TBoard>,\n spaceIds: edge.spaceIds as ReadonlyArray<BoardSpaceIdOf<TBoard>>,\n typeId: normalizeOptional(edge.typeId),\n label: normalizeOptional(edge.label),\n owner: normalizeOptional(\n (edge as SquareEdgeState<string, string, RuntimeFields>).owner,\n ),\n properties: (edge as SquareEdgeState<string, string, RuntimeFields>)\n .properties as SquareEdgePropertiesOf<TBoard>,\n };\n}\n\nfunction normalizeSquareVertex<TBoard extends AnySquareBoardInput>(\n vertex: VertexValueOf<TBoard>,\n): NormalizedSquareVertexOf<TBoard> {\n if (\"ownerId\" in vertex || \"fields\" in vertex) {\n return {\n id: vertex.id as BoardVertexIdOf<TBoard>,\n spaceIds: vertex.spaceIds as ReadonlyArray<BoardSpaceIdOf<TBoard>>,\n typeId: normalizeOptional(vertex.typeId),\n label: normalizeOptional(vertex.label),\n owner: normalizeOptional(vertex.ownerId),\n properties: (vertex.fields ??\n undefined) as SquareVertexPropertiesOf<TBoard>,\n };\n }\n\n return {\n id: vertex.id as BoardVertexIdOf<TBoard>,\n spaceIds: vertex.spaceIds as ReadonlyArray<BoardSpaceIdOf<TBoard>>,\n typeId: normalizeOptional(vertex.typeId),\n label: normalizeOptional(vertex.label),\n owner: normalizeOptional(\n (vertex as SquareVertexState<string, string, RuntimeFields>).owner,\n ),\n properties: (vertex as SquareVertexState<string, string, RuntimeFields>)\n .properties as SquareVertexPropertiesOf<TBoard>,\n };\n}\n\nfunction isAuthoredHexBoardInput(\n board: AnyHexBoardInput,\n): board is Extract<AnyHexBoardInput, { tiles: readonly unknown[] }> {\n return \"tiles\" in board;\n}\n\nfunction isAuthoredSquareBoardInput(\n board: AnySquareBoardInput,\n): board is Extract<AnySquareBoardInput, { cells: readonly unknown[] }> {\n return \"cells\" in board;\n}\n\nexport function normalizeHexBoardInput<TBoard extends AnyHexBoardInput>(\n board: TBoard,\n): NormalizedHexBoard<TBoard> {\n if (isGeneratedHexBoardInput(board)) {\n return {\n id: board.id,\n orientation: board.orientation,\n tiles: Object.values(board.spaces).map((tile) =>\n normalizeHexTile<TBoard>(tile as SpaceRecordValueOf<TBoard>),\n ),\n edges: board.edges.map((edge) =>\n normalizeHexEdge<TBoard>(edge as EdgeValueOf<TBoard>),\n ),\n vertices: board.vertices.map((vertex) =>\n normalizeHexVertex<TBoard>(vertex as VertexValueOf<TBoard>),\n ),\n } as unknown as NormalizedHexBoard<TBoard>;\n }\n\n if (!isAuthoredHexBoardInput(board)) {\n throw new Error(\"Expected authored hex board input.\");\n }\n const authoredBoard = board as Extract<TBoard, { tiles: readonly unknown[] }>;\n return {\n id: authoredBoard.id,\n orientation: authoredBoard.orientation,\n tiles: authoredBoard.tiles.map((tile) => ({\n ...tile,\n label: normalizeOptional(tile.label),\n owner: normalizeOptional(tile.owner),\n typeId: normalizeOptional(tile.typeId),\n properties: tile.properties,\n view: tile.view,\n })),\n edges: authoredBoard.edges.map((edge) =>\n normalizeHexEdge<TBoard>(edge as EdgeValueOf<TBoard>),\n ),\n vertices: authoredBoard.vertices.map((vertex) =>\n normalizeHexVertex<TBoard>(vertex as VertexValueOf<TBoard>),\n ),\n } as unknown as NormalizedHexBoard<TBoard>;\n}\n\nexport function normalizeSquareBoardInput<TBoard extends AnySquareBoardInput>(\n board: TBoard,\n): NormalizedSquareBoard<TBoard> {\n if (isGeneratedSquareBoardInput(board)) {\n const cells = Object.values(board.spaces).map((cell) =>\n normalizeSquareCell<TBoard>(cell as SpaceRecordValueOf<TBoard>),\n );\n const rows =\n cells.length === 0 ? 0 : Math.max(...cells.map((cell) => cell.row)) + 1;\n const cols =\n cells.length === 0 ? 0 : Math.max(...cells.map((cell) => cell.col)) + 1;\n\n return {\n id: board.id,\n rows,\n cols,\n cells,\n edges: board.edges.map((edge) =>\n normalizeSquareEdge<TBoard>(edge as EdgeValueOf<TBoard>),\n ),\n vertices: board.vertices.map((vertex) =>\n normalizeSquareVertex<TBoard>(vertex as VertexValueOf<TBoard>),\n ),\n pieces: (\n (board.pieces ?? []) as ReadonlyArray<NormalizedSquarePieceOf<TBoard>>\n ).map((piece) => ({\n ...piece,\n owner: normalizeOptional(piece.owner),\n typeId: piece.typeId,\n properties: piece.properties,\n })),\n } as unknown as NormalizedSquareBoard<TBoard>;\n }\n\n if (!isAuthoredSquareBoardInput(board)) {\n throw new Error(\"Expected authored square board input.\");\n }\n const authoredBoard = board as Extract<TBoard, { cells: readonly unknown[] }>;\n return {\n id: authoredBoard.id,\n rows: authoredBoard.rows,\n cols: authoredBoard.cols,\n cells: authoredBoard.cells.map((cell) => ({\n ...cell,\n label: normalizeOptional(cell.label),\n owner: normalizeOptional(cell.owner),\n typeId: normalizeOptional(cell.typeId),\n properties: cell.properties,\n })),\n edges: authoredBoard.edges.map((edge) =>\n normalizeSquareEdge<TBoard>(edge as EdgeValueOf<TBoard>),\n ),\n vertices: authoredBoard.vertices.map((vertex) =>\n normalizeSquareVertex<TBoard>(vertex as VertexValueOf<TBoard>),\n ),\n pieces: (authoredBoard.pieces ?? []).map((piece) => ({\n ...piece,\n owner: normalizeOptional(piece.owner),\n typeId: piece.typeId,\n properties: piece.properties,\n })),\n } as unknown as NormalizedSquareBoard<TBoard>;\n}\n","/**\n * Controlled visual state contract for `@dreamboard-games/sdk/ui` components.\n *\n * The SDK is Dreamboard-interaction unaware: components consume `display data`\n * and `controlled semantic states`. Runtime adapters compute these states from\n * descriptors/drafts and pass them in as plain props.\n */\n\n/**\n * Generic semantic state attached to a presentational component.\n *\n * Every flag is optional and renders as a stable `data-*` attribute on the\n * underlying element so that selectors, snapshot diffs and accessibility\n * announcements can react to state without inspecting class strings.\n */\nexport interface InteractionVisualState {\n /** Caller may activate this surface right now. */\n eligible?: boolean;\n /**\n * Eligible *and* a meaningful subset — i.e. at least one peer surface is not\n * eligible. Use this (rather than `eligible`) to drive a \"highlight the\n * playable cards\" affordance: when every card in a hand is a legal target\n * (e.g. a pass where any card may be chosen, or a turn where you may play\n * anything) the highlight carries no information, so `distinctlyEligible` is\n * `false` for all of them and the ring naturally disappears. `eligible`\n * keeps its literal meaning (\"is a legal target\") for dimming/logic.\n */\n distinctlyEligible?: boolean;\n /** Currently chosen as part of a draft selection or focus state. */\n selected?: boolean;\n /** Surface is non-interactive and visually muted. */\n disabled?: boolean;\n /** Caller's draft is invalid — render an error tint without removing the surface. */\n invalid?: boolean;\n /** Action has been submitted; render a settled/locked feedback state. */\n submitted?: boolean;\n /** Surface is being previewed (long-press, hover hold) without commitment. */\n previewing?: boolean;\n /**\n * Optional 0..1 progress reading for an in-flight UI intent (swipe, hold,\n * etc.). Components may render this as a fill, scale or halo without owning\n * the gesture pipeline themselves.\n */\n intentProgress?: number;\n}\n\n/**\n * Generic UI intent emitted by SDK components.\n *\n * Components do not know what `activate`/`drop` mean in Dreamboard terms —\n * that mapping belongs to a runtime adapter. They only emit when a generic\n * pointer/keyboard gesture completes.\n *\n * - `activate` is a single-target commit produced by a desktop click or a\n * keyboard activation in `direct-activate` mode.\n * - `drop` is a card→target commit produced by mobile drag or keyboard drop\n * in `drag-to-target` mode. The opaque `targetId` is registered by a\n * `CardDropTargetView` and resolved against pointer geometry inside the\n * `CardDragSurface`.\n * - `previewStart`/`previewEnd` bracket a long-press inspection that does\n * not commit.\n */\nexport type CardIntent<\n CardId extends string = string,\n TargetId extends string = string,\n> =\n | { type: \"activate\"; cardId: CardId; source: \"tap\" | \"keyboard\" }\n | { type: \"previewStart\"; cardId: CardId }\n | { type: \"previewEnd\"; cardId: CardId }\n | {\n type: \"drop\";\n cardId: CardId;\n targetId: TargetId;\n source: \"pointer\" | \"keyboard\";\n };\n\n/**\n * Generic UI intent emitted for a board target (space/edge/vertex).\n */\nexport type TargetIntent<TargetId extends string = string> =\n | { type: \"activate\"; targetId: TargetId; source: \"tap\" | \"keyboard\" }\n | { type: \"previewStart\"; targetId: TargetId }\n | { type: \"previewEnd\"; targetId: TargetId };\n\n/**\n * Controlled visual state for a card drop target rendered through\n * `CardDropTargetView`.\n *\n * `active` is `true` when any card is currently being dragged anywhere on\n * the surface (eligible target should advertise itself). `over` is `true`\n * only for the target that the lifted pointer would currently drop on.\n */\nexport interface CardDropTargetVisualState extends InteractionVisualState {\n active?: boolean;\n over?: boolean;\n}\n\n/**\n * Build the `data-*` attribute bag for an {@link InteractionVisualState} so\n * that components apply a single consistent attribute surface.\n *\n * `undefined` values are emitted (rather than `false`) so that CSS\n * `[data-…=\"true\"]` selectors do not match by mistake.\n */\nexport function visualStateDataAttributes(\n state: InteractionVisualState | undefined,\n): Readonly<Record<string, string | undefined>> {\n if (!state) return {};\n return {\n \"data-eligible\": state.eligible ? \"true\" : undefined,\n \"data-distinctly-eligible\": state.distinctlyEligible ? \"true\" : undefined,\n \"data-selected\": state.selected ? \"true\" : undefined,\n \"data-disabled\": state.disabled ? \"true\" : undefined,\n \"data-invalid\": state.invalid ? \"true\" : undefined,\n \"data-submitted\": state.submitted ? \"true\" : undefined,\n \"data-previewing\": state.previewing ? \"true\" : undefined,\n \"data-intent-progress\":\n typeof state.intentProgress === \"number\"\n ? String(Math.max(0, Math.min(1, state.intentProgress)))\n : undefined,\n };\n}\n\n/**\n * Build the `data-*` attribute bag for a {@link CardDropTargetVisualState}.\n */\nexport function dropTargetVisualStateDataAttributes(\n state: CardDropTargetVisualState | undefined,\n): Readonly<Record<string, string | undefined>> {\n const base = visualStateDataAttributes(state);\n if (!state) return base;\n return {\n ...base,\n \"data-drag-active\": state.active ? \"true\" : undefined,\n \"data-drag-over\": state.over ? \"true\" : undefined,\n };\n}\n","/**\n * Presentational card shell. Feed from reducer views, not runtime state.\n *\n * `CardFace` is the only public reusable card shell in `@dreamboard-games/sdk/ui`.\n * It renders display content with controlled {@link InteractionVisualState}\n * (eligible / selected / disabled / invalid / submitted / previewing) and\n * exposes stable `data-*` attributes. It does not own activation behavior —\n * compose it with a generic `<button>` (or with a runtime adapter) when an\n * authored surface needs to react to taps or keyboard activation.\n */\n\nimport { clsx } from \"clsx\";\nimport type { ViewCard } from \"../../types/index.js\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\nimport { motionDuration } from \"../theme/derive.js\";\nimport {\n visualStateDataAttributes,\n type InteractionVisualState,\n} from \"../types/visual-state.js\";\n\nexport interface CardFaceProps<CardData extends ViewCard = ViewCard>\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, \"children\">,\n InteractionVisualState {\n card: CardData;\n size?: \"sm\" | \"md\" | \"lg\";\n faceDown?: boolean;\n renderContent?: (card: CardData) => React.ReactNode;\n children?: React.ReactNode;\n}\n\n/**\n * Reserved keys on `ViewCard.properties` that the default content\n * renderer recognises and styles consistently. Authors who set these\n * keys at view-build time get a properly laid-out card face for free\n * (icon → title → subtitle → effect → cost), instead of the previous\n * \"first three properties as label/value\" fallback that produced\n * inconsistent card faces across games.\n *\n * Any other property keys are still rendered, just below the\n * conventional cluster, so authors can mix and match without losing\n * data — but the canonical surface should pick from these slots first.\n *\n * Slots:\n *\n * - `icon` — short visual flag (emoji, glyph). Rendered large at the\n * top of the card.\n * - `title` — primary label. Falls back to `card.name`.\n * - `subtitle` — short qualifier (\"1 VP\", \"Action\", \"Resource\").\n * - `effect` — body text describing what the card does.\n * - `cost` — short cost line (\"3 brick\"); rendered as a chip footer.\n */\nconst RESERVED_CONTENT_KEYS = [\n \"icon\",\n \"title\",\n \"subtitle\",\n \"effect\",\n \"cost\",\n] as const;\n\ntype ReservedKey = (typeof RESERVED_CONTENT_KEYS)[number];\n\nconst RESERVED_KEY_SET: ReadonlySet<string> = new Set(RESERVED_CONTENT_KEYS);\n\nfunction readReserved(\n props: Record<string, unknown> | undefined,\n key: ReservedKey,\n): string | undefined {\n if (!props) return undefined;\n const raw = props[key];\n if (raw === undefined || raw === null) return undefined;\n return String(raw);\n}\n\n/** Default card content renderer. */\nfunction DefaultCardContent({\n card,\n size,\n}: {\n card: ViewCard;\n size: NonNullable<CardFaceProps[\"size\"]>;\n}) {\n const theme = useTheme();\n const props = card.properties as Record<string, unknown> | undefined;\n const icon = readReserved(props, \"icon\");\n const title = readReserved(props, \"title\") ?? card.name;\n const subtitle = readReserved(props, \"subtitle\");\n const effect = readReserved(props, \"effect\");\n const cost = readReserved(props, \"cost\");\n const extra = props\n ? Object.entries(props).filter(([key]) => !RESERVED_KEY_SET.has(key))\n : [];\n\n const hasAnyReserved = icon || title || subtitle || effect || cost;\n const compact = size === \"sm\";\n\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n height: \"100%\",\n minHeight: 0,\n boxSizing: \"border-box\",\n overflow: \"hidden\",\n textAlign: \"center\",\n padding: compact ? theme.space[1] : theme.space[2],\n gap: compact ? theme.space[0.5] : theme.space[1],\n }}\n >\n {icon ? (\n <span\n aria-hidden\n style={{\n flexShrink: 0,\n fontSize: compact\n ? theme.typography.fontSize.lg\n : theme.typography.fontSize[\"2xl\"],\n lineHeight: 1,\n }}\n >\n {icon}\n </span>\n ) : null}\n {title ? (\n <span\n style={{\n flexShrink: 0,\n fontFamily: theme.typography.fontFamily.display,\n fontSize: theme.typography.fontSize.sm,\n fontWeight: theme.typography.fontWeight.bold,\n color: theme.semantic.text.primary,\n lineHeight: theme.typography.lineHeight.tight,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n display: \"-webkit-box\",\n WebkitLineClamp: 2,\n WebkitBoxOrient: \"vertical\",\n wordBreak: \"break-word\",\n }}\n >\n {title}\n </span>\n ) : null}\n {subtitle ? (\n <span\n style={{\n flexShrink: 0,\n fontFamily: theme.typography.fontFamily.body,\n fontSize: theme.typography.fontSize.xs,\n fontWeight: theme.typography.fontWeight.medium,\n color: theme.semantic.text.muted,\n letterSpacing: theme.typography.letterSpacing.wide,\n textTransform: \"uppercase\",\n }}\n >\n {subtitle}\n </span>\n ) : null}\n {effect ? (\n <span\n style={{\n flex: \"1 1 auto\",\n minHeight: 0,\n fontFamily: theme.typography.fontFamily.body,\n fontSize: theme.typography.fontSize.xs,\n color: theme.semantic.text.muted,\n lineHeight: theme.typography.lineHeight.normal,\n display: \"-webkit-box\",\n WebkitLineClamp: compact ? 1 : size === \"md\" ? 2 : 3,\n WebkitBoxOrient: \"vertical\",\n overflow: \"hidden\",\n }}\n >\n {effect}\n </span>\n ) : null}\n {cost ? (\n <span\n style={{\n display: \"inline-flex\",\n flexShrink: 0,\n alignItems: \"center\",\n gap: theme.space[1],\n paddingBlock: theme.space[0.5],\n paddingInline: theme.space[2],\n borderRadius: theme.radius.pill,\n background: theme.semantic.surface.inset,\n border: `1px solid ${theme.semantic.border.subtle}`,\n fontFamily: theme.typography.fontFamily.tabular,\n fontSize: theme.typography.fontSize.xs,\n fontWeight: theme.typography.fontWeight.bold,\n color: theme.semantic.text.primary,\n marginTop: \"auto\",\n }}\n >\n {cost}\n </span>\n ) : null}\n {!hasAnyReserved && extra.length > 0\n ? extra.slice(0, 3).map(([key, value]) => (\n <span\n key={key}\n style={{\n flexShrink: 0,\n fontFamily: theme.typography.fontFamily.body,\n fontSize: theme.typography.fontSize.xs,\n color: theme.semantic.text.primary,\n }}\n >\n <span style={{ color: theme.semantic.text.muted }}>{key}:</span>{\" \"}\n <span style={{ fontWeight: theme.typography.fontWeight.bold }}>\n {String(value)}\n </span>\n </span>\n ))\n : null}\n {!hasAnyReserved && extra.length === 0 ? (\n <span\n style={{\n flexShrink: 0,\n fontFamily: theme.typography.fontFamily.mono,\n fontSize: theme.typography.fontSize.xs,\n color: theme.semantic.text.disabled,\n }}\n >\n {card.id.slice(0, 8)}\n </span>\n ) : null}\n </div>\n );\n}\n\nconst CARD_SIZE_CLASSES = {\n sm: \"w-16 h-24 sm:w-20 sm:h-28\",\n md: \"w-20 h-32 sm:w-24 sm:h-36\",\n lg: \"w-24 h-36 sm:w-32 sm:h-48\",\n} as const;\n\nexport function CardFace<CardData extends ViewCard = ViewCard>({\n card,\n eligible,\n selected = false,\n disabled = false,\n invalid,\n submitted,\n previewing,\n intentProgress,\n size = \"md\",\n faceDown = false,\n renderContent,\n children,\n className,\n style,\n ...props\n}: CardFaceProps<CardData>) {\n const theme = useTheme();\n const calmCornerRadius = theme.radius.md;\n const accentCornerRadius = `${theme.radius.lg} ${theme.radius.sm} ${theme.radius.lg} ${theme.radius.sm} / ${theme.radius.sm} ${theme.radius.lg} ${theme.radius.sm} ${theme.radius.lg}`;\n const selectionRingColor = theme.component.card.selectedRing;\n const eligibleRingColor = theme.semantic.intent.warning.border;\n const invalidRingColor = theme.semantic.intent.danger.border;\n const submittedRingColor = theme.semantic.intent.success.border;\n const restBorderColor = theme.component.card.border;\n const dataAttributes = visualStateDataAttributes({\n eligible,\n selected,\n disabled,\n invalid,\n submitted,\n previewing,\n intentProgress,\n });\n // Routine resting cards use a calm modern surface. Hard-shadow / irregular\n // corner accents are reserved for explicit emphasis states so a fanned\n // hand reads as ordered play instead of repeated decoration.\n const accentColor = invalid\n ? invalidRingColor\n : submitted\n ? submittedRingColor\n : selected\n ? selectionRingColor\n : previewing\n ? selectionRingColor\n : eligible\n ? eligibleRingColor\n : undefined;\n const isAccented = Boolean(accentColor);\n const accentShadow = selected\n ? `6px 6px 0px 0px ${selectionRingColor}`\n : previewing\n ? `4px 4px 0px 0px ${selectionRingColor}`\n : invalid\n ? `4px 4px 0px 0px ${invalidRingColor}`\n : submitted\n ? `4px 4px 0px 0px ${submittedRingColor}`\n : eligible\n ? `4px 4px 0px 0px ${eligibleRingColor}`\n : undefined;\n const restShadow = theme.elevation.rest;\n\n return (\n <div\n {...props}\n {...dataAttributes}\n data-dreamboard-card-face=\"\"\n data-accented={isAccented ? \"true\" : undefined}\n data-face-down={faceDown ? \"true\" : undefined}\n className={clsx(\"relative\", CARD_SIZE_CLASSES[size], className)}\n style={{\n opacity: disabled ? 0.5 : submitted ? 0.85 : 1,\n transitionProperty: \"transform, box-shadow, border-color\",\n transitionDuration: motionDuration(theme, \"normal\"),\n transitionTimingFunction: theme.motion.easing.out,\n transform: previewing ? \"translateY(-2px) scale(1.02)\" : undefined,\n ...style,\n }}\n >\n {faceDown ? (\n // Card back: keep the playful diagonal pattern as artwork, but\n // anchor the shell on the same calm baseline as a face-up card so\n // a row of opponent hands or a draw pile reads as ordered chrome\n // rather than repeated decoration. Emphasis states (selected,\n // eligible, invalid, submitted, previewing) still upgrade to the\n // accent radius + hard-offset shadow.\n <div\n className=\"absolute inset-0 overflow-hidden pointer-events-none\"\n style={{\n background: theme.component.card.backBackground,\n borderStyle: \"solid\",\n borderWidth: isAccented ? 3 : 1,\n borderColor: accentColor ?? restBorderColor,\n borderRadius: isAccented ? accentCornerRadius : calmCornerRadius,\n boxShadow: accentShadow ?? restShadow,\n }}\n >\n <div\n className=\"absolute inset-2\"\n style={{\n borderRadius: calmCornerRadius,\n background:\n \"repeating-linear-gradient(45deg, transparent, transparent 10px, rgba(255,255,255,0.2) 10px, rgba(255,255,255,0.2) 20px)\",\n }}\n />\n </div>\n ) : (\n <div\n className=\"absolute inset-0 overflow-hidden pointer-events-none\"\n style={{\n background: submitted\n ? theme.semantic.intent.success.soft\n : theme.semantic.surface.card,\n borderStyle: \"solid\",\n borderWidth: isAccented ? 3 : 1,\n borderColor: accentColor ?? restBorderColor,\n borderRadius: isAccented ? accentCornerRadius : calmCornerRadius,\n boxShadow: accentShadow ?? restShadow,\n outline:\n selected || invalid\n ? `2px solid ${accentColor ?? selectionRingColor}`\n : undefined,\n outlineOffset: selected || invalid ? \"1px\" : undefined,\n }}\n >\n {children ??\n (renderContent ? (\n renderContent(card)\n ) : (\n <DefaultCardContent card={card} size={size} />\n ))}\n </div>\n )}\n </div>\n );\n}\n\nexport type { ViewCard };\n","/** Mobile-friendly slide-out panel built on vaul. Used as fallback when cards can't fit on screen. */\n\nimport * as React from \"react\";\nimport { Drawer as DrawerPrimitive } from \"vaul\";\nimport { clsx } from \"clsx\";\n\nfunction Drawer({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Root>) {\n return <DrawerPrimitive.Root data-slot=\"drawer\" {...props} />;\n}\n\nfunction DrawerTrigger({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {\n return <DrawerPrimitive.Trigger data-slot=\"drawer-trigger\" {...props} />;\n}\n\nfunction DrawerPortal({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Portal>) {\n return <DrawerPrimitive.Portal data-slot=\"drawer-portal\" {...props} />;\n}\n\nfunction DrawerClose({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Close>) {\n return <DrawerPrimitive.Close data-slot=\"drawer-close\" {...props} />;\n}\n\nfunction DrawerOverlay({\n className,\n style,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {\n return (\n <DrawerPrimitive.Overlay\n data-slot=\"drawer-overlay\"\n className={clsx(\n \"fixed inset-0 z-50 bg-black/50\",\n \"data-[state=open]:animate-in data-[state=closed]:animate-out\",\n \"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n className,\n )}\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 50,\n background: \"rgba(0, 0, 0, 0.5)\",\n ...style,\n }}\n {...props}\n />\n );\n}\n\ninterface DrawerContentProps extends React.ComponentPropsWithoutRef<\n typeof DrawerPrimitive.Content\n> {\n showHandle?: boolean;\n children?: React.ReactNode;\n}\n\nfunction DrawerContent({\n className,\n children,\n showHandle = true,\n ...props\n}: DrawerContentProps) {\n return (\n <DrawerPortal data-slot=\"drawer-portal\">\n <DrawerOverlay />\n <DrawerPrimitive.Content\n data-slot=\"drawer-content\"\n className={clsx(\n \"group/drawer-content fixed z-50 flex h-auto flex-col bg-white\",\n // Bottom drawer (default for mobile hand display)\n \"data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0\",\n \"data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh]\",\n \"data-[vaul-drawer-direction=bottom]:rounded-t-xl data-[vaul-drawer-direction=bottom]:border-t\",\n // Top drawer\n \"data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0\",\n \"data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh]\",\n \"data-[vaul-drawer-direction=top]:rounded-b-xl data-[vaul-drawer-direction=top]:border-b\",\n // Right drawer\n \"data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0\",\n \"data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:max-w-sm\",\n \"data-[vaul-drawer-direction=right]:rounded-l-xl data-[vaul-drawer-direction=right]:border-l\",\n // Left drawer\n \"data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0\",\n \"data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:max-w-sm\",\n \"data-[vaul-drawer-direction=left]:rounded-r-xl data-[vaul-drawer-direction=left]:border-r\",\n className,\n )}\n {...props}\n >\n {/* Drag handle for bottom drawer */}\n {showHandle && (\n <div\n className=\"mx-auto mt-4 h-2 w-[100px] shrink-0 rounded-full bg-slate-300\"\n style={{\n width: 100,\n height: 8,\n margin: \"16px auto 0\",\n flexShrink: 0,\n borderRadius: 999,\n background: \"#cbd5e1\",\n }}\n />\n )}\n {children}\n </DrawerPrimitive.Content>\n </DrawerPortal>\n );\n}\n\nfunction DrawerHeader({\n className,\n ...props\n}: React.ComponentPropsWithoutRef<\"div\">) {\n return (\n <div\n data-slot=\"drawer-header\"\n className={clsx(\"flex flex-col gap-1.5 p-4\", className)}\n {...props}\n />\n );\n}\n\nfunction DrawerFooter({\n className,\n ...props\n}: React.ComponentPropsWithoutRef<\"div\">) {\n return (\n <div\n data-slot=\"drawer-footer\"\n className={clsx(\"mt-auto flex flex-col gap-2 p-4\", className)}\n {...props}\n />\n );\n}\n\nfunction DrawerTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Title>) {\n return (\n <DrawerPrimitive.Title\n data-slot=\"drawer-title\"\n className={clsx(\"text-slate-900 font-semibold text-lg\", className)}\n {...props}\n />\n );\n}\n\nfunction DrawerDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Description>) {\n return (\n <DrawerPrimitive.Description\n data-slot=\"drawer-description\"\n className={clsx(\"text-slate-500 text-sm\", className)}\n {...props}\n />\n );\n}\n\nexport {\n Drawer,\n DrawerPortal,\n DrawerOverlay,\n DrawerTrigger,\n DrawerClose,\n DrawerContent,\n DrawerHeader,\n DrawerFooter,\n DrawerTitle,\n DrawerDescription,\n};\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n type ReactNode,\n} from \"react\";\n\ntype ChromeSuppressionRegistration = (id: string, suppressed: boolean) => void;\n\nconst ChromeSuppressionContext =\n createContext<ChromeSuppressionRegistration | null>(null);\n\nexport function ChromeSuppressionProvider({\n children,\n onSuppressedChange,\n}: {\n children: ReactNode;\n onSuppressedChange: (suppressed: boolean) => void;\n}) {\n const [suppressedEntries, setSuppressedEntries] = useState<\n ReadonlySet<string>\n >(() => new Set());\n\n const register = useCallback<ChromeSuppressionRegistration>(\n (id, suppressed) => {\n setSuppressedEntries((current) =>\n updateSuppressedEntries(current, id, suppressed),\n );\n },\n [],\n );\n const suppressed = suppressedEntries.size > 0;\n\n useEffect(() => {\n onSuppressedChange(suppressed);\n }, [onSuppressedChange, suppressed]);\n\n const value = useMemo(() => register, [register]);\n\n return (\n <ChromeSuppressionContext.Provider value={value}>\n {children}\n </ChromeSuppressionContext.Provider>\n );\n}\n\nexport function useChromeSuppression(id: string, suppressed: boolean) {\n const register = useContext(ChromeSuppressionContext);\n\n useEffect(() => {\n if (!register) return;\n register(id, suppressed);\n return () => register(id, false);\n }, [id, register, suppressed]);\n}\n\nfunction updateSuppressedEntries(\n current: ReadonlySet<string>,\n id: string,\n suppressed: boolean,\n) {\n if (current.has(id) === suppressed) return current;\n const next = new Set(current);\n if (suppressed) next.add(id);\n else next.delete(id);\n return next;\n}\n","import type { ComponentProps } from \"react\";\nimport { clsx } from \"clsx\";\nimport { Button as ShadcnButton } from \"../internal/ui/button.js\";\nimport {\n buttonStyle,\n type ButtonSize,\n type ButtonVariant,\n} from \"../theme/derive.js\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\nimport {\n visualStateDataAttributes,\n type InteractionVisualState,\n} from \"../types/visual-state.js\";\n\ntype ShadcnButtonProps = ComponentProps<typeof ShadcnButton>;\n\nexport interface ThemedButtonProps\n extends Omit<ShadcnButtonProps, \"variant\" | \"size\">, InteractionVisualState {\n variant?: ButtonVariant;\n size?: ButtonSize;\n /** Renders the pressed/active visual treatment without changing variant. */\n pressed?: boolean;\n /** Render the in-flight loading state and disable activation. */\n loading?: boolean;\n}\n\nexport function ThemedButton({\n variant = \"primary\",\n size = \"md\",\n pressed = false,\n loading = false,\n eligible,\n selected,\n disabled,\n invalid,\n submitted,\n previewing,\n intentProgress,\n className,\n style,\n ...props\n}: ThemedButtonProps) {\n const theme = useTheme();\n const isDisabled = disabled || loading || submitted;\n const dataAttributes = visualStateDataAttributes({\n eligible,\n selected,\n disabled: isDisabled,\n invalid,\n submitted,\n previewing,\n intentProgress,\n });\n return (\n <ShadcnButton\n variant={toShadcnVariant(submitted ? \"submitted\" : variant)}\n size={toShadcnSize(size)}\n disabled={isDisabled}\n data-dreamboard-button\n data-dreamboard-button-variant={submitted ? \"submitted\" : variant}\n data-dreamboard-button-size={size}\n data-pressed={pressed ? \"true\" : undefined}\n data-loading={loading ? \"true\" : undefined}\n aria-busy={loading || undefined}\n aria-pressed={selected ? true : pressed ? true : undefined}\n aria-invalid={invalid || undefined}\n {...dataAttributes}\n className={clsx(\"font-sans\", className)}\n style={{\n ...buttonStyle(theme, {\n variant: submitted ? \"submitted\" : variant,\n size,\n disabled: isDisabled,\n pressed,\n }),\n ...style,\n }}\n {...props}\n />\n );\n}\n\nfunction toShadcnVariant(\n variant: ButtonVariant,\n): NonNullable<ShadcnButtonProps[\"variant\"]> {\n switch (variant) {\n case \"danger\":\n return \"destructive\";\n case \"ghost\":\n return \"ghost\";\n case \"secondary\":\n return \"secondary\";\n case \"primary\":\n case \"submitted\":\n case \"success\":\n case \"warning\":\n case \"info\":\n return \"default\";\n }\n}\n\nfunction toShadcnSize(\n size: ButtonSize,\n): NonNullable<ShadcnButtonProps[\"size\"]> {\n switch (size) {\n case \"sm\":\n return \"sm\";\n case \"md\":\n return \"default\";\n case \"lg\":\n return \"lg\";\n }\n}\n","import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cn } from \"./utils.js\";\n\nexport type ButtonVariant =\n | \"default\"\n | \"destructive\"\n | \"outline\"\n | \"secondary\"\n | \"ghost\"\n | \"link\";\n\nexport type ButtonSize = \"default\" | \"sm\" | \"lg\" | \"icon\";\n\nexport interface ButtonProps extends React.ComponentProps<\"button\"> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n asChild?: boolean;\n}\n\nconst variantClass: Record<ButtonVariant, string> = {\n default: \"border-slate-900 bg-white text-slate-950 hover:bg-slate-100\",\n destructive: \"border-red-900 bg-red-600 text-white hover:bg-red-700\",\n outline: \"border-slate-900 bg-transparent hover:bg-slate-100\",\n secondary: \"border-slate-700 bg-slate-100 text-slate-950 hover:bg-slate-200\",\n ghost: \"border-transparent bg-transparent hover:bg-slate-100\",\n link: \"border-transparent bg-transparent text-blue-700 underline-offset-4 hover:underline\",\n};\n\nconst sizeClass: Record<ButtonSize, string> = {\n default: \"h-10 px-4 py-2\",\n sm: \"h-9 px-3\",\n lg: \"h-11 px-8\",\n icon: \"size-10\",\n};\n\nexport function Button({\n className,\n variant = \"default\",\n size = \"default\",\n asChild = false,\n ...props\n}: ButtonProps) {\n const Comp = asChild ? Slot : \"button\";\n return (\n <Comp\n data-slot=\"button\"\n className={cn(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md border text-sm font-medium transition-colors outline-none disabled:pointer-events-none disabled:opacity-50\",\n \"focus-visible:ring-2 focus-visible:ring-slate-400 focus-visible:ring-offset-2\",\n variantClass[variant],\n sizeClass[size],\n className,\n )}\n {...props}\n />\n );\n}\n","import { clsx, type ClassValue } from \"clsx\";\n\nexport function cn(...inputs: ClassValue[]) {\n return clsx(inputs);\n}\n","import { useId, useState, type CSSProperties, type ReactNode } from \"react\";\nimport { useDrag } from \"@use-gesture/react\";\nimport {\n Drawer,\n DrawerContent,\n DrawerDescription,\n DrawerHeader,\n DrawerTitle,\n DrawerTrigger,\n} from \"./Drawer.js\";\nimport { useChromeSuppression } from \"./ChromeSuppressionContext.js\";\nimport { ThemedButton } from \"./ThemedButton.js\";\nimport { useThemeCssVars } from \"../theme/ThemeProvider.js\";\n\nexport type HandDockMode = \"inline\" | \"drawer\" | \"hidden\";\nexport type HandDockPlacement =\n | \"bottom-left\"\n | \"bottom-center\"\n | \"bottom-right\";\n\nexport interface HandDockToggleContext {\n label: string;\n count: number;\n open: boolean;\n}\n\nexport interface HandDockPresentation {\n /**\n * `inline` preserves the normal shell hand strip. `drawer` collapses the\n * zone behind a viewport-safe toggle. `hidden` suppresses the zone entirely.\n */\n mode?: HandDockMode;\n /** Initial drawer state. Defaults to closed. */\n defaultOpen?: boolean;\n /** Where the drawer toggle/tray docks in the viewport. */\n placement?: HandDockPlacement;\n /** Toggle label override. Receives card count and open state. */\n toggleLabel?: ReactNode | ((context: HandDockToggleContext) => ReactNode);\n /** Width of the opened tray. */\n maxWidth?: CSSProperties[\"maxWidth\"];\n /** Height of the opened tray before it scrolls. */\n maxHeight?: CSSProperties[\"maxHeight\"];\n /** Extra style escape hatch for the outer dock. */\n style?: CSSProperties;\n}\n\nexport interface HandDockProps {\n label: string;\n count: number;\n presentation?: HandDockPresentation;\n children: ReactNode;\n}\n\nconst DEFAULT_MAX_WIDTH = \"min(28rem, calc(100vw - 24px))\";\nconst DEFAULT_MAX_HEIGHT = \"min(65vh, calc(100vh - 96px))\";\n\nfunction placementStyle(placement: HandDockPlacement): CSSProperties {\n const base: CSSProperties = {\n position: \"fixed\",\n bottom: \"calc(12px + env(safe-area-inset-bottom, 0px))\",\n zIndex: 900,\n };\n switch (placement) {\n case \"bottom-center\":\n return {\n ...base,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n };\n case \"bottom-right\":\n return {\n ...base,\n right: \"calc(12px + env(safe-area-inset-right, 0px))\",\n };\n case \"bottom-left\":\n default:\n return {\n ...base,\n left: \"calc(12px + env(safe-area-inset-left, 0px))\",\n };\n }\n}\n\nfunction triggerAlignment(\n placement: HandDockPlacement,\n): CSSProperties[\"alignSelf\"] {\n switch (placement) {\n case \"bottom-center\":\n return \"center\";\n case \"bottom-right\":\n return \"flex-end\";\n case \"bottom-left\":\n default:\n return \"flex-start\";\n }\n}\n\nfunction renderToggleLabel(\n label: string,\n count: number,\n open: boolean,\n override: HandDockPresentation[\"toggleLabel\"],\n) {\n if (typeof override === \"function\") return override({ label, count, open });\n if (override !== undefined) return override;\n return `${label} (${count})`;\n}\n\nexport function HandDock({\n label,\n count,\n presentation,\n children,\n}: HandDockProps) {\n const mode = presentation?.mode ?? \"inline\";\n const [open, setOpen] = useState(presentation?.defaultOpen ?? false);\n const contentId = useId();\n const themeCssVars = useThemeCssVars();\n useChromeSuppression(contentId, mode === \"drawer\" && open);\n\n // Swipe-up-to-open gesture on the dock handle strip.\n // The hook must be called unconditionally (React rules); we apply the\n // bindings only in drawer mode when the drawer is closed.\n const bindDrag = useDrag(\n ({ movement: [, my], velocity: [, vy], last }) => {\n // Require: upward movement > 40 px at > 0.3 px/ms velocity on release\n if (last && my < -40 && vy > 0.3) {\n setOpen(true);\n }\n },\n { axis: \"y\", filterTaps: true },\n );\n\n if (mode === \"hidden\") return null;\n if (mode === \"inline\") return <>{children}</>;\n\n const placement = presentation?.placement ?? \"bottom-left\";\n const toggleLabel = renderToggleLabel(\n label,\n count,\n open,\n presentation?.toggleLabel,\n );\n\n const fallbackContentStyle: CSSProperties = {\n maxHeight: presentation?.maxHeight ?? DEFAULT_MAX_HEIGHT,\n overflow: \"auto\",\n padding: 12,\n pointerEvents: \"auto\",\n };\n const triggerStyle: CSSProperties = {\n alignSelf: triggerAlignment(placement),\n boxShadow: \"0 10px 28px rgba(15, 23, 42, 0.22)\",\n pointerEvents: \"auto\",\n visibility: open ? \"hidden\" : \"visible\",\n };\n const canUsePortal = typeof document !== \"undefined\";\n const serverOpenContent =\n !canUsePortal && open ? (\n <div\n id={contentId}\n role=\"region\"\n aria-label={label}\n style={fallbackContentStyle}\n >\n {children}\n </div>\n ) : null;\n\n return (\n <Drawer open={open} onOpenChange={setOpen} direction=\"bottom\">\n <div\n data-hand-dock={label}\n data-state={open ? \"open\" : \"closed\"}\n style={{\n ...placementStyle(placement),\n display: \"flex\",\n maxWidth: presentation?.maxWidth ?? DEFAULT_MAX_WIDTH,\n width: presentation?.maxWidth ?? DEFAULT_MAX_WIDTH,\n flexDirection: \"column\",\n alignItems: \"stretch\",\n gap: 8,\n pointerEvents: \"none\",\n ...presentation?.style,\n }}\n >\n {serverOpenContent}\n {/* Drag-handle strip — visible only when drawer is closed.\n Provides a touch target for the swipe-up-to-open gesture and a\n visual affordance matching the standard mobile bottom-sheet pattern. */}\n {!open && (\n <div\n {...bindDrag()}\n aria-hidden\n role=\"presentation\"\n style={{\n alignSelf: triggerAlignment(placement),\n padding: \"8px 16px 4px\",\n cursor: \"grab\",\n touchAction: \"none\",\n pointerEvents: \"auto\",\n display: \"flex\",\n justifyContent: \"center\",\n }}\n >\n <div\n style={{\n width: 36,\n height: 4,\n borderRadius: 2,\n background: \"rgba(15, 23, 42, 0.25)\",\n }}\n />\n </div>\n )}\n <DrawerTrigger asChild>\n <ThemedButton\n type=\"button\"\n variant=\"secondary\"\n size=\"sm\"\n data-state={open ? \"open\" : \"closed\"}\n aria-expanded={open}\n aria-controls={open ? contentId : undefined}\n className=\"rounded-full\"\n style={triggerStyle}\n >\n {toggleLabel}\n </ThemedButton>\n </DrawerTrigger>\n </div>\n {canUsePortal ? (\n <DrawerContent\n id={contentId}\n aria-describedby={undefined}\n className=\"border-border bg-background/95 shadow-2xl backdrop-blur supports-[backdrop-filter]:bg-background/90\"\n style={{\n ...themeCssVars,\n position: \"fixed\",\n right: 0,\n bottom: 0,\n left: 0,\n zIndex: 50,\n display: \"flex\",\n maxHeight: \"80vh\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n borderTop: \"1px solid var(--border, #cbd5e1)\",\n borderTopLeftRadius: 16,\n borderTopRightRadius: 16,\n background: \"var(--background, rgba(255, 255, 255, 0.96))\",\n color: \"var(--foreground, #0f172a)\",\n fontFamily: \"var(--font-sans)\",\n boxShadow: \"0 -18px 48px rgba(15, 23, 42, 0.22)\",\n backdropFilter: \"blur(8px)\",\n }}\n >\n <DrawerHeader\n className=\"border-border border-b px-4 pb-3 pt-3 text-left\"\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 4,\n borderBottom: \"1px solid var(--border, #e2e8f0)\",\n padding: \"12px 16px\",\n textAlign: \"left\",\n }}\n >\n <DrawerTitle\n className=\"text-base\"\n style={{ fontSize: 16, fontWeight: 600, lineHeight: 1.25 }}\n >\n {label}\n </DrawerTitle>\n <DrawerDescription>\n {count} card{count === 1 ? \"\" : \"s\"} available.\n </DrawerDescription>\n </DrawerHeader>\n <div\n role=\"region\"\n aria-label={label}\n style={{\n maxHeight: presentation?.maxHeight ?? DEFAULT_MAX_HEIGHT,\n maxWidth: presentation?.maxWidth ?? DEFAULT_MAX_WIDTH,\n width: \"100%\",\n margin: \"0 auto\",\n overflow: \"auto\",\n padding:\n \"12px 16px calc(16px + env(safe-area-inset-bottom, 0px))\",\n boxSizing: \"border-box\",\n }}\n className=\"mx-auto w-full overflow-y-auto px-4 pb-[calc(1rem+env(safe-area-inset-bottom,0px))] pt-3\"\n >\n {children}\n </div>\n </DrawerContent>\n ) : null}\n </Drawer>\n );\n}\n","/**\n * Player hand with adaptive overlap, automatic drawer fallback, and keyboard navigation.\n * For full control, use the `useHandLayout` hook directly.\n */\n\nimport { clsx } from \"clsx\";\nimport { useCallback, useState } from \"react\";\nimport {\n useHandLayout,\n type CardSize,\n type HandLayout,\n} from \"../hooks/useHandLayout.js\";\nimport { CardFace, type ViewCard } from \"./Card.js\";\nimport { HandDock } from \"./HandDock.js\";\nimport type { ReactNode } from \"react\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\n\nexport interface HandCardRenderProps<CardData extends ViewCard = ViewCard> {\n card: CardData;\n index: number;\n isHovered: boolean;\n isSelected: boolean;\n x: number;\n y: number;\n zIndex: number;\n cardDimensions: { width: number; height: number };\n}\n\nexport interface HandDrawerRenderProps<CardData extends ViewCard = ViewCard> {\n cards: readonly CardData[];\n selectedIds: readonly string[];\n cardCount: number;\n selectedCount: number;\n disabled: boolean;\n cardDimensions: { width: number; height: number };\n}\n\nexport interface HandEmptyRenderProps {\n layout: HandLayout;\n}\n\nexport interface HandContainerRenderProps {\n totalWidth: number;\n totalHeight: number;\n cardDimensions: { width: number; height: number };\n children: ReactNode;\n onMouseMove: (e: React.MouseEvent<HTMLDivElement>) => void;\n onMouseLeave: () => void;\n}\n\nexport interface HandProps<CardData extends ViewCard = ViewCard> {\n cards: readonly CardData[];\n selectedIds?: readonly string[];\n disabled?: boolean;\n cardSize?: CardSize;\n layout?: HandLayout;\n \"aria-label\"?: string;\n /**\n * Called when a card is clicked. Wired into the default `renderCard`;\n * ignored when the caller supplies a custom `renderCard`.\n */\n onCardClick?: (cardId: string) => void;\n /** Per-card content renderer forwarded to the default `<CardFace>`. */\n renderCardContent?: (card: CardData) => ReactNode;\n /** Defaults to a positioned `<CardFace>` honouring click/selection state. */\n renderCard?: (props: HandCardRenderProps<CardData>) => ReactNode;\n /**\n * Custom drawer fallback for large hands (when `useHandLayout` switches\n * to drawer mode). When omitted, `Hand` renders a `HandDock` bottom drawer\n * automatically.\n */\n renderDrawer?: (props: HandDrawerRenderProps<CardData>) => ReactNode;\n /** Defaults to a subtle \"No cards in hand\" placeholder. */\n renderEmpty?: (props: HandEmptyRenderProps) => ReactNode;\n renderContainer?: (props: HandContainerRenderProps) => ReactNode;\n className?: string;\n}\n\nconst EMPTY_SELECTED_IDS: readonly string[] = [];\n\n// DefaultDrawer is intentionally omitted — when no `renderDrawer` prop is\n// provided, `Hand` automatically renders a `HandDock` bottom drawer instead\n// (see the drawer-mode branch in the `Hand` component below).\n// This gives large hands a proper mobile-friendly expandable UI for free.\n\nfunction DefaultEmpty(): ReactNode {\n const theme = useTheme();\n return (\n <span\n style={{\n fontFamily: theme.typography.fontFamily.body,\n fontSize: theme.typography.fontSize.xs,\n color: theme.semantic.text.disabled,\n }}\n >\n No cards in hand\n </span>\n );\n}\n\ninterface ClickableCardFaceProps<CardData extends ViewCard = ViewCard> {\n card: CardData;\n selected?: boolean;\n disabled?: boolean;\n size?: CardSize;\n onCardClick?: (cardId: CardData[\"id\"]) => void;\n renderContent?: (card: CardData) => ReactNode;\n}\n\nfunction ClickableCardFace<CardData extends ViewCard = ViewCard>({\n card,\n selected,\n disabled,\n size,\n onCardClick,\n renderContent,\n}: ClickableCardFaceProps<CardData>) {\n const interactive = !disabled && Boolean(onCardClick);\n const handleActivate = () => {\n if (!interactive) return;\n onCardClick?.(card.id);\n };\n\n return (\n <button\n type=\"button\"\n disabled={disabled}\n aria-pressed={selected ? true : undefined}\n aria-disabled={disabled || undefined}\n tabIndex={disabled ? -1 : 0}\n onClick={handleActivate}\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n handleActivate();\n }\n }}\n className={clsx(\n \"border-0 bg-transparent p-0\",\n \"focus-visible:outline-none\",\n interactive ? \"cursor-pointer\" : \"cursor-default\",\n )}\n style={{ all: \"unset\" }}\n >\n <CardFace\n card={card}\n selected={selected}\n disabled={disabled}\n size={size}\n renderContent={renderContent}\n />\n </button>\n );\n}\n\n/**\n * Hand component with customizable rendering via render props.\n *\n * `renderCard`, `renderDrawer`, and `renderEmpty` are all optional — the\n * defaults render the built-in `<CardFace>` with the supplied `onCardClick` /\n * `renderCardContent`, a compact drawer fallback on small screens, and a\n * muted empty placeholder. Override any of them when you need a different\n * visual treatment.\n *\n * For complete control over layout and interactions, use the\n * `useHandLayout` hook directly.\n *\n * @example Zero-config\n * ```tsx\n * <Hand cards={cards} onCardClick={(id) => play(id)} />\n * ```\n *\n * @example Custom card content\n * ```tsx\n * <Hand\n * cards={cards}\n * onCardClick={(id) => play(id)}\n * renderCardContent={(card) => <DevCardFace card={card} />}\n * />\n * ```\n */\nexport function Hand<CardData extends ViewCard = ViewCard>({\n cards,\n selectedIds = EMPTY_SELECTED_IDS,\n disabled = false,\n cardSize = \"md\",\n layout = \"overlap\",\n \"aria-label\": ariaLabel = \"Your hand\",\n onCardClick,\n renderCardContent,\n renderCard,\n renderDrawer,\n renderEmpty,\n renderContainer,\n className,\n}: HandProps<CardData>) {\n const defaultRenderCard = useCallback(\n (props: HandCardRenderProps<CardData>): ReactNode => (\n <div\n key={props.card.id}\n className=\"absolute bottom-0 transition-all duration-150 ease-out\"\n style={{\n left: props.x,\n zIndex: props.zIndex,\n transform: `translateY(${props.y}px)`,\n }}\n >\n <ClickableCardFace\n card={props.card}\n selected={props.isSelected}\n disabled={disabled}\n size={cardSize}\n onCardClick={onCardClick}\n renderContent={renderCardContent}\n />\n </div>\n ),\n [cardSize, disabled, onCardClick, renderCardContent],\n );\n const effectiveRenderCard = renderCard ?? defaultRenderCard;\n const effectiveRenderEmpty = renderEmpty ?? DefaultEmpty;\n const cardCount = cards.length;\n const [focusedIndex, setFocusedIndex] = useState(-1);\n\n const {\n containerRef,\n cardsContainerRef,\n totalWidth,\n useDrawerMode,\n cardDimensions,\n constants,\n hoveredIndex,\n handleMouseMove,\n handleMouseLeave,\n handleTouchMove,\n handleTouchEnd,\n getCardPosition,\n } = useHandLayout({\n cardCount,\n cardSize,\n layout,\n });\n\n const selectedCount = cards.filter((c) => selectedIds.includes(c.id)).length;\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (cardCount === 0) return;\n switch (e.key) {\n case \"ArrowLeft\":\n e.preventDefault();\n setFocusedIndex((prev) => (prev <= 0 ? cardCount - 1 : prev - 1));\n break;\n case \"ArrowRight\":\n e.preventDefault();\n setFocusedIndex((prev) => (prev >= cardCount - 1 ? 0 : prev + 1));\n break;\n case \"Home\":\n e.preventDefault();\n setFocusedIndex(0);\n break;\n case \"End\":\n e.preventDefault();\n setFocusedIndex(cardCount - 1);\n break;\n }\n },\n [cardCount],\n );\n\n // Drawer mode — too many cards to show inline.\n // If the caller provides a custom `renderDrawer`, delegate entirely to it.\n // Otherwise render a `HandDock` bottom drawer so the hand is always\n // reachable on mobile without any extra author wiring.\n if (useDrawerMode && layout === \"overlap\" && cardCount > 0) {\n if (renderDrawer) {\n return (\n <div\n ref={containerRef}\n className={clsx(\n \"relative w-full flex items-center justify-center py-4\",\n className,\n )}\n role=\"group\"\n aria-label={`${ariaLabel} - ${cardCount} card${cardCount !== 1 ? \"s\" : \"\"}`}\n >\n {renderDrawer({\n cards,\n selectedIds,\n cardCount,\n selectedCount,\n disabled,\n cardDimensions,\n })}\n </div>\n );\n }\n\n // Default: HandDock bottom drawer with the cards in a wrap grid.\n // The outer div is kept for the containerRef measurement; HandDock itself\n // is fixed-position and renders outside normal flow.\n return (\n <div\n ref={containerRef}\n className={clsx(\n \"relative w-full flex items-center justify-center\",\n className,\n )}\n role=\"group\"\n aria-label={`${ariaLabel} - ${cardCount} card${cardCount !== 1 ? \"s\" : \"\"}`}\n >\n <HandDock\n label={ariaLabel}\n count={cardCount}\n presentation={{ mode: \"drawer\", placement: \"bottom-center\" }}\n >\n <div\n style={{\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: 8,\n padding: \"4px 0 8px\",\n justifyContent: \"center\",\n }}\n >\n {cards.map((card) => (\n <ClickableCardFace\n key={card.id}\n card={card}\n selected={selectedIds.includes(card.id)}\n disabled={disabled}\n size={cardSize}\n onCardClick={onCardClick}\n renderContent={renderCardContent}\n />\n ))}\n </div>\n </HandDock>\n </div>\n );\n }\n\n // Empty hand\n if (cardCount === 0) {\n return (\n <div\n ref={containerRef}\n className={clsx(\n \"relative w-full flex items-end justify-center py-4 sm:py-6\",\n className,\n )}\n role=\"group\"\n aria-label={`${ariaLabel} - empty`}\n >\n {effectiveRenderEmpty({ layout })}\n </div>\n );\n }\n\n const renderedCards = cards.map((card, index) => {\n const isSelected = selectedIds.includes(card.id);\n const isFocused = focusedIndex === index;\n const isHovered = hoveredIndex === index || isFocused;\n const position = getCardPosition(index, isHovered, isSelected);\n\n return effectiveRenderCard({\n card,\n index,\n isHovered,\n isSelected,\n x: position.x,\n y: position.y,\n zIndex: position.zIndex,\n cardDimensions,\n });\n });\n\n if (layout === \"spread\") {\n return (\n <div\n ref={containerRef}\n className={clsx(\n \"relative w-full flex items-end justify-center py-4 sm:py-6\",\n className,\n )}\n role=\"group\"\n aria-label={`${ariaLabel} - ${cardCount} card${cardCount !== 1 ? \"s\" : \"\"}`}\n tabIndex={0}\n onKeyDown={handleKeyDown}\n onBlur={() => setFocusedIndex(-1)}\n >\n <div className=\"flex gap-1 justify-center flex-wrap\">\n {renderedCards}\n </div>\n </div>\n );\n }\n\n // Overlap/Stack layout\n const totalHeight = cardDimensions.height + constants.hoverLift + 8;\n\n const containerProps: HandContainerRenderProps = {\n totalWidth,\n totalHeight,\n cardDimensions,\n children: renderedCards,\n onMouseMove: handleMouseMove,\n onMouseLeave: handleMouseLeave,\n };\n\n // Allow custom container rendering\n if (renderContainer) {\n return (\n <div\n ref={containerRef}\n className={clsx(\n \"relative w-full flex items-end justify-center py-4 sm:py-6 overflow-visible\",\n className,\n )}\n role=\"group\"\n aria-label={`${ariaLabel} - ${cardCount} card${cardCount !== 1 ? \"s\" : \"\"}`}\n >\n {renderContainer(containerProps)}\n </div>\n );\n }\n\n return (\n <div\n ref={containerRef}\n className={clsx(\n \"relative w-full flex items-end justify-center py-4 sm:py-6 overflow-visible\",\n className,\n )}\n role=\"group\"\n aria-label={`${ariaLabel} - ${cardCount} card${cardCount !== 1 ? \"s\" : \"\"}`}\n tabIndex={0}\n onKeyDown={handleKeyDown}\n onBlur={() => setFocusedIndex(-1)}\n >\n <div\n ref={cardsContainerRef}\n className=\"relative\"\n style={{\n width: layout === \"overlap\" ? totalWidth : undefined,\n height: totalHeight,\n }}\n onMouseMove={handleMouseMove}\n onMouseLeave={handleMouseLeave}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n >\n {renderedCards}\n </div>\n </div>\n );\n}\n\n// Re-export types and hook for users who want full control\nexport { useHandLayout } from \"../hooks/useHandLayout.js\";\nexport type {\n UseHandLayoutOptions,\n UseHandLayoutReturn,\n CardPositionProps,\n CardSize,\n HandLayout,\n} from \"../hooks/useHandLayout.js\";\nexport type { ViewCard } from \"./Card.js\";\n","import { useState, useRef, useEffect, useMemo, useCallback } from \"react\";\nimport type { RefObject } from \"react\";\n\n// Card dimensions used for fan offset and total-width calculations.\n// These must match the rendered widths from `Card.tsx`'s `sizeClasses`\n// at the `sm` Tailwind breakpoint (≥640px), since that's the size\n// player decks render at on virtually all gameplay viewports. Older\n// values here were ~30% smaller than what `Card` actually paints,\n// which caused cards to overlap by 30+ pixels even when there was\n// plenty of horizontal room in the hand container.\nconst CARD_DIMENSIONS = {\n sm: { width: 80, height: 112 },\n md: { width: 96, height: 144 },\n lg: { width: 128, height: 192 },\n} as const;\n\nconst MIN_VISIBLE_PORTION = 16; // minimum visible pixels per card when overlapping\nconst HOVER_LIFT = 20; // pixels to lift on hover\nconst SELECTED_LIFT = 8; // pixels to lift when selected\nconst DRAWER_THRESHOLD_RATIO = 0.3; // if overlap is less than 30% of card width, use drawer\n\nexport type CardSize = \"sm\" | \"md\" | \"lg\";\nexport type HandLayout = \"spread\" | \"stack\" | \"overlap\";\n\nexport interface CardPositionProps {\n /** X position (left offset) */\n x: number;\n /** Y position (vertical offset for hover/selected) */\n y: number;\n /** Z-index for layering */\n zIndex: number;\n /** CSS transform origin */\n transformOrigin: string;\n}\n\nexport interface UseHandLayoutOptions {\n /** Number of cards in the hand */\n cardCount: number;\n /** Card size variant */\n cardSize?: CardSize;\n /** Layout style */\n layout?: HandLayout;\n /** Padding to subtract from container width */\n containerPadding?: number;\n}\n\nexport interface UseHandLayoutReturn {\n /** Ref to attach to the container element */\n containerRef: RefObject<HTMLDivElement | null>;\n /** Ref to attach to the cards container element (for mouse/touch tracking) */\n cardsContainerRef: RefObject<HTMLDivElement | null>;\n /** Measured container width */\n containerWidth: number;\n /** Calculated offset between cards */\n cardOffset: number;\n /** Total width of all cards */\n totalWidth: number;\n /** Whether drawer mode should be used */\n useDrawerMode: boolean;\n /** Card dimensions for the current size */\n cardDimensions: { width: number; height: number };\n /** Constants for positioning */\n constants: {\n hoverLift: number;\n selectedLift: number;\n };\n /** Currently hovered card index */\n hoveredIndex: number | null;\n /** Mouse move handler for the cards container */\n handleMouseMove: (e: React.MouseEvent<HTMLDivElement>) => void;\n /** Mouse leave handler for the cards container */\n handleMouseLeave: () => void;\n /** Touch move handler for the cards container (mirrors mouse hover lift on touch) */\n handleTouchMove: (e: React.TouchEvent<HTMLDivElement>) => void;\n /** Touch end handler for the cards container */\n handleTouchEnd: () => void;\n /** Get position props for a card at the given index */\n getCardPosition: (\n index: number,\n isHovered: boolean,\n isSelected: boolean,\n ) => CardPositionProps;\n}\n\n/**\n * Hook for managing hand layout calculations and interactions.\n *\n * Provides container measurement, overlap calculations, drawer mode detection,\n * and hover state management for card hand displays.\n *\n * @example\n * ```tsx\n * function MyHand({ cards, selectedIds }) {\n * const {\n * containerRef,\n * cardsContainerRef,\n * totalWidth,\n * useDrawerMode,\n * cardDimensions,\n * hoveredIndex,\n * handleMouseMove,\n * handleMouseLeave,\n * getCardPosition,\n * constants,\n * } = useHandLayout({\n * cardCount: cards.length,\n * cardSize: \"md\",\n * layout: \"overlap\",\n * });\n *\n * if (useDrawerMode) {\n * return <MyDrawerUI cards={cards} />;\n * }\n *\n * return (\n * <div ref={containerRef}>\n * <div\n * ref={cardsContainerRef}\n * style={{ width: totalWidth, height: cardDimensions.height + constants.hoverLift }}\n * onMouseMove={handleMouseMove}\n * onMouseLeave={handleMouseLeave}\n * >\n * {cards.map((card, index) => {\n * const isHovered = hoveredIndex === index;\n * const isSelected = selectedIds.includes(card.id);\n * const position = getCardPosition(index, isHovered, isSelected);\n *\n * return (\n * <div\n * key={card.id}\n * style={{\n * position: \"absolute\",\n * left: position.x,\n * transform: `translateY(${position.y}px)`,\n * zIndex: position.zIndex,\n * }}\n * >\n * <MyCard card={card} />\n * </div>\n * );\n * })}\n * </div>\n * </div>\n * );\n * }\n * ```\n */\nexport function useHandLayout({\n cardCount,\n cardSize = \"md\",\n layout = \"overlap\",\n containerPadding = 32,\n}: UseHandLayoutOptions): UseHandLayoutReturn {\n const containerRef = useRef<HTMLDivElement>(null);\n const cardsContainerRef = useRef<HTMLDivElement>(null);\n const [containerWidth, setContainerWidth] = useState(0);\n const [hoveredIndex, setHoveredIndex] = useState<number | null>(null);\n\n const cardDimensions = CARD_DIMENSIONS[cardSize];\n\n // Measure container width with ResizeObserver\n useEffect(() => {\n const updateWidth = () => {\n if (containerRef.current) {\n setContainerWidth(containerRef.current.clientWidth - containerPadding);\n }\n };\n\n updateWidth();\n const observer = new ResizeObserver(updateWidth);\n if (containerRef.current) {\n observer.observe(containerRef.current);\n }\n\n return () => observer.disconnect();\n }, [containerPadding]);\n\n // Calculate adaptive overlap based on container width and card count\n const { cardOffset, totalWidth, useDrawerMode } = useMemo(() => {\n if (layout !== \"overlap\") {\n return {\n cardOffset: cardDimensions.width,\n totalWidth: 0,\n useDrawerMode: false,\n };\n }\n\n if (cardCount === 0) {\n return { cardOffset: 0, totalWidth: 0, useDrawerMode: false };\n }\n if (cardCount === 1) {\n return {\n cardOffset: cardDimensions.width,\n totalWidth: cardDimensions.width,\n useDrawerMode: false,\n };\n }\n\n // Available width for overlap distribution\n const availableWidth = containerWidth;\n if (availableWidth <= 0) {\n return {\n cardOffset: cardDimensions.width,\n totalWidth: cardDimensions.width * cardCount,\n useDrawerMode: false,\n };\n }\n\n // Calculate the offset needed to fit all cards\n // Total width = cardWidth + (cardCount - 1) * offset\n // So offset = (availableWidth - cardWidth) / (cardCount - 1)\n const idealOffset =\n (availableWidth - cardDimensions.width) / (cardCount - 1);\n\n // Clamp offset between minimum visible portion and full card width\n const clampedOffset = Math.max(\n MIN_VISIBLE_PORTION,\n Math.min(cardDimensions.width, idealOffset),\n );\n\n // Calculate total width with this offset\n const width = cardDimensions.width + (cardCount - 1) * clampedOffset;\n\n // Determine if we should use drawer mode\n // Use drawer if cards are overlapping too much (less than threshold of card visible)\n const visiblePortion = clampedOffset / cardDimensions.width;\n const shouldUseDrawer =\n visiblePortion < DRAWER_THRESHOLD_RATIO && cardCount > 2;\n\n return {\n cardOffset: clampedOffset,\n totalWidth: width,\n useDrawerMode: shouldUseDrawer,\n };\n }, [cardCount, containerWidth, layout, cardDimensions.width]);\n\n // Shared logic: map a clientX coordinate to the card index it's over.\n // Used by both mouse and touch move handlers.\n const getHoveredIndexFromClientX = useCallback(\n (clientX: number): number | null => {\n if (!cardsContainerRef.current) return null;\n const rect = cardsContainerRef.current.getBoundingClientRect();\n const mouseX = clientX - rect.left;\n\n let newHoveredIndex: number | null = null;\n\n // Find which card the pointer is over based on X position.\n // Iterate right-to-left so cards on top (higher z-index) win.\n for (let i = cardCount - 1; i >= 0; i--) {\n const cardLeft = i * cardOffset;\n const cardRight =\n i === cardCount - 1\n ? cardLeft + cardDimensions.width\n : (i + 1) * cardOffset;\n\n if (mouseX >= cardLeft && mouseX < cardRight) {\n newHoveredIndex = i;\n break;\n }\n }\n\n // Check if pointer is in the rightmost card's full area\n if (newHoveredIndex === null && mouseX >= 0 && mouseX < totalWidth) {\n const lastCardLeft = (cardCount - 1) * cardOffset;\n if (mouseX >= lastCardLeft) {\n newHoveredIndex = cardCount - 1;\n }\n }\n\n return newHoveredIndex;\n },\n [cardCount, cardOffset, totalWidth, cardDimensions.width],\n );\n\n // Calculate hovered card index based on mouse X position.\n // This allows hovering on adjacent cards even when one is popped up.\n const handleMouseMove = useCallback(\n (e: React.MouseEvent<HTMLDivElement>) => {\n if (cardCount === 0 || layout === \"spread\" || layout === \"stack\") {\n return;\n }\n setHoveredIndex(getHoveredIndexFromClientX(e.clientX));\n },\n [cardCount, layout, getHoveredIndexFromClientX],\n );\n\n const handleMouseLeave = useCallback(() => {\n setHoveredIndex(null);\n }, []);\n\n // Touch equivalents — mirror the hover-lift feedback on touch devices so\n // the active card is clearly highlighted while the finger is moving.\n const handleTouchMove = useCallback(\n (e: React.TouchEvent<HTMLDivElement>) => {\n if (cardCount === 0 || layout === \"spread\" || layout === \"stack\") {\n return;\n }\n const touch = e.touches[0];\n if (!touch) return;\n setHoveredIndex(getHoveredIndexFromClientX(touch.clientX));\n },\n [cardCount, layout, getHoveredIndexFromClientX],\n );\n\n const handleTouchEnd = useCallback(() => {\n setHoveredIndex(null);\n }, []);\n\n // Calculate z-index: hovered > selected > position\n const getZIndex = useCallback(\n (index: number, isHovered: boolean, isSelected: boolean) => {\n if (isHovered) return 200;\n if (isSelected) return 100 + index;\n return index;\n },\n [],\n );\n\n // Get card position props for different layouts\n const getCardPosition = useCallback(\n (\n index: number,\n isHovered: boolean,\n isSelected: boolean,\n ): CardPositionProps => {\n const zIndex = getZIndex(index, isHovered, isSelected);\n\n if (layout === \"stack\") {\n return {\n x: index * 4,\n y: 0,\n zIndex,\n transformOrigin: \"bottom center\",\n };\n }\n\n if (layout === \"spread\") {\n return {\n x: 0,\n y: 0,\n zIndex,\n transformOrigin: \"bottom center\",\n };\n }\n\n // Overlap layout (default) - simple horizontal overlap with lift on hover/select\n const yOffset = isHovered ? -HOVER_LIFT : isSelected ? -SELECTED_LIFT : 0;\n\n return {\n x: index * cardOffset,\n y: yOffset,\n zIndex,\n transformOrigin: \"bottom center\",\n };\n },\n [layout, cardOffset, getZIndex],\n );\n\n return {\n containerRef,\n cardsContainerRef,\n containerWidth,\n cardOffset,\n totalWidth,\n useDrawerMode,\n cardDimensions,\n constants: {\n hoverLift: HOVER_LIFT,\n selectedLift: SELECTED_LIFT,\n },\n hoveredIndex,\n handleMouseMove,\n handleMouseLeave,\n handleTouchMove,\n handleTouchEnd,\n getCardPosition,\n };\n}\n","/**\n * Controlled staging zone — a fixed row of card slots for a many-select\n * collection (e.g. \"the cards you are passing\"). Filled slots render a\n * caller-provided card and are tappable to remove it; the remaining slots\n * render a themed empty placeholder so the zone is always visible (and always\n * an obvious target) even before anything is staged.\n *\n * Purely presentational: it does not read or mutate any Dreamboard draft. A\n * runtime adapter feeds it the staged cards plus an `onRemove` that toggles the\n * card back out of the collection. In a later slice this same surface becomes\n * the drop target for drag-to-stage.\n */\n\nimport { clsx } from \"clsx\";\nimport type { ReactNode } from \"react\";\nimport type { ViewCard } from \"../../types/index.js\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\n\nexport interface StagingZoneProps<CardData extends ViewCard = ViewCard> {\n /** Cards currently staged, in order. */\n cards: readonly CardData[];\n /** Total number of slots to render (e.g. the collector's selection max). */\n slotCount: number;\n /** Card size; empty-slot dimensions match the SDK `CardFace` sizes. */\n size?: \"sm\" | \"md\" | \"lg\";\n /** Visual for a staged card (typically a `CardFace`). */\n renderCard: (card: CardData) => ReactNode;\n /** Fires when a staged card is activated — remove it from the collection. */\n onRemove?: (cardId: string) => void;\n /** Custom empty-slot content. Defaults to an empty dashed placeholder. */\n renderEmptySlot?: (index: number) => ReactNode;\n /** Optional heading rendered above the slots. */\n label?: ReactNode;\n /** Accessible label for the region. */\n \"aria-label\"?: string;\n className?: string;\n}\n\n// Match `CardFace`'s `sizeClasses` so empty slots line up with staged cards.\nconst SLOT_SIZE_CLASS: Record<\"sm\" | \"md\" | \"lg\", string> = {\n sm: \"w-16 h-24 sm:w-20 sm:h-28\",\n md: \"w-20 h-32 sm:w-24 sm:h-36\",\n lg: \"w-24 h-36 sm:w-32 sm:h-48\",\n};\n\nexport function StagingZone<CardData extends ViewCard = ViewCard>({\n cards,\n slotCount,\n size = \"sm\",\n renderCard,\n onRemove,\n renderEmptySlot,\n label,\n \"aria-label\": ariaLabel = \"Staged cards\",\n className,\n}: StagingZoneProps<CardData>) {\n const theme = useTheme();\n const total = Math.max(0, slotCount, cards.length);\n const slotClass = SLOT_SIZE_CLASS[size];\n const interactive = Boolean(onRemove);\n\n return (\n <div\n data-dreamboard-staging-zone=\"\"\n data-staged-count={cards.length}\n role=\"group\"\n aria-label={ariaLabel}\n className={clsx(\n \"flex flex-col items-center gap-2 rounded-2xl px-4 py-3\",\n className,\n )}\n style={{\n background: theme.semantic.surface.inset,\n border: `2px solid ${theme.semantic.border.subtle}`,\n }}\n >\n {label != null ? (\n <span\n className=\"text-[11px] font-bold uppercase tracking-[0.12em]\"\n style={{ color: theme.semantic.text.muted }}\n >\n {label}\n </span>\n ) : null}\n <div className=\"flex items-end justify-center gap-2\">\n {Array.from({ length: total }, (_, index) => {\n const card = cards[index];\n if (!card) {\n return (\n <div\n key={`empty-${index}`}\n data-dreamboard-staging-slot=\"empty\"\n aria-hidden\n className={clsx(\n \"flex shrink-0 items-center justify-center rounded-xl\",\n slotClass,\n )}\n style={{\n border: `2px dashed ${theme.semantic.border.subtle}`,\n color: theme.semantic.text.disabled,\n }}\n >\n {renderEmptySlot ? renderEmptySlot(index) : null}\n </div>\n );\n }\n const cardId = card.id as string;\n return (\n <button\n key={cardId}\n type=\"button\"\n data-dreamboard-staging-slot=\"filled\"\n data-card-id={cardId}\n disabled={!interactive}\n aria-label={\n interactive ? `Remove ${card.name ?? cardId}` : undefined\n }\n onClick={interactive ? () => onRemove?.(cardId) : undefined}\n className={clsx(\n \"relative shrink-0 appearance-none border-0 bg-transparent p-0 m-0\",\n \"transition-transform focus-visible:outline-none\",\n interactive\n ? \"cursor-pointer hover:-translate-y-1\"\n : \"cursor-default\",\n )}\n >\n {renderCard(card)}\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n","/**\n * Controlled drag-to-target surface for the SDK hand and drop-target views.\n *\n * `CardDragSurface` is the single owner of:\n *\n * - the drag-lifecycle phase (`idle`/`inspecting`/`dragging`/`settling`/\n * `returning`)\n * - the registry of drop targets, including their eligibility\n * - all committed `CardIntent` emission (`activate`, `previewStart`,\n * `previewEnd`, and `drop`)\n * - the lifted-card overlay, settle/snap-back animation and live\n * announcement\n *\n * `CardDropTargetView` is a generic controlled drop-target wrapper. It\n * registers the underlying DOM element (and its eligible/disabled state) so\n * the lifted pointer can be matched without exposing geometry to the\n * caller. Its registration is stable: only the `targetId` triggers register/\n * unregister; eligibility and label changes flow through `updateTarget`.\n *\n * `HandView` (and the hook it uses) drives this surface through the\n * controller exposed by `useCardDragSurface()`. Pointer events come from\n * `HandPointerEngine`'s lift callbacks. Keyboard pickup, target traversal\n * and Escape are handled here so that the drag-lifecycle has exactly one\n * authoritative owner.\n */\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type KeyboardEvent,\n type ReactNode,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { clsx } from \"clsx\";\nimport { AnimatePresence, motion, type Transition } from \"framer-motion\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\nimport {\n dropTargetVisualStateDataAttributes,\n type CardDropTargetVisualState,\n type CardIntent,\n} from \"../types/visual-state.js\";\n\ninterface RegisteredDropTarget {\n targetId: string;\n disabled: boolean;\n eligible: boolean;\n element: HTMLElement;\n /** Plain-text label used for the live a11y announcement. */\n label: string | null;\n /** Order hint for keyboard target traversal (lower numbers focus first). */\n order: number;\n}\n\nexport type DragPhase =\n | \"idle\"\n | \"inspecting\"\n | \"dragging\"\n | \"settling\"\n | \"returning\";\n\ninterface ActiveDragState {\n cardId: string;\n cardLabel: string | null;\n source: \"pointer\" | \"keyboard\";\n pointerId: number | null;\n pointerX: number;\n pointerY: number;\n grabOffsetX: number;\n grabOffsetY: number;\n /**\n * Source rectangle captured at lift time, used as the snap-back/origin\n * geometry for animated returns.\n */\n sourceRect: { left: number; top: number; width: number; height: number };\n content: ReactNode;\n overTargetId: string | null;\n keyboardFocusedTargetId: string | null;\n /** DOM node we should focus when the lifecycle ends. */\n sourceFocus: HTMLElement | null;\n}\n\ninterface SettlingState {\n cardId: string;\n source: \"pointer\" | \"keyboard\";\n pointerX: number;\n pointerY: number;\n grabOffsetX: number;\n grabOffsetY: number;\n sourceRect: { left: number; top: number; width: number; height: number };\n targetRect: { left: number; top: number; width: number; height: number };\n content: ReactNode;\n}\n\ninterface ReturningState {\n cardId: string;\n source: \"pointer\" | \"keyboard\";\n pointerX: number;\n pointerY: number;\n grabOffsetX: number;\n grabOffsetY: number;\n sourceRect: { left: number; top: number; width: number; height: number };\n content: ReactNode;\n}\n\nexport interface CardDragSurfaceController {\n /** Identity of the card currently in the drag-lifecycle, if any. */\n activeCardId: string | null;\n /** Source of the active drag, if any. */\n activeSource: \"pointer\" | \"keyboard\" | null;\n /** Drag-lifecycle phase. */\n phase: DragPhase;\n /** Currently highlighted drop target id, if any. */\n overTargetId: string | null;\n /** Currently keyboard-focused target id, if any. */\n keyboardFocusedTargetId: string | null;\n /**\n * Begin a pointer drag session. Returns `true` if the session started.\n */\n startPointerDrag: (input: PointerDragInput) => boolean;\n /** Update the pointer coordinates of an active pointer drag. */\n updatePointer: (point: { x: number; y: number }) => void;\n /**\n * Commit the active pointer drag at the supplied release position. Emits\n * a `drop` intent if the pointer is over an eligible target, or schedules\n * a snap back otherwise.\n */\n releasePointer: (point: { x: number; y: number }) => void;\n /** Cancel the active drag (pointer or keyboard) without committing. */\n cancelDrag: () => void;\n /**\n * Begin a keyboard drag session. The first eligible registered target is\n * focused automatically.\n */\n startKeyboardDrag: (input: KeyboardDragInput) => boolean;\n /** Move keyboard focus across registered eligible targets. */\n moveKeyboardFocus: (direction: \"next\" | \"prev\") => void;\n /** Commit the active keyboard drag on the focused target. */\n commitKeyboardDrop: () => void;\n /**\n * Record a tap that did not produce a lift. The surface holds the\n * `inspecting` phase until another lift, drop, or external dismissal.\n */\n recordTap: (input: TapInput) => void;\n /**\n * Record a `previewStart` intent. Surface owns canonical intent emission\n * so consumers subscribe in one place.\n */\n recordPreviewStart: (cardId: string) => void;\n /** Record a `previewEnd` intent. */\n recordPreviewEnd: (cardId: string) => void;\n /**\n * Record a desktop/keyboard `activate` intent under the `direct-activate`\n * policy. Drag-to-target policy never calls this; it is centralized here\n * so that the surface remains the only ingress for `CardIntent`.\n */\n recordActivate: (cardId: string, source: \"tap\" | \"keyboard\") => void;\n /** Clear the `inspecting` phase. */\n clearInspect: () => void;\n /** Total number of currently registered eligible targets. */\n eligibleTargetCount: number;\n}\n\ninterface TapInput {\n cardId: string;\n cardEligible: boolean;\n cardDisabled: boolean;\n sourceFocus?: HTMLElement | null;\n}\n\ninterface PointerDragInput {\n cardId: string;\n cardLabel?: string | null;\n pointerId: number;\n startX: number;\n startY: number;\n pointerX: number;\n pointerY: number;\n grabOffsetX: number;\n grabOffsetY: number;\n sourceRect: { left: number; top: number; width: number; height: number };\n content: ReactNode;\n sourceFocus?: HTMLElement | null;\n}\n\ninterface KeyboardDragInput {\n cardId: string;\n cardLabel?: string | null;\n cardEligible: boolean;\n sourceRect: { left: number; top: number; width: number; height: number };\n content: ReactNode;\n sourceFocus?: HTMLElement | null;\n}\n\nexport interface CardDragSurfaceContextValue {\n registerTarget: (target: RegisteredDropTarget) => () => void;\n updateTarget: (\n targetId: string,\n patch: Partial<Omit<RegisteredDropTarget, \"targetId\" | \"element\">>,\n ) => void;\n controller: CardDragSurfaceController;\n /** Expose the most recent active card id for visual-state computation. */\n activeCardId: string | null;\n /** Expose the highlighted target id for visual-state computation. */\n overTargetId: string | null;\n /** Expose whether any drag is in progress. */\n dragActive: boolean;\n keyboardFocusedTargetId: string | null;\n}\n\nconst CardDragSurfaceContext =\n createContext<CardDragSurfaceContextValue | null>(null);\n\nexport function useCardDragSurface(): CardDragSurfaceContextValue | null {\n return useContext(CardDragSurfaceContext);\n}\n\nexport interface CardDragSurfaceProps {\n onCardIntent?: (intent: CardIntent) => void;\n /**\n * Approximate inset (px) used for the deterministic hit test. Defaults to\n * `8`. Lowering this lets edges register more aggressively; raising it\n * makes overlapping targets less ambiguous.\n */\n hitTestInsetPx?: number;\n /** Suppress the live a11y announcement (for environments providing their own). */\n suppressLiveAnnouncement?: boolean;\n /** Animation transition tunable for settle/return. */\n motionTransition?: Transition;\n className?: string;\n style?: CSSProperties;\n children: ReactNode;\n}\n\nconst SETTLE_TRANSITION: Transition = {\n type: \"spring\",\n stiffness: 380,\n damping: 32,\n mass: 0.9,\n};\nconst RETURN_TRANSITION: Transition = {\n type: \"spring\",\n stiffness: 320,\n damping: 26,\n mass: 0.8,\n};\nconst REDUCED_TRANSITION: Transition = { duration: 0 };\n\nexport function CardDragSurface({\n onCardIntent,\n hitTestInsetPx = 8,\n suppressLiveAnnouncement = false,\n motionTransition,\n className,\n style,\n children,\n}: CardDragSurfaceProps) {\n const theme = useTheme();\n const reducedMotion = theme.motion.reducedMotion === \"true\";\n const liveRegionId = useId();\n const targetsRef = useRef(new Map<string, RegisteredDropTarget>());\n const orderCounterRef = useRef(0);\n const activeDragRef = useRef<ActiveDragState | null>(null);\n const inspectingRef = useRef<string | null>(null);\n const [activeDrag, setActiveDrag] = useState<ActiveDragState | null>(null);\n const [inspectingCardId, setInspectingCardId] = useState<string | null>(null);\n const [settlingState, setSettlingState] = useState<SettlingState | null>(\n null,\n );\n const [returningState, setReturningState] = useState<ReturningState | null>(\n null,\n );\n const onIntentRef = useRef(onCardIntent);\n onIntentRef.current = onCardIntent;\n\n const settleTransition = motionTransition ?? SETTLE_TRANSITION;\n const returnTransition = motionTransition ?? RETURN_TRANSITION;\n\n const setActive = useCallback((next: ActiveDragState | null) => {\n activeDragRef.current = next;\n setActiveDrag(next);\n }, []);\n\n const setInspecting = useCallback((next: string | null) => {\n inspectingRef.current = next;\n setInspectingCardId(next);\n }, []);\n\n const finalizeInteraction = useCallback((sourceFocus: HTMLElement | null) => {\n if (sourceFocus) {\n // Defer focus restoration so animation can complete first frame.\n queueMicrotask(() => {\n try {\n sourceFocus.focus({ preventScroll: true });\n } catch {\n // Source may have been unmounted; ignore.\n }\n });\n }\n }, []);\n\n const registerTarget = useCallback(\n (target: RegisteredDropTarget) => {\n targetsRef.current.set(target.targetId, {\n ...target,\n order: target.order || ++orderCounterRef.current,\n });\n return () => {\n targetsRef.current.delete(target.targetId);\n const active = activeDragRef.current;\n if (active && active.keyboardFocusedTargetId === target.targetId) {\n setActive({ ...active, keyboardFocusedTargetId: null });\n }\n };\n },\n [setActive],\n );\n\n const updateTarget = useCallback(\n (\n targetId: string,\n patch: Partial<Omit<RegisteredDropTarget, \"targetId\" | \"element\">>,\n ) => {\n const existing = targetsRef.current.get(targetId);\n if (!existing) return;\n targetsRef.current.set(targetId, { ...existing, ...patch });\n },\n [],\n );\n\n const isTargetUsable = useCallback((target: RegisteredDropTarget) => {\n return !target.disabled && target.eligible !== false;\n }, []);\n\n const resolveDropTarget = useCallback(\n (point: { x: number; y: number }): string | null => {\n for (const target of targetsRef.current.values()) {\n if (!isTargetUsable(target)) continue;\n const rect = target.element.getBoundingClientRect();\n if (\n point.x >= rect.left + hitTestInsetPx &&\n point.x <= rect.right - hitTestInsetPx &&\n point.y >= rect.top + hitTestInsetPx &&\n point.y <= rect.bottom - hitTestInsetPx\n ) {\n return target.targetId;\n }\n }\n return null;\n },\n [hitTestInsetPx, isTargetUsable],\n );\n\n const sortedUsableTargetIds = useCallback((): string[] => {\n const entries = Array.from(targetsRef.current.values()).filter((t) =>\n isTargetUsable(t),\n );\n entries.sort((a, b) => a.order - b.order);\n return entries.map((t) => t.targetId);\n }, [isTargetUsable]);\n\n const recordTap = useCallback(\n (input: TapInput) => {\n if (input.cardDisabled || !input.cardEligible) return;\n // Tap is non-committing in drag-to-target mode regardless of whether\n // any usable target is currently registered. A missing target is a\n // composition/availability problem, not a reason to silently fall\n // back to tap-to-play. Hold the card in `inspecting` so the user can\n // see what they tapped while the runtime decides what to do next.\n setInspecting(input.cardId);\n },\n [setInspecting],\n );\n\n const recordPreviewStart = useCallback((cardId: string) => {\n onIntentRef.current?.({ type: \"previewStart\", cardId });\n }, []);\n\n const recordPreviewEnd = useCallback((cardId: string) => {\n onIntentRef.current?.({ type: \"previewEnd\", cardId });\n }, []);\n\n const recordActivate = useCallback(\n (cardId: string, source: \"tap\" | \"keyboard\") => {\n onIntentRef.current?.({ type: \"activate\", cardId, source });\n },\n [],\n );\n\n const clearInspect = useCallback(() => {\n if (inspectingRef.current !== null) setInspecting(null);\n }, [setInspecting]);\n\n const startPointerDrag = useCallback(\n (input: PointerDragInput): boolean => {\n if (activeDragRef.current) return false;\n if (inspectingRef.current) setInspecting(null);\n const overTargetId = resolveDropTarget({\n x: input.pointerX,\n y: input.pointerY,\n });\n const next: ActiveDragState = {\n cardId: input.cardId,\n cardLabel: input.cardLabel ?? null,\n source: \"pointer\",\n pointerId: input.pointerId,\n pointerX: input.pointerX,\n pointerY: input.pointerY,\n grabOffsetX: input.grabOffsetX,\n grabOffsetY: input.grabOffsetY,\n sourceRect: input.sourceRect,\n content: input.content,\n overTargetId,\n keyboardFocusedTargetId: null,\n sourceFocus: input.sourceFocus ?? null,\n };\n setActive(next);\n return true;\n },\n [resolveDropTarget, setActive, setInspecting],\n );\n\n const updatePointer = useCallback(\n (point: { x: number; y: number }) => {\n const active = activeDragRef.current;\n if (!active || active.source !== \"pointer\") return;\n const overTargetId = resolveDropTarget(point);\n setActive({\n ...active,\n pointerX: point.x,\n pointerY: point.y,\n overTargetId,\n });\n },\n [resolveDropTarget, setActive],\n );\n\n const completeWithDrop = useCallback(\n (\n active: ActiveDragState,\n targetId: string,\n releaseX: number,\n releaseY: number,\n ) => {\n const target = targetsRef.current.get(targetId);\n const targetRect = target?.element.getBoundingClientRect();\n const settling: SettlingState = {\n cardId: active.cardId,\n source: active.source,\n pointerX: releaseX,\n pointerY: releaseY,\n grabOffsetX: active.grabOffsetX,\n grabOffsetY: active.grabOffsetY,\n sourceRect: active.sourceRect,\n targetRect: targetRect\n ? {\n left: targetRect.left,\n top: targetRect.top,\n width: targetRect.width,\n height: targetRect.height,\n }\n : active.sourceRect,\n content: active.content,\n };\n onIntentRef.current?.({\n type: \"drop\",\n cardId: active.cardId,\n targetId,\n source: active.source === \"keyboard\" ? \"keyboard\" : \"pointer\",\n });\n setSettlingState(settling);\n setReturningState(null);\n setActive(null);\n finalizeInteraction(active.sourceFocus);\n },\n [finalizeInteraction, setActive],\n );\n\n const completeWithReturn = useCallback(\n (active: ActiveDragState, releaseX: number, releaseY: number) => {\n const returning: ReturningState = {\n cardId: active.cardId,\n source: active.source,\n pointerX: releaseX,\n pointerY: releaseY,\n grabOffsetX: active.grabOffsetX,\n grabOffsetY: active.grabOffsetY,\n sourceRect: active.sourceRect,\n content: active.content,\n };\n setReturningState(returning);\n setSettlingState(null);\n setActive(null);\n finalizeInteraction(active.sourceFocus);\n },\n [finalizeInteraction, setActive],\n );\n\n const releasePointer = useCallback(\n (point: { x: number; y: number }) => {\n const active = activeDragRef.current;\n if (!active || active.source !== \"pointer\") return;\n const overTargetId = resolveDropTarget(point);\n if (overTargetId) {\n completeWithDrop(active, overTargetId, point.x, point.y);\n return;\n }\n completeWithReturn(active, point.x, point.y);\n },\n [completeWithDrop, completeWithReturn, resolveDropTarget],\n );\n\n const cancelDrag = useCallback(() => {\n const active = activeDragRef.current;\n if (!active) return;\n completeWithReturn(active, active.pointerX, active.pointerY);\n }, [completeWithReturn]);\n\n const startKeyboardDrag = useCallback(\n (input: KeyboardDragInput): boolean => {\n if (activeDragRef.current) return false;\n if (!input.cardEligible) return false;\n if (inspectingRef.current) setInspecting(null);\n const ids = sortedUsableTargetIds();\n if (ids.length === 0) return false;\n const firstFocus = ids[0]!;\n const firstTarget = targetsRef.current.get(firstFocus);\n const firstRect = firstTarget?.element.getBoundingClientRect();\n const next: ActiveDragState = {\n cardId: input.cardId,\n cardLabel: input.cardLabel ?? null,\n source: \"keyboard\",\n pointerId: null,\n pointerX: firstRect ? firstRect.left + firstRect.width / 2 : 0,\n pointerY: firstRect ? firstRect.top + firstRect.height / 2 : 0,\n grabOffsetX: 0,\n grabOffsetY: 0,\n sourceRect: input.sourceRect,\n content: input.content,\n overTargetId: firstFocus,\n keyboardFocusedTargetId: firstFocus,\n sourceFocus: input.sourceFocus ?? null,\n };\n setActive(next);\n // Focus is moved by `CardDropTargetView` in an effect that watches\n // `keyboardFocusedTargetId`, ensuring focus transfer happens after\n // React commits the render that promotes this target.\n return true;\n },\n [setActive, setInspecting, sortedUsableTargetIds],\n );\n\n const moveKeyboardFocus = useCallback(\n (direction: \"next\" | \"prev\") => {\n const active = activeDragRef.current;\n if (!active || active.source !== \"keyboard\") return;\n const ids = sortedUsableTargetIds();\n if (ids.length === 0) return;\n const currentIdx = active.keyboardFocusedTargetId\n ? ids.indexOf(active.keyboardFocusedTargetId)\n : -1;\n const nextIdx =\n direction === \"next\"\n ? (currentIdx + 1) % ids.length\n : (currentIdx - 1 + ids.length) % ids.length;\n const nextId = ids[nextIdx]!;\n const target = targetsRef.current.get(nextId);\n const rect = target?.element.getBoundingClientRect();\n setActive({\n ...active,\n keyboardFocusedTargetId: nextId,\n overTargetId: nextId,\n pointerX: rect ? rect.left + rect.width / 2 : active.pointerX,\n pointerY: rect ? rect.top + rect.height / 2 : active.pointerY,\n });\n // Focus moved by the target's keyboardFocused effect.\n },\n [setActive, sortedUsableTargetIds],\n );\n\n const commitKeyboardDrop = useCallback(() => {\n const active = activeDragRef.current;\n if (!active || active.source !== \"keyboard\") return;\n const targetId = active.keyboardFocusedTargetId;\n if (!targetId) return;\n const target = targetsRef.current.get(targetId);\n if (!target || !isTargetUsable(target)) return;\n const rect = target.element.getBoundingClientRect();\n completeWithDrop(\n active,\n targetId,\n rect.left + rect.width / 2,\n rect.top + rect.height / 2,\n );\n }, [completeWithDrop, isTargetUsable]);\n\n const phase: DragPhase = useMemo(() => {\n if (activeDrag) return \"dragging\";\n if (settlingState) return \"settling\";\n if (returningState) return \"returning\";\n if (inspectingCardId) return \"inspecting\";\n return \"idle\";\n }, [activeDrag, inspectingCardId, returningState, settlingState]);\n\n const eligibleTargetCount = useMemo(\n () => sortedUsableTargetIds().length,\n // Recompute whenever any target patch changes — `activeDrag` is a cheap\n // proxy: target updates also bump the surface re-render via parent state.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [activeDrag, sortedUsableTargetIds],\n );\n\n const controller: CardDragSurfaceController = useMemo(\n () => ({\n activeCardId:\n activeDrag?.cardId ??\n settlingState?.cardId ??\n returningState?.cardId ??\n (inspectingCardId ? inspectingCardId : null),\n activeSource: activeDrag?.source ?? null,\n phase,\n overTargetId: activeDrag?.overTargetId ?? null,\n keyboardFocusedTargetId: activeDrag?.keyboardFocusedTargetId ?? null,\n startPointerDrag,\n updatePointer,\n releasePointer,\n cancelDrag,\n startKeyboardDrag,\n moveKeyboardFocus,\n commitKeyboardDrop,\n recordTap,\n recordPreviewStart,\n recordPreviewEnd,\n recordActivate,\n clearInspect,\n eligibleTargetCount,\n }),\n [\n activeDrag,\n cancelDrag,\n clearInspect,\n commitKeyboardDrop,\n eligibleTargetCount,\n inspectingCardId,\n moveKeyboardFocus,\n phase,\n recordActivate,\n recordPreviewEnd,\n recordPreviewStart,\n recordTap,\n releasePointer,\n returningState,\n settlingState,\n startKeyboardDrag,\n startPointerDrag,\n updatePointer,\n ],\n );\n\n const contextValue: CardDragSurfaceContextValue = useMemo(\n () => ({\n registerTarget,\n updateTarget,\n controller,\n activeCardId: controller.activeCardId,\n overTargetId: activeDrag?.overTargetId ?? null,\n dragActive: activeDrag !== null,\n keyboardFocusedTargetId: activeDrag?.keyboardFocusedTargetId ?? null,\n }),\n [activeDrag, controller, registerTarget, updateTarget],\n );\n\n useEffect(() => {\n if (!activeDrag) return;\n function onKeyDown(event: globalThis.KeyboardEvent) {\n if (event.key === \"Escape\") {\n event.preventDefault();\n cancelDrag();\n }\n }\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [activeDrag, cancelDrag]);\n\n const announcement = useMemo(() => {\n if (!activeDrag) return null;\n const overTarget = activeDrag.overTargetId\n ? targetsRef.current.get(activeDrag.overTargetId)\n : null;\n const overLabel = overTarget?.label ?? null;\n const cardLabel = activeDrag.cardLabel ?? \"Card\";\n if (overLabel) {\n return `${cardLabel} over ${overLabel}. Press Enter to drop or Escape to cancel.`;\n }\n return `${cardLabel} picked up. Move to a target or press Escape to cancel.`;\n }, [activeDrag]);\n\n const overlayContent = activeDrag ? (\n <DragOverlay session={activeDrag} reducedMotion={reducedMotion} />\n ) : null;\n\n const settleOverlay = settlingState ? (\n <SettleOverlay\n key={`settle-${settlingState.cardId}`}\n session={settlingState}\n transition={reducedMotion ? REDUCED_TRANSITION : settleTransition}\n onDone={() => setSettlingState(null)}\n />\n ) : null;\n\n const returnOverlay = returningState ? (\n <ReturnOverlay\n key={`return-${returningState.cardId}`}\n session={returningState}\n transition={reducedMotion ? REDUCED_TRANSITION : returnTransition}\n onDone={() => setReturningState(null)}\n />\n ) : null;\n\n const portalRoot = typeof document !== \"undefined\" ? document.body : null;\n\n return (\n <CardDragSurfaceContext.Provider value={contextValue}>\n <div\n data-dreamboard-card-drag-surface=\"\"\n data-drag-active={activeDrag ? \"true\" : undefined}\n data-drag-source={activeDrag?.source}\n data-drag-phase={phase}\n className={clsx(\"relative\", className)}\n style={style}\n >\n {children}\n </div>\n {portalRoot\n ? createPortal(\n <AnimatePresence initial={false}>\n {overlayContent}\n {settleOverlay}\n {returnOverlay}\n </AnimatePresence>,\n portalRoot,\n )\n : null}\n {!suppressLiveAnnouncement ? (\n <div\n id={liveRegionId}\n role=\"status\"\n aria-live=\"polite\"\n className=\"sr-only\"\n data-dreamboard-card-drag-announcement=\"\"\n style={{\n position: \"absolute\",\n width: 1,\n height: 1,\n padding: 0,\n margin: -1,\n overflow: \"hidden\",\n clip: \"rect(0,0,0,0)\",\n whiteSpace: \"nowrap\",\n border: 0,\n }}\n >\n {announcement ?? \"\"}\n </div>\n ) : null}\n </CardDragSurfaceContext.Provider>\n );\n}\n\ninterface DragOverlayProps {\n session: ActiveDragState;\n reducedMotion: boolean;\n}\n\nfunction DragOverlay({ session, reducedMotion }: DragOverlayProps) {\n if (session.source === \"keyboard\") {\n return (\n <motion.div\n key=\"overlay-keyboard\"\n data-dreamboard-card-drag-overlay=\"\"\n data-source=\"keyboard\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={reducedMotion ? REDUCED_TRANSITION : { duration: 0.12 }}\n style={{\n position: \"fixed\",\n left: session.sourceRect.left,\n top: session.sourceRect.top,\n width: session.sourceRect.width,\n height: session.sourceRect.height,\n pointerEvents: \"none\",\n zIndex: 1000,\n boxShadow: reducedMotion ? \"none\" : \"0 12px 32px rgba(0,0,0,0.18)\",\n borderRadius: 12,\n }}\n >\n {session.content}\n </motion.div>\n );\n }\n\n const liftedAnimate = reducedMotion\n ? {\n scale: 1,\n rotate: 0,\n filter: \"drop-shadow(0 0 0 rgba(0,0,0,0))\",\n }\n : {\n scale: [1, 1.42, 1.35],\n rotate: [0, -3, 3, -1.8, 1.8, 0],\n filter: [\n \"drop-shadow(0 4px 8px rgba(0,0,0,0.18))\",\n \"drop-shadow(0 24px 36px rgba(0,0,0,0.36))\",\n ],\n };\n const liftedTransition: Transition = reducedMotion\n ? REDUCED_TRANSITION\n : {\n scale: { type: \"spring\", stiffness: 420, damping: 22, mass: 0.7 },\n rotate: { duration: 0.55, ease: \"easeInOut\" },\n filter: { duration: 0.18, ease: \"easeOut\" },\n };\n return (\n <motion.div\n key=\"overlay-pointer\"\n data-dreamboard-card-drag-overlay=\"\"\n data-source=\"pointer\"\n initial={{\n scale: 1,\n rotate: 0,\n opacity: 1,\n filter: \"drop-shadow(0 2px 6px rgba(0,0,0,0.15))\",\n }}\n animate={liftedAnimate}\n exit={{ opacity: 0 }}\n transition={liftedTransition}\n style={{\n position: \"fixed\",\n left: session.pointerX - session.sourceRect.width / 2,\n top: session.pointerY - session.sourceRect.height / 2,\n width: session.sourceRect.width,\n height: session.sourceRect.height,\n zIndex: 1000,\n pointerEvents: \"none\",\n touchAction: \"none\",\n transformOrigin: \"center center\",\n willChange: \"transform, filter\",\n }}\n >\n {session.content}\n </motion.div>\n );\n}\n\ninterface SettleOverlayProps {\n session: SettlingState;\n transition: Transition;\n onDone: () => void;\n}\n\nfunction SettleOverlay({ session, transition, onDone }: SettleOverlayProps) {\n const startLeft = session.pointerX - session.sourceRect.width / 2;\n const startTop = session.pointerY - session.sourceRect.height / 2;\n const endLeft =\n session.targetRect.left +\n session.targetRect.width / 2 -\n session.sourceRect.width / 2;\n const endTop =\n session.targetRect.top +\n session.targetRect.height / 2 -\n session.sourceRect.height / 2;\n return (\n <motion.div\n data-dreamboard-card-drag-overlay=\"\"\n data-source={session.source}\n data-drag-phase=\"settling\"\n initial={{ left: startLeft, top: startTop, scale: 1.06, opacity: 1 }}\n animate={{ left: endLeft, top: endTop, scale: 0.92, opacity: 0 }}\n transition={transition}\n onAnimationComplete={onDone}\n style={{\n position: \"fixed\",\n width: session.sourceRect.width,\n height: session.sourceRect.height,\n zIndex: 1000,\n pointerEvents: \"none\",\n }}\n >\n {session.content}\n </motion.div>\n );\n}\n\ninterface ReturnOverlayProps {\n session: ReturningState;\n transition: Transition;\n onDone: () => void;\n}\n\nfunction ReturnOverlay({ session, transition, onDone }: ReturnOverlayProps) {\n const startLeft = session.pointerX - session.sourceRect.width / 2;\n const startTop = session.pointerY - session.sourceRect.height / 2;\n return (\n <motion.div\n data-dreamboard-card-drag-overlay=\"\"\n data-source={session.source}\n data-drag-phase=\"returning\"\n initial={{ left: startLeft, top: startTop, scale: 1.06, opacity: 1 }}\n animate={{\n left: session.sourceRect.left,\n top: session.sourceRect.top,\n scale: 1,\n opacity: 1,\n }}\n exit={{ opacity: 0 }}\n transition={transition}\n onAnimationComplete={onDone}\n style={{\n position: \"fixed\",\n width: session.sourceRect.width,\n height: session.sourceRect.height,\n zIndex: 1000,\n pointerEvents: \"none\",\n }}\n >\n {session.content}\n </motion.div>\n );\n}\n\nexport interface CardDropTargetViewProps {\n targetId: string;\n state?: CardDropTargetVisualState;\n /** Plain-text label used in live announcements (\"Selected cards\", etc.). */\n label?: string;\n renderTarget: (state: CardDropTargetVisualState) => ReactNode;\n className?: string;\n style?: CSSProperties;\n /** Tab order hint (lower numbers focus first). */\n order?: number;\n /** ARIA role override; defaults to `button`. */\n role?: string;\n}\n\nexport function CardDropTargetView({\n targetId,\n state,\n label,\n renderTarget,\n className,\n style,\n order,\n role = \"button\",\n}: CardDropTargetViewProps) {\n const surface = useCardDragSurface();\n const ref = useRef<HTMLDivElement | null>(null);\n const disabled = state?.disabled ?? false;\n const baseEligible = state?.eligible ?? true;\n const baseLabel = label ?? null;\n const orderProp = order ?? 0;\n\n const registerTargetRef = useRef(surface?.registerTarget);\n registerTargetRef.current = surface?.registerTarget;\n const updateTargetRef = useRef(surface?.updateTarget);\n updateTargetRef.current = surface?.updateTarget;\n\n // Stable register/unregister keyed only on `targetId`. Eligibility, label\n // and disabled flow through `updateTarget` so changing surface context\n // values cannot tear down the registration mid-drag.\n useEffect(() => {\n const element = ref.current;\n const register = registerTargetRef.current;\n if (!register || !element) return;\n const unregister = register({\n targetId,\n disabled,\n eligible: baseEligible,\n element,\n label: baseLabel,\n order: orderProp,\n });\n return unregister;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [targetId]);\n\n useEffect(() => {\n updateTargetRef.current?.(targetId, {\n disabled,\n eligible: baseEligible,\n label: baseLabel,\n order: orderProp,\n });\n }, [targetId, disabled, baseEligible, baseLabel, orderProp]);\n\n const dragActive = surface?.dragActive ?? false;\n const overTargetId = surface?.overTargetId ?? null;\n const keyboardFocused = surface?.keyboardFocusedTargetId === targetId;\n\n // Move focus into this target whenever the surface promotes it to the\n // keyboard-focused id. Doing it here, after React commits, is more\n // reliable than firing focus() from inside the surface's `setActive`\n // callback (where React batching can race the source card's commit).\n useEffect(() => {\n if (!keyboardFocused) return;\n const el = ref.current;\n if (!el) return;\n if (document.activeElement === el) return;\n try {\n el.focus({ preventScroll: true });\n } catch {\n // Element may have unmounted; ignore.\n }\n }, [keyboardFocused, targetId]);\n\n const computedState: CardDropTargetVisualState = {\n ...state,\n eligible: baseEligible,\n active: dragActive ? true : state?.active,\n over:\n overTargetId === targetId && baseEligible ? true : (state?.over ?? false),\n };\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n if (!surface) return;\n const controller = surface.controller;\n if (controller.activeSource !== \"keyboard\") return;\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n controller.commitKeyboardDrop();\n return;\n }\n if (event.key === \"ArrowRight\" || event.key === \"ArrowDown\") {\n event.preventDefault();\n controller.moveKeyboardFocus(\"next\");\n return;\n }\n if (event.key === \"ArrowLeft\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n controller.moveKeyboardFocus(\"prev\");\n return;\n }\n if (event.key === \"Escape\") {\n event.preventDefault();\n controller.cancelDrag();\n }\n },\n [surface],\n );\n\n return (\n <div\n ref={ref}\n data-dreamboard-card-drop-target=\"\"\n data-target-id={targetId}\n data-keyboard-focused={keyboardFocused ? \"true\" : undefined}\n role={role}\n tabIndex={disabled || !baseEligible ? -1 : 0}\n aria-disabled={disabled || !baseEligible || undefined}\n aria-label={label}\n onKeyDown={handleKeyDown}\n className={className}\n style={style}\n {...dropTargetVisualStateDataAttributes(computedState)}\n >\n {renderTarget(computedState)}\n </div>\n );\n}\n","/**\n * Controlled, presentational hand view.\n *\n * `HandView` does not consume any Dreamboard descriptor or runtime state.\n * Callers supply:\n *\n * - the cards to render\n * - a `stateForCard(card)` function returning a controlled\n * {@link InteractionVisualState}\n * - a `renderCard(card, state)` slot for the visual surface (typically\n * a {@link CardFace})\n *\n * The component emits generic {@link CardIntent} events. A runtime\n * adapter is responsible for turning an `activate`/`drop` intent into a\n * Dreamboard submission.\n *\n * `mobileInteraction` selects the gesture policy:\n * - `direct-activate` — desktop tap and keyboard Enter/Space emit a single\n * `activate` intent.\n * - `drag-to-target` — pointer/keyboard lift initiates a drag against a\n * surrounding `CardDragSurface`. Tap collapses to an `inspecting` state\n * that does not commit. Drop emits an opaque `drop` intent.\n *\n * Layout, gesture, scroll arbitration and tray presentation are documented in\n * `docs/references/ui-sdk-mobile-hand-and-card-interactions.md`.\n */\n\nimport {\n useCallback,\n useId,\n useMemo,\n type CSSProperties,\n type ReactNode,\n} from \"react\";\nimport { clsx } from \"clsx\";\nimport type { ViewCard } from \"../../types/index.js\";\nimport type {\n CardIntent,\n InteractionVisualState,\n} from \"../types/visual-state.js\";\nimport type {\n HandPresentationMode,\n FanCardPosition,\n} from \"./hand-layout-math.js\";\nimport { useHandPresentation } from \"../hooks/useHandPresentation.js\";\nimport { useHandCardPointer } from \"../hooks/useHandCardPointer.js\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\nimport { useCardDragSurface } from \"./CardDragSurface.js\";\nimport type { HandInteractionPolicy } from \"./hand-pointer-engine.js\";\n\nexport type HandLayoutKind = HandPresentationMode | \"stack\";\n\nexport interface HandLayoutPolicy {\n desktop?: HandLayoutKind;\n mobile?: HandLayoutKind;\n}\n\nexport interface HandViewProps<CardData extends ViewCard = ViewCard> {\n cards: readonly CardData[];\n /**\n * Layout policy. Pass a single layout kind to use the same layout in every\n * viewport, or pass `{ desktop, mobile }` for a measured-width decision.\n * Defaults to `{ desktop: \"fan\", mobile: \"tray\" }`.\n */\n layout?: HandLayoutKind | HandLayoutPolicy;\n /**\n * Mobile interaction policy. Defaults to `direct-activate`. Use\n * `drag-to-target` together with a surrounding `CardDragSurface` and one\n * or more `CardDropTargetView` children.\n */\n mobileInteraction?: HandInteractionPolicy;\n /** Returns the controlled visual state for a card. */\n stateForCard?: (\n card: CardData,\n index: number,\n ) => InteractionVisualState | undefined;\n /** Visual surface renderer. */\n renderCard: (\n card: CardData,\n state: InteractionVisualState,\n index: number,\n ) => ReactNode;\n /** Generic UI intent callback. */\n onCardIntent?: (intent: CardIntent<CardData[\"id\"] & string>) => void;\n /** Card width hint for fan geometry. */\n cardSize?: \"sm\" | \"md\" | \"lg\";\n /** Slot for the empty state. Defaults to nothing rendered. */\n renderEmpty?: () => ReactNode;\n /** ARIA label for the hand region. */\n \"aria-label\"?: string;\n className?: string;\n style?: CSSProperties;\n}\n\nconst CARD_DIMENSIONS = {\n sm: { width: 80, height: 112 },\n md: { width: 96, height: 144 },\n lg: { width: 128, height: 192 },\n} as const;\n\nconst EMPTY_STATE: InteractionVisualState = {};\n\ninterface ResolvedLayoutPolicy {\n desktop: HandPresentationMode;\n mobile: HandPresentationMode;\n /** What we report on `data-layout` for stories/tests. */\n reported: HandLayoutKind;\n}\n\nfunction resolveLayoutPolicy(\n layout: HandViewProps[\"layout\"],\n): ResolvedLayoutPolicy {\n if (!layout) {\n return { desktop: \"fan\", mobile: \"tray\", reported: \"fan\" };\n }\n if (typeof layout === \"string\") {\n if (layout === \"stack\") {\n return { desktop: \"strip\", mobile: \"strip\", reported: \"stack\" };\n }\n return { desktop: layout, mobile: layout, reported: layout };\n }\n const desktop =\n layout.desktop === \"stack\" ? \"strip\" : (layout.desktop ?? \"fan\");\n const mobile =\n layout.mobile === \"stack\" ? \"strip\" : (layout.mobile ?? \"tray\");\n return {\n desktop,\n mobile,\n reported: (layout.desktop ?? layout.mobile ?? \"fan\") as HandLayoutKind,\n };\n}\n\nexport function HandView<CardData extends ViewCard = ViewCard>({\n cards,\n layout,\n mobileInteraction = \"direct-activate\",\n stateForCard,\n renderCard,\n onCardIntent,\n cardSize = \"md\",\n renderEmpty,\n \"aria-label\": ariaLabel = \"Your hand\",\n className,\n style,\n}: HandViewProps<CardData>) {\n const policy = useMemo(() => resolveLayoutPolicy(layout), [layout]);\n const dims = CARD_DIMENSIONS[cardSize];\n const regionId = useId();\n const theme = useTheme();\n const reducedMotion = theme.motion.reducedMotion === \"true\";\n\n const presentation = useHandPresentation({\n cardCount: cards.length,\n cardWidth: dims.width,\n cardHeight: dims.height,\n desktop: policy.desktop,\n mobile: policy.mobile,\n });\n\n const surface = useCardDragSurface();\n const surfaceController = surface?.controller ?? null;\n\n const emit = useCallback(\n (intent: CardIntent<CardData[\"id\"] & string>) => {\n onCardIntent?.(intent);\n },\n [onCardIntent],\n );\n\n const items = useMemo(\n () =>\n cards.map((card, index) => {\n const baseState = stateForCard?.(card, index) ?? EMPTY_STATE;\n return { card, index, baseState };\n }),\n [cards, stateForCard],\n );\n\n const renderLiftedCard = useCallback(\n (cardId: string): ReactNode => {\n const found = items.find((item) => (item.card.id as string) === cardId);\n if (!found) return null;\n return renderCard(found.card, found.baseState, found.index);\n },\n [items, renderCard],\n );\n\n const resolveCardLabel = useCallback(\n (cardId: string): string | null => {\n const found = items.find((item) => (item.card.id as string) === cardId);\n if (!found) return null;\n const card = found.card as ViewCard;\n return (\n card.name ??\n (card.properties as { title?: string } | undefined)?.title ??\n null\n );\n },\n [items],\n );\n\n const pointer = useHandCardPointer({\n onIntent: (intent) => emit(intent as CardIntent<CardData[\"id\"] & string>),\n policy: mobileInteraction,\n surface: surfaceController,\n renderLiftedCard,\n resolveCardLabel,\n });\n\n if (cards.length === 0) {\n return (\n <div\n ref={presentation.containerRef}\n data-dreamboard-hand-view=\"\"\n data-layout={policy.reported}\n data-mode=\"empty\"\n data-empty=\"true\"\n data-mobile-interaction={mobileInteraction}\n role=\"group\"\n aria-label={`${ariaLabel} - empty`}\n className={clsx(\n \"relative w-full min-w-0 flex items-end justify-center py-4 sm:py-6\",\n className,\n )}\n style={style}\n >\n {renderEmpty ? renderEmpty() : null}\n </div>\n );\n }\n\n const ariaCount = `${ariaLabel} - ${cards.length} card${cards.length === 1 ? \"\" : \"s\"}`;\n\n const surfacePhase = surfaceController?.phase ?? \"idle\";\n const surfaceActiveCardId = surfaceController?.activeCardId ?? null;\n\n const renderItem = (\n {\n card,\n index,\n baseState,\n }: { card: CardData; index: number; baseState: InteractionVisualState },\n extra: { positioned?: FanCardPosition } = {},\n ) => {\n const cardId = card.id as string;\n const isPointerActive = pointer.activeCardId === cardId;\n const isSurfaceActive = surfaceActiveCardId === cardId;\n const previewing =\n isPointerActive && pointer.recognitionState.kind === \"preview\"\n ? true\n : baseState.previewing;\n const isInspecting = isSurfaceActive && surfacePhase === \"inspecting\";\n const isDragging = isSurfaceActive && surfacePhase === \"dragging\";\n const isSettling = isSurfaceActive && surfacePhase === \"settling\";\n const isReturning = isSurfaceActive && surfacePhase === \"returning\";\n // Hide the source slot whenever the portal overlay is showing this card\n // (drag, settle, or return). The overlay is the visible card during\n // those phases — leaving the source visible duplicates it.\n const isLifted = isDragging || isSettling || isReturning;\n const state: InteractionVisualState = {\n ...baseState,\n previewing,\n };\n const eligible = state.eligible ?? false;\n const disabled = state.disabled ?? false;\n const bindings = pointer.bindCard({\n cardId,\n eligible,\n disabled,\n });\n const positioned = extra.positioned;\n const transformParts: string[] = [];\n if (positioned) {\n transformParts.push(`translateY(${positioned.translateY}px)`);\n transformParts.push(`rotate(${positioned.rotate}deg)`);\n }\n if (isInspecting && !reducedMotion) {\n transformParts.push(\"translateY(-12px)\", \"scale(1.04)\");\n }\n const transform = transformParts.length\n ? transformParts.join(\" \")\n : undefined;\n const liftVisualOpacity = isLifted ? 0.25 : 1;\n const inspectShadow =\n isInspecting && !reducedMotion\n ? \"0 14px 28px rgba(0,0,0,0.18)\"\n : undefined;\n return (\n <div\n key={card.id}\n role=\"gridcell\"\n aria-rowindex={1}\n aria-colindex={index + 1}\n id={`${regionId}-${index}`}\n tabIndex={disabled ? -1 : 0}\n data-lifted={isLifted ? \"true\" : undefined}\n data-returning={isReturning ? \"true\" : undefined}\n data-inspecting={isInspecting ? \"true\" : undefined}\n {...bindings}\n style={{\n ...bindings.style,\n opacity: liftVisualOpacity,\n boxShadow: inspectShadow,\n ...(positioned\n ? {\n position: \"absolute\",\n left: positioned.left,\n bottom: 0,\n zIndex: isInspecting ? 50 : positioned.zIndex,\n transform,\n transformOrigin: \"bottom center\",\n transition: reducedMotion\n ? \"none\"\n : \"transform 180ms ease-out, box-shadow 180ms ease-out\",\n }\n : transform\n ? {\n transform,\n transformOrigin: \"bottom center\",\n transition: reducedMotion\n ? \"none\"\n : \"transform 180ms ease-out, box-shadow 180ms ease-out\",\n }\n : null),\n }}\n >\n {renderCard(card, state, index)}\n </div>\n );\n };\n\n if (presentation.mode === \"fan\" || presentation.mode === \"compressed-fan\") {\n const totalHeight = dims.height + 24;\n return (\n <div\n ref={presentation.containerRef}\n data-dreamboard-hand-view=\"\"\n data-layout={policy.reported}\n data-mode={presentation.mode}\n data-mobile-interaction={mobileInteraction}\n data-reduced-motion={reducedMotion ? \"true\" : undefined}\n role=\"grid\"\n aria-label={ariaCount}\n aria-rowcount={1}\n aria-colcount={cards.length}\n className={clsx(\n \"relative w-full min-w-0 flex items-end justify-center py-4 sm:py-6 overflow-visible\",\n className,\n )}\n style={{\n touchAction: \"pan-x\",\n ...style,\n }}\n >\n <div\n role=\"row\"\n className=\"relative\"\n style={{\n width: presentation.totalWidth,\n height: totalHeight,\n }}\n >\n {items.map((item, index) =>\n renderItem(item, {\n positioned: presentation.fanPositions[index],\n }),\n )}\n </div>\n </div>\n );\n }\n\n if (presentation.mode === \"tray\") {\n return (\n <div\n ref={presentation.containerRef}\n data-dreamboard-hand-view=\"\"\n data-layout={policy.reported}\n data-mode=\"tray\"\n data-mobile-interaction={mobileInteraction}\n data-reduced-motion={reducedMotion ? \"true\" : undefined}\n role=\"grid\"\n aria-label={ariaCount}\n aria-rowcount={1}\n aria-colcount={cards.length}\n className={clsx(\"relative w-full min-w-0\", className)}\n style={style}\n >\n <div\n role=\"row\"\n className={clsx(\n \"flex items-end gap-3 overflow-x-auto px-4\",\n \"snap-x scroll-px-4\",\n )}\n style={{\n touchAction: pointer.scrollLocked ? \"none\" : \"pan-x\",\n paddingTop: 12,\n paddingBottom: \"max(1rem, env(safe-area-inset-bottom, 0px))\",\n scrollBehavior: reducedMotion ? \"auto\" : \"smooth\",\n }}\n >\n {items.map((item) => (\n <div\n key={item.card.id}\n className=\"snap-start shrink-0\"\n role=\"presentation\"\n >\n {renderItem(item)}\n </div>\n ))}\n </div>\n </div>\n );\n }\n\n // strip / stack — flow-based layout that keeps every card individually\n // touch-usable. Stack layout draws cards with a small horizontal cascade.\n return (\n <div\n ref={presentation.containerRef}\n data-dreamboard-hand-view=\"\"\n data-layout={policy.reported}\n data-mode={presentation.mode}\n data-mobile-interaction={mobileInteraction}\n data-reduced-motion={reducedMotion ? \"true\" : undefined}\n role=\"grid\"\n aria-label={ariaCount}\n aria-rowcount={1}\n aria-colcount={cards.length}\n className={clsx(\n \"relative w-full min-w-0 flex items-end justify-center py-4 sm:py-6\",\n className,\n )}\n style={{ touchAction: \"pan-x\", ...style }}\n >\n <div role=\"row\" className=\"flex flex-wrap justify-center gap-1\">\n {items.map((item) => renderItem(item))}\n </div>\n </div>\n );\n}\n","/**\n * Width-aware presentation selector for the controlled `HandView`.\n *\n * Measures the wrapping element with `ResizeObserver` and returns the chosen\n * presentation mode plus the resolved fan geometry. The hook is purely\n * presentational: it does not consume runtime state or descriptors.\n */\n\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n HAND_MODE_GEOMETRY,\n chooseHandLayoutMode,\n computeFanLayout,\n type FanCardPosition,\n type HandPresentationMode,\n} from \"../components/hand-layout-math.js\";\n\nexport interface HandPresentationOptions {\n cardCount: number;\n cardWidth: number;\n cardHeight: number;\n /** Desktop preference; defaults to `fan`. */\n desktop?: HandPresentationMode;\n /** Mobile fallback; defaults to `tray`. */\n mobile?: HandPresentationMode;\n /** Subtracted from measured container width (gutter, scroll padding). */\n containerPadding?: number;\n}\n\nexport interface HandPresentationResult {\n containerRef: React.RefObject<HTMLDivElement | null>;\n containerWidth: number;\n mode: HandPresentationMode;\n fanPositions: FanCardPosition[];\n fanStep: number;\n totalWidth: number;\n visibleSlice: number;\n}\n\nconst DEFAULT_PADDING = 16;\n\nexport function useHandPresentation({\n cardCount,\n cardWidth,\n cardHeight,\n desktop = \"fan\",\n mobile = \"tray\",\n containerPadding = DEFAULT_PADDING,\n}: HandPresentationOptions): HandPresentationResult {\n const containerRef = useRef<HTMLDivElement>(null);\n const [containerWidth, setContainerWidth] = useState(0);\n\n useEffect(() => {\n const node = containerRef.current;\n if (!node) return;\n let frame = 0;\n // Round to whole pixels and bail when the width is unchanged. The chosen\n // mode (fan vs compressed-fan) feeds the rendered card geometry, so an\n // unguarded float setState here can ping-pong the layout via ResizeObserver\n // (sub-pixel jitter, or a content-sized ancestor) and re-render forever.\n // Deferring to rAF also avoids \"ResizeObserver loop limit exceeded\".\n const apply = () => {\n const node = containerRef.current;\n if (!node) return;\n const next = Math.max(\n 0,\n Math.round(node.getBoundingClientRect().width) - containerPadding,\n );\n setContainerWidth((prev) => (prev === next ? prev : next));\n };\n apply();\n if (typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(() => {\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(apply);\n });\n observer.observe(node);\n return () => {\n cancelAnimationFrame(frame);\n observer.disconnect();\n };\n }, [containerPadding]);\n\n return useMemo<HandPresentationResult>(() => {\n const mode = chooseHandLayoutMode({\n containerWidth,\n cardCount,\n cardWidth,\n desktop,\n mobile,\n });\n if (mode === \"fan\" || mode === \"compressed-fan\") {\n const geometry = HAND_MODE_GEOMETRY[mode];\n const layout = computeFanLayout({\n availableWidth: containerWidth || cardWidth * cardCount,\n cardWidth,\n cardHeight,\n count: cardCount,\n ...geometry,\n });\n return {\n containerRef,\n containerWidth,\n mode,\n fanPositions: layout.positions,\n fanStep: layout.step,\n totalWidth: layout.totalWidth,\n visibleSlice: layout.visibleSlice,\n };\n }\n return {\n containerRef,\n containerWidth,\n mode,\n fanPositions: [],\n fanStep: cardWidth,\n totalWidth: cardWidth * cardCount,\n visibleSlice: cardWidth,\n };\n }, [cardCount, cardHeight, cardWidth, containerWidth, desktop, mobile]);\n}\n","/**\n * Pure layout math for the controlled `HandView`.\n *\n * The functions here are independent of React and DOM measurement so they can\n * be unit-tested directly. {@link computeFanLayout} matches the algorithm\n * documented in `docs/references/ui-sdk-mobile-hand-and-card-interactions.md`,\n * and {@link chooseHandLayoutMode} translates a measured container width and a\n * caller policy into the actual presentation mode the hand should render.\n */\n\nexport type HandPresentationMode = \"fan\" | \"compressed-fan\" | \"strip\" | \"tray\";\n\nexport interface FanLayoutOptions {\n availableWidth: number;\n cardWidth: number;\n cardHeight: number;\n count: number;\n /** Minimum visible slice for any card (touch readability floor). */\n minVisibleSlice: number;\n /** Maximum tilt of the outermost card, in degrees. */\n maxAngle: number;\n /** How many pixels the outermost cards drop below the center card. */\n arcDepth: number;\n}\n\nexport interface FanCardPosition {\n left: number;\n rotate: number;\n translateY: number;\n zIndex: number;\n}\n\nexport interface FanLayoutResult {\n positions: FanCardPosition[];\n /** Step between successive card origins (left offset). */\n step: number;\n /** Minimum bounding width of the laid-out hand. */\n totalWidth: number;\n /** Visible portion of each card after overlap, in pixels. */\n visibleSlice: number;\n}\n\nexport function computeFanLayout(options: FanLayoutOptions): FanLayoutResult {\n const {\n availableWidth,\n cardWidth,\n count,\n minVisibleSlice,\n maxAngle,\n arcDepth,\n } = options;\n if (count <= 0) {\n return { positions: [], step: 0, totalWidth: 0, visibleSlice: cardWidth };\n }\n if (count === 1) {\n return {\n positions: [{ left: 0, rotate: 0, translateY: 0, zIndex: 1 }],\n step: cardWidth,\n totalWidth: cardWidth,\n visibleSlice: cardWidth,\n };\n }\n\n const idealStep =\n availableWidth > cardWidth\n ? (availableWidth - cardWidth) / (count - 1)\n : minVisibleSlice;\n const step = Math.max(minVisibleSlice, Math.min(cardWidth, idealStep));\n const center = (count - 1) / 2;\n\n const positions: FanCardPosition[] = Array.from(\n { length: count },\n (_, index) => {\n const t = center === 0 ? 0 : (index - center) / center;\n return {\n left: index * step,\n rotate: t * maxAngle,\n translateY: Math.abs(t) * arcDepth,\n zIndex: index + 1,\n };\n },\n );\n\n return {\n positions,\n step,\n totalWidth: cardWidth + (count - 1) * step,\n visibleSlice: step,\n };\n}\n\nexport interface ChooseHandLayoutModeOptions {\n /** Measured container width in CSS pixels. `0` means unmeasured. */\n containerWidth: number;\n cardCount: number;\n cardWidth: number;\n /**\n * Caller-stated layout preference. The pair represents the desktop/mobile\n * intent — the visible-slice gate decides which one renders.\n */\n desktop: HandPresentationMode;\n mobile: HandPresentationMode;\n /** Minimum visible per-card slice that still feels touch-usable. */\n comfortableSlice?: number;\n /** Floor for compressed fan; below this the mobile fallback wins. */\n compressedSlice?: number;\n}\n\n/**\n * Choose the actual presentation mode for the current viewport.\n *\n * The decision is target-exposure based, not breakpoint based:\n *\n * - if the desktop preference fits with a comfortable slice, render it as-is;\n * - if it would only barely fit, use a `compressed-fan` when the desktop side\n * is fan-like;\n * - otherwise switch to the mobile fallback (`tray`, `strip`, or whatever the\n * caller asked for) so playable targets stay usable.\n */\nexport function chooseHandLayoutMode({\n containerWidth,\n cardCount,\n cardWidth,\n desktop,\n mobile,\n comfortableSlice = HAND_MODE_GEOMETRY.fan.minVisibleSlice,\n compressedSlice = HAND_MODE_GEOMETRY[\"compressed-fan\"].minVisibleSlice,\n}: ChooseHandLayoutModeOptions): HandPresentationMode {\n if (cardCount <= 1) return desktop;\n if (containerWidth <= 0) return desktop;\n\n const idealStep = (containerWidth - cardWidth) / (cardCount - 1);\n const step = Math.max(0, Math.min(cardWidth, idealStep));\n\n const desktopIsFanLike = desktop === \"fan\" || desktop === \"compressed-fan\";\n if (!desktopIsFanLike) {\n if (containerWidth >= cardWidth * cardCount) return desktop;\n return mobile;\n }\n\n if (step >= comfortableSlice) {\n return desktop === \"compressed-fan\" ? \"compressed-fan\" : \"fan\";\n }\n if (step >= compressedSlice) {\n return \"compressed-fan\";\n }\n return mobile;\n}\n\nexport interface HandModeGeometry {\n minVisibleSlice: number;\n maxAngle: number;\n arcDepth: number;\n}\n\n/** Recommended starting values from the mobile-hand reference. */\nexport const HAND_MODE_GEOMETRY: Record<\n Exclude<HandPresentationMode, \"tray\" | \"strip\">,\n HandModeGeometry\n> = {\n fan: { minVisibleSlice: 64, maxAngle: 5, arcDepth: 12 },\n \"compressed-fan\": { minVisibleSlice: 44, maxAngle: 4, arcDepth: 8 },\n};\n","/**\n * React binding for the {@link HandPointerEngine}.\n *\n * The hook recognizes pointer/keyboard activity on a card and forwards it to\n * the surrounding `CardDragSurface` controller. All `CardIntent` emission\n * (`activate`, `previewStart`, `previewEnd`, `drop`) flows through the\n * surface so that the surface is the single source of truth for the\n * drag-lifecycle.\n *\n * Two interaction policies:\n *\n * - `direct-activate` — desktop tap/click and keyboard Enter/Space emit one\n * `activate` (the hook calls `onIntent` directly because no drag-lifecycle\n * exists in this mode).\n * - `drag-to-target` — pointer lift starts a surface drag session; release\n * commits/returns through the surface; tap/keyboard Enter trigger the\n * surface's `recordTap`/`startKeyboardDrag` so it owns the lifecycle.\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n DEFAULT_POINTER_THRESHOLDS,\n HandPointerEngine,\n type CardPointerState,\n type HandInteractionPolicy,\n type PointerEngineCardSnapshot,\n type PointerEngineThresholds,\n} from \"../components/hand-pointer-engine.js\";\nimport type { CardDragSurfaceController } from \"../components/CardDragSurface.js\";\nimport type { CardIntent } from \"../types/visual-state.js\";\nimport type { ReactNode } from \"react\";\n\nexport interface UseHandCardPointerOptions {\n onIntent?: (intent: CardIntent) => void;\n thresholds?: PointerEngineThresholds;\n /**\n * Active interaction policy. Defaults to `direct-activate`.\n */\n policy?: HandInteractionPolicy;\n /**\n * Drag-surface controller for `drag-to-target` mode. The hook forwards\n * pointer/keyboard lifts to the controller; the controller emits intents.\n */\n surface?: CardDragSurfaceController | null;\n /**\n * Render the lifted card payload. Required when a `surface` is supplied;\n * the hook calls this to produce the overlay content for the active card.\n */\n renderLiftedCard?: (cardId: string) => ReactNode;\n /**\n * Resolve the human-readable label of the card being dragged for live\n * announcements.\n */\n resolveCardLabel?: (cardId: string) => string | null | undefined;\n}\n\nexport interface HandCardPointerBindings {\n /** Identity of the card the engine is currently tracking, if any. */\n activeCardId: string | null;\n /** Pointer recognition state (used for previewing/scroll-lock visuals). */\n recognitionState: CardPointerState;\n /** Whether the host should suppress vertical scrolling. */\n scrollLocked: boolean;\n /** Returns the props bag for a single card. */\n bindCard: (card: PointerEngineCardSnapshot) => HandCardPointerProps;\n /** Programmatic activation, for keyboard and synthetic clicks. */\n activateKeyboard: (card: PointerEngineCardSnapshot) => void;\n}\n\nexport interface HandCardPointerProps {\n ref: (element: HTMLElement | null) => void;\n onPointerDown: (event: React.PointerEvent<HTMLElement>) => void;\n onPointerMove: (event: React.PointerEvent<HTMLElement>) => void;\n onPointerUp: (event: React.PointerEvent<HTMLElement>) => void;\n onPointerCancel: (event: React.PointerEvent<HTMLElement>) => void;\n onLostPointerCapture: (event: React.PointerEvent<HTMLElement>) => void;\n onKeyDown: (event: React.KeyboardEvent<HTMLElement>) => void;\n onClick: (event: React.MouseEvent<HTMLElement>) => void;\n style: React.CSSProperties;\n \"data-pointer-state\": CardPointerState[\"kind\"];\n}\n\nexport function useHandCardPointer({\n onIntent,\n thresholds = DEFAULT_POINTER_THRESHOLDS,\n policy = \"direct-activate\",\n surface = null,\n renderLiftedCard,\n resolveCardLabel,\n}: UseHandCardPointerOptions = {}): HandCardPointerBindings {\n const intentRef = useRef(onIntent);\n intentRef.current = onIntent;\n const policyRef = useRef(policy);\n policyRef.current = policy;\n const surfaceRef = useRef<CardDragSurfaceController | null>(surface);\n surfaceRef.current = surface;\n const renderLiftedCardRef = useRef(renderLiftedCard);\n renderLiftedCardRef.current = renderLiftedCard;\n const resolveCardLabelRef = useRef(resolveCardLabel);\n resolveCardLabelRef.current = resolveCardLabel;\n\n const cardElementsRef = useRef(new Map<string, HTMLElement>());\n const cardRefsRef = useRef(\n new Map<string, (element: HTMLElement | null) => void>(),\n );\n\n const getCardRef = useCallback((cardId: string) => {\n let stable = cardRefsRef.current.get(cardId);\n if (!stable) {\n stable = (element: HTMLElement | null) => {\n if (element) {\n cardElementsRef.current.set(cardId, element);\n } else {\n cardElementsRef.current.delete(cardId);\n }\n };\n cardRefsRef.current.set(cardId, stable);\n }\n return stable;\n }, []);\n\n const [activeCardId, setActiveCardId] = useState<string | null>(null);\n const [recognitionState, setRecognitionState] = useState<CardPointerState>({\n kind: \"idle\",\n });\n const [scrollLocked, setScrollLocked] = useState(false);\n\n const captureSourceRect = useCallback((cardId: string) => {\n const el = cardElementsRef.current.get(cardId);\n if (!el) return { left: 0, top: 0, width: 0, height: 0 };\n const rect = el.getBoundingClientRect();\n return {\n left: rect.left,\n top: rect.top,\n width: rect.width,\n height: rect.height,\n };\n }, []);\n\n const engine = useMemo(\n () =>\n new HandPointerEngine(\n {\n onTap: (cardId) => {\n const cardEl = cardElementsRef.current.get(cardId);\n if (policyRef.current === \"drag-to-target\" && surfaceRef.current) {\n surfaceRef.current.recordTap({\n cardId,\n cardEligible: true,\n cardDisabled: false,\n sourceFocus: cardEl ?? null,\n });\n return;\n }\n if (surfaceRef.current) {\n surfaceRef.current.recordActivate(cardId, \"tap\");\n return;\n }\n intentRef.current?.({\n type: \"activate\",\n cardId,\n source: \"tap\",\n });\n },\n onPreviewStart: (cardId) => {\n // Surface is the canonical owner of all `CardIntent` emission\n // when present. Without a surface (legacy direct-activate-only\n // mounts), fall back to the local `onIntent` callback.\n if (surfaceRef.current) {\n surfaceRef.current.recordPreviewStart(cardId);\n return;\n }\n intentRef.current?.({ type: \"previewStart\", cardId });\n },\n onPreviewEnd: (cardId) => {\n if (surfaceRef.current) {\n surfaceRef.current.recordPreviewEnd(cardId);\n return;\n }\n intentRef.current?.({ type: \"previewEnd\", cardId });\n },\n onLiftStart: (event) => {\n if (policyRef.current !== \"drag-to-target\") return;\n const surfaceController = surfaceRef.current;\n if (!surfaceController) return;\n const content = renderLiftedCardRef.current?.(event.cardId) ?? null;\n const label = resolveCardLabelRef.current?.(event.cardId) ?? null;\n const sourceRect = captureSourceRect(event.cardId);\n const cardEl = cardElementsRef.current.get(event.cardId) ?? null;\n surfaceController.startPointerDrag({\n cardId: event.cardId,\n cardLabel: label,\n pointerId: event.pointerId,\n startX: event.startX,\n startY: event.startY,\n pointerX: event.pointerX,\n pointerY: event.pointerY,\n grabOffsetX: event.grabOffsetX,\n grabOffsetY: event.grabOffsetY,\n sourceRect,\n content,\n sourceFocus: cardEl,\n });\n },\n onLiftMove: (event) => {\n surfaceRef.current?.updatePointer({\n x: event.pointerX,\n y: event.pointerY,\n });\n },\n onLiftEnd: (event) => {\n surfaceRef.current?.releasePointer({\n x: event.pointerX,\n y: event.pointerY,\n });\n },\n onLiftCancel: () => {\n surfaceRef.current?.cancelDrag();\n },\n onLockScroll: setScrollLocked,\n onStateChange: (next) => {\n setRecognitionState(next);\n if (next.kind === \"idle\") {\n setActiveCardId(null);\n } else {\n setActiveCardId(next.cardId);\n }\n },\n },\n thresholds,\n ),\n [captureSourceRect, thresholds],\n );\n\n useEffect(() => () => engine.dispose(), [engine]);\n\n const bindCard = useCallback(\n (card: PointerEngineCardSnapshot): HandCardPointerProps => {\n const isActive = activeCardId === card.cardId;\n const pointerStateKind: CardPointerState[\"kind\"] = isActive\n ? recognitionState.kind\n : \"idle\";\n return {\n ref: getCardRef(card.cardId),\n style: {\n touchAction: isActive && scrollLocked ? \"none\" : \"pan-x\",\n userSelect: \"none\",\n WebkitUserSelect: \"none\",\n },\n \"data-pointer-state\": pointerStateKind,\n onPointerDown: (event) => {\n if (event.button !== undefined && event.button !== 0) return;\n if (card.disabled) return;\n try {\n (event.currentTarget as HTMLElement).setPointerCapture?.(\n event.pointerId,\n );\n } catch {\n // Test environments without an OS-backed pointer (jsdom-like\n // headless Chromium with synthesized PointerEvents) may throw\n // here. Capture is a UX nicety, not required for correctness.\n }\n engine.handlePointerDown(card, {\n pointerId: event.pointerId,\n clientX: event.clientX,\n clientY: event.clientY,\n });\n },\n onPointerMove: (event) => {\n engine.handlePointerMove(card, {\n pointerId: event.pointerId,\n clientX: event.clientX,\n clientY: event.clientY,\n });\n },\n onPointerUp: (event) => {\n try {\n (event.currentTarget as HTMLElement).releasePointerCapture?.(\n event.pointerId,\n );\n } catch {\n // Pair with the synthesized-pointer try in `onPointerDown`.\n }\n engine.handlePointerUp(card, {\n pointerId: event.pointerId,\n clientX: event.clientX,\n clientY: event.clientY,\n });\n },\n onPointerCancel: () => {\n engine.handlePointerCancel(card);\n },\n onLostPointerCapture: () => {\n engine.handlePointerCancel(card);\n },\n onKeyDown: (event) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n surfaceRef.current?.cancelDrag();\n return;\n }\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n if (card.disabled || !card.eligible) return;\n if (policyRef.current === \"drag-to-target\") {\n const surfaceController = surfaceRef.current;\n if (!surfaceController) return;\n const cardEl = cardElementsRef.current.get(card.cardId) ?? null;\n const content =\n renderLiftedCardRef.current?.(card.cardId) ?? null;\n const label = resolveCardLabelRef.current?.(card.cardId) ?? null;\n const sourceRect = captureSourceRect(card.cardId);\n const started = surfaceController.startKeyboardDrag({\n cardId: card.cardId,\n cardLabel: label,\n cardEligible: card.eligible,\n sourceRect,\n content,\n sourceFocus: cardEl,\n });\n if (!started) {\n // No eligible target — record an inspection through the\n // surface so the visual treatment matches a tap. We never\n // silently revert to direct activate under drag-to-target.\n surfaceController.recordTap({\n cardId: card.cardId,\n cardEligible: card.eligible,\n cardDisabled: card.disabled,\n sourceFocus: cardEl,\n });\n }\n return;\n }\n if (surfaceRef.current) {\n surfaceRef.current.recordActivate(card.cardId, \"keyboard\");\n return;\n }\n intentRef.current?.({\n type: \"activate\",\n cardId: card.cardId,\n source: \"keyboard\",\n });\n }\n },\n onClick: () => {\n // Pointerup paths already emit; suppress the synthetic click.\n },\n };\n },\n [\n activeCardId,\n captureSourceRect,\n engine,\n getCardRef,\n recognitionState.kind,\n scrollLocked,\n ],\n );\n\n const activateKeyboard = useCallback((card: PointerEngineCardSnapshot) => {\n if (card.disabled || !card.eligible) return;\n if (policyRef.current === \"drag-to-target\") return;\n if (surfaceRef.current) {\n surfaceRef.current.recordActivate(card.cardId, \"keyboard\");\n return;\n }\n intentRef.current?.({\n type: \"activate\",\n cardId: card.cardId,\n source: \"keyboard\",\n });\n }, []);\n\n return {\n activeCardId,\n recognitionState,\n scrollLocked,\n bindCard,\n activateKeyboard,\n };\n}\n","/**\n * Deterministic pointer recognizer for the controlled hand view.\n *\n * The engine is independent from React: it consumes pointer events and a\n * caller-supplied callbacks bag, and produces semantic gesture events. It\n * owns no DOM, emits no `CardIntent`, and does not track the drag-lifecycle\n * `phase` — that responsibility lives in `CardDragSurface`. The engine only\n * recognizes `tap`, `previewStart`/`previewEnd`, `liftStart`/`liftMove`/\n * `liftEnd`/`liftCancel`, and a `horizontalBrowse` informational signal.\n *\n * The thresholds match\n * `docs/references/ui-sdk-mobile-hand-and-card-interactions.md`:\n *\n * | Threshold | Default |\n * | ------------------------- | ----------- |\n * | Press preview delay | `220ms` |\n * | Movement slop | `8px` |\n * | Axis bias | `1.25` |\n * | Drag lift distance | `28px` |\n *\n * Callers wire the engine's `handlePointerDown` / `handlePointerMove` /\n * `handlePointerUp` / `handlePointerCancel` to the matching DOM events on\n * each interactive card.\n */\n\nexport type HandInteractionPolicy = \"direct-activate\" | \"drag-to-target\";\n\n/**\n * Internal recognition state. Not exposed to consumers because drag-lifecycle\n * phases (`inspecting`/`dragging`/`settling`/`returning`) live in\n * `CardDragSurface`.\n */\nexport type CardPointerState =\n | { kind: \"idle\" }\n | { kind: \"pressing\"; pointerId: number; cardId: string; startedAt: number }\n | { kind: \"preview\"; pointerId: number; cardId: string }\n | { kind: \"horizontalBrowse\"; pointerId: number; cardId: string }\n | { kind: \"lifted\"; pointerId: number; cardId: string };\n\nexport interface PointerEngineThresholds {\n pressPreviewMs: number;\n movementSlopPx: number;\n axisBiasRatio: number;\n dragLiftDistancePx: number;\n}\n\nexport const DEFAULT_POINTER_THRESHOLDS: PointerEngineThresholds = {\n pressPreviewMs: 220,\n movementSlopPx: 8,\n axisBiasRatio: 1.25,\n dragLiftDistancePx: 28,\n};\n\nexport type AxisDecision = \"undecided\" | \"horizontal\" | \"upward\";\n\nexport function resolveAxis(\n dx: number,\n dy: number,\n thresholds: PointerEngineThresholds = DEFAULT_POINTER_THRESHOLDS,\n): AxisDecision {\n if (\n Math.abs(dx) < thresholds.movementSlopPx &&\n Math.abs(dy) < thresholds.movementSlopPx\n ) {\n return \"undecided\";\n }\n if (Math.abs(dx) > Math.abs(dy) * thresholds.axisBiasRatio)\n return \"horizontal\";\n if (-dy > Math.abs(dx) * thresholds.axisBiasRatio) return \"upward\";\n return \"undecided\";\n}\n\nexport interface PointerEngineCardSnapshot {\n cardId: string;\n /** Whether the runtime adapter says this card is interactive. */\n eligible: boolean;\n /** Whether the runtime adapter says this card is disabled. */\n disabled: boolean;\n}\n\nexport interface LiftStartEvent {\n cardId: string;\n pointerId: number;\n startX: number;\n startY: number;\n pointerX: number;\n pointerY: number;\n grabOffsetX: number;\n grabOffsetY: number;\n}\n\nexport interface LiftMoveEvent {\n cardId: string;\n pointerId: number;\n pointerX: number;\n pointerY: number;\n}\n\nexport interface LiftEndEvent {\n cardId: string;\n pointerId: number;\n pointerX: number;\n pointerY: number;\n}\n\nexport interface PointerEngineCallbacks {\n /**\n * Recognized clean tap (no movement, no preview). Source is `pointer` for\n * pointerup taps; the keyboard activation path is a separate caller method\n * (see `triggerKeyboardActivate`/`triggerKeyboardLift`).\n */\n onTap?: (cardId: string) => void;\n /** Long-press preview started. */\n onPreviewStart?: (cardId: string) => void;\n /** Preview ended (release or axis disqualification). */\n onPreviewEnd?: (cardId: string) => void;\n /** Vertical lift gesture began past the drag threshold. */\n onLiftStart?: (event: LiftStartEvent) => void;\n /** Pointer move while lifted. */\n onLiftMove?: (event: LiftMoveEvent) => void;\n /** Pointer release while lifted. */\n onLiftEnd?: (event: LiftEndEvent) => void;\n /** Lift was cancelled (pointer cancel/lost capture). */\n onLiftCancel?: (cardId: string) => void;\n /** Horizontal browse arbitration (informational). */\n onHorizontalBrowse?: (cardId: string) => void;\n /**\n * Called when the engine has captured the pointer and wants the host to\n * suppress scrolling. The host controls the `touch-action` value.\n */\n onLockScroll?: (locked: boolean) => void;\n /** Called whenever the recognition state transitions, for visual hints. */\n onStateChange?: (next: CardPointerState) => void;\n}\n\ninterface ActivePointer {\n cardId: string;\n pointerId: number;\n startedAt: number;\n startX: number;\n startY: number;\n lastX: number;\n lastY: number;\n axis: AxisDecision;\n /** Set when the long-press preview timer fires. */\n previewActive: boolean;\n}\n\nexport class HandPointerEngine {\n private readonly callbacks: PointerEngineCallbacks;\n private readonly thresholds: PointerEngineThresholds;\n private active: ActivePointer | null = null;\n private state: CardPointerState = { kind: \"idle\" };\n private previewTimer: ReturnType<typeof setTimeout> | null = null;\n private now: () => number;\n\n constructor(\n callbacks: PointerEngineCallbacks,\n thresholds: PointerEngineThresholds = DEFAULT_POINTER_THRESHOLDS,\n now: () => number = () => Date.now(),\n ) {\n this.callbacks = callbacks;\n this.thresholds = thresholds;\n this.now = now;\n }\n\n /** Returns the most recently emitted recognition state (test helper). */\n getState(): CardPointerState {\n return this.state;\n }\n\n dispose(): void {\n this.clearPreviewTimer();\n if (this.state.kind === \"lifted\") {\n this.callbacks.onLiftCancel?.(this.state.cardId);\n }\n this.active = null;\n this.transition({ kind: \"idle\" });\n this.callbacks.onLockScroll?.(false);\n }\n\n handlePointerDown(\n card: PointerEngineCardSnapshot,\n event: { pointerId: number; clientX: number; clientY: number },\n ): void {\n if (this.active) return;\n if (card.disabled) return;\n\n const startedAt = this.now();\n this.active = {\n cardId: card.cardId,\n pointerId: event.pointerId,\n startedAt,\n startX: event.clientX,\n startY: event.clientY,\n lastX: event.clientX,\n lastY: event.clientY,\n axis: \"undecided\",\n previewActive: false,\n };\n this.transition({\n kind: \"pressing\",\n pointerId: event.pointerId,\n cardId: card.cardId,\n startedAt,\n });\n this.schedulePreview(card);\n }\n\n handlePointerMove(\n card: PointerEngineCardSnapshot,\n event: { pointerId: number; clientX: number; clientY: number },\n ): void {\n const pointer = this.active;\n if (!pointer || pointer.pointerId !== event.pointerId) return;\n if (pointer.cardId !== card.cardId) return;\n\n pointer.lastX = event.clientX;\n pointer.lastY = event.clientY;\n\n const dx = event.clientX - pointer.startX;\n const dy = event.clientY - pointer.startY;\n const axis = resolveAxis(dx, dy, this.thresholds);\n if (axis !== \"undecided\") pointer.axis = axis;\n\n if (this.state.kind === \"lifted\") {\n this.callbacks.onLiftMove?.({\n cardId: pointer.cardId,\n pointerId: pointer.pointerId,\n pointerX: event.clientX,\n pointerY: event.clientY,\n });\n return;\n }\n\n if (this.state.kind === \"pressing\") {\n if (axis === \"horizontal\") {\n this.clearPreviewTimer();\n this.transition({\n kind: \"horizontalBrowse\",\n pointerId: pointer.pointerId,\n cardId: pointer.cardId,\n });\n this.callbacks.onHorizontalBrowse?.(pointer.cardId);\n return;\n }\n if (\n axis === \"upward\" &&\n card.eligible &&\n -dy >= this.thresholds.dragLiftDistancePx\n ) {\n this.clearPreviewTimer();\n this.beginLift(pointer, event.clientX, event.clientY);\n return;\n }\n return;\n }\n\n if (this.state.kind === \"preview\") {\n if (\n axis === \"upward\" &&\n card.eligible &&\n -dy >= this.thresholds.dragLiftDistancePx\n ) {\n this.callbacks.onPreviewEnd?.(card.cardId);\n pointer.previewActive = false;\n this.beginLift(pointer, event.clientX, event.clientY);\n return;\n }\n if (axis === \"horizontal\") {\n this.callbacks.onPreviewEnd?.(card.cardId);\n pointer.previewActive = false;\n this.transition({\n kind: \"horizontalBrowse\",\n pointerId: pointer.pointerId,\n cardId: pointer.cardId,\n });\n this.callbacks.onHorizontalBrowse?.(pointer.cardId);\n return;\n }\n return;\n }\n\n // horizontalBrowse — remain locked until release.\n }\n\n handlePointerUp(\n card: PointerEngineCardSnapshot,\n event: { pointerId: number; clientX: number; clientY: number },\n ): void {\n const pointer = this.active;\n if (!pointer || pointer.pointerId !== event.pointerId) return;\n if (pointer.cardId !== card.cardId) return;\n this.clearPreviewTimer();\n\n const dx = event.clientX - pointer.startX;\n const dy = event.clientY - pointer.startY;\n const isTap =\n pointer.axis === \"undecided\" &&\n !pointer.previewActive &&\n Math.abs(dx) < this.thresholds.movementSlopPx &&\n Math.abs(dy) < this.thresholds.movementSlopPx;\n\n if (this.state.kind === \"lifted\") {\n this.callbacks.onLiftEnd?.({\n cardId: pointer.cardId,\n pointerId: pointer.pointerId,\n pointerX: event.clientX,\n pointerY: event.clientY,\n });\n this.reset();\n return;\n }\n\n if (isTap) {\n if (card.eligible && !card.disabled) {\n this.callbacks.onTap?.(card.cardId);\n }\n this.reset();\n return;\n }\n\n if (pointer.previewActive) {\n this.callbacks.onPreviewEnd?.(card.cardId);\n }\n this.reset();\n }\n\n handlePointerCancel(card: PointerEngineCardSnapshot): void {\n const pointer = this.active;\n if (!pointer || pointer.cardId !== card.cardId) return;\n this.clearPreviewTimer();\n if (this.state.kind === \"lifted\") {\n this.callbacks.onLiftCancel?.(card.cardId);\n this.reset();\n return;\n }\n if (pointer.previewActive) {\n this.callbacks.onPreviewEnd?.(card.cardId);\n }\n this.reset();\n }\n\n /**\n * Programmatic reset of recognition state (e.g. after the surface commits\n * a keyboard lift externally). Does not emit callbacks.\n */\n resetRecognition(): void {\n this.clearPreviewTimer();\n this.active = null;\n this.callbacks.onLockScroll?.(false);\n this.transition({ kind: \"idle\" });\n }\n\n private beginLift(\n pointer: ActivePointer,\n clientX: number,\n clientY: number,\n ): void {\n this.callbacks.onLockScroll?.(true);\n const grabOffsetX = clientX - pointer.startX;\n const grabOffsetY = clientY - pointer.startY;\n this.transition({\n kind: \"lifted\",\n pointerId: pointer.pointerId,\n cardId: pointer.cardId,\n });\n this.callbacks.onLiftStart?.({\n cardId: pointer.cardId,\n pointerId: pointer.pointerId,\n startX: pointer.startX,\n startY: pointer.startY,\n pointerX: clientX,\n pointerY: clientY,\n grabOffsetX,\n grabOffsetY,\n });\n }\n\n private schedulePreview(card: PointerEngineCardSnapshot): void {\n this.clearPreviewTimer();\n this.previewTimer = setTimeout(() => {\n const pointer = this.active;\n if (!pointer || pointer.cardId !== card.cardId) return;\n if (pointer.axis !== \"undecided\") return;\n pointer.previewActive = true;\n this.callbacks.onPreviewStart?.(card.cardId);\n this.transition({\n kind: \"preview\",\n pointerId: pointer.pointerId,\n cardId: card.cardId,\n });\n }, this.thresholds.pressPreviewMs);\n }\n\n private clearPreviewTimer(): void {\n if (this.previewTimer !== null) {\n clearTimeout(this.previewTimer);\n this.previewTimer = null;\n }\n }\n\n private reset(): void {\n this.active = null;\n this.callbacks.onLockScroll?.(false);\n this.transition({ kind: \"idle\" });\n }\n\n private transition(next: CardPointerState): void {\n this.state = next;\n this.callbacks.onStateChange?.(next);\n }\n}\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\nimport { useDrag } from \"@use-gesture/react\";\nimport { clsx } from \"clsx\";\nimport { useIsMobile } from \"../hooks/useIsMobile.js\";\nimport { useThemeCssVars } from \"../theme/ThemeProvider.js\";\n\nexport type HandRole = \"primary\" | \"auxiliary\" | \"task\";\n\nexport interface MobileHandRegistration {\n id: string;\n zone: string;\n label: string;\n role: HandRole;\n order?: number;\n version: string;\n count: number;\n active: boolean;\n autoOpen: boolean;\n content: ReactNode;\n}\n\ninterface MobileHandTrayContextValue {\n registerHand: (hand: MobileHandRegistration) => () => void;\n}\n\nconst MobileHandTrayContext = createContext<MobileHandTrayContextValue | null>(\n null,\n);\n\n// Kept separate from the registration context on purpose: this value changes\n// whenever the tray opens/closes or hands (de)register, whereas `registerHand`\n// must stay referentially stable so `useRegisterMobileHand`'s effect does not\n// re-run and thrash registrations.\nconst MobileHandTrayStateContext = createContext<{ active: boolean }>({\n active: false,\n});\n\nconst ROLE_PRIORITY: Record<HandRole, number> = {\n task: 0,\n primary: 1,\n auxiliary: 2,\n};\n\nconst TRAY_CONTENT_ID = \"dreamboard-mobile-hand-tray\";\n\n/** Dock snap heights, ordered collapsed → tall. */\nconst DOCK_SNAPS = [\"peek\", \"raised\", \"expanded\"] as const;\ntype DockSnap = (typeof DOCK_SNAPS)[number];\nconst DOCK_SNAP_MAX_HEIGHT: Record<DockSnap, number | string> = {\n peek: 0,\n raised: \"min(52vh, 440px)\",\n expanded: \"82vh\",\n};\n\nexport function MobileHandTrayProvider({ children }: { children: ReactNode }) {\n const [handsById, setHandsById] = useState<\n ReadonlyMap<string, MobileHandRegistration>\n >(() => new Map());\n const isMobile = useIsMobile();\n const registerHand = useCallback((hand: MobileHandRegistration) => {\n setHandsById((current) => {\n const previous = current.get(hand.id);\n if (\n previous &&\n previous.zone === hand.zone &&\n previous.label === hand.label &&\n previous.role === hand.role &&\n previous.order === hand.order &&\n previous.version === hand.version &&\n previous.count === hand.count &&\n previous.active === hand.active &&\n previous.autoOpen === hand.autoOpen\n ) {\n return current;\n }\n const next = new Map(current);\n next.set(hand.id, hand);\n return next;\n });\n return () => {\n setHandsById((current) => {\n if (!current.has(hand.id)) return current;\n const next = new Map(current);\n next.delete(hand.id);\n return next;\n });\n };\n }, []);\n const value = useMemo<MobileHandTrayContextValue>(\n () => ({ registerHand }),\n [registerHand],\n );\n const hands = useMemo(\n () =>\n [...handsById.values()].sort(\n (a, b) =>\n (a.order ?? ROLE_PRIORITY[a.role]) -\n (b.order ?? ROLE_PRIORITY[b.role]) ||\n ROLE_PRIORITY[a.role] - ROLE_PRIORITY[b.role] ||\n a.label.localeCompare(b.label),\n ),\n [handsById],\n );\n\n const trayActive = isMobile && hands.length > 0;\n const stateValue = useMemo(() => ({ active: trayActive }), [trayActive]);\n\n return (\n <MobileHandTrayContext.Provider value={value}>\n <MobileHandTrayStateContext.Provider value={stateValue}>\n <div\n data-dreamboard-mobile-hand-shell=\"\"\n data-mobile-hand-count={hands.length}\n data-mobile-hand-tray-active={trayActive ? \"true\" : undefined}\n style={{\n minHeight: \"100%\",\n paddingBottom: trayActive\n ? \"calc(92px + env(safe-area-inset-bottom, 0px))\"\n : undefined,\n }}\n >\n {children}\n </div>\n {trayActive ? <MobileHandTray hands={hands} /> : null}\n </MobileHandTrayStateContext.Provider>\n </MobileHandTrayContext.Provider>\n );\n}\n\nexport function useRegisterMobileHand(hand: MobileHandRegistration): void {\n const context = useContext(MobileHandTrayContext);\n if (!context) {\n throw new Error(\n \"Generated hand surfaces must be rendered inside <UI.Root>; mobile hand tray registration is unavailable.\",\n );\n }\n useEffect(() => context.registerHand(hand), [context, hand]);\n}\n\n/**\n * Whether the mobile hand tray is currently presenting hands — i.e. the\n * viewport is below the mobile breakpoint and at least one primary/auxiliary\n * hand has registered. Authors can use this to drop redundant inline hand\n * chrome (labels, framing) that the tray already provides, instead of guessing\n * the breakpoint with a CSS media query. Returns `false` outside `<UI.Root>`.\n */\nexport function useMobileHandTrayActive(): boolean {\n return useContext(MobileHandTrayStateContext).active;\n}\n\nfunction MobileHandTray({\n hands,\n}: {\n hands: readonly MobileHandRegistration[];\n}) {\n // Snap height of the dock. `peek` is the collapsed handle bar; `raised` shows\n // the hand at an actionable height; `expanded` opens it tall for a long hand.\n // The dock is always mounted and never modal — there is no scrim, and only\n // the dock surface captures pointer events, so the board behind it stays\n // visible and interactive.\n const [snap, setSnap] = useState<DockSnap>(\"peek\");\n const open = snap !== \"peek\";\n const advanceSnap = useCallback((direction: 1 | -1) => {\n setSnap((current) => {\n const index = DOCK_SNAPS.indexOf(current);\n const next = Math.min(\n DOCK_SNAPS.length - 1,\n Math.max(0, index + direction),\n );\n return DOCK_SNAPS[next] ?? current;\n });\n }, []);\n const [activeId, setActiveId] = useState<string | null>(null);\n const themeCssVars = useThemeCssVars();\n\n const preferredHand =\n hands.find((hand) => hand.id === activeId) ??\n hands.find((hand) => hand.active) ??\n hands.find((hand) => hand.role === \"primary\") ??\n hands[0] ??\n null;\n const selectedHand =\n hands.find((hand) => hand.id === activeId) ?? preferredHand;\n\n useEffect(() => {\n if (!preferredHand) {\n setActiveId(null);\n return;\n }\n setActiveId((current) =>\n current && hands.some((hand) => hand.id === current)\n ? current\n : preferredHand.id,\n );\n }, [hands, preferredHand]);\n\n // Auto-raise to the actionable height when it becomes this seat's turn to\n // act, and settle back to the peek when the turn passes. We only toggle on\n // the active transition, so a manual expand/collapse sticks until the turn\n // changes.\n const active = selectedHand?.active ?? false;\n const prevActiveRef = useRef(false);\n useEffect(() => {\n if (active !== prevActiveRef.current) {\n prevActiveRef.current = active;\n setSnap(active ? \"raised\" : \"peek\");\n }\n }, [active]);\n\n // Swipe the handle up to expand a step (peek → raised → expanded), down to\n // collapse a step. Taps fall through to the handle's onClick toggle\n // (filterTaps), and velocity lets a quick flick advance even on a short drag.\n const bindDrag = useDrag(\n ({ movement: [, my], velocity: [, vy], last }) => {\n if (!last) return;\n if (my < -24 || (my < 0 && vy > 0.4)) advanceSnap(1);\n else if (my > 24 || (my > 0 && vy > 0.4)) advanceSnap(-1);\n },\n { axis: \"y\", filterTaps: true },\n );\n\n if (!selectedHand) return null;\n\n const activeBadges = hands.filter(\n (hand) => hand.id !== selectedHand.id && hand.active,\n );\n\n return (\n <div\n data-dreamboard-mobile-hand-tray=\"\"\n data-state={snap}\n data-active-hand={selectedHand.id}\n style={{\n ...themeCssVars,\n position: \"fixed\",\n left: \"env(safe-area-inset-left, 0px)\",\n right: \"env(safe-area-inset-right, 0px)\",\n bottom: 0,\n zIndex: 900,\n display: \"flex\",\n justifyContent: \"center\",\n // Non-modal: the wrapper ignores pointers so taps land on the board;\n // only the dock panel below opts back in.\n pointerEvents: \"none\",\n }}\n >\n <div\n className=\"flex w-full flex-col overflow-hidden rounded-t-2xl\"\n style={{\n pointerEvents: \"auto\",\n maxWidth: \"min(40rem, 100%)\",\n background: \"var(--background, #fdfbf7)\",\n color: \"var(--foreground, #2d2d2d)\",\n borderTop: \"1px solid var(--border, rgba(45,45,45,0.18))\",\n borderLeft: \"1px solid var(--border, rgba(45,45,45,0.10))\",\n borderRight: \"1px solid var(--border, rgba(45,45,45,0.10))\",\n boxShadow:\n \"0 -18px 48px -22px rgba(45,45,45,0.30), 0 -6px 18px -16px rgba(45,45,45,0.20)\",\n }}\n >\n {/* Handle + summary bar — drag or tap to toggle peek/open. */}\n <button\n type=\"button\"\n {...bindDrag()}\n onClick={() =>\n setSnap((value) => (value === \"peek\" ? \"raised\" : \"peek\"))\n }\n aria-controls={TRAY_CONTENT_ID}\n aria-expanded={open}\n data-dreamboard-mobile-hand-trigger=\"\"\n data-hand-role={selectedHand.role}\n data-active-badges={activeBadges.length || undefined}\n className=\"flex w-full flex-col items-stretch gap-1.5 px-4 pb-2 pt-2 text-left\"\n style={{\n touchAction: \"none\",\n background: \"transparent\",\n border: 0,\n cursor: \"pointer\",\n }}\n >\n <span\n aria-hidden\n className=\"mx-auto h-1.5 w-10 rounded-full\"\n style={{ background: \"rgba(45,45,45,0.28)\" }}\n />\n <span className=\"flex items-center justify-between gap-2\">\n <span className=\"flex min-w-0 items-center gap-2 text-sm font-semibold\">\n <span className=\"truncate\">{selectedHand.label}</span>\n <span\n className=\"rounded-full px-2 py-0.5 text-xs font-bold\"\n style={{ background: \"rgba(45,45,45,0.08)\" }}\n >\n {selectedHand.count}\n </span>\n {active ? (\n <span className=\"rounded-full bg-amber-400 px-2 py-0.5 text-[10px] font-bold uppercase tracking-wide text-amber-950\">\n your turn\n </span>\n ) : null}\n </span>\n {activeBadges.length > 0 ? (\n <span\n aria-label={`${activeBadges.length} other active hand sections`}\n className=\"inline-flex min-w-5 items-center justify-center rounded-full bg-red-500 px-1.5 text-xs font-bold text-white\"\n >\n {activeBadges.length}\n </span>\n ) : null}\n </span>\n </button>\n\n {/* Collapsible body — kept mounted at the peek (clipped to zero height\n and made inert) so raising the dock never remounts the hand or\n loses scroll position, and so the auto-raise can animate. The body\n is the scroll container, so the action slot's sticky footer pins to\n its bottom edge. */}\n <div\n id={TRAY_CONTENT_ID}\n role=\"region\"\n aria-label={selectedHand.label}\n data-state={snap}\n inert={open ? undefined : true}\n className=\"overscroll-contain\"\n style={{\n maxHeight: DOCK_SNAP_MAX_HEIGHT[snap],\n overflowY: open ? \"auto\" : \"hidden\",\n transition: \"max-height 240ms ease\",\n }}\n >\n {hands.length > 1 ? (\n <div\n role=\"tablist\"\n aria-label=\"Hand sections\"\n className=\"flex gap-2 overflow-x-auto px-4 pb-2 pt-1 [scrollbar-width:none]\"\n >\n {hands.map((hand) => (\n <button\n key={hand.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={hand.id === selectedHand.id}\n data-active={hand.active || undefined}\n data-hand-role={hand.role}\n onClick={() => setActiveId(hand.id)}\n className={clsx(\n \"shrink-0 rounded-full border px-3 py-1 text-sm font-semibold\",\n hand.id === selectedHand.id\n ? \"border-slate-900 bg-white text-slate-950\"\n : \"border-slate-300 bg-white/60 text-slate-600\",\n hand.active && hand.id !== selectedHand.id\n ? \"ring-2 ring-red-400\"\n : null,\n )}\n >\n {hand.label} ({hand.count})\n </button>\n ))}\n </div>\n ) : null}\n <div\n className=\"px-3 pt-2 sm:px-4\"\n style={{\n paddingBottom: \"calc(20px + env(safe-area-inset-bottom, 0px))\",\n }}\n >\n {selectedHand.content}\n </div>\n </div>\n </div>\n </div>\n );\n}\n","/**\n * Central game board area for active game components (tricks, played\n * cards, zones, etc.).\n *\n * Visual chrome (frame, empty placeholder, card entrance/exit) is\n * sourced from the active {@link useTheme} so the play area re-skins\n * with the rest of the shell.\n */\n\nimport { motion, AnimatePresence } from \"framer-motion\";\nimport { clsx } from \"clsx\";\nimport { CardFace, type CardFaceProps, type ViewCard } from \"./Card.js\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\nimport { chipStyle } from \"../theme/derive.js\";\n\nexport interface PlayAreaProps<CardData extends ViewCard = ViewCard> {\n cards: readonly CardData[];\n filter?: (card: CardData) => boolean;\n cardSize?: CardFaceProps[\"size\"];\n renderCard?: CardFaceProps<CardData>[\"renderContent\"];\n layout?: \"grid\" | \"row\";\n interactive?: boolean;\n onCardClick?: (cardId: string) => void;\n \"aria-label\"?: string;\n className?: string;\n}\n\n/**\n * @example\n * ```tsx\n * <PlayArea cards={trickCards} layout=\"row\" renderCard={(card) => <PlayingCard card={card} />} />\n * ```\n */\nexport function PlayArea<CardData extends ViewCard = ViewCard>({\n cards,\n filter,\n cardSize = \"md\",\n renderCard,\n layout = \"row\",\n interactive = false,\n onCardClick,\n \"aria-label\": ariaLabel = \"Play area\",\n className,\n}: PlayAreaProps<CardData>) {\n const theme = useTheme();\n const reducedMotion = theme.motion.reducedMotion === \"true\";\n const visibleCards = filter ? cards.filter(filter) : cards;\n\n const layoutClasses = {\n grid: \"grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-3 sm:gap-6\",\n row: \"flex flex-wrap items-center justify-center gap-3 sm:gap-6\",\n };\n\n return (\n <div\n className={clsx(\n \"relative w-full min-h-[200px] sm:min-h-[300px] p-6 sm:p-8\",\n className,\n )}\n style={{\n background: theme.semantic.surface.inset,\n border: `2px dashed ${theme.semantic.border.default}`,\n borderRadius: theme.radius.hud,\n fontFamily: theme.typography.fontFamily.body,\n color: theme.semantic.text.primary,\n }}\n role=\"region\"\n aria-label={`${ariaLabel} - ${visibleCards.length} item${visibleCards.length !== 1 ? \"s\" : \"\"}`}\n >\n <AnimatePresence mode=\"popLayout\">\n {visibleCards.length === 0 ? (\n <motion.div\n className=\"flex items-center justify-center h-full absolute inset-0 pointer-events-none\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n role=\"status\"\n aria-live=\"polite\"\n >\n <div\n style={{\n ...chipStyle(theme, { variant: \"warning\", size: \"md\" }),\n fontSize: theme.typography.fontSize.md,\n paddingBlock: theme.space[2],\n paddingInline: theme.space[4],\n }}\n >\n No cards in play\n </div>\n </motion.div>\n ) : (\n <div className={layoutClasses[layout]}>\n {visibleCards.map((card, index) => (\n <motion.div\n key={card.id}\n layout={!reducedMotion}\n initial={\n reducedMotion\n ? { opacity: 0, scale: 1 }\n : { opacity: 0, scale: 0.8 }\n }\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.8 }}\n transition={{\n type: \"spring\",\n stiffness: 260,\n damping: 20,\n delay: reducedMotion ? 0 : index * 0.05,\n }}\n >\n {interactive && onCardClick ? (\n <button\n type=\"button\"\n aria-label={card.name ?? `Card ${card.id}`}\n onClick={() => onCardClick(card.id)}\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onCardClick(card.id);\n }\n }}\n className=\"border-0 bg-transparent p-0 cursor-pointer focus-visible:outline-none\"\n style={{ all: \"unset\", cursor: \"pointer\" }}\n >\n <CardFace\n card={card}\n size={cardSize}\n renderContent={renderCard}\n />\n </button>\n ) : (\n <CardFace\n card={card}\n size={cardSize}\n renderContent={renderCard}\n disabled={!interactive}\n />\n )}\n </motion.div>\n ))}\n </div>\n )}\n </AnimatePresence>\n </div>\n );\n}\n","/**\n * GameSkeleton - Loading state component\n *\n * Displays animated placeholders while game content loads\n */\n\nimport { motion } from \"framer-motion\";\nimport { clsx } from \"clsx\";\nimport { Loader2 } from \"lucide-react\";\n\nconst CARD_SKELETON_KEYS = [\"card-1\", \"card-2\", \"card-3\", \"card-4\", \"card-5\"];\nconst PLAYER_SKELETON_KEYS = [\"player-1\", \"player-2\", \"player-3\", \"player-4\"];\nconst HAND_SKELETON_KEYS = [\n \"hand-card-1\",\n \"hand-card-2\",\n \"hand-card-3\",\n \"hand-card-4\",\n \"hand-card-5\",\n \"hand-card-6\",\n];\n\nexport interface GameSkeletonProps {\n variant?: \"default\" | \"cards\" | \"players\" | \"minimal\";\n message?: string;\n className?: string;\n}\nfunction SkeletonBox({\n className,\n animate = true,\n}: {\n className?: string;\n animate?: boolean;\n}) {\n return (\n <motion.div\n className={clsx(\"bg-slate-200 rounded\", className)}\n animate={\n animate\n ? {\n opacity: [0.5, 1, 0.5],\n }\n : undefined\n }\n transition={{\n duration: 1.5,\n repeat: Infinity,\n ease: \"easeInOut\",\n }}\n aria-hidden=\"true\"\n />\n );\n}\n\nfunction CardSkeleton({ size = \"md\" }: { size?: \"sm\" | \"md\" | \"lg\" }) {\n const sizeClasses = {\n sm: \"w-16 h-24 sm:w-20 sm:h-28\",\n md: \"w-20 h-32 sm:w-24 sm:h-36\",\n lg: \"w-24 h-36 sm:w-32 sm:h-48\",\n };\n\n return (\n <motion.div\n className={clsx(\n \"rounded-lg sm:rounded-xl overflow-hidden\",\n sizeClasses[size],\n )}\n initial={{ opacity: 0, y: 20 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ type: \"spring\", stiffness: 300, damping: 25 }}\n >\n <SkeletonBox className=\"w-full h-full\" />\n </motion.div>\n );\n}\n\nfunction PlayerSkeleton() {\n return (\n <div className=\"flex items-center gap-3 p-3 bg-white/80 rounded-xl border-2 border-slate-200\">\n <SkeletonBox className=\"w-12 h-12 sm:w-14 sm:h-14 rounded-full\" />\n <div className=\"flex-1 space-y-2\">\n <SkeletonBox className=\"h-4 w-24 sm:w-32\" />\n <SkeletonBox className=\"h-3 w-16 sm:w-20\" />\n </div>\n </div>\n );\n}\n\nexport function GameSkeleton({\n variant = \"default\",\n message = \"Loading game...\",\n className,\n}: GameSkeletonProps) {\n if (variant === \"minimal\") {\n return (\n <div\n className={clsx(\n \"flex flex-col items-center justify-center min-h-screen p-8 bg-gradient-to-br from-slate-50 to-slate-100\",\n className,\n )}\n role=\"status\"\n aria-live=\"polite\"\n aria-label={message}\n >\n <motion.div\n animate={{ rotate: 360 }}\n transition={{ duration: 1, repeat: Infinity, ease: \"linear\" }}\n >\n <Loader2 size={48} className=\"text-blue-500\" aria-hidden=\"true\" />\n </motion.div>\n <motion.p\n className=\"mt-4 text-slate-600 text-lg font-medium\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ delay: 0.2 }}\n >\n {message}\n </motion.p>\n </div>\n );\n }\n\n if (variant === \"cards\") {\n return (\n <div\n className={clsx(\n \"flex flex-col items-center justify-center min-h-screen p-4 sm:p-8\",\n className,\n )}\n role=\"status\"\n aria-live=\"polite\"\n aria-label={message}\n >\n <div className=\"flex gap-2 sm:gap-4 mb-8\">\n {CARD_SKELETON_KEYS.map((key, i) => (\n <motion.div\n key={key}\n initial={{ opacity: 0, y: 20 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ delay: i * 0.1 }}\n >\n <CardSkeleton />\n </motion.div>\n ))}\n </div>\n <motion.p\n className=\"text-slate-600 text-sm sm:text-base\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ delay: 0.5 }}\n >\n {message}\n </motion.p>\n </div>\n );\n }\n\n if (variant === \"players\") {\n return (\n <div\n className={clsx(\n \"flex flex-col items-center justify-center min-h-screen p-4 sm:p-8\",\n className,\n )}\n role=\"status\"\n aria-live=\"polite\"\n aria-label={message}\n >\n <div className=\"w-full max-w-md space-y-4 mb-8\">\n {PLAYER_SKELETON_KEYS.map((key, i) => (\n <motion.div\n key={key}\n initial={{ opacity: 0, x: -20 }}\n animate={{ opacity: 1, x: 0 }}\n transition={{ delay: i * 0.1 }}\n >\n <PlayerSkeleton />\n </motion.div>\n ))}\n </div>\n <motion.p\n className=\"text-slate-600 text-sm sm:text-base\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ delay: 0.4 }}\n >\n {message}\n </motion.p>\n </div>\n );\n }\n\n // Default variant - complete game layout\n return (\n <div\n className={clsx(\n \"min-h-screen p-4 sm:p-8 bg-gradient-to-br from-slate-50 to-slate-100\",\n className,\n )}\n role=\"status\"\n aria-live=\"polite\"\n aria-label={message}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between mb-6 sm:mb-8\">\n <SkeletonBox className=\"h-8 w-32 sm:w-48\" />\n <SkeletonBox className=\"h-8 w-20 sm:w-32\" />\n </div>\n\n {/* Players */}\n <div className=\"grid grid-cols-2 lg:grid-cols-4 gap-3 sm:gap-4 mb-6 sm:mb-8\">\n {PLAYER_SKELETON_KEYS.map((key, i) => (\n <motion.div\n key={key}\n initial={{ opacity: 0, scale: 0.9 }}\n animate={{ opacity: 1, scale: 1 }}\n transition={{ delay: i * 0.1 }}\n >\n <PlayerSkeleton />\n </motion.div>\n ))}\n </div>\n\n {/* Play area */}\n <div className=\"mb-6 sm:mb-8\">\n <SkeletonBox className=\"w-full h-48 sm:h-64 rounded-2xl\" />\n </div>\n\n {/* Hand */}\n <div className=\"flex justify-center gap-2 sm:gap-4\">\n {HAND_SKELETON_KEYS.map((key, i) => (\n <motion.div\n key={key}\n initial={{ opacity: 0, y: 20 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ delay: 0.4 + i * 0.05 }}\n >\n <CardSkeleton />\n </motion.div>\n ))}\n </div>\n\n {/* Loading message */}\n <motion.div\n className=\"flex items-center justify-center mt-8\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ delay: 0.8 }}\n >\n <Loader2\n size={24}\n className=\"text-blue-500 animate-spin mr-3\"\n aria-hidden=\"true\"\n />\n <p className=\"text-slate-600 text-sm sm:text-base font-medium\">\n {message}\n </p>\n </motion.div>\n </div>\n );\n}\n","/**\n * Plugin-internal toast notification system.\n *\n * `<ToastProvider>` exposes `<Toast.Actions>` for game-specific feedback\n * (\"Resource gained\", \"Card discarded\", \"Tip: rotate the board with R\", …).\n * It is intentionally NOT wired to the host notification stream:\n * `YOUR_TURN`, `PROMPT_OPENED` and `ACTION_REJECTED` events are owned\n * by the product host runtime's `<HostFeedbackToaster>` and must\n * not be mirrored from inside the plugin tree.\n */\n\nimport { motion, AnimatePresence } from \"framer-motion\";\nimport { X, CheckCircle, AlertCircle, Info, AlertTriangle } from \"lucide-react\";\nimport { Alert, AlertDescription } from \"../internal/ui/alert.js\";\nimport {\n createContext,\n useContext,\n useState,\n useCallback,\n type ReactNode,\n} from \"react\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\nimport { intentForVariant, type ButtonVariant } from \"../theme/derive.js\";\nimport type { Theme } from \"../theme/tokens.js\";\nimport { ThemedButton } from \"./ThemedButton.js\";\n\nexport type ToastType = \"success\" | \"error\" | \"info\" | \"warning\";\n\nexport interface ToastNotification {\n id: string;\n type: ToastType;\n message: string;\n duration?: number;\n}\n\ninterface ToastContextValue {\n toasts: ToastNotification[];\n show: (message: string, type?: ToastType, duration?: number) => void;\n dismiss: (id: string) => void;\n success: (message: string, duration?: number) => void;\n error: (message: string, duration?: number) => void;\n info: (message: string, duration?: number) => void;\n warning: (message: string, duration?: number) => void;\n}\n\nconst ToastContext = createContext<ToastContextValue | null>(null);\n\nexport type ToastActionsValue = ToastContextValue;\n\nexport interface ToastProviderProps {\n children: ReactNode;\n}\n\nexport function ToastProvider({ children }: ToastProviderProps) {\n const [toasts, setToasts] = useState<ToastNotification[]>([]);\n\n const show = useCallback(\n (message: string, type: ToastType = \"info\", duration = 3000) => {\n const id = `toast-${Date.now()}-${Math.random()}`;\n const toast: ToastNotification = { id, type, message, duration };\n\n setToasts((prev) => {\n // Dedup by `(type, message)` so a fast burst of identical\n // toasts collapses to one visible toast instead of stacking\n // and producing the flicker effect (toast-1 dismisses while\n // toast-2 mounts → user sees a flash). Keep the existing\n // entry untouched so its dismiss timer continues.\n if (\n prev.some((item) => item.type === type && item.message === message)\n ) {\n return prev;\n }\n return [...prev, toast];\n });\n\n if (duration > 0) {\n setTimeout(() => {\n setToasts((prev) => prev.filter((t) => t.id !== id));\n }, duration);\n }\n },\n [],\n );\n\n const dismiss = useCallback((id: string) => {\n setToasts((prev) => prev.filter((t) => t.id !== id));\n }, []);\n\n const success = useCallback(\n (message: string, duration?: number) => show(message, \"success\", duration),\n [show],\n );\n const error = useCallback(\n (message: string, duration?: number) => show(message, \"error\", duration),\n [show],\n );\n const info = useCallback(\n (message: string, duration?: number) => show(message, \"info\", duration),\n [show],\n );\n const warning = useCallback(\n (message: string, duration?: number) => show(message, \"warning\", duration),\n [show],\n );\n\n return (\n <ToastContext.Provider\n value={{ toasts, show, dismiss, success, error, info, warning }}\n >\n {children}\n <ToastContainer toasts={toasts} onDismiss={dismiss} />\n </ToastContext.Provider>\n );\n}\n\nexport function useToast() {\n const context = useContext(ToastContext);\n if (!context) {\n throw new Error(\"useToast must be used within ToastProvider\");\n }\n return context;\n}\n\nexport interface ToastActionsProps {\n children: (actions: ToastActionsValue) => ReactNode;\n}\n\nexport function ToastActions({ children }: ToastActionsProps) {\n return <>{children(useToast())}</>;\n}\n\nexport const Toast = {\n Actions: ToastActions,\n} as const;\n\nfunction ToastContainer({\n toasts,\n onDismiss,\n}: {\n toasts: ToastNotification[];\n onDismiss: (id: string) => void;\n}) {\n return (\n <div\n className=\"fixed bottom-4 right-4 z-50 flex flex-col gap-2 pointer-events-none\"\n role=\"region\"\n aria-live=\"polite\"\n aria-label=\"Notifications\"\n >\n <AnimatePresence>\n {toasts.map((toast) => (\n <ToastItem key={toast.id} toast={toast} onDismiss={onDismiss} />\n ))}\n </AnimatePresence>\n </div>\n );\n}\n\nconst TOAST_ICONS = {\n success: CheckCircle,\n error: AlertCircle,\n info: Info,\n warning: AlertTriangle,\n} as const satisfies Record<ToastType, unknown>;\n\nconst TOAST_VARIANT: Record<\n ToastType,\n Exclude<ButtonVariant, \"ghost\" | \"secondary\">\n> = {\n success: \"success\",\n error: \"danger\",\n info: \"info\",\n warning: \"warning\",\n};\n\nfunction toastSurfaceStyle(theme: Theme, type: ToastType): React.CSSProperties {\n const intent = intentForVariant(theme, TOAST_VARIANT[type]);\n return {\n minWidth: 280,\n maxWidth: 400,\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: theme.space[3],\n padding: theme.space[4],\n background: intent.soft,\n color: intent.onSoft,\n border: `2px solid ${intent.border}`,\n borderRadius: theme.radius.lg,\n boxShadow: theme.elevation.lifted,\n backdropFilter: \"blur(4px)\",\n WebkitBackdropFilter: \"blur(4px)\",\n fontFamily: theme.typography.fontFamily.body,\n };\n}\n\nfunction ToastItem({\n toast,\n onDismiss,\n}: {\n toast: ToastNotification;\n onDismiss: (id: string) => void;\n}) {\n const theme = useTheme();\n const reducedMotion = theme.motion.reducedMotion === \"true\";\n const Icon = TOAST_ICONS[toast.type];\n const intent = intentForVariant(theme, TOAST_VARIANT[toast.type]);\n const surfaceStyle = toastSurfaceStyle(theme, toast.type);\n\n return (\n <motion.div\n style={{ pointerEvents: \"auto\" }}\n initial={\n reducedMotion ? { opacity: 0 } : { opacity: 0, y: 20, scale: 0.9 }\n }\n animate={reducedMotion ? { opacity: 1 } : { opacity: 1, y: 0, scale: 1 }}\n exit={reducedMotion ? { opacity: 0 } : { opacity: 0, x: 100, scale: 0.9 }}\n transition={{ type: \"spring\", stiffness: 300, damping: 25 }}\n >\n <Alert\n variant={toast.type === \"error\" ? \"destructive\" : \"default\"}\n style={surfaceStyle}\n >\n <Icon\n size={20}\n style={{\n marginTop: 2,\n flexShrink: 0,\n color: intent.solid,\n }}\n aria-hidden=\"true\"\n />\n\n <AlertDescription\n style={{\n flex: 1,\n fontSize: theme.typography.fontSize.sm,\n fontWeight: theme.typography.fontWeight.medium,\n lineHeight: theme.typography.lineHeight.relaxed,\n color: intent.onSoft,\n }}\n >\n {toast.message}\n </AlertDescription>\n\n <ThemedButton\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => onDismiss(toast.id)}\n style={{\n height: 28,\n width: 28,\n flexShrink: 0,\n borderRadius: theme.radius.pill,\n color: intent.onSoft,\n }}\n aria-label=\"Close notification\"\n >\n <X size={16} aria-hidden=\"true\" />\n </ThemedButton>\n </Alert>\n </motion.div>\n );\n}\n","import * as React from \"react\";\nimport { cn } from \"./utils.js\";\n\nexport interface AlertProps extends React.ComponentProps<\"div\"> {\n variant?: \"default\" | \"destructive\";\n}\n\nexport function Alert({\n className,\n variant = \"default\",\n ...props\n}: AlertProps) {\n return (\n <div\n data-slot=\"alert\"\n role=\"alert\"\n className={cn(\n \"relative grid w-full grid-cols-[0_1fr] items-start gap-y-0.5 rounded-lg border px-4 py-3 text-sm has-[>svg]:grid-cols-[1rem_1fr] has-[>svg]:gap-x-3 [&>svg]:translate-y-0.5\",\n variant === \"destructive\" && \"border-red-300 text-red-800\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport function AlertTitle({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-title\"\n className={cn(\"col-start-2 font-medium tracking-tight\", className)}\n {...props}\n />\n );\n}\n\nexport function AlertDescription({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-description\"\n className={cn(\"col-start-2 text-sm opacity-90\", className)}\n {...props}\n />\n );\n}\n","/**\n * ErrorBoundary component\n *\n * Catches React errors and displays a fallback UI.\n *\n * Visuals are sourced from the public `--db-*` theme variables so that\n * mounting under {@link ThemeProvider} reskins the fallback automatically.\n * Fallback values match the calm `tabletop` preset, so the surface still\n * reads correctly when the boundary catches an error before any provider\n * could mount (a common case during startup).\n */\n\nimport {\n Component,\n type CSSProperties,\n type ReactNode,\n type ErrorInfo,\n} from \"react\";\nimport { AlertTriangle, RefreshCw } from \"lucide-react\";\nimport { cssVarOr } from \"../theme/css-vars.js\";\n\nexport interface ErrorBoundaryProps {\n children: ReactNode;\n fallback?: (error: Error, reset: () => void) => ReactNode;\n onError?: (error: Error, errorInfo: ErrorInfo) => void;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n}\n\nexport class ErrorBoundary extends Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false, error: null };\n }\n\n static getDerivedStateFromError(error: Error): ErrorBoundaryState {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo): void {\n // eslint-disable-next-line no-console\n console.error(\"[ErrorBoundary] Caught error:\", error, errorInfo);\n this.props.onError?.(error, errorInfo);\n }\n\n handleReset = (): void => {\n this.setState({ hasError: false, error: null });\n };\n\n render(): ReactNode {\n if (this.state.hasError && this.state.error) {\n if (this.props.fallback) {\n return this.props.fallback(this.state.error, this.handleReset);\n }\n\n return (\n <DefaultErrorFallback\n error={this.state.error}\n onReset={this.handleReset}\n />\n );\n }\n\n return this.props.children;\n }\n}\n\n/**\n * Stable, theme-driven default tokens for the fallback UI.\n *\n * Each value resolves through `--db-*` theme variables when a\n * {@link ThemeProvider} ancestor is present, and falls back to the\n * tabletop preset's calm baseline when the boundary renders standalone.\n */\nconst FALLBACK_TOKENS = {\n appSurface: cssVarOr(\"#fdfbf7\", \"semantic\", \"surface\", \"app\"),\n panelSurface: cssVarOr(\"#ffffff\", \"semantic\", \"surface\", \"card\"),\n insetSurface: cssVarOr(\"#f8fafc\", \"semantic\", \"surface\", \"inset\"),\n textPrimary: cssVarOr(\"#1f2937\", \"semantic\", \"text\", \"primary\"),\n textMuted: cssVarOr(\"#475569\", \"semantic\", \"text\", \"muted\"),\n textDisabled: cssVarOr(\"#94a3b8\", \"semantic\", \"text\", \"disabled\"),\n borderSubtle: cssVarOr(\"#e2e8f0\", \"semantic\", \"border\", \"subtle\"),\n borderDefault: cssVarOr(\"#cbd5e1\", \"semantic\", \"border\", \"default\"),\n dangerSoft: cssVarOr(\"#fee2e2\", \"semantic\", \"intent\", \"danger\", \"soft\"),\n dangerBorder: cssVarOr(\"#991b1b\", \"semantic\", \"intent\", \"danger\", \"border\"),\n dangerOnSoft: cssVarOr(\"#991b1b\", \"semantic\", \"intent\", \"danger\", \"onSoft\"),\n primarySolid: cssVarOr(\"#0f172a\", \"semantic\", \"intent\", \"primary\", \"solid\"),\n primaryOn: cssVarOr(\"#ffffff\", \"semantic\", \"intent\", \"primary\", \"on\"),\n primaryBorder: cssVarOr(\"#0f172a\", \"semantic\", \"intent\", \"primary\", \"border\"),\n fontBody: cssVarOr(\n \"system-ui, -apple-system, Segoe UI, Roboto, sans-serif\",\n \"typography\",\n \"fontFamily\",\n \"body\",\n ),\n fontDisplay: cssVarOr(\n \"system-ui, -apple-system, Segoe UI, Roboto, sans-serif\",\n \"typography\",\n \"fontFamily\",\n \"display\",\n ),\n fontMono: cssVarOr(\n \"ui-monospace, SFMono-Regular, monospace\",\n \"typography\",\n \"fontFamily\",\n \"mono\",\n ),\n radiusMd: cssVarOr(\"8px\", \"radius\", \"md\"),\n radiusLg: cssVarOr(\"12px\", \"radius\", \"lg\"),\n radiusPill: cssVarOr(\"999px\", \"radius\", \"pill\"),\n elevationRest: cssVarOr(\n \"0 4px 12px rgba(15, 23, 42, 0.08)\",\n \"elevation\",\n \"rest\",\n ),\n} as const;\n\nexport function DefaultErrorFallback({\n error,\n onReset,\n}: {\n error: Error;\n onReset: () => void;\n}) {\n const t = FALLBACK_TOKENS;\n const styles = {\n shell: {\n alignItems: \"center\",\n background: t.appSurface,\n boxSizing: \"border-box\",\n color: t.textPrimary,\n display: \"flex\",\n fontFamily: t.fontBody,\n justifyContent: \"center\",\n minHeight: \"100vh\",\n padding: \"24px\",\n },\n panel: {\n background: t.panelSurface,\n border: `1px solid ${t.borderSubtle}`,\n borderRadius: t.radiusLg,\n boxShadow: t.elevationRest,\n boxSizing: \"border-box\",\n maxWidth: \"520px\",\n padding: \"28px\",\n width: \"100%\",\n },\n iconWrap: {\n alignItems: \"center\",\n background: t.dangerSoft,\n border: `1px solid ${t.dangerBorder}`,\n borderRadius: t.radiusPill,\n display: \"flex\",\n height: \"56px\",\n justifyContent: \"center\",\n marginBottom: \"18px\",\n width: \"56px\",\n },\n eyebrow: {\n color: t.dangerOnSoft,\n fontSize: \"12px\",\n fontWeight: 700,\n letterSpacing: \"0.08em\",\n margin: \"0 0 8px\",\n textTransform: \"uppercase\",\n },\n title: {\n color: t.textPrimary,\n fontFamily: t.fontDisplay,\n fontSize: \"28px\",\n fontWeight: 800,\n lineHeight: 1.1,\n margin: \"0 0 12px\",\n },\n body: {\n color: t.textMuted,\n fontSize: \"15px\",\n lineHeight: 1.5,\n margin: \"0 0 20px\",\n },\n details: {\n marginBottom: \"22px\",\n },\n summary: {\n color: t.textPrimary,\n cursor: \"pointer\",\n fontSize: \"14px\",\n fontWeight: 600,\n marginBottom: \"8px\",\n },\n pre: {\n background: t.insetSurface,\n border: `1px solid ${t.borderDefault}`,\n borderRadius: t.radiusMd,\n color: t.textMuted,\n fontFamily: t.fontMono,\n fontSize: \"12px\",\n lineHeight: 1.45,\n margin: 0,\n maxHeight: \"180px\",\n overflow: \"auto\",\n padding: \"12px\",\n whiteSpace: \"pre-wrap\",\n },\n button: {\n alignItems: \"center\",\n background: t.primarySolid,\n border: `1px solid ${t.primaryBorder}`,\n borderRadius: t.radiusMd,\n color: t.primaryOn,\n cursor: \"pointer\",\n display: \"inline-flex\",\n fontFamily: t.fontBody,\n fontSize: \"15px\",\n fontWeight: 700,\n gap: \"8px\",\n justifyContent: \"center\",\n padding: \"12px 16px\",\n width: \"100%\",\n },\n } satisfies Record<string, CSSProperties>;\n\n return (\n <div\n data-dreamboard-error-fallback=\"\"\n style={styles.shell}\n role=\"alert\"\n aria-live=\"assertive\"\n >\n <div style={styles.panel}>\n <div style={styles.iconWrap}>\n <AlertTriangle\n size={28}\n color={t.dangerBorder}\n strokeWidth={2.25}\n aria-hidden=\"true\"\n />\n </div>\n\n <p style={styles.eyebrow}>Runtime error</p>\n\n <h1 style={styles.title}>Game failed to start</h1>\n\n <p style={styles.body}>\n The game encountered an error and couldn't continue. You can try\n reloading to start fresh.\n </p>\n\n <details style={styles.details}>\n <summary style={styles.summary}>Technical details</summary>\n <pre style={styles.pre}>\n {error.message}\n {error.stack && (\n <>\n {\"\\n\\n\"}\n {error.stack}\n </>\n )}\n </pre>\n </details>\n\n <button type=\"button\" onClick={onReset} style={styles.button}>\n <RefreshCw size={18} aria-hidden=\"true\" />\n Try again\n </button>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { XIcon } from \"lucide-react\";\nimport { cn } from \"./utils.js\";\n\nexport function Dialog(\n props: React.ComponentProps<typeof DialogPrimitive.Root>,\n) {\n return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />;\n}\n\nexport function DialogTrigger(\n props: React.ComponentProps<typeof DialogPrimitive.Trigger>,\n) {\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />;\n}\n\nexport function DialogPortal(\n props: React.ComponentProps<typeof DialogPrimitive.Portal>,\n) {\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />;\n}\n\nexport function DialogClose(\n props: React.ComponentProps<typeof DialogPrimitive.Close>,\n) {\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />;\n}\n\nexport function DialogOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n return (\n <DialogPrimitive.Overlay\n data-slot=\"dialog-overlay\"\n className={cn(\"fixed inset-0 z-50 bg-black/50\", className)}\n {...props}\n />\n );\n}\n\nexport function DialogContent({\n className,\n children,\n showCloseButton = true,\n overlayClassName,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content> & {\n showCloseButton?: boolean;\n overlayClassName?: string;\n}) {\n return (\n <DialogPortal>\n <DialogOverlay className={overlayClassName} />\n <DialogPrimitive.Content\n data-slot=\"dialog-content\"\n className={cn(\n \"fixed left-1/2 top-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-lg border bg-white p-6 shadow-lg sm:max-w-lg\",\n className,\n )}\n {...props}\n >\n {children}\n {showCloseButton ? (\n <DialogPrimitive.Close\n data-slot=\"dialog-close\"\n className=\"absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-slate-400\"\n >\n <XIcon aria-hidden=\"true\" className=\"size-4\" />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n ) : null}\n </DialogPrimitive.Content>\n </DialogPortal>\n );\n}\n\nexport function DialogHeader({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-header\"\n className={cn(\"flex flex-col gap-2 text-center sm:text-left\", className)}\n {...props}\n />\n );\n}\n\nexport function DialogFooter({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-footer\"\n className={cn(\n \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport function DialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n return (\n <DialogPrimitive.Title\n data-slot=\"dialog-title\"\n className={cn(\"text-lg font-semibold leading-none\", className)}\n {...props}\n />\n );\n}\n\nexport function DialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n return (\n <DialogPrimitive.Description\n data-slot=\"dialog-description\"\n className={cn(\"text-sm text-slate-600\", className)}\n {...props}\n />\n );\n}\n","import * as React from \"react\";\nimport { cn } from \"./utils.js\";\n\nexport function Input({\n className,\n type,\n ...props\n}: React.ComponentProps<\"input\">) {\n return (\n <input\n type={type}\n data-slot=\"input\"\n className={cn(\n \"h-10 w-full min-w-0 rounded-md border border-slate-300 bg-white px-3 py-2 text-base outline-none disabled:cursor-not-allowed disabled:opacity-50\",\n \"focus-visible:border-slate-600 focus-visible:ring-2 focus-visible:ring-slate-300\",\n className,\n )}\n {...props}\n />\n );\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as LabelPrimitive from \"@radix-ui/react-label\";\nimport { cn } from \"./utils.js\";\n\nexport function Label({\n className,\n ...props\n}: React.ComponentProps<typeof LabelPrimitive.Root>) {\n return (\n <LabelPrimitive.Root\n data-slot=\"label\"\n className={cn(\n \"flex items-center gap-2 text-sm font-medium leading-none\",\n className,\n )}\n {...props}\n />\n );\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as SelectPrimitive from \"@radix-ui/react-select\";\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\";\nimport { cn } from \"./utils.js\";\n\nexport function Select(\n props: React.ComponentProps<typeof SelectPrimitive.Root>,\n) {\n return <SelectPrimitive.Root data-slot=\"select\" {...props} />;\n}\n\nexport function SelectTrigger({\n className,\n size = \"default\",\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n size?: \"sm\" | \"default\";\n}) {\n return (\n <SelectPrimitive.Trigger\n data-slot=\"select-trigger\"\n data-size={size}\n className={cn(\n \"flex w-fit items-center justify-between gap-2 rounded-md border border-slate-300 bg-white px-3 py-2 text-sm outline-none disabled:cursor-not-allowed disabled:opacity-50\",\n \"focus-visible:border-slate-600 focus-visible:ring-2 focus-visible:ring-slate-300\",\n size === \"default\" ? \"h-9\" : \"h-8\",\n className,\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDownIcon className=\"size-4 opacity-50\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n );\n}\n\nexport function SelectContent({\n className,\n children,\n position = \"popper\",\n align = \"center\",\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n return (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n data-slot=\"select-content\"\n className={cn(\n \"relative z-50 max-h-[var(--radix-select-content-available-height)] min-w-32 overflow-x-hidden overflow-y-auto rounded-md border bg-white text-slate-950 shadow-md\",\n className,\n )}\n position={position}\n align={align}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport className=\"p-1\">\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n );\n}\n\nexport function SelectItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n return (\n <SelectPrimitive.Item\n data-slot=\"select-item\"\n className={cn(\n \"relative flex w-full cursor-default select-none items-center gap-2 rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-slate-100 data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n className,\n )}\n {...props}\n >\n <span className=\"absolute right-2 flex size-3.5 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n );\n}\n\nfunction SelectScrollUpButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n return (\n <SelectPrimitive.ScrollUpButton\n data-slot=\"select-scroll-up-button\"\n className={cn(\n \"flex cursor-default items-center justify-center py-1\",\n className,\n )}\n {...props}\n >\n <ChevronUpIcon className=\"size-4\" />\n </SelectPrimitive.ScrollUpButton>\n );\n}\n\nfunction SelectScrollDownButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n return (\n <SelectPrimitive.ScrollDownButton\n data-slot=\"select-scroll-down-button\"\n className={cn(\n \"flex cursor-default items-center justify-center py-1\",\n className,\n )}\n {...props}\n >\n <ChevronDownIcon className=\"size-4\" />\n </SelectPrimitive.ScrollDownButton>\n );\n}\n","import {\n createContext,\n createElement,\n useContext,\n useMemo,\n type ComponentType,\n type HTMLAttributes,\n type ReactElement,\n type ReactNode,\n} from \"react\";\nimport {\n composeEventHandlers,\n renderPrimitive,\n type PrimitiveCommonProps,\n} from \"../primitives/primitive-props.js\";\n\nexport type ResourceId = string;\n\nexport interface ResourceDisplayConfig<Resource extends string = ResourceId> {\n type: Resource;\n label: string;\n icon:\n | ReactNode\n | ComponentType<{\n className?: string;\n strokeWidth?: number;\n \"aria-hidden\"?: boolean | \"true\" | \"false\";\n }>;\n iconColor?: string;\n bgColor?: string;\n textColor?: string;\n}\n\nexport interface ResourceCounterItemState<\n Resource extends string = ResourceId,\n> {\n type: Resource;\n label: string;\n icon: ResourceDisplayConfig<Resource>[\"icon\"];\n iconColor?: string;\n bgColor?: string;\n textColor?: string;\n count: number;\n isZero: boolean;\n interactive: boolean;\n select: () => void;\n renderIcon: (props?: ResourceIconProps) => ReactNode;\n dataAttributes: {\n \"data-resource-id\": Resource;\n \"data-resource-count\": number;\n \"data-resource-zero\": boolean | undefined;\n \"data-interactive\": boolean | undefined;\n };\n}\n\nexport interface ResourceIconProps {\n className?: string;\n strokeWidth?: number;\n \"aria-hidden\"?: boolean | \"true\" | \"false\";\n}\n\nexport type ResourceCounterRootProps<Resource extends string = ResourceId> =\n Omit<PrimitiveCommonProps, \"children\"> &\n Omit<HTMLAttributes<HTMLElement>, \"children\"> & {\n resources: ReadonlyArray<ResourceDisplayConfig<Resource>>;\n counts: Partial<Record<Resource, number>>;\n zero?: \"show\" | \"hide\";\n onResourceClick?: (resourceType: Resource) => void;\n children: ReactNode;\n };\n\nexport type BoundResourceCounterRootProps<\n Resource extends string = ResourceId,\n> = Omit<ResourceCounterRootProps<Resource>, \"resources\">;\n\nexport type ResourceCounterProps<Resource extends string = ResourceId> =\n ResourceCounterRootProps<Resource>;\n\nexport type ResourceCounterPartProps<Resource extends string = ResourceId> =\n Omit<PrimitiveCommonProps, \"children\"> &\n Omit<HTMLAttributes<HTMLElement>, \"children\"> & {\n children?:\n | ReactNode\n | ((resource: ResourceCounterItemState<Resource>) => ReactNode);\n };\n\nconst ResourceCounterItemContext =\n createContext<ResourceCounterItemState<string> | null>(null);\n\nfunction useResourceCounterItemContext<Resource extends string>() {\n const value = useContext(ResourceCounterItemContext);\n if (!value) {\n throw new Error(\n \"ResourceCounter item primitives must be rendered inside <ResourceCounter.Item>.\",\n );\n }\n return value as ResourceCounterItemState<Resource>;\n}\n\nfunction renderResourceIcon(\n icon: ResourceDisplayConfig<string>[\"icon\"],\n props: ResourceIconProps = {},\n) {\n if (typeof icon === \"function\") {\n return createElement(icon, {\n \"aria-hidden\": true,\n strokeWidth: 2.5,\n ...props,\n });\n }\n const {\n strokeWidth: _strokeWidth,\n \"aria-hidden\": ariaHidden,\n ...spanProps\n } = props;\n return (\n <span\n aria-hidden={ariaHidden === undefined ? true : ariaHidden !== \"false\"}\n {...spanProps}\n >\n {icon}\n </span>\n );\n}\n\nfunction resolveResourceChildren<Resource extends string>(\n children: ResourceCounterPartProps<Resource>[\"children\"],\n resource: ResourceCounterItemState<Resource>,\n) {\n return typeof children === \"function\" ? children(resource) : children;\n}\n\nexport function ResourceCounterRoot<Resource extends string = ResourceId>({\n resources,\n counts,\n zero = \"show\",\n onResourceClick,\n children,\n \"aria-label\": ariaLabel,\n ...props\n}: ResourceCounterRootProps<Resource>) {\n const items = useMemo(\n () =>\n resources\n .map((resource) => {\n const count = counts[resource.type] ?? 0;\n return {\n ...resource,\n count,\n isZero: count === 0,\n interactive: Boolean(onResourceClick),\n select: () => onResourceClick?.(resource.type),\n renderIcon: (iconProps) =>\n renderResourceIcon(resource.icon, iconProps),\n dataAttributes: {\n \"data-resource-id\": resource.type,\n \"data-resource-count\": count,\n \"data-resource-zero\": count === 0 || undefined,\n \"data-interactive\": onResourceClick ? true : undefined,\n },\n } satisfies ResourceCounterItemState<Resource>;\n })\n .filter((resource) => zero === \"show\" || !resource.isZero),\n [counts, onResourceClick, resources, zero],\n );\n\n return renderPrimitive(\"div\", {\n role: \"list\",\n \"aria-label\": ariaLabel ?? \"Resource counts\",\n \"data-dreamboard-resource-counter\": \"\",\n ...props,\n children: items.map((resource) => (\n <ResourceCounterItemContext.Provider key={resource.type} value={resource}>\n {children}\n </ResourceCounterItemContext.Provider>\n )),\n });\n}\n\nexport function ResourceCounterItem<Resource extends string = ResourceId>({\n children,\n onClick,\n \"aria-label\": ariaLabel,\n ...props\n}: ResourceCounterPartProps<Resource>) {\n const resource = useResourceCounterItemContext<Resource>();\n return renderPrimitive(\"span\", {\n role: \"listitem\",\n \"aria-label\": ariaLabel ?? `${resource.label}: ${resource.count}`,\n ...resource.dataAttributes,\n ...props,\n onClick: composeEventHandlers(\n onClick,\n resource.interactive ? resource.select : undefined,\n ),\n children: resolveResourceChildren(children, resource),\n });\n}\n\nexport function ResourceCounterIcon<Resource extends string = ResourceId>({\n className,\n strokeWidth,\n \"aria-hidden\": ariaHidden,\n}: ResourceIconProps): ReactNode {\n const resource = useResourceCounterItemContext<Resource>();\n return resource.renderIcon({\n className,\n strokeWidth,\n \"aria-hidden\": ariaHidden,\n });\n}\n\nexport function ResourceCounterCount<Resource extends string = ResourceId>({\n children,\n ...props\n}: ResourceCounterPartProps<Resource>) {\n const resource = useResourceCounterItemContext<Resource>();\n return renderPrimitive(\"span\", {\n ...props,\n \"data-dreamboard-resource-count\": \"\",\n children: resolveResourceChildren(children ?? resource.count, resource),\n });\n}\n\nexport function ResourceCounterLabel<Resource extends string = ResourceId>({\n children,\n ...props\n}: ResourceCounterPartProps<Resource>) {\n const resource = useResourceCounterItemContext<Resource>();\n return renderPrimitive(\"span\", {\n ...props,\n \"data-dreamboard-resource-label\": \"\",\n children: resolveResourceChildren(children ?? resource.label, resource),\n });\n}\n\nexport interface ResourceCounterComponents<\n Resource extends string = ResourceId,\n> {\n Root(props: BoundResourceCounterRootProps<Resource>): ReactElement;\n Item(props: ResourceCounterPartProps<Resource>): ReactElement;\n Icon(props: ResourceIconProps): ReactNode;\n Count(props: ResourceCounterPartProps<Resource>): ReactElement;\n Label(props: ResourceCounterPartProps<Resource>): ReactElement;\n}\n\nexport function createResourceCounter<Resource extends string>(\n resources: ReadonlyArray<ResourceDisplayConfig<Resource>>,\n): ResourceCounterComponents<Resource> {\n return {\n Root(props) {\n return createElement(ResourceCounterRoot<Resource>, {\n ...props,\n resources,\n });\n },\n Item: ResourceCounterItem,\n Icon: ResourceCounterIcon,\n Count: ResourceCounterCount,\n Label: ResourceCounterLabel,\n } satisfies ResourceCounterComponents<Resource>;\n}\n\nexport const ResourceCounter = {\n Root: ResourceCounterRoot,\n Item: ResourceCounterItem,\n Icon: ResourceCounterIcon,\n Count: ResourceCounterCount,\n Label: ResourceCounterLabel,\n};\n","/** Shows resource costs with affordability indication (green/red). */\n\nimport { clsx } from \"clsx\";\nimport type { ComponentType } from \"react\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"../internal/ui/tooltip.js\";\n\nexport interface ResourceDefinition {\n type: string;\n label: string;\n icon?: ComponentType<{ className?: string }>;\n color?: string;\n}\n\nexport interface CostDisplayProps {\n /** Cost requirements keyed by resource type */\n cost: Record<string, number>;\n /** Current resources to check affordability */\n currentResources?: Record<string, number>;\n resourceDefs: ResourceDefinition[];\n size?: \"sm\" | \"md\";\n layout?: \"inline\" | \"stacked\";\n className?: string;\n}\nexport function CostDisplay({\n cost,\n currentResources,\n resourceDefs,\n size = \"sm\",\n layout = \"inline\",\n className,\n}: CostDisplayProps) {\n const resourceMap = Object.fromEntries(resourceDefs.map((r) => [r.type, r]));\n\n const sizeClasses = {\n sm: { icon: \"w-3 h-3\", text: \"text-xs\", gap: \"gap-0.5\" },\n md: { icon: \"w-4 h-4\", text: \"text-sm\", gap: \"gap-1\" },\n };\n\n const styles = sizeClasses[size];\n\n // Calculate total affordability for aria label\n const canAffordAll =\n !currentResources ||\n Object.entries(cost).every(\n ([type, amount]) => (currentResources[type] ?? 0) >= amount,\n );\n\n const costEntries = Object.entries(cost).filter(\n ([, amount]) => amount !== undefined && amount > 0,\n );\n\n if (costEntries.length === 0) {\n return null;\n }\n\n return (\n <div\n className={clsx(\n \"flex\",\n styles.gap,\n layout === \"stacked\" && \"flex-col\",\n layout === \"inline\" && \"flex-row flex-wrap items-center\",\n className,\n )}\n role=\"list\"\n aria-label={`Cost: ${costEntries.map(([type, amount]) => `${amount} ${resourceMap[type]?.label || type}`).join(\", \")}${currentResources ? (canAffordAll ? \" (affordable)\" : \" (cannot afford)\") : \"\"}`}\n >\n <TooltipProvider delayDuration={200}>\n {costEntries.map(([type, amount]) => {\n const def = resourceMap[type];\n const have = currentResources?.[type] ?? Infinity;\n const canAfford = have >= amount;\n const Icon = def?.icon;\n const label = def?.label || type;\n\n return (\n <Tooltip key={type}>\n <TooltipTrigger asChild>\n <div\n className={clsx(\n \"flex cursor-help items-center rounded-sm outline-none focus-visible:ring-2 focus-visible:ring-white/70\",\n styles.gap,\n styles.text,\n currentResources && !canAfford && \"text-red-400\",\n currentResources && canAfford && \"text-green-400\",\n !currentResources && \"text-slate-300\",\n )}\n role=\"listitem\"\n tabIndex={0}\n >\n {Icon && <Icon className={styles.icon} aria-hidden=\"true\" />}\n <span className=\"font-semibold\">{amount}</span>\n {!Icon && (\n <span className=\"text-[10px] opacity-70\">\n {def?.label?.slice(0, 3) || type.slice(0, 3)}\n </span>\n )}\n </div>\n </TooltipTrigger>\n <TooltipContent\n side=\"top\"\n sideOffset={6}\n className=\"max-w-xs text-left\"\n >\n <p className=\"font-sans text-sm font-bold\">{label}</p>\n <p className=\"font-sans mt-1 text-xs font-normal opacity-90\">\n {formatCostAvailability({\n amount,\n canAfford,\n have,\n })}\n </p>\n </TooltipContent>\n </Tooltip>\n );\n })}\n </TooltipProvider>\n </div>\n );\n}\n\n/** Second line under the resource name — avoids repeating {@link label} in the tooltip. */\nfunction formatCostAvailability({\n amount,\n canAfford,\n have,\n}: {\n amount: number;\n canAfford: boolean;\n have: number;\n}) {\n if (!Number.isFinite(have)) {\n return `Cost: ${amount}.`;\n }\n\n const missing = Math.max(0, amount - have);\n return canAfford\n ? `Cost: ${amount}. You have ${have}.`\n : `Cost: ${amount}. You have ${have}; short by ${missing}.`;\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\nimport { cn } from \"./utils.js\";\n\nexport function TooltipProvider({\n delayDuration = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delayDuration={delayDuration}\n {...props}\n />\n );\n}\n\nexport function Tooltip(\n props: React.ComponentProps<typeof TooltipPrimitive.Root>,\n) {\n return (\n <TooltipProvider>\n <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n </TooltipProvider>\n );\n}\n\nexport function TooltipTrigger(\n props: React.ComponentProps<typeof TooltipPrimitive.Trigger>,\n) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />;\n}\n\nexport function TooltipContent({\n className,\n sideOffset = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n \"z-50 w-fit rounded-md border border-slate-900 bg-white px-3 py-2 text-sm font-semibold text-slate-950 shadow-md\",\n className,\n )}\n {...props}\n />\n </TooltipPrimitive.Portal>\n );\n}\n","import type {\n ButtonHTMLAttributes,\n ElementType,\n MouseEvent,\n ReactNode,\n} from \"react\";\nimport type { ButtonSize, ButtonVariant } from \"../theme/derive.js\";\nimport type { InteractionVisualState } from \"../types/visual-state.js\";\nimport { CostDisplay, type ResourceDefinition } from \"./CostDisplay.js\";\nimport { ThemedButton } from \"./ThemedButton.js\";\n\nexport interface ActionButtonProps\n extends\n Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\">,\n InteractionVisualState {\n label?: ReactNode;\n description?: ReactNode;\n icon?: ElementType<{ className?: string }>;\n cost?: Record<string, number>;\n currentResources?: Record<string, number>;\n resourceDefs?: ResourceDefinition[];\n available?: boolean;\n disabledReason?: string;\n loading?: boolean;\n variant?: ButtonVariant;\n size?: ButtonSize;\n children?: ReactNode;\n}\n\nexport function ActionButton({\n label,\n description,\n icon,\n cost,\n currentResources,\n resourceDefs,\n available = true,\n disabledReason,\n loading = false,\n disabled,\n eligible,\n selected,\n invalid,\n submitted,\n previewing,\n intentProgress,\n title,\n variant = \"secondary\",\n size = \"md\",\n children,\n onClick,\n ...rest\n}: ActionButtonProps) {\n const isDisabled = disabled || loading || !available;\n const Icon = icon;\n const resolvedTitle = title ?? (!available ? disabledReason : undefined);\n\n function handleClick(event: MouseEvent<HTMLButtonElement>) {\n if (isDisabled) return;\n onClick?.(event);\n }\n\n return (\n <ThemedButton\n type=\"button\"\n variant={variant}\n size={size}\n disabled={isDisabled}\n eligible={eligible ?? (available && !isDisabled ? undefined : undefined)}\n selected={selected}\n invalid={invalid}\n submitted={submitted}\n previewing={previewing}\n intentProgress={intentProgress}\n loading={loading}\n title={resolvedTitle}\n onClick={handleClick}\n {...rest}\n >\n {Icon ? <Icon className=\"h-4 w-4\" aria-hidden=\"true\" /> : null}\n <span className=\"inline-flex min-w-0 flex-col items-start gap-0.5\">\n <span>{children ?? label ?? \"Action\"}</span>\n {description ? (\n <span className=\"text-xs font-normal opacity-75\">{description}</span>\n ) : null}\n {cost && resourceDefs ? (\n <CostDisplay\n cost={cost}\n currentResources={currentResources}\n resourceDefs={resourceDefs}\n />\n ) : null}\n </span>\n {loading ? <span aria-hidden=\"true\">...</span> : null}\n </ThemedButton>\n );\n}\n","/**\n * Minimally-styled primary action button.\n *\n * Visual styling now flows through {@link buttonStyle}: the background,\n * border, foreground, radius, typography and elevation all derive from\n * the active {@link useTheme}'s `intent.primary` slot. Override the\n * variant when a non-primary call site needs a different emphasis (the\n * underlying `<DefaultInteractionButton>` is the canonical button for\n * interaction-bound submission).\n */\n\nimport type { ButtonHTMLAttributes } from \"react\";\nimport type { ButtonSize, ButtonVariant } from \"../theme/derive.js\";\nimport type { InteractionVisualState } from \"../types/visual-state.js\";\nimport { ThemedButton } from \"./ThemedButton.js\";\n\nexport interface PrimaryButtonProps\n extends ButtonHTMLAttributes<HTMLButtonElement>, InteractionVisualState {\n /** Intent slot — defaults to `primary`. */\n variant?: ButtonVariant;\n /** Sizing token — defaults to `md`. */\n size?: ButtonSize;\n}\n\nexport function PrimaryButton({\n children,\n disabled,\n style,\n variant = \"primary\",\n size = \"md\",\n ...rest\n}: PrimaryButtonProps) {\n return (\n <ThemedButton\n type=\"button\"\n disabled={disabled}\n variant={variant}\n size={size}\n style={style}\n {...rest}\n >\n {children}\n </ThemedButton>\n );\n}\n","/**\n * Theme-aware controlled primary CTA button — the dominant call-to-action on\n * the screen at any given moment (\"Roll dice\", \"End turn\", \"Confirm\n * trade\", \"Place settlement\").\n *\n * Visual contract (Laws of UX cross-references):\n *\n * - **Fitts** — defaults to `lg` size (min 56px tall, generous\n * horizontal padding) so the dock target is easy to land on.\n * Authors can opt down to `md`.\n * - **Von Restorff (isolation)** — uses `intent.primary.solid` with\n * `elevation.lifted` and an animated halo when `attention=\"auto\"`\n * and `available` is true, so the button outranks every other\n * element in its peripheral neighbourhood.\n * - **Peak-end** — when the action becomes available, the halo pulses for one breath cycle\n * so the eye finds the change without re-scanning the screen.\n * - **Doherty / responsiveness** — clicks set an internal `pending`\n * flag the moment submit fires so the button visibly absorbs the\n * tap, even on slow networks. Throwing submitters are swallowed\n * here for the same reason `<DefaultInteractionButton>` does:\n * descriptor availability is authoritative.\n * - **Accessibility** — minimum 56×56 hit area satisfies WCAG 2.5.5.\n * `prefers-reduced-motion` zeroes out the halo and press\n * transitions through the theme's `motion.reducedMotion` token.\n */\n\nimport {\n useEffect,\n useRef,\n useState,\n type CSSProperties,\n type MouseEvent,\n type ReactNode,\n} from \"react\";\nimport { motion } from \"framer-motion\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\nimport {\n intentForVariant,\n type ButtonSize,\n type ButtonVariant,\n} from \"../theme/derive.js\";\nimport type { InteractionVisualState } from \"../types/visual-state.js\";\nimport { ThemedButton } from \"./ThemedButton.js\";\n\n/** Attention-pulse policy for the trailing halo. */\nexport type PrimaryActionAttention = \"auto\" | \"always\" | \"off\";\n\nexport interface SubmittedActionConfig {\n label?: ReactNode;\n icon?: ReactNode;\n variant?: ButtonVariant;\n}\n\nexport interface PrimaryActionButtonProps extends InteractionVisualState {\n /**\n * Override the visual variant. Defaults to `primary` (which maps\n * to `intent.primary` regardless of the descriptor's `emphasis`\n * hint — the shell's primary slot is, by definition, primary).\n */\n variant?: ButtonVariant;\n /**\n * Sizing. Defaults to `lg` so the dock target is comfortable on\n * touch and visually outranks panel buttons sized `md`.\n */\n size?: ButtonSize;\n /**\n * Override the label inferred from `descriptor.label`. Use only\n * when the descriptor's label needs phase-specific copy that the\n * authoring layer can't express.\n */\n label?: ReactNode;\n /** Client-side draft readiness. Reducer availability remains authoritative. */\n ready?: boolean;\n /** Whether the action is currently available according to the caller. */\n available?: boolean;\n /** Optional reason rendered as the disabled tooltip. */\n unavailableReason?: string;\n /** External submission state. */\n submitting?: boolean;\n /** External submitted state. */\n submitted?: boolean;\n /** Copy and visual overrides once this interaction has been submitted. */\n whenSubmitted?: SubmittedActionConfig;\n /**\n * Optional leading icon override. When omitted, falls back to\n * `descriptor.icon` (an emoji glyph from the authoring spec).\n */\n icon?: ReactNode;\n /** Stable identifier for diagnostics and tests. */\n actionId?: string;\n /** Called when the controlled action is activated. */\n onAction?: () => void | Promise<void>;\n /**\n * Attention-halo policy. `auto` (default) pulses the halo for one\n * breath when the button transitions from disabled → enabled (so\n * the user sees the moment the action becomes available), then\n * settles into a slow ambient breath while the action remains\n * available. `always` keeps the breath running unconditionally.\n * `off` suppresses the halo entirely.\n *\n * Ignored when `theme.motion.reducedMotion === \"true\"`.\n */\n attention?: PrimaryActionAttention;\n /** Additional inline style merged after the resolved button style. */\n style?: CSSProperties;\n /** Optional className for downstream styling hooks. */\n className?: string;\n}\n\n/**\n * @see PrimaryActionButtonProps\n */\nexport function PrimaryActionButton({\n variant = \"primary\",\n size = \"lg\",\n label = \"Action\",\n ready = true,\n available: availableProp = true,\n unavailableReason,\n submitting: submittingProp = false,\n submitted = false,\n whenSubmitted,\n icon,\n actionId,\n onAction,\n attention = \"auto\",\n style,\n className,\n}: PrimaryActionButtonProps) {\n const theme = useTheme();\n const reducedMotion = theme.motion.reducedMotion === \"true\";\n const [pending, setPending] = useState(false);\n\n const submitting = submittingProp || pending;\n const available = availableProp && ready && !submitted && !submitting;\n const resolvedVariant = submitted\n ? (whenSubmitted?.variant ?? \"submitted\")\n : variant;\n const disabled = !available;\n const intent = intentForVariant(theme, resolvedVariant);\n\n // Pulse the halo for one breath when availability flips on. After\n // the breath we settle into the ambient cadence (or stop, when\n // `attention` is `off`). Tracking the previous availability lets\n // us catch the transition without re-mounting the component.\n const previouslyAvailableRef = useRef(available);\n const [pulseKey, setPulseKey] = useState(0);\n useEffect(() => {\n if (!previouslyAvailableRef.current && available) {\n setPulseKey((n) => n + 1);\n }\n previouslyAvailableRef.current = available;\n }, [available]);\n\n const haloEnabled =\n !reducedMotion && available && attention !== \"off\" && !submitted;\n\n const tooltip = available\n ? undefined\n : formatUnavailableReason(unavailableReason);\n\n const resolvedLabel: ReactNode = submitted\n ? (whenSubmitted?.label ?? label)\n : label;\n const resolvedIcon: ReactNode =\n submitted && whenSubmitted?.icon ? (\n <span aria-hidden style={{ fontSize: \"1.15em\" }}>\n {whenSubmitted.icon}\n </span>\n ) : (\n (icon ?? null)\n );\n\n return (\n <span\n data-dreamboard-primary-action\n data-available={available ? \"true\" : \"false\"}\n data-pending={submitting ? \"true\" : undefined}\n data-action-state={\n submitted\n ? \"submitted\"\n : submitting\n ? \"submitting\"\n : available\n ? \"available\"\n : \"unavailable\"\n }\n style={{\n position: \"relative\",\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n // The halo overflows the button bounds; the wrapper reserves\n // a transparent buffer so it doesn't get clipped by the\n // dock's safe-area frame.\n padding: theme.space[1],\n }}\n >\n {haloEnabled ? (\n <>\n {/*\n Ambient breath — slow, low-amplitude, runs as long as the\n action is available. The outer `haloEnabled` already\n short-circuits when `attention === \"off\"`, so this layer\n is gated purely on the availability + reduced-motion\n checks.\n */}\n <motion.span\n aria-hidden\n style={{\n position: \"absolute\",\n inset: 0,\n borderRadius: theme.radius.md,\n background: intent.soft,\n opacity: 0.55,\n pointerEvents: \"none\",\n }}\n animate={{\n scale: [1, 1.06, 1],\n opacity: [0.45, 0.18, 0.45],\n }}\n transition={{\n repeat: Infinity,\n duration: 2.4,\n ease: \"easeInOut\",\n }}\n />\n {/*\n One-shot announce pulse keyed on `pulseKey` — re-mounts\n (and thus re-runs) every time availability flips on so the\n eye registers the change. We use a separate layer (rather\n than retriggering the ambient breath) so the announce is\n visibly louder than the steady-state cadence.\n */}\n <motion.span\n key={pulseKey}\n aria-hidden\n style={{\n position: \"absolute\",\n inset: 0,\n borderRadius: theme.radius.md,\n boxShadow: `0 0 0 0 ${intent.solid}`,\n pointerEvents: \"none\",\n }}\n initial={{ opacity: 0.7 }}\n animate={{\n boxShadow: [\n `0 0 0 0 ${withAlpha(intent.solid, 0.55)}`,\n `0 0 0 14px ${withAlpha(intent.solid, 0)}`,\n ],\n opacity: [0.7, 0],\n }}\n transition={{ duration: 0.9, ease: \"easeOut\" }}\n />\n </>\n ) : null}\n <ThemedButton\n type=\"button\"\n variant={resolvedVariant}\n size={size}\n pressed={submitting}\n className={className}\n aria-label={\n typeof resolvedLabel === \"string\" ? resolvedLabel : \"Primary action\"\n }\n aria-disabled={disabled || undefined}\n data-interaction-id={actionId}\n data-emphasis=\"primary\"\n title={tooltip}\n disabled={disabled}\n style={{\n // Sit above the halo so clicks land on the button.\n position: \"relative\",\n zIndex: 1,\n boxShadow: disabled || submitted ? undefined : theme.elevation.lifted,\n ...style,\n }}\n onClick={async (event: MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n if (disabled) return;\n setPending(true);\n try {\n await onAction?.();\n } finally {\n setPending(false);\n }\n }}\n >\n {resolvedIcon}\n <span>{resolvedLabel}</span>\n </ThemedButton>\n </span>\n );\n}\n\nfunction formatUnavailableReason(\n reason: string | undefined,\n): string | undefined {\n if (reason === \"INSUFFICIENT_RESOURCES\") {\n return \"Insufficient resources\";\n }\n return reason;\n}\n\n/**\n * Add an alpha channel to a CSS colour string. Supports `#rgb`,\n * `#rrggbb`, and any colour the browser can paint via a fallback to\n * `color-mix` (modern Safari/Chrome/Firefox all support this; older\n * runtimes get the original colour without alpha which is still\n * visible — the halo is decorative).\n */\nfunction withAlpha(color: string, alpha: number): string {\n const trimmed = color.trim();\n if (trimmed.startsWith(\"#\")) {\n const hex = trimmed.slice(1);\n if (hex.length === 3) {\n // `String.prototype.slice` always returns a string (possibly\n // empty) — never `undefined` — so duplicating each digit is\n // safe to feed to `parseInt` without further narrowing.\n const r = parseInt(hex.slice(0, 1).repeat(2), 16);\n const g = parseInt(hex.slice(1, 2).repeat(2), 16);\n const b = parseInt(hex.slice(2, 3).repeat(2), 16);\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n }\n if (hex.length === 6) {\n const r = parseInt(hex.slice(0, 2), 16);\n const g = parseInt(hex.slice(2, 4), 16);\n const b = parseInt(hex.slice(4, 6), 16);\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n }\n }\n // Best-effort fallback for non-hex colours (rgb/hsl/named): use\n // `color-mix` with transparent. Safe to land in inline style — the\n // halo is purely decorative and will gracefully degrade.\n return `color-mix(in srgb, ${trimmed} ${Math.round(alpha * 100)}%, transparent)`;\n}\n","/**\n * Collapsible panel for grouping game actions with state-based visibility.\n *\n * Visual styling is sourced entirely from the active {@link useTheme}.\n * The previous bespoke \"wobbly notebook\" treatment (`wobbly-border-lg` /\n * `hard-shadow-lg` / hardcoded `#fff9c4` / `#fdfbf7`) has been retired\n * in favour of `surfaceStyle` + `chipStyle` so the panel re-skins\n * uniformly when authors swap themes.\n */\n\nimport { useId, useState, type ReactNode } from \"react\";\nimport { motion, AnimatePresence } from \"framer-motion\";\nimport { ChevronUp } from \"lucide-react\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\nimport {\n chipStyle,\n intentForVariant,\n surfaceStyle,\n type ButtonVariant,\n} from \"../theme/derive.js\";\n\nexport interface ActionPanelProps {\n title?: string;\n /** Current game state/phase for context display */\n state?: string;\n /** Human-readable state labels */\n stateLabels?: Record<string, string>;\n collapsible?: boolean;\n defaultExpanded?: boolean;\n children: ReactNode;\n className?: string;\n}\n\nexport function ActionPanel({\n title = \"Actions\",\n state,\n stateLabels,\n collapsible = true,\n defaultExpanded = true,\n children,\n className,\n}: ActionPanelProps) {\n const theme = useTheme();\n const reducedMotion = theme.motion.reducedMotion === \"true\";\n const contentId = useId();\n const [isExpanded, setIsExpanded] = useState(defaultExpanded);\n const [isHovered, setIsHovered] = useState(false);\n\n const stateLabel = state\n ? stateLabels?.[state] || state.replace(/([A-Z])/g, \" $1\").trim()\n : undefined;\n\n return (\n <motion.div\n initial={reducedMotion ? { opacity: 0 } : { opacity: 0, y: 20 }}\n animate={reducedMotion ? { opacity: 1 } : { opacity: 1, y: 0 }}\n className={className}\n data-dreamboard-action-panel=\"\"\n data-state={isExpanded ? \"open\" : \"closed\"}\n data-collapsible={collapsible ? \"true\" : undefined}\n style={{\n ...surfaceStyle(theme, { tone: \"card\", radius: \"hud\" }),\n boxShadow: theme.elevation.rest,\n overflow: \"hidden\",\n }}\n role=\"region\"\n aria-label={title}\n >\n <button\n type=\"button\"\n onClick={() => collapsible && setIsExpanded(!isExpanded)}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n disabled={!collapsible}\n aria-expanded={isExpanded}\n aria-controls={contentId}\n style={{\n width: \"100%\",\n padding: `${theme.space[3]} ${theme.space[4]}`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: theme.space[3],\n borderBottom: isExpanded\n ? `1px dashed ${theme.semantic.border.subtle}`\n : \"1px solid transparent\",\n background:\n collapsible && isHovered\n ? theme.semantic.surface.inset\n : theme.semantic.surface.hud,\n color: theme.semantic.text.primary,\n fontFamily: theme.typography.fontFamily.body,\n cursor: collapsible ? \"pointer\" : \"default\",\n transition: `background ${theme.motion.duration.fast} ${theme.motion.easing.out}`,\n // Reset native button look.\n border: \"none\",\n textAlign: \"left\",\n appearance: \"none\",\n }}\n >\n <div>\n <h2\n style={{\n margin: 0,\n fontFamily: theme.typography.fontFamily.display,\n fontSize: theme.typography.fontSize.xl,\n fontWeight: theme.typography.fontWeight.bold,\n color: theme.semantic.text.primary,\n lineHeight: theme.typography.lineHeight.tight,\n }}\n >\n {title}\n </h2>\n {stateLabel && (\n <p\n style={{\n margin: 0,\n marginTop: theme.space[1],\n fontSize: theme.typography.fontSize.sm,\n fontWeight: theme.typography.fontWeight.medium,\n color: theme.semantic.text.muted,\n display: \"flex\",\n alignItems: \"center\",\n gap: theme.space[2],\n }}\n >\n <span\n style={{\n width: 8,\n height: 8,\n borderRadius: theme.radius.pill,\n background: theme.semantic.intent.primary.solid,\n border: `1px solid ${theme.semantic.intent.primary.border}`,\n display: \"inline-block\",\n }}\n />\n Phase: {stateLabel}\n </p>\n )}\n </div>\n {collapsible && (\n <motion.div\n animate={\n reducedMotion ? undefined : { rotate: isExpanded ? 0 : 180 }\n }\n transition={{ duration: 0.2 }}\n style={{\n padding: theme.space[1],\n borderRadius: theme.radius.md,\n border: `1px solid ${theme.semantic.border.default}`,\n background: theme.semantic.surface.card,\n color: theme.semantic.text.primary,\n display: \"inline-flex\",\n }}\n >\n <ChevronUp\n size={20}\n strokeWidth={2.5}\n aria-hidden=\"true\"\n style={{ display: \"block\" }}\n />\n </motion.div>\n )}\n </button>\n\n <AnimatePresence initial={false}>\n {isExpanded && (\n <motion.div\n id={contentId}\n initial={reducedMotion ? { opacity: 0 } : { height: 0, opacity: 0 }}\n animate={\n reducedMotion ? { opacity: 1 } : { height: \"auto\", opacity: 1 }\n }\n exit={reducedMotion ? { opacity: 0 } : { height: 0, opacity: 0 }}\n transition={{ duration: 0.2, ease: \"easeInOut\" }}\n style={{\n overflow: \"hidden\",\n background: theme.semantic.surface.card,\n }}\n >\n <div\n style={{\n padding: theme.space[4],\n display: \"flex\",\n flexDirection: \"column\",\n gap: theme.space[6],\n }}\n >\n {children}\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </motion.div>\n );\n}\n\nexport interface ActionGroupProps {\n title: string;\n description?: string;\n visible?: boolean;\n /** Highlight style for special phases. Maps directly onto theme intent slots. */\n variant?: \"default\" | \"warning\" | \"danger\" | \"success\";\n children: ReactNode;\n className?: string;\n}\n\nconst VARIANT_TO_INTENT: Record<\n ActionGroupProps[\"variant\"] & string,\n ButtonVariant | null\n> = {\n default: null,\n warning: \"warning\",\n danger: \"danger\",\n success: \"success\",\n};\n\nexport function ActionGroup({\n title,\n description,\n visible = true,\n variant = \"default\",\n children,\n className,\n}: ActionGroupProps) {\n const theme = useTheme();\n const reducedMotion = theme.motion.reducedMotion === \"true\";\n\n if (!visible) return null;\n\n const intentVariant = VARIANT_TO_INTENT[variant];\n const intent = intentVariant ? intentForVariant(theme, intentVariant) : null;\n\n const containerStyle: React.CSSProperties = intent\n ? {\n background: intent.soft,\n color: intent.onSoft,\n border: `1px solid ${intent.border}`,\n borderRadius: theme.radius.lg,\n boxShadow: theme.elevation.rest,\n }\n : {\n background: theme.semantic.surface.card,\n color: theme.semantic.text.primary,\n border: `1px solid ${theme.semantic.border.subtle}`,\n borderRadius: theme.radius.lg,\n boxShadow: theme.elevation.rest,\n };\n\n return (\n <motion.div\n initial={reducedMotion ? { opacity: 0 } : { opacity: 0, x: -10 }}\n animate={reducedMotion ? { opacity: 1 } : { opacity: 1, x: 0 }}\n className={className}\n data-dreamboard-action-group=\"\"\n data-variant={variant}\n style={{\n position: \"relative\",\n padding: theme.space[4],\n fontFamily: theme.typography.fontFamily.body,\n ...containerStyle,\n }}\n role=\"group\"\n aria-labelledby={`action-group-${title.toLowerCase().replace(/\\s+/g, \"-\")}`}\n >\n <span\n style={{\n position: \"absolute\",\n top: -10,\n left: theme.space[3],\n ...chipStyle(theme, { variant: \"secondary\", size: \"sm\" }),\n background: theme.semantic.surface.card,\n }}\n >\n Group\n </span>\n <h3\n id={`action-group-${title.toLowerCase().replace(/\\s+/g, \"-\")}`}\n style={{\n margin: 0,\n fontFamily: theme.typography.fontFamily.display,\n fontSize: theme.typography.fontSize.lg,\n fontWeight: theme.typography.fontWeight.bold,\n color: intent?.onSoft ?? theme.semantic.text.primary,\n marginBottom: description ? theme.space[2] : theme.space[3],\n }}\n >\n {title}\n </h3>\n {description && (\n <p\n style={{\n margin: 0,\n marginBottom: theme.space[4],\n fontSize: theme.typography.fontSize.sm,\n fontWeight: theme.typography.fontWeight.medium,\n color: intent?.onSoft ?? theme.semantic.text.muted,\n opacity: 0.85,\n }}\n >\n {description}\n </p>\n )}\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: theme.space[3],\n }}\n >\n {children}\n </div>\n </motion.div>\n );\n}\n","/**\n * Disclosure that hides a list of low-salience actions behind a single\n * \"More\" toggle. Sized and styled by the active theme so it looks\n * consistent with neighbouring `<DefaultInteractionButton>` rows.\n *\n * Why not a popover or dropdown? Two reasons:\n *\n * 1. **Layout safety.** The default panel surface lives directly above\n * the hand strip; a floating popover would be obscured by the\n * hand's `overflow-x: auto` clipping. An inline expansion stays\n * inside the panel container and pushes neighbouring rows down.\n * 2. **Discoverability.** Players miss menus that hide behind triple\n * dots / chevrons. An expanded inline list still looks like a row\n * of buttons (Jakob — same affordance as the always-visible row).\n *\n * The toggle reports its open state via `aria-expanded` and labels\n * the disclosed region via `aria-controls` so screen readers announce\n * \"Expanded — More actions, region containing 3 buttons\" naturally.\n */\n\nimport { useId, useState, type CSSProperties, type ReactNode } from \"react\";\nimport { ChevronDown, MoreHorizontal } from \"lucide-react\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\nimport { ThemedButton } from \"./ThemedButton.js\";\n\nexport interface MoreActionsProps {\n /**\n * Items rendered inside the disclosure when expanded. Typically\n * `<DefaultInteractionButton>` instances for `salience: \"tertiary\"`\n * descriptors, but any `ReactNode` works (custom panel cards, etc.).\n */\n children: ReactNode;\n /**\n * Toggle label. Defaults to `\"More\"`. The descriptor count gets\n * appended automatically when {@link count} is supplied.\n */\n label?: string;\n /**\n * Number of hidden items, used to render the trailing \"(N)\" badge.\n * Omit when the count is irrelevant or already implied (e.g. when\n * the panel only has a fixed set of disclosed items).\n */\n count?: number;\n /**\n * Initial open state. Defaults to `false` — the disclosure is the\n * point. Authors who want it open by default for a specific seat\n * (e.g. tutorial mode) should pass `true`.\n */\n defaultOpen?: boolean;\n /** Additional inline style merged after the default container. */\n style?: CSSProperties;\n}\n\nexport function MoreActions({\n children,\n label = \"More\",\n count,\n defaultOpen = false,\n style,\n}: MoreActionsProps) {\n const theme = useTheme();\n const [open, setOpen] = useState(defaultOpen);\n // `useId` keeps the aria pairing stable across re-renders even when\n // many `<MoreActions>` exist on screen (rare, but easy to break).\n const regionId = `more-actions-${useId().replace(/:/g, \"\")}`;\n\n const showCount = typeof count === \"number\" && count > 0;\n\n return (\n <div\n data-shell-slot=\"more-actions\"\n data-more-actions-open={open ? \"true\" : \"false\"}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: theme.space[2],\n alignItems: \"stretch\",\n // The disclosure is its own block so wrap behaviour upstream\n // doesn't interleave the toggle and the disclosed items.\n flex: \"1 1 100%\",\n minWidth: 0,\n }}\n >\n <ThemedButton\n type=\"button\"\n variant=\"secondary\"\n size=\"md\"\n aria-expanded={open}\n aria-controls={regionId}\n onClick={() => setOpen((value) => !value)}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: theme.space[1],\n ...style,\n }}\n >\n <MoreHorizontal size={16} aria-hidden />\n <span>{label}</span>\n {showCount ? (\n <span\n aria-hidden\n style={{\n fontVariantNumeric: \"tabular-nums\",\n opacity: 0.78,\n }}\n >\n ({count})\n </span>\n ) : null}\n <ChevronDown\n size={14}\n aria-hidden\n style={{\n transform: open ? \"rotate(180deg)\" : \"rotate(0deg)\",\n transition: `transform ${theme.motion.duration.fast} ${theme.motion.easing.out}`,\n }}\n />\n </ThemedButton>\n {open ? (\n <div\n id={regionId}\n role=\"region\"\n aria-label={label}\n style={{\n display: \"flex\",\n flexDirection: \"row\",\n flexWrap: \"wrap\",\n gap: theme.space[2],\n // Inset visually so the disclosed cluster reads as a\n // sub-region rather than a continuation of the main panel.\n paddingInline: theme.space[3],\n paddingBlock: theme.space[2],\n background: theme.semantic.surface.inset,\n borderRadius: theme.radius.lg,\n }}\n >\n {children}\n </div>\n ) : null}\n </div>\n );\n}\n","import { clsx } from \"clsx\";\nimport { motion } from \"framer-motion\";\nimport {\n useCallback,\n useEffect,\n useRef,\n useState,\n type CSSProperties,\n type ReactNode,\n} from \"react\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from \"../internal/ui/dialog.js\";\nimport { surfaceStyle } from \"../theme/derive.js\";\nimport { useTheme, useThemeCssVars } from \"../theme/ThemeProvider.js\";\nimport { normalizeDiceState, type DiceValue } from \"../primitives/dice.js\";\nimport { ThemedButton } from \"./ThemedButton.js\";\n\nexport interface DiceRollerRenderProps {\n values: ReadonlyArray<number | undefined> | undefined;\n /** Undefined if any die hasn't been rolled */\n sum: number | undefined;\n diceCount: number;\n allRolled: boolean;\n}\n\nexport interface DiceRollerRollAction {\n /** Controlled action callback supplied by the runtime or application. */\n onRoll?: () => void | Promise<void>;\n available?: boolean;\n disabledReason?: string;\n title?: ReactNode;\n description?: ReactNode;\n rollLabel?: ReactNode;\n resultLabel?: ReactNode;\n minSpinMs?: number;\n revealHoldMs?: number;\n}\n\nexport interface DiceRollerProps {\n values?: readonly DiceValue[] | null;\n /** Used when values not provided */\n diceCount?: number;\n render?: (props: DiceRollerRenderProps) => ReactNode;\n /** Optional controlled dialog flow for actions such as `rollDice`. */\n rollAction?: DiceRollerRollAction;\n className?: string;\n}\n\ntype RollPhase = \"idle\" | \"rolling\" | \"revealed\";\n\nconst DEFAULT_MIN_SPIN_MS = 1200;\nconst DEFAULT_REVEAL_HOLD_MS = 1400;\nconst FACE_SEQUENCE = [1, 2, 3, 4, 5, 6] as const;\n\nexport function DiceRoller({\n values,\n diceCount = 2,\n render,\n rollAction,\n className,\n}: DiceRollerProps) {\n const renderProps = normalizeDiceState({ values, count: diceCount });\n\n return (\n <div\n className={clsx(\"flex flex-col items-center gap-4\", className)}\n role=\"region\"\n aria-label=\"Dice roller\"\n >\n {render ? render(renderProps) : <DefaultDiceReadout {...renderProps} />}\n\n {rollAction ? (\n <DiceRollDialog\n action={rollAction}\n values={renderProps.values}\n diceCount={renderProps.diceCount}\n />\n ) : null}\n\n {/* Screen reader only: dice info */}\n <div className=\"sr-only\" aria-live=\"polite\">\n {renderProps.allRolled && renderProps.values\n ? `Rolled ${renderProps.values.join(\", \")}. Total: ${renderProps.sum}`\n : \"Dice not rolled yet\"}\n </div>\n </div>\n );\n}\n\nfunction DefaultDiceReadout({\n values,\n sum,\n diceCount,\n allRolled,\n}: DiceRollerRenderProps) {\n const theme = useTheme();\n const dice = values ?? Array(diceCount).fill(undefined);\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: theme.space[2],\n }}\n >\n {allRolled ? (\n <strong\n style={{\n fontFamily: theme.typography.fontFamily.display,\n fontSize: theme.typography.fontSize.lg,\n color: theme.semantic.text.primary,\n fontVariantNumeric: \"tabular-nums\",\n }}\n >\n Total {sum}\n </strong>\n ) : null}\n <DiceRow values={dice} size={44} rolling={false} />\n </div>\n );\n}\n\nfunction DiceRollDialog({\n action,\n values,\n diceCount,\n}: {\n action: DiceRollerRollAction;\n values: ReadonlyArray<number | undefined> | undefined;\n diceCount: number;\n}) {\n const theme = useTheme();\n const themeCssVars = useThemeCssVars();\n const reducedMotion = theme.motion.reducedMotion === \"true\";\n const [open, setOpen] = useState(false);\n const [phase, setPhase] = useState<RollPhase>(\"idle\");\n const [error, setError] = useState<string | null>(null);\n const [animatedValues, setAnimatedValues] = useState<number[]>(() =>\n nextAnimatedValues(diceCount),\n );\n const [revealedValues, setRevealedValues] = useState<\n Array<number | undefined> | undefined\n >(undefined);\n const startedAtRef = useRef(0);\n const revealedRollKeyRef = useRef<string | null>(null);\n\n const shouldPresentDialog = Boolean(action.onRoll);\n const minSpinMs = reducedMotion\n ? 0\n : (action.minSpinMs ?? DEFAULT_MIN_SPIN_MS);\n const revealHoldMs = action.revealHoldMs ?? DEFAULT_REVEAL_HOLD_MS;\n const rolledValuesKey = values?.join(\",\") ?? \"\";\n const valuesAreReady =\n values !== undefined &&\n values.length > 0 &&\n values.every((value) => typeof value === \"number\");\n\n useEffect(() => {\n if (!shouldPresentDialog) {\n setOpen(false);\n return;\n }\n if (!valuesAreReady) {\n revealedRollKeyRef.current = null;\n setOpen(true);\n if (phase !== \"rolling\") {\n setPhase(\"idle\");\n setRevealedValues(undefined);\n setError(null);\n }\n return;\n }\n if (\n open &&\n phase === \"idle\" &&\n revealedRollKeyRef.current !== rolledValuesKey\n ) {\n startedAtRef.current = Date.now();\n setPhase(\"rolling\");\n setAnimatedValues(nextAnimatedValues(diceCount));\n }\n }, [\n diceCount,\n open,\n phase,\n rolledValuesKey,\n shouldPresentDialog,\n valuesAreReady,\n ]);\n\n useEffect(() => {\n if (phase !== \"rolling\") return;\n if (reducedMotion) return;\n const interval = setInterval(() => {\n setAnimatedValues(nextAnimatedValues(diceCount));\n }, 120);\n return () => clearInterval(interval);\n }, [diceCount, phase, reducedMotion]);\n\n useEffect(() => {\n if (phase !== \"rolling\" || !valuesAreReady || !values) return;\n const remaining = Math.max(\n 0,\n minSpinMs - (Date.now() - startedAtRef.current),\n );\n const timeout = setTimeout(() => {\n setRevealedValues([...values]);\n revealedRollKeyRef.current = rolledValuesKey;\n setPhase(\"revealed\");\n }, remaining);\n return () => clearTimeout(timeout);\n }, [minSpinMs, phase, rolledValuesKey, values, valuesAreReady]);\n\n useEffect(() => {\n if (phase !== \"revealed\") return;\n const timeout = setTimeout(() => {\n setOpen(false);\n setPhase(\"idle\");\n }, revealHoldMs);\n return () => clearTimeout(timeout);\n }, [phase, revealHoldMs]);\n\n const roll = useCallback(async () => {\n if (!action.onRoll || action.available === false || phase === \"rolling\") {\n return;\n }\n startedAtRef.current = Date.now();\n setOpen(true);\n setPhase(\"rolling\");\n setError(null);\n setRevealedValues(undefined);\n setAnimatedValues(nextAnimatedValues(diceCount));\n try {\n await action.onRoll();\n } catch (caught) {\n setPhase(\"idle\");\n setError(\n caught instanceof Error ? caught.message : \"Unable to roll dice.\",\n );\n }\n }, [action, diceCount, phase]);\n\n const displayValues =\n phase === \"rolling\"\n ? animatedValues\n : (revealedValues ?? values ?? Array(diceCount).fill(undefined));\n const displaySum = sumValues(displayValues);\n const title = action.title ?? \"Roll dice\";\n const description = action.description ?? \"Roll to resolve the current turn.\";\n const resultLabel = action.resultLabel ?? \"Roll result\";\n const rollLabel = action.rollLabel ?? \"Roll dice\";\n const disabled = action.available === false || phase === \"rolling\";\n const canClose = true;\n\n return (\n <Dialog open={open} onOpenChange={canClose ? setOpen : undefined}>\n <DialogContent\n data-dismiss-behavior=\"dismiss\"\n showCloseButton={canClose}\n className=\"max-h-[calc(100vh-2rem)] overflow-y-auto p-4 sm:max-w-md sm:p-6\"\n style={{\n ...themeCssVars,\n ...surfaceStyle(theme, { tone: \"sheet\", radius: \"lg\" }),\n width: \"min(100%, 28rem)\",\n fontFamily: theme.typography.fontFamily.body,\n }}\n onEscapeKeyDown={\n canClose ? undefined : (event: Event) => event.preventDefault()\n }\n onInteractOutside={\n canClose ? undefined : (event: Event) => event.preventDefault()\n }\n >\n <DialogHeader className=\"text-center sm:text-center\">\n <DialogTitle\n style={{\n fontFamily: theme.typography.fontFamily.display,\n fontSize: theme.typography.fontSize.xl,\n }}\n >\n {title}\n </DialogTitle>\n <DialogDescription>{description}</DialogDescription>\n </DialogHeader>\n\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: theme.space[4],\n }}\n >\n <RollResult label={resultLabel} sum={displaySum} phase={phase} />\n <DiceRow\n values={displayValues}\n size={76}\n rolling={phase === \"rolling\"}\n />\n {error ? (\n <span\n role=\"alert\"\n style={{\n color: theme.semantic.intent.danger.solid,\n fontSize: theme.typography.fontSize.sm,\n textAlign: \"center\",\n }}\n >\n {error}\n </span>\n ) : null}\n <ThemedButton\n type=\"button\"\n variant=\"primary\"\n size=\"lg\"\n disabled={disabled}\n pressed={phase === \"rolling\"}\n onClick={(event) => {\n event.preventDefault();\n void roll();\n }}\n >\n {phase === \"rolling\" ? \"Rolling...\" : rollLabel}\n </ThemedButton>\n </div>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction RollResult({\n label,\n sum,\n phase,\n}: {\n label: ReactNode;\n sum: number | undefined;\n phase: RollPhase;\n}) {\n const theme = useTheme();\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n style={{\n ...surfaceStyle(theme, { tone: \"inset\", radius: \"lg\" }),\n width: \"100%\",\n padding: `${theme.space[3]} ${theme.space[4]}`,\n textAlign: \"center\",\n }}\n >\n <div\n style={{\n color: theme.semantic.text.muted,\n fontSize: theme.typography.fontSize.xs,\n fontWeight: theme.typography.fontWeight.bold,\n letterSpacing: theme.typography.letterSpacing.wide,\n textTransform: \"uppercase\",\n }}\n >\n {label}\n </div>\n <div\n style={{\n fontFamily: theme.typography.fontFamily.display,\n fontSize: \"clamp(2.75rem, 12vw, 4.5rem)\",\n fontWeight: theme.typography.fontWeight.bold,\n lineHeight: 1,\n color: theme.semantic.text.primary,\n fontVariantNumeric: \"tabular-nums\",\n }}\n >\n {sum ?? (phase === \"rolling\" ? \"...\" : \"?\")}\n </div>\n </div>\n );\n}\n\nfunction DiceRow({\n values,\n size,\n rolling,\n}: {\n values: ReadonlyArray<number | undefined>;\n size: number;\n rolling: boolean;\n}) {\n const gap = Math.max(8, Math.round(size * 0.18));\n return (\n <div\n role=\"list\"\n aria-label=\"Dice values\"\n style={{\n display: \"flex\",\n justifyContent: \"center\",\n gap,\n flexWrap: \"wrap\",\n }}\n >\n {values.map((value, index) => (\n <DieFace\n key={index}\n value={value}\n size={size}\n rolling={rolling}\n index={index}\n />\n ))}\n </div>\n );\n}\n\nfunction DieFace({\n value,\n size,\n rolling,\n index,\n}: {\n value: number | undefined;\n size: number;\n rolling: boolean;\n index: number;\n}) {\n const theme = useTheme();\n const reducedMotion = theme.motion.reducedMotion === \"true\";\n const showPips = typeof value === \"number\" && value >= 1 && value <= 6;\n const style: CSSProperties = {\n position: \"relative\",\n width: size,\n height: size,\n borderRadius: Math.max(10, Math.round(size * 0.2)),\n border: `1px solid ${theme.semantic.border.default}`,\n background: `linear-gradient(145deg, ${theme.semantic.surface.card}, ${theme.semantic.surface.inset})`,\n boxShadow: `${theme.elevation.lifted}, inset 0 1px 0 rgba(255,255,255,0.45)`,\n color: theme.semantic.text.primary,\n display: \"grid\",\n placeItems: \"center\",\n flex: \"0 0 auto\",\n overflow: \"hidden\",\n };\n return (\n <motion.div\n role=\"listitem\"\n aria-label={\n typeof value === \"number\"\n ? `Die ${index + 1}: ${value}`\n : `Die ${index + 1}: not rolled`\n }\n style={style}\n animate={\n rolling && !reducedMotion\n ? {\n rotate: [0, 12, -10, 0],\n y: [0, -8, 0],\n scale: [1, 1.04, 1],\n }\n : { rotate: 0, y: 0, scale: 1 }\n }\n transition={\n rolling && !reducedMotion\n ? {\n repeat: Infinity,\n duration: 0.42,\n delay: index * 0.06,\n ease: \"easeInOut\",\n }\n : { duration: 0.2 }\n }\n >\n {showPips ? (\n <PipFace value={value} />\n ) : (\n <span\n style={{\n fontFamily: theme.typography.fontFamily.display,\n fontSize: Math.round(size * 0.42),\n fontWeight: theme.typography.fontWeight.bold,\n fontVariantNumeric: \"tabular-nums\",\n }}\n >\n {value ?? \"?\"}\n </span>\n )}\n </motion.div>\n );\n}\n\nfunction PipFace({ value }: { value: number }) {\n const theme = useTheme();\n const pips = pipPositions(value);\n return (\n <span\n aria-hidden\n style={{\n position: \"absolute\",\n inset: \"18%\",\n }}\n >\n {pips.map(([left, top], index) => (\n <span\n key={`${left}-${top}-${index}`}\n style={{\n position: \"absolute\",\n left: `${left}%`,\n top: `${top}%`,\n width: \"22%\",\n height: \"22%\",\n borderRadius: \"9999px\",\n transform: \"translate(-50%, -50%)\",\n background: theme.semantic.text.primary,\n boxShadow: \"0 1px 2px rgba(0,0,0,0.25)\",\n }}\n />\n ))}\n </span>\n );\n}\n\nfunction pipPositions(value: number): Array<[number, number]> {\n switch (value) {\n case 1:\n return [[50, 50]];\n case 2:\n return [\n [28, 28],\n [72, 72],\n ];\n case 3:\n return [\n [28, 28],\n [50, 50],\n [72, 72],\n ];\n case 4:\n return [\n [28, 28],\n [72, 28],\n [28, 72],\n [72, 72],\n ];\n case 5:\n return [\n [28, 28],\n [72, 28],\n [50, 50],\n [28, 72],\n [72, 72],\n ];\n case 6:\n return [\n [28, 25],\n [72, 25],\n [28, 50],\n [72, 50],\n [28, 75],\n [72, 75],\n ];\n default:\n return [];\n }\n}\n\nfunction nextAnimatedValues(count: number): number[] {\n return Array.from({ length: count }, (_, index) => {\n const offset = Math.floor(Math.random() * FACE_SEQUENCE.length);\n return FACE_SEQUENCE[(offset + index) % FACE_SEQUENCE.length] ?? 1;\n });\n}\n\nfunction sumValues(\n values: ReadonlyArray<number | undefined>,\n): number | undefined {\n if (!values.every((value) => typeof value === \"number\")) return undefined;\n return values.reduce((total, value) => total + (value ?? 0), 0);\n}\n","import { createContext, useContext, type ReactNode } from \"react\";\n\nexport type DiceValue = number | null | undefined;\n\nexport interface DiceState {\n values: ReadonlyArray<number | undefined> | undefined;\n /** Undefined if any die has not been rolled yet. */\n sum: number | undefined;\n diceCount: number;\n allRolled: boolean;\n}\n\nexport interface DiceRootProps {\n values?: readonly DiceValue[] | null;\n /** Used when values are not provided. */\n count?: number;\n children: ReactNode;\n}\n\nexport interface DiceValuesProps {\n children: (state: DiceState) => ReactNode;\n}\n\nexport interface DiceComponents {\n Root(props: DiceRootProps): ReactNode;\n Values(props: DiceValuesProps): ReactNode;\n}\n\nconst DiceContext = createContext<DiceState | null>(null);\n\nexport function normalizeDiceState({\n values,\n count = 2,\n}: {\n values?: readonly DiceValue[] | null;\n count?: number;\n}): DiceState {\n const normalizedValues = values?.map((value) => value ?? undefined);\n const allRolled =\n normalizedValues?.every((value) => value !== undefined) ?? false;\n const sum = allRolled\n ? normalizedValues?.reduce<number>(\n (total, value) => total + (value ?? 0),\n 0,\n )\n : undefined;\n\n return {\n values: normalizedValues,\n sum,\n diceCount: normalizedValues?.length ?? count,\n allRolled,\n };\n}\n\nexport function DiceRoot({ values, count, children }: DiceRootProps) {\n return (\n <DiceContext.Provider value={normalizeDiceState({ values, count })}>\n {children}\n </DiceContext.Provider>\n );\n}\n\nexport function useDicePrimitiveContext(): DiceState {\n const value = useContext(DiceContext);\n if (!value) {\n throw new Error(\"Dice primitives must be rendered inside <Dice.Root>.\");\n }\n return value;\n}\n\nexport function DiceValues({ children }: DiceValuesProps) {\n return children(useDicePrimitiveContext());\n}\n\nexport const Dice: DiceComponents = {\n Root: DiceRoot,\n Values: DiceValues,\n};\n","/**\n * Surfaces the dominant turn-state question — \"is this me?\" / \"who am I\n * waiting for?\" — as a single headline, with the phase label demoted to\n * secondary copy underneath.\n *\n * The previous design rendered three peer chips (`Waiting`, `Roll dice`,\n * `Player 3`) which fragmented one piece of information across three\n * UI atoms. The redesign collapses them into a single status line:\n *\n * ◐ Waiting for Player 3…\n * Roll dice\n *\n * ● Your turn\n * Build, trade, or end your turn.\n *\n * Both states get a leading status indicator that animates so the eye\n * picks up the \"live\" cue immediately. Animations are skipped when the\n * theme reports `motion.reducedMotion === \"true\"`.\n *\n * Prop API is unchanged so existing callers (Catan, Things-in-Rings,\n * tests) keep working without edits. The `variant` knob still toggles\n * surface treatment (`badge` is layout-only, `bar` wraps the headline\n * in an inset HUD strip, `minimal` collapses to a single underlined\n * label for tight HUDs).\n */\n\nimport { motion } from \"framer-motion\";\nimport { clsx } from \"clsx\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\nimport { surfaceStyle } from \"../theme/derive.js\";\nimport type { Theme } from \"../theme/tokens.js\";\n\nexport interface PhaseIndicatorProps {\n currentPhase: string;\n phaseLabels?: Record<string, string>;\n isMyTurn?: boolean;\n activePlayerNames?: string[];\n variant?: \"badge\" | \"bar\" | \"minimal\";\n className?: string;\n}\n\nexport function PhaseIndicator({\n currentPhase,\n phaseLabels,\n isMyTurn,\n activePlayerNames,\n variant = \"badge\",\n className,\n}: PhaseIndicatorProps) {\n const theme = useTheme();\n const reducedMotion = theme.motion.reducedMotion === \"true\";\n\n const label = phaseLabels?.[currentPhase] ?? formatPhase(currentPhase);\n\n if (variant === \"minimal\") {\n return (\n <span\n className={className}\n style={{\n fontFamily: theme.typography.fontFamily.body,\n fontSize: theme.typography.fontSize.sm,\n fontWeight: theme.typography.fontWeight.bold,\n color: theme.semantic.text.muted,\n textDecoration: \"underline\",\n textDecorationStyle: \"wavy\",\n textDecorationColor: theme.semantic.border.subtle,\n textUnderlineOffset: \"4px\",\n }}\n role=\"status\"\n aria-label={`Current phase: ${label}`}\n >\n {label}\n </span>\n );\n }\n\n // Decide which state we're in. Only one is active at a time so the\n // headline is unambiguous.\n const state: \"your-turn\" | \"waiting\" | \"phase-only\" =\n isMyTurn === true\n ? \"your-turn\"\n : isMyTurn === false && activePlayerNames && activePlayerNames.length > 0\n ? \"waiting\"\n : \"phase-only\";\n\n const containerStyle: React.CSSProperties =\n variant === \"bar\"\n ? {\n ...surfaceStyle(theme, { tone: \"inset\", radius: \"hud\" }),\n padding: theme.space[3],\n boxShadow: theme.elevation.inset,\n fontFamily: theme.typography.fontFamily.body,\n }\n : { fontFamily: theme.typography.fontFamily.body };\n\n const headline = renderHeadline({\n state,\n activePlayerNames,\n label,\n theme,\n reducedMotion,\n });\n const ariaLabel =\n state === \"your-turn\"\n ? `Your turn — ${label}`\n : state === \"waiting\"\n ? `Waiting for ${formatPlayerList(activePlayerNames ?? [])} — ${label}`\n : label;\n\n return (\n <div\n className={clsx(\"flex items-center gap-3 flex-wrap\", className)}\n style={containerStyle}\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n aria-label={ariaLabel}\n >\n {headline}\n </div>\n );\n}\n\nfunction formatPhase(phase: string): string {\n const formatted = phase\n .replace(/([A-Z])/g, \" $1\")\n .replace(/_/g, \" \")\n .trim()\n .replace(/^\\w/, (c) => c.toUpperCase());\n return formatted === \"Player Turn\" ? \"Turn\" : formatted;\n}\n\nfunction formatPlayerList(names: readonly string[]): string {\n if (names.length === 0) return \"\";\n if (names.length === 1) return names[0]!;\n if (names.length === 2) return `${names[0]} and ${names[1]}`;\n return `${names.slice(0, -1).join(\", \")}, and ${names[names.length - 1]}`;\n}\n\ninterface HeadlineArgs {\n state: \"your-turn\" | \"waiting\" | \"phase-only\";\n activePlayerNames: readonly string[] | undefined;\n label: string;\n theme: Theme;\n reducedMotion: boolean;\n}\n\nfunction renderHeadline({\n state,\n activePlayerNames,\n label,\n theme,\n reducedMotion,\n}: HeadlineArgs) {\n if (state === \"phase-only\") {\n return (\n <div style={textBlockStyle(theme)}>\n <span style={titleTextStyle(theme)}>{label}</span>\n </div>\n );\n }\n\n const isYourTurn = state === \"your-turn\";\n const intent = isYourTurn\n ? theme.semantic.intent.success\n : theme.semantic.intent.info;\n const titleText = isYourTurn\n ? \"Your turn\"\n : `Waiting for ${formatPlayerList(activePlayerNames ?? [])}…`;\n\n return (\n <motion.div\n initial={reducedMotion ? { opacity: 0 } : { opacity: 0, y: -4 }}\n animate={reducedMotion ? { opacity: 1 } : { opacity: 1, y: 0 }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: theme.space[3],\n }}\n >\n <StatusIndicator\n intent={intent}\n kind={isYourTurn ? \"pulse\" : \"spinner\"}\n reducedMotion={reducedMotion}\n />\n <div style={textBlockStyle(theme)}>\n <span style={titleTextStyle(theme)}>{titleText}</span>\n <span style={subtitleTextStyle(theme)}>{label}</span>\n </div>\n </motion.div>\n );\n}\n\nfunction textBlockStyle(theme: Theme): React.CSSProperties {\n return {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n gap: theme.space[0.5],\n minWidth: 0,\n };\n}\n\nfunction titleTextStyle(theme: Theme): React.CSSProperties {\n return {\n fontFamily: theme.typography.fontFamily.body,\n fontSize: theme.typography.fontSize.lg,\n fontWeight: theme.typography.fontWeight.bold,\n letterSpacing: theme.typography.letterSpacing.tight,\n lineHeight: theme.typography.lineHeight.tight,\n color: theme.semantic.text.primary,\n };\n}\n\nfunction subtitleTextStyle(theme: Theme): React.CSSProperties {\n return {\n fontFamily: theme.typography.fontFamily.body,\n fontSize: theme.typography.fontSize.xs,\n fontWeight: theme.typography.fontWeight.medium,\n letterSpacing: theme.typography.letterSpacing.caps,\n textTransform: \"uppercase\",\n color: theme.semantic.text.muted,\n };\n}\n\ninterface StatusIndicatorProps {\n intent: Theme[\"semantic\"][\"intent\"][\"success\"];\n kind: \"pulse\" | \"spinner\";\n reducedMotion: boolean;\n}\n\n/**\n * Animated status indicator sized to sit next to a body-font headline.\n *\n * Kept intentionally chip-less so it shares the chrome strip's\n * understated treatment (the rest of the chrome uses bare typography\n * and lets intent colour live in chips, dots, and borders — not in\n * full-saturation surfaces). The colour comes from one\n * {@link Theme}-supplied intent ramp so swapping themes keeps the\n * indicator consistent with chips, toasts, and buttons that use the\n * same intent.\n *\n * - `pulse` — soft halo radiating outward from a solid centre dot.\n * Used for the player's own active turn.\n * - `spinner` — thin partial ring rotating around a soft-filled\n * centre. Reads as the standard \"in flight / live\" affordance.\n */\nfunction StatusIndicator({\n intent,\n kind,\n reducedMotion,\n}: StatusIndicatorProps) {\n const size = 16;\n\n if (kind === \"pulse\") {\n return (\n <span\n aria-hidden=\"true\"\n style={{\n position: \"relative\",\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: size,\n height: size,\n flexShrink: 0,\n }}\n >\n <motion.span\n style={{\n position: \"absolute\",\n inset: 2,\n borderRadius: \"9999px\",\n background: intent.soft,\n }}\n animate={\n reducedMotion\n ? undefined\n : { scale: [1, 1.6, 1], opacity: [0.7, 0, 0.7] }\n }\n transition={{\n repeat: reducedMotion ? 0 : Infinity,\n duration: 1.6,\n ease: \"easeOut\",\n }}\n />\n <span\n style={{\n position: \"relative\",\n display: \"inline-block\",\n width: 8,\n height: 8,\n borderRadius: \"9999px\",\n background: intent.solid,\n }}\n />\n </span>\n );\n }\n\n // \"spinner\" — partial ring rotating around an inset soft fill.\n return (\n <span\n aria-hidden=\"true\"\n style={{\n position: \"relative\",\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: size,\n height: size,\n flexShrink: 0,\n }}\n >\n <span\n style={{\n position: \"absolute\",\n inset: 4,\n borderRadius: \"9999px\",\n background: intent.soft,\n }}\n />\n <motion.span\n style={{\n position: \"absolute\",\n inset: 0,\n borderRadius: \"9999px\",\n border: \"2px solid transparent\",\n borderTopColor: intent.solid,\n borderRightColor: intent.solid,\n }}\n animate={reducedMotion ? undefined : { rotate: 360 }}\n transition={{\n repeat: reducedMotion ? 0 : Infinity,\n duration: 1.2,\n ease: \"linear\",\n }}\n />\n </span>\n );\n}\n","/**\n * End-of-game winner display and scoreboard overlay.\n *\n * Visual styling derives entirely from the active {@link useTheme}\n * (semantic + intent + elevation tokens). The win moment is the\n * Peak-end anchor of the session, so the surface intentionally pushes\n * the loudest theme signals (display typeface, primary intent,\n * elevation.overlay) without inventing one-off colours.\n */\n\nimport { motion } from \"framer-motion\";\nimport { Trophy, Home, Crown, Medal } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport { Dialog, DialogContent, DialogTitle } from \"../internal/ui/dialog.js\";\nimport { useTheme } from \"../theme/ThemeProvider.js\";\nimport {\n chipStyle,\n intentForVariant,\n surfaceStyle,\n type ButtonVariant,\n} from \"../theme/derive.js\";\nimport type { Theme } from \"../theme/tokens.js\";\nimport { ThemedButton } from \"./ThemedButton.js\";\n\nexport interface PlayerScore {\n playerId: string;\n name: string;\n score: number;\n isWinner?: boolean;\n details?: Record<string, number>;\n}\n\nexport interface GameEndDisplayProps {\n isGameOver: boolean;\n /** Sorted by rank */\n scores: PlayerScore[];\n winnerMessage?: string;\n showDetails?: boolean;\n onReturnToLobby?: () => void;\n className?: string;\n}\n\nfunction rankIntent(rank: number): ButtonVariant {\n if (rank === 1) return \"warning\"; // gold\n if (rank === 2) return \"secondary\"; // silver\n if (rank === 3) return \"info\"; // bronze-ish (no bronze in palette)\n return \"secondary\";\n}\n\nfunction RankIcon({ rank, theme }: { rank: number; theme: Theme }) {\n const intent = intentForVariant(theme, rankIntent(rank));\n if (rank === 1) {\n return (\n <Trophy\n width={20}\n height={20}\n strokeWidth={3}\n aria-hidden=\"true\"\n style={{ color: intent.solid }}\n />\n );\n }\n if (rank === 2 || rank === 3) {\n return (\n <Medal\n width={20}\n height={20}\n strokeWidth={2.5}\n aria-hidden=\"true\"\n style={{ color: intent.solid }}\n />\n );\n }\n return (\n <span\n style={{\n width: 20,\n textAlign: \"center\",\n color: theme.semantic.text.muted,\n fontFamily: theme.typography.fontFamily.tabular,\n fontWeight: theme.typography.fontWeight.bold,\n }}\n >\n #{rank}\n </span>\n );\n}\n\nexport function GameEndDisplay({\n isGameOver,\n scores,\n winnerMessage,\n showDetails = false,\n onReturnToLobby,\n className,\n}: GameEndDisplayProps) {\n const theme = useTheme();\n const reducedMotion = theme.motion.reducedMotion === \"true\";\n const [isOpen, setIsOpen] = useState(isGameOver);\n\n useEffect(() => {\n setIsOpen(isGameOver);\n }, [isGameOver]);\n\n if (!isGameOver) return null;\n\n const winner = scores.find((s) => s.isWinner) || scores[0];\n const sortedScores = [...scores].sort((a, b) => b.score - a.score);\n const winningIntent = theme.semantic.intent.warning;\n const title = `${winner?.name ?? \"Game\"} Wins!`;\n\n return (\n <Dialog open={isOpen} onOpenChange={setIsOpen}>\n <DialogContent\n className={`border-0 p-6 text-center shadow-none sm:max-w-lg ${className ?? \"\"}`}\n overlayClassName=\"bg-black/50 backdrop-blur-md\"\n aria-describedby={undefined}\n style={{\n ...surfaceStyle(theme, { tone: \"sheet\", radius: \"hud\" }),\n width: \"100%\",\n maxWidth: 480,\n padding: `${theme.space[8]} ${theme.space[6]}`,\n textAlign: \"center\",\n boxShadow: theme.elevation.overlay,\n overflow: \"hidden\",\n backgroundImage: `radial-gradient(circle at top, ${winningIntent.soft} 0%, ${theme.semantic.surface.sheet} 60%)`,\n fontFamily: theme.typography.fontFamily.body,\n }}\n >\n <DialogTitle className=\"sr-only\">{title}</DialogTitle>\n\n {/* Trophy badge */}\n <motion.div\n initial={\n reducedMotion\n ? { scale: 1 }\n : { scale: 0.95, rotate: -180, opacity: 0 }\n }\n animate={\n reducedMotion ? { scale: 1 } : { scale: 1, rotate: 0, opacity: 1 }\n }\n transition={{\n type: \"spring\",\n stiffness: 200,\n damping: 15,\n delay: reducedMotion ? 0 : 0.2,\n }}\n style={{\n marginBottom: theme.space[6],\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: 96,\n height: 96,\n borderRadius: theme.radius.pill,\n background: winningIntent.soft,\n border: `3px solid ${winningIntent.border}`,\n boxShadow: theme.elevation.lifted,\n }}\n >\n <Trophy\n width={48}\n height={48}\n strokeWidth={2.5}\n aria-hidden=\"true\"\n style={{ color: winningIntent.solid }}\n />\n </motion.div>\n\n <motion.div\n initial={reducedMotion ? { opacity: 0 } : { opacity: 0, y: 10 }}\n animate={reducedMotion ? { opacity: 1 } : { opacity: 1, y: 0 }}\n transition={{ delay: reducedMotion ? 0 : 0.4 }}\n >\n <h2\n aria-hidden=\"true\"\n style={{\n margin: 0,\n fontFamily: theme.typography.fontFamily.display,\n fontSize: theme.typography.fontSize[\"3xl\"],\n fontWeight: theme.typography.fontWeight.bold,\n color: theme.semantic.text.primary,\n marginBottom: theme.space[2],\n lineHeight: theme.typography.lineHeight.tight,\n }}\n >\n {title}\n </h2>\n {winnerMessage && (\n <p\n style={{\n margin: 0,\n marginBottom: theme.space[6],\n display: \"inline-block\",\n ...chipStyle(theme, { variant: \"warning\", size: \"md\" }),\n fontSize: theme.typography.fontSize.sm,\n }}\n >\n {winnerMessage}\n </p>\n )}\n </motion.div>\n\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ delay: reducedMotion ? 0 : 0.6 }}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: theme.space[3],\n marginBottom: theme.space[8],\n textAlign: \"left\",\n }}\n role=\"list\"\n aria-label=\"Final scores\"\n >\n {sortedScores.map((player, index) => {\n const rank = index + 1;\n const intent = intentForVariant(theme, rankIntent(rank));\n const isWinner = player.isWinner ?? rank === 1;\n return (\n <motion.div\n key={player.playerId}\n initial={\n reducedMotion ? { opacity: 0 } : { opacity: 0, x: -20 }\n }\n animate={reducedMotion ? { opacity: 1 } : { opacity: 1, x: 0 }}\n transition={{\n delay: reducedMotion ? 0 : 0.6 + index * 0.1,\n }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n padding: theme.space[3],\n background: isWinner\n ? intent.soft\n : theme.semantic.surface.card,\n border: `1px solid ${\n isWinner ? intent.border : theme.semantic.border.subtle\n }`,\n borderRadius: theme.radius.lg,\n boxShadow: isWinner\n ? theme.elevation.hover\n : theme.elevation.rest,\n }}\n role=\"listitem\"\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: theme.space[3],\n }}\n >\n <RankIcon rank={rank} theme={theme} />\n <span\n style={{\n fontFamily: theme.typography.fontFamily.body,\n fontSize: theme.typography.fontSize.lg,\n fontWeight: theme.typography.fontWeight.bold,\n color: isWinner\n ? intent.onSoft\n : theme.semantic.text.primary,\n }}\n >\n {player.name}\n </span>\n {isWinner && (\n <Crown\n width={20}\n height={20}\n strokeWidth={3}\n aria-label=\"Winner\"\n style={{ color: intent.solid }}\n />\n )}\n </div>\n <span\n style={{\n fontFamily: theme.typography.fontFamily.tabular,\n fontSize: theme.typography.fontSize[\"2xl\"],\n fontWeight: theme.typography.fontWeight.bold,\n color: isWinner\n ? intent.onSoft\n : theme.semantic.text.primary,\n paddingInline: theme.space[2],\n paddingBlock: theme.space[0.5],\n background: theme.semantic.surface.inset,\n borderRadius: theme.radius.md,\n border: `1px solid ${theme.semantic.border.subtle}`,\n }}\n >\n {player.score}\n </span>\n </motion.div>\n );\n })}\n </motion.div>\n\n {showDetails && winner?.details && (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ delay: reducedMotion ? 0 : 0.8 }}\n style={{\n marginBottom: theme.space[8],\n padding: theme.space[4],\n background: theme.semantic.surface.inset,\n border: `1px dashed ${theme.semantic.border.default}`,\n borderRadius: theme.radius.lg,\n textAlign: \"left\",\n }}\n >\n <h3\n style={{\n margin: 0,\n marginBottom: theme.space[3],\n fontFamily: theme.typography.fontFamily.display,\n fontSize: theme.typography.fontSize.md,\n fontWeight: theme.typography.fontWeight.bold,\n color: theme.semantic.text.primary,\n display: \"flex\",\n alignItems: \"center\",\n gap: theme.space[2],\n }}\n >\n <span\n style={{\n width: 8,\n height: 8,\n background: theme.semantic.intent.primary.solid,\n borderRadius: theme.radius.pill,\n display: \"inline-block\",\n }}\n />\n Score Breakdown\n </h3>\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: theme.space[2],\n }}\n >\n {Object.entries(winner.details).map(([key, value]) => (\n <div\n key={key}\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n fontSize: theme.typography.fontSize.md,\n color: theme.semantic.text.primary,\n }}\n >\n <span style={{ textTransform: \"capitalize\" }}>\n {key.replace(/([A-Z])/g, \" $1\")}\n </span>\n <span\n style={{\n fontFamily: theme.typography.fontFamily.tabular,\n fontWeight: theme.typography.fontWeight.bold,\n }}\n >\n {value}\n </span>\n </div>\n ))}\n </div>\n </motion.div>\n )}\n\n {onReturnToLobby && (\n <motion.div\n initial={reducedMotion ? { opacity: 0 } : { opacity: 0, y: 10 }}\n animate={reducedMotion ? { opacity: 1 } : { opacity: 1, y: 0 }}\n transition={{ delay: reducedMotion ? 0 : 1 }}\n style={{ display: \"flex\", justifyContent: \"center\" }}\n >\n <ThemedButton\n type=\"button\"\n variant=\"primary\"\n size=\"lg\"\n onClick={onReturnToLobby}\n style={{\n gap: theme.space[2],\n }}\n >\n <Home size={20} strokeWidth={3} aria-hidden=\"true\" />\n Return to Lobby\n </ThemedButton>\n </motion.div>\n )}\n </DialogContent>\n </Dialog>\n );\n}\n","/**\n * SVG-based network/graph visualization for route-building games\n * (Ticket to Ride, Pandemic, Power Grid, Brass).\n */\n\nimport { useMemo, type ReactNode } from \"react\";\nimport { clsx } from \"clsx\";\nimport { usePanZoom, calculateViewBox } from \"../../hooks/usePanZoom.js\";\nimport { handleKeyboardActivation } from \"./interaction-accessibility.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface NetworkNode {\n id: string;\n label?: string;\n position: { x: number; y: number };\n type?: string;\n data?: Record<string, unknown>;\n}\n\nexport interface NetworkEdge {\n id: string;\n from: string;\n to: string;\n label?: string | number;\n owner?: string;\n type?: string;\n data?: Record<string, unknown>;\n}\n\nexport interface NetworkPiece {\n id: string;\n nodeId: string;\n owner?: string;\n type?: string;\n data?: Record<string, unknown>;\n}\n\nexport interface NetworkGraphProps {\n nodes: NetworkNode[];\n edges: NetworkEdge[];\n pieces: NetworkPiece[];\n /** Receives node centered at its position */\n renderNode: (node: NetworkNode, pieces: NetworkPiece[]) => ReactNode;\n renderEdge: (\n edge: NetworkEdge,\n fromNode: NetworkNode,\n toNode: NetworkNode,\n ) => ReactNode;\n renderPiece: (\n piece: NetworkPiece,\n position: { x: number; y: number },\n ) => ReactNode;\n width?: number | string;\n height?: number | string;\n nodeRadius?: number;\n enablePanZoom?: boolean;\n initialZoom?: number;\n minZoom?: number;\n maxZoom?: number;\n padding?: number;\n className?: string;\n}\n\nconst EMPTY_NETWORK_EDGES: NetworkEdge[] = [];\nconst EMPTY_NETWORK_PIECES: NetworkPiece[] = [];\n\n// ============================================================================\n// Pre-built Helper Components\n// ============================================================================\n\nexport interface DefaultNetworkNodeProps {\n radius?: number;\n fill?: string;\n stroke?: string;\n strokeWidth?: number;\n isSelected?: boolean;\n isHighlighted?: boolean;\n label?: string;\n maxLabelLength?: number;\n onClick?: () => void;\n onPointerEnter?: () => void;\n onPointerLeave?: () => void;\n className?: string;\n}\n\n/** Pre-built network node for use in `renderNode`. */\nexport function DefaultNetworkNode({\n radius = 20,\n fill = \"#1e293b\",\n stroke = \"#475569\",\n strokeWidth = 2,\n isSelected = false,\n isHighlighted = false,\n label,\n maxLabelLength = 6,\n onClick,\n onPointerEnter,\n onPointerLeave,\n className,\n}: DefaultNetworkNodeProps) {\n const effectiveFill = isSelected\n ? \"#3b82f6\"\n : isHighlighted\n ? \"#22c55e\"\n : fill;\n\n const effectiveStroke = isSelected\n ? \"#60a5fa\"\n : isHighlighted\n ? \"#4ade80\"\n : stroke;\n\n const effectiveStrokeWidth = isSelected || isHighlighted ? 3 : strokeWidth;\n\n const displayLabel = label\n ? label.length > maxLabelLength\n ? label.slice(0, maxLabelLength - 1) + \"…\"\n : label\n : undefined;\n\n return (\n <g\n onClick={onClick}\n onPointerEnter={onPointerEnter}\n onPointerLeave={onPointerLeave}\n onKeyDown={(event) => handleKeyboardActivation(event, onClick)}\n className={clsx(\n \"transition-all duration-150\",\n onClick && \"cursor-pointer\",\n className,\n )}\n role={onClick ? \"button\" : undefined}\n tabIndex={onClick ? 0 : undefined}\n aria-label={onClick ? (label ?? \"Network node\") : undefined}\n >\n <circle\n r={radius}\n fill={effectiveFill}\n stroke={effectiveStroke}\n strokeWidth={effectiveStrokeWidth}\n />\n {displayLabel && (\n <text\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n fill=\"white\"\n fontSize={10}\n fontWeight=\"bold\"\n >\n {displayLabel}\n </text>\n )}\n </g>\n );\n}\n\nexport interface DefaultNetworkEdgeProps {\n from: { x: number; y: number };\n to: { x: number; y: number };\n color?: string;\n strokeWidth?: number;\n isSelected?: boolean;\n isHighlighted?: boolean;\n /** Displayed at midpoint */\n label?: string | number;\n onClick?: () => void;\n onPointerEnter?: () => void;\n onPointerLeave?: () => void;\n className?: string;\n}\n\n/** Pre-built network edge for use in `renderEdge`. */\nexport function DefaultNetworkEdge({\n from,\n to,\n color = \"#64748b\",\n strokeWidth = 3,\n isSelected = false,\n isHighlighted = false,\n label,\n onClick,\n onPointerEnter,\n onPointerLeave,\n className,\n}: DefaultNetworkEdgeProps) {\n const effectiveColor = isSelected\n ? \"#3b82f6\"\n : isHighlighted\n ? \"#22c55e\"\n : color;\n\n const effectiveWidth =\n isSelected || isHighlighted ? strokeWidth + 2 : strokeWidth;\n\n const midX = (from.x + to.x) / 2;\n const midY = (from.y + to.y) / 2;\n\n return (\n <g\n onClick={onClick}\n onPointerEnter={onPointerEnter}\n onPointerLeave={onPointerLeave}\n onKeyDown={(event) => handleKeyboardActivation(event, onClick)}\n className={clsx(\n \"transition-all duration-150\",\n onClick && \"cursor-pointer\",\n className,\n )}\n role={onClick ? \"button\" : undefined}\n tabIndex={onClick ? 0 : undefined}\n aria-label={\n onClick\n ? label !== undefined\n ? `Network edge ${label}`\n : \"Network edge\"\n : undefined\n }\n >\n <line\n x1={from.x}\n y1={from.y}\n x2={to.x}\n y2={to.y}\n stroke={effectiveColor}\n strokeWidth={effectiveWidth}\n strokeLinecap=\"round\"\n />\n {label !== undefined && (\n <>\n <circle\n cx={midX}\n cy={midY}\n r={12}\n fill=\"#1e293b\"\n stroke=\"#475569\"\n strokeWidth={1}\n />\n <text\n x={midX}\n y={midY}\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n fill=\"white\"\n fontSize={10}\n fontWeight=\"bold\"\n >\n {label}\n </text>\n </>\n )}\n </g>\n );\n}\n\nexport interface DefaultNetworkPieceProps {\n color?: string;\n radius?: number;\n shape?: \"circle\" | \"square\";\n onClick?: () => void;\n className?: string;\n}\nexport function DefaultNetworkPiece({\n color = \"#f59e0b\",\n radius = 6,\n shape = \"circle\",\n onClick,\n className,\n}: DefaultNetworkPieceProps) {\n return (\n <g\n onClick={onClick}\n onKeyDown={(event) => handleKeyboardActivation(event, onClick)}\n className={clsx(onClick && \"cursor-pointer\", className)}\n role={onClick ? \"button\" : undefined}\n tabIndex={onClick ? 0 : undefined}\n aria-label={onClick ? \"Network piece\" : undefined}\n >\n {shape === \"square\" ? (\n <rect\n x={-radius}\n y={-radius}\n width={radius * 2}\n height={radius * 2}\n fill={color}\n stroke=\"white\"\n strokeWidth={1.5}\n />\n ) : (\n <circle r={radius} fill={color} stroke=\"white\" strokeWidth={1.5} />\n )}\n </g>\n );\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport function NetworkGraph({\n nodes,\n edges = EMPTY_NETWORK_EDGES,\n pieces = EMPTY_NETWORK_PIECES,\n renderNode,\n renderEdge,\n renderPiece,\n width = 800,\n height = 600,\n nodeRadius = 20,\n enablePanZoom = false,\n initialZoom = 1,\n minZoom = 0.5,\n maxZoom = 3,\n padding = 40,\n className,\n}: NetworkGraphProps) {\n // Use the unified pan/zoom hook\n const { transform, bind, isDragging } = usePanZoom({\n enabled: enablePanZoom,\n initialZoom,\n minZoom,\n maxZoom,\n mode: \"viewbox\",\n });\n\n // Group pieces by node\n const piecesByNode = useMemo(() => {\n const map: Record<string, NetworkPiece[]> = {};\n pieces.forEach((p) => {\n const nodeId = p.nodeId;\n const existing = map[nodeId];\n if (existing) {\n existing.push(p);\n } else {\n map[nodeId] = [p];\n }\n });\n return map;\n }, [pieces]);\n\n // Create node lookup map\n const nodeMap = useMemo(() => {\n return Object.fromEntries(nodes.map((n) => [n.id, n]));\n }, [nodes]);\n\n // Calculate bounds for viewBox\n const bounds = useMemo(() => {\n if (nodes.length === 0) {\n return { minX: 0, minY: 0, width: 400, height: 300 };\n }\n\n let minX = Infinity,\n minY = Infinity,\n maxX = -Infinity,\n maxY = -Infinity;\n nodes.forEach((node) => {\n minX = Math.min(minX, node.position.x - nodeRadius);\n minY = Math.min(minY, node.position.y - nodeRadius);\n maxX = Math.max(maxX, node.position.x + nodeRadius);\n maxY = Math.max(maxY, node.position.y + nodeRadius);\n });\n\n return {\n minX: minX - padding,\n minY: minY - padding,\n width: maxX - minX + padding * 2,\n height: maxY - minY + padding * 2,\n };\n }, [nodes, nodeRadius, padding]);\n\n // Calculate viewBox with pan and zoom\n const viewBox = calculateViewBox(bounds, transform);\n\n // Parse viewBox for zoom indicator positioning\n const viewBoxParts = viewBox.split(\" \").map(Number);\n const viewBoxX = viewBoxParts[0] ?? 0;\n const viewBoxY = viewBoxParts[1] ?? 0;\n const viewBoxHeight = viewBoxParts[3] ?? 0;\n\n return (\n <svg\n width={width}\n height={height}\n viewBox={viewBox}\n className={clsx(\n \"overflow-visible\",\n enablePanZoom && \"touch-none\",\n isDragging && \"cursor-grabbing\",\n enablePanZoom && !isDragging && \"cursor-grab\",\n className,\n )}\n {...bind()}\n role=\"img\"\n aria-label=\"Network graph\"\n >\n {/* Render edges first (below nodes) */}\n <g className=\"network-edges\" role=\"list\" aria-label=\"Network connections\">\n {edges.map((edge) => {\n const fromNode = nodeMap[edge.from];\n const toNode = nodeMap[edge.to];\n if (!fromNode || !toNode) return null;\n\n return (\n <g\n key={edge.id}\n role=\"listitem\"\n aria-label={`Edge from ${fromNode.label ?? fromNode.id} to ${toNode.label ?? toNode.id}`}\n >\n {renderEdge(edge, fromNode, toNode)}\n </g>\n );\n })}\n </g>\n\n {/* Render nodes */}\n <g className=\"network-nodes\" role=\"list\" aria-label=\"Network nodes\">\n {nodes.map((node) => {\n const nodePieces = piecesByNode[node.id] ?? [];\n\n return (\n <g\n key={node.id}\n transform={`translate(${node.position.x}, ${node.position.y})`}\n role=\"listitem\"\n aria-label={node.label ?? node.id}\n >\n {renderNode(node, nodePieces)}\n\n {/* Render pieces around the node */}\n {nodePieces.length > 0 && (\n <g className=\"node-pieces\">\n {nodePieces.map((piece, i) => {\n const angle =\n (i / nodePieces.length) * 2 * Math.PI - Math.PI / 2;\n const pieceX = Math.cos(angle) * (nodeRadius + 8);\n const pieceY = Math.sin(angle) * (nodeRadius + 8);\n\n return (\n <g\n key={piece.id}\n transform={`translate(${pieceX}, ${pieceY})`}\n >\n {renderPiece(piece, { x: pieceX, y: pieceY })}\n </g>\n );\n })}\n </g>\n )}\n </g>\n );\n })}\n </g>\n\n {/* Zoom indicator */}\n {enablePanZoom && transform.zoom !== 1 && (\n <g\n transform={`translate(${viewBoxX + 10}, ${viewBoxY + viewBoxHeight - 30})`}\n >\n <rect\n x={0}\n y={0}\n width={60}\n height={20}\n rx={4}\n fill=\"rgba(0,0,0,0.6)\"\n />\n <text x={30} y={14} textAnchor=\"middle\" fill=\"white\" fontSize={12}>\n {Math.round(transform.zoom * 100)}%\n </text>\n </g>\n )}\n </svg>\n );\n}\n","import type { KeyboardEvent } from \"react\";\n\nexport function handleKeyboardActivation(\n event: KeyboardEvent,\n onActivate: (() => void) | undefined,\n options?: { stopPropagation?: boolean },\n): void {\n if (!onActivate) {\n return;\n }\n\n if (event.key !== \"Enter\" && event.key !== \" \") {\n return;\n }\n\n event.preventDefault();\n if (options?.stopPropagation) {\n event.stopPropagation();\n }\n onActivate();\n}\n","/**\n * SVG-based area control visualization for territory games (Risk, Small World, Diplomacy).\n */\n\nimport { useMemo, type ReactNode } from \"react\";\nimport { clsx } from \"clsx\";\nimport { usePanZoom } from \"../../hooks/usePanZoom.js\";\nimport { handleKeyboardActivation } from \"./interaction-accessibility.js\";\n\nexport interface ZoneShape {\n type: \"polygon\" | \"path\" | \"circle\";\n points?: Array<{ x: number; y: number }>;\n /** SVG path data */\n path?: string;\n center?: { x: number; y: number };\n radius?: number;\n}\n\nexport interface ZoneDefinition {\n id: string;\n name: string;\n adjacentTo: string[];\n shape?: ZoneShape;\n value?: number;\n type?: string;\n data?: Record<string, unknown>;\n}\n\nexport interface ZonePiece {\n id: string;\n zoneId: string;\n type: string;\n owner?: string;\n /** Count for stackable pieces (armies) */\n count?: number;\n data?: Record<string, unknown>;\n}\n\nexport interface ZoneMapProps {\n zones: ZoneDefinition[];\n pieces: ZonePiece[];\n renderZone: (zone: ZoneDefinition, pieces: ZonePiece[]) => ReactNode;\n backgroundImage?: string;\n width?: number | string;\n height?: number | string;\n enablePanZoom?: boolean;\n initialZoom?: number;\n minZoom?: number;\n maxZoom?: number;\n className?: string;\n}\n\n// ============================================================================\n// Helper Components\n// ============================================================================\n\nexport type ZoneHighlightType =\n | \"valid\"\n | \"selected\"\n | \"attack\"\n | \"defend\"\n | \"neutral\";\n\n// Highlight colors by type\nconst HIGHLIGHT_COLORS: Record<ZoneHighlightType, string> = {\n valid: \"rgba(34, 197, 94, 0.4)\", // Green\n selected: \"rgba(59, 130, 246, 0.4)\", // Blue\n attack: \"rgba(239, 68, 68, 0.4)\", // Red\n defend: \"rgba(234, 179, 8, 0.4)\", // Yellow\n neutral: \"rgba(148, 163, 184, 0.4)\", // Slate\n};\n\nconst HIGHLIGHT_STROKES: Record<ZoneHighlightType, string> = {\n valid: \"#22c55e\",\n selected: \"#3b82f6\",\n attack: \"#ef4444\",\n defend: \"#eab308\",\n neutral: \"#94a3b8\",\n};\n\nconst EMPTY_PLAYER_COLORS: Record<string, string> = {};\n\nexport interface DefaultZoneProps {\n zone: ZoneDefinition;\n fill?: string;\n stroke?: string;\n strokeWidth?: number;\n isHighlighted?: boolean;\n highlightType?: ZoneHighlightType;\n isSelected?: boolean;\n showLabel?: boolean;\n showValue?: boolean;\n onClick?: () => void;\n onHover?: (hovering: boolean) => void;\n className?: string;\n children?: ReactNode;\n}\nexport function DefaultZone({\n zone,\n fill = \"rgba(100, 116, 139, 0.2)\",\n stroke = \"#475569\",\n strokeWidth = 1,\n isHighlighted = false,\n highlightType,\n isSelected = false,\n showLabel = true,\n showValue = false,\n onClick,\n onHover,\n className,\n children,\n}: DefaultZoneProps) {\n // Calculate colors based on state\n let computedFill = fill;\n let computedStroke = stroke;\n let computedStrokeWidth = strokeWidth;\n\n if (isHighlighted && highlightType && HIGHLIGHT_COLORS[highlightType]) {\n computedFill = HIGHLIGHT_COLORS[highlightType];\n computedStroke = HIGHLIGHT_STROKES[highlightType];\n computedStrokeWidth = 3;\n } else if (isSelected) {\n computedFill = HIGHLIGHT_COLORS.selected;\n computedStroke = HIGHLIGHT_STROKES.selected;\n computedStrokeWidth = 3;\n }\n\n // Render zone shape\n const renderShape = () => {\n if (!zone.shape) return null;\n\n switch (zone.shape.type) {\n case \"polygon\":\n if (!zone.shape.points) return null;\n return (\n <polygon\n points={zone.shape.points.map((p) => `${p.x},${p.y}`).join(\" \")}\n fill={computedFill}\n stroke={computedStroke}\n strokeWidth={computedStrokeWidth}\n />\n );\n\n case \"path\":\n if (!zone.shape.path) return null;\n return (\n <path\n d={zone.shape.path}\n fill={computedFill}\n stroke={computedStroke}\n strokeWidth={computedStrokeWidth}\n />\n );\n\n case \"circle\":\n if (!zone.shape.center) return null;\n return (\n <circle\n cx={zone.shape.center.x}\n cy={zone.shape.center.y}\n r={zone.shape.radius || 30}\n fill={computedFill}\n stroke={computedStroke}\n strokeWidth={computedStrokeWidth}\n />\n );\n\n default:\n return null;\n }\n };\n\n return (\n <g\n onClick={onClick}\n onMouseEnter={() => onHover?.(true)}\n onMouseLeave={() => onHover?.(false)}\n onKeyDown={(event) => handleKeyboardActivation(event, onClick)}\n className={clsx(onClick && \"cursor-pointer\", className)}\n role={onClick ? \"button\" : \"listitem\"}\n aria-label={zone.name}\n tabIndex={onClick ? 0 : undefined}\n >\n {/* Zone shape */}\n {renderShape()}\n\n {/* Zone label */}\n {showLabel && zone.shape?.center && (\n <text\n x={zone.shape.center.x}\n y={zone.shape.center.y - (showValue ? 8 : 0)}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n fill=\"white\"\n fontSize={12}\n fontWeight=\"bold\"\n style={{ textShadow: \"1px 1px 2px rgba(0,0,0,0.8)\" }}\n >\n {zone.name}\n </text>\n )}\n\n {/* Zone value */}\n {showValue && zone.value !== undefined && zone.shape?.center && (\n <text\n x={zone.shape.center.x}\n y={zone.shape.center.y + 8}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n fill=\"#fbbf24\"\n fontSize={10}\n fontWeight=\"bold\"\n style={{ textShadow: \"1px 1px 2px rgba(0,0,0,0.8)\" }}\n >\n +{zone.value}\n </text>\n )}\n\n {/* Children (pieces) */}\n {children}\n </g>\n );\n}\n\nexport interface DefaultZonePiecesProps {\n pieces: ZonePiece[];\n zone: ZoneDefinition;\n playerColors?: Record<string, string>;\n radius?: number;\n spacing?: number;\n yOffset?: number;\n className?: string;\n}\nexport function DefaultZonePieces({\n pieces,\n zone,\n playerColors = EMPTY_PLAYER_COLORS,\n radius = 14,\n spacing = 25,\n yOffset = 20,\n className,\n}: DefaultZonePiecesProps) {\n if (pieces.length === 0 || !zone.shape?.center) return null;\n\n const centerX = zone.shape.center.x;\n const centerY = zone.shape.center.y;\n\n // Group pieces by owner\n const piecesByOwner: Record<string, ZonePiece[]> = {};\n pieces.forEach((p) => {\n const owner = p.owner || \"neutral\";\n const existing = piecesByOwner[owner];\n if (existing) {\n existing.push(p);\n } else {\n piecesByOwner[owner] = [p];\n }\n });\n\n const owners = Object.keys(piecesByOwner);\n const startOffset = -((owners.length - 1) * spacing) / 2;\n\n return (\n <g className={clsx(\"zone-pieces\", className)}>\n {owners.map((owner, i) => {\n const ownerPieces = piecesByOwner[owner] || [];\n const totalCount = ownerPieces.reduce(\n (sum, p) => sum + (p.count || 1),\n 0,\n );\n const offsetX = startOffset + i * spacing;\n\n return (\n <g\n key={owner}\n transform={`translate(${centerX + offsetX}, ${centerY + yOffset})`}\n >\n {/* Piece circle */}\n <circle\n r={radius}\n fill={playerColors[owner] || \"#64748b\"}\n stroke=\"white\"\n strokeWidth={2}\n />\n {/* Count */}\n <text\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n fill=\"white\"\n fontSize={10}\n fontWeight=\"bold\"\n >\n {totalCount}\n </text>\n </g>\n );\n })}\n </g>\n );\n}\n\nexport interface DefaultZonePieceProps {\n piece: ZonePiece;\n x?: number;\n y?: number;\n radius?: number;\n color?: string;\n onClick?: () => void;\n className?: string;\n}\nexport function DefaultZonePiece({\n piece,\n x = 0,\n y = 0,\n radius = 14,\n color = \"#64748b\",\n onClick,\n className,\n}: DefaultZonePieceProps) {\n const count = piece.count || 1;\n\n return (\n <g\n transform={`translate(${x}, ${y})`}\n onClick={(e) => {\n e.stopPropagation();\n onClick?.();\n }}\n onKeyDown={(event) =>\n handleKeyboardActivation(event, onClick, { stopPropagation: true })\n }\n className={clsx(onClick && \"cursor-pointer\", className)}\n role={onClick ? \"button\" : undefined}\n tabIndex={onClick ? 0 : undefined}\n aria-label={`Piece ${piece.id}`}\n >\n <circle r={radius} fill={color} stroke=\"white\" strokeWidth={2} />\n <text\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n fill=\"white\"\n fontSize={10}\n fontWeight=\"bold\"\n >\n {count}\n </text>\n </g>\n );\n}\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\nexport function ZoneMap({\n zones,\n pieces,\n renderZone,\n backgroundImage,\n width = 800,\n height = 600,\n enablePanZoom = false,\n initialZoom = 1,\n minZoom = 0.5,\n maxZoom = 3,\n className,\n}: ZoneMapProps) {\n // Use the unified pan/zoom hook\n const { transform, bind, isDragging } = usePanZoom({\n enabled: enablePanZoom,\n initialZoom,\n minZoom,\n maxZoom,\n mode: \"viewbox\",\n });\n\n // Group pieces by zone\n const piecesByZone = useMemo(() => {\n const map: Record<string, ZonePiece[]> = {};\n pieces.forEach((p) => {\n const existing = map[p.zoneId];\n if (existing) {\n existing.push(p);\n } else {\n map[p.zoneId] = [p];\n }\n });\n return map;\n }, [pieces]);\n\n // Calculate viewBox dimensions\n const baseWidth = typeof width === \"number\" ? width : 800;\n const baseHeight = typeof height === \"number\" ? height : 600;\n const viewBoxWidth = baseWidth / transform.zoom;\n const viewBoxHeight = baseHeight / transform.zoom;\n const viewBoxX = (baseWidth - viewBoxWidth) / 2 - transform.pan.x;\n const viewBoxY = (baseHeight - viewBoxHeight) / 2 - transform.pan.y;\n\n return (\n <svg\n width={width}\n height={height}\n viewBox={`${viewBoxX} ${viewBoxY} ${viewBoxWidth} ${viewBoxHeight}`}\n className={clsx(\n \"overflow-visible\",\n enablePanZoom && \"touch-none\",\n isDragging && \"cursor-grabbing\",\n enablePanZoom && !isDragging && \"cursor-grab\",\n className,\n )}\n {...bind()}\n role=\"img\"\n aria-label=\"Zone map\"\n >\n {/* Background image */}\n {backgroundImage && (\n <image href={backgroundImage} width={width} height={height} />\n )}\n\n {/* Zones */}\n <g className=\"zones\" role=\"list\" aria-label=\"Map zones\">\n {zones.map((zone) => {\n const zonePieces = piecesByZone[zone.id] || [];\n return <g key={zone.id}>{renderZone(zone, zonePieces)}</g>;\n })}\n </g>\n\n {/* Zoom indicator */}\n {enablePanZoom && transform.zoom !== 1 && (\n <g\n transform={`translate(${viewBoxX + 10}, ${viewBoxY + viewBoxHeight - 30})`}\n >\n <rect\n x={0}\n y={0}\n width={60}\n height={20}\n rx={4}\n fill=\"rgba(0,0,0,0.6)\"\n />\n <text x={30} y={14} textAnchor=\"middle\" fill=\"white\" fontSize={12}>\n {Math.round(transform.zoom * 100)}%\n </text>\n </g>\n )}\n </svg>\n );\n}\n","/**\n * SVG-based track visualization for racing and path games\n * (Monopoly, Game of Life, Snakes & Ladders). Supports linear, circular, and branching tracks.\n */\n\nimport { useMemo, type ReactNode } from \"react\";\nimport { clsx } from \"clsx\";\nimport { usePanZoom } from \"../../hooks/usePanZoom.js\";\nimport { handleKeyboardActivation } from \"./interaction-accessibility.js\";\n\nexport interface TrackSpace<\n SpaceIdValue extends string = string,\n Data = unknown,\n> {\n id: SpaceIdValue;\n index: number;\n name?: string;\n type?: string;\n /** Override next spaces (for branching) */\n nextSpaces?: readonly SpaceIdValue[];\n /** Jump to another space (snakes/ladders) */\n jumpTo?: SpaceIdValue;\n position: { x: number; y: number };\n data?: Data;\n}\n\nexport interface TrackPiece<\n PieceIdValue extends string = string,\n SpaceIdValue extends string = string,\n OwnerIdValue extends string = string,\n Data = unknown,\n> {\n id: PieceIdValue;\n spaceId: SpaceIdValue;\n owner: OwnerIdValue;\n type?: string;\n data?: Data;\n}\n\nexport interface TrackBoardProps {\n spaces: TrackSpace[];\n pieces: TrackPiece[];\n type?: \"linear\" | \"circular\" | \"branching\";\n renderSpace: (space: TrackSpace, pieces: TrackPiece[]) => ReactNode;\n renderConnection?: (\n from: { x: number; y: number },\n to: { x: number; y: number },\n fromSpace: TrackSpace,\n toSpace: TrackSpace,\n ) => ReactNode;\n renderJump?: (\n from: { x: number; y: number },\n to: { x: number; y: number },\n fromSpace: TrackSpace,\n toSpace: TrackSpace,\n isUp: boolean,\n ) => ReactNode;\n width?: number | string;\n height?: number | string;\n enablePanZoom?: boolean;\n initialZoom?: number;\n minZoom?: number;\n maxZoom?: number;\n className?: string;\n}\n\n// ============================================================================\n// Helper Components\n// ============================================================================\n\nexport interface DefaultTrackSpaceProps {\n space: TrackSpace;\n size?: number;\n fill?: string;\n stroke?: string;\n strokeWidth?: number;\n isHighlighted?: boolean;\n isSelected?: boolean;\n showJumpIndicator?: boolean;\n onClick?: () => void;\n onHover?: (hovering: boolean) => void;\n className?: string;\n children?: ReactNode;\n}\nexport function DefaultTrackSpace({\n space,\n size = 50,\n fill = \"#1e293b\",\n stroke = \"#475569\",\n strokeWidth = 1,\n isHighlighted = false,\n isSelected = false,\n showJumpIndicator = true,\n onClick,\n onHover,\n className,\n children,\n}: DefaultTrackSpaceProps) {\n const halfSize = size / 2;\n\n const computedFill = isHighlighted ? \"rgba(59, 130, 246, 0.3)\" : fill;\n const computedStroke = isSelected\n ? \"#3b82f6\"\n : isHighlighted\n ? \"#60a5fa\"\n : stroke;\n const computedStrokeWidth = isHighlighted || isSelected ? 3 : strokeWidth;\n\n return (\n <g\n onClick={onClick}\n onMouseEnter={() => onHover?.(true)}\n onMouseLeave={() => onHover?.(false)}\n onKeyDown={(event) => handleKeyboardActivation(event, onClick)}\n className={clsx(onClick && \"cursor-pointer\", className)}\n role={onClick ? \"button\" : \"listitem\"}\n aria-label={space.name || `Space ${space.index}`}\n tabIndex={onClick ? 0 : undefined}\n >\n {/* Space background */}\n <rect\n x={-halfSize}\n y={-halfSize}\n width={size}\n height={size}\n rx={8}\n fill={computedFill}\n stroke={computedStroke}\n strokeWidth={computedStrokeWidth}\n />\n\n {/* Space name or index */}\n {space.name ? (\n <text\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n fill=\"white\"\n fontSize={space.name.length > 4 ? 8 : 10}\n fontWeight=\"bold\"\n >\n {space.name.length > 8 ? space.name.slice(0, 7) + \"…\" : space.name}\n </text>\n ) : (\n <text\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n fill=\"#94a3b8\"\n fontSize={12}\n fontWeight=\"bold\"\n >\n {space.index}\n </text>\n )}\n\n {/* Jump indicator */}\n {showJumpIndicator && space.jumpTo && (\n <g transform={`translate(${halfSize - 6}, ${-halfSize + 6})`}>\n <circle r={6} fill=\"#fbbf24\" />\n <text\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n fill=\"black\"\n fontSize={8}\n fontWeight=\"bold\"\n >\n ↗\n </text>\n </g>\n )}\n\n {/* Pieces */}\n {children}\n </g>\n );\n}\n\nexport interface DefaultTrackPieceProps {\n piece: TrackPiece;\n index?: number;\n total?: number;\n radius?: number;\n color?: string;\n onClick?: () => void;\n className?: string;\n}\nexport function DefaultTrackPiece({\n piece,\n index = 0,\n total = 1,\n radius = 8,\n color = \"#f59e0b\",\n onClick,\n className,\n}: DefaultTrackPieceProps) {\n // Arrange pieces in a circle around the space center\n const spacing = radius * 2.2;\n const angle = (index / total) * 2 * Math.PI - Math.PI / 2;\n const offset = total > 1 ? spacing : 0;\n const px = Math.cos(angle) * offset;\n const py = Math.sin(angle) * offset;\n\n return (\n <circle\n cx={px}\n cy={py}\n r={radius}\n fill={color}\n stroke=\"white\"\n strokeWidth={2}\n onClick={(e) => {\n e.stopPropagation();\n onClick?.();\n }}\n onKeyDown={(event) =>\n handleKeyboardActivation(event, onClick, { stopPropagation: true })\n }\n className={clsx(onClick && \"cursor-pointer\", className)}\n role={onClick ? \"button\" : undefined}\n tabIndex={onClick ? 0 : undefined}\n aria-label={`Piece ${piece.id} owned by ${piece.owner}`}\n />\n );\n}\n\nexport interface DefaultTrackConnectionProps {\n from: { x: number; y: number };\n to: { x: number; y: number };\n stroke?: string;\n strokeWidth?: number;\n className?: string;\n}\nexport function DefaultTrackConnection({\n from,\n to,\n stroke = \"#475569\",\n strokeWidth = 2,\n className,\n}: DefaultTrackConnectionProps) {\n return (\n <line\n x1={from.x}\n y1={from.y}\n x2={to.x}\n y2={to.y}\n stroke={stroke}\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n className={className}\n />\n );\n}\n\nexport interface DefaultTrackJumpProps {\n from: { x: number; y: number };\n to: { x: number; y: number };\n /** Whether the jump goes forward or backward */\n isUp: boolean;\n spaceSize?: number;\n upColor?: string;\n downColor?: string;\n strokeWidth?: number;\n className?: string;\n}\nexport function DefaultTrackJump({\n from,\n to,\n isUp,\n spaceSize = 50,\n upColor = \"#22c55e\",\n downColor = \"#ef4444\",\n strokeWidth = 3,\n className,\n}: DefaultTrackJumpProps) {\n const color = isUp ? upColor : downColor;\n\n // Calculate arrow direction\n const dx = to.x - from.x;\n const dy = to.y - from.y;\n const len = Math.sqrt(dx * dx + dy * dy);\n const unitX = dx / len;\n const unitY = dy / len;\n\n // Offset start and end points\n const startX = from.x + unitX * (spaceSize / 2 + 5);\n const startY = from.y + unitY * (spaceSize / 2 + 5);\n const endX = to.x - unitX * (spaceSize / 2 + 5);\n const endY = to.y - unitY * (spaceSize / 2 + 5);\n\n // Generate unique marker IDs\n const markerId = `arrow-${isUp ? \"up\" : \"down\"}-${from.x}-${from.y}`;\n\n return (\n <g className={className}>\n <defs>\n <marker\n id={markerId}\n markerWidth=\"10\"\n markerHeight=\"7\"\n refX=\"9\"\n refY=\"3.5\"\n orient=\"auto\"\n >\n <polygon points=\"0 0, 10 3.5, 0 7\" fill={color} />\n </marker>\n </defs>\n <line\n x1={startX}\n y1={startY}\n x2={endX}\n y2={endY}\n stroke={color}\n strokeWidth={strokeWidth}\n strokeDasharray=\"6,4\"\n markerEnd={`url(#${markerId})`}\n />\n </g>\n );\n}\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\nexport function TrackBoard({\n spaces,\n pieces,\n type = \"linear\",\n renderSpace,\n renderConnection,\n renderJump,\n width = 800,\n height = 600,\n enablePanZoom = false,\n initialZoom = 1,\n minZoom = 0.5,\n maxZoom = 3,\n className,\n}: TrackBoardProps) {\n // Use the unified pan/zoom hook\n const { transform, bind, isDragging } = usePanZoom({\n enabled: enablePanZoom,\n initialZoom,\n minZoom,\n maxZoom,\n mode: \"viewbox\",\n });\n\n // Group pieces by space\n const piecesBySpace = useMemo(() => {\n const map: Record<string, TrackPiece[]> = {};\n pieces.forEach((p) => {\n const existing = map[p.spaceId];\n if (existing) {\n existing.push(p);\n } else {\n map[p.spaceId] = [p];\n }\n });\n return map;\n }, [pieces]);\n\n // Sort spaces by index for drawing connections\n const sortedSpaces = useMemo(() => {\n return [...spaces].sort((a, b) => a.index - b.index);\n }, [spaces]);\n\n // Create space lookup\n const spaceMap = useMemo(() => {\n return new Map(spaces.map((s) => [s.id, s]));\n }, [spaces]);\n\n // Render connections between spaces\n const renderConnections = () => {\n if (!renderConnection) return null;\n\n return sortedSpaces.map((space, i) => {\n const nextSpace = sortedSpaces[i + 1];\n const firstSpace = sortedSpaces[0];\n const nextSpaceIds =\n space.nextSpaces ||\n (i < sortedSpaces.length - 1 && nextSpace\n ? [nextSpace.id]\n : type === \"circular\" && firstSpace\n ? [firstSpace.id]\n : []);\n\n return nextSpaceIds.map((nextId) => {\n const targetSpace = spaceMap.get(nextId);\n if (!targetSpace) return null;\n\n return (\n <g key={`${space.id}-${nextId}`}>\n {renderConnection(\n space.position,\n targetSpace.position,\n space,\n targetSpace,\n )}\n </g>\n );\n });\n });\n };\n\n // Render jump arrows (snakes/ladders)\n const renderJumps = () => {\n if (!renderJump) return null;\n\n return spaces.flatMap((space) => {\n if (!space.jumpTo) return [];\n const targetSpace = spaceMap.get(space.jumpTo);\n if (!targetSpace) return [];\n\n const isUp = targetSpace.index > space.index;\n\n return [\n <g key={`jump-${space.id}`}>\n {renderJump(\n space.position,\n targetSpace.position,\n space,\n targetSpace,\n isUp,\n )}\n </g>,\n ];\n });\n };\n\n // Calculate viewBox dimensions\n const baseWidth = typeof width === \"number\" ? width : 800;\n const baseHeight = typeof height === \"number\" ? height : 600;\n const viewBoxWidth = baseWidth / transform.zoom;\n const viewBoxHeight = baseHeight / transform.zoom;\n const viewBoxX = (baseWidth - viewBoxWidth) / 2 - transform.pan.x;\n const viewBoxY = (baseHeight - viewBoxHeight) / 2 - transform.pan.y;\n\n return (\n <svg\n width={width}\n height={height}\n viewBox={`${viewBoxX} ${viewBoxY} ${viewBoxWidth} ${viewBoxHeight}`}\n className={clsx(\n \"overflow-visible\",\n enablePanZoom && \"touch-none\",\n isDragging && \"cursor-grabbing\",\n enablePanZoom && !isDragging && \"cursor-grab\",\n className,\n )}\n {...bind()}\n role=\"img\"\n aria-label=\"Track board\"\n >\n {/* Connections layer */}\n <g className=\"track-connections\">{renderConnections()}</g>\n\n {/* Jump arrows layer */}\n <g className=\"track-jumps\">{renderJumps()}</g>\n\n {/* Spaces layer */}\n <g className=\"track-spaces\" role=\"list\" aria-label=\"Track spaces\">\n {spaces.map((space) => {\n const spacePieces = piecesBySpace[space.id] || [];\n\n return (\n <g\n key={space.id}\n transform={`translate(${space.position.x}, ${space.position.y})`}\n >\n {renderSpace(space, spacePieces)}\n </g>\n );\n })}\n </g>\n\n {/* Zoom indicator */}\n {enablePanZoom && transform.zoom !== 1 && (\n <g\n transform={`translate(${viewBoxX + 10}, ${viewBoxY + viewBoxHeight - 30})`}\n >\n <rect\n x={0}\n y={0}\n width={60}\n height={20}\n rx={4}\n fill=\"rgba(0,0,0,0.6)\"\n />\n <text x={30} y={14} textAnchor=\"middle\" fill=\"white\" fontSize={12}>\n {Math.round(transform.zoom * 100)}%\n </text>\n </g>\n )}\n </svg>\n );\n}\n","/**\n * Worker placement visualization for Euro games (Agricola, Viticulture, Lords of Waterdeep).\n */\n\nimport { useMemo, type ReactNode } from \"react\";\nimport { clsx } from \"clsx\";\nimport { Users, Lock, Gift, Coins } from \"lucide-react\";\nimport type { ViewSlotOccupant } from \"../../../types/index.js\";\nimport { useTheme } from \"../../theme/ThemeProvider.js\";\nimport { handleKeyboardActivation } from \"./interaction-accessibility.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface SlotDefinition {\n id: string;\n name: string;\n description?: string;\n capacity: number;\n /** One player per round */\n exclusive?: boolean;\n /** Personal action space owner */\n owner?: string;\n group?: string;\n cost?: Record<string, number>;\n reward?: Record<string, number>;\n type?: string;\n position?: { x: number; y: number };\n data?: Record<string, unknown>;\n}\n\nexport type SlotOccupant = ViewSlotOccupant;\n\nexport interface SlotSystemProps {\n slots: readonly SlotDefinition[];\n occupants: readonly SlotOccupant[];\n renderSlot: (\n slot: SlotDefinition,\n occupants: readonly SlotOccupant[],\n ) => ReactNode;\n layout?: \"grid\" | \"list\" | \"grouped\";\n width?: number | string;\n height?: number | string;\n /** Minimum slot width for responsive grid */\n minSlotWidth?: number;\n className?: string;\n}\n\nconst EMPTY_SLOT_OCCUPANTS: readonly SlotOccupant[] = [];\n\n// ============================================================================\n// Pre-built Helper Components\n// ============================================================================\n\nexport interface DefaultSlotItemProps {\n name: string;\n description?: string;\n capacity: number;\n occupantCount: number;\n isExclusive?: boolean;\n isAvailable?: boolean;\n isHighlighted?: boolean;\n isSelected?: boolean;\n costLabel?: string;\n rewardLabel?: string;\n renderOccupants?: () => ReactNode;\n onClick?: () => void;\n onPointerEnter?: () => void;\n onPointerLeave?: () => void;\n className?: string;\n}\n\n/** Pre-built slot item for use in `renderSlot`. */\nexport function DefaultSlotItem({\n name,\n description,\n capacity,\n occupantCount,\n isExclusive = false,\n isAvailable = true,\n isHighlighted = false,\n isSelected = false,\n costLabel,\n rewardLabel,\n renderOccupants,\n onClick,\n onPointerEnter,\n onPointerLeave,\n className,\n}: DefaultSlotItemProps) {\n const theme = useTheme();\n const isFull = occupantCount >= capacity;\n const borderColor = isSelected\n ? theme.semantic.intent.primary.border\n : isFull\n ? theme.semantic.border.strong\n : isAvailable\n ? theme.semantic.border.default\n : theme.semantic.border.subtle;\n const background = isSelected\n ? theme.semantic.intent.primary.soft\n : isFull\n ? theme.semantic.surface.inset\n : theme.semantic.surface.card;\n const ringColor = isSelected\n ? theme.semantic.intent.primary.border\n : isHighlighted\n ? theme.semantic.intent.warning.border\n : undefined;\n\n return (\n <div\n onClick={isAvailable ? onClick : undefined}\n onPointerEnter={onPointerEnter}\n onPointerLeave={onPointerLeave}\n onKeyDown={(event) =>\n handleKeyboardActivation(event, isAvailable ? onClick : undefined)\n }\n className={clsx(\n \"p-4 rounded-lg border-2 transition-all\",\n isAvailable && onClick && \"cursor-pointer hover:opacity-90\",\n className,\n )}\n style={{\n borderColor,\n background,\n boxShadow: ringColor ? `0 0 0 2px ${ringColor}` : undefined,\n }}\n role={isAvailable && onClick ? \"button\" : undefined}\n aria-label={name}\n aria-disabled={!isAvailable}\n tabIndex={isAvailable && onClick ? 0 : undefined}\n >\n {/* Header */}\n <div className=\"flex items-start justify-between gap-2\">\n <div>\n <h3\n className=\"font-bold\"\n style={{ color: theme.semantic.text.primary }}\n >\n {name}\n </h3>\n {description && (\n <p\n className=\"text-xs mt-0.5\"\n style={{ color: theme.semantic.text.muted }}\n >\n {description}\n </p>\n )}\n </div>\n\n {/* Status indicators */}\n <div className=\"flex items-center gap-1\">\n {isExclusive && (\n <Lock\n className=\"w-4 h-4\"\n style={{ color: theme.semantic.intent.warning.solid }}\n aria-label=\"Exclusive slot\"\n />\n )}\n {capacity > 1 && (\n <div\n className=\"flex items-center gap-0.5 text-xs\"\n style={{ color: theme.semantic.text.muted }}\n title={`Capacity: ${capacity}`}\n >\n <Users className=\"w-3 h-3\" />\n <span>{capacity}</span>\n </div>\n )}\n </div>\n </div>\n\n {/* Cost/Reward */}\n {(costLabel || rewardLabel) && (\n <div className=\"mt-2 flex flex-wrap gap-2 text-xs\">\n {costLabel && (\n <div\n className=\"flex items-center gap-1\"\n style={{ color: theme.semantic.intent.danger.solid }}\n >\n <Coins className=\"w-3 h-3\" aria-hidden=\"true\" />\n <span>{costLabel}</span>\n </div>\n )}\n {rewardLabel && (\n <div\n className=\"flex items-center gap-1\"\n style={{ color: theme.semantic.intent.success.solid }}\n >\n <Gift className=\"w-3 h-3\" aria-hidden=\"true\" />\n <span>{rewardLabel}</span>\n </div>\n )}\n </div>\n )}\n\n {/* Occupants */}\n {renderOccupants && <div className=\"mt-2\">{renderOccupants()}</div>}\n\n {/* Availability indicator */}\n {!isAvailable && !isFull && (\n <div\n className=\"mt-2 text-xs\"\n style={{ color: theme.semantic.text.disabled }}\n >\n Not available\n </div>\n )}\n </div>\n );\n}\n\nexport interface DefaultSlotOccupantProps {\n color?: string;\n size?: number;\n shape?: \"circle\" | \"square\";\n label?: string;\n onClick?: () => void;\n className?: string;\n}\nexport function DefaultSlotOccupant({\n color = \"#3b82f6\",\n size = 24,\n shape = \"circle\",\n label,\n onClick,\n className,\n}: DefaultSlotOccupantProps) {\n return (\n <div\n onClick={onClick}\n onKeyDown={(event) => handleKeyboardActivation(event, onClick)}\n className={clsx(\n \"transition-all\",\n shape === \"circle\" ? \"rounded-full\" : \"rounded\",\n onClick && \"cursor-pointer hover:scale-110\",\n className,\n )}\n style={{\n width: size,\n height: size,\n backgroundColor: color,\n }}\n title={label}\n role={onClick ? \"button\" : \"img\"}\n aria-label={label ?? \"Occupant\"}\n tabIndex={onClick ? 0 : undefined}\n />\n );\n}\n\nexport interface DefaultEmptySlotProps {\n size?: number;\n className?: string;\n}\nexport function DefaultEmptySlot({\n size = 24,\n className,\n}: DefaultEmptySlotProps) {\n const theme = useTheme();\n\n return (\n <div\n className={clsx(\"rounded-full border-2 border-dashed\", className)}\n style={{\n width: size,\n height: size,\n borderColor: theme.semantic.border.default,\n }}\n title=\"Empty slot\"\n role=\"img\"\n aria-label=\"Empty slot\"\n />\n );\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport function SlotSystem({\n slots,\n occupants = EMPTY_SLOT_OCCUPANTS,\n renderSlot,\n layout = \"grid\",\n width,\n height,\n minSlotWidth = 280,\n className,\n}: SlotSystemProps) {\n const theme = useTheme();\n\n // Group occupants by slot\n const occupantsBySlot = useMemo(() => {\n const map: Record<string, SlotOccupant[]> = {};\n occupants.forEach((o) => {\n const slotId = o.slotId;\n const existing = map[slotId];\n if (existing) {\n existing.push(o);\n } else {\n map[slotId] = [o];\n }\n });\n return map;\n }, [occupants]);\n\n // Group slots by group property for grouped layout\n const slotGroups = useMemo(() => {\n if (layout !== \"grouped\") return null;\n\n const groups: Record<string, SlotDefinition[]> = {};\n slots.forEach((slot) => {\n const group = slot.group ?? \"Other\";\n const existing = groups[group];\n if (existing) {\n existing.push(slot);\n } else {\n groups[group] = [slot];\n }\n });\n return groups;\n }, [slots, layout]);\n\n // Render a single slot\n const renderSlotItem = (slot: SlotDefinition) => {\n const slotOccupants = occupantsBySlot[slot.id] ?? [];\n\n return (\n <div key={slot.id} role=\"listitem\" aria-label={slot.name}>\n {renderSlot(slot, slotOccupants)}\n </div>\n );\n };\n\n // Responsive grid style - uses auto-fit to stack items when they don't fit\n const responsiveGridStyle = {\n display: \"grid\",\n gridTemplateColumns: `repeat(auto-fit, minmax(${minSlotWidth}px, 1fr))`,\n gap: \"1rem\",\n };\n\n // Container wrapper\n const wrapContent = (content: ReactNode) => (\n <div style={{ width, height }} className={clsx(\"slot-system\", className)}>\n {content}\n </div>\n );\n\n // Render based on layout\n if (layout === \"grouped\" && slotGroups) {\n return wrapContent(\n <div className=\"space-y-6\" role=\"list\">\n {Object.entries(slotGroups).map(([groupName, groupSlots]) => (\n <div key={groupName}>\n <h3\n className=\"text-lg font-semibold mb-3\"\n style={{ color: theme.semantic.text.primary }}\n >\n {groupName}\n </h3>\n <div style={responsiveGridStyle}>\n {groupSlots.map(renderSlotItem)}\n </div>\n </div>\n ))}\n </div>,\n );\n }\n\n if (layout === \"list\") {\n return wrapContent(\n <div className=\"flex flex-col gap-2\" role=\"list\">\n {slots.map(renderSlotItem)}\n </div>,\n );\n }\n\n // Default grid layout - responsive by default\n return wrapContent(\n <div style={responsiveGridStyle} role=\"list\">\n {slots.map(renderSlotItem)}\n </div>,\n );\n}\n","/**\n * SVG-based square grid for grid-based games (Chess, Checkers, Go, Scrabble, Battleship).\n * All rendering controlled by parent via required render functions.\n */\n\nimport { useMemo, useState, type ReactNode } from \"react\";\nimport { clsx } from \"clsx\";\nimport { usePanZoom } from \"../../hooks/usePanZoom.js\";\nimport { handleKeyboardActivation } from \"./interaction-accessibility.js\";\nimport {\n interactiveTargetRenderState,\n isInteractiveTargetSelectable,\n type InteractiveTargetLayer,\n type InteractiveTargetRenderState,\n} from \"./target-layer.js\";\nimport type { SquarePieceState } from \"../../types/player-state.js\";\nimport {\n type AuthoredSquareBoardInput,\n type AnySquareBoardInput,\n type GeneratedSquareBoardInput,\n type NormalizedSquareBoard,\n type NormalizedSquareCellOf,\n type NormalizedSquareEdgeOf,\n type NormalizedSquarePieceOf,\n type NormalizedSquareVertexOf,\n normalizeSquareBoardInput,\n} from \"../../types/tiled-board.js\";\n\nexport type {\n InteractiveTargetLayer,\n InteractiveTargetRenderState,\n} from \"./target-layer.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface SquareCellWithId {\n id: string;\n row: number;\n col: number;\n}\n\nexport interface SquareEdgePosition {\n x1: number;\n y1: number;\n x2: number;\n y2: number;\n midX: number;\n midY: number;\n angle: number;\n}\n\nexport interface SquareVertexPosition {\n x: number;\n y: number;\n}\n\nexport interface InteractiveSquareEdge<\n TBoard extends AnySquareBoardInput = AnySquareBoardInput,\n> extends NormalizedSquareEdgeOf<TBoard> {\n position: SquareEdgePosition;\n}\n\nexport interface InteractiveSquareVertex<\n TBoard extends AnySquareBoardInput = AnySquareBoardInput,\n> extends NormalizedSquareVertexOf<TBoard> {\n position: SquareVertexPosition;\n}\n\nexport type InteractiveSquareSpace<\n TBoard extends AnySquareBoardInput = AnySquareBoardInput,\n> = NormalizedSquareCellOf<TBoard>;\n\ninterface SquareGeneratedGridInputProps {\n id?: string;\n layout?: \"square\";\n spaces: Extract<AnySquareBoardInput, { spaces: unknown }>[\"spaces\"];\n pieces?: AnySquareBoardInput[\"pieces\"];\n edges?: AnySquareBoardInput[\"edges\"];\n vertices?: AnySquareBoardInput[\"vertices\"];\n}\n\ninterface SquareAuthoredGridInputProps {\n id?: string;\n layout?: \"square\";\n rows?: number;\n cols?: number;\n cells: Extract<AnySquareBoardInput, { cells: unknown }>[\"cells\"];\n pieces?: readonly SquarePieceState[];\n edges?: AnySquareBoardInput[\"edges\"];\n vertices?: AnySquareBoardInput[\"vertices\"];\n}\n\ntype SquareGridInputProps =\n | SquareGeneratedGridInputProps\n | SquareAuthoredGridInputProps;\n\ntype ResolvedSquareArrayProp<Value> =\n Exclude<Value, undefined> extends readonly unknown[]\n ? Exclude<Value, undefined>\n : readonly [];\n\ntype SquareBoardLikeOfProps<TProps extends SquareGridInputProps> =\n TProps extends {\n id?: infer Id;\n layout?: infer Layout;\n spaces: infer Spaces;\n pieces?: infer Pieces;\n edges?: infer Edges;\n vertices?: infer Vertices;\n }\n ? {\n id: Extract<Id, string> extends never ? string : Extract<Id, string>;\n layout?: Extract<Layout, \"square\">;\n spaces: Spaces;\n pieces: ResolvedSquareArrayProp<Pieces>;\n edges: ResolvedSquareArrayProp<Edges>;\n vertices: ResolvedSquareArrayProp<Vertices>;\n } & GeneratedSquareBoardInput\n : TProps extends {\n id?: infer Id;\n layout?: infer Layout;\n rows?: infer Rows;\n cols?: infer Cols;\n cells: infer Cells;\n pieces?: infer Pieces;\n edges?: infer Edges;\n vertices?: infer Vertices;\n }\n ? {\n id: Extract<Id, string> extends never ? string : Extract<Id, string>;\n layout?: Extract<Layout, \"square\">;\n rows: Extract<Rows, number> extends never\n ? number\n : Extract<Rows, number>;\n cols: Extract<Cols, number> extends never\n ? number\n : Extract<Cols, number>;\n cells: Cells;\n pieces: ResolvedSquareArrayProp<Pieces>;\n edges: ResolvedSquareArrayProp<Edges>;\n vertices: ResolvedSquareArrayProp<Vertices>;\n } & AuthoredSquareBoardInput\n : never;\n\nexport type SquareGridProps<\n TProps extends SquareGridInputProps = SquareGridInputProps,\n> = TProps & {\n cellSize?: number;\n /** Receives row/col with transform centered at cell position */\n renderCell: (row: number, col: number) => ReactNode;\n /** Receives piece with transform centered at cell center */\n renderPiece: (\n piece: NormalizedSquarePieceOf<NoInfer<SquareBoardLikeOfProps<TProps>>>,\n ) => ReactNode;\n renderEdge?: (\n edge: NormalizedSquareEdgeOf<NoInfer<SquareBoardLikeOfProps<TProps>>>,\n position: SquareEdgePosition,\n ) => ReactNode;\n renderVertex?: (\n vertex: NormalizedSquareVertexOf<NoInfer<SquareBoardLikeOfProps<TProps>>>,\n position: SquareVertexPosition,\n ) => ReactNode;\n showCoordinates?: boolean;\n coordinateStyle?: \"algebraic\" | \"numeric\" | \"none\";\n width?: number | string;\n height?: number | string;\n enablePanZoom?: boolean;\n initialZoom?: number;\n minZoom?: number;\n maxZoom?: number;\n className?: string;\n interactiveSpaces?: InteractiveTargetLayer;\n interactiveEdges?: InteractiveTargetLayer;\n interactiveVertices?: InteractiveTargetLayer;\n renderInteractiveSpace?: (\n space: InteractiveSquareSpace<NoInfer<SquareBoardLikeOfProps<TProps>>>,\n state: InteractiveTargetRenderState,\n ) => ReactNode;\n renderInteractiveEdge?: (\n edge: InteractiveSquareEdge<NoInfer<SquareBoardLikeOfProps<TProps>>>,\n position: SquareEdgePosition,\n state: InteractiveTargetRenderState,\n ) => ReactNode;\n renderInteractiveVertex?: (\n vertex: InteractiveSquareVertex<NoInfer<SquareBoardLikeOfProps<TProps>>>,\n position: SquareVertexPosition,\n state: InteractiveTargetRenderState,\n ) => ReactNode;\n};\n\nexport interface SquareGridBoardProps<\n TBoard extends AnySquareBoardInput = AnySquareBoardInput,\n> {\n board: TBoard;\n cellSize?: number;\n renderCell: (row: number, col: number) => ReactNode;\n renderPiece: (piece: NormalizedSquarePieceOf<NoInfer<TBoard>>) => ReactNode;\n renderEdge?: (\n edge: NormalizedSquareEdgeOf<NoInfer<TBoard>>,\n position: SquareEdgePosition,\n ) => ReactNode;\n renderVertex?: (\n vertex: NormalizedSquareVertexOf<NoInfer<TBoard>>,\n position: SquareVertexPosition,\n ) => ReactNode;\n showCoordinates?: boolean;\n coordinateStyle?: \"algebraic\" | \"numeric\" | \"none\";\n width?: number | string;\n height?: number | string;\n enablePanZoom?: boolean;\n initialZoom?: number;\n minZoom?: number;\n maxZoom?: number;\n className?: string;\n interactiveSpaces?: InteractiveTargetLayer;\n interactiveEdges?: InteractiveTargetLayer;\n interactiveVertices?: InteractiveTargetLayer;\n renderInteractiveSpace?: (\n space: InteractiveSquareSpace<NoInfer<TBoard>>,\n state: InteractiveTargetRenderState,\n ) => ReactNode;\n renderInteractiveEdge?: (\n edge: InteractiveSquareEdge<NoInfer<TBoard>>,\n position: SquareEdgePosition,\n state: InteractiveTargetRenderState,\n ) => ReactNode;\n renderInteractiveVertex?: (\n vertex: InteractiveSquareVertex<NoInfer<TBoard>>,\n position: SquareVertexPosition,\n state: InteractiveTargetRenderState,\n ) => ReactNode;\n}\n\n// ============================================================================\n// Pre-built Helper Components\n// ============================================================================\n\nexport interface DefaultGridCellProps {\n size: number;\n isLight?: boolean;\n lightColor?: string;\n darkColor?: string;\n isHighlighted?: boolean;\n highlightColor?: string;\n isSelected?: boolean;\n selectedColor?: string;\n isValidMove?: boolean;\n isCapture?: boolean;\n onClick?: () => void;\n onPointerEnter?: () => void;\n onPointerLeave?: () => void;\n className?: string;\n}\n\n/** Pre-built grid cell component for use in `renderCell`. */\nexport function DefaultGridCell({\n size,\n isLight = true,\n lightColor = \"#f0d9b5\",\n darkColor = \"#b58863\",\n isHighlighted = false,\n highlightColor = \"rgba(250, 204, 21, 0.4)\",\n isSelected = false,\n selectedColor = \"rgba(59, 130, 246, 0.5)\",\n isValidMove = false,\n isCapture = false,\n onClick,\n onPointerEnter,\n onPointerLeave,\n className,\n}: DefaultGridCellProps) {\n const baseColor = isLight ? lightColor : darkColor;\n\n return (\n <g\n onClick={onClick}\n onPointerEnter={onPointerEnter}\n onPointerLeave={onPointerLeave}\n onKeyDown={(event) => handleKeyboardActivation(event, onClick)}\n className={clsx(\n \"transition-colors duration-100\",\n onClick && \"cursor-pointer\",\n className,\n )}\n role={onClick ? \"button\" : undefined}\n tabIndex={onClick ? 0 : undefined}\n aria-label={onClick ? \"Grid cell\" : undefined}\n >\n {/* Base cell */}\n <rect width={size} height={size} fill={baseColor} />\n\n {/* Selected overlay */}\n {isSelected && (\n <rect\n width={size}\n height={size}\n fill={selectedColor}\n pointerEvents=\"none\"\n />\n )}\n\n {/* Highlight overlay */}\n {isHighlighted && !isSelected && (\n <rect\n width={size}\n height={size}\n fill={highlightColor}\n pointerEvents=\"none\"\n />\n )}\n\n {/* Valid move indicator (dot) */}\n {isValidMove && !isCapture && (\n <circle\n cx={size / 2}\n cy={size / 2}\n r={size * 0.15}\n fill=\"rgba(34, 197, 94, 0.6)\"\n pointerEvents=\"none\"\n />\n )}\n\n {/* Capture indicator (ring) */}\n {isCapture && (\n <circle\n cx={size / 2}\n cy={size / 2}\n r={size * 0.42}\n fill=\"none\"\n stroke=\"rgba(239, 68, 68, 0.8)\"\n strokeWidth={size * 0.08}\n pointerEvents=\"none\"\n />\n )}\n </g>\n );\n}\n\nexport interface DefaultGridPieceProps {\n size: number;\n color?: string;\n strokeColor?: string;\n label?: string;\n isDragging?: boolean;\n onClick?: () => void;\n onPointerDown?: (e: React.PointerEvent) => void;\n className?: string;\n}\n\n/** Pre-built grid piece component for use in `renderPiece`. */\nexport function DefaultGridPiece({\n size,\n color = \"#94a3b8\",\n strokeColor,\n label,\n isDragging = false,\n onClick,\n onPointerDown,\n className,\n}: DefaultGridPieceProps) {\n const radius = size * 0.38;\n const effectiveStroke =\n strokeColor ??\n (color === \"#f8fafc\" || color === \"#ffffff\" ? \"#1e293b\" : \"#f8fafc\");\n\n return (\n <g\n onClick={onClick}\n onPointerDown={onPointerDown}\n onKeyDown={(event) => handleKeyboardActivation(event, onClick)}\n className={clsx(\n \"transition-transform duration-150\",\n (onClick || onPointerDown) && \"cursor-pointer hover:scale-105\",\n className,\n )}\n opacity={isDragging ? 0.8 : 1}\n role={onClick ? \"button\" : undefined}\n tabIndex={onClick ? 0 : undefined}\n aria-label={onClick ? (label ?? \"Grid piece\") : undefined}\n >\n <circle\n r={isDragging ? radius * 1.1 : radius}\n fill={color}\n stroke={effectiveStroke}\n strokeWidth={2}\n style={{ filter: \"drop-shadow(1px 2px 2px rgba(0,0,0,0.4))\" }}\n />\n {label && (\n <text\n y={4}\n textAnchor=\"middle\"\n fill={effectiveStroke}\n fontSize={size * 0.35}\n fontWeight=\"bold\"\n pointerEvents=\"none\"\n >\n {label}\n </text>\n )}\n </g>\n );\n}\n\nexport interface DefaultChessPieceProps {\n size: number;\n type: string;\n owner: \"white\" | \"black\";\n onClick?: () => void;\n onPointerDown?: (e: React.PointerEvent) => void;\n className?: string;\n}\n\nconst CHESS_SYMBOLS: Record<string, Record<string, string>> = {\n white: {\n king: \"♔\",\n queen: \"♕\",\n rook: \"♖\",\n bishop: \"♗\",\n knight: \"♘\",\n pawn: \"♙\",\n },\n black: {\n king: \"♚\",\n queen: \"♛\",\n rook: \"♜\",\n bishop: \"♝\",\n knight: \"♞\",\n pawn: \"♟\",\n },\n};\n\n/** Pre-built chess piece component using Unicode symbols. */\nexport function DefaultChessPiece({\n size,\n type,\n owner,\n onClick,\n onPointerDown,\n className,\n}: DefaultChessPieceProps) {\n const symbol = CHESS_SYMBOLS[owner]?.[type] ?? \"?\";\n const textColor = owner === \"white\" ? \"#f8fafc\" : \"#1e293b\";\n const shadowFilter =\n owner === \"white\"\n ? \"drop-shadow(1px 1px 1px rgba(0,0,0,0.5))\"\n : \"drop-shadow(1px 1px 1px rgba(255,255,255,0.3))\";\n\n return (\n <g\n onClick={onClick}\n onPointerDown={onPointerDown}\n onKeyDown={(event) => handleKeyboardActivation(event, onClick)}\n className={clsx(\n (onClick || onPointerDown) && \"cursor-pointer\",\n className,\n )}\n role={onClick ? \"button\" : undefined}\n tabIndex={onClick ? 0 : undefined}\n aria-label={onClick ? `${owner} ${type}` : undefined}\n >\n <text\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n fontSize={size * 0.7}\n fill={textColor}\n style={{ filter: shadowFilter }}\n >\n {symbol}\n </text>\n </g>\n );\n}\n\n// ============================================================================\n// Utilities\n// ============================================================================\n\n/**\n * Convert row/col to algebraic notation (a1, b2, etc.)\n */\nexport function toAlgebraic(\n row: number,\n col: number,\n totalRows: number,\n): string {\n const file = String.fromCharCode(97 + col); // a, b, c, ...\n const rank = totalRows - row; // 8, 7, 6, ... (bottom to top)\n return `${file}${rank}`;\n}\n\n/**\n * Convert row/col to numeric notation (1,1, 2,3, etc.)\n */\nexport function toNumeric(row: number, col: number): string {\n return `${row + 1},${col + 1}`;\n}\n\nfunction getCellId(cell: { id: string }): string {\n return cell.id;\n}\n\nfunction edgePositionForCells(\n firstCell: { row: number; col: number },\n secondCell: { row: number; col: number },\n cellSize: number,\n labelMargin: number,\n): SquareEdgePosition | null {\n if (\n Math.abs(firstCell.row - secondCell.row) +\n Math.abs(firstCell.col - secondCell.col) !==\n 1\n ) {\n return null;\n }\n\n const minRow = Math.min(firstCell.row, secondCell.row);\n const minCol = Math.min(firstCell.col, secondCell.col);\n\n if (firstCell.row === secondCell.row) {\n const x = labelMargin + (minCol + 1) * cellSize;\n const y1 = minRow * cellSize;\n const y2 = y1 + cellSize;\n return {\n x1: x,\n y1,\n x2: x,\n y2,\n midX: x,\n midY: (y1 + y2) / 2,\n angle: 90,\n };\n }\n\n const y = (minRow + 1) * cellSize;\n const x1 = labelMargin + minCol * cellSize;\n const x2 = x1 + cellSize;\n return {\n x1,\n y1: y,\n x2,\n y2: y,\n midX: (x1 + x2) / 2,\n midY: y,\n angle: 0,\n };\n}\n\nfunction cornerKeysForCell(cell: {\n row: number;\n col: number;\n}): Record<string, SquareVertexPosition> {\n return {\n [`${cell.col},${cell.row}`]: { x: cell.col, y: cell.row },\n [`${cell.col + 1},${cell.row}`]: { x: cell.col + 1, y: cell.row },\n [`${cell.col + 1},${cell.row + 1}`]: {\n x: cell.col + 1,\n y: cell.row + 1,\n },\n [`${cell.col},${cell.row + 1}`]: { x: cell.col, y: cell.row + 1 },\n };\n}\n\nfunction vertexPositionForCells(\n cells: readonly SquareCellWithId[],\n cellSize: number,\n labelMargin: number,\n): SquareVertexPosition | null {\n if (cells.length === 0) {\n return null;\n }\n\n const candidateKeys = cells.map(\n (cell) => new Set(Object.keys(cornerKeysForCell(cell))),\n );\n const firstKeySet = candidateKeys[0];\n if (firstKeySet === undefined) {\n return null;\n }\n const sharedKeys = [...firstKeySet].filter((key) =>\n candidateKeys.every((keySet) => keySet.has(key)),\n );\n if (sharedKeys.length !== 1) {\n return null;\n }\n\n const sharedKey = sharedKeys[0];\n if (!sharedKey) {\n return null;\n }\n const [colToken, rowToken] = sharedKey.split(\",\");\n if (colToken === undefined || rowToken === undefined) {\n return null;\n }\n const col = Number(colToken);\n const row = Number(rowToken);\n if (!Number.isFinite(col) || !Number.isFinite(row)) {\n return null;\n }\n\n return {\n x: labelMargin + col * cellSize,\n y: row * cellSize,\n };\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport interface SquareGridComponent {\n <const TBoard extends AnySquareBoardInput>(\n props: SquareGridBoardProps<TBoard>,\n ): ReactNode;\n <const TProps extends SquareGeneratedGridInputProps>(\n props: SquareGridProps<TProps>,\n ): ReactNode;\n <const TProps extends SquareAuthoredGridInputProps>(\n props: SquareGridProps<TProps>,\n ): ReactNode;\n}\n\nfunction SquareGridImpl(\n props:\n | SquareGridBoardProps<AnySquareBoardInput>\n | SquareGridProps<SquareGridInputProps>,\n) {\n const {\n cellSize = 60,\n renderCell,\n renderPiece,\n renderEdge,\n renderVertex,\n showCoordinates = true,\n coordinateStyle = \"algebraic\",\n width,\n height,\n enablePanZoom = false,\n initialZoom = 1,\n minZoom = 0.5,\n maxZoom = 3,\n className,\n interactiveSpaces,\n interactiveEdges,\n interactiveVertices,\n renderInteractiveSpace,\n renderInteractiveEdge,\n renderInteractiveVertex,\n } = props;\n const board =\n \"board\" in props\n ? props.board\n : ((\"spaces\" in props\n ? {\n id: \"__square-grid__\",\n spaces: props.spaces,\n pieces: props.pieces ?? [],\n edges: props.edges ?? [],\n vertices: props.vertices ?? [],\n }\n : {\n id: \"__square-grid__\",\n rows: props.rows ?? 0,\n cols: props.cols ?? 0,\n cells: props.cells,\n pieces: props.pieces ?? [],\n edges: props.edges ?? [],\n vertices: props.vertices ?? [],\n }) satisfies AnySquareBoardInput);\n const [hoveredInteractiveSpaceId, setHoveredInteractiveSpaceId] = useState<\n string | null\n >(null);\n const [hoveredInteractiveEdgeId, setHoveredInteractiveEdgeId] = useState<\n string | null\n >(null);\n const [hoveredInteractiveVertexId, setHoveredInteractiveVertexId] = useState<\n string | null\n >(null);\n\n // Use the unified pan/zoom hook\n const {\n transform,\n bind,\n isDragging: isPanning,\n } = usePanZoom({\n enabled: enablePanZoom,\n initialZoom,\n minZoom,\n maxZoom,\n mode: \"viewbox\",\n });\n\n // Coordinate label margin\n const labelMargin = showCoordinates && coordinateStyle !== \"none\" ? 24 : 0;\n\n const normalizedBoard = useMemo<NormalizedSquareBoard<AnySquareBoardInput>>(\n () => normalizeSquareBoardInput(board),\n [board],\n );\n\n const rows = normalizedBoard.rows;\n const cols = normalizedBoard.cols;\n const resolvedEdges = normalizedBoard.edges as Array<\n NormalizedSquareEdgeOf<AnySquareBoardInput>\n >;\n const resolvedVertices = normalizedBoard.vertices as Array<\n NormalizedSquareVertexOf<AnySquareBoardInput>\n >;\n const resolvedPieces = normalizedBoard.pieces as Array<\n NormalizedSquarePieceOf<AnySquareBoardInput>\n >;\n\n // Calculate grid dimensions\n const gridWidth = cols * cellSize;\n const gridHeight = rows * cellSize;\n const totalWidth = gridWidth + labelMargin;\n const totalHeight = gridHeight + labelMargin;\n\n const renderableCells = useMemo(() => {\n const result: Array<{ row: number; col: number }> = [];\n for (let row = 0; row < rows; row++) {\n for (let col = 0; col < cols; col++) {\n result.push({ row, col });\n }\n }\n return result;\n }, [rows, cols]);\n\n const resolvedCells = useMemo<SquareCellWithId[]>(() => {\n if (normalizedBoard.cells.length > 0) {\n return normalizedBoard.cells.map((cell) => ({\n ...cell,\n id: getCellId(cell),\n }));\n }\n\n return renderableCells.map(({ row, col }) => ({\n id: `${row},${col}`,\n row,\n col,\n }));\n }, [normalizedBoard.cells, renderableCells]);\n\n const cellsById = useMemo(\n () => new Map(resolvedCells.map((cell) => [cell.id, cell] as const)),\n [resolvedCells],\n );\n\n const resolvedEdgePositions = useMemo(\n () =>\n resolvedEdges.flatMap((edge) => {\n if (edge.spaceIds.length < 2) {\n return [];\n }\n const firstCell = cellsById.get(edge.spaceIds[0] ?? \"\");\n const secondCell = cellsById.get(edge.spaceIds[1] ?? \"\");\n if (!firstCell || !secondCell) {\n return [];\n }\n const position = edgePositionForCells(\n firstCell,\n secondCell,\n cellSize,\n labelMargin,\n );\n return position\n ? [\n {\n edge,\n interactiveEdge: {\n ...edge,\n position,\n } as InteractiveSquareEdge<AnySquareBoardInput>,\n },\n ]\n : [];\n }),\n [cellSize, cellsById, resolvedEdges, labelMargin],\n );\n\n const resolvedVertexPositions = useMemo(\n () =>\n resolvedVertices.flatMap((vertex) => {\n const vertexCells = vertex.spaceIds.flatMap((spaceId) => {\n const cell = cellsById.get(spaceId);\n return cell ? [cell] : [];\n });\n const position = vertexPositionForCells(\n vertexCells,\n cellSize,\n labelMargin,\n );\n return position\n ? [\n {\n vertex,\n interactiveVertex: {\n ...vertex,\n position,\n } as InteractiveSquareVertex<AnySquareBoardInput>,\n },\n ]\n : [];\n }),\n [cellSize, cellsById, labelMargin, resolvedVertices],\n );\n\n // Calculate viewBox for pan/zoom\n const viewBoxWidth = totalWidth / transform.zoom;\n const viewBoxHeight = totalHeight / transform.zoom;\n const viewBoxX = (totalWidth - viewBoxWidth) / 2 - transform.pan.x;\n const viewBoxY = (totalHeight - viewBoxHeight) / 2 - transform.pan.y;\n\n // Determine SVG dimensions\n const svgWidth = width ?? totalWidth;\n const svgHeight = height ?? totalHeight;\n\n return (\n <svg\n width={svgWidth}\n height={svgHeight}\n viewBox={\n enablePanZoom\n ? `${viewBoxX} ${viewBoxY} ${viewBoxWidth} ${viewBoxHeight}`\n : `0 0 ${totalWidth} ${totalHeight}`\n }\n className={clsx(\n \"square-grid\",\n enablePanZoom && \"touch-none\",\n isPanning && \"cursor-grabbing\",\n enablePanZoom && !isPanning && \"cursor-grab\",\n className,\n )}\n {...bind()}\n role=\"img\"\n aria-label={`${rows}x${cols} game grid`}\n >\n <defs>\n {/* Drop shadow for pieces */}\n <filter id=\"pieceShadow\" x=\"-20%\" y=\"-20%\" width=\"140%\" height=\"140%\">\n <feDropShadow dx=\"1\" dy=\"2\" stdDeviation=\"2\" floodOpacity=\"0.4\" />\n </filter>\n </defs>\n\n {/* Cells layer */}\n <g className=\"cells\" role=\"list\" aria-label=\"Grid cells\">\n {renderableCells.map(({ row, col }) => {\n const x = labelMargin + col * cellSize;\n const y = row * cellSize;\n\n return (\n <g\n key={`${row}-${col}`}\n transform={`translate(${x}, ${y})`}\n role=\"listitem\"\n aria-label={\n coordinateStyle === \"algebraic\"\n ? toAlgebraic(row, col, rows)\n : toNumeric(row, col)\n }\n >\n {renderCell(row, col)}\n </g>\n );\n })}\n </g>\n\n {interactiveSpaces && (\n <g className=\"interactive-spaces\" aria-label=\"Interactive spaces\">\n {resolvedCells.map((space) => {\n const state = interactiveTargetRenderState(\n interactiveSpaces,\n space.id,\n hoveredInteractiveSpaceId === space.id,\n );\n const isSelectable = isInteractiveTargetSelectable(\n interactiveSpaces,\n state,\n );\n const x = labelMargin + space.col * cellSize;\n const y = space.row * cellSize;\n return (\n <g\n key={space.id}\n transform={`translate(${x}, ${y})`}\n onClick={\n isSelectable\n ? () => {\n void interactiveSpaces.selectTargetId?.(space.id);\n }\n : undefined\n }\n onKeyDown={(event) =>\n handleKeyboardActivation(\n event,\n isSelectable\n ? () => {\n void interactiveSpaces.selectTargetId?.(space.id);\n }\n : undefined,\n )\n }\n onPointerEnter={() => setHoveredInteractiveSpaceId(space.id)}\n onPointerLeave={() =>\n setHoveredInteractiveSpaceId((currentId) =>\n currentId === space.id ? null : currentId,\n )\n }\n className={clsx(isSelectable && \"cursor-pointer\")}\n role={isSelectable ? \"button\" : undefined}\n tabIndex={isSelectable ? 0 : undefined}\n aria-label={\n isSelectable ? `Select space ${space.id}` : undefined\n }\n >\n {isSelectable && (\n <rect\n x={0}\n y={0}\n width={cellSize}\n height={cellSize}\n fill=\"rgba(255,255,255,0.001)\"\n pointerEvents=\"all\"\n />\n )}\n {renderInteractiveSpace\n ? renderInteractiveSpace(space, state)\n : null}\n </g>\n );\n })}\n </g>\n )}\n\n {renderEdge && resolvedEdgePositions.length > 0 && (\n <g className=\"edges\" aria-label=\"Board edges\">\n {resolvedEdgePositions.map(({ edge, interactiveEdge }) => (\n <g key={edge.id}>{renderEdge(edge, interactiveEdge.position)}</g>\n ))}\n </g>\n )}\n\n {interactiveEdges && (\n <g className=\"interactive-edges\" aria-label=\"Interactive edges\">\n {resolvedEdgePositions.map(({ interactiveEdge: edge }) => {\n const state = interactiveTargetRenderState(\n interactiveEdges,\n edge.id,\n hoveredInteractiveEdgeId === edge.id,\n );\n const isSelectable = isInteractiveTargetSelectable(\n interactiveEdges,\n state,\n );\n return (\n <g\n key={edge.id}\n onClick={\n isSelectable\n ? () => {\n void interactiveEdges.selectTargetId?.(edge.id);\n }\n : undefined\n }\n onKeyDown={(event) =>\n handleKeyboardActivation(\n event,\n isSelectable\n ? () => {\n void interactiveEdges.selectTargetId?.(edge.id);\n }\n : undefined,\n )\n }\n onPointerEnter={() => setHoveredInteractiveEdgeId(edge.id)}\n onPointerLeave={() =>\n setHoveredInteractiveEdgeId((currentId) =>\n currentId === edge.id ? null : currentId,\n )\n }\n className={clsx(isSelectable && \"cursor-pointer\")}\n role={isSelectable ? \"button\" : undefined}\n tabIndex={isSelectable ? 0 : undefined}\n aria-label={isSelectable ? `Select edge ${edge.id}` : undefined}\n >\n {renderInteractiveEdge ? (\n renderInteractiveEdge(edge, edge.position, state)\n ) : state.isEnabled && state.isEligible ? (\n <line\n x1={edge.position.x1}\n y1={edge.position.y1}\n x2={edge.position.x2}\n y2={edge.position.y2}\n stroke=\"rgba(255,255,255,0.001)\"\n strokeWidth={Math.max(12, cellSize * 0.18)}\n pointerEvents=\"stroke\"\n />\n ) : null}\n </g>\n );\n })}\n </g>\n )}\n\n {renderVertex && resolvedVertexPositions.length > 0 && (\n <g className=\"vertices\" aria-label=\"Board vertices\">\n {resolvedVertexPositions.map(({ vertex, interactiveVertex }) => (\n <g key={vertex.id}>\n {renderVertex(vertex, interactiveVertex.position)}\n </g>\n ))}\n </g>\n )}\n\n {interactiveVertices && (\n <g className=\"interactive-vertices\" aria-label=\"Interactive vertices\">\n {resolvedVertexPositions.map(({ interactiveVertex: vertex }) => {\n const state = interactiveTargetRenderState(\n interactiveVertices,\n vertex.id,\n hoveredInteractiveVertexId === vertex.id,\n );\n const isSelectable = isInteractiveTargetSelectable(\n interactiveVertices,\n state,\n );\n return (\n <g\n key={vertex.id}\n onClick={\n isSelectable\n ? () => {\n void interactiveVertices.selectTargetId?.(vertex.id);\n }\n : undefined\n }\n onKeyDown={(event) =>\n handleKeyboardActivation(\n event,\n isSelectable\n ? () => {\n void interactiveVertices.selectTargetId?.(vertex.id);\n }\n : undefined,\n )\n }\n onPointerEnter={() => setHoveredInteractiveVertexId(vertex.id)}\n onPointerLeave={() =>\n setHoveredInteractiveVertexId((currentId) =>\n currentId === vertex.id ? null : currentId,\n )\n }\n className={clsx(isSelectable && \"cursor-pointer\")}\n role={isSelectable ? \"button\" : undefined}\n tabIndex={isSelectable ? 0 : undefined}\n aria-label={\n isSelectable ? `Select vertex ${vertex.id}` : undefined\n }\n >\n {renderInteractiveVertex ? (\n renderInteractiveVertex(vertex, vertex.position, state)\n ) : state.isEnabled && state.isEligible ? (\n <circle\n cx={vertex.position.x}\n cy={vertex.position.y}\n r={Math.max(8, cellSize * 0.12)}\n fill=\"rgba(255,255,255,0.001)\"\n pointerEvents=\"all\"\n />\n ) : null}\n </g>\n );\n })}\n </g>\n )}\n\n {/* Coordinate labels */}\n {showCoordinates && coordinateStyle !== \"none\" && (\n <g className=\"coordinates\" aria-hidden=\"true\">\n {/* File labels (a-h) - bottom */}\n {Array.from({ length: cols }).map((_, col) => {\n const label =\n coordinateStyle === \"algebraic\"\n ? String.fromCharCode(97 + col)\n : String(col + 1);\n return (\n <text\n key={`file-${col}`}\n x={labelMargin + col * cellSize + cellSize / 2}\n y={gridHeight + 16}\n textAnchor=\"middle\"\n fill=\"#64748b\"\n fontSize={12}\n fontWeight=\"500\"\n >\n {label}\n </text>\n );\n })}\n {/* Rank labels (1-8) - left */}\n {Array.from({ length: rows }).map((_, row) => {\n const label =\n coordinateStyle === \"algebraic\"\n ? String(rows - row)\n : String(row + 1);\n return (\n <text\n key={`rank-${row}`}\n x={10}\n y={row * cellSize + cellSize / 2 + 4}\n textAnchor=\"middle\"\n fill=\"#64748b\"\n fontSize={12}\n fontWeight=\"500\"\n >\n {label}\n </text>\n );\n })}\n </g>\n )}\n\n {/* Pieces layer */}\n <g className=\"pieces\" role=\"list\" aria-label=\"Game pieces\">\n {resolvedPieces.map((piece) => {\n const x = labelMargin + piece.col * cellSize + cellSize / 2;\n const y = piece.row * cellSize + cellSize / 2;\n\n return (\n <g\n key={piece.id}\n transform={`translate(${x}, ${y})`}\n role=\"listitem\"\n aria-label={`${piece.owner ?? \"\"} ${piece.typeId}`}\n >\n {renderPiece(piece)}\n </g>\n );\n })}\n </g>\n\n {/* Zoom indicator */}\n {enablePanZoom && transform.zoom !== 1 && (\n <g\n transform={`translate(${viewBoxX + 10}, ${viewBoxY + viewBoxHeight - 30})`}\n >\n <rect\n x={0}\n y={0}\n width={60}\n height={20}\n rx={4}\n fill=\"rgba(0,0,0,0.6)\"\n />\n <text x={30} y={14} textAnchor=\"middle\" fill=\"white\" fontSize={12}>\n {Math.round(transform.zoom * 100)}%\n </text>\n </g>\n )}\n </svg>\n );\n}\n\nexport const SquareGrid = SquareGridImpl as SquareGridComponent;\n","export type BoardTargetKind = \"edge\" | \"vertex\" | \"space\" | \"tile\";\n\nexport interface InteractiveTargetState {\n kind?: BoardTargetKind;\n id: string;\n eligible: boolean;\n selectable: boolean;\n hovered: boolean;\n pending: boolean;\n conflict: boolean;\n unavailableReason?: string;\n browserAttributes?: Record<string, string | boolean>;\n select?: () => unknown | Promise<unknown>;\n}\n\nexport interface InteractiveTargetLayer {\n enabled?: boolean;\n eligible?: ReadonlySet<string>;\n selectTargetId?: (targetId: string) => unknown | Promise<unknown>;\n targetState?: (targetId: string) => Partial<InteractiveTargetState>;\n}\n\nexport interface InteractiveTargetRenderState extends InteractiveTargetState {\n isEnabled: boolean;\n isEligible: boolean;\n isHovered: boolean;\n}\n\nexport function interactiveTargetRenderState(\n layer: InteractiveTargetLayer,\n targetId: string,\n isHovered: boolean,\n): InteractiveTargetRenderState {\n const enabled = layer.enabled !== false;\n const eligible = layer.eligible?.has(targetId) ?? true;\n const extra = layer.targetState?.(targetId) ?? {};\n const selectable =\n extra.selectable ?? (enabled && eligible && !!layer.selectTargetId);\n return {\n id: targetId,\n ...extra,\n eligible: extra.eligible ?? eligible,\n selectable,\n hovered: isHovered,\n pending: extra.pending ?? false,\n conflict: extra.conflict ?? false,\n select:\n extra.select ??\n (layer.selectTargetId\n ? () => layer.selectTargetId?.(targetId)\n : undefined),\n isEnabled: enabled,\n isEligible: extra.eligible ?? eligible,\n isHovered,\n };\n}\n\nexport function isInteractiveTargetSelectable(\n layer: InteractiveTargetLayer,\n state: InteractiveTargetRenderState,\n): boolean {\n return (\n state.isEnabled &&\n state.selectable &&\n !!(state.select ?? layer.selectTargetId)\n );\n}\n","/**\n * SVG-based hex grid for hex-based games (Catan, wargames, Hive, Twilight Imperium).\n * Supports tiles, edges (roads), vertices (settlements), and interactive placement overlays.\n * Pan/zoom enabled on mobile via @use-gesture.\n */\n\nimport { useMemo, useState, type ReactNode } from \"react\";\nimport { clsx } from \"clsx\";\nimport { usePanZoom, calculateViewBox } from \"../../hooks/usePanZoom.js\";\nimport { useIsMobile } from \"../../hooks/useIsMobile.js\";\nimport { handleKeyboardActivation } from \"./interaction-accessibility.js\";\nimport {\n interactiveTargetRenderState,\n isInteractiveTargetSelectable,\n type InteractiveTargetLayer,\n type InteractiveTargetRenderState,\n} from \"./target-layer.js\";\nimport {\n type AuthoredHexBoardInput,\n type AnyHexBoardInput,\n type BoardSpaceIdOf,\n type GeneratedHexBoardInput,\n type NormalizedHexBoard,\n type NormalizedHexEdgeOf,\n type NormalizedHexTileOf,\n type NormalizedHexVertexOf,\n normalizeHexBoardInput,\n} from \"../../types/tiled-board.js\";\n\nexport type {\n InteractiveTargetLayer,\n InteractiveTargetRenderState,\n} from \"./target-layer.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type HexOrientation = \"pointy-top\" | \"flat-top\";\n\n/**\n * Geometry context passed to `renderTile`.\n *\n * `corners`, `points`, and `bounds` are expressed in tile-local\n * coordinates because each tile is rendered inside a `<g>` translated\n * to its center. Use `position` if you need the resolved center in the\n * board's absolute SVG coordinates.\n *\n * The `inset` option shrinks the polygon toward the center by that many\n * pixels, which is useful for layered effects such as borders, frames,\n * or inner highlights without re-deriving the hex math yourself.\n */\nexport interface HexTileGeometry {\n size: number;\n orientation: HexOrientation;\n center: { x: 0; y: 0 };\n position: { x: number; y: number };\n corners: (options?: { inset?: number }) => Array<{ x: number; y: number }>;\n points: (options?: { inset?: number }) => string;\n bounds: {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n width: number;\n height: number;\n };\n}\n\nexport interface EdgePosition {\n /** Absolute SVG start point of the visible edge line. */\n x1: number;\n y1: number;\n /** Absolute SVG end point of the visible edge line. */\n x2: number;\n y2: number;\n /** Absolute SVG midpoint of the edge. */\n midX: number;\n midY: number;\n /**\n * Angle in degrees from hex1 center to hex2 center.\n * This is perpendicular to the visible edge line.\n */\n centerAngle: number;\n /** Angle in degrees of the visible edge line itself. */\n edgeAngle: number;\n}\n\nexport interface InteractiveHexVertex<\n TBoard extends AnyHexBoardInput = AnyHexBoardInput,\n> extends NormalizedHexVertexOf<TBoard> {\n position: { x: number; y: number };\n spaceIds: ReadonlyArray<BoardSpaceIdOf<TBoard>>;\n}\n\nexport interface InteractiveHexEdge<\n TBoard extends AnyHexBoardInput = AnyHexBoardInput,\n> extends NormalizedHexEdgeOf<TBoard> {\n position: EdgePosition;\n spaceIds: ReadonlyArray<BoardSpaceIdOf<TBoard>>;\n}\n\nexport type InteractiveHexSpace<\n TBoard extends AnyHexBoardInput = AnyHexBoardInput,\n> = NormalizedHexTileOf<TBoard>;\n\ninterface HexGeneratedGridInputProps {\n id?: string;\n layout?: \"hex\";\n orientation?: HexOrientation;\n spaces: Extract<AnyHexBoardInput, { spaces: unknown }>[\"spaces\"];\n edges?: AnyHexBoardInput[\"edges\"];\n vertices?: AnyHexBoardInput[\"vertices\"];\n}\n\ninterface HexAuthoredGridInputProps {\n id?: string;\n layout?: \"hex\";\n orientation?: HexOrientation;\n tiles: Extract<AnyHexBoardInput, { tiles: unknown }>[\"tiles\"];\n edges?: AnyHexBoardInput[\"edges\"];\n vertices?: AnyHexBoardInput[\"vertices\"];\n}\n\ntype HexGridInputProps = HexGeneratedGridInputProps | HexAuthoredGridInputProps;\n\ntype ResolvedArrayProp<Value> =\n Exclude<Value, undefined> extends readonly unknown[]\n ? Exclude<Value, undefined>\n : readonly [];\n\ntype HexBoardLikeOfProps<TProps extends HexGridInputProps> = TProps extends {\n id?: infer Id;\n layout?: infer Layout;\n orientation?: infer Orientation;\n spaces: infer Spaces;\n edges?: infer Edges;\n vertices?: infer Vertices;\n}\n ? {\n id: Extract<Id, string> extends never ? string : Extract<Id, string>;\n layout?: Extract<Layout, \"hex\">;\n orientation?: Extract<Orientation, HexOrientation>;\n spaces: Spaces;\n edges: ResolvedArrayProp<Edges>;\n vertices: ResolvedArrayProp<Vertices>;\n } & GeneratedHexBoardInput\n : TProps extends {\n id?: infer Id;\n layout?: infer Layout;\n orientation?: infer Orientation;\n tiles: infer Tiles;\n edges?: infer Edges;\n vertices?: infer Vertices;\n }\n ? {\n id: Extract<Id, string> extends never ? string : Extract<Id, string>;\n layout?: Extract<Layout, \"hex\">;\n orientation?: Extract<Orientation, HexOrientation>;\n tiles: Tiles;\n edges: ResolvedArrayProp<Edges>;\n vertices: ResolvedArrayProp<Vertices>;\n } & AuthoredHexBoardInput\n : never;\n\nexport type HexGridProps<TProps extends HexGridInputProps = HexGridInputProps> =\n TProps & {\n orientation?: HexOrientation;\n /** Hex radius in pixels */\n hexSize?: number;\n /**\n * Receives tile data centered at (0,0) plus a `HexTileGeometry`\n * helper. Use `geometry.points({ inset })` to draw custom polygons\n * without duplicating `hexSize` / orientation in the consumer.\n */\n renderTile: (\n tile: NormalizedHexTileOf<NoInfer<HexBoardLikeOfProps<TProps>>>,\n geometry: HexTileGeometry,\n ) => ReactNode;\n /**\n * Receives edge geometry in absolute SVG coordinates.\n * Use `position.edgeAngle` to align artwork with the visible edge.\n */\n renderEdge: (\n edge: NormalizedHexEdgeOf<NoInfer<HexBoardLikeOfProps<TProps>>>,\n position: EdgePosition,\n ) => ReactNode;\n renderVertex: (\n vertex: NormalizedHexVertexOf<NoInfer<HexBoardLikeOfProps<TProps>>>,\n position: { x: number; y: number },\n ) => ReactNode;\n width?: number | string;\n height?: number | string;\n enablePanZoom?: boolean;\n initialZoom?: number;\n minZoom?: number;\n maxZoom?: number;\n className?: string;\n\n // Interactive board target layers.\n\n /** Reducer-aware space target layer from `board.targetLayers.space(...)`. */\n interactiveSpaces?: InteractiveTargetLayer;\n /** Reducer-aware vertex target layer from `board.targetLayers.vertex(...)`. */\n interactiveVertices?: InteractiveTargetLayer;\n /** Reducer-aware edge target layer from `board.targetLayers.edge(...)`. */\n interactiveEdges?: InteractiveTargetLayer;\n /** Receives space geometry centered at (0,0). */\n renderInteractiveSpace?: (\n space: InteractiveHexSpace<NoInfer<HexBoardLikeOfProps<TProps>>>,\n state: InteractiveTargetRenderState,\n ) => ReactNode;\n /**\n * Receives vertex geometry in absolute SVG coordinates.\n */\n renderInteractiveVertex?: (\n vertex: InteractiveHexVertex<NoInfer<HexBoardLikeOfProps<TProps>>>,\n position: { x: number; y: number },\n state: InteractiveTargetRenderState,\n ) => ReactNode;\n /**\n * Receives edge geometry in the same absolute SVG coordinates as `renderEdge`.\n */\n renderInteractiveEdge?: (\n edge: InteractiveHexEdge<NoInfer<HexBoardLikeOfProps<TProps>>>,\n position: EdgePosition,\n state: InteractiveTargetRenderState,\n ) => ReactNode;\n interactiveVertexSize?: number;\n interactiveEdgeSize?: number;\n };\n\nexport interface HexGridBoardProps<\n TBoard extends AnyHexBoardInput = AnyHexBoardInput,\n> {\n board: TBoard;\n orientation?: HexOrientation;\n hexSize?: number;\n /**\n * Receives tile data centered at (0,0) plus a `HexTileGeometry`\n * helper. Use `geometry.points({ inset })` to draw custom polygons\n * without duplicating `hexSize` / orientation in the consumer.\n */\n renderTile: (\n tile: NormalizedHexTileOf<NoInfer<TBoard>>,\n geometry: HexTileGeometry,\n ) => ReactNode;\n /**\n * Receives edge geometry in absolute SVG coordinates.\n * Use `position.edgeAngle` to align artwork with the visible edge.\n */\n renderEdge: (\n edge: NormalizedHexEdgeOf<NoInfer<TBoard>>,\n position: EdgePosition,\n ) => ReactNode;\n renderVertex: (\n vertex: NormalizedHexVertexOf<NoInfer<TBoard>>,\n position: { x: number; y: number },\n ) => ReactNode;\n width?: number | string;\n height?: number | string;\n enablePanZoom?: boolean;\n initialZoom?: number;\n minZoom?: number;\n maxZoom?: number;\n className?: string;\n interactiveSpaces?: InteractiveTargetLayer;\n interactiveVertices?: InteractiveTargetLayer;\n interactiveEdges?: InteractiveTargetLayer;\n /** Receives space geometry centered at (0,0). */\n renderInteractiveSpace?: (\n space: InteractiveHexSpace<NoInfer<TBoard>>,\n state: InteractiveTargetRenderState,\n ) => ReactNode;\n /**\n * Receives vertex geometry in absolute SVG coordinates.\n */\n renderInteractiveVertex?: (\n vertex: InteractiveHexVertex<NoInfer<TBoard>>,\n position: { x: number; y: number },\n state: InteractiveTargetRenderState,\n ) => ReactNode;\n /**\n * Receives edge geometry in the same absolute SVG coordinates as `renderEdge`.\n */\n renderInteractiveEdge?: (\n edge: InteractiveHexEdge<NoInfer<TBoard>>,\n position: EdgePosition,\n state: InteractiveTargetRenderState,\n ) => ReactNode;\n interactiveVertexSize?: number;\n interactiveEdgeSize?: number;\n}\n\n// ============================================================================\n// Pre-built Helper Components\n// ============================================================================\n\nexport interface DefaultHexTileProps {\n /** Should match hexSize from HexGrid */\n size: number;\n fill: string;\n stroke?: string;\n strokeWidth?: number;\n isSelected?: boolean;\n isHighlighted?: boolean;\n label?: string;\n showCoordinates?: boolean;\n coordinates?: { q: number; r: number };\n orientation?: HexOrientation;\n onClick?: () => void;\n onPointerEnter?: () => void;\n onPointerLeave?: () => void;\n className?: string;\n}\n\n/** Pre-built hexagon tile for use in `renderTile`. */\nexport function DefaultHexTile({\n size,\n fill,\n stroke = \"#1e293b\",\n strokeWidth = 1.5,\n isSelected = false,\n isHighlighted = false,\n label,\n showCoordinates = false,\n coordinates,\n orientation = \"pointy-top\",\n onClick,\n onPointerEnter,\n onPointerLeave,\n className,\n}: DefaultHexTileProps) {\n const effectiveFill = isSelected\n ? \"rgba(59, 130, 246, 0.5)\"\n : isHighlighted\n ? \"rgba(34, 197, 94, 0.4)\"\n : fill;\n\n const effectiveStroke = isSelected\n ? \"#3b82f6\"\n : isHighlighted\n ? \"#22c55e\"\n : stroke;\n\n const effectiveStrokeWidth = isSelected || isHighlighted ? 3 : strokeWidth;\n\n const points = hexUtils.getHexPoints(0, 0, size * 0.95, orientation);\n\n return (\n <g\n onClick={onClick}\n onPointerEnter={onPointerEnter}\n onPointerLeave={onPointerLeave}\n onKeyDown={(event) => handleKeyboardActivation(event, onClick)}\n className={clsx(\n \"transition-all duration-150\",\n onClick && \"cursor-pointer hover:brightness-110\",\n className,\n )}\n role={onClick ? \"button\" : undefined}\n tabIndex={onClick ? 0 : undefined}\n aria-label={onClick ? (label ?? \"Hex tile\") : undefined}\n >\n <polygon\n points={points}\n fill={effectiveFill}\n stroke={effectiveStroke}\n strokeWidth={effectiveStrokeWidth}\n filter=\"url(#hexShadow)\"\n />\n\n {label && (\n <text\n x={0}\n y={showCoordinates ? -8 : 0}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n fill=\"white\"\n fontSize={size * 0.28}\n fontWeight=\"bold\"\n style={{ textShadow: \"1px 1px 2px rgba(0,0,0,0.8)\" }}\n pointerEvents=\"none\"\n >\n {label}\n </text>\n )}\n\n {showCoordinates && coordinates && (\n <text\n x={0}\n y={label ? 10 : 0}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n fill=\"rgba(255,255,255,0.7)\"\n fontSize={size * 0.2}\n pointerEvents=\"none\"\n >\n {coordinates.q},{coordinates.r}\n </text>\n )}\n </g>\n );\n}\n\nexport interface DefaultHexEdgeProps {\n position: EdgePosition;\n color: string;\n hasOwner?: boolean;\n strokeWidth?: number;\n touchTargetSize?: number;\n onClick?: () => void;\n className?: string;\n}\n\n/** Pre-built edge/road component for use in `renderEdge`. */\nexport function DefaultHexEdge({\n position,\n color,\n hasOwner = true,\n strokeWidth = 6,\n touchTargetSize = 20,\n onClick,\n className,\n}: DefaultHexEdgeProps) {\n const touchTargetLength = Math.hypot(\n position.x2 - position.x1,\n position.y2 - position.y1,\n );\n\n return (\n <g\n onClick={onClick}\n onKeyDown={(event) => handleKeyboardActivation(event, onClick)}\n className={clsx(\n \"transition-all duration-150\",\n onClick && \"cursor-pointer\",\n className,\n )}\n role={onClick ? \"button\" : undefined}\n tabIndex={onClick ? 0 : undefined}\n aria-label={onClick ? \"Hex edge\" : undefined}\n >\n {/* Invisible touch target */}\n <rect\n x={position.midX - touchTargetLength / 2}\n y={position.midY - touchTargetSize / 2}\n width={touchTargetLength}\n height={touchTargetSize}\n rx={touchTargetSize / 2}\n fill=\"rgba(255,255,255,0.001)\"\n transform={`rotate(${position.edgeAngle} ${position.midX} ${position.midY})`}\n pointerEvents=\"all\"\n />\n {/* Visible edge */}\n <line\n x1={position.x1}\n y1={position.y1}\n x2={position.x2}\n y2={position.y2}\n stroke={color}\n strokeWidth={hasOwner ? strokeWidth : strokeWidth / 2}\n strokeLinecap=\"round\"\n className={hasOwner ? \"\" : \"opacity-30\"}\n />\n </g>\n );\n}\n\nexport interface DefaultHexVertexProps {\n position: { x: number; y: number };\n color: string;\n stroke?: string;\n strokeWidth?: number;\n hasOwner?: boolean;\n isSelected?: boolean;\n isHighlighted?: boolean;\n size?: number;\n touchTargetSize?: number;\n shape?: \"circle\" | \"square\";\n onClick?: () => void;\n onPointerEnter?: () => void;\n onPointerLeave?: () => void;\n className?: string;\n}\n\n/** Pre-built vertex/settlement component for use in `renderVertex`. */\nexport function DefaultHexVertex({\n position,\n color,\n stroke = \"#1e293b\",\n strokeWidth = 1.5,\n hasOwner = true,\n isSelected = false,\n isHighlighted = false,\n size = 10,\n touchTargetSize = 22,\n shape = \"circle\",\n onClick,\n onPointerEnter,\n onPointerLeave,\n className,\n}: DefaultHexVertexProps) {\n const effectiveColor = isSelected\n ? \"rgba(59, 130, 246, 0.8)\"\n : isHighlighted\n ? \"rgba(34, 197, 94, 0.8)\"\n : color;\n\n const effectiveStroke = isSelected\n ? \"#3b82f6\"\n : isHighlighted\n ? \"#22c55e\"\n : stroke;\n\n const effectiveStrokeWidth = isSelected || isHighlighted ? 3 : strokeWidth;\n\n return (\n <g\n onClick={onClick}\n onPointerEnter={onPointerEnter}\n onPointerLeave={onPointerLeave}\n onKeyDown={(event) => handleKeyboardActivation(event, onClick)}\n className={clsx(\n \"transition-all duration-150\",\n onClick && \"cursor-pointer hover:scale-110\",\n className,\n )}\n style={{ transformOrigin: `${position.x}px ${position.y}px` }}\n role={onClick ? \"button\" : undefined}\n tabIndex={onClick ? 0 : undefined}\n aria-label={onClick ? \"Hex vertex\" : undefined}\n >\n {/* Invisible touch target */}\n <circle\n cx={position.x}\n cy={position.y}\n r={touchTargetSize}\n fill=\"rgba(255,255,255,0.001)\"\n pointerEvents=\"all\"\n />\n {/* Visible vertex */}\n {shape === \"square\" ? (\n <rect\n x={position.x - size}\n y={position.y - size}\n width={size * 2}\n height={size * 2}\n fill={effectiveColor}\n stroke={effectiveStroke}\n strokeWidth={effectiveStrokeWidth}\n className={hasOwner ? \"\" : \"opacity-30\"}\n />\n ) : (\n <circle\n cx={position.x}\n cy={position.y}\n r={hasOwner ? size : size * 0.5}\n fill={effectiveColor}\n stroke={effectiveStroke}\n strokeWidth={effectiveStrokeWidth}\n className={hasOwner ? \"\" : \"opacity-30\"}\n />\n )}\n </g>\n );\n}\n\n// ============================================================================\n// Interactive Helper Components (for placement UI)\n// ============================================================================\n\nexport interface DefaultInteractiveVertexProps {\n position: { x: number; y: number };\n isHovered: boolean;\n size?: number;\n color?: string;\n hoverColor?: string;\n className?: string;\n}\nexport function DefaultInteractiveVertex({\n position,\n isHovered,\n size = 8,\n color = \"rgba(255, 255, 255, 0.2)\",\n hoverColor = \"rgba(34, 197, 94, 0.8)\",\n className,\n}: DefaultInteractiveVertexProps) {\n return (\n <circle\n cx={position.x}\n cy={position.y}\n r={isHovered ? size * 1.5 : size}\n fill={isHovered ? hoverColor : color}\n stroke={isHovered ? \"#22c55e\" : \"rgba(255,255,255,0.4)\"}\n strokeWidth={isHovered ? 2 : 1}\n className={clsx(\"transition-all duration-150\", className)}\n />\n );\n}\n\nexport interface DefaultInteractiveEdgeProps {\n position: EdgePosition;\n isHovered: boolean;\n strokeWidth?: number;\n color?: string;\n hoverColor?: string;\n className?: string;\n}\nexport function DefaultInteractiveEdge({\n position,\n isHovered,\n strokeWidth = 4,\n color = \"rgba(255, 255, 255, 0.15)\",\n hoverColor = \"rgba(251, 146, 60, 0.8)\",\n className,\n}: DefaultInteractiveEdgeProps) {\n return (\n <line\n x1={position.x1}\n y1={position.y1}\n x2={position.x2}\n y2={position.y2}\n stroke={isHovered ? hoverColor : color}\n strokeWidth={isHovered ? strokeWidth * 1.5 : strokeWidth}\n strokeLinecap=\"round\"\n className={clsx(\"transition-all duration-150\", className)}\n />\n );\n}\n\n// ============================================================================\n// Hex Math Utilities\n// ============================================================================\n\nexport const hexUtils = {\n /** Convert axial coordinates to pixel position. */\n axialToPixel(\n q: number,\n r: number,\n size: number,\n orientation: HexOrientation,\n ): { x: number; y: number } {\n if (orientation === \"pointy-top\") {\n const x = size * (Math.sqrt(3) * q + (Math.sqrt(3) / 2) * r);\n const y = size * ((3 / 2) * r);\n return { x, y };\n } else {\n const x = size * ((3 / 2) * q);\n const y = size * ((Math.sqrt(3) / 2) * q + Math.sqrt(3) * r);\n return { x, y };\n }\n },\n\n getNeighbors(q: number, r: number): Array<{ q: number; r: number }> {\n return [\n { q: q + 1, r: r },\n { q: q + 1, r: r - 1 },\n { q: q, r: r - 1 },\n { q: q - 1, r: r },\n { q: q - 1, r: r + 1 },\n { q: q, r: r + 1 },\n ];\n },\n\n getDistance(q1: number, r1: number, q2: number, r2: number): number {\n return (\n (Math.abs(q1 - q2) + Math.abs(q1 + r1 - q2 - r2) + Math.abs(r1 - r2)) / 2\n );\n },\n\n getHexCorners(\n centerX: number,\n centerY: number,\n size: number,\n orientation: HexOrientation,\n ): Array<{ x: number; y: number }> {\n const corners: Array<{ x: number; y: number }> = [];\n const startAngle = orientation === \"pointy-top\" ? 30 : 0;\n\n for (let i = 0; i < 6; i++) {\n const angleDeg = startAngle + 60 * i;\n const angleRad = (Math.PI / 180) * angleDeg;\n corners.push({\n x: centerX + size * Math.cos(angleRad),\n y: centerY + size * Math.sin(angleRad),\n });\n }\n return corners;\n },\n\n getHexPoints(\n centerX: number,\n centerY: number,\n size: number,\n orientation: HexOrientation,\n ): string {\n const corners = this.getHexCorners(centerX, centerY, size, orientation);\n return corners.map((c) => `${c.x},${c.y}`).join(\" \");\n },\n\n getEdgePosition(\n hex1Pos: { x: number; y: number },\n hex2Pos: { x: number; y: number },\n size: number,\n ): EdgePosition {\n const midX = (hex1Pos.x + hex2Pos.x) / 2;\n const midY = (hex1Pos.y + hex2Pos.y) / 2;\n const centerAngleRad = Math.atan2(\n hex2Pos.y - hex1Pos.y,\n hex2Pos.x - hex1Pos.x,\n );\n\n // Calculate edge endpoints perpendicular to the line between hex centers\n const edgeAngleRad = centerAngleRad + Math.PI / 2;\n const edgeLength = size * 0.8;\n const centerAngle = (centerAngleRad * 180) / Math.PI;\n const edgeAngle = (edgeAngleRad * 180) / Math.PI;\n\n return {\n x1: midX - (edgeLength / 2) * Math.cos(edgeAngleRad),\n y1: midY - (edgeLength / 2) * Math.sin(edgeAngleRad),\n x2: midX + (edgeLength / 2) * Math.cos(edgeAngleRad),\n y2: midY + (edgeLength / 2) * Math.sin(edgeAngleRad),\n midX,\n midY,\n centerAngle,\n edgeAngle,\n };\n },\n\n getVertexPosition(\n hex1Pos: { x: number; y: number },\n hex2Pos: { x: number; y: number },\n hex3Pos: { x: number; y: number },\n ): { x: number; y: number } {\n return {\n x: (hex1Pos.x + hex2Pos.x + hex3Pos.x) / 3,\n y: (hex1Pos.y + hex2Pos.y + hex3Pos.y) / 3,\n };\n },\n};\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport interface HexGridComponent {\n <const TBoard extends AnyHexBoardInput>(\n props: HexGridBoardProps<TBoard>,\n ): ReactNode;\n <const TProps extends HexGeneratedGridInputProps>(\n props: HexGridProps<TProps>,\n ): ReactNode;\n <const TProps extends HexAuthoredGridInputProps>(\n props: HexGridProps<TProps>,\n ): ReactNode;\n}\n\nfunction HexGridImpl(\n props: HexGridBoardProps<AnyHexBoardInput> | HexGridProps<HexGridInputProps>,\n) {\n const {\n orientation = \"pointy-top\",\n hexSize = 50,\n renderTile,\n renderEdge,\n renderVertex,\n width = 800,\n height = 600,\n enablePanZoom = true,\n initialZoom = 1,\n minZoom = 0.5,\n maxZoom = 3,\n className,\n interactiveSpaces,\n interactiveVertices,\n interactiveEdges,\n renderInteractiveSpace,\n renderInteractiveVertex,\n renderInteractiveEdge,\n interactiveVertexSize = 12,\n interactiveEdgeSize = 10,\n } = props;\n const board =\n \"board\" in props\n ? props.board\n : ((\"spaces\" in props\n ? {\n id: \"__hex-grid__\",\n orientation,\n spaces: props.spaces,\n edges: props.edges ?? [],\n vertices: props.vertices ?? [],\n }\n : {\n id: \"__hex-grid__\",\n orientation,\n tiles: props.tiles,\n edges: props.edges ?? [],\n vertices: props.vertices ?? [],\n }) satisfies AnyHexBoardInput);\n // Pan/zoom is only enabled on mobile devices when the prop is true\n const isMobile = useIsMobile();\n const effectivePanZoom = enablePanZoom && isMobile;\n const normalizedBoard = useMemo<NormalizedHexBoard<AnyHexBoardInput>>(\n () => normalizeHexBoardInput(board),\n [board],\n );\n const resolvedTiles = normalizedBoard.tiles;\n const resolvedEdges = normalizedBoard.edges;\n const resolvedVertices = normalizedBoard.vertices;\n const resolvedOrientation = normalizedBoard.orientation ?? orientation;\n\n // Hover state for interactive elements\n const [hoveredSpaceId, setHoveredSpaceId] = useState<string | null>(null);\n const [hoveredVertexId, setHoveredVertexId] = useState<string | null>(null);\n const [hoveredEdgeId, setHoveredEdgeId] = useState<string | null>(null);\n\n // Use the unified pan/zoom hook\n const { transform, bind, isDragging } = usePanZoom({\n enabled: effectivePanZoom,\n initialZoom,\n minZoom,\n maxZoom,\n mode: \"viewbox\",\n });\n\n // Pre-compute tile positions\n const tilePositions = useMemo(() => {\n const positions = new Map<string, { x: number; y: number }>();\n resolvedTiles.forEach((tile) => {\n positions.set(\n tile.id,\n hexUtils.axialToPixel(tile.q, tile.r, hexSize, resolvedOrientation),\n );\n });\n return positions;\n }, [resolvedTiles, hexSize, resolvedOrientation]);\n\n // Build a `HexTileGeometry` for a tile centered at `position`.\n //\n // The closures intentionally re-derive corners on demand so callers\n // can pass a per-call `inset` without the grid pre-computing every\n // possible inset. Hex math is cheap (six trig calls).\n const buildTileGeometry = useMemo(\n () =>\n (position: { x: number; y: number }): HexTileGeometry => {\n const corners = (options?: { inset?: number }) => {\n const inset = options?.inset ?? 0;\n const radius = Math.max(0, hexSize - inset);\n return hexUtils.getHexCorners(0, 0, radius, resolvedOrientation);\n };\n const points = (options?: { inset?: number }) =>\n corners(options)\n .map((corner) => `${corner.x},${corner.y}`)\n .join(\" \");\n const outer = corners();\n const xs = outer.map((corner) => corner.x);\n const ys = outer.map((corner) => corner.y);\n const minX = Math.min(...xs);\n const maxX = Math.max(...xs);\n const minY = Math.min(...ys);\n const maxY = Math.max(...ys);\n return {\n size: hexSize,\n orientation: resolvedOrientation,\n center: { x: 0, y: 0 },\n position,\n corners,\n points,\n bounds: {\n minX,\n minY,\n maxX,\n maxY,\n width: maxX - minX,\n height: maxY - minY,\n },\n };\n },\n [hexSize, resolvedOrientation],\n );\n\n const resolvedEdgePositions = useMemo(\n () =>\n resolvedEdges.flatMap((edge) => {\n const pos1 = tilePositions.get(edge.hex1);\n const pos2 = tilePositions.get(edge.hex2);\n if (!pos1 || !pos2) {\n return [];\n }\n return [\n {\n edge,\n interactiveEdge: {\n ...edge,\n spaceIds: [edge.hex1, edge.hex2] as const,\n position: hexUtils.getEdgePosition(pos1, pos2, hexSize),\n } as InteractiveHexEdge<AnyHexBoardInput>,\n },\n ];\n }),\n [hexSize, resolvedEdges, tilePositions],\n );\n\n const resolvedVertexPositions = useMemo(\n () =>\n resolvedVertices.flatMap((vertex) => {\n const [hex0, hex1, hex2] = vertex.hexes;\n if (!hex0 || !hex1 || !hex2) {\n return [];\n }\n\n const pos0 = tilePositions.get(hex0);\n const pos1 = tilePositions.get(hex1);\n const pos2 = tilePositions.get(hex2);\n if (!pos0 || !pos1 || !pos2) {\n return [];\n }\n\n return [\n {\n vertex,\n interactiveVertex: {\n ...vertex,\n spaceIds: vertex.hexes,\n position: hexUtils.getVertexPosition(pos0, pos1, pos2),\n } as InteractiveHexVertex<AnyHexBoardInput>,\n },\n ];\n }),\n [resolvedVertices, tilePositions],\n );\n\n // Calculate bounds for viewBox\n const bounds = useMemo(() => {\n if (resolvedTiles.length === 0) {\n return { minX: 0, minY: 0, width: 400, height: 300 };\n }\n\n let minX = Infinity,\n minY = Infinity,\n maxX = -Infinity,\n maxY = -Infinity;\n resolvedTiles.forEach((tile) => {\n const pos = tilePositions.get(tile.id);\n if (pos) {\n minX = Math.min(minX, pos.x - hexSize);\n minY = Math.min(minY, pos.y - hexSize);\n maxX = Math.max(maxX, pos.x + hexSize);\n maxY = Math.max(maxY, pos.y + hexSize);\n }\n });\n\n const padding = hexSize;\n return {\n minX: minX - padding,\n minY: minY - padding,\n width: maxX - minX + padding * 2,\n height: maxY - minY + padding * 2,\n };\n }, [resolvedTiles, tilePositions, hexSize]);\n\n // Calculate viewBox with pan and zoom\n const viewBox = calculateViewBox(bounds, transform);\n\n // Parse viewBox for zoom indicator positioning\n const viewBoxParts = viewBox.split(\" \").map(Number);\n const viewBoxX = viewBoxParts[0] ?? 0;\n const viewBoxY = viewBoxParts[1] ?? 0;\n const viewBoxHeight = viewBoxParts[3] ?? 0;\n\n return (\n <svg\n width={width}\n height={height}\n viewBox={viewBox}\n className={clsx(\n \"hex-grid\",\n effectivePanZoom && \"touch-none\",\n isDragging && \"cursor-grabbing\",\n effectivePanZoom && !isDragging && \"cursor-grab\",\n className,\n )}\n {...bind()}\n role=\"img\"\n aria-label=\"Hex grid game board\"\n >\n <defs>\n {/* Gradient for ocean tiles */}\n <linearGradient id=\"oceanGradient\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor=\"#0ea5e9\" />\n <stop offset=\"100%\" stopColor=\"#0284c7\" />\n </linearGradient>\n {/* Drop shadow filter */}\n <filter id=\"hexShadow\" x=\"-20%\" y=\"-20%\" width=\"140%\" height=\"140%\">\n <feDropShadow dx=\"1\" dy=\"1\" stdDeviation=\"2\" floodOpacity=\"0.3\" />\n </filter>\n </defs>\n\n {/* Tiles layer */}\n <g className=\"tiles\" role=\"list\" aria-label=\"Hex tiles\">\n {resolvedTiles.map((tile) => {\n const pos = tilePositions.get(tile.id);\n if (!pos) return null;\n\n const geometry = buildTileGeometry(pos);\n return (\n <g\n key={tile.id}\n transform={`translate(${pos.x}, ${pos.y})`}\n role=\"listitem\"\n aria-label={tile.label ?? `Tile ${tile.id}`}\n >\n {renderTile(tile, geometry)}\n </g>\n );\n })}\n </g>\n\n {/* Interactive spaces layer */}\n {interactiveSpaces && resolvedTiles.length > 0 && (\n <g\n className=\"interactive-spaces\"\n role=\"list\"\n aria-label=\"Interactive spaces\"\n >\n {resolvedTiles.map((space) => {\n const pos = tilePositions.get(space.id);\n if (!pos) return null;\n const state = interactiveTargetRenderState(\n interactiveSpaces,\n space.id,\n hoveredSpaceId === space.id,\n );\n const isSelectable = isInteractiveTargetSelectable(\n interactiveSpaces,\n state,\n );\n return (\n <g\n key={space.id}\n {...state.browserAttributes}\n transform={`translate(${pos.x}, ${pos.y})`}\n role={isSelectable ? \"button\" : undefined}\n className={clsx(isSelectable && \"cursor-pointer\")}\n onPointerEnter={() => setHoveredSpaceId(space.id)}\n onPointerLeave={() =>\n setHoveredSpaceId((currentId) =>\n currentId === space.id ? null : currentId,\n )\n }\n onClick={\n isSelectable\n ? () => {\n void state.select?.();\n }\n : undefined\n }\n onKeyDown={(event) =>\n handleKeyboardActivation(\n event,\n isSelectable\n ? () => {\n void state.select?.();\n }\n : undefined,\n )\n }\n tabIndex={isSelectable ? 0 : undefined}\n aria-label={\n isSelectable ? `Select space ${space.id}` : undefined\n }\n >\n {isSelectable && (\n <polygon\n points={buildTileGeometry(pos).points({\n inset: hexSize * 0.05,\n })}\n fill=\"rgba(255,255,255,0.001)\"\n pointerEvents=\"all\"\n />\n )}\n {renderInteractiveSpace\n ? renderInteractiveSpace(space, state)\n : null}\n </g>\n );\n })}\n </g>\n )}\n\n {/* Edges layer (for roads) */}\n {resolvedEdges.length > 0 && (\n <g className=\"edges\" role=\"list\" aria-label=\"Hex edges\">\n {resolvedEdgePositions.map(({ edge, interactiveEdge }) => {\n return (\n <g key={edge.id} role=\"listitem\">\n {renderEdge(edge, interactiveEdge.position)}\n </g>\n );\n })}\n </g>\n )}\n\n {/* Vertices layer (for settlements) */}\n {resolvedVertices.length > 0 && (\n <g className=\"vertices\" role=\"list\" aria-label=\"Hex vertices\">\n {resolvedVertexPositions.map(({ vertex, interactiveVertex }) => {\n return (\n <g key={vertex.id} role=\"listitem\">\n {renderVertex(vertex, interactiveVertex.position)}\n </g>\n );\n })}\n </g>\n )}\n\n {/* Interactive edges layer (for road placement) */}\n {interactiveEdges && resolvedEdgePositions.length > 0 && (\n <g\n className=\"interactive-edges\"\n role=\"list\"\n aria-label=\"Interactive edges for placement\"\n >\n {resolvedEdgePositions.map(({ interactiveEdge: edge }) => {\n const state = interactiveTargetRenderState(\n interactiveEdges,\n edge.id,\n hoveredEdgeId === edge.id,\n );\n const isSelectable = isInteractiveTargetSelectable(\n interactiveEdges,\n state,\n );\n const touchTargetLength = Math.hypot(\n edge.position.x2 - edge.position.x1,\n edge.position.y2 - edge.position.y1,\n );\n return (\n <g\n key={edge.id}\n {...state.browserAttributes}\n role={isSelectable ? \"button\" : undefined}\n className={clsx(isSelectable && \"cursor-pointer\")}\n onPointerEnter={() => setHoveredEdgeId(edge.id)}\n onPointerLeave={() =>\n setHoveredEdgeId((currentId) =>\n currentId === edge.id ? null : currentId,\n )\n }\n onClick={\n isSelectable\n ? () => {\n void state.select?.();\n }\n : undefined\n }\n onKeyDown={(event) =>\n handleKeyboardActivation(\n event,\n isSelectable\n ? () => {\n void state.select?.();\n }\n : undefined,\n )\n }\n tabIndex={isSelectable ? 0 : undefined}\n aria-label={isSelectable ? `Select edge ${edge.id}` : undefined}\n >\n {isSelectable && (\n <rect\n x={edge.position.midX - touchTargetLength / 2}\n y={edge.position.midY - interactiveEdgeSize}\n width={touchTargetLength}\n height={interactiveEdgeSize * 2}\n rx={interactiveEdgeSize}\n fill=\"rgba(255,255,255,0.001)\"\n transform={`rotate(${edge.position.edgeAngle} ${edge.position.midX} ${edge.position.midY})`}\n pointerEvents=\"all\"\n />\n )}\n {renderInteractiveEdge ? (\n renderInteractiveEdge(edge, edge.position, state)\n ) : state.isEnabled && state.isEligible ? (\n <DefaultInteractiveEdge\n position={edge.position}\n isHovered={state.isHovered}\n strokeWidth={interactiveEdgeSize * 0.6}\n />\n ) : null}\n </g>\n );\n })}\n </g>\n )}\n\n {/* Interactive vertices layer (for settlement placement) */}\n {interactiveVertices && resolvedVertexPositions.length > 0 && (\n <g\n className=\"interactive-vertices\"\n role=\"list\"\n aria-label=\"Interactive vertices for placement\"\n >\n {resolvedVertexPositions.map(({ interactiveVertex: vertex }) => {\n const state = interactiveTargetRenderState(\n interactiveVertices,\n vertex.id,\n hoveredVertexId === vertex.id,\n );\n const isSelectable = isInteractiveTargetSelectable(\n interactiveVertices,\n state,\n );\n return (\n <g\n key={vertex.id}\n {...state.browserAttributes}\n role={isSelectable ? \"button\" : undefined}\n className={clsx(isSelectable && \"cursor-pointer\")}\n onPointerEnter={() => setHoveredVertexId(vertex.id)}\n onPointerLeave={() =>\n setHoveredVertexId((currentId) =>\n currentId === vertex.id ? null : currentId,\n )\n }\n onClick={\n isSelectable\n ? () => {\n void state.select?.();\n }\n : undefined\n }\n onKeyDown={(event) =>\n handleKeyboardActivation(\n event,\n isSelectable\n ? () => {\n void state.select?.();\n }\n : undefined,\n )\n }\n tabIndex={isSelectable ? 0 : undefined}\n aria-label={\n isSelectable ? `Select vertex ${vertex.id}` : undefined\n }\n >\n {isSelectable && (\n <circle\n cx={vertex.position.x}\n cy={vertex.position.y}\n r={interactiveVertexSize * 1.5}\n fill=\"rgba(255,255,255,0.001)\"\n pointerEvents=\"all\"\n />\n )}\n {renderInteractiveVertex ? (\n renderInteractiveVertex(vertex, vertex.position, state)\n ) : state.isEnabled && state.isEligible ? (\n <DefaultInteractiveVertex\n position={vertex.position}\n isHovered={state.isHovered}\n size={interactiveVertexSize * 0.6}\n />\n ) : null}\n </g>\n );\n })}\n </g>\n )}\n\n {/* Zoom indicator (for mobile) */}\n {effectivePanZoom && transform.zoom !== 1 && (\n <g\n transform={`translate(${viewBoxX + 10}, ${viewBoxY + viewBoxHeight - 30})`}\n >\n <rect\n x={0}\n y={0}\n width={60}\n height={20}\n rx={4}\n fill=\"rgba(0,0,0,0.6)\"\n />\n <text x={30} y={14} textAnchor=\"middle\" fill=\"white\" fontSize={12}>\n {Math.round(transform.zoom * 100)}%\n </text>\n </g>\n )}\n </svg>\n );\n}\n\nexport const HexGrid = HexGridImpl as HexGridComponent;\n","/**\n * Typed adapter for joining static hex-board topology with a dynamic\n * per-space view overlay. Use this to feed `HexGrid` a single board\n * value whose tiles carry both static geometry (`q`, `r`, `id`) and\n * the projected view fields the UI cares about (e.g. `terrain`,\n * `numberToken`).\n *\n * The runtime is intentionally strict: every static space must have\n * exactly one overlay, duplicates throw, and overlays for ids that\n * are not on the board throw. There is no relaxed fallback in v1 —\n * silent merge bugs are far more expensive than a loud throw at\n * dev/CI time.\n */\n\nimport type {\n AnyHexBoardInput,\n BoardIdOf,\n BoardSpaceIdOf,\n NormalizedHexTileOf,\n} from \"../../types/tiled-board.js\";\nimport { normalizeHexBoardInput } from \"../../types/tiled-board.js\";\n\n/**\n * Per-tile result produced by {@link createHexBoardView}. Each tile\n * carries the static topology (`id`, `q`, `r`) plus the matched\n * overlay row in `view`.\n *\n * Static board fields/properties are preserved from `TBoard`.\n * Consumers should use `tile.properties` for authored static space\n * fields and `tile.view` for dynamic per-space projection data.\n */\nexport type HexBoardViewTile<\n TBoard extends AnyHexBoardInput,\n TSpaceView extends { id: BoardSpaceIdOf<TBoard> },\n> = Omit<NormalizedHexTileOf<TBoard>, \"view\"> & { view: TSpaceView };\n\n/**\n * Result of {@link createHexBoardView}. Shaped like an authored hex\n * board so it can be passed straight to `<HexGrid board={...} />`\n * without any further adapter work.\n *\n * The type-level board id and space id are preserved from `TBoard`,\n * so `tile.id` stays narrow inside `renderTile`. `tile.view` is the\n * authored overlay row, fully typed.\n */\nexport interface HexBoardView<\n TBoard extends AnyHexBoardInput,\n TSpaceView extends { id: BoardSpaceIdOf<TBoard> },\n> {\n id: BoardIdOf<TBoard>;\n layout?: \"hex\";\n orientation?: \"pointy-top\" | \"flat-top\";\n tiles: ReadonlyArray<HexBoardViewTile<TBoard, TSpaceView>>;\n edges: TBoard[\"edges\"];\n vertices: TBoard[\"vertices\"];\n}\n\ninterface CreateHexBoardViewOptions<TSpaceView> {\n spaces: readonly TSpaceView[];\n}\n\n/**\n * Join a static hex board topology with a dynamic per-space overlay.\n *\n * The result is suitable for direct use as the `board` prop on\n * `<HexGrid>`. Every overlay is enforced 1-to-1 against the board's\n * spaces:\n *\n * - missing overlay for a board space → throws\n * - duplicate overlay (same `id` twice) → throws\n * - overlay `id` not present on the board → throws\n *\n * Each tile in the result carries a `view` field with the matched\n * overlay row.\n */\nexport function createHexBoardView<\n const TBoard extends AnyHexBoardInput,\n const TSpaceView extends { id: BoardSpaceIdOf<TBoard> },\n>(\n board: TBoard,\n options: CreateHexBoardViewOptions<TSpaceView>,\n): HexBoardView<TBoard, TSpaceView> {\n const overlayById = new Map<string, TSpaceView>();\n for (const overlay of options.spaces) {\n if (overlayById.has(overlay.id)) {\n throw new Error(\n `createHexBoardView: duplicate overlay for space '${overlay.id}'.`,\n );\n }\n overlayById.set(overlay.id, overlay);\n }\n\n const consumed = new Set<string>();\n const normalizedBoard = normalizeHexBoardInput(board);\n const tiles: Array<HexBoardViewTile<TBoard, TSpaceView>> =\n normalizedBoard.tiles.map((tile) => {\n const overlay = overlayById.get(tile.id);\n if (!overlay) {\n throw new Error(\n `createHexBoardView: missing overlay for space '${tile.id}'.`,\n );\n }\n consumed.add(tile.id);\n return { ...tile, view: overlay };\n });\n\n for (const id of overlayById.keys()) {\n if (!consumed.has(id)) {\n throw new Error(\n `createHexBoardView: overlay '${id}' is not on the board.`,\n );\n }\n }\n\n return {\n id: normalizedBoard.id,\n layout: \"hex\",\n orientation: board.orientation,\n tiles,\n edges: board.edges,\n vertices: board.vertices,\n };\n}\n"],"mappings":"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","names":["useState","useEffect","useEffect","useMemo","useState","useState","useEffect","useMemo","jsx","clsx","jsx","jsxs","createContext","useCallback","useContext","useEffect","useMemo","useState","jsx","suppressed","clsx","clsx","jsx","jsx","clsx","useState","jsx","jsxs","useState","clsx","useCallback","useState","useState","useEffect","useMemo","useCallback","jsx","clsx","useCallback","useState","clsx","jsx","jsxs","clsx","createContext","useCallback","useContext","useEffect","useId","useMemo","useRef","useState","clsx","jsx","jsxs","createContext","useContext","useId","useRef","useState","useCallback","useMemo","useEffect","clsx","useCallback","useId","useMemo","clsx","useEffect","useMemo","useRef","useState","useRef","useState","useEffect","node","useMemo","useCallback","useEffect","useMemo","useRef","useState","useRef","useCallback","useState","useMemo","useEffect","jsx","CARD_DIMENSIONS","useMemo","useId","useCallback","clsx","createContext","useCallback","useContext","useEffect","useMemo","useRef","useState","useDrag","clsx","jsx","jsxs","createContext","useState","useCallback","useMemo","useContext","useEffect","useRef","useDrag","clsx","motion","AnimatePresence","clsx","jsx","clsx","AnimatePresence","motion","motion","clsx","jsx","jsxs","motion","AnimatePresence","jsx","jsx","createContext","useContext","useState","useCallback","Fragment","jsx","jsxs","createContext","useState","useCallback","useContext","AnimatePresence","Icon","surfaceStyle","motion","AlertTriangle","Fragment","jsx","jsxs","AlertTriangle","jsx","jsxs","jsx","jsx","jsx","jsxs","createContext","useContext","useMemo","jsx","createContext","useContext","useMemo","clsx","jsx","jsx","jsxs","clsx","Icon","jsx","jsxs","Icon","jsx","useEffect","useRef","useState","motion","Fragment","jsx","jsxs","useState","useRef","useEffect","motion","useId","useState","motion","AnimatePresence","jsx","jsxs","useId","useState","motion","AnimatePresence","useId","useState","jsx","jsxs","useState","useId","clsx","motion","useCallback","useEffect","useRef","useState","createContext","useContext","jsx","jsx","jsxs","clsx","useState","useRef","useEffect","useCallback","motion","motion","clsx","jsx","jsxs","clsx","motion","motion","useEffect","useState","jsx","jsxs","useState","useEffect","motion","useMemo","clsx","Fragment","jsx","jsxs","clsx","useMemo","useMemo","clsx","jsx","jsxs","clsx","useMemo","useMemo","clsx","jsx","jsxs","clsx","useMemo","useMemo","clsx","jsx","jsxs","clsx","useMemo","useMemo","useState","clsx","jsx","jsxs","clsx","useState","useMemo","useMemo","useState","clsx","jsx","jsxs","clsx","useMemo","useState"]}
|