@scriptonita/chess-football-ui 0.9.0 → 0.10.0

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/utils.ts","../src/components/game/game-piece.tsx","../src/components/game/football.tsx","../src/i18n/index.tsx","../src/components/game/ball-holder-chip.tsx","../src/components/game/keyboard-shortcuts.tsx","../src/components/game/pitch.tsx","../src/components/game/game-board.tsx","../src/components/ui/avatar.tsx","../src/components/action-points.tsx","../src/components/game/player-identity.tsx","../src/components/game/scoreboard.tsx","../src/components/game/mini-scoreboard.tsx","../src/components/ui/button.tsx","../src/lib/use-dialog-a11y.ts","../src/components/ui/confirm-dialog.tsx","../src/components/game/game-controls.tsx","../src/components/game/selected-piece-detail.tsx","../src/components/game/move-history.tsx","../src/components/game/static-game-board.tsx","../src/components/game/turn-banner.tsx","../src/components/game/event-toast.tsx","../src/components/game/mobile-history.tsx","../src/tokens.ts"],"names":["twMerge","clsx","ChessKing","ChessQueen","ChessRook","ChessBishop","ChessKnight","ShieldQuestion","jsxs","jsx","useId","SHORT_KEY","LONG_KEY","createContext","MotionConfig","useContext","useGameStore","Fragment","useReducedMotion","useShallow","useState","useRef","useEffect","id","useMemo","getValidMoves","getValidPasses","isInEnemyArea","getPath","squareName","Move","HelpCircle","AnimatePresence","motion","RANK_LABELS","FILE_LABELS","Crown","Zap","DEFAULT_MAX_AP","React","Flag","PIECE_ICON","COLS","ROWS","getInitialBoardState","X"],"mappings":"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","file":"index.cjs","sourcesContent":["import { clsx, type ClassValue } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","import { Piece } from '@scriptonita/chess-football-engine'\nimport { cn } from '../../lib/utils'\nimport {\n ChessKing,\n ChessQueen,\n ChessRook,\n ChessBishop,\n ChessKnight,\n ShieldQuestion,\n type LucideIcon,\n} from 'lucide-react'\n\ninterface GamePieceProps {\n piece: Piece\n isSelected: boolean\n hasBall: boolean\n onClick: (e: React.MouseEvent) => void\n /**\n * True while the piece is travelling between squares. The chip lifts\n * slightly and its ground shadow drops away, so the move reads as the\n * piece being picked up and slid across the turf rather than dragged.\n */\n isMoving?: boolean\n}\n\nconst PIECE_ICON: Record<Piece['type'], LucideIcon> = {\n king: ChessKing,\n queen: ChessQueen,\n rook: ChessRook,\n bishop: ChessBishop,\n knight: ChessKnight,\n}\n\n// Embossed glyph: with the light source at the top-left (same as the chip's\n// radial gradient), a raised figure catches a thin highlight on its upper edge\n// and casts a short shadow below. Tuned per side so it reads on both chips.\nconst EMBOSS_FILTER: Record<Piece['side'], string> = {\n white: 'drop-shadow(0 -0.75px 0 rgba(255,255,255,0.65)) drop-shadow(0 1.25px 1px rgba(0,0,0,0.45))',\n black: 'drop-shadow(0 -0.5px 0 rgba(255,255,255,0.3)) drop-shadow(0 1.25px 1.5px rgba(0,0,0,0.8))',\n}\n\nexport const PieceIcon = ({ type, side }: { type: Piece['type']; side: Piece['side'] }) => {\n const Icon = PIECE_ICON[type] ?? ShieldQuestion\n // Size scales with the board container width (cqw); clamp keeps the glyph\n // readable on small screens and avoids overflow on very large ones.\n const style: React.CSSProperties = {\n width: 'clamp(16px, 7.4cqw, 44px)',\n height: 'clamp(16px, 7.4cqw, 44px)',\n filter: EMBOSS_FILTER[side],\n }\n return <Icon style={style} strokeWidth={2} aria-hidden=\"true\" />\n}\n\n// 3D piece styling: radial gradient for top-left light source + layered\n// box-shadows (inner highlight, inner bottom shade, outer drop shadows) to\n// suggest a chip floating slightly above the board. Used as-is by standalone\n// chips (e.g. the ball-holder badge in the board toolbar).\nexport const WHITE_PIECE_STYLE: React.CSSProperties = {\n background: 'radial-gradient(circle at 30% 25%, #ffffff 0%, #f4f4f5 55%, #d4d4d8 100%)',\n boxShadow: [\n 'inset 0 1.5px 1px rgba(255,255,255,0.95)',\n 'inset 0 -2px 3px rgba(0,0,0,0.18)',\n '0 4px 6px rgba(0,0,0,0.45)',\n '0 1px 2px rgba(0,0,0,0.35)',\n ].join(', '),\n border: '1px solid rgba(0,0,0,0.18)',\n color: '#09090b',\n}\n\nexport const BLACK_PIECE_STYLE: React.CSSProperties = {\n background: 'radial-gradient(circle at 30% 25%, #52525b 0%, #1c1c1f 55%, #050507 100%)',\n boxShadow: [\n 'inset 0 1.5px 1px rgba(255,255,255,0.22)',\n 'inset 0 -2px 3px rgba(0,0,0,0.6)',\n '0 4px 6px rgba(0,0,0,0.55)',\n '0 1px 2px rgba(0,0,0,0.4)',\n ].join(', '),\n border: '1px solid rgba(0,0,0,0.55)',\n color: '#fafafa',\n}\n\n// On the board the ground shadow is a separate blurred layer (see below), so\n// the chip itself only keeps its bevel plus a tight contact edge — stacking the\n// toolbar's drop shadows on top would double up and read as smudged.\nconst ON_BOARD_CHIP_STYLE: Record<Piece['side'], React.CSSProperties> = {\n white: {\n ...WHITE_PIECE_STYLE,\n boxShadow: [\n 'inset 0 1.5px 1px rgba(255,255,255,0.95)',\n 'inset 0 -2px 3px rgba(0,0,0,0.18)',\n '0 1px 1px rgba(0,0,0,0.35)',\n ].join(', '),\n },\n black: {\n ...BLACK_PIECE_STYLE,\n boxShadow: [\n 'inset 0 1.5px 1px rgba(255,255,255,0.22)',\n 'inset 0 -2px 3px rgba(0,0,0,0.6)',\n '0 1px 1px rgba(0,0,0,0.5)',\n ].join(', '),\n },\n}\n\nconst MOVED_STYLE: React.CSSProperties = {\n filter: 'saturate(0.15) brightness(0.75)',\n}\n\nexport default function GamePiece({ piece, isSelected, hasBall, onClick, isMoving = false }: GamePieceProps) {\n const chipStyle = ON_BOARD_CHIP_STYLE[piece.side]\n\n return (\n <div\n onClick={onClick}\n style={piece.hasMovedThisTurn ? MOVED_STYLE : undefined}\n className={cn(\n \"relative w-[88%] h-[88%] rounded-full cursor-pointer z-10 transition-transform duration-200 ease-out motion-reduce:transition-none\",\n // `--primary` was the package's one remaining shadcn token, and\n // CrazyGames had to define it by hand just to make the selection\n // ring visible. It is part of the design system now.\n isSelected && \"ring-4 ring-accent-green scale-110 z-30\",\n isMoving && \"scale-[1.08] z-40\",\n piece.hasMovedThisTurn && \"opacity-70\"\n )}\n >\n {/* Ground shadow — light comes from the top-left, so it falls to the\n bottom-right. While moving the chip is \"lifted\": the shadow drops\n further away, spreads and fades, then snaps back on landing. */}\n <div\n aria-hidden=\"true\"\n data-testid=\"piece-shadow\"\n data-lifted={isMoving ? 'true' : 'false'}\n className={cn(\n \"absolute inset-0 rounded-full bg-black pointer-events-none transition-all duration-200 ease-out motion-reduce:transition-none\",\n isMoving\n ? \"translate-x-[9%] translate-y-[24%] scale-[1.04] opacity-35 blur-[5px]\"\n : \"translate-x-[4%] translate-y-[9%] scale-95 opacity-50 blur-[3px]\",\n )}\n />\n\n <div\n data-testid=\"piece-chip\"\n style={chipStyle}\n className=\"absolute inset-0 rounded-full flex items-center justify-center\"\n >\n <PieceIcon type={piece.type} side={piece.side} />\n\n {hasBall && (\n <div className=\"absolute inset-0 rounded-full ring-2 ring-orange-400 pointer-events-none\" />\n )}\n\n {isSelected && (\n <div className=\"absolute inset-0 rounded-full animate-pulse motion-reduce:animate-none ring-2 ring-yellow-400 ring-offset-2 ring-offset-transparent\" />\n )}\n </div>\n </div>\n )\n}\n","import { useId } from 'react'\nimport { cn } from '../../lib/utils'\n\ninterface FootballProps {\n className?: string\n}\n\nexport const Football = ({ className }: FootballProps) => {\n const bodyId = useId()\n const hiId = `${bodyId}-h`\n\n return (\n <svg\n viewBox=\"0 0 100 100\"\n className={cn('w-full h-full drop-shadow-md', className)}\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <defs>\n <radialGradient id={bodyId} cx=\"36%\" cy=\"32%\" r=\"68%\">\n <stop offset=\"0%\" stopColor=\"#f0f9ff\" />\n <stop offset=\"55%\" stopColor=\"#bae6fd\" />\n <stop offset=\"100%\" stopColor=\"#38bdf8\" />\n </radialGradient>\n <radialGradient id={hiId} cx=\"32%\" cy=\"28%\" r=\"22%\">\n <stop offset=\"0%\" stopColor=\"#ffffff\" stopOpacity=\"0.85\" />\n <stop offset=\"100%\" stopColor=\"#ffffff\" stopOpacity=\"0\" />\n </radialGradient>\n </defs>\n\n <circle cx=\"50\" cy=\"50\" r=\"47\" fill={`url(#${bodyId})`} stroke=\"#18181b\" strokeWidth=\"1.5\" />\n\n <g stroke=\"#18181b\" strokeWidth=\"1.4\" strokeLinecap=\"round\" fill=\"none\">\n <line x1=\"50\" y1=\"41\" x2=\"50\" y2=\"30\" />\n <line x1=\"41.44\" y1=\"47.22\" x2=\"30.97\" y2=\"43.82\" />\n <line x1=\"44.71\" y1=\"57.28\" x2=\"38.24\" y2=\"66.18\" />\n <line x1=\"55.29\" y1=\"57.28\" x2=\"61.76\" y2=\"66.18\" />\n <line x1=\"58.56\" y1=\"47.22\" x2=\"69.03\" y2=\"43.82\" />\n\n <line x1=\"50\" y1=\"15.5\" x2=\"50\" y2=\"4.5\" />\n <line x1=\"17.18\" y1=\"39.34\" x2=\"6.71\" y2=\"35.94\" />\n <line x1=\"29.72\" y1=\"77.91\" x2=\"23.25\" y2=\"86.81\" />\n <line x1=\"70.28\" y1=\"77.91\" x2=\"76.75\" y2=\"86.81\" />\n <line x1=\"82.82\" y1=\"39.34\" x2=\"93.29\" y2=\"35.94\" />\n </g>\n\n <g fill=\"#18181b\" stroke=\"#18181b\" strokeWidth=\"0.6\" strokeLinejoin=\"round\">\n <polygon points=\"50,41 41.44,47.22 44.71,57.28 55.29,57.28 58.56,47.22\" />\n <polygon points=\"50,30 57.61,24.47 54.70,15.53 45.30,15.53 42.39,24.47\" />\n <polygon points=\"30.97,43.82 28.06,34.88 18.66,34.88 15.75,43.82 23.36,49.35\" />\n <polygon points=\"38.24,66.18 29.84,66.18 25.93,75.12 33.54,80.65 41.15,75.12\" />\n <polygon points=\"61.76,66.18 58.85,75.12 66.46,80.65 74.07,75.12 71.16,66.18\" />\n <polygon points=\"69.03,43.82 76.64,49.35 84.25,43.82 81.34,34.88 71.94,34.88\" />\n </g>\n\n <circle cx=\"50\" cy=\"50\" r=\"47\" fill={`url(#${hiId})`} pointerEvents=\"none\" />\n </svg>\n )\n}\n","import { createContext, useContext, type ReactNode } from 'react'\nimport { MotionConfig } from 'framer-motion'\nimport { SHORT_KEY, LONG_KEY, type PieceShortKey, type PieceLongKey } from '@scriptonita/chess-football-engine'\n\n/**\n * A translator scoped to the `game` namespace: `t('yourTurn')`, `t('move')`, …\n * Each host app supplies one bound to its own i18n library:\n * - Next.js (next-intl): const t = useTranslations('game')\n * - Vite (react-i18next): (key) => t(`game.${key}`)\n */\nexport type GameTranslator = (key: string, values?: Record<string, unknown>) => string\n\n/**\n * Static leaf keys the package's components read via `useGameT` with a literal `t('…')` call.\n * Keep in sync with those call sites — recipe:\n * grep -rhoE \"t\\('[a-zA-Z0-9_.]+'\" src/components | sed -E \"s/t\\('//;s/'//\" | sort -u\n * (the dynamic `pieces.*` / `eventToast.*` families are derived separately below).\n */\nconst STATIC_I18N_KEYS = [\n 'actionPointsAriaLabel',\n 'actionPointsShort',\n 'ballHolder',\n 'boardAriaLabel',\n 'endTurn',\n 'endTurnConfirm',\n 'endTurnConfirmDescription',\n 'endTurnConfirmYes',\n 'endTurnKeepPlaying',\n 'history.empty',\n 'history.goal',\n 'history.interception',\n 'history.move',\n 'history.offside',\n 'history.pass',\n 'history.tackle',\n 'history.title',\n 'history.close',\n 'history.turn',\n 'history.viewAll',\n 'move',\n 'offsideWarning',\n 'pass',\n 'scoreAriaLabel',\n 'selectedPiece.alreadyMoved',\n 'selectedPiece.atSquare',\n 'selectedPiece.empty',\n 'selectedPiece.hasBall',\n 'shortcuts.arrows',\n 'shortcuts.buttonLabel',\n 'shortcuts.cancel',\n 'shortcuts.move',\n 'shortcuts.pass',\n 'shortcuts.select',\n 'shortcuts.title',\n 'square.empty',\n 'square.emptyWithBall',\n 'square.moveOrPassTarget',\n 'square.moveTarget',\n 'square.passTarget',\n 'square.piece',\n 'square.pieceWithBall',\n 'square.selected',\n 'teamBlack',\n 'teamWhite',\n 'waitingRival',\n 'yourTurn',\n] as const\n\n/** `pieces.*` — one key per short and long piece label the engine exposes (move-history, selected-piece-detail). */\ntype PieceI18nKey = `pieces.${PieceShortKey | PieceLongKey}`\nconst PIECE_I18N_KEYS: PieceI18nKey[] = [...Object.values(SHORT_KEY), ...Object.values(LONG_KEY)].map(\n (label) => `pieces.${label}` as PieceI18nKey,\n)\n\n/** `eventToast.*` — one key per toastable event (see `ToastEvent` in `event-toast.tsx`). */\ntype EventToastI18nKey = `eventToast.${'goal' | 'interception' | 'offside' | 'tackle'}`\nconst EVENT_TOAST_I18N_KEYS: EventToastI18nKey[] = [\n 'eventToast.goal',\n 'eventToast.interception',\n 'eventToast.offside',\n 'eventToast.tackle',\n]\n\n/** Union of every `game`-namespace key the package reads. */\nexport type GameI18nKey = (typeof STATIC_I18N_KEYS)[number] | PieceI18nKey | EventToastI18nKey\n\n/**\n * Manifest of every `game`-namespace key the package's components read via `useGameT`.\n * Host apps use it to assert their translation catalogs cover the package (AD-4).\n * The `pieces.*` family is derived from the engine's `SHORT_KEY`/`LONG_KEY` so it can't\n * drift when a piece is added; static keys and `eventToast.*` are listed above.\n * No key names an automated-opponent brand — the roster owns opponent identity.\n */\nexport const GAME_I18N_KEYS: readonly GameI18nKey[] = [\n ...STATIC_I18N_KEYS,\n ...PIECE_I18N_KEYS,\n ...EVENT_TOAST_I18N_KEYS,\n]\n\n/**\n * Identity fallback: renders the key itself when the host app has no catalog\n * entry for it. It shouts in development because a missing key is invisible in\n * production until a player screenshots `⚠ game.offsideWarning` on the pitch.\n * `GAME_I18N_KEYS` exists so a test catches this before a human does.\n */\nconst nodeEnv = (globalThis as { process?: { env?: { NODE_ENV?: string } } }).process?.env?.NODE_ENV\n\nconst fallback: GameTranslator = (key) => {\n if (nodeEnv && nodeEnv !== 'production') {\n console.warn(`[chess-football-ui] missing game i18n key: \"${key}\" (no GameI18nProvider?)`)\n }\n return key\n}\n\nconst GameI18nContext = createContext<GameTranslator>(fallback)\n\nexport function GameI18nProvider({ t, children }: { t: GameTranslator; children: ReactNode }) {\n return (\n <GameI18nContext.Provider value={t}>\n <MotionConfig reducedMotion=\"user\">\n {children}\n </MotionConfig>\n </GameI18nContext.Provider>\n )\n}\n\n/** Returns the `game`-scoped translator provided by the host app (identity fallback). */\nexport function useGameT(): GameTranslator {\n return useContext(GameI18nContext)\n}\n","import { useGameStore } from '../../store/use-game-store'\nimport { PieceIcon, WHITE_PIECE_STYLE, BLACK_PIECE_STYLE } from './game-piece'\nimport { Football } from './football'\nimport { useGameT } from '../../i18n'\nimport { cn } from '../../lib/utils'\n\ninterface BallHolderChipProps {\n className?: string\n}\n\n/**\n * §12b: a persistent, always-visible answer to \"whose ball is it\" — the piece\n * type currently holding the ball, drawn as a mini chip. Additive to the subtle\n * per-piece ring on the board. Renders nothing while the ball is loose.\n *\n * GameBoard shows it in its own toolbar by default; apps with a side panel can\n * pass `toolbar={false}` to the board and place this chip wherever it reads best.\n */\nexport function BallHolderChip({ className }: BallHolderChipProps) {\n const t = useGameT()\n const boardState = useGameStore(s => s.boardState)\n const holder = boardState?.pieces.find(p => p.id === boardState.ball.holderId) ?? null\n if (!holder) return null\n\n return (\n <div className={cn('flex items-center gap-1.5 min-h-[1.75rem]', className)} aria-live=\"polite\">\n <div\n style={holder.side === 'white' ? WHITE_PIECE_STYLE : BLACK_PIECE_STYLE}\n className=\"relative w-7 h-7 flex items-center justify-center rounded-full shrink-0\"\n >\n <PieceIcon type={holder.type} side={holder.side} />\n <div className=\"absolute -bottom-1 -right-1 w-3.5 h-3.5 flex items-center justify-center rounded-full bg-bg-secondary border border-border-subtle\">\n <div className=\"w-2.5 h-2.5\"><Football /></div>\n </div>\n </div>\n <span className=\"font-inter text-[11px] text-fg-secondary\">\n {t('ballHolder')}: {t(`pieces.${holder.type}`)}\n </span>\n </div>\n )\n}\n","import { useGameT } from '../../i18n'\nimport { cn } from '../../lib/utils'\n\ninterface KeyboardShortcutsListProps {\n className?: string\n}\n\n/**\n * §12: the legend of the board's keyboard shortcuts. GameBoard shows it in a\n * popover behind a \"?\" button in its toolbar; apps that pass `toolbar={false}`\n * can render the list inline in a side panel instead.\n */\nexport function KeyboardShortcutsList({ className }: KeyboardShortcutsListProps) {\n const t = useGameT()\n return (\n <ul className={cn('font-mono text-[10px] text-fg-secondary leading-relaxed', className)}>\n <li><kbd className=\"text-fg-primary\">↑↓←→</kbd> {t('shortcuts.arrows')}</li>\n <li><kbd className=\"text-fg-primary\">Enter</kbd> {t('shortcuts.select')}</li>\n <li><kbd className=\"text-fg-primary\">M</kbd> {t('shortcuts.move')}</li>\n <li><kbd className=\"text-fg-primary\">P</kbd> {t('shortcuts.pass')}</li>\n <li><kbd className=\"text-fg-primary\">Esc</kbd> {t('shortcuts.cancel')}</li>\n </ul>\n )\n}\n","import { useId } from 'react'\nimport { cn } from '../../lib/utils'\n\n// ─── Squares ─────────────────────────────────────────────────────────────────\n\nexport const PITCH_COLS = 9\nexport const PITCH_ROWS = 12\n\n/** The two goal boxes: files c–g on the first two and last two ranks. */\nexport const isGoalAreaSquare = (x: number, y: number): boolean =>\n x >= 2 && x <= 6 && ((y >= 0 && y <= 1) || (y >= PITCH_ROWS - 2 && y <= PITCH_ROWS - 1))\n\n/**\n * Goal-box shading: an inset box-shadow that darkens the square *over* its own\n * green, so the box reads as a distinct zone (the king's area) while the\n * checkerboard alternation stays visible — opponents enter it square by square\n * and need to read their moves there. An inset shadow (rather than a flat\n * replacement colour) keeps the app's tokens in charge of the hue and composes\n * with Tailwind's `ring-*` utilities on the live board's highlighted squares.\n */\nexport const GOAL_AREA_SHADE_CLASS = 'shadow-[inset_0_0_0_100vmax_rgba(0,0,0,0.32)]'\n\n/**\n * Base classes of one pitch square. Every board renderer — the live GameBoard,\n * StaticGameBoard, and any app-side mini board built on PitchSurface — derives\n * its squares from here, so the field reads identically everywhere. Colours\n * come from the app's `field-green-*` design tokens.\n */\nexport function pitchSquareClass(x: number, y: number): string {\n const isEven = (x + y) % 2 === 0\n return cn(\n 'relative aspect-square w-full',\n isEven ? 'bg-field-green-1' : 'bg-field-green-2',\n isGoalAreaSquare(x, y) && GOAL_AREA_SHADE_CLASS,\n )\n}\n\n// ─── Grass ───────────────────────────────────────────────────────────────────\n//\n// A seamless fractal-noise tile, inlined as an SVG data URI and repeated as a\n// background. `stitchTiles` makes the repeat seamless, so the grain reads as\n// one continuous surface across the whole pitch instead of per-square. Blended\n// with `mix-blend-mode: overlay`, mid-grey is neutral: the noise only nudges\n// the underlying green lighter/darker, so both square shades (and the darker\n// goal boxes) keep their own colour while gaining a turf-like texture. The\n// browser rasterises the tile once and caches it — no per-frame filter cost.\nconst GRAIN_TILE_SVG =\n '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"160\" height=\"160\">' +\n '<filter id=\"g\" x=\"0\" y=\"0\" width=\"100%\" height=\"100%\" color-interpolation-filters=\"sRGB\">' +\n '<feTurbulence type=\"fractalNoise\" baseFrequency=\"0.9\" numOctaves=\"3\" seed=\"7\" stitchTiles=\"stitch\"/>' +\n '<feColorMatrix type=\"saturate\" values=\"0\"/>' +\n '</filter>' +\n '<rect width=\"100%\" height=\"100%\" filter=\"url(#g)\"/>' +\n '</svg>'\n\nexport const GRAIN_TILE_URL = `url(\"data:image/svg+xml;utf8,${encodeURIComponent(GRAIN_TILE_SVG)}\")`\n\n// Stadium-light falloff: a faint highlight around the upper middle of the pitch\n// and darker edges, so the surface reads as a lit plane the pieces sit on\n// rather than a flat fill. Kept subtle so move/pass highlights stay legible.\nconst VIGNETTE =\n 'radial-gradient(120% 95% at 50% 38%, rgba(255,255,255,0.06) 0%, rgba(255,255,255,0) 42%, rgba(0,0,0,0.26) 100%)'\n\ninterface GrassOverlayProps {\n className?: string\n}\n\n/**\n * Decorative turf texture for the pitch. Absolutely positioned over the square\n * grid and click-through, so it sits between the squares and the pieces without\n * affecting hit-testing or the per-square highlight classes.\n */\nexport function GrassOverlay({ className }: GrassOverlayProps) {\n return (\n <div\n aria-hidden=\"true\"\n data-testid=\"grass-overlay\"\n className={cn('absolute inset-0 pointer-events-none overflow-hidden', className)}\n >\n <div\n data-layer=\"grain\"\n className=\"absolute inset-0 mix-blend-overlay opacity-60\"\n style={{ backgroundImage: GRAIN_TILE_URL, backgroundSize: '160px 160px' }}\n />\n <div data-layer=\"light\" className=\"absolute inset-0\" style={{ background: VIGNETTE }} />\n </div>\n )\n}\n\n// ─── Chalk markings ──────────────────────────────────────────────────────────\n//\n// Coordinates are in board cells (viewBox 0 0 9 12, y grows downwards), so the\n// markings stretch with the grid at any size.\n\nconst CHALK = '#f6f5ee'\n\ninterface PitchMarkingsProps {\n className?: string\n children?: React.ReactNode\n}\n\n/**\n * The painted pitch lines — touchline, goal boxes, halfway line, centre circle,\n * spots and the two \"D\" arcs — drawn to look like chalk on grass: a roughened,\n * slightly displaced edge and a noise-driven alpha so the coverage is powdery\n * rather than a crisp vector stroke. A faint, wider unfiltered pass underneath\n * acts as the dust halo the line leaves on the turf.\n *\n * Static and cached by the browser as its own layer; anything dynamic that\n * shares the board's coordinate space (e.g. the pass-trajectory preview) should\n * live in a separate <svg> so a hover repaint never re-runs this filter.\n */\nexport function PitchMarkings({ className, children }: PitchMarkingsProps) {\n const id = useId()\n const filterId = `${id}-chalk`\n\n return (\n <svg\n viewBox=\"0 0 9 12\"\n preserveAspectRatio=\"none\"\n className={cn('absolute inset-0 w-full h-full pointer-events-none', className)}\n aria-hidden=\"true\"\n data-testid=\"pitch-markings\"\n >\n <defs>\n <filter\n id={filterId}\n filterUnits=\"userSpaceOnUse\"\n x=\"-0.5\"\n y=\"-0.5\"\n width=\"10\"\n height=\"13\"\n colorInterpolationFilters=\"sRGB\"\n >\n {/* Wobble the edge: low-frequency noise pushes the stroke by up to ~0.04 cells. */}\n <feTurbulence type=\"fractalNoise\" baseFrequency=\"5.5\" numOctaves=\"2\" seed=\"3\" result=\"edgeNoise\" />\n <feDisplacementMap\n in=\"SourceGraphic\"\n in2=\"edgeNoise\"\n scale=\"0.045\"\n xChannelSelector=\"R\"\n yChannelSelector=\"G\"\n result=\"rough\"\n />\n {/* Powdery coverage: a second noise becomes an alpha mask in the 0.55–1 range. */}\n <feTurbulence type=\"fractalNoise\" baseFrequency=\"14\" numOctaves=\"3\" seed=\"11\" result=\"dust\" />\n <feColorMatrix\n in=\"dust\"\n type=\"matrix\"\n values=\"0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0.75 0 0 0 0.55\"\n result=\"dustMask\"\n />\n <feComposite in=\"rough\" in2=\"dustMask\" operator=\"arithmetic\" k1=\"1\" k2=\"0\" k3=\"0\" k4=\"0\" />\n </filter>\n </defs>\n\n {/* Dust halo: wider, faint, unfiltered so it stays cheap. */}\n <g data-layer=\"halo\" fill=\"none\" stroke={CHALK} strokeOpacity=\"0.09\" strokeWidth=\"0.16\" strokeLinecap=\"round\">\n <Markings />\n </g>\n\n <g\n data-layer=\"chalk\"\n filter={`url(#${filterId})`}\n fill=\"none\"\n stroke={CHALK}\n strokeOpacity=\"0.82\"\n strokeWidth=\"0.07\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <Markings />\n </g>\n\n {children}\n </svg>\n )\n}\n\nfunction Markings() {\n return (\n <>\n {/* Touchline / goal lines */}\n <rect x=\"0.06\" y=\"0.06\" width=\"8.88\" height=\"11.88\" />\n {/* Goal boxes */}\n <rect x=\"2\" y=\"0.06\" width=\"5\" height=\"1.94\" />\n <rect x=\"2\" y=\"10\" width=\"5\" height=\"1.94\" />\n {/* Halfway line */}\n <line x1=\"0.06\" y1=\"6\" x2=\"8.94\" y2=\"6\" />\n {/* Centre circle + spot */}\n <circle cx=\"4.5\" cy=\"6\" r=\"1.5\" />\n <circle cx=\"4.5\" cy=\"6\" r=\"0.09\" fill={CHALK} fillOpacity=\"0.9\" stroke=\"none\" />\n {/* Penalty spots */}\n <circle cx=\"4.5\" cy=\"1.5\" r=\"0.08\" fill={CHALK} fillOpacity=\"0.9\" stroke=\"none\" />\n <circle cx=\"4.5\" cy=\"10.5\" r=\"0.08\" fill={CHALK} fillOpacity=\"0.9\" stroke=\"none\" />\n {/* The \"D\" arcs */}\n <path d=\"M 3.086,2 A 1.5,1.5 0 0 0 5.914,2\" />\n <path d=\"M 3.086,10 A 1.5,1.5 0 0 1 5.914,10\" />\n </>\n )\n}\n\n// ─── Surface ─────────────────────────────────────────────────────────────────\n\ninterface PitchSurfaceProps {\n className?: string\n /**\n * Extra classes for a given square (e.g. a highlighted area in a rules\n * diagram). Falsy return values are ignored.\n */\n squareClassName?: (x: number, y: number) => string | false | null | undefined\n /** Layers rendered above the markings — pieces, ball, overlays. */\n children?: React.ReactNode\n}\n\n/**\n * The complete, non-interactive pitch: squares, turf grain and chalk lines, in\n * that order, inside a container-query wrapper so pieces can size themselves\n * with `cqw`. Callers put their own frame (border/radius) around it and their\n * own piece layer inside it. The interactive GameBoard renders its own square\n * grid (it needs per-square handlers) but builds every square from the same\n * `pitchSquareClass`, and stacks the same GrassOverlay + PitchMarkings.\n */\nexport function PitchSurface({ className, squareClassName, children }: PitchSurfaceProps) {\n const squares = []\n for (let y = PITCH_ROWS - 1; y >= 0; y--) {\n for (let x = 0; x < PITCH_COLS; x++) {\n squares.push(\n <div key={`${x}-${y}`} className={cn(pitchSquareClass(x, y), squareClassName?.(x, y))} />,\n )\n }\n }\n return (\n <div className={cn('relative', className)} style={{ containerType: 'inline-size' }}>\n <div className=\"grid grid-cols-9 gap-[1px]\" data-testid=\"pitch-squares\">\n {squares}\n </div>\n <GrassOverlay />\n <PitchMarkings />\n {children}\n </div>\n )\n}\n","import { useGameStore } from '../../store/use-game-store'\nimport { useShallow } from 'zustand/react/shallow'\nimport { getValidMoves, getValidPasses, getPath, isInEnemyArea } from '@scriptonita/chess-football-engine'\nimport { cn } from '../../lib/utils'\nimport { motion, AnimatePresence, useReducedMotion } from 'framer-motion'\nimport GamePiece from './game-piece'\nimport { BallHolderChip } from './ball-holder-chip'\nimport { KeyboardShortcutsList } from './keyboard-shortcuts'\nimport { useEffect, useId, useMemo, useRef, useState } from 'react'\nimport { Side, Position, MoveHistoryEntry, Piece, LONG_KEY, squareName } from '@scriptonita/chess-football-engine'\nimport { Football } from './football'\nimport { GrassOverlay, PitchMarkings, pitchSquareClass } from './pitch'\nimport { FILE_LABELS, RANK_LABELS } from '@scriptonita/chess-football-engine'\nimport { Move, HelpCircle } from 'lucide-react'\nimport { useGameT } from '../../i18n'\n\ninterface GameBoardProps {\n userSide: Side | null\n /** When true, render A-I / 1-12 coordinate guides around the board (tablet+ only). */\n showCoordinates?: boolean\n /** When true, the board is keyboard-operable (arrows move a cursor, Enter acts). */\n keyboardNav?: boolean\n /**\n * Desktop-only row above the grid with the ball-holder chip and the keyboard\n * shortcuts button. Pass `false` when the app renders `BallHolderChip` and\n * `KeyboardShortcutsList` itself (e.g. in a side panel) so nothing is shown twice.\n */\n toolbar?: boolean\n className?: string\n}\n\n// Board dimensions\nconst COLS = 9\nconst ROWS = 12\n\nconst clamp = (v: number, lo: number, hi: number) => Math.max(lo, Math.min(hi, v))\n\n// Pieces and the ball are positioned with translate transforms instead of\n// animating `left`/`top`: each wrapper is exactly one cell wide/tall, so a\n// percentage translate of N×100% lands on cell N, and the animation runs on the\n// compositor (no layout/paint per frame) — that is what makes the slide smooth.\nconst cellX = (x: number) => `${x * 100}%`\nconst cellY = (y: number) => `${(ROWS - 1 - y) * 100}%`\n\n// Critically-damped springs (ratio ≈ 1.0): a firm push-off, a long glide and\n// a soft landing with no bounce — a chip sliding across turf, not a rubber\n// ball. Settles in roughly half a second regardless of distance, so a long\n// rook run still reads as one motion. A carried ball uses the piece's curve\n// so it never drifts ahead of or behind its holder; a free ball (pass) is\n// lighter and snappier.\nconst PIECE_SLIDE = { type: 'spring' as const, stiffness: 190, damping: 28, mass: 1 }\nconst BALL_SLIDE = { type: 'spring' as const, stiffness: 300, damping: 26, mass: 0.6 }\n\nexport default function GameBoard({ userSide, showCoordinates = false, keyboardNav = true, toolbar = true, className }: GameBoardProps) {\n const t = useGameT()\n const boardId = useId()\n const prefersReducedMotion = useReducedMotion()\n // Selector + useShallow: without it every `set` on the store re-renders all\n // 108 squares, including sets this component does not care about.\n const {\n boardState,\n selectedPieceId,\n interactionMode,\n setSelectedPieceId,\n setInteractionMode,\n movePiece,\n passBall,\n } = useGameStore(\n useShallow(s => ({\n boardState: s.boardState,\n selectedPieceId: s.selectedPieceId,\n interactionMode: s.interactionMode,\n setSelectedPieceId: s.setSelectedPieceId,\n setInteractionMode: s.setInteractionMode,\n movePiece: s.movePiece,\n passBall: s.passBall,\n })),\n )\n\n const [cursor, setCursor] = useState<Position | null>(null)\n const [disambiguateAt, setDisambiguateAt] = useState<Position | null>(null)\n const [shortcutsOpen, setShortcutsOpen] = useState(false)\n const shortcutsRef = useRef<HTMLDivElement>(null)\n useEffect(() => {\n if (!shortcutsOpen) return\n const onPointerDown = (e: MouseEvent) => {\n if (shortcutsRef.current && !shortcutsRef.current.contains(e.target as Node)) {\n setShortcutsOpen(false)\n }\n }\n document.addEventListener('mousedown', onPointerDown)\n return () => document.removeEventListener('mousedown', onPointerDown)\n }, [shortcutsOpen])\n const [invalidClickAt, setInvalidClickAt] = useState<(Position & { nonce: number }) | null>(null)\n const invalidClickNonceRef = useRef(0)\n const triggerInvalidClickShake = (x: number, y: number) => {\n invalidClickNonceRef.current += 1\n setInvalidClickAt({ x, y, nonce: invalidClickNonceRef.current })\n }\n const [hoveredPassAt, setHoveredPassAt] = useState<Position | null>(null)\n\n // Pieces currently travelling between squares (framer-motion drives the\n // slide; this only toggles the lift/shadow cue on GamePiece).\n const [movingIds, setMovingIds] = useState<ReadonlySet<string>>(() => new Set())\n const setMoving = (id: string, moving: boolean) =>\n setMovingIds(prev => {\n if (prev.has(id) === moving) return prev\n const next = new Set(prev)\n if (moving) next.add(id); else next.delete(id)\n return next\n })\n\n useEffect(() => {\n if (!invalidClickAt) return\n const id = setTimeout(() => setInvalidClickAt(null), 100)\n return () => clearTimeout(id)\n }, [invalidClickAt])\n\n const prevBallRef = useRef(boardState?.ball)\n const prevBall = prevBallRef.current\n useEffect(() => {\n prevBallRef.current = boardState?.ball\n })\n\n // §4: sequential replay of a just-finished opponent turn — when the turn\n // hands back to userSide and the opponent recorded more than one action,\n // briefly step through each origin/destination before settling on the\n // real last move, so a multi-action turn doesn't read as a single jump.\n const prevTurnRef = useRef(boardState?.turn)\n const [replay, setReplay] = useState<{ steps: MoveHistoryEntry[]; index: number } | null>(null)\n useEffect(() => {\n const prevTurn = prevTurnRef.current\n prevTurnRef.current = boardState?.turn\n if (!boardState || prevTurn === boardState.turn) return\n\n // Turn moved on again before a replay finished (e.g. a very fast\n // opponent turn) — the in-flight replay is now stale, drop it.\n if (boardState.turn !== userSide) {\n setReplay(null)\n return\n }\n if (prefersReducedMotion || userSide === null) return\n\n const lastEntry = boardState.moveHistory.at(-1)\n if (!lastEntry) return\n const steps = boardState.moveHistory.filter(\n m => m.turnNumber === lastEntry.turnNumber && m.pieceSide !== userSide,\n )\n if (steps.length > 1) setReplay({ steps, index: 0 })\n }, [boardState, userSide, prefersReducedMotion])\n\n useEffect(() => {\n if (!replay) return\n if (replay.index >= replay.steps.length - 1) {\n const id = setTimeout(() => setReplay(null), 350)\n return () => clearTimeout(id)\n }\n const id = setTimeout(() => setReplay(r => (r ? { ...r, index: r.index + 1 } : null)), 350)\n return () => clearTimeout(id)\n }, [replay])\n\n // `interactionMode` was written by both apps (their Move/Pass selector) and\n // read by nobody: the board highlighted every target regardless and still\n // popped the disambiguation popover. Honouring it turns that selector into\n // a real filter — and on touch, into a way to act without the popover.\n const validMoves = useMemo(() => {\n if (!boardState || interactionMode === 'pass') return []\n const sp = boardState.pieces.find(p => p.id === selectedPieceId)\n if (sp && !sp.hasMovedThisTurn) {\n return getValidMoves(sp, boardState)\n }\n return []\n }, [boardState, selectedPieceId, interactionMode])\n\n const validPasses = useMemo(() => {\n if (!boardState || interactionMode === 'move') return []\n const sp = boardState.pieces.find(p => p.id === selectedPieceId)\n if (sp && boardState.ball.holderId === sp.id) {\n return getValidPasses(sp, boardState)\n }\n return []\n }, [boardState, selectedPieceId, interactionMode])\n\n if (!boardState) return null\n\n const lastMove = boardState.lastMove\n const ball = boardState.ball\n const ballMoved =\n !!prevBall &&\n (prevBall.pos.x !== ball.pos.x || prevBall.pos.y !== ball.pos.y)\n const isPickupOnMove =\n !!prevBall &&\n !prevBall.holderId &&\n !!ball.holderId &&\n lastMove?.type === 'move' &&\n lastMove?.playerId === ball.holderId &&\n ballMoved\n\n const PICKUP_DURATION = 0.5\n const pickupCarrierId = isPickupOnMove ? ball.holderId : null\n let pickupProportion = 0.5\n if (isPickupOnMove && prevBall && lastMove?.from) {\n const totalSteps = Math.max(\n Math.abs(lastMove.to.x - lastMove.from.x),\n Math.abs(lastMove.to.y - lastMove.from.y),\n )\n const stepsToBall = Math.max(\n Math.abs(prevBall.pos.x - lastMove.from.x),\n Math.abs(prevBall.pos.y - lastMove.from.y),\n )\n pickupProportion = totalSteps > 0\n ? Math.min(0.85, Math.max(0.15, stepsToBall / totalSteps))\n : 0.5\n }\n\n // §8: Offside risk — ball carrier (non-king) in enemy area during user's turn\n const ballCarrier = ball.holderId\n ? boardState.pieces.find(p => p.id === ball.holderId) ?? null\n : null\n const isOffsideRisk =\n !!ballCarrier &&\n ballCarrier.type !== 'king' &&\n userSide !== null &&\n ballCarrier.side === userSide &&\n boardState.turn === userSide &&\n isInEnemyArea(ballCarrier.pos, ballCarrier.side)\n\n // §16: pass-trajectory preview — dashed line from the ball carrier to the\n // hovered valid-pass square, red if an opposing piece would intercept it.\n // Mirrors applyPass's own rules (game-engine.ts): the path INCLUDES the\n // destination (an enemy sitting there still intercepts/scores), and a\n // knight's pass only ever checks the destination — no traversal, since a\n // knight throw doesn't travel the straight/diagonal line getPath assumes.\n const passCarrier = boardState.pieces.find(p => p.id === selectedPieceId && boardState.ball.holderId === p.id) ?? null\n const trajectoryPath = (hoveredPassAt && passCarrier)\n ? (passCarrier.type === 'knight' ? [hoveredPassAt] : getPath(passCarrier.pos, hoveredPassAt))\n : null\n const trajectoryIntercepted = !!(trajectoryPath && passCarrier && trajectoryPath\n .some(sq => boardState.pieces.some(p => p.pos.x === sq.x && p.pos.y === sq.y && p.side !== passCarrier.side)))\n\n const handleSquareClick = (x: number, y: number) => {\n if (replay) return // §4: don't act while the opponent-turn replay is playing\n setCursor(null)\n const isValidMove = validMoves.some(m => m.x === x && m.y === y)\n const isValidPass = validPasses.some(p => p.x === x && p.y === y)\n\n if (isValidMove && isValidPass) {\n setDisambiguateAt({ x, y })\n return\n }\n if (isValidMove && selectedPieceId) {\n movePiece(selectedPieceId, { x, y })\n setDisambiguateAt(null)\n setInvalidClickAt(null)\n } else if (isValidPass) {\n passBall({ x, y })\n setDisambiguateAt(null)\n setInvalidClickAt(null)\n } else {\n // §16: subtle shake when a piece is selected but the target square\n // isn't a legal move/pass — no-op clicks on empty board stay silent.\n if (selectedPieceId) {\n triggerInvalidClickShake(x, y)\n }\n setDisambiguateAt(null)\n }\n }\n\n const handlePieceClick = (pieceId: string, x: number, y: number, e: React.MouseEvent) => {\n e.stopPropagation()\n if (replay) return // §4: don't act while the opponent-turn replay is playing\n const pieceAt = boardState.pieces.find(p => p.id === pieceId)\n if (!pieceAt) return\n\n const isValidMove = validMoves.some(m => m.x === x && m.y === y)\n const isValidPass = validPasses.some(p => p.x === x && p.y === y)\n\n if (isValidMove || isValidPass) {\n handleSquareClick(x, y)\n } else if (boardState.turn === pieceAt.side && userSide === pieceAt.side) {\n if (selectedPieceId === pieceAt.id) {\n setSelectedPieceId(null)\n } else {\n setSelectedPieceId(pieceAt.id)\n }\n setDisambiguateAt(null)\n setInvalidClickAt(null)\n } else if (selectedPieceId) {\n // §16: clicking an occupied square (own non-selectable or opponent\n // piece) that isn't a legal target is just as \"invalid\" as clicking\n // an illegal empty square — keep the feedback consistent.\n triggerInvalidClickShake(x, y)\n setDisambiguateAt(null)\n }\n }\n\n const defaultCursor = (): Position => {\n const sel = boardState.pieces.find(p => p.id === selectedPieceId)\n return sel ? { ...sel.pos } : { ...boardState.ball.pos }\n }\n\n const activate = (x: number, y: number) => {\n const pieceAt = boardState.pieces.find(p => p.pos.x === x && p.pos.y === y)\n if (pieceAt) {\n handlePieceClick(pieceAt.id, x, y, { stopPropagation() {} } as React.MouseEvent)\n } else {\n handleSquareClick(x, y)\n }\n }\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (!keyboardNav || replay) return\n const step = (dx: number, dy: number) => {\n e.preventDefault()\n setCursor(c => {\n const base = c ?? defaultCursor()\n return { x: clamp(base.x + dx, 0, COLS - 1), y: clamp(base.y + dy, 0, ROWS - 1) }\n })\n }\n switch (e.key) {\n case 'ArrowUp': step(0, 1); break\n case 'ArrowDown': step(0, -1); break\n case 'ArrowLeft': step(-1, 0); break\n case 'ArrowRight': step(1, 0); break\n case 'Enter':\n case ' ': {\n e.preventDefault()\n const c = cursor ?? defaultCursor()\n setCursor(c)\n activate(c.x, c.y)\n break\n }\n // Bare M / P only: Cmd+P is Print and Ctrl+M is a browser shortcut,\n // and both used to resolve the popover behind the user's back.\n case 'm': case 'M':\n if (e.ctrlKey || e.metaKey || e.altKey) break\n if (disambiguateAt && selectedPieceId) {\n movePiece(selectedPieceId, disambiguateAt)\n setDisambiguateAt(null)\n }\n break\n case 'p': case 'P':\n if (e.ctrlKey || e.metaKey || e.altKey) break\n if (disambiguateAt) {\n passBall(disambiguateAt)\n setDisambiguateAt(null)\n }\n break\n case 'Escape':\n if (shortcutsOpen) {\n setShortcutsOpen(false)\n } else if (disambiguateAt) {\n setDisambiguateAt(null)\n } else {\n setSelectedPieceId(null)\n setInteractionMode(null)\n }\n break\n }\n }\n\n const cellId = (x: number, y: number) => `${boardId}-sq-${x}-${y}`\n\n /**\n * The square's accessible name: coordinate first (so a screen reader user\n * always knows where the cursor is), then what is on it, then why it is\n * highlighted. Fragments are joined with \", \" rather than composed into one\n * template so every part stays independently translatable.\n */\n const squareLabel = (\n x: number,\n y: number,\n pieceAt: Piece | undefined,\n isValidMove: boolean,\n isValidPass: boolean,\n ) => {\n const square = squareName({ x, y })\n const ballHere = ball.pos.x === x && ball.pos.y === y\n const parts: string[] = []\n\n if (pieceAt) {\n const piece = t(`pieces.${LONG_KEY[pieceAt.type]}`)\n const team = pieceAt.side === 'white' ? t('teamWhite') : t('teamBlack')\n parts.push(t(ballHere ? 'square.pieceWithBall' : 'square.piece', { square, piece, team }))\n } else {\n parts.push(t(ballHere ? 'square.emptyWithBall' : 'square.empty', { square }))\n }\n\n if (isValidMove && isValidPass) parts.push(t('square.moveOrPassTarget'))\n else if (isValidMove) parts.push(t('square.moveTarget'))\n else if (isValidPass) parts.push(t('square.passTarget'))\n\n if (pieceAt && pieceAt.id === selectedPieceId) parts.push(t('square.selected'))\n\n return parts.join(', ')\n }\n\n // One `role=\"row\"` per rank. `display: contents` keeps the rows out of the\n // layout so the 9x12 CSS grid is unchanged — only the accessibility tree\n // gains the row structure `role=\"grid\"` requires.\n const renderRows = () => {\n const rows = []\n for (let y = ROWS - 1; y >= 0; y--) {\n const squares = []\n for (let x = 0; x < COLS; x++) {\n const isValidMove = validMoves.some(m => m.x === x && m.y === y)\n const isValidPass = validPasses.some(p => p.x === x && p.y === y)\n const isAmbiguous = isValidMove && isValidPass\n\n // §4: while a sequential replay is in progress, the highlighted\n // origin/destination trail follows the current replay step\n // instead of the real last move.\n const displayedLastMove = replay ? replay.steps[replay.index] : lastMove\n const isLastMoveOrigin = displayedLastMove?.from && displayedLastMove.from.x === x && displayedLastMove.from.y === y\n const isLastMoveDest = displayedLastMove?.to && displayedLastMove.to.x === x && displayedLastMove.to.y === y\n const isLastMove = isLastMoveOrigin || isLastMoveDest\n\n // §8: enemy goal area for offside warning\n const isEnemyGoalArea = userSide !== null\n && (x >= 2 && x <= 6)\n && (userSide === 'white' ? (y >= 10 && y <= 11) : (y >= 0 && y <= 1))\n\n const pieceAt = boardState.pieces.find(p => p.pos.x === x && p.pos.y === y)\n const isCursor = keyboardNav && cursor?.x === x && cursor?.y === y\n const isDisambiguateTarget = disambiguateAt?.x === x && disambiguateAt?.y === y\n\n squares.push(\n <div\n key={`${x}-${y}`}\n id={cellId(x, y)}\n role=\"gridcell\"\n aria-label={squareLabel(x, y, pieceAt, isValidMove, isValidPass)}\n aria-selected={!!pieceAt && pieceAt.id === selectedPieceId}\n onClick={() => handleSquareClick(x, y)}\n onMouseEnter={() => { if (isValidPass) setHoveredPassAt({ x, y }) }}\n onMouseLeave={() => setHoveredPassAt(null)}\n // The preview hung off onMouseEnter alone, so it never\n // appeared on the touch devices that are most of the\n // CrazyGames audience. A first touch previews the\n // trajectory; handleSquareClick then confirms it.\n onTouchStart={() => { if (isValidPass) setHoveredPassAt({ x, y }) }}\n className={cn(\n pitchSquareClass(x, y),\n \"flex items-center justify-center cursor-pointer\",\n !isValidMove && !isValidPass && isLastMove && \"bg-last-move-highlight/20\",\n // §8: pulsing warning ring on enemy goal area\n isOffsideRisk && isEnemyGoalArea && !isValidMove && !isValidPass && \"ring-2 ring-inset ring-warning/60\",\n // Move and pass used raw yellow-400/sky-400 here while\n // the popover a few lines below used the\n // move-highlight/pass-highlight tokens — two palettes\n // for the same two concepts. One palette now: tokens.\n isAmbiguous && \"ring-[3px] ring-inset ring-move-highlight/90 bg-move-highlight/20\",\n !isAmbiguous && isValidMove && \"ring-[3px] ring-inset ring-move-highlight/80 bg-move-highlight/15\",\n !isAmbiguous && isValidPass && \"ring-[3px] ring-inset ring-pass-highlight/80 bg-pass-highlight/15\",\n )}\n >\n {/* Colour alone does not distinguish move from pass for a\n colour-blind player, so the marks differ in shape too:\n a filled dot moves, a hollow ring passes. */}\n {!isAmbiguous && isValidMove && !pieceAt && (\n <div data-testid=\"move-marker\" className=\"w-3 h-3 rounded-full bg-move-highlight/65\" />\n )}\n {!isAmbiguous && isValidPass && !pieceAt && (\n <div data-testid=\"pass-marker\" className=\"w-3.5 h-3.5 rounded-full border-2 border-pass-highlight/80\" />\n )}\n {isAmbiguous && !pieceAt && (\n <div className=\"flex items-center gap-0.5\">\n <div data-testid=\"move-marker\" className=\"w-2.5 h-2.5 rounded-full bg-move-highlight/80\" />\n <div data-testid=\"pass-marker\" className=\"w-2.5 h-2.5 rounded-full border-2 border-pass-highlight/90\" />\n </div>\n )}\n\n {isCursor && (\n <div className=\"absolute inset-0 ring-2 ring-inset ring-white pointer-events-none z-20\" aria-hidden=\"true\" />\n )}\n\n {isDisambiguateTarget && selectedPieceId && (\n <div\n className={cn(\n \"absolute z-50 flex gap-1 bg-bg-secondary border border-border-subtle rounded-md p-1 shadow-xl pointer-events-auto whitespace-nowrap\",\n // The board container is `overflow-hidden` (for its rounded\n // corners), so a popover that spills past an edge gets clipped.\n // Anchor it inside the board on edge columns / the top row.\n y === ROWS - 1 ? \"top-full mt-1\" : \"bottom-full mb-1\",\n x === 0\n ? \"left-0\"\n : x === COLS - 1\n ? \"right-0\"\n : \"left-1/2 -translate-x-1/2\",\n )}\n onClick={e => e.stopPropagation()}\n >\n <button\n className=\"flex items-center gap-1 px-2 py-1 rounded text-[11px] font-semibold font-inter text-move-highlight bg-move-highlight/10 hover:bg-move-highlight/20 transition-colors\"\n onClick={() => { movePiece(selectedPieceId, { x, y }); setDisambiguateAt(null) }}\n >\n <Move size={11} strokeWidth={2} />\n {t('move')}\n </button>\n <button\n className=\"flex items-center gap-1 px-2 py-1 rounded text-[11px] font-semibold font-inter text-pass-highlight bg-pass-highlight/10 hover:bg-pass-highlight/20 transition-colors\"\n onClick={() => { passBall({ x, y }); setDisambiguateAt(null) }}\n >\n <span className=\"w-3 h-3 inline-flex\"><Football /></span>\n {t('pass')}\n </button>\n </div>\n )}\n </div>\n )\n }\n rows.push(\n <div key={`row-${y}`} role=\"row\" className=\"contents\">\n {squares}\n </div>,\n )\n }\n return rows\n }\n\n const board = (\n <div\n data-testid=\"board-root\"\n className={cn(\n // §6: Mobile edge-to-edge — thin 2px margin, no border, no radius\n // The frame was hardcoded #1a3317 in three files, hand-tuned for\n // the webapp's darker grass and visibly wrong against the\n // CrazyGames pitch. It is a token now (see README).\n \"w-full mx-0.5 bg-field-frame overflow-hidden\",\n // §5+§6: Desktop — centered, rounded, bordered, height-based max-width\n \"md:mx-auto md:rounded-xl md:shadow-2xl md:border-4 md:border-field-frame\",\n \"md:max-w-[min(700px,calc((100dvh_-_150px)*0.75))]\",\n !showCoordinates && className,\n )}\n >\n {/* §12: desktop-only board toolbar — sits in its own row above the grid so\n nothing here ever overlaps a playable square. Left: persistent ball-holder\n chip. Right: keyboard-shortcuts legend, when the board is keyboard-operable.\n Apps with a side panel can opt out (toolbar={false}) and place both\n components themselves. */}\n {toolbar && (\n <div className=\"hidden md:flex items-center justify-between gap-2 px-2.5 py-1\" data-testid=\"board-toolbar\">\n <BallHolderChip />\n\n {keyboardNav && (\n <div\n ref={shortcutsRef}\n className=\"relative\"\n // The board's own key handler lives on the grid, which\n // is not an ancestor of this button — so Escape has to\n // be handled here or the popover can't be closed from\n // the keyboard at all.\n onKeyDown={e => {\n if (e.key === 'Escape' && shortcutsOpen) {\n e.stopPropagation()\n setShortcutsOpen(false)\n }\n }}\n >\n <button\n type=\"button\"\n onClick={(e) => { e.stopPropagation(); setShortcutsOpen(o => !o) }}\n aria-label={t('shortcuts.buttonLabel')}\n aria-expanded={shortcutsOpen}\n className=\"w-8 h-8 flex items-center justify-center rounded-full bg-bg-secondary/80 border border-border-subtle text-fg-muted hover:text-fg-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-green\"\n >\n <HelpCircle size={16} strokeWidth={2} aria-hidden=\"true\" />\n </button>\n {shortcutsOpen && (\n <div\n className=\"absolute top-full right-0 mt-1 z-50 w-max max-w-[220px] bg-bg-secondary border border-border-subtle rounded-md shadow-xl p-2.5 pointer-events-auto\"\n onClick={e => e.stopPropagation()}\n >\n <p className=\"font-inter text-[11px] font-semibold text-fg-primary mb-1.5\">{t('shortcuts.title')}</p>\n <KeyboardShortcutsList />\n </div>\n )}\n </div>\n )}\n </div>\n )}\n\n <div className=\"relative\" style={{ containerType: 'inline-size' }}>\n {/* `role=\"grid\"` sits on the grid element itself, not on the\n wrapper: the wrapper also holds the toolbar, and a button is\n not a valid child of a grid. It replaces the previous\n `role=\"application\"`, which suppressed the screen reader's\n reading mode without offering any structure in exchange. */}\n <div\n role=\"grid\"\n aria-label={t('boardAriaLabel')}\n aria-rowcount={ROWS}\n aria-colcount={COLS}\n className={cn(\n \"grid grid-cols-9 gap-[1px]\",\n keyboardNav && \"focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-accent-green\",\n )}\n {...(keyboardNav\n ? {\n tabIndex: 0,\n onKeyDown: handleKeyDown,\n 'aria-activedescendant': cursor ? cellId(cursor.x, cursor.y) : undefined,\n }\n : {})}\n >\n {renderRows()}\n </div>\n\n {/* Turf grain + stadium light: decorative, click-through. */}\n <GrassOverlay />\n\n {/* Chalk pitch lines — static, so the browser caches the filter as its own layer. */}\n <PitchMarkings />\n\n {/* Dynamic board-space overlays live in their own <svg> so hover\n repaints never re-run the chalk filter above. */}\n <svg\n viewBox=\"0 0 9 12\"\n preserveAspectRatio=\"none\"\n className=\"absolute inset-0 w-full h-full pointer-events-none\"\n aria-hidden=\"true\"\n >\n {hoveredPassAt && passCarrier && (\n <line\n data-testid=\"pass-trajectory-line\"\n x1={passCarrier.pos.x + 0.5}\n y1={ROWS - 1 - passCarrier.pos.y + 0.5}\n x2={hoveredPassAt.x + 0.5}\n y2={ROWS - 1 - hoveredPassAt.y + 0.5}\n stroke={trajectoryIntercepted ? 'var(--danger)' : 'var(--pass-highlight)'}\n strokeWidth=\"0.08\"\n strokeDasharray=\"0.15 0.1\"\n strokeLinecap=\"round\"\n />\n )}\n </svg>\n\n {/* Visual layer only: every piece is already announced by its\n grid cell, so exposing it twice would double the board. */}\n <div className=\"absolute inset-0 pointer-events-none\" data-testid=\"pieces-layer\" aria-hidden=\"true\">\n <AnimatePresence mode=\"sync\">\n {boardState.pieces.map(piece => {\n const isPickupCarrier = pickupCarrierId === piece.id\n const pieceTransition = isPickupCarrier\n ? { duration: PICKUP_DURATION, ease: 'linear' as const }\n : PIECE_SLIDE\n return (\n <motion.div\n key={piece.id}\n data-piece-id={piece.id}\n initial={false}\n animate={{ x: cellX(piece.pos.x), y: cellY(piece.pos.y) }}\n transition={pieceTransition}\n onAnimationStart={() => setMoving(piece.id, true)}\n onAnimationComplete={() => setMoving(piece.id, false)}\n style={{\n position: 'absolute',\n left: 0,\n top: 0,\n width: `${100 / COLS}%`,\n height: `${100 / ROWS}%`,\n willChange: 'transform',\n }}\n className=\"flex items-center justify-center pointer-events-auto\"\n >\n <GamePiece\n piece={piece}\n isSelected={selectedPieceId === piece.id}\n hasBall={boardState.ball.holderId === piece.id}\n isMoving={movingIds.has(piece.id)}\n onClick={(e: React.MouseEvent) => handlePieceClick(piece.id, piece.pos.x, piece.pos.y, e)}\n />\n </motion.div>\n )\n })}\n </AnimatePresence>\n\n {(() => {\n const targetX = cellX(ball.pos.x)\n const targetY = cellY(ball.pos.y)\n let animate: any\n let transition: any\n if (isPickupOnMove && prevBall) {\n const prevX = cellX(prevBall.pos.x)\n const prevY = cellY(prevBall.pos.y)\n const pulseStart = Math.max(0.05, pickupProportion - 0.06)\n animate = {\n x: [prevX, prevX, prevX, targetX],\n y: [prevY, prevY, prevY, targetY],\n scale: [1, 1, 1.35, 1],\n }\n transition = { duration: PICKUP_DURATION, times: [0, pulseStart, pickupProportion, 1], ease: 'linear' }\n } else {\n animate = { x: targetX, y: targetY, scale: 1 }\n transition = ball.holderId ? PIECE_SLIDE : BALL_SLIDE\n }\n return (\n <motion.div\n key=\"ball\"\n initial={false}\n animate={animate}\n transition={transition}\n style={{\n position: 'absolute',\n left: 0,\n top: 0,\n width: `${100 / COLS}%`,\n height: `${100 / ROWS}%`,\n zIndex: 50,\n willChange: 'transform',\n }}\n className=\"flex items-center justify-center pointer-events-none\"\n >\n <div className=\"w-[60%] h-[60%]\"><Football /></div>\n </motion.div>\n )\n })()}\n\n {/* §16: subtle shake feedback on an illegal move/pass target */}\n {invalidClickAt && (\n <motion.div\n key={invalidClickAt.nonce}\n data-testid=\"invalid-action-shake\"\n aria-hidden=\"true\"\n initial={false}\n animate={prefersReducedMotion ? { opacity: [0.9, 0] } : { x: [0, -3, 3, -3, 3, 0] }}\n transition={{ duration: 0.08 }}\n style={{\n position: 'absolute',\n left: `${(invalidClickAt.x / COLS) * 100}%`,\n top: `${((ROWS - 1 - invalidClickAt.y) / ROWS) * 100}%`,\n width: `${100 / COLS}%`,\n height: `${100 / ROWS}%`,\n }}\n className=\"ring-2 ring-inset ring-danger/70 rounded-sm\"\n />\n )}\n </div>\n\n {/* §8: Offside warning chip overlaid on board bottom */}\n {isOffsideRisk && (\n <div className=\"absolute bottom-2 left-1/2 -translate-x-1/2 z-30 flex items-center gap-1.5 px-3 py-1.5 bg-warning/20 border border-warning/50 rounded-full font-inter text-xs font-semibold text-warning pointer-events-none whitespace-nowrap backdrop-blur-sm\">\n ⚠ {t('offsideWarning')}\n </div>\n )}\n\n </div>\n </div>\n )\n\n if (!showCoordinates) return board\n\n const ranksTopToBottom = [...RANK_LABELS].reverse()\n return (\n <div className={cn('w-full max-w-[540px] md:max-w-none mx-auto', className)}>\n <div\n className=\"grid gap-1 select-none\"\n style={{\n gridTemplateColumns: '20px 1fr 20px',\n gridTemplateRows: '14px 1fr 14px',\n }}\n >\n <span aria-hidden=\"true\" />\n <FileRow files={FILE_LABELS} />\n <span aria-hidden=\"true\" />\n\n <RankColumn ranks={ranksTopToBottom} />\n <div>{board}</div>\n <RankColumn ranks={ranksTopToBottom} />\n\n <span aria-hidden=\"true\" />\n <FileRow files={FILE_LABELS} />\n <span aria-hidden=\"true\" />\n </div>\n </div>\n )\n}\n\nfunction FileRow({ files }: { files: readonly string[] }) {\n return (\n <div className=\"grid grid-cols-9 gap-[1px] px-[2px]\">\n {files.map(f => (\n <span key={f} aria-hidden=\"true\" className=\"flex items-center justify-center font-mono text-[9px] text-fg-muted/80 uppercase tracking-[0.5px]\">\n {f}\n </span>\n ))}\n </div>\n )\n}\n\nfunction RankColumn({ ranks }: { ranks: readonly number[] }) {\n return (\n <div className=\"grid grid-rows-12 gap-[1px] py-[2px]\">\n {ranks.map(r => (\n <span key={r} aria-hidden=\"true\" className=\"flex items-center justify-center font-mono text-[9px] text-fg-muted/80 tabular-nums\">\n {r}\n </span>\n ))}\n </div>\n )\n}\n","import { useEffect, useState, type ReactNode } from 'react'\nimport { cn } from '../../lib/utils'\n\ninterface AvatarProps { className?: string; children: ReactNode }\ninterface AvatarImageProps { src?: string; alt?: string; className?: string }\ninterface AvatarFallbackProps { className?: string; children: ReactNode }\n\nexport function Avatar({ className, children }: AvatarProps) {\n return <div className={cn('relative w-9 h-9 rounded-full overflow-hidden shrink-0', className)}>{children}</div>\n}\n\nexport function AvatarImage({ src, alt, className }: AvatarImageProps) {\n // Without onError a broken URL renders an empty box stacked over the initials\n // fallback, so the fallback never shows. Drop out and let it through.\n const [failed, setFailed] = useState(false)\n useEffect(() => { setFailed(false) }, [src])\n\n if (!src || failed) return null\n return (\n <img\n src={src}\n alt={alt ?? ''}\n onError={() => setFailed(true)}\n className={cn('w-full h-full object-cover', className)}\n />\n )\n}\n\nexport function AvatarFallback({ className, children }: AvatarFallbackProps) {\n return (\n <div className={cn('absolute inset-0 flex items-center justify-center text-xs font-semibold', className)}>\n {children}\n </div>\n )\n}\n","import { useEffect, useRef, useState } from 'react'\nimport { motion } from 'framer-motion'\nimport { Zap, Crown } from 'lucide-react'\nimport { cn } from '../lib/utils'\nimport { useGameT } from '../i18n'\n\ninterface ActionPointsProps {\n total: number\n remaining: number\n size?: number\n className?: string\n kingMustRelease?: boolean\n}\n\nexport function ActionPoints({ total, remaining, size = 20, className, kingMustRelease }: ActionPointsProps) {\n const t = useGameT()\n\n // §16: brief \"spent\" pop on every pip that just went from active to inactive\n // (a forced turn end — interception, goal — can drop AP straight to 0, not\n // just by one). Cleared immediately if `remaining` rises again before the\n // pop finishes (an AP rollback), not left dangling for the old timeout.\n const prevRemainingRef = useRef(remaining)\n const [spentRange, setSpentRange] = useState<[number, number] | null>(null)\n useEffect(() => {\n const prev = prevRemainingRef.current\n prevRemainingRef.current = remaining\n if (remaining < prev) {\n setSpentRange([remaining, prev - 1])\n const id = setTimeout(() => setSpentRange(null), 300)\n return () => clearTimeout(id)\n }\n setSpentRange(null)\n }, [remaining])\n\n return (\n <div className={cn('flex items-center gap-1.5', className)} aria-label={t('actionPointsAriaLabel', { remaining, total })}>\n {Array.from({ length: total }).map((_, i) => {\n const isActive = i < remaining\n const showCrown = kingMustRelease && i === total - 1\n const justSpent = !!spentRange && i >= spentRange[0] && i <= spentRange[1]\n\n return (\n <motion.span\n key={i}\n data-testid={`ap-pip-${i}`}\n data-spent={justSpent || undefined}\n className=\"inline-flex\"\n animate={justSpent ? { scale: [1.5, 1] } : undefined}\n transition={{ duration: 0.3 }}\n >\n {showCrown ? (\n <Crown\n size={size}\n strokeWidth={2}\n className=\"text-yellow-400 fill-yellow-400 transition-colors duration-150\"\n aria-hidden=\"true\"\n />\n ) : (\n <Zap\n size={size}\n strokeWidth={2}\n className={cn(\n 'transition-colors duration-150',\n isActive ? 'text-accent-green fill-accent-green' : 'text-fg-muted fill-none',\n )}\n aria-hidden=\"true\"\n />\n )}\n </motion.span>\n )\n })}\n </div>\n )\n}\n","import { cn } from '../../lib/utils'\n\ninterface PlayerIdentityProps {\n name: string\n team: string\n /**\n * `full` — the side panels and the mobile scoreboard: name on its own line,\n * team beneath it. `compact` — the tablet/desktop mini-scoreboard, where the\n * pair shares one line.\n */\n variant?: 'full' | 'compact'\n isActive?: boolean\n align?: 'left' | 'right'\n /** Rendered inline after the team label (e.g. the active-turn pulse dot). */\n adornment?: React.ReactNode\n className?: string\n}\n\n/**\n * One player's name and team.\n *\n * `Scoreboard` set this in Inter 13px semibold with the team in mono 10px, and\n * `MiniScoreboard` in mono 10px uppercase joined by a middot — so the same\n * player changed appearance on a viewport change. Both now render this, and the\n * only difference left is the deliberate one: how much room there is.\n */\nexport function PlayerIdentity({\n name,\n team,\n variant = 'full',\n isActive = false,\n align = 'left',\n adornment,\n className,\n}: PlayerIdentityProps) {\n if (variant === 'compact') {\n return (\n <span\n className={cn(\n 'font-inter text-[11px] font-medium truncate max-w-[160px]',\n isActive ? 'text-fg-secondary' : 'text-fg-muted',\n className,\n )}\n >\n {name}\n <span className=\"font-mono uppercase tracking-[0.5px] text-fg-muted\"> · {team}</span>\n </span>\n )\n }\n\n return (\n <div className={cn('flex flex-col gap-1 min-w-0', align === 'right' && 'items-end', className)}>\n <span\n className={cn(\n 'font-inter text-[13px] font-semibold leading-none truncate transition-colors duration-300',\n isActive ? 'text-fg-primary' : 'text-fg-muted',\n )}\n >\n {name}\n </span>\n <div className={cn('flex items-center gap-1', align === 'right' && 'flex-row-reverse')}>\n <span className=\"font-mono text-[10px] text-fg-muted uppercase tracking-[0.5px]\">{team}</span>\n {adornment}\n </div>\n </div>\n )\n}\n","import { useGameStore, DEFAULT_MAX_AP } from '../../store/use-game-store'\nimport { cn } from '../../lib/utils'\nimport { Avatar, AvatarFallback, AvatarImage } from '../ui/avatar'\nimport { ActionPoints } from '../action-points'\nimport { useGameT } from '../../i18n'\nimport { PlayerIdentity } from './player-identity'\n\ninterface ScoreboardProps {\n creatorUsername: string\n opponentUsername: string\n creatorAvatarUrl?: string\n opponentAvatarUrl?: string\n userSide?: 'white' | 'black' | null\n className?: string\n}\n\nfunction initials(name: string) {\n return (name?.split(' ').map(w => w[0]).join('').toUpperCase() || '?').slice(0, 2)\n}\n\nexport default function Scoreboard({\n creatorUsername,\n opponentUsername,\n creatorAvatarUrl,\n opponentAvatarUrl,\n userSide,\n className,\n}: ScoreboardProps) {\n const t = useGameT()\n const boardState = useGameStore(s => s.boardState)\n if (!boardState?.score) return null\n\n const { score, turn, actionPoints, kingMustRelease } = boardState\n\n // El creador siempre juega con blancas\n const myScore = userSide === 'white' ? score.white : score.black\n const rivalScore = userSide === 'white' ? score.black : score.white\n const myName = userSide === 'white' ? creatorUsername : opponentUsername\n const rivalName = userSide === 'white' ? opponentUsername : creatorUsername\n const myAvatar = userSide === 'white' ? creatorAvatarUrl : opponentAvatarUrl\n const rivalAvatar= userSide === 'white' ? opponentAvatarUrl : creatorAvatarUrl\n const myTeam = userSide === 'white' ? t('teamWhite') : t('teamBlack')\n const rivalTeam = userSide === 'white' ? t('teamBlack') : t('teamWhite')\n const isMyTurn = turn === userSide\n const myKingMustRelease = isMyTurn && kingMustRelease === turn\n const rivalKingMustRelease = !isMyTurn && kingMustRelease === turn\n\n const maxAP = boardState.maxActionPoints ?? DEFAULT_MAX_AP\n\n return (\n <div className={cn('w-full bg-bg-secondary flex items-center justify-between px-5 py-2.5', className)}>\n {/* Jugador local */}\n <PlayerInfo\n name={myName}\n team={myTeam}\n avatarUrl={myAvatar}\n isActive={isMyTurn}\n actionPoints={isMyTurn ? actionPoints : 0}\n maxActionPoints={maxAP}\n kingMustRelease={myKingMustRelease}\n align=\"left\"\n />\n\n {/* Marcador central. La región live lleva el texto en un `sr-only` en vez\n de un `aria-label`: un `aria-label` sobre una región live silencia su\n contenido y el lector nunca llegaría a anunciar el gol. */}\n <div role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" className=\"flex items-center gap-3\">\n <span aria-hidden=\"true\" className=\"font-anton text-[32px] leading-none text-fg-primary tabular-nums\">\n {myScore}\n </span>\n <span aria-hidden=\"true\" className=\"font-anton text-2xl text-fg-muted\">—</span>\n <span aria-hidden=\"true\" className=\"font-anton text-[32px] leading-none text-fg-primary tabular-nums\">\n {rivalScore}\n </span>\n <span className=\"sr-only\">\n {t('scoreAriaLabel', { me: myName, myScore, rival: rivalName, rivalScore })}\n </span>\n </div>\n\n {/* Rival */}\n <PlayerInfo\n name={rivalName}\n team={rivalTeam}\n avatarUrl={rivalAvatar}\n isActive={!isMyTurn}\n actionPoints={!isMyTurn ? actionPoints : 0}\n maxActionPoints={maxAP}\n kingMustRelease={rivalKingMustRelease}\n align=\"right\"\n />\n </div>\n )\n}\n\ninterface PlayerInfoProps {\n name: string\n team: string\n avatarUrl?: string\n isActive: boolean\n actionPoints: number\n maxActionPoints: number\n kingMustRelease: boolean\n align: 'left' | 'right'\n}\n\nfunction PlayerInfo({ name, team, avatarUrl, isActive, actionPoints, maxActionPoints, kingMustRelease, align }: PlayerInfoProps) {\n return (\n <div className={cn('flex items-center gap-2.5', align === 'right' && 'flex-row-reverse')}>\n <Avatar className={cn(\n 'w-9 h-9 border-2 transition-colors duration-300',\n isActive ? 'border-accent-green' : 'border-border-subtle'\n )}>\n <AvatarImage src={avatarUrl} alt={name} className=\"object-cover\" />\n <AvatarFallback className=\"bg-bg-surface-elevated text-fg-secondary text-xs font-semibold\">\n {initials(name)}\n </AvatarFallback>\n </Avatar>\n\n <div className={cn('flex flex-col gap-1', align === 'right' && 'items-end')}>\n <PlayerIdentity\n name={name}\n team={team}\n isActive={isActive}\n align={align}\n adornment={isActive ? (\n <span className=\"w-1.5 h-1.5 rounded-full bg-accent-green animate-pulse motion-reduce:animate-none\" aria-hidden=\"true\" />\n ) : undefined}\n />\n <ActionPoints\n total={maxActionPoints}\n remaining={actionPoints}\n size={12}\n kingMustRelease={kingMustRelease}\n className=\"gap-0.5\"\n />\n </div>\n </div>\n )\n}\n","import { useGameStore } from '../../store/use-game-store'\nimport { cn } from '../../lib/utils'\nimport { useGameT } from '../../i18n'\nimport { PlayerIdentity } from './player-identity'\n\ninterface MiniScoreboardProps {\n creatorUsername: string\n opponentUsername: string\n userSide?: 'white' | 'black' | null\n className?: string\n}\n\n/**\n * Compact scoreboard shown above the board on tablet/desktop. Renders only the\n * grouped name + score per side — no avatars, since the side panels already show them.\n */\nexport function MiniScoreboard({\n creatorUsername,\n opponentUsername,\n userSide,\n className,\n}: MiniScoreboardProps) {\n const t = useGameT()\n const boardState = useGameStore(s => s.boardState)\n if (!boardState?.score) return null\n\n const { score, turn } = boardState\n\n const myScore = userSide === 'white' ? score.white : score.black\n const rivalScore = userSide === 'white' ? score.black : score.white\n const myName = userSide === 'white' ? creatorUsername : opponentUsername\n const rivalName = userSide === 'white' ? opponentUsername : creatorUsername\n const myTeam = userSide === 'white' ? t('teamWhite') : t('teamBlack')\n const rivalTeam = userSide === 'white' ? t('teamBlack') : t('teamWhite')\n const isMyTurn = turn === userSide\n\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n className={cn(\n 'w-full max-w-[540px] rounded-xl bg-bg-surface border border-border-subtle',\n 'flex items-center justify-between gap-4 px-5 py-3',\n className,\n )}\n >\n {/* El bloque visual se oculta al lector y se sustituye por una única\n frase con nombres y marcador: leído celda a celda, \"2\" \"vs\" \"1\"\n no dice de quién es cada cifra. */}\n <div className=\"contents\" aria-hidden=\"true\">\n <SideCell name={myName} team={myTeam} score={myScore} isActive={isMyTurn} align=\"left\" />\n\n <span className=\"font-anton text-base text-fg-muted uppercase tracking-[2px]\">\n vs\n </span>\n\n <SideCell name={rivalName} team={rivalTeam} score={rivalScore} isActive={!isMyTurn} align=\"right\" />\n </div>\n\n <span className=\"sr-only\">\n {t('scoreAriaLabel', { me: myName, myScore, rival: rivalName, rivalScore })}\n </span>\n </div>\n )\n}\n\ninterface SideCellProps {\n name: string\n team: string\n score: number\n isActive: boolean\n align: 'left' | 'right'\n}\n\nfunction SideCell({ name, team, score, isActive, align }: SideCellProps) {\n return (\n <div className={cn('flex flex-col min-w-0', align === 'right' ? 'items-end' : 'items-start')}>\n <PlayerIdentity name={name} team={team} variant=\"compact\" isActive={isActive} />\n <span className={cn(\n 'font-anton text-[32px] leading-none tabular-nums',\n isActive ? 'text-fg-primary' : 'text-fg-secondary',\n )}>\n {score}\n </span>\n </div>\n )\n}\n","import * as React from 'react'\nimport { cn } from '../../lib/utils'\n\ntype Variant = 'primary' | 'secondary' | 'ghost' | 'destructive'\ntype Size = 'default' | 'sm' | 'lg' | 'icon'\n\nconst VARIANT: Record<Variant, string> = {\n // White on `--accent-green` is 4.27:1 — under WCAG AA for the Anton 400 the\n // primary CTA is set in. `--accent-green-dark` clears it (~6.5:1), so the\n // resting state is the dark green and interaction brightens it rather than\n // darkening it. Hover/active are transient; the resting state is the one a\n // player reads.\n primary:\n 'bg-accent-green-dark text-fg-primary font-anton tracking-widest rounded-md ' +\n 'hover:bg-accent-green active:bg-accent-green-light',\n secondary:\n 'bg-bg-surface text-fg-primary font-inter font-semibold rounded-md ' +\n 'border border-border-subtle hover:bg-bg-surface-elevated active:bg-bg-secondary',\n ghost:\n 'bg-transparent text-fg-secondary font-inter font-medium rounded-md ' +\n 'hover:text-fg-primary active:text-fg-muted',\n destructive:\n 'bg-danger/10 text-danger font-inter font-semibold rounded-md ' +\n 'border border-danger hover:bg-danger/20 active:bg-danger/30',\n}\n\nconst SIZE: Record<Size, string> = {\n default: 'h-12 min-h-[44px] px-6 text-base',\n sm: 'h-9 min-h-[36px] px-4 text-sm',\n lg: 'h-13 min-h-[52px] px-8 text-lg',\n icon: 'h-11 w-11 min-h-[44px]',\n}\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: Variant\n size?: Size\n}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant = 'primary', size = 'default', ...props }, ref) => (\n <button\n ref={ref}\n className={cn(\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap transition-all duration-150',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-green focus-visible:ring-offset-2 focus-visible:ring-offset-bg-primary',\n 'disabled:pointer-events-none disabled:opacity-40',\n '[&_svg]:pointer-events-none [&_svg]:shrink-0',\n VARIANT[variant],\n SIZE[size],\n className,\n )}\n {...props}\n />\n ),\n)\nButton.displayName = 'Button'\n","import { useEffect, useRef } from 'react'\n\n/**\n * Selector for the elements a modal's Tab cycle may land on. `[tabindex=\"-1\"]`\n * is deliberately excluded: programmatically focusable nodes (like the panel\n * itself) must not become Tab stops.\n */\nconst FOCUSABLE = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(',')\n\n/**\n * Deliberately not an `offsetParent` check: that is `null` for anything inside a\n * `position: fixed` subtree (which every one of these dialogs is) and always\n * `null` under jsdom. Attribute-level hiding is what actually matters here.\n */\nfunction focusableWithin(panel: HTMLElement): HTMLElement[] {\n return Array.from(panel.querySelectorAll<HTMLElement>(FOCUSABLE)).filter(\n el => !el.closest('[hidden]') && !el.closest('[aria-hidden=\"true\"]'),\n )\n}\n\ninterface DialogA11yOptions {\n open: boolean\n onClose: () => void\n}\n\n/**\n * The four behaviours `aria-modal=\"true\"` promises but does not implement.\n * Declaring `aria-modal` without them is worse than not declaring it at all:\n * assistive tech stops exposing the page behind the dialog while the keyboard\n * happily walks straight into it.\n *\n * 1. Initial focus — the first focusable control, or the panel itself.\n * 2. Focus trap — Tab / Shift+Tab cycle inside the panel.\n * 3. Escape closes.\n * 4. Focus returns to whatever opened the dialog.\n *\n * Attach the returned ref to the dialog panel (the node carrying `role=\"dialog\"`).\n */\nexport function useDialogA11y({ open, onClose }: DialogA11yOptions) {\n const panelRef = useRef<HTMLDivElement | null>(null)\n const restoreToRef = useRef<HTMLElement | null>(null)\n\n // `onClose` is nearly always an inline arrow: keep it in a ref so the\n // key listener isn't torn down and re-attached on every parent render.\n const onCloseRef = useRef(onClose)\n useEffect(() => { onCloseRef.current = onClose })\n\n useEffect(() => {\n if (!open) return\n const panel = panelRef.current\n if (!panel) return\n\n restoreToRef.current = document.activeElement as HTMLElement | null\n\n const initial = focusableWithin(panel)[0]\n if (initial) {\n initial.focus()\n } else {\n panel.tabIndex = -1\n panel.focus()\n }\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.stopPropagation()\n onCloseRef.current()\n return\n }\n if (e.key !== 'Tab') return\n\n const items = focusableWithin(panel)\n if (items.length === 0) {\n e.preventDefault()\n return\n }\n const first = items[0]\n const last = items[items.length - 1]\n const active = document.activeElement\n\n if (e.shiftKey && (active === first || !panel.contains(active))) {\n e.preventDefault()\n last.focus()\n } else if (!e.shiftKey && (active === last || !panel.contains(active))) {\n e.preventDefault()\n first.focus()\n }\n }\n\n document.addEventListener('keydown', onKeyDown, true)\n return () => {\n document.removeEventListener('keydown', onKeyDown, true)\n restoreToRef.current?.focus?.()\n }\n }, [open])\n\n return panelRef\n}\n","import { useId } from 'react'\nimport { cn } from '../../lib/utils'\nimport { useDialogA11y } from '../../lib/use-dialog-a11y'\nimport { Button } from './button'\n\ninterface ConfirmDialogProps {\n open: boolean\n title: string\n description?: string\n confirmLabel: string\n cancelLabel: string\n onConfirm: () => void\n onCancel: () => void\n}\n\nexport function ConfirmDialog({ open, title, description, confirmLabel, cancelLabel, onConfirm, onCancel }: ConfirmDialogProps) {\n const baseId = useId()\n const titleId = `${baseId}-title`\n const descId = `${baseId}-desc`\n // Escape and the backdrop resolve to the same outcome as the cancel button:\n // the dialog is a question, and dismissing it is answering \"no\".\n const panelRef = useDialogA11y({ open, onClose: onCancel })\n\n if (!open) return null\n return (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm\"\n onClick={onCancel}\n >\n <div\n ref={panelRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n aria-describedby={description ? descId : undefined}\n onClick={e => e.stopPropagation()}\n className={cn(\n 'bg-bg-surface border border-border-subtle rounded-xl p-6 mx-4 max-w-sm w-full',\n 'flex flex-col gap-4 shadow-2xl',\n 'focus:outline-none',\n )}\n >\n <h2 id={titleId} className=\"font-anton text-lg text-fg-primary uppercase tracking-wide\">{title}</h2>\n {description && <p id={descId} className=\"font-inter text-sm text-fg-secondary\">{description}</p>}\n <div className=\"flex gap-2 pt-1\">\n <Button variant=\"secondary\" className=\"flex-1\" onClick={onCancel}>{cancelLabel}</Button>\n <Button variant=\"primary\" className=\"flex-1\" onClick={onConfirm}>{confirmLabel}</Button>\n </div>\n </div>\n </div>\n )\n}\n","import { useState } from 'react'\nimport { useGameStore } from '../../store/use-game-store'\nimport { Button } from '../ui/button'\nimport { ConfirmDialog } from '../ui/confirm-dialog'\nimport { Flag } from 'lucide-react'\nimport { cn } from '../../lib/utils'\nimport { useGameT } from '../../i18n'\n\ninterface GameControlsProps {\n isMyTurn: boolean\n className?: string\n}\n\nexport default function GameControls({ isMyTurn, className }: GameControlsProps) {\n const boardState = useGameStore(s => s.boardState)\n const endTurn = useGameStore(s => s.endTurn)\n\n const t = useGameT()\n const [showEndTurnConfirm, setShowEndTurnConfirm] = useState(false)\n\n if (!boardState) return null\n\n const actionPoints = boardState.actionPoints\n\n // Only ask for confirmation when ≥2 AP remain — with 0–1 AP left it's obvious\n const handleEndTurn = () => {\n if (actionPoints >= 2) {\n setShowEndTurnConfirm(true)\n } else {\n endTurn()\n }\n }\n\n return (\n <div className={cn('w-full bg-bg-secondary flex flex-col gap-3 px-5 pt-3 pb-5', className)}>\n {/* Finalizar turno */}\n {isMyTurn && (\n <Button\n variant=\"primary\"\n size=\"default\"\n className=\"w-full gap-2 tracking-[1.5px]\"\n onClick={handleEndTurn}\n >\n <Flag size={16} strokeWidth={2} />\n {t('endTurn')}\n {actionPoints >= 2 && (\n <span className={cn('ml-1 font-inter text-xs font-normal opacity-70 tracking-normal')}>\n · {actionPoints} {t('actionPointsShort')}\n </span>\n )}\n </Button>\n )}\n\n {/* Turno del rival */}\n {!isMyTurn && (\n <div\n role=\"status\"\n aria-live=\"polite\"\n className=\"flex items-center justify-center h-11 rounded-md bg-bg-surface border border-border-subtle\"\n >\n <span className=\"font-inter text-sm text-fg-muted\">{t('waitingRival')}</span>\n </div>\n )}\n\n <ConfirmDialog\n open={showEndTurnConfirm}\n title={t('endTurnConfirm')}\n description={t('endTurnConfirmDescription', { count: actionPoints })}\n confirmLabel={t('endTurnConfirmYes')}\n cancelLabel={t('endTurnKeepPlaying')}\n onConfirm={() => { endTurn(); setShowEndTurnConfirm(false) }}\n onCancel={() => setShowEndTurnConfirm(false)}\n />\n </div>\n )\n}\n","import {\n ChessKing,\n ChessQueen,\n ChessRook,\n ChessBishop,\n ChessKnight,\n ShieldQuestion,\n type LucideIcon,\n} from 'lucide-react'\nimport { useGameStore } from '../../store/use-game-store'\nimport { useShallow } from 'zustand/react/shallow'\nimport { Football } from './football'\nimport { cn } from '../../lib/utils'\nimport { LONG_KEY, squareName } from '@scriptonita/chess-football-engine'\nimport type { Piece, PieceType } from '@scriptonita/chess-football-engine'\nimport { useGameT } from '../../i18n'\n\nconst PIECE_ICON: Record<PieceType, LucideIcon> = {\n king: ChessKing,\n queen: ChessQueen,\n rook: ChessRook,\n bishop: ChessBishop,\n knight: ChessKnight,\n}\n\ninterface SelectedPieceDetailProps {\n isMyTurn: boolean\n className?: string\n}\n\n/**\n * Compact card that surfaces the selected piece's identity, position and current state.\n * Renders below the board on tablet/desktop to put the empty space to use.\n */\nexport function SelectedPieceDetail({ isMyTurn, className }: SelectedPieceDetailProps) {\n const t = useGameT()\n const { boardState, selectedPieceId } = useGameStore(\n useShallow(s => ({ boardState: s.boardState, selectedPieceId: s.selectedPieceId })),\n )\n\n if (!boardState) return null\n\n const piece: Piece | undefined = boardState.pieces.find(p => p.id === selectedPieceId)\n\n if (!piece) {\n return (\n <div\n className={cn(\n 'rounded-xl bg-bg-surface/40 border border-dashed border-border-subtle',\n 'px-4 py-3 flex items-center gap-3',\n className,\n )}\n >\n <ShieldQuestion size={20} className=\"text-fg-muted shrink-0\" aria-hidden=\"true\" />\n <span className=\"font-mono text-[11px] text-fg-muted\">\n {t('selectedPiece.empty')}\n </span>\n </div>\n )\n }\n\n const Icon = PIECE_ICON[piece.type] ?? ShieldQuestion\n const longName = t(`pieces.${LONG_KEY[piece.type]}`)\n const square = squareName(piece.pos)\n const hasBall = boardState.ball.holderId === piece.id\n const movedThisTurn = piece.hasMovedThisTurn && isMyTurn\n\n return (\n <div\n className={cn(\n 'rounded-xl bg-bg-surface border border-border-subtle',\n 'px-4 py-3 flex items-center gap-4',\n className,\n )}\n role=\"status\"\n aria-live=\"polite\"\n >\n <div\n className={cn(\n 'w-12 h-12 shrink-0 rounded-full flex items-center justify-center',\n piece.side === 'white' ? 'bg-white text-black' : 'bg-fg-primary/90 text-bg-primary',\n )}\n >\n <Icon size={26} strokeWidth={1.75} aria-hidden=\"true\" />\n </div>\n\n <div className=\"flex flex-col min-w-0 flex-1\">\n <span className=\"font-anton text-base text-fg-primary leading-none uppercase tracking-[0.5px]\">\n {longName}\n </span>\n <span className=\"font-mono text-[11px] text-fg-muted mt-1\">\n {t('selectedPiece.atSquare', { square })}\n </span>\n </div>\n\n <div className=\"flex flex-col items-end gap-1 shrink-0\">\n {hasBall && (\n <span className=\"flex items-center gap-1.5 font-mono text-[10px] text-pass-highlight uppercase tracking-[0.5px]\">\n <span className=\"w-3 h-3 inline-flex\">\n <Football />\n </span>\n {t('selectedPiece.hasBall')}\n </span>\n )}\n {movedThisTurn && (\n <span className=\"font-mono text-[10px] text-fg-muted uppercase tracking-[0.5px]\">\n {t('selectedPiece.alreadyMoved')}\n </span>\n )}\n </div>\n </div>\n )\n}\n","import { useEffect, useRef } from 'react'\nimport { useGameStore } from '../../store/use-game-store'\nimport { cn } from '../../lib/utils'\nimport { squareName, SHORT_KEY } from '@scriptonita/chess-football-engine'\nimport type { MoveHistoryEntry } from '@scriptonita/chess-football-engine'\nimport { useGameT } from '../../i18n'\n\ninterface MoveHistoryProps {\n /** When false, renders without the inner scroll wrapper (handy in tablet panels). */\n scrollable?: boolean\n /** Cap the number of entries displayed; useful in compact tablet panels. */\n limit?: number\n className?: string\n}\n\n/**\n * Move history list — chess-style notation grouped by turn.\n * Reads `boardState.moveHistory` and auto-scrolls to the latest entry.\n */\nexport function MoveHistory({ scrollable = true, limit, className }: MoveHistoryProps) {\n const t = useGameT()\n const boardState = useGameStore(s => s.boardState)\n const scrollRef = useRef<HTMLOListElement>(null)\n\n const history: MoveHistoryEntry[] = boardState?.moveHistory ?? []\n const visible = limit ? history.slice(-limit) : history\n // Latest at top of the list — easier to scan in narrow panels\n const ordered = [...visible].reverse()\n\n useEffect(() => {\n if (!scrollable) return\n if (scrollRef.current) scrollRef.current.scrollTop = 0\n }, [history.length, scrollable])\n\n if (ordered.length === 0) {\n return (\n <p\n className={cn(\n 'font-mono text-[11px] text-fg-muted text-center py-3 px-3',\n 'bg-bg-surface/40 rounded-md',\n className,\n )}\n >\n {t('history.empty')}\n </p>\n )\n }\n\n return (\n <ol\n ref={scrollRef}\n aria-label={t('history.title')}\n className={cn(\n 'flex flex-col gap-1',\n scrollable && 'h-full overflow-y-auto pr-1',\n className,\n )}\n >\n {ordered.map((entry, i) => {\n const isLatest = i === 0\n const prev = ordered[i - 1]\n const showTurnDivider = !prev || prev.turnNumber !== entry.turnNumber\n return (\n <li key={`${entry.at}-${i}`} className=\"flex flex-col gap-1\">\n {showTurnDivider && (\n <div\n className=\"flex items-center gap-2 pt-1\"\n aria-hidden={prev ? 'true' : undefined}\n >\n <span className=\"font-mono text-[9px] tracking-[1px] text-fg-muted uppercase\">\n {t('history.turn', { n: entry.turnNumber })}\n </span>\n <span className=\"flex-1 h-px bg-border-subtle/60\" />\n </div>\n )}\n <HistoryRow entry={entry} isLatest={isLatest} />\n </li>\n )\n })}\n </ol>\n )\n}\n\ninterface HistoryRowProps {\n entry: MoveHistoryEntry\n isLatest: boolean\n}\n\nfunction HistoryRow({ entry, isLatest }: HistoryRowProps) {\n const t = useGameT()\n const fromSq = entry.from ? squareName(entry.from) : '—'\n const toSq = squareName(entry.to)\n const pieceShort = t(`pieces.${SHORT_KEY[entry.pieceType]}`)\n\n let label: string\n switch (entry.type) {\n case 'pass':\n label = t('history.pass', { to: toSq })\n break\n case 'tackle':\n label = t('history.tackle', { to: toSq })\n break\n case 'interception':\n label = t('history.interception', { to: toSq })\n break\n case 'goal':\n label = t('history.goal', { from: fromSq, to: toSq })\n break\n case 'offside':\n label = t('history.offside', { from: fromSq })\n break\n case 'move':\n default:\n label = t('history.move', { piece: pieceShort, from: fromSq, to: toSq })\n }\n\n const dotColor =\n entry.type === 'goal' ? 'bg-accent-green' :\n entry.type === 'pass' ? 'bg-pass-highlight' :\n entry.type === 'interception' ? 'bg-danger' :\n entry.type === 'tackle' ? 'bg-danger/80' :\n entry.type === 'offside' ? 'bg-warning' :\n 'bg-move-highlight'\n\n return (\n <div\n className={cn(\n 'flex items-center gap-2.5 min-h-[32px] px-3 py-1.5 rounded-md',\n 'font-mono text-[11px] leading-tight',\n isLatest\n ? 'bg-bg-surface-elevated text-fg-primary'\n : 'bg-bg-surface/60 text-fg-secondary',\n entry.pieceSide === 'black' && 'border-l-2 border-l-fg-primary/30',\n entry.pieceSide === 'white' && 'border-l-2 border-l-fg-primary/80',\n )}\n >\n <span\n aria-hidden=\"true\"\n className={cn('w-1.5 h-1.5 rounded-full shrink-0', dotColor)}\n />\n <span className=\"truncate flex-1\">{label}</span>\n {entry.type === 'goal' && (\n <span className=\"font-anton text-[10px] tracking-[1px] uppercase text-accent-green\">\n GOL\n </span>\n )}\n </div>\n )\n}\n","import { cn } from '../../lib/utils'\nimport { useMemo } from 'react'\nimport { getInitialBoardState } from '../../store/use-game-store'\nimport { Football } from './football'\nimport GamePiece from './game-piece'\nimport { PitchSurface } from './pitch'\n\nconst COLS = 9\nconst ROWS = 12\n\nexport function StaticGameBoard({ className }: { className?: string } = {}) {\n const boardState = useMemo(() => getInitialBoardState('white'), [])\n\n return (\n <div className={cn('relative w-full overflow-hidden rounded-xl shadow-2xl border-4 border-field-frame bg-field-frame', className)}>\n <PitchSurface>\n <div className=\"absolute inset-0 pointer-events-none\">\n {boardState.pieces.map(piece => (\n <div\n key={piece.id}\n style={{\n position: 'absolute',\n left: `${(piece.pos.x / COLS) * 100}%`,\n top: `${((ROWS - 1 - piece.pos.y) / ROWS) * 100}%`,\n width: `${100 / COLS}%`,\n height: `${100 / ROWS}%`,\n }}\n className=\"flex items-center justify-center\"\n >\n <GamePiece\n piece={piece}\n isSelected={false}\n hasBall={boardState.ball.holderId === piece.id}\n onClick={() => { }}\n />\n </div>\n ))}\n </div>\n </PitchSurface>\n\n {/* Ball rendered OUTSIDE the containerType wrapper to escape its stacking context */}\n <div\n style={{\n position: 'absolute',\n left: `${(boardState.ball.pos.x / COLS) * 100}%`,\n top: `${((ROWS - 1 - boardState.ball.pos.y) / ROWS) * 100}%`,\n width: `${100 / COLS}%`,\n height: `${100 / ROWS}%`,\n zIndex: 50,\n }}\n className=\"flex items-center justify-center pointer-events-none\"\n >\n <div className=\"w-[60%] h-[60%]\">\n <Football />\n </div>\n </div>\n </div>\n )\n}\n","import { useGameStore, DEFAULT_MAX_AP } from '../../store/use-game-store'\nimport { cn } from '../../lib/utils'\nimport { useGameT } from '../../i18n'\nimport { Zap } from 'lucide-react'\n\ninterface TurnBannerProps {\n isMyTurn: boolean\n /** Override for the \"not my turn\" label (e.g. \"Bot pensando…\" in training mode). */\n waitingLabel?: string\n className?: string\n}\n\n/**\n * Full-width banner showing whose turn it is.\n * - My turn: accent-green background + \"TU TURNO\" + AP counter\n * - Opponent: neutral background + waiting label\n *\n * Absorbs the floating \"Bot pensando…\" toast in training mode when waitingLabel is set.\n */\nexport function TurnBanner({ isMyTurn, waitingLabel, className }: TurnBannerProps) {\n const t = useGameT()\n const boardState = useGameStore(s => s.boardState)\n if (!boardState) return null\n\n const { actionPoints, turnNumber } = boardState\n const maxActionPoints = boardState.maxActionPoints ?? DEFAULT_MAX_AP\n\n return (\n <div\n className={cn(\n 'w-full h-9 flex items-center justify-between px-4 shrink-0 transition-colors duration-300',\n isMyTurn\n ? 'bg-accent-green/15 border-b border-accent-green/30'\n : 'bg-bg-surface border-b border-border-subtle',\n className,\n )}\n aria-live=\"polite\"\n aria-atomic=\"true\"\n >\n <div className=\"flex items-baseline gap-2 min-w-0\">\n <span\n className={cn(\n 'font-anton text-sm tracking-[1.5px] uppercase truncate',\n isMyTurn ? 'text-accent-green' : 'text-fg-muted',\n )}\n >\n {isMyTurn ? t('yourTurn') : (waitingLabel ?? t('waitingRival'))}\n </span>\n {/* In a correspondence game \"you are on turn 14\" is first-order\n information. The engine exposes it and nothing rendered it. */}\n {typeof turnNumber === 'number' && (\n <span className=\"font-mono text-[10px] text-fg-muted uppercase tracking-[0.5px] shrink-0\">\n {t('history.turn', { n: turnNumber })}\n </span>\n )}\n </div>\n\n {isMyTurn && (\n <div className=\"flex items-center gap-1\" aria-label={t('actionPointsAriaLabel', { remaining: actionPoints, total: maxActionPoints })}>\n <Zap size={12} className=\"text-accent-green\" aria-hidden=\"true\" />\n <span className=\"font-mono text-xs text-fg-secondary tabular-nums\">\n {actionPoints}/{maxActionPoints}\n </span>\n </div>\n )}\n </div>\n )\n}\n","import { useEffect, useState } from 'react'\nimport { useGameStore } from '../../store/use-game-store'\nimport { cn } from '../../lib/utils'\nimport { AnimatePresence, motion } from 'framer-motion'\nimport { useGameT } from '../../i18n'\n\ninterface EventToastProps {\n className?: string\n}\n\ntype ToastEvent = 'goal' | 'interception' | 'offside' | 'tackle'\n\nconst TOASTABLE: ReadonlySet<string> = new Set<ToastEvent>(['goal', 'interception', 'offside', 'tackle'])\n\nconst TOAST_CONFIG: Record<ToastEvent, string> = {\n goal: 'bg-accent-green/20 border-accent-green/60 text-accent-green-light',\n interception: 'bg-danger/20 border-danger/50 text-danger',\n offside: 'bg-warning/20 border-warning/50 text-warning',\n tackle: 'bg-warning/20 border-warning/50 text-warning',\n}\n\nexport function EventToast({ className }: EventToastProps) {\n const t = useGameT()\n const boardState = useGameStore(s => s.boardState)\n const [toast, setToast] = useState<{ type: ToastEvent; key: string } | null>(null)\n\n useEffect(() => {\n const lastMove = boardState?.lastMove\n if (!lastMove) return\n if (!TOASTABLE.has(lastMove.type)) return\n setToast({ type: lastMove.type as ToastEvent, key: String(lastMove.at) })\n }, [boardState?.lastMove?.at])\n\n useEffect(() => {\n if (!toast) return\n const timer = setTimeout(() => setToast(null), 2500)\n return () => clearTimeout(timer)\n }, [toast?.key])\n\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n className={cn('pointer-events-none flex justify-center', className)}\n >\n <AnimatePresence mode=\"wait\">\n {toast && (\n <motion.div\n key={toast.key}\n initial={{ opacity: 0, y: -8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -8 }}\n transition={{ duration: 0.15 }}\n className={cn(\n 'px-4 py-2 rounded-full border font-inter text-sm font-semibold shadow-lg backdrop-blur-sm text-center',\n TOAST_CONFIG[toast.type],\n )}\n >\n {t(`eventToast.${toast.type}`)}\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n )\n}\n","import { useId, useState } from 'react'\nimport { useGameStore } from '../../store/use-game-store'\nimport { cn } from '../../lib/utils'\nimport { AnimatePresence, motion } from 'framer-motion'\nimport { MoveHistory } from './move-history'\nimport { squareName, SHORT_KEY } from '@scriptonita/chess-football-engine'\nimport type { MoveHistoryEntry } from '@scriptonita/chess-football-engine'\nimport { useGameT } from '../../i18n'\nimport { useDialogA11y } from '../../lib/use-dialog-a11y'\nimport { X } from 'lucide-react'\n\ninterface MobileHistoryProps {\n className?: string\n}\n\nexport function MobileHistory({ className }: MobileHistoryProps) {\n const boardState = useGameStore(s => s.boardState)\n const [open, setOpen] = useState(false)\n const titleId = `${useId()}-title`\n const panelRef = useDialogA11y({ open, onClose: () => setOpen(false) })\n\n const lastMove = boardState?.moveHistory?.at(-1)\n\n if (!lastMove) return null\n\n return (\n <>\n <HistoryChip lastMove={lastMove} onClick={() => setOpen(true)} className={className} />\n\n <AnimatePresence>\n {open && (\n <>\n <motion.div\n key=\"backdrop\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.2 }}\n className=\"fixed inset-0 z-40 bg-black/60 backdrop-blur-sm\"\n onClick={() => setOpen(false)}\n aria-hidden=\"true\"\n />\n <motion.div\n key=\"sheet\"\n initial={{ y: '100%' }}\n animate={{ y: 0 }}\n exit={{ y: '100%' }}\n transition={{ type: 'spring', stiffness: 300, damping: 32 }}\n ref={panelRef}\n className=\"fixed bottom-0 left-0 right-0 z-50 bg-bg-secondary rounded-t-2xl border-t border-border-subtle shadow-xl focus:outline-none\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n >\n <SheetHeader titleId={titleId} onClose={() => setOpen(false)} />\n <div className=\"px-4 pb-6 max-h-[50dvh] overflow-y-auto\">\n <MoveHistory scrollable={false} />\n </div>\n </motion.div>\n </>\n )}\n </AnimatePresence>\n </>\n )\n}\n\nfunction SheetHeader({ titleId, onClose }: { titleId: string; onClose: () => void }) {\n const t = useGameT()\n return (\n <div className=\"flex items-center justify-between px-5 pt-4 pb-3 border-b border-border-subtle\">\n <span id={titleId} className=\"font-mono text-[10px] tracking-[0.5px] uppercase text-fg-muted\">\n {t('history.title')}\n </span>\n <button\n onClick={onClose}\n className=\"w-8 h-8 flex items-center justify-center rounded-full bg-bg-surface hover:bg-bg-surface-elevated text-fg-muted hover:text-fg-primary transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-green\"\n aria-label={t('history.close')}\n >\n <X size={14} aria-hidden=\"true\" />\n </button>\n </div>\n )\n}\n\ninterface HistoryChipProps {\n lastMove: MoveHistoryEntry\n onClick: () => void\n className?: string\n}\n\nfunction HistoryChip({ lastMove, onClick, className }: HistoryChipProps) {\n const t = useGameT()\n const toSq = squareName(lastMove.to)\n let label: string\n switch (lastMove.type) {\n case 'pass': label = `⊕ ${toSq}`; break\n case 'tackle': label = `✕ ${toSq}`; break\n case 'interception': label = `⛔ ${toSq}`; break\n case 'goal': label = `⚽ GOL`; break\n case 'offside': label = `⚠ OFS`; break\n default: {\n const pieceShort = t(`pieces.${SHORT_KEY[lastMove.pieceType]}`)\n const fromSq = lastMove.from ? squareName(lastMove.from) : ''\n label = fromSq ? `${pieceShort}${fromSq}→${toSq}` : `${pieceShort}→${toSq}`\n }\n }\n\n return (\n <button\n onClick={onClick}\n className={cn(\n 'flex items-center gap-1.5 px-3 py-1.5 rounded-full',\n 'bg-bg-surface border border-border-subtle',\n 'font-mono text-[11px] text-fg-secondary',\n 'hover:text-fg-primary hover:bg-bg-surface-elevated active:scale-95',\n 'transition-all duration-150 motion-reduce:transition-none',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-green',\n className,\n )}\n aria-label={t('history.viewAll')}\n >\n <span>{label}</span>\n <span className=\"text-fg-muted text-[10px]\" aria-hidden=\"true\">▾</span>\n </button>\n )\n}\n","/**\n * Every CSS custom property the package's Tailwind classes resolve against.\n *\n * A token the host app does not define fails *silently*: Tailwind emits the\n * rule, the variable resolves to nothing, and the declaration is dropped. That\n * is how `--last-move-highlight` went missing in the CrazyGames SPA — the\n * last-move highlight and the bot's turn replay simply never rendered, with no\n * error anywhere.\n *\n * This is the visual counterpart to `GAME_I18N_KEYS`: assert it in each app.\n *\n * ```ts\n * import { REQUIRED_TOKENS } from '@scriptonita/chess-football-ui'\n *\n * const css = readFileSync('src/index.css', 'utf8')\n * expect(REQUIRED_TOKENS.filter(t => !css.includes(`${t}:`))).toEqual([])\n * ```\n */\nexport const REQUIRED_TOKENS = [\n // Surfaces\n '--bg-primary',\n '--bg-secondary',\n '--bg-surface',\n '--bg-surface-elevated',\n // Text\n '--fg-primary',\n '--fg-secondary',\n '--fg-muted',\n // Accent (the primary CTA rests on the dark step — see Button)\n '--accent-green',\n '--accent-green-light',\n '--accent-green-dark',\n // Borders\n '--border-subtle',\n // Semantic\n '--danger',\n '--warning',\n // Board\n '--field-green-1',\n '--field-green-2',\n '--field-frame',\n '--move-highlight',\n '--pass-highlight',\n '--last-move-highlight',\n] as const\n\nexport type RequiredToken = (typeof REQUIRED_TOKENS)[number]\n"]}
1
+ {"version":3,"sources":["../src/lib/utils.ts","../src/components/game/game-piece.tsx","../src/components/game/football.tsx","../src/i18n/index.tsx","../src/components/game/ball-holder-chip.tsx","../src/components/game/keyboard-shortcuts.tsx","../src/components/game/pitch.tsx","../src/components/game/game-board.tsx","../src/components/ui/avatar.tsx","../src/components/action-points.tsx","../src/components/game/player-identity.tsx","../src/components/game/scoreboard.tsx","../src/components/game/mini-scoreboard.tsx","../src/components/ui/button.tsx","../src/lib/use-dialog-a11y.ts","../src/components/ui/confirm-dialog.tsx","../src/components/game/game-controls.tsx","../src/components/game/selected-piece-detail.tsx","../src/components/game/move-history.tsx","../src/components/game/static-game-board.tsx","../src/components/game/turn-banner.tsx","../src/components/game/event-toast.tsx","../src/components/game/mobile-history.tsx","../src/components/game/game-hints.tsx","../src/hooks/use-bot-turn.ts","../src/tokens.ts"],"names":["twMerge","clsx","ChessKing","ChessQueen","ChessRook","ChessBishop","ChessKnight","ShieldQuestion","jsxs","jsx","useId","SHORT_KEY","LONG_KEY","createContext","MotionConfig","useContext","useGameStore","Fragment","useReducedMotion","useShallow","useState","useRef","useEffect","id","useMemo","getValidMoves","getValidPasses","isInEnemyArea","getPath","t","squareName","Move","HelpCircle","AnimatePresence","motion","RANK_LABELS","FILE_LABELS","Crown","Zap","DEFAULT_MAX_AP","React","Flag","PIECE_ICON","COLS","ROWS","getInitialBoardState","X","checkGoal","useCallback"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAOA,qBAAA,CAAQC,SAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACoBA,IAAM,UAAA,GAAgD;AAAA,EAClD,IAAA,EAAMC,qBAAA;AAAA,EACN,KAAA,EAAOC,sBAAA;AAAA,EACP,IAAA,EAAMC,qBAAA;AAAA,EACN,MAAA,EAAQC,uBAAA;AAAA,EACR,MAAA,EAAQC;AACZ,CAAA;AAKA,IAAM,aAAA,GAA+C;AAAA,EACjD,KAAA,EAAO,4FAAA;AAAA,EACP,KAAA,EAAO;AACX,CAAA;AAcO,IAAM,iBAAA,GAAmD;AAAA,EAC5D,KAAA,EAAO,SAAA;AAAA,EACP,KAAA,EAAO;AACX,CAAA;AAEO,IAAM,YAAY,CAAC,EAAE,MAAM,IAAA,EAAM,KAAA,GAAQ,OAAM,KAAqE;AACvH,EAAA,MAAM,IAAA,GAAO,UAAA,CAAW,IAAI,CAAA,IAAKC,0BAAA;AAGjC,EAAA,MAAM,KAAA,GAA6B;AAAA,IAC/B,KAAA,EAAO,2BAAA;AAAA,IACP,MAAA,EAAQ,2BAAA;AAAA,IACR,MAAA,EAAQ,cAAc,IAAI,CAAA;AAAA,IAC1B,GAAI,KAAA,GAAQ,EAAE,OAAO,iBAAA,CAAkB,IAAI,GAAE,GAAI;AAAA,GACrD;AACA,EAAA,sCAAQ,IAAA,EAAA,EAAK,KAAA,EAAc,WAAA,EAAa,CAAA,EAAG,eAAY,MAAA,EAAO,CAAA;AAClE,CAAA;AAMO,IAAM,iBAAA,GAAyC;AAAA,EAClD,UAAA,EAAY,2EAAA;AAAA,EACZ,SAAA,EAAW;AAAA,IACP,0CAAA;AAAA,IACA,mCAAA;AAAA,IACA,4BAAA;AAAA,IACA;AAAA,GACJ,CAAE,KAAK,IAAI,CAAA;AAAA,EACX,MAAA,EAAQ,4BAAA;AAAA,EACR,KAAA,EAAO;AACX,CAAA;AAEO,IAAM,iBAAA,GAAyC;AAAA,EAClD,UAAA,EAAY,2EAAA;AAAA,EACZ,SAAA,EAAW;AAAA,IACP,0CAAA;AAAA,IACA,kCAAA;AAAA,IACA,4BAAA;AAAA,IACA;AAAA,GACJ,CAAE,KAAK,IAAI,CAAA;AAAA,EACX,MAAA,EAAQ,4BAAA;AAAA,EACR,KAAA,EAAO;AACX,CAAA;AAKA,IAAM,mBAAA,GAAkE;AAAA,EACpE,KAAA,EAAO;AAAA,IACH,GAAG,iBAAA;AAAA,IACH,SAAA,EAAW;AAAA,MACP,0CAAA;AAAA,MACA,mCAAA;AAAA,MACA;AAAA,KACJ,CAAE,KAAK,IAAI;AAAA,GACf;AAAA,EACA,KAAA,EAAO;AAAA,IACH,GAAG,iBAAA;AAAA,IACH,SAAA,EAAW;AAAA,MACP,0CAAA;AAAA,MACA,kCAAA;AAAA,MACA;AAAA,KACJ,CAAE,KAAK,IAAI;AAAA;AAEnB,CAAA;AAEe,SAAR,SAAA,CAA2B,EAAE,KAAA,EAAO,UAAA,EAAY,SAAS,OAAA,EAAS,QAAA,GAAW,OAAM,EAAmB;AACzG,EAAA,MAAM,SAAA,GAAY,mBAAA,CAAoB,KAAA,CAAM,IAAI,CAAA;AAEhD,EAAA,uBACIC,eAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACG,OAAA;AAAA,MACA,YAAA,EAAY,KAAA,CAAM,gBAAA,GAAmB,MAAA,GAAS,OAAA;AAAA,MAC9C,SAAA,EAAW,EAAA;AAAA,QACP,oIAAA;AAAA;AAAA;AAAA;AAAA,QAIA,UAAA,IAAc,yCAAA;AAAA,QACd,QAAA,IAAY;AAAA,OAChB;AAAA,MAKA,QAAA,EAAA;AAAA,wBAAAC,cAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACG,aAAA,EAAY,MAAA;AAAA,YACZ,aAAA,EAAY,cAAA;AAAA,YACZ,aAAA,EAAa,WAAW,MAAA,GAAS,OAAA;AAAA,YACjC,SAAA,EAAW,EAAA;AAAA,cACP,+HAAA;AAAA,cACA,WACM,uEAAA,GACA;AAAA;AACV;AAAA,SACJ;AAAA,wBAEAD,eAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACG,aAAA,EAAY,YAAA;AAAA,YACZ,KAAA,EAAO,SAAA;AAAA,YACP,SAAA,EAAU,gEAAA;AAAA,YAEV,QAAA,EAAA;AAAA,8BAAAC,cAAA,CAAC,SAAA,EAAA,EAAU,MAAM,KAAA,CAAM,IAAA,EAAM,MAAM,KAAA,CAAM,IAAA,EAAM,KAAA,EAAO,KAAA,CAAM,gBAAA,EAAkB,CAAA;AAAA,cAE7E,OAAA,oBACGA,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,0EAAA,EAA2E,CAAA;AAAA,cAG7F,UAAA,oBACGA,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qIAAA,EAAsI;AAAA;AAAA;AAAA;AAE7J;AAAA;AAAA,GACJ;AAER;AC7JA,IAAM,UAAA,GAAa,4BAAA;AACnB,IAAM,UAAA,GAAa,6DAAA;AAEZ,IAAM,QAAA,GAAW,CAAC,EAAE,SAAA,EAAU,KAAqB;AACtD,EAAA,MAAM,SAASC,WAAA,EAAM;AACrB,EAAA,MAAM,IAAA,GAAO,GAAG,MAAM,CAAA,EAAA,CAAA;AAEtB,EAAA,uBACIF,eAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACG,OAAA,EAAQ,aAAA;AAAA,MACR,SAAA,EAAW,EAAA,CAAG,8BAAA,EAAgC,SAAS,CAAA;AAAA,MACvD,KAAA,EAAM,4BAAA;AAAA,MACN,aAAA,EAAY,MAAA;AAAA,MAEZ,QAAA,EAAA;AAAA,wBAAAA,gBAAC,MAAA,EAAA,EACG,QAAA,EAAA;AAAA,0BAAAA,eAAAA,CAAC,oBAAe,EAAA,EAAI,MAAA,EAAQ,IAAG,KAAA,EAAM,EAAA,EAAG,KAAA,EAAM,CAAA,EAAE,KAAA,EAC5C,QAAA,EAAA;AAAA,4BAAAC,cAAAA,CAAC,UAAK,MAAA,EAAO,IAAA,EAAK,OAAO,EAAE,SAAA,EAAW,WAAU,EAAG,CAAA;AAAA,4BACnDA,eAAC,MAAA,EAAA,EAAK,MAAA,EAAO,OAAM,KAAA,EAAO,EAAE,SAAA,EAAW,UAAA,EAAW,EAAG,CAAA;AAAA,4BACrDA,eAAC,MAAA,EAAA,EAAK,MAAA,EAAO,QAAO,KAAA,EAAO,EAAE,SAAA,EAAW,UAAA,EAAW,EAAG;AAAA,WAAA,EAC1D,CAAA;AAAA,0BACAD,eAAAA,CAAC,gBAAA,EAAA,EAAe,EAAA,EAAI,IAAA,EAAM,IAAG,KAAA,EAAM,EAAA,EAAG,KAAA,EAAM,CAAA,EAAE,KAAA,EAC1C,QAAA,EAAA;AAAA,4BAAAC,eAAC,MAAA,EAAA,EAAK,MAAA,EAAO,MAAK,SAAA,EAAU,SAAA,EAAU,aAAY,MAAA,EAAO,CAAA;AAAA,4BACzDA,eAAC,MAAA,EAAA,EAAK,MAAA,EAAO,QAAO,SAAA,EAAU,SAAA,EAAU,aAAY,GAAA,EAAI;AAAA,WAAA,EAC5D;AAAA,SAAA,EACJ,CAAA;AAAA,wBAEAA,cAAAA,CAAC,QAAA,EAAA,EAAO,EAAA,EAAG,IAAA,EAAK,IAAG,IAAA,EAAK,CAAA,EAAE,IAAA,EAAK,IAAA,EAAM,QAAQ,MAAM,CAAA,CAAA,CAAA,EAAK,MAAA,EAAO,SAAA,EAAU,aAAY,KAAA,EAAM,CAAA;AAAA,wBAE3FD,eAAAA,CAAC,GAAA,EAAA,EAAE,MAAA,EAAO,SAAA,EAAU,aAAY,KAAA,EAAM,aAAA,EAAc,OAAA,EAAQ,IAAA,EAAK,MAAA,EAC7D,QAAA,EAAA;AAAA,0BAAAC,cAAAA,CAAC,UAAK,EAAA,EAAG,IAAA,EAAK,IAAG,IAAA,EAAK,EAAA,EAAG,IAAA,EAAK,EAAA,EAAG,IAAA,EAAK,CAAA;AAAA,0BACtCA,cAAAA,CAAC,MAAA,EAAA,EAAK,EAAA,EAAG,OAAA,EAAQ,IAAG,OAAA,EAAQ,EAAA,EAAG,OAAA,EAAQ,EAAA,EAAG,OAAA,EAAQ,CAAA;AAAA,0BAClDA,cAAAA,CAAC,MAAA,EAAA,EAAK,EAAA,EAAG,OAAA,EAAQ,IAAG,OAAA,EAAQ,EAAA,EAAG,OAAA,EAAQ,EAAA,EAAG,OAAA,EAAQ,CAAA;AAAA,0BAClDA,cAAAA,CAAC,MAAA,EAAA,EAAK,EAAA,EAAG,OAAA,EAAQ,IAAG,OAAA,EAAQ,EAAA,EAAG,OAAA,EAAQ,EAAA,EAAG,OAAA,EAAQ,CAAA;AAAA,0BAClDA,cAAAA,CAAC,MAAA,EAAA,EAAK,EAAA,EAAG,OAAA,EAAQ,IAAG,OAAA,EAAQ,EAAA,EAAG,OAAA,EAAQ,EAAA,EAAG,OAAA,EAAQ,CAAA;AAAA,0BAElDA,cAAAA,CAAC,MAAA,EAAA,EAAK,EAAA,EAAG,IAAA,EAAK,IAAG,MAAA,EAAO,EAAA,EAAG,IAAA,EAAK,EAAA,EAAG,KAAA,EAAM,CAAA;AAAA,0BACzCA,cAAAA,CAAC,MAAA,EAAA,EAAK,EAAA,EAAG,OAAA,EAAQ,IAAG,OAAA,EAAQ,EAAA,EAAG,MAAA,EAAO,EAAA,EAAG,OAAA,EAAQ,CAAA;AAAA,0BACjDA,cAAAA,CAAC,MAAA,EAAA,EAAK,EAAA,EAAG,OAAA,EAAQ,IAAG,OAAA,EAAQ,EAAA,EAAG,OAAA,EAAQ,EAAA,EAAG,OAAA,EAAQ,CAAA;AAAA,0BAClDA,cAAAA,CAAC,MAAA,EAAA,EAAK,EAAA,EAAG,OAAA,EAAQ,IAAG,OAAA,EAAQ,EAAA,EAAG,OAAA,EAAQ,EAAA,EAAG,OAAA,EAAQ,CAAA;AAAA,0BAClDA,cAAAA,CAAC,MAAA,EAAA,EAAK,EAAA,EAAG,OAAA,EAAQ,IAAG,OAAA,EAAQ,EAAA,EAAG,OAAA,EAAQ,EAAA,EAAG,OAAA,EAAQ;AAAA,SAAA,EACtD,CAAA;AAAA,wBAEAD,eAAAA,CAAC,GAAA,EAAA,EAAE,IAAA,EAAK,SAAA,EAAU,QAAO,SAAA,EAAU,WAAA,EAAY,KAAA,EAAM,cAAA,EAAe,OAAA,EAChE,QAAA,EAAA;AAAA,0BAAAC,cAAAA,CAAC,SAAA,EAAA,EAAQ,MAAA,EAAO,uDAAA,EAAwD,CAAA;AAAA,0BACxEA,cAAAA,CAAC,SAAA,EAAA,EAAQ,MAAA,EAAO,uDAAA,EAAwD,CAAA;AAAA,0BACxEA,cAAAA,CAAC,SAAA,EAAA,EAAQ,MAAA,EAAO,6DAAA,EAA8D,CAAA;AAAA,0BAC9EA,cAAAA,CAAC,SAAA,EAAA,EAAQ,MAAA,EAAO,6DAAA,EAA8D,CAAA;AAAA,0BAC9EA,cAAAA,CAAC,SAAA,EAAA,EAAQ,MAAA,EAAO,6DAAA,EAA8D,CAAA;AAAA,0BAC9EA,cAAAA,CAAC,SAAA,EAAA,EAAQ,MAAA,EAAO,6DAAA,EAA8D;AAAA,SAAA,EAClF,CAAA;AAAA,wBAEAA,cAAAA,CAAC,QAAA,EAAA,EAAO,EAAA,EAAG,MAAK,EAAA,EAAG,IAAA,EAAK,CAAA,EAAE,IAAA,EAAK,IAAA,EAAM,CAAA,KAAA,EAAQ,IAAI,CAAA,CAAA,CAAA,EAAK,eAAc,MAAA,EAAO;AAAA;AAAA;AAAA,GAC/E;AAER;AC/CA,IAAM,gBAAA,GAAmB;AAAA,EACvB,uBAAA;AAAA,EACA,mBAAA;AAAA,EACA,YAAA;AAAA,EACA,gBAAA;AAAA,EACA,SAAA;AAAA,EACA,gBAAA;AAAA,EACA,2BAAA;AAAA,EACA,mBAAA;AAAA,EACA,oBAAA;AAAA,EACA,eAAA;AAAA,EACA,eAAA;AAAA,EACA,uBAAA;AAAA,EACA,mBAAA;AAAA,EACA,aAAA;AAAA,EACA,eAAA;AAAA,EACA,cAAA;AAAA,EACA,sBAAA;AAAA,EACA,cAAA;AAAA,EACA,iBAAA;AAAA,EACA,cAAA;AAAA,EACA,gBAAA;AAAA,EACA,eAAA;AAAA,EACA,eAAA;AAAA,EACA,cAAA;AAAA,EACA,iBAAA;AAAA,EACA,MAAA;AAAA,EACA,gBAAA;AAAA,EACA,MAAA;AAAA,EACA,gBAAA;AAAA,EACA,4BAAA;AAAA,EACA,wBAAA;AAAA,EACA,qBAAA;AAAA,EACA,uBAAA;AAAA,EACA,kBAAA;AAAA,EACA,uBAAA;AAAA,EACA,kBAAA;AAAA,EACA,gBAAA;AAAA,EACA,gBAAA;AAAA,EACA,kBAAA;AAAA,EACA,iBAAA;AAAA,EACA,cAAA;AAAA,EACA,sBAAA;AAAA,EACA,yBAAA;AAAA,EACA,mBAAA;AAAA,EACA,mBAAA;AAAA,EACA,cAAA;AAAA,EACA,sBAAA;AAAA,EACA,iBAAA;AAAA,EACA,WAAA;AAAA,EACA,WAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAAA;AAIA,IAAM,eAAA,GAAkC,CAAC,GAAG,MAAA,CAAO,MAAA,CAAOE,6BAAS,CAAA,EAAG,GAAG,MAAA,CAAO,MAAA,CAAOC,4BAAQ,CAAC,CAAA,CAAE,GAAA;AAAA,EAChG,CAAC,KAAA,KAAU,CAAA,OAAA,EAAU,KAAK,CAAA;AAC5B,CAAA;AAIA,IAAM,qBAAA,GAA6C;AAAA,EACjD,iBAAA;AAAA,EACA,yBAAA;AAAA,EACA,oBAAA;AAAA,EACA;AACF,CAAA;AAYO,IAAM,cAAA,GAAyC;AAAA,EACpD,GAAG,gBAAA;AAAA,EACH,GAAG,eAAA;AAAA,EACH,GAAG;AACL;AAQA,IAAM,OAAA,GAAW,UAAA,CAA6D,OAAA,EAAS,GAAA,EAAK,QAAA;AAE5F,IAAM,QAAA,GAA2B,CAAC,GAAA,KAAQ;AACxC,EAAA,IAAI,OAAA,IAAW,YAAY,YAAA,EAAc;AACvC,IAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,4CAAA,EAA+C,GAAG,CAAA,wBAAA,CAA0B,CAAA;AAAA,EAC3F;AACA,EAAA,OAAO,GAAA;AACT,CAAA;AAEA,IAAM,eAAA,GAAkBC,oBAA8B,QAAQ,CAAA;AAEvD,SAAS,gBAAA,CAAiB,EAAE,CAAA,EAAG,QAAA,EAAS,EAA+C;AAC5F,EAAA,uBACEJ,cAAAA,CAAC,eAAA,CAAgB,QAAA,EAAhB,EAAyB,KAAA,EAAO,CAAA,EAC/B,QAAA,kBAAAA,cAAAA,CAACK,yBAAA,EAAA,EAAa,aAAA,EAAc,MAAA,EACzB,UACH,CAAA,EACF,CAAA;AAEJ;AAGO,SAAS,QAAA,GAA2B;AACzC,EAAA,OAAOC,iBAAW,eAAe,CAAA;AACnC;ACrHO,SAAS,cAAA,CAAe,EAAE,SAAA,EAAU,EAAwB;AAC/D,EAAA,MAAM,IAAI,QAAA,EAAS;AACnB,EAAA,MAAM,UAAA,GAAaC,8BAAA,CAAa,CAAA,CAAA,KAAK,CAAA,CAAE,UAAU,CAAA;AACjD,EAAA,MAAM,MAAA,GAAS,UAAA,EAAY,MAAA,CAAO,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,EAAA,KAAO,UAAA,CAAW,IAAA,CAAK,QAAQ,CAAA,IAAK,IAAA;AAClF,EAAA,IAAI,CAAC,QAAQ,OAAO,IAAA;AAEpB,EAAA,uBACIR,gBAAC,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,2CAAA,EAA6C,SAAS,CAAA,EAAG,WAAA,EAAU,QAAA,EAClF,QAAA,EAAA;AAAA,oBAAAA,eAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACG,KAAA,EAAO,MAAA,CAAO,IAAA,KAAS,OAAA,GAAU,iBAAA,GAAoB,iBAAA;AAAA,QACrD,SAAA,EAAU,yEAAA;AAAA,QAEV,QAAA,EAAA;AAAA,0BAAAC,eAAC,SAAA,EAAA,EAAU,IAAA,EAAM,OAAO,IAAA,EAAM,IAAA,EAAM,OAAO,IAAA,EAAM,CAAA;AAAA,0BACjDA,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qIACX,QAAA,kBAAAA,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,aAAA,EAAc,QAAA,kBAAAA,cAAAA,CAAC,QAAA,EAAA,EAAS,GAAE,CAAA,EAC7C;AAAA;AAAA;AAAA,KACJ;AAAA,oBACAD,eAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,0CAAA,EACX,QAAA,EAAA;AAAA,MAAA,CAAA,CAAE,YAAY,CAAA;AAAA,MAAE,IAAA;AAAA,MAAG,CAAA,CAAE,CAAA,OAAA,EAAU,MAAA,CAAO,IAAI,CAAA,CAAE;AAAA,KAAA,EACjD;AAAA,GAAA,EACJ,CAAA;AAER;AC5BO,SAAS,qBAAA,CAAsB,EAAE,SAAA,EAAU,EAA+B;AAC7E,EAAA,MAAM,IAAI,QAAA,EAAS;AACnB,EAAA,uBACIA,eAAAA,CAAC,IAAA,EAAA,EAAG,WAAW,EAAA,CAAG,yDAAA,EAA2D,SAAS,CAAA,EAClF,QAAA,EAAA;AAAA,oBAAAA,gBAAC,IAAA,EAAA,EAAG,QAAA,EAAA;AAAA,sBAAAC,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iBAAA,EAAkB,QAAA,EAAA,0BAAA,EAAI,CAAA;AAAA,MAAM,GAAA;AAAA,MAAE,EAAE,kBAAkB;AAAA,KAAA,EAAE,CAAA;AAAA,oBACvED,gBAAC,IAAA,EAAA,EAAG,QAAA,EAAA;AAAA,sBAAAC,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iBAAA,EAAkB,QAAA,EAAA,OAAA,EAAK,CAAA;AAAA,MAAM,GAAA;AAAA,MAAE,EAAE,kBAAkB;AAAA,KAAA,EAAE,CAAA;AAAA,oBACxED,gBAAC,IAAA,EAAA,EAAG,QAAA,EAAA;AAAA,sBAAAC,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iBAAA,EAAkB,QAAA,EAAA,GAAA,EAAC,CAAA;AAAA,MAAM,GAAA;AAAA,MAAE,EAAE,gBAAgB;AAAA,KAAA,EAAE,CAAA;AAAA,oBAClED,gBAAC,IAAA,EAAA,EAAG,QAAA,EAAA;AAAA,sBAAAC,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iBAAA,EAAkB,QAAA,EAAA,GAAA,EAAC,CAAA;AAAA,MAAM,GAAA;AAAA,MAAE,EAAE,gBAAgB;AAAA,KAAA,EAAE,CAAA;AAAA,oBAClED,gBAAC,IAAA,EAAA,EAAG,QAAA,EAAA;AAAA,sBAAAC,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iBAAA,EAAkB,QAAA,EAAA,KAAA,EAAG,CAAA;AAAA,MAAM,GAAA;AAAA,MAAE,EAAE,kBAAkB;AAAA,KAAA,EAAE;AAAA,GAAA,EAC1E,CAAA;AAER;AClBO,IAAM,UAAA,GAAa;AACnB,IAAM,UAAA,GAAa;AAGnB,IAAM,mBAAmB,CAAC,CAAA,EAAW,CAAA,KACxC,CAAA,IAAK,KAAK,CAAA,IAAK,CAAA,KAAO,CAAA,IAAK,CAAA,IAAK,KAAK,CAAA,IAAO,CAAA,IAAK,UAAA,GAAa,CAAA,IAAK,KAAK,UAAA,GAAa,CAAA;AAUlF,IAAM,qBAAA,GAAwB;AAQ9B,SAAS,gBAAA,CAAiB,GAAW,CAAA,EAAmB;AAC3D,EAAA,MAAM,MAAA,GAAA,CAAU,CAAA,GAAI,CAAA,IAAK,CAAA,KAAM,CAAA;AAC/B,EAAA,OAAO,EAAA;AAAA,IACH,+BAAA;AAAA,IACA,SAAS,kBAAA,GAAqB,kBAAA;AAAA,IAC9B,gBAAA,CAAiB,CAAA,EAAG,CAAC,CAAA,IAAK;AAAA,GAC9B;AACJ;AAWA,IAAM,cAAA,GACF,6WAAA;AAQG,IAAM,cAAA,GAAiB,CAAA,6BAAA,EAAgC,kBAAA,CAAmB,cAAc,CAAC,CAAA,EAAA,CAAA;AAKhG,IAAM,QAAA,GACF,iHAAA;AAWG,SAAS,YAAA,CAAa,EAAE,SAAA,EAAU,EAAsB;AAC3D,EAAA,uBACID,eAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACG,aAAA,EAAY,MAAA;AAAA,MACZ,aAAA,EAAY,eAAA;AAAA,MACZ,SAAA,EAAW,EAAA,CAAG,sDAAA,EAAwD,SAAS,CAAA;AAAA,MAE/E,QAAA,EAAA;AAAA,wBAAAC,cAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACG,YAAA,EAAW,OAAA;AAAA,YACX,SAAA,EAAU,+CAAA;AAAA,YACV,KAAA,EAAO,EAAE,eAAA,EAAiB,cAAA,EAAgB,gBAAgB,aAAA;AAAc;AAAA,SAC5E;AAAA,wBACAA,cAAAA,CAAC,KAAA,EAAA,EAAI,YAAA,EAAW,OAAA,EAAQ,SAAA,EAAU,kBAAA,EAAmB,KAAA,EAAO,EAAE,UAAA,EAAY,QAAA,EAAS,EAAG;AAAA;AAAA;AAAA,GAC1F;AAER;AAOA,IAAM,KAAA,GAAQ,SAAA;AAkBP,SAAS,aAAA,CAAc,EAAE,SAAA,EAAW,QAAA,EAAS,EAAuB;AACvE,EAAA,MAAM,KAAKC,WAAAA,EAAM;AACjB,EAAA,MAAM,QAAA,GAAW,GAAG,EAAE,CAAA,MAAA,CAAA;AAEtB,EAAA,uBACIF,eAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACG,OAAA,EAAQ,UAAA;AAAA,MACR,mBAAA,EAAoB,MAAA;AAAA,MACpB,SAAA,EAAW,EAAA,CAAG,oDAAA,EAAsD,SAAS,CAAA;AAAA,MAC7E,aAAA,EAAY,MAAA;AAAA,MACZ,aAAA,EAAY,gBAAA;AAAA,MAEZ,QAAA,EAAA;AAAA,wBAAAC,cAAAA,CAAC,UACG,QAAA,kBAAAD,eAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACG,EAAA,EAAI,QAAA;AAAA,YACJ,WAAA,EAAY,gBAAA;AAAA,YACZ,CAAA,EAAE,MAAA;AAAA,YACF,CAAA,EAAE,MAAA;AAAA,YACF,KAAA,EAAM,IAAA;AAAA,YACN,MAAA,EAAO,IAAA;AAAA,YACP,yBAAA,EAA0B,MAAA;AAAA,YAG1B,QAAA,EAAA;AAAA,8BAAAC,cAAAA,CAAC,cAAA,EAAA,EAAa,IAAA,EAAK,cAAA,EAAe,aAAA,EAAc,KAAA,EAAM,UAAA,EAAW,GAAA,EAAI,IAAA,EAAK,GAAA,EAAI,MAAA,EAAO,WAAA,EAAY,CAAA;AAAA,8BACjGA,cAAAA;AAAA,gBAAC,mBAAA;AAAA,gBAAA;AAAA,kBACG,EAAA,EAAG,eAAA;AAAA,kBACH,GAAA,EAAI,WAAA;AAAA,kBACJ,KAAA,EAAM,OAAA;AAAA,kBACN,gBAAA,EAAiB,GAAA;AAAA,kBACjB,gBAAA,EAAiB,GAAA;AAAA,kBACjB,MAAA,EAAO;AAAA;AAAA,eACX;AAAA,8BAEAA,cAAAA,CAAC,cAAA,EAAA,EAAa,IAAA,EAAK,cAAA,EAAe,aAAA,EAAc,IAAA,EAAK,UAAA,EAAW,GAAA,EAAI,IAAA,EAAK,IAAA,EAAK,MAAA,EAAO,MAAA,EAAO,CAAA;AAAA,8BAC5FA,cAAAA;AAAA,gBAAC,eAAA;AAAA,gBAAA;AAAA,kBACG,EAAA,EAAG,MAAA;AAAA,kBACH,IAAA,EAAK,QAAA;AAAA,kBACL,MAAA,EAAO,kDAAA;AAAA,kBACP,MAAA,EAAO;AAAA;AAAA,eACX;AAAA,8BACAA,cAAAA,CAAC,aAAA,EAAA,EAAY,EAAA,EAAG,OAAA,EAAQ,KAAI,UAAA,EAAW,QAAA,EAAS,YAAA,EAAa,EAAA,EAAG,KAAI,EAAA,EAAG,GAAA,EAAI,EAAA,EAAG,GAAA,EAAI,IAAG,GAAA,EAAI;AAAA;AAAA;AAAA,SAC7F,EACJ,CAAA;AAAA,wBAGAA,cAAAA,CAAC,GAAA,EAAA,EAAE,cAAW,MAAA,EAAO,IAAA,EAAK,QAAO,MAAA,EAAQ,KAAA,EAAO,aAAA,EAAc,MAAA,EAAO,aAAY,MAAA,EAAO,aAAA,EAAc,SAClG,QAAA,kBAAAA,cAAAA,CAAC,YAAS,CAAA,EACd,CAAA;AAAA,wBAEAA,cAAAA;AAAA,UAAC,GAAA;AAAA,UAAA;AAAA,YACG,YAAA,EAAW,OAAA;AAAA,YACX,MAAA,EAAQ,QAAQ,QAAQ,CAAA,CAAA,CAAA;AAAA,YACxB,IAAA,EAAK,MAAA;AAAA,YACL,MAAA,EAAQ,KAAA;AAAA,YACR,aAAA,EAAc,MAAA;AAAA,YACd,WAAA,EAAY,MAAA;AAAA,YACZ,aAAA,EAAc,OAAA;AAAA,YACd,cAAA,EAAe,OAAA;AAAA,YAEf,QAAA,kBAAAA,eAAC,QAAA,EAAA,EAAS;AAAA;AAAA,SACd;AAAA,QAEC;AAAA;AAAA;AAAA,GACL;AAER;AAEA,SAAS,QAAA,GAAW;AAChB,EAAA,uBACID,gBAAAS,mBAAA,EAAA,EAEI,QAAA,EAAA;AAAA,oBAAAR,cAAAA,CAAC,UAAK,CAAA,EAAE,MAAA,EAAO,GAAE,MAAA,EAAO,KAAA,EAAM,MAAA,EAAO,MAAA,EAAO,OAAA,EAAQ,CAAA;AAAA,oBAEpDA,cAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,GAAA,EAAI,GAAE,MAAA,EAAO,KAAA,EAAM,GAAA,EAAI,MAAA,EAAO,MAAA,EAAO,CAAA;AAAA,oBAC7CA,cAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,GAAA,EAAI,GAAE,IAAA,EAAK,KAAA,EAAM,GAAA,EAAI,MAAA,EAAO,MAAA,EAAO,CAAA;AAAA,oBAE3CA,cAAAA,CAAC,MAAA,EAAA,EAAK,EAAA,EAAG,MAAA,EAAO,IAAG,GAAA,EAAI,EAAA,EAAG,MAAA,EAAO,EAAA,EAAG,GAAA,EAAI,CAAA;AAAA,oBAExCA,eAAC,QAAA,EAAA,EAAO,EAAA,EAAG,OAAM,EAAA,EAAG,GAAA,EAAI,GAAE,KAAA,EAAM,CAAA;AAAA,oBAChCA,cAAAA,CAAC,QAAA,EAAA,EAAO,EAAA,EAAG,OAAM,EAAA,EAAG,GAAA,EAAI,CAAA,EAAE,MAAA,EAAO,IAAA,EAAM,KAAA,EAAO,WAAA,EAAY,KAAA,EAAM,QAAO,MAAA,EAAO,CAAA;AAAA,oBAE9EA,cAAAA,CAAC,QAAA,EAAA,EAAO,EAAA,EAAG,OAAM,EAAA,EAAG,KAAA,EAAM,CAAA,EAAE,MAAA,EAAO,IAAA,EAAM,KAAA,EAAO,WAAA,EAAY,KAAA,EAAM,QAAO,MAAA,EAAO,CAAA;AAAA,oBAChFA,cAAAA,CAAC,QAAA,EAAA,EAAO,EAAA,EAAG,OAAM,EAAA,EAAG,MAAA,EAAO,CAAA,EAAE,MAAA,EAAO,IAAA,EAAM,KAAA,EAAO,WAAA,EAAY,KAAA,EAAM,QAAO,MAAA,EAAO,CAAA;AAAA,oBAEjFA,cAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,mCAAA,EAAoC,CAAA;AAAA,oBAC5CA,cAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,qCAAA,EAAsC;AAAA,GAAA,EAClD,CAAA;AAER;AAuBO,SAAS,YAAA,CAAa,EAAE,SAAA,EAAW,eAAA,EAAiB,UAAS,EAAsB;AACtF,EAAA,MAAM,UAAU,EAAC;AACjB,EAAA,KAAA,IAAS,CAAA,GAAI,UAAA,GAAa,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AACtC,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,UAAA,EAAY,CAAA,EAAA,EAAK;AACjC,MAAA,OAAA,CAAQ,IAAA;AAAA,wBACJA,cAAAA,CAAC,KAAA,EAAA,EAAsB,WAAW,EAAA,CAAG,gBAAA,CAAiB,GAAG,CAAC,CAAA,EAAG,eAAA,GAAkB,CAAA,EAAG,CAAC,CAAC,CAAA,EAAA,EAA1E,GAAG,CAAC,CAAA,CAAA,EAAI,CAAC,CAAA,CAAoE;AAAA,OAC3F;AAAA,IACJ;AAAA,EACJ;AACA,EAAA,uBACID,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,UAAA,EAAY,SAAS,CAAA,EAAG,KAAA,EAAO,EAAE,aAAA,EAAe,aAAA,EAAc,EAC7E,QAAA,EAAA;AAAA,oBAAAC,eAAC,KAAA,EAAA,EAAI,SAAA,EAAU,4BAAA,EAA6B,aAAA,EAAY,iBACnD,QAAA,EAAA,OAAA,EACL,CAAA;AAAA,oBACAA,eAAC,YAAA,EAAA,EAAa,CAAA;AAAA,oBACdA,eAAC,aAAA,EAAA,EAAc,CAAA;AAAA,IACd;AAAA,GAAA,EACL,CAAA;AAER;ACzMA,IAAM,IAAA,GAAO,CAAA;AACb,IAAM,IAAA,GAAO,EAAA;AAEb,IAAM,KAAA,GAAQ,CAAC,CAAA,EAAW,EAAA,EAAY,EAAA,KAAe,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,CAAC,CAAC,CAAA;AAMjF,IAAM,KAAA,GAAQ,CAAC,CAAA,KAAc,CAAA,EAAG,IAAI,GAAG,CAAA,CAAA,CAAA;AACvC,IAAM,QAAQ,CAAC,CAAA,KAAc,IAAI,IAAA,GAAO,CAAA,GAAI,KAAK,GAAG,CAAA,CAAA,CAAA;AAGpD,IAAM,qBAAA,GAAwB,GAAA;AAQ9B,IAAM,WAAA,GAAc,EAAE,IAAA,EAAM,QAAA,EAAmB,WAAW,GAAA,EAAK,OAAA,EAAS,EAAA,EAAI,IAAA,EAAM,CAAA,EAAE;AACpF,IAAM,UAAA,GAAc,EAAE,IAAA,EAAM,QAAA,EAAmB,WAAW,GAAA,EAAK,OAAA,EAAS,EAAA,EAAI,IAAA,EAAM,GAAA,EAAI;AAEvE,SAAR,SAAA,CAA2B,EAAE,QAAA,EAAU,eAAA,GAAkB,KAAA,EAAO,WAAA,GAAc,IAAA,EAAM,OAAA,GAAU,IAAA,EAAM,aAAA,GAAgB,KAAA,EAAO,SAAA,EAAU,EAAmB;AAC3J,EAAA,MAAM,IAAI,QAAA,EAAS;AACnB,EAAA,MAAM,UAAUC,WAAAA,EAAM;AACtB,EAAA,MAAM,uBAAuBQ,6BAAA,EAAiB;AAG9C,EAAA,MAAM;AAAA,IACF,UAAA;AAAA,IACA,eAAA;AAAA,IACA,eAAA;AAAA,IACA,kBAAA;AAAA,IACA,kBAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACJ,GAAIF,8BAAA;AAAA,IACAG,mBAAW,CAAA,CAAA,MAAM;AAAA,MACb,YAAY,CAAA,CAAE,UAAA;AAAA,MACd,iBAAiB,CAAA,CAAE,eAAA;AAAA,MACnB,iBAAiB,CAAA,CAAE,eAAA;AAAA,MACnB,oBAAoB,CAAA,CAAE,kBAAA;AAAA,MACtB,oBAAoB,CAAA,CAAE,kBAAA;AAAA,MACtB,WAAW,CAAA,CAAE,SAAA;AAAA,MACb,UAAU,CAAA,CAAE;AAAA,KAChB,CAAE;AAAA,GACN;AAEA,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIC,eAA0B,IAAI,CAAA;AAC1D,EAAA,MAAM,CAAC,cAAA,EAAgB,iBAAiB,CAAA,GAAIA,eAA0B,IAAI,CAAA;AAC1E,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAIA,eAAS,KAAK,CAAA;AACxD,EAAA,MAAM,YAAA,GAAeC,aAAuB,IAAI,CAAA;AAChD,EAAAC,eAAA,CAAU,MAAM;AACZ,IAAA,IAAI,CAAC,aAAA,EAAe;AACpB,IAAA,MAAM,aAAA,GAAgB,CAAC,CAAA,KAAkB;AACrC,MAAA,IAAI,YAAA,CAAa,WAAW,CAAC,YAAA,CAAa,QAAQ,QAAA,CAAS,CAAA,CAAE,MAAc,CAAA,EAAG;AAC1E,QAAA,gBAAA,CAAiB,KAAK,CAAA;AAAA,MAC1B;AAAA,IACJ,CAAA;AACA,IAAA,QAAA,CAAS,gBAAA,CAAiB,aAAa,aAAa,CAAA;AACpD,IAAA,OAAO,MAAM,QAAA,CAAS,mBAAA,CAAoB,WAAA,EAAa,aAAa,CAAA;AAAA,EACxE,CAAA,EAAG,CAAC,aAAa,CAAC,CAAA;AAClB,EAAA,MAAM,CAAC,cAAA,EAAgB,iBAAiB,CAAA,GAAIF,eAAgD,IAAI,CAAA;AAChG,EAAA,MAAM,oBAAA,GAAuBC,aAAO,CAAC,CAAA;AACrC,EAAA,MAAM,wBAAA,GAA2B,CAAC,CAAA,EAAW,CAAA,KAAc;AACvD,IAAA,oBAAA,CAAqB,OAAA,IAAW,CAAA;AAChC,IAAA,iBAAA,CAAkB,EAAE,CAAA,EAAG,CAAA,EAAG,KAAA,EAAO,oBAAA,CAAqB,SAAS,CAAA;AAAA,EACnE,CAAA;AACA,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAID,eAA0B,IAAI,CAAA;AACxE,EAAA,MAAM,cAAA,GAAiBC,aAAO,CAAC,CAAA;AAI/B,EAAA,MAAM,CAAC,WAAW,YAAY,CAAA,GAAID,eAA8B,sBAAM,IAAI,KAAK,CAAA;AAC/E,EAAA,MAAM,SAAA,GAAY,CAAC,EAAA,EAAY,MAAA,KAC3B,aAAa,CAAA,IAAA,KAAQ;AACjB,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA,KAAM,QAAQ,OAAO,IAAA;AACpC,IAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,IAAI,CAAA;AACzB,IAAA,IAAI,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA;AAAA,SAAQ,IAAA,CAAK,OAAO,EAAE,CAAA;AAC7C,IAAA,OAAO,IAAA;AAAA,EACX,CAAC,CAAA;AAEL,EAAAE,eAAA,CAAU,MAAM;AACZ,IAAA,IAAI,CAAC,cAAA,EAAgB;AACrB,IAAA,MAAM,KAAK,UAAA,CAAW,MAAM,iBAAA,CAAkB,IAAI,GAAG,GAAG,CAAA;AACxD,IAAA,OAAO,MAAM,aAAa,EAAE,CAAA;AAAA,EAChC,CAAA,EAAG,CAAC,cAAc,CAAC,CAAA;AAEnB,EAAA,MAAM,WAAA,GAAcD,YAAA,CAAO,UAAA,EAAY,IAAI,CAAA;AAC3C,EAAA,MAAM,WAAW,WAAA,CAAY,OAAA;AAC7B,EAAAC,eAAA,CAAU,MAAM;AACZ,IAAA,WAAA,CAAY,UAAU,UAAA,EAAY,IAAA;AAAA,EACtC,CAAC,CAAA;AAMD,EAAA,MAAM,WAAA,GAAcD,YAAA,CAAO,UAAA,EAAY,IAAI,CAAA;AAC3C,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAID,eAA8D,IAAI,CAAA;AAC9F,EAAAE,eAAA,CAAU,MAAM;AACZ,IAAA,MAAM,WAAW,WAAA,CAAY,OAAA;AAC7B,IAAA,WAAA,CAAY,UAAU,UAAA,EAAY,IAAA;AAClC,IAAA,IAAI,CAAC,UAAA,IAAc,QAAA,KAAa,UAAA,CAAW,IAAA,EAAM;AAIjD,IAAA,IAAI,UAAA,CAAW,SAAS,QAAA,EAAU;AAC9B,MAAA,SAAA,CAAU,IAAI,CAAA;AACd,MAAA;AAAA,IACJ;AACA,IAAA,IAAI,oBAAA,IAAwB,aAAa,IAAA,EAAM;AAE/C,IAAA,MAAM,SAAA,GAAY,UAAA,CAAW,WAAA,CAAY,EAAA,CAAG,EAAE,CAAA;AAC9C,IAAA,IAAI,CAAC,SAAA,EAAW;AAChB,IAAA,MAAM,KAAA,GAAQ,WAAW,WAAA,CAAY,MAAA;AAAA,MACjC,OAAK,CAAA,CAAE,UAAA,KAAe,SAAA,CAAU,UAAA,IAAc,EAAE,SAAA,KAAc;AAAA,KAClE;AACA,IAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG,SAAA,CAAU,EAAE,KAAA,EAAO,KAAA,EAAO,GAAG,CAAA;AAAA,EACvD,CAAA,EAAG,CAAC,UAAA,EAAY,QAAA,EAAU,oBAAoB,CAAC,CAAA;AAE/C,EAAAA,eAAA,CAAU,MAAM;AACZ,IAAA,IAAI,CAAC,MAAA,EAAQ;AACb,IAAA,IAAI,MAAA,CAAO,KAAA,IAAS,MAAA,CAAO,KAAA,CAAM,SAAS,CAAA,EAAG;AACzC,MAAA,MAAMC,MAAK,UAAA,CAAW,MAAM,SAAA,CAAU,IAAI,GAAG,GAAG,CAAA;AAChD,MAAA,OAAO,MAAM,aAAaA,GAAE,CAAA;AAAA,IAChC;AACA,IAAA,MAAM,KAAK,UAAA,CAAW,MAAM,SAAA,CAAU,CAAA,CAAA,KAAM,IAAI,EAAE,GAAG,CAAA,EAAG,KAAA,EAAO,EAAE,KAAA,GAAQ,CAAA,EAAE,GAAI,IAAK,GAAG,GAAG,CAAA;AAC1F,IAAA,OAAO,MAAM,aAAa,EAAE,CAAA;AAAA,EAChC,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAMX,EAAA,MAAM,UAAA,GAAaC,cAAQ,MAAM;AAC7B,IAAA,IAAI,CAAC,UAAA,IAAc,eAAA,KAAoB,MAAA,SAAe,EAAC;AACvD,IAAA,MAAM,KAAK,UAAA,CAAW,MAAA,CAAO,KAAK,CAAA,CAAA,KAAK,CAAA,CAAE,OAAO,eAAe,CAAA;AAC/D,IAAA,IAAI,EAAA,IAAM,CAAC,EAAA,CAAG,gBAAA,EAAkB;AAC5B,MAAA,OAAOC,iCAAA,CAAc,IAAI,UAAU,CAAA;AAAA,IACvC;AACA,IAAA,OAAO,EAAC;AAAA,EACZ,CAAA,EAAG,CAAC,UAAA,EAAY,eAAA,EAAiB,eAAe,CAAC,CAAA;AAEjD,EAAA,MAAM,WAAA,GAAcD,cAAQ,MAAM;AAC9B,IAAA,IAAI,CAAC,UAAA,IAAc,eAAA,KAAoB,MAAA,SAAe,EAAC;AACvD,IAAA,MAAM,KAAK,UAAA,CAAW,MAAA,CAAO,KAAK,CAAA,CAAA,KAAK,CAAA,CAAE,OAAO,eAAe,CAAA;AAC/D,IAAA,IAAI,EAAA,IAAM,UAAA,CAAW,IAAA,CAAK,QAAA,KAAa,GAAG,EAAA,EAAI;AAC1C,MAAA,OAAOE,kCAAA,CAAe,IAAI,UAAU,CAAA;AAAA,IACxC;AACA,IAAA,OAAO,EAAC;AAAA,EACZ,CAAA,EAAG,CAAC,UAAA,EAAY,eAAA,EAAiB,eAAe,CAAC,CAAA;AAEjD,EAAA,IAAI,CAAC,YAAY,OAAO,IAAA;AAExB,EAAA,MAAM,WAAW,UAAA,CAAW,QAAA;AAC5B,EAAA,MAAM,OAAO,UAAA,CAAW,IAAA;AACxB,EAAA,MAAM,SAAA,GACF,CAAC,CAAC,QAAA,KACD,SAAS,GAAA,CAAI,CAAA,KAAM,IAAA,CAAK,GAAA,CAAI,CAAA,IAAK,QAAA,CAAS,GAAA,CAAI,CAAA,KAAM,KAAK,GAAA,CAAI,CAAA,CAAA;AAClE,EAAA,MAAM,iBACF,CAAC,CAAC,QAAA,IACF,CAAC,SAAS,QAAA,IACV,CAAC,CAAC,IAAA,CAAK,YACP,QAAA,EAAU,IAAA,KAAS,UACnB,QAAA,EAAU,QAAA,KAAa,KAAK,QAAA,IAC5B,SAAA;AAEJ,EAAA,MAAM,eAAA,GAAkB,GAAA;AACxB,EAAA,MAAM,eAAA,GAAkB,cAAA,GAAiB,IAAA,CAAK,QAAA,GAAW,IAAA;AACzD,EAAA,IAAI,gBAAA,GAAmB,GAAA;AACvB,EAAA,IAAI,cAAA,IAAkB,QAAA,IAAY,QAAA,EAAU,IAAA,EAAM;AAC9C,IAAA,MAAM,aAAa,IAAA,CAAK,GAAA;AAAA,MACpB,KAAK,GAAA,CAAI,QAAA,CAAS,GAAG,CAAA,GAAI,QAAA,CAAS,KAAK,CAAC,CAAA;AAAA,MACxC,KAAK,GAAA,CAAI,QAAA,CAAS,GAAG,CAAA,GAAI,QAAA,CAAS,KAAK,CAAC;AAAA,KAC5C;AACA,IAAA,MAAM,cAAc,IAAA,CAAK,GAAA;AAAA,MACrB,KAAK,GAAA,CAAI,QAAA,CAAS,IAAI,CAAA,GAAI,QAAA,CAAS,KAAK,CAAC,CAAA;AAAA,MACzC,KAAK,GAAA,CAAI,QAAA,CAAS,IAAI,CAAA,GAAI,QAAA,CAAS,KAAK,CAAC;AAAA,KAC7C;AACA,IAAA,gBAAA,GAAmB,UAAA,GAAa,CAAA,GAC1B,IAAA,CAAK,GAAA,CAAI,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,IAAA,EAAM,WAAA,GAAc,UAAU,CAAC,CAAA,GACvD,GAAA;AAAA,EACV;AAGA,EAAA,MAAM,WAAA,GAAc,IAAA,CAAK,QAAA,GACnB,UAAA,CAAW,MAAA,CAAO,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,EAAA,KAAO,IAAA,CAAK,QAAQ,CAAA,IAAK,IAAA,GACvD,IAAA;AACN,EAAA,MAAM,gBACF,CAAC,CAAC,eACF,WAAA,CAAY,IAAA,KAAS,UACrB,QAAA,KAAa,IAAA,IACb,YAAY,IAAA,KAAS,QAAA,IACrB,WAAW,IAAA,KAAS,QAAA,IACpBC,kCAAc,WAAA,CAAY,GAAA,EAAK,YAAY,IAAI,CAAA;AAQnD,EAAA,MAAM,WAAA,GAAc,UAAA,CAAW,MAAA,CAAO,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,EAAA,KAAO,eAAA,IAAmB,UAAA,CAAW,IAAA,CAAK,QAAA,KAAa,CAAA,CAAE,EAAE,CAAA,IAAK,IAAA;AAClH,EAAA,MAAM,cAAA,GAAkB,aAAA,IAAiB,WAAA,GAClC,WAAA,CAAY,IAAA,KAAS,QAAA,GAAW,CAAC,aAAa,CAAA,GAAIC,2BAAA,CAAQ,WAAA,CAAY,GAAA,EAAK,aAAa,CAAA,GACzF,IAAA;AACN,EAAA,MAAM,qBAAA,GAAwB,CAAC,EAAE,cAAA,IAAkB,WAAA,IAAe,cAAA,CAC7D,IAAA,CAAK,CAAA,EAAA,KAAM,UAAA,CAAW,MAAA,CAAO,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,IAAI,CAAA,KAAM,EAAA,CAAG,CAAA,IAAK,CAAA,CAAE,GAAA,CAAI,CAAA,KAAM,EAAA,CAAG,CAAA,IAAK,CAAA,CAAE,IAAA,KAAS,WAAA,CAAY,IAAI,CAAC,CAAA,CAAA;AAIhH,EAAA,MAAM,kBAAA,GAAqB,CAAC,CAAA,EAAW,CAAA,KAA+B;AAClE,IAAA,MAAM,OAAO,CAAC,GAAG,UAAA,EAAY,GAAG,WAAW,CAAA,CAAE,MAAA;AAAA,MACzC,CAACC,EAAAA,EAAG,CAAA,EAAG,GAAA,KACH,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,GAAA,CAAIA,EAAAA,CAAE,CAAA,GAAI,CAAC,CAAA,EAAG,KAAK,GAAA,CAAIA,EAAAA,CAAE,CAAA,GAAI,CAAC,CAAC,CAAA,KAAM,CAAA,IACnD,GAAA,CAAI,UAAU,CAAA,CAAA,KAAK,CAAA,CAAE,CAAA,KAAMA,EAAAA,CAAE,CAAA,IAAK,CAAA,CAAE,CAAA,KAAMA,EAAAA,CAAE,CAAC,CAAA,KAAM;AAAA,KAC3D;AACA,IAAA,OAAO,IAAA,CAAK,MAAA,KAAW,CAAA,GAAI,IAAA,CAAK,CAAC,CAAA,GAAI,IAAA;AAAA,EACzC,CAAA;AAEA,EAAA,MAAM,iBAAA,GAAoB,CAAC,CAAA,EAAW,CAAA,EAAW,YAAY,KAAA,KAAU;AACnE,IAAA,IAAI,MAAA,EAAQ;AACZ,IAAA,SAAA,CAAU,IAAI,CAAA;AACd,IAAA,MAAM,WAAA,GAAc,WAAW,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,CAAA,KAAM,CAAA,IAAK,CAAA,CAAE,CAAA,KAAM,CAAC,CAAA;AAC/D,IAAA,MAAM,WAAA,GAAc,YAAY,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,CAAA,KAAM,CAAA,IAAK,CAAA,CAAE,CAAA,KAAM,CAAC,CAAA;AAEhE,IAAA,IAAI,CAAC,WAAA,IAAe,CAAC,WAAA,IAAe,SAAA,IAAa,iBAAiB,eAAA,EAAiB;AAC/E,MAAA,MAAM,MAAA,GAAS,kBAAA,CAAmB,CAAA,EAAG,CAAC,CAAA;AACtC,MAAA,IAAI,MAAA,EAAQ;AACR,QAAA,iBAAA,CAAkB,MAAA,CAAO,CAAA,EAAG,MAAA,CAAO,CAAC,CAAA;AACpC,QAAA;AAAA,MACJ;AAAA,IACJ;AAEA,IAAA,IAAI,eAAe,WAAA,EAAa;AAC5B,MAAA,iBAAA,CAAkB,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA;AAC1B,MAAA;AAAA,IACJ;AACA,IAAA,IAAI,eAAe,eAAA,EAAiB;AAChC,MAAA,SAAA,CAAU,eAAA,EAAiB,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA;AACnC,MAAA,iBAAA,CAAkB,IAAI,CAAA;AACtB,MAAA,iBAAA,CAAkB,IAAI,CAAA;AAAA,IAC1B,WAAW,WAAA,EAAa;AACpB,MAAA,QAAA,CAAS,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA;AACjB,MAAA,iBAAA,CAAkB,IAAI,CAAA;AACtB,MAAA,iBAAA,CAAkB,IAAI,CAAA;AAAA,IAC1B,CAAA,MAAO;AAGH,MAAA,IAAI,eAAA,EAAiB;AACjB,QAAA,wBAAA,CAAyB,GAAG,CAAC,CAAA;AAAA,MACjC;AACA,MAAA,iBAAA,CAAkB,IAAI,CAAA;AAAA,IAC1B;AAAA,EACJ,CAAA;AAEA,EAAA,MAAM,gBAAA,GAAmB,CAAC,OAAA,EAAiB,CAAA,EAAW,GAAW,CAAA,KAAwB;AACrF,IAAA,CAAA,CAAE,eAAA,EAAgB;AAClB,IAAA,IAAI,MAAA,EAAQ;AACZ,IAAA,MAAM,UAAU,UAAA,CAAW,MAAA,CAAO,KAAK,CAAA,CAAA,KAAK,CAAA,CAAE,OAAO,OAAO,CAAA;AAC5D,IAAA,IAAI,CAAC,OAAA,EAAS;AAEd,IAAA,MAAM,WAAA,GAAc,WAAW,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,CAAA,KAAM,CAAA,IAAK,CAAA,CAAE,CAAA,KAAM,CAAC,CAAA;AAC/D,IAAA,MAAM,WAAA,GAAc,YAAY,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,CAAA,KAAM,CAAA,IAAK,CAAA,CAAE,CAAA,KAAM,CAAC,CAAA;AAEhE,IAAA,IAAI,eAAe,WAAA,EAAa;AAC5B,MAAA,iBAAA,CAAkB,GAAG,CAAC,CAAA;AAAA,IAC1B,WAAW,UAAA,CAAW,IAAA,KAAS,QAAQ,IAAA,IAAQ,QAAA,KAAa,QAAQ,IAAA,EAAM;AACtE,MAAA,IAAI,eAAA,KAAoB,QAAQ,EAAA,EAAI;AAChC,QAAA,kBAAA,CAAmB,IAAI,CAAA;AAAA,MAC3B,CAAA,MAAO;AACH,QAAA,kBAAA,CAAmB,QAAQ,EAAE,CAAA;AAAA,MACjC;AACA,MAAA,iBAAA,CAAkB,IAAI,CAAA;AACtB,MAAA,iBAAA,CAAkB,IAAI,CAAA;AAAA,IAC1B,WAAW,eAAA,EAAiB;AAIxB,MAAA,wBAAA,CAAyB,GAAG,CAAC,CAAA;AAC7B,MAAA,iBAAA,CAAkB,IAAI,CAAA;AAAA,IAC1B;AAAA,EACJ,CAAA;AAEA,EAAA,MAAM,gBAAgB,MAAgB;AAClC,IAAA,MAAM,MAAM,UAAA,CAAW,MAAA,CAAO,KAAK,CAAA,CAAA,KAAK,CAAA,CAAE,OAAO,eAAe,CAAA;AAChE,IAAA,OAAO,GAAA,GAAM,EAAE,GAAG,GAAA,CAAI,GAAA,KAAQ,EAAE,GAAG,UAAA,CAAW,IAAA,CAAK,GAAA,EAAI;AAAA,EAC3D,CAAA;AAEA,EAAA,MAAM,QAAA,GAAW,CAAC,CAAA,EAAW,CAAA,KAAc;AACvC,IAAA,MAAM,OAAA,GAAU,UAAA,CAAW,MAAA,CAAO,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,GAAA,CAAI,CAAA,KAAM,CAAA,IAAK,CAAA,CAAE,GAAA,CAAI,CAAA,KAAM,CAAC,CAAA;AAC1E,IAAA,IAAI,OAAA,EAAS;AACT,MAAA,gBAAA,CAAiB,OAAA,CAAQ,EAAA,EAAI,CAAA,EAAG,CAAA,EAAG,EAAE,eAAA,GAAkB;AAAA,MAAC,GAAuB,CAAA;AAAA,IACnF,CAAA,MAAO;AACH,MAAA,iBAAA,CAAkB,GAAG,CAAC,CAAA;AAAA,IAC1B;AAAA,EACJ,CAAA;AAEA,EAAA,MAAM,aAAA,GAAgB,CAAC,CAAA,KAA2B;AAC9C,IAAA,IAAI,CAAC,eAAe,MAAA,EAAQ;AAC5B,IAAA,MAAM,IAAA,GAAO,CAAC,EAAA,EAAY,EAAA,KAAe;AACrC,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,SAAA,CAAU,CAAA,CAAA,KAAK;AACX,QAAA,MAAM,IAAA,GAAO,KAAK,aAAA,EAAc;AAChC,QAAA,OAAO,EAAE,CAAA,EAAG,KAAA,CAAM,KAAK,CAAA,GAAI,EAAA,EAAI,GAAG,IAAA,GAAO,CAAC,CAAA,EAAG,CAAA,EAAG,MAAM,IAAA,CAAK,CAAA,GAAI,IAAI,CAAA,EAAG,IAAA,GAAO,CAAC,CAAA,EAAE;AAAA,MACpF,CAAC,CAAA;AAAA,IACL,CAAA;AACA,IAAA,QAAQ,EAAE,GAAA;AAAK,MACX,KAAK,SAAA;AAAc,QAAA,IAAA,CAAK,GAAG,CAAC,CAAA;AAAG,QAAA;AAAA,MAC/B,KAAK,WAAA;AAAc,QAAA,IAAA,CAAK,GAAG,EAAE,CAAA;AAAG,QAAA;AAAA,MAChC,KAAK,WAAA;AAAc,QAAA,IAAA,CAAK,IAAI,CAAC,CAAA;AAAG,QAAA;AAAA,MAChC,KAAK,YAAA;AAAc,QAAA,IAAA,CAAK,GAAG,CAAC,CAAA;AAAG,QAAA;AAAA,MAC/B,KAAK,OAAA;AAAA,MACL,KAAK,GAAA,EAAK;AACN,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,MAAM,CAAA,GAAI,UAAU,aAAA,EAAc;AAClC,QAAA,SAAA,CAAU,CAAC,CAAA;AACX,QAAA,QAAA,CAAS,CAAA,CAAE,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA;AACjB,QAAA;AAAA,MACJ;AAAA;AAAA;AAAA,MAGA,KAAK,GAAA;AAAA,MAAK,KAAK,GAAA;AACX,QAAA,IAAI,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,OAAA,IAAW,EAAE,MAAA,EAAQ;AACxC,QAAA,IAAI,kBAAkB,eAAA,EAAiB;AACnC,UAAA,SAAA,CAAU,iBAAiB,cAAc,CAAA;AACzC,UAAA,iBAAA,CAAkB,IAAI,CAAA;AAAA,QAC1B;AACA,QAAA;AAAA,MACJ,KAAK,GAAA;AAAA,MAAK,KAAK,GAAA;AACX,QAAA,IAAI,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,OAAA,IAAW,EAAE,MAAA,EAAQ;AACxC,QAAA,IAAI,cAAA,EAAgB;AAChB,UAAA,QAAA,CAAS,cAAc,CAAA;AACvB,UAAA,iBAAA,CAAkB,IAAI,CAAA;AAAA,QAC1B;AACA,QAAA;AAAA,MACJ,KAAK,QAAA;AACD,QAAA,IAAI,aAAA,EAAe;AACf,UAAA,gBAAA,CAAiB,KAAK,CAAA;AAAA,QAC1B,WAAW,cAAA,EAAgB;AACvB,UAAA,iBAAA,CAAkB,IAAI,CAAA;AAAA,QAC1B,CAAA,MAAO;AACH,UAAA,kBAAA,CAAmB,IAAI,CAAA;AACvB,UAAA,kBAAA,CAAmB,IAAI,CAAA;AAAA,QAC3B;AACA,QAAA;AAAA;AACR,EACJ,CAAA;AAEA,EAAA,MAAM,MAAA,GAAS,CAAC,CAAA,EAAW,CAAA,KAAc,GAAG,OAAO,CAAA,IAAA,EAAO,CAAC,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA;AAQhE,EAAA,MAAM,cAAc,CAChB,CAAA,EACA,CAAA,EACA,OAAA,EACA,aACA,WAAA,KACC;AACD,IAAA,MAAM,MAAA,GAASC,8BAAA,CAAW,EAAE,CAAA,EAAG,GAAG,CAAA;AAClC,IAAA,MAAM,WAAW,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,IAAK,IAAA,CAAK,IAAI,CAAA,KAAM,CAAA;AACpD,IAAA,MAAM,QAAkB,EAAC;AAEzB,IAAA,IAAI,OAAA,EAAS;AACT,MAAA,MAAM,QAAQ,CAAA,CAAE,CAAA,OAAA,EAAUlB,6BAAS,OAAA,CAAQ,IAAI,CAAC,CAAA,CAAE,CAAA;AAClD,MAAA,MAAM,IAAA,GAAO,QAAQ,IAAA,KAAS,OAAA,GAAU,EAAE,WAAW,CAAA,GAAI,EAAE,WAAW,CAAA;AACtE,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,CAAE,QAAA,GAAW,sBAAA,GAAyB,cAAA,EAAgB,EAAE,MAAA,EAAQ,KAAA,EAAO,IAAA,EAAM,CAAC,CAAA;AAAA,IAC7F,CAAA,MAAO;AACH,MAAA,KAAA,CAAM,IAAA,CAAK,EAAE,QAAA,GAAW,sBAAA,GAAyB,gBAAgB,EAAE,MAAA,EAAQ,CAAC,CAAA;AAAA,IAChF;AAEA,IAAA,IAAI,eAAe,WAAA,EAAa,KAAA,CAAM,IAAA,CAAK,CAAA,CAAE,yBAAyB,CAAC,CAAA;AAAA,SAAA,IAC9D,WAAA,EAAa,KAAA,CAAM,IAAA,CAAK,CAAA,CAAE,mBAAmB,CAAC,CAAA;AAAA,SAAA,IAC9C,WAAA,EAAa,KAAA,CAAM,IAAA,CAAK,CAAA,CAAE,mBAAmB,CAAC,CAAA;AAEvD,IAAA,IAAI,OAAA,IAAW,QAAQ,EAAA,KAAO,eAAA,QAAuB,IAAA,CAAK,CAAA,CAAE,iBAAiB,CAAC,CAAA;AAE9E,IAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AAAA,EAC1B,CAAA;AAKA,EAAA,MAAM,aAAa,MAAM;AACrB,IAAA,MAAM,OAAO,EAAC;AACd,IAAA,KAAA,IAAS,CAAA,GAAI,IAAA,GAAO,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AAChC,MAAA,MAAM,UAAU,EAAC;AACjB,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,IAAA,EAAM,CAAA,EAAA,EAAK;AAC3B,QAAA,MAAM,WAAA,GAAc,WAAW,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,CAAA,KAAM,CAAA,IAAK,CAAA,CAAE,CAAA,KAAM,CAAC,CAAA;AAC/D,QAAA,MAAM,WAAA,GAAc,YAAY,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,CAAA,KAAM,CAAA,IAAK,CAAA,CAAE,CAAA,KAAM,CAAC,CAAA;AAChE,QAAA,MAAM,cAAc,WAAA,IAAe,WAAA;AAKnC,QAAA,MAAM,oBAAoB,MAAA,GAAS,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO,KAAK,CAAA,GAAI,QAAA;AAChE,QAAA,MAAM,gBAAA,GAAmB,mBAAmB,IAAA,IAAQ,iBAAA,CAAkB,KAAK,CAAA,KAAM,CAAA,IAAK,iBAAA,CAAkB,IAAA,CAAK,CAAA,KAAM,CAAA;AACnH,QAAA,MAAM,cAAA,GAAmB,mBAAmB,EAAA,IAAQ,iBAAA,CAAkB,GAAG,CAAA,KAAQ,CAAA,IAAK,iBAAA,CAAkB,EAAA,CAAG,CAAA,KAAQ,CAAA;AACnH,QAAA,MAAM,aAAa,gBAAA,IAAoB,cAAA;AAGvC,QAAA,MAAM,eAAA,GAAkB,QAAA,KAAa,IAAA,KAC7B,CAAA,IAAK,KAAK,CAAA,IAAK,CAAA,CAAA,KACf,QAAA,KAAa,OAAA,GAAW,KAAK,EAAA,IAAM,CAAA,IAAK,EAAA,GAAO,CAAA,IAAK,KAAK,CAAA,IAAK,CAAA,CAAA;AAEtE,QAAA,MAAM,OAAA,GAAU,UAAA,CAAW,MAAA,CAAO,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,GAAA,CAAI,CAAA,KAAM,CAAA,IAAK,CAAA,CAAE,GAAA,CAAI,CAAA,KAAM,CAAC,CAAA;AAC1E,QAAA,MAAM,WAAW,WAAA,IAAe,MAAA,EAAQ,CAAA,KAAM,CAAA,IAAK,QAAQ,CAAA,KAAM,CAAA;AACjE,QAAA,MAAM,oBAAA,GAAuB,cAAA,EAAgB,CAAA,KAAM,CAAA,IAAK,gBAAgB,CAAA,KAAM,CAAA;AAE9E,QAAA,OAAA,CAAQ,IAAA;AAAA,0BACJJ,eAAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cAEG,EAAA,EAAI,MAAA,CAAO,CAAA,EAAG,CAAC,CAAA;AAAA,cACf,IAAA,EAAK,UAAA;AAAA,cACL,cAAY,WAAA,CAAY,CAAA,EAAG,CAAA,EAAG,OAAA,EAAS,aAAa,WAAW,CAAA;AAAA,cAC/D,eAAA,EAAe,CAAC,CAAC,OAAA,IAAW,QAAQ,EAAA,KAAO,eAAA;AAAA,cAC3C,OAAA,EAAS,MAAM,iBAAA,CAAkB,CAAA,EAAG,CAAA,EAAG,KAAK,GAAA,EAAI,GAAI,cAAA,CAAe,OAAA,GAAU,qBAAqB,CAAA;AAAA,cAClG,cAAc,MAAM;AAAE,gBAAA,IAAI,WAAA,EAAa,gBAAA,CAAiB,EAAE,CAAA,EAAG,GAAG,CAAA;AAAA,cAAE,CAAA;AAAA,cAClE,YAAA,EAAc,MAAM,gBAAA,CAAiB,IAAI,CAAA;AAAA,cAKzC,cAAc,MAAM;AAChB,gBAAA,cAAA,CAAe,OAAA,GAAU,KAAK,GAAA,EAAI;AAClC,gBAAA,IAAI,WAAA,EAAa,gBAAA,CAAiB,EAAE,CAAA,EAAG,GAAG,CAAA;AAAA,cAC9C,CAAA;AAAA,cACA,SAAA,EAAW,EAAA;AAAA,gBACP,gBAAA,CAAiB,GAAG,CAAC,CAAA;AAAA,gBACrB,iDAAA;AAAA,gBACA,CAAC,WAAA,IAAe,CAAC,WAAA,IAAe,UAAA,IAAc,2BAAA;AAAA;AAAA,gBAE9C,aAAA,IAAiB,eAAA,IAAmB,CAAC,WAAA,IAAe,CAAC,WAAA,IAAe,mCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAKpE,WAAA,IAAe,mEAAA;AAAA,gBACf,CAAC,eAAe,WAAA,IAAe,mEAAA;AAAA,gBAC/B,CAAC,eAAe,WAAA,IAAe;AAAA,eACnC;AAAA,cAKC,QAAA,EAAA;AAAA,gBAAA,CAAC,WAAA,IAAe,WAAA,IAAe,CAAC,OAAA,oBAC7BC,eAAC,KAAA,EAAA,EAAI,aAAA,EAAY,aAAA,EAAc,SAAA,EAAU,2CAAA,EAA4C,CAAA;AAAA,gBAExF,CAAC,WAAA,IAAe,WAAA,IAAe,CAAC,OAAA,oBAC7BA,cAAAA,CAAC,KAAA,EAAA,EAAI,aAAA,EAAY,aAAA,EAAc,SAAA,EAAU,4DAAA,EAA6D,CAAA;AAAA,gBAEzG,eAAe,CAAC,OAAA,oBACbD,eAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,2BAAA,EACX,QAAA,EAAA;AAAA,kCAAAC,cAAAA,CAAC,KAAA,EAAA,EAAI,aAAA,EAAY,aAAA,EAAc,WAAU,+CAAA,EAAgD,CAAA;AAAA,kCACzFA,cAAAA,CAAC,KAAA,EAAA,EAAI,aAAA,EAAY,aAAA,EAAc,WAAU,4DAAA,EAA6D;AAAA,iBAAA,EAC1G,CAAA;AAAA,gBAGH,4BACGA,cAAAA,CAAC,SAAI,SAAA,EAAU,wEAAA,EAAyE,eAAY,MAAA,EAAO,CAAA;AAAA,gBAG9G,oBAAA,IAAwB,mCACrBD,eAAAA;AAAA,kBAAC,KAAA;AAAA,kBAAA;AAAA,oBACG,SAAA,EAAW,EAAA;AAAA,sBACP,qIAAA;AAAA;AAAA;AAAA;AAAA,sBAIA,CAAA,KAAM,IAAA,GAAO,CAAA,GAAI,eAAA,GAAkB,kBAAA;AAAA,sBACnC,MAAM,CAAA,GACA,QAAA,GACA,CAAA,KAAM,IAAA,GAAO,IACT,SAAA,GACA;AAAA,qBACd;AAAA,oBACA,OAAA,EAAS,CAAA,CAAA,KAAK,CAAA,CAAE,eAAA,EAAgB;AAAA,oBAEhC,QAAA,EAAA;AAAA,sCAAAA,eAAAA;AAAA,wBAAC,QAAA;AAAA,wBAAA;AAAA,0BACG,SAAA,EAAU,sKAAA;AAAA,0BACV,SAAS,MAAM;AAAE,4BAAA,SAAA,CAAU,eAAA,EAAiB,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA;AAAG,4BAAA,iBAAA,CAAkB,IAAI,CAAA;AAAA,0BAAE,CAAA;AAAA,0BAE/E,QAAA,EAAA;AAAA,4CAAAC,cAAAA,CAACsB,gBAAA,EAAA,EAAK,IAAA,EAAM,EAAA,EAAI,aAAa,CAAA,EAAG,CAAA;AAAA,4BAC/B,EAAE,MAAM;AAAA;AAAA;AAAA,uBACb;AAAA,sCACAvB,eAAAA;AAAA,wBAAC,QAAA;AAAA,wBAAA;AAAA,0BACG,SAAA,EAAU,sKAAA;AAAA,0BACV,SAAS,MAAM;AAAE,4BAAA,QAAA,CAAS,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA;AAAG,4BAAA,iBAAA,CAAkB,IAAI,CAAA;AAAA,0BAAE,CAAA;AAAA,0BAE7D,QAAA,EAAA;AAAA,4CAAAC,eAAC,MAAA,EAAA,EAAK,SAAA,EAAU,uBAAsB,QAAA,kBAAAA,cAAAA,CAAC,YAAS,CAAA,EAAE,CAAA;AAAA,4BACjD,EAAE,MAAM;AAAA;AAAA;AAAA;AACb;AAAA;AAAA;AACJ;AAAA,aAAA;AAAA,YAjFC,CAAA,EAAG,CAAC,CAAA,CAAA,EAAI,CAAC,CAAA;AAAA;AAmFlB,SACJ;AAAA,MACJ;AACA,MAAA,IAAA,CAAK,IAAA;AAAA,wBACDA,cAAAA,CAAC,KAAA,EAAA,EAAqB,IAAA,EAAK,KAAA,EAAM,WAAU,UAAA,EACtC,QAAA,EAAA,OAAA,EAAA,EADK,CAAA,IAAA,EAAO,CAAC,CAAA,CAElB;AAAA,OACJ;AAAA,IACJ;AACA,IAAA,OAAO,IAAA;AAAA,EACX,CAAA;AAEA,EAAA,MAAM,wBACFD,eAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACG,aAAA,EAAY,YAAA;AAAA,MACZ,SAAA,EAAW,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAKP,8CAAA;AAAA;AAAA,QAEA,0EAAA;AAAA,QACA,mDAAA;AAAA,QACA,CAAC,eAAA,IAAmB;AAAA,OACxB;AAAA,MAOC,QAAA,EAAA;AAAA,QAAA,OAAA,oBACGA,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,+DAAA,EAAgE,eAAY,eAAA,EACvF,QAAA,EAAA;AAAA,0BAAAC,eAAC,cAAA,EAAA,EAAe,CAAA;AAAA,UAEf,+BACGD,eAAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACG,GAAA,EAAK,YAAA;AAAA,cACL,SAAA,EAAU,UAAA;AAAA,cAKV,WAAW,CAAA,CAAA,KAAK;AACZ,gBAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,QAAA,IAAY,aAAA,EAAe;AACrC,kBAAA,CAAA,CAAE,eAAA,EAAgB;AAClB,kBAAA,gBAAA,CAAiB,KAAK,CAAA;AAAA,gBAC1B;AAAA,cACJ,CAAA;AAAA,cAEA,QAAA,EAAA;AAAA,gCAAAC,cAAAA;AAAA,kBAAC,QAAA;AAAA,kBAAA;AAAA,oBACG,IAAA,EAAK,QAAA;AAAA,oBACL,OAAA,EAAS,CAAC,CAAA,KAAM;AAAE,sBAAA,CAAA,CAAE,eAAA,EAAgB;AAAG,sBAAA,gBAAA,CAAiB,CAAA,CAAA,KAAK,CAAC,CAAC,CAAA;AAAA,oBAAE,CAAA;AAAA,oBACjE,YAAA,EAAY,EAAE,uBAAuB,CAAA;AAAA,oBACrC,eAAA,EAAe,aAAA;AAAA,oBACf,SAAA,EAAU,4NAAA;AAAA,oBAEV,QAAA,kBAAAA,eAACuB,sBAAA,EAAA,EAAW,IAAA,EAAM,IAAI,WAAA,EAAa,CAAA,EAAG,eAAY,MAAA,EAAO;AAAA;AAAA,iBAC7D;AAAA,gBACC,iCACGxB,eAAAA;AAAA,kBAAC,KAAA;AAAA,kBAAA;AAAA,oBACG,SAAA,EAAU,oJAAA;AAAA,oBACV,OAAA,EAAS,CAAA,CAAA,KAAK,CAAA,CAAE,eAAA,EAAgB;AAAA,oBAEhC,QAAA,EAAA;AAAA,sCAAAC,eAAC,GAAA,EAAA,EAAE,SAAA,EAAU,6DAAA,EAA+D,QAAA,EAAA,CAAA,CAAE,iBAAiB,CAAA,EAAE,CAAA;AAAA,sCACjGA,eAAC,qBAAA,EAAA,EAAsB;AAAA;AAAA;AAAA;AAC3B;AAAA;AAAA;AAER,SAAA,EAER,CAAA;AAAA,wBAGJD,gBAAC,KAAA,EAAA,EAAI,SAAA,EAAU,YAAW,KAAA,EAAO,EAAE,aAAA,EAAe,aAAA,EAAc,EAM5D,QAAA,EAAA;AAAA,0BAAAC,cAAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACG,IAAA,EAAK,MAAA;AAAA,cACL,YAAA,EAAY,EAAE,gBAAgB,CAAA;AAAA,cAC9B,eAAA,EAAe,IAAA;AAAA,cACf,eAAA,EAAe,IAAA;AAAA,cACf,SAAA,EAAW,EAAA;AAAA,gBACP,4BAAA;AAAA,gBACA,WAAA,IAAe;AAAA,eACnB;AAAA,cACC,GAAI,WAAA,GACC;AAAA,gBACE,QAAA,EAAU,CAAA;AAAA,gBACV,SAAA,EAAW,aAAA;AAAA,gBACX,yBAAyB,MAAA,GAAS,MAAA,CAAO,OAAO,CAAA,EAAG,MAAA,CAAO,CAAC,CAAA,GAAI;AAAA,kBAEjE,EAAC;AAAA,cAEN,QAAA,EAAA,UAAA;AAAW;AAAA,WAChB;AAAA,0BAGAA,eAAC,YAAA,EAAA,EAAa,CAAA;AAAA,0BAGdA,eAAC,aAAA,EAAA,EAAc,CAAA;AAAA,0BAIfA,cAAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACG,OAAA,EAAQ,UAAA;AAAA,cACR,mBAAA,EAAoB,MAAA;AAAA,cACpB,SAAA,EAAU,oDAAA;AAAA,cACV,aAAA,EAAY,MAAA;AAAA,cAEX,QAAA,EAAA,aAAA,IAAiB,+BACdA,cAAAA;AAAA,gBAAC,MAAA;AAAA,gBAAA;AAAA,kBACG,aAAA,EAAY,sBAAA;AAAA,kBACZ,EAAA,EAAI,WAAA,CAAY,GAAA,CAAI,CAAA,GAAI,GAAA;AAAA,kBACxB,EAAA,EAAI,IAAA,GAAO,CAAA,GAAI,WAAA,CAAY,IAAI,CAAA,GAAI,GAAA;AAAA,kBACnC,EAAA,EAAI,cAAc,CAAA,GAAI,GAAA;AAAA,kBACtB,EAAA,EAAI,IAAA,GAAO,CAAA,GAAI,aAAA,CAAc,CAAA,GAAI,GAAA;AAAA,kBACjC,MAAA,EAAQ,wBAAwB,eAAA,GAAkB,uBAAA;AAAA,kBAClD,WAAA,EAAY,MAAA;AAAA,kBACZ,eAAA,EAAgB,UAAA;AAAA,kBAChB,aAAA,EAAc;AAAA;AAAA;AAClB;AAAA,WAER;AAAA,0BAIAD,gBAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wCAAuC,aAAA,EAAY,cAAA,EAAe,eAAY,MAAA,EACzF,QAAA,EAAA;AAAA,4BAAAC,eAACwB,4BAAA,EAAA,EAAgB,IAAA,EAAK,QACjB,QAAA,EAAA,UAAA,CAAW,MAAA,CAAO,IAAI,CAAA,KAAA,KAAS;AAC5B,cAAA,MAAM,eAAA,GAAkB,oBAAoB,KAAA,CAAM,EAAA;AAClD,cAAA,MAAM,kBAAkB,eAAA,GAClB,EAAE,UAAU,eAAA,EAAiB,IAAA,EAAM,UAAkB,GACrD,WAAA;AACN,cAAA,uBACIxB,cAAAA;AAAA,gBAACyB,mBAAA,CAAO,GAAA;AAAA,gBAAP;AAAA,kBAEG,iBAAe,KAAA,CAAM,EAAA;AAAA,kBACrB,OAAA,EAAS,KAAA;AAAA,kBACT,OAAA,EAAS,EAAE,CAAA,EAAG,KAAA,CAAM,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,EAAG,KAAA,CAAM,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,EAAE;AAAA,kBACxD,UAAA,EAAY,eAAA;AAAA,kBACZ,gBAAA,EAAkB,MAAM,SAAA,CAAU,KAAA,CAAM,IAAI,IAAI,CAAA;AAAA,kBAChD,mBAAA,EAAqB,MAAM,SAAA,CAAU,KAAA,CAAM,IAAI,KAAK,CAAA;AAAA,kBACpD,KAAA,EAAO;AAAA,oBACH,QAAA,EAAU,UAAA;AAAA,oBACV,IAAA,EAAM,CAAA;AAAA,oBACN,GAAA,EAAK,CAAA;AAAA,oBACL,KAAA,EAAO,CAAA,EAAG,GAAA,GAAM,IAAI,CAAA,CAAA,CAAA;AAAA,oBACpB,MAAA,EAAQ,CAAA,EAAG,GAAA,GAAM,IAAI,CAAA,CAAA,CAAA;AAAA,oBACrB,UAAA,EAAY;AAAA,mBAChB;AAAA,kBACA,SAAA,EAAU,sDAAA;AAAA,kBAEV,QAAA,kBAAAzB,cAAAA;AAAA,oBAAC,SAAA;AAAA,oBAAA;AAAA,sBACG,KAAA;AAAA,sBACA,UAAA,EAAY,oBAAoB,KAAA,CAAM,EAAA;AAAA,sBACtC,OAAA,EAAS,UAAA,CAAW,IAAA,CAAK,QAAA,KAAa,KAAA,CAAM,EAAA;AAAA,sBAC5C,QAAA,EAAU,SAAA,CAAU,GAAA,CAAI,KAAA,CAAM,EAAE,CAAA;AAAA,sBAChC,OAAA,EAAS,CAAC,CAAA,KAAwB,gBAAA,CAAiB,KAAA,CAAM,EAAA,EAAI,KAAA,CAAM,GAAA,CAAI,CAAA,EAAG,KAAA,CAAM,GAAA,CAAI,CAAA,EAAG,CAAC;AAAA;AAAA;AAC5F,iBAAA;AAAA,gBAvBK,KAAA,CAAM;AAAA,eAwBf;AAAA,YAER,CAAC,CAAA,EACL,CAAA;AAAA,YAAA,CAEE,MAAM;AACJ,cAAA,MAAM,OAAA,GAAU,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA;AAChC,cAAA,MAAM,OAAA,GAAU,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA;AAChC,cAAA,IAAI,OAAA;AACJ,cAAA,IAAI,UAAA;AACJ,cAAA,IAAI,kBAAkB,QAAA,EAAU;AAC5B,gBAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA;AAClC,gBAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA;AAClC,gBAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,CAAI,IAAA,EAAM,mBAAmB,IAAI,CAAA;AACzD,gBAAA,OAAA,GAAU;AAAA,kBACN,CAAA,EAAG,CAAC,KAAA,EAAO,KAAA,EAAO,OAAO,OAAO,CAAA;AAAA,kBAChC,CAAA,EAAG,CAAC,KAAA,EAAO,KAAA,EAAO,OAAO,OAAO,CAAA;AAAA,kBAChC,KAAA,EAAO,CAAC,CAAA,EAAG,CAAA,EAAG,MAAM,CAAC;AAAA,iBACzB;AACA,gBAAA,UAAA,GAAa,EAAE,QAAA,EAAU,eAAA,EAAiB,KAAA,EAAO,CAAC,CAAA,EAAG,UAAA,EAAY,gBAAA,EAAkB,CAAC,CAAA,EAAG,IAAA,EAAM,QAAA,EAAS;AAAA,cAC1G,CAAA,MAAO;AACH,gBAAA,OAAA,GAAU,EAAE,CAAA,EAAG,OAAA,EAAS,CAAA,EAAG,OAAA,EAAS,OAAO,CAAA,EAAE;AAC7C,gBAAA,UAAA,GAAa,IAAA,CAAK,WAAW,WAAA,GAAc,UAAA;AAAA,cAC/C;AACA,cAAA,uBACIA,cAAAA;AAAA,gBAACyB,mBAAA,CAAO,GAAA;AAAA,gBAAP;AAAA,kBAEG,OAAA,EAAS,KAAA;AAAA,kBACT,OAAA;AAAA,kBACA,UAAA;AAAA,kBACA,KAAA,EAAO;AAAA,oBACH,QAAA,EAAU,UAAA;AAAA,oBACV,IAAA,EAAM,CAAA;AAAA,oBACN,GAAA,EAAK,CAAA;AAAA,oBACL,KAAA,EAAO,CAAA,EAAG,GAAA,GAAM,IAAI,CAAA,CAAA,CAAA;AAAA,oBACpB,MAAA,EAAQ,CAAA,EAAG,GAAA,GAAM,IAAI,CAAA,CAAA,CAAA;AAAA,oBACrB,MAAA,EAAQ,EAAA;AAAA,oBACR,UAAA,EAAY;AAAA,mBAChB;AAAA,kBACA,SAAA,EAAU,sDAAA;AAAA,kBAEV,QAAA,kBAAAzB,eAAC,KAAA,EAAA,EAAI,SAAA,EAAU,mBAAkB,QAAA,kBAAAA,cAAAA,CAAC,YAAS,CAAA,EAAE;AAAA,iBAAA;AAAA,gBAfzC;AAAA,eAgBR;AAAA,YAER,CAAA,GAAG;AAAA,YAGF,kCACGA,cAAAA;AAAA,cAACyB,mBAAA,CAAO,GAAA;AAAA,cAAP;AAAA,gBAEG,aAAA,EAAY,sBAAA;AAAA,gBACZ,aAAA,EAAY,MAAA;AAAA,gBACZ,OAAA,EAAS,KAAA;AAAA,gBACT,SAAS,oBAAA,GAAuB,EAAE,SAAS,CAAC,GAAA,EAAK,CAAC,CAAA,EAAE,GAAI,EAAE,CAAA,EAAG,CAAC,CAAA,EAAG,EAAA,EAAI,GAAG,EAAA,EAAI,CAAA,EAAG,CAAC,CAAA,EAAE;AAAA,gBAClF,UAAA,EAAY,EAAE,QAAA,EAAU,IAAA,EAAK;AAAA,gBAC7B,KAAA,EAAO;AAAA,kBACH,QAAA,EAAU,UAAA;AAAA,kBACV,IAAA,EAAM,CAAA,EAAI,cAAA,CAAe,CAAA,GAAI,OAAQ,GAAG,CAAA,CAAA,CAAA;AAAA,kBACxC,KAAK,CAAA,EAAA,CAAK,IAAA,GAAO,IAAI,cAAA,CAAe,CAAA,IAAK,OAAQ,GAAG,CAAA,CAAA,CAAA;AAAA,kBACpD,KAAA,EAAO,CAAA,EAAG,GAAA,GAAM,IAAI,CAAA,CAAA,CAAA;AAAA,kBACpB,MAAA,EAAQ,CAAA,EAAG,GAAA,GAAM,IAAI,CAAA,CAAA;AAAA,iBACzB;AAAA,gBACA,SAAA,EAAU;AAAA,eAAA;AAAA,cAbL,cAAA,CAAe;AAAA;AAcxB,WAAA,EAER,CAAA;AAAA,UAGC,aAAA,oBACG1B,eAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,iPAAA,EAAkP,QAAA,EAAA;AAAA,YAAA,SAAA;AAAA,YAC1P,EAAE,gBAAgB;AAAA,WAAA,EACzB;AAAA,SAAA,EAGR;AAAA;AAAA;AAAA,GACJ;AAGJ,EAAA,IAAI,CAAC,iBAAiB,OAAO,KAAA;AAE7B,EAAA,MAAM,gBAAA,GAAmB,CAAC,GAAG2B,+BAAW,EAAE,OAAA,EAAQ;AAClD,EAAA,uBACI1B,eAAC,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,4CAAA,EAA8C,SAAS,GACtE,QAAA,kBAAAD,eAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACG,SAAA,EAAU,wBAAA;AAAA,MACV,KAAA,EAAO;AAAA,QACH,mBAAA,EAAqB,eAAA;AAAA,QACrB,gBAAA,EAAkB;AAAA,OACtB;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAAC,cAAAA,CAAC,MAAA,EAAA,EAAK,aAAA,EAAY,MAAA,EAAO,CAAA;AAAA,wBACzBA,cAAAA,CAAC,OAAA,EAAA,EAAQ,KAAA,EAAO2B,+BAAA,EAAa,CAAA;AAAA,wBAC7B3B,cAAAA,CAAC,MAAA,EAAA,EAAK,aAAA,EAAY,MAAA,EAAO,CAAA;AAAA,wBAEzBA,cAAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAO,gBAAA,EAAkB,CAAA;AAAA,wBACrCA,cAAAA,CAAC,KAAA,EAAA,EAAK,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,wBACZA,cAAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAO,gBAAA,EAAkB,CAAA;AAAA,wBAErCA,cAAAA,CAAC,MAAA,EAAA,EAAK,aAAA,EAAY,MAAA,EAAO,CAAA;AAAA,wBACzBA,cAAAA,CAAC,OAAA,EAAA,EAAQ,KAAA,EAAO2B,+BAAA,EAAa,CAAA;AAAA,wBAC7B3B,cAAAA,CAAC,MAAA,EAAA,EAAK,aAAA,EAAY,MAAA,EAAO;AAAA;AAAA;AAAA,GAC7B,EACJ,CAAA;AAER;AAEA,SAAS,OAAA,CAAQ,EAAE,KAAA,EAAM,EAAiC;AACtD,EAAA,uBACIA,cAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,qCAAA,EACV,QAAA,EAAA,KAAA,CAAM,IAAI,CAAA,CAAA,qBACPA,cAAAA,CAAC,MAAA,EAAA,EAAa,eAAY,MAAA,EAAO,SAAA,EAAU,qGACtC,QAAA,EAAA,CAAA,EAAA,EADM,CAEX,CACH,CAAA,EACL,CAAA;AAER;AAEA,SAAS,UAAA,CAAW,EAAE,KAAA,EAAM,EAAiC;AACzD,EAAA,uBACIA,cAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,sCAAA,EACV,QAAA,EAAA,KAAA,CAAM,IAAI,CAAA,CAAA,qBACPA,cAAAA,CAAC,MAAA,EAAA,EAAa,eAAY,MAAA,EAAO,SAAA,EAAU,uFACtC,QAAA,EAAA,CAAA,EAAA,EADM,CAEX,CACH,CAAA,EACL,CAAA;AAER;AC5zBO,SAAS,MAAA,CAAO,EAAE,SAAA,EAAW,QAAA,EAAS,EAAgB;AAC3D,EAAA,uBAAOA,eAAC,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,wDAAA,EAA0D,SAAS,GAAI,QAAA,EAAS,CAAA;AAC5G;AAEO,SAAS,WAAA,CAAY,EAAE,GAAA,EAAK,GAAA,EAAK,WAAU,EAAqB;AAGrE,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIW,eAAS,KAAK,CAAA;AAC1C,EAAAE,gBAAU,MAAM;AAAE,IAAA,SAAA,CAAU,KAAK,CAAA;AAAA,EAAE,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAE3C,EAAA,IAAI,CAAC,GAAA,IAAO,MAAA,EAAQ,OAAO,IAAA;AAC3B,EAAA,uBACEb,cAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,KAAK,GAAA,IAAO,EAAA;AAAA,MACZ,OAAA,EAAS,MAAM,SAAA,CAAU,IAAI,CAAA;AAAA,MAC7B,SAAA,EAAW,EAAA,CAAG,4BAAA,EAA8B,SAAS;AAAA;AAAA,GACvD;AAEJ;AAEO,SAAS,cAAA,CAAe,EAAE,SAAA,EAAW,QAAA,EAAS,EAAwB;AAC3E,EAAA,uBACEA,eAAC,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,yEAAA,EAA2E,SAAS,GACpG,QAAA,EACH,CAAA;AAEJ;ACpBO,SAAS,YAAA,CAAa,EAAE,KAAA,EAAO,SAAA,EAAW,OAAO,EAAA,EAAI,SAAA,EAAW,iBAAgB,EAAsB;AAC3G,EAAA,MAAM,IAAI,QAAA,EAAS;AAMnB,EAAA,MAAM,gBAAA,GAAmBY,aAAO,SAAS,CAAA;AACzC,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAID,eAAkC,IAAI,CAAA;AAC1E,EAAAE,gBAAU,MAAM;AACd,IAAA,MAAM,OAAO,gBAAA,CAAiB,OAAA;AAC9B,IAAA,gBAAA,CAAiB,OAAA,GAAU,SAAA;AAC3B,IAAA,IAAI,YAAY,IAAA,EAAM;AACpB,MAAA,aAAA,CAAc,CAAC,SAAA,EAAW,IAAA,GAAO,CAAC,CAAC,CAAA;AACnC,MAAA,MAAM,KAAK,UAAA,CAAW,MAAM,aAAA,CAAc,IAAI,GAAG,GAAG,CAAA;AACpD,MAAA,OAAO,MAAM,aAAa,EAAE,CAAA;AAAA,IAC9B;AACA,IAAA,aAAA,CAAc,IAAI,CAAA;AAAA,EACpB,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAEd,EAAA,uBACEb,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,2BAAA,EAA6B,SAAS,CAAA,EAAG,YAAA,EAAY,CAAA,CAAE,uBAAA,EAAyB,EAAE,SAAA,EAAW,OAAO,CAAA,EACpH,QAAA,EAAA,KAAA,CAAM,IAAA,CAAK,EAAE,MAAA,EAAQ,KAAA,EAAO,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,KAAM;AAC3C,IAAA,MAAM,WAAW,CAAA,GAAI,SAAA;AACrB,IAAA,MAAM,SAAA,GAAY,eAAA,IAAmB,CAAA,KAAM,KAAA,GAAQ,CAAA;AACnD,IAAA,MAAM,SAAA,GAAY,CAAC,CAAC,UAAA,IAAc,CAAA,IAAK,WAAW,CAAC,CAAA,IAAK,CAAA,IAAK,UAAA,CAAW,CAAC,CAAA;AAEzE,IAAA,uBACEA,cAAAA;AAAA,MAACyB,mBAAAA,CAAO,IAAA;AAAA,MAAP;AAAA,QAEC,aAAA,EAAa,UAAU,CAAC,CAAA,CAAA;AAAA,QACxB,cAAY,SAAA,IAAa,MAAA;AAAA,QACzB,SAAA,EAAU,aAAA;AAAA,QACV,OAAA,EAAS,YAAY,EAAE,KAAA,EAAO,CAAC,GAAA,EAAK,CAAC,GAAE,GAAI,MAAA;AAAA,QAC3C,UAAA,EAAY,EAAE,QAAA,EAAU,GAAA,EAAI;AAAA,QAE3B,sCACCzB,cAAAA;AAAA,UAAC4B,iBAAA;AAAA,UAAA;AAAA,YACC,IAAA;AAAA,YACA,WAAA,EAAa,CAAA;AAAA,YACb,SAAA,EAAU,gEAAA;AAAA,YACV,aAAA,EAAY;AAAA;AAAA,4BAGd5B,cAAAA;AAAA,UAAC6B,eAAA;AAAA,UAAA;AAAA,YACC,IAAA;AAAA,YACA,WAAA,EAAa,CAAA;AAAA,YACb,SAAA,EAAW,EAAA;AAAA,cACT,gCAAA;AAAA,cACA,WAAW,qCAAA,GAAwC;AAAA,aACrD;AAAA,YACA,aAAA,EAAY;AAAA;AAAA;AACd,OAAA;AAAA,MAvBG;AAAA,KAyBP;AAAA,EAEJ,CAAC,CAAA,EACH,CAAA;AAEJ;AC/CO,SAAS,cAAA,CAAe;AAAA,EAC7B,IAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA,GAAU,MAAA;AAAA,EACV,QAAA,GAAW,KAAA;AAAA,EACX,KAAA,GAAQ,MAAA;AAAA,EACR,SAAA;AAAA,EACA;AACF,CAAA,EAAwB;AACtB,EAAA,IAAI,YAAY,SAAA,EAAW;AACzB,IAAA,uBACE9B,eAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,EAAA;AAAA,UACT,2DAAA;AAAA,UACA,WAAW,mBAAA,GAAsB,eAAA;AAAA,UACjC;AAAA,SACF;AAAA,QAEC,QAAA,EAAA;AAAA,UAAA,IAAA;AAAA,0BACDA,eAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,oDAAA,EAAqD,QAAA,EAAA;AAAA,YAAA,QAAA;AAAA,YAAI;AAAA,WAAA,EAAK;AAAA;AAAA;AAAA,KAChF;AAAA,EAEJ;AAEA,EAAA,uBACEA,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,+BAA+B,KAAA,KAAU,OAAA,IAAW,WAAA,EAAa,SAAS,CAAA,EAC3F,QAAA,EAAA;AAAA,oBAAAC,cAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,EAAA;AAAA,UACT,2FAAA;AAAA,UACA,WAAW,iBAAA,GAAoB;AAAA,SACjC;AAAA,QAEC,QAAA,EAAA;AAAA;AAAA,KACH;AAAA,oBACAD,gBAAC,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,yBAAA,EAA2B,KAAA,KAAU,OAAA,IAAW,kBAAkB,CAAA,EACnF,QAAA,EAAA;AAAA,sBAAAC,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,gEAAA,EAAkE,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,MACtF;AAAA,KAAA,EACH;AAAA,GAAA,EACF,CAAA;AAEJ;AClDA,SAAS,SAAS,IAAA,EAAc;AAC9B,EAAA,OAAA,CAAQ,MAAM,KAAA,CAAM,GAAG,EAAE,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,CAAC,CAAC,CAAA,CAAE,IAAA,CAAK,EAAE,CAAA,CAAE,WAAA,MAAiB,GAAA,EAAK,KAAA,CAAM,GAAG,CAAC,CAAA;AACnF;AAEe,SAAR,UAAA,CAA4B;AAAA,EACjC,eAAA;AAAA,EACA,gBAAA;AAAA,EACA,gBAAA;AAAA,EACA,iBAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAAoB;AAClB,EAAA,MAAM,IAAI,QAAA,EAAS;AACnB,EAAA,MAAM,UAAA,GAAaO,8BAAA,CAAa,CAAA,CAAA,KAAK,CAAA,CAAE,UAAU,CAAA;AACjD,EAAA,IAAI,CAAC,UAAA,EAAY,KAAA,EAAO,OAAO,IAAA;AAE/B,EAAA,MAAM,EAAE,KAAA,EAAO,IAAA,EAAM,YAAA,EAAc,iBAAgB,GAAI,UAAA;AAGvD,EAAA,MAAM,OAAA,GAAa,QAAA,KAAa,OAAA,GAAU,KAAA,CAAM,QAAQ,KAAA,CAAM,KAAA;AAC9D,EAAA,MAAM,UAAA,GAAa,QAAA,KAAa,OAAA,GAAU,KAAA,CAAM,QAAQ,KAAA,CAAM,KAAA;AAC9D,EAAA,MAAM,MAAA,GAAa,QAAA,KAAa,OAAA,GAAU,eAAA,GAAkB,gBAAA;AAC5D,EAAA,MAAM,SAAA,GAAa,QAAA,KAAa,OAAA,GAAU,gBAAA,GAAmB,eAAA;AAC7D,EAAA,MAAM,QAAA,GAAa,QAAA,KAAa,OAAA,GAAU,gBAAA,GAAmB,iBAAA;AAC7D,EAAA,MAAM,WAAA,GAAa,QAAA,KAAa,OAAA,GAAU,iBAAA,GAAoB,gBAAA;AAC9D,EAAA,MAAM,SAAa,QAAA,KAAa,OAAA,GAAU,EAAE,WAAW,CAAA,GAAI,EAAE,WAAW,CAAA;AACxE,EAAA,MAAM,YAAa,QAAA,KAAa,OAAA,GAAU,EAAE,WAAW,CAAA,GAAI,EAAE,WAAW,CAAA;AACxE,EAAA,MAAM,WAAa,IAAA,KAAS,QAAA;AAC5B,EAAA,MAAM,iBAAA,GAAuB,YAAa,eAAA,KAAoB,IAAA;AAC9D,EAAA,MAAM,oBAAA,GAAuB,CAAC,QAAA,IAAY,eAAA,KAAoB,IAAA;AAE9D,EAAA,MAAM,KAAA,GAAQ,WAAW,eAAA,IAAmBuB,gCAAA;AAE5C,EAAA,uBACE/B,eAAAA,CAAC,KAAA,EAAA,EAAI,WAAW,EAAA,CAAG,sEAAA,EAAwE,SAAS,CAAA,EAElG,QAAA,EAAA;AAAA,oBAAAC,cAAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,MAAA;AAAA,QACN,IAAA,EAAM,MAAA;AAAA,QACN,SAAA,EAAW,QAAA;AAAA,QACX,QAAA,EAAU,QAAA;AAAA,QACV,YAAA,EAAc,WAAW,YAAA,GAAe,CAAA;AAAA,QACxC,eAAA,EAAiB,KAAA;AAAA,QACjB,eAAA,EAAiB,iBAAA;AAAA,QACjB,KAAA,EAAM;AAAA;AAAA,KACR;AAAA,oBAKAD,eAAAA,CAAC,KAAA,EAAA,EAAI,IAAA,EAAK,QAAA,EAAS,aAAU,QAAA,EAAS,aAAA,EAAY,MAAA,EAAO,SAAA,EAAU,yBAAA,EACjE,QAAA,EAAA;AAAA,sBAAAC,eAAC,MAAA,EAAA,EAAK,aAAA,EAAY,MAAA,EAAO,SAAA,EAAU,oEAChC,QAAA,EAAA,OAAA,EACH,CAAA;AAAA,sBACAA,cAAAA,CAAC,MAAA,EAAA,EAAK,eAAY,MAAA,EAAO,SAAA,EAAU,qCAAoC,QAAA,EAAA,QAAA,EAAC,CAAA;AAAA,sBACxEA,cAAAA,CAAC,MAAA,EAAA,EAAK,eAAY,MAAA,EAAO,SAAA,EAAU,oEAChC,QAAA,EAAA,UAAA,EACH,CAAA;AAAA,sBACAA,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,WACb,QAAA,EAAA,CAAA,CAAE,gBAAA,EAAkB,EAAE,EAAA,EAAI,QAAQ,OAAA,EAAS,KAAA,EAAO,SAAA,EAAW,UAAA,EAAY,CAAA,EAC5E;AAAA,KAAA,EACF,CAAA;AAAA,oBAGAA,cAAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,SAAA;AAAA,QACN,IAAA,EAAM,SAAA;AAAA,QACN,SAAA,EAAW,WAAA;AAAA,QACX,UAAU,CAAC,QAAA;AAAA,QACX,YAAA,EAAc,CAAC,QAAA,GAAW,YAAA,GAAe,CAAA;AAAA,QACzC,eAAA,EAAiB,KAAA;AAAA,QACjB,eAAA,EAAiB,oBAAA;AAAA,QACjB,KAAA,EAAM;AAAA;AAAA;AACR,GAAA,EACF,CAAA;AAEJ;AAaA,SAAS,UAAA,CAAW,EAAE,IAAA,EAAM,IAAA,EAAM,SAAA,EAAW,UAAU,YAAA,EAAc,eAAA,EAAiB,eAAA,EAAiB,KAAA,EAAM,EAAoB;AAC/H,EAAA,uBACED,gBAAC,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,2BAAA,EAA6B,KAAA,KAAU,OAAA,IAAW,kBAAkB,CAAA,EACrF,QAAA,EAAA;AAAA,oBAAAA,eAAAA,CAAC,UAAO,SAAA,EAAW,EAAA;AAAA,MACjB,iDAAA;AAAA,MACA,WAAW,qBAAA,GAAwB;AAAA,KACrC,EACE,QAAA,EAAA;AAAA,sBAAAC,eAAC,WAAA,EAAA,EAAY,GAAA,EAAK,WAAW,GAAA,EAAK,IAAA,EAAM,WAAU,cAAA,EAAe,CAAA;AAAA,sBACjEA,cAAAA,CAAC,cAAA,EAAA,EAAe,WAAU,gEAAA,EACvB,QAAA,EAAA,QAAA,CAAS,IAAI,CAAA,EAChB;AAAA,KAAA,EACF,CAAA;AAAA,oBAEAD,gBAAC,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,qBAAA,EAAuB,KAAA,KAAU,OAAA,IAAW,WAAW,CAAA,EACxE,QAAA,EAAA;AAAA,sBAAAC,cAAAA;AAAA,QAAC,cAAA;AAAA,QAAA;AAAA,UACC,IAAA;AAAA,UACA,IAAA;AAAA,UACA,QAAA;AAAA,UACA,KAAA;AAAA,UACA,SAAA,EAAW,2BACTA,cAAAA,CAAC,UAAK,SAAA,EAAU,mFAAA,EAAoF,aAAA,EAAY,MAAA,EAAO,CAAA,GACrH;AAAA;AAAA,OACN;AAAA,sBACAA,cAAAA;AAAA,QAAC,YAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAO,eAAA;AAAA,UACP,SAAA,EAAW,YAAA;AAAA,UACX,IAAA,EAAM,EAAA;AAAA,UACN,eAAA;AAAA,UACA,SAAA,EAAU;AAAA;AAAA;AACZ,KAAA,EACF;AAAA,GAAA,EACF,CAAA;AAEJ;AC1HO,SAAS,cAAA,CAAe;AAAA,EAC3B,eAAA;AAAA,EACA,gBAAA;AAAA,EACA,QAAA;AAAA,EACA;AACJ,CAAA,EAAwB;AACpB,EAAA,MAAM,IAAI,QAAA,EAAS;AACnB,EAAA,MAAM,UAAA,GAAaO,8BAAA,CAAa,CAAA,CAAA,KAAK,CAAA,CAAE,UAAU,CAAA;AACjD,EAAA,IAAI,CAAC,UAAA,EAAY,KAAA,EAAO,OAAO,IAAA;AAE/B,EAAA,MAAM,EAAE,KAAA,EAAO,IAAA,EAAK,GAAI,UAAA;AAExB,EAAA,MAAM,OAAA,GAAa,QAAA,KAAa,OAAA,GAAU,KAAA,CAAM,QAAQ,KAAA,CAAM,KAAA;AAC9D,EAAA,MAAM,UAAA,GAAa,QAAA,KAAa,OAAA,GAAU,KAAA,CAAM,QAAQ,KAAA,CAAM,KAAA;AAC9D,EAAA,MAAM,MAAA,GAAa,QAAA,KAAa,OAAA,GAAU,eAAA,GAAkB,gBAAA;AAC5D,EAAA,MAAM,SAAA,GAAa,QAAA,KAAa,OAAA,GAAU,gBAAA,GAAmB,eAAA;AAC7D,EAAA,MAAM,SAAa,QAAA,KAAa,OAAA,GAAU,EAAE,WAAW,CAAA,GAAI,EAAE,WAAW,CAAA;AACxE,EAAA,MAAM,YAAa,QAAA,KAAa,OAAA,GAAU,EAAE,WAAW,CAAA,GAAI,EAAE,WAAW,CAAA;AACxE,EAAA,MAAM,WAAa,IAAA,KAAS,QAAA;AAE5B,EAAA,uBACIR,eAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACG,IAAA,EAAK,QAAA;AAAA,MACL,WAAA,EAAU,QAAA;AAAA,MACV,aAAA,EAAY,MAAA;AAAA,MACZ,SAAA,EAAW,EAAA;AAAA,QACP,2EAAA;AAAA,QACA,mDAAA;AAAA,QACA;AAAA,OACJ;AAAA,MAKA,QAAA,EAAA;AAAA,wBAAAA,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,UAAA,EAAW,eAAY,MAAA,EAClC,QAAA,EAAA;AAAA,0BAAAC,cAAAA,CAAC,QAAA,EAAA,EAAS,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,OAAA,EAAS,QAAA,EAAU,QAAA,EAAU,KAAA,EAAM,MAAA,EAAO,CAAA;AAAA,0BAEvFA,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,+DAA8D,QAAA,EAAA,IAAA,EAE9E,CAAA;AAAA,0BAEAA,cAAAA,CAAC,QAAA,EAAA,EAAS,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM,SAAA,EAAW,KAAA,EAAO,UAAA,EAAY,QAAA,EAAU,CAAC,QAAA,EAAU,OAAM,OAAA,EAAQ;AAAA,SAAA,EACtG,CAAA;AAAA,wBAEAA,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,WACX,QAAA,EAAA,CAAA,CAAE,gBAAA,EAAkB,EAAE,EAAA,EAAI,QAAQ,OAAA,EAAS,KAAA,EAAO,SAAA,EAAW,UAAA,EAAY,CAAA,EAC9E;AAAA;AAAA;AAAA,GACJ;AAER;AAUA,SAAS,SAAS,EAAE,IAAA,EAAM,MAAM,KAAA,EAAO,QAAA,EAAU,OAAM,EAAkB;AACrE,EAAA,uBACID,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,yBAAyB,KAAA,KAAU,OAAA,GAAU,WAAA,GAAc,aAAa,CAAA,EACvF,QAAA,EAAA;AAAA,oBAAAC,eAAC,cAAA,EAAA,EAAe,IAAA,EAAY,IAAA,EAAY,OAAA,EAAQ,WAAU,QAAA,EAAoB,CAAA;AAAA,oBAC9EA,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAW,EAAA;AAAA,MACb,kDAAA;AAAA,MACA,WAAW,iBAAA,GAAoB;AAAA,OAE9B,QAAA,EAAA,KAAA,EACL;AAAA,GAAA,EACJ,CAAA;AAER;ACjFA,IAAM,OAAA,GAAmC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMvC,OAAA,EACE,+HAAA;AAAA,EAEF,SAAA,EACE,mJAAA;AAAA,EAEF,KAAA,EACE,+GAAA;AAAA,EAEF,WAAA,EACE;AAEJ,CAAA;AAEA,IAAM,IAAA,GAA6B;AAAA,EACjC,OAAA,EAAS,kCAAA;AAAA,EACT,EAAA,EAAI,+BAAA;AAAA,EACJ,EAAA,EAAI,gCAAA;AAAA,EACJ,IAAA,EAAM;AACR,CAAA;AAOO,IAAM,MAAA,GAAe+B,gBAAA,CAAA,UAAA;AAAA,EAC1B,CAAC,EAAE,SAAA,EAAW,OAAA,GAAU,SAAA,EAAW,IAAA,GAAO,SAAA,EAAW,GAAG,KAAA,EAAM,EAAG,GAAA,qBAC/D/B,cAAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,SAAA,EAAW,EAAA;AAAA,QACT,6FAAA;AAAA,QACA,kJAAA;AAAA,QACA,kDAAA;AAAA,QACA,8CAAA;AAAA,QACA,QAAQ,OAAO,CAAA;AAAA,QACf,KAAK,IAAI,CAAA;AAAA,QACT;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA;AAGV;AACA,MAAA,CAAO,WAAA,GAAc,QAAA;AChDrB,IAAM,SAAA,GAAY;AAAA,EAChB,SAAA;AAAA,EACA,wBAAA;AAAA,EACA,uBAAA;AAAA,EACA,wBAAA;AAAA,EACA,0BAAA;AAAA,EACA;AACF,CAAA,CAAE,KAAK,GAAG,CAAA;AAOV,SAAS,gBAAgB,KAAA,EAAmC;AAC1D,EAAA,OAAO,MAAM,IAAA,CAAK,KAAA,CAAM,gBAAA,CAA8B,SAAS,CAAC,CAAA,CAAE,MAAA;AAAA,IAChE,CAAA,EAAA,KAAM,CAAC,EAAA,CAAG,OAAA,CAAQ,UAAU,CAAA,IAAK,CAAC,EAAA,CAAG,OAAA,CAAQ,sBAAsB;AAAA,GACrE;AACF;AAoBO,SAAS,aAAA,CAAc,EAAE,IAAA,EAAM,OAAA,EAAQ,EAAsB;AAClE,EAAA,MAAM,QAAA,GAAWY,aAA8B,IAAI,CAAA;AACnD,EAAA,MAAM,YAAA,GAAeA,aAA2B,IAAI,CAAA;AAIpD,EAAA,MAAM,UAAA,GAAaA,aAAO,OAAO,CAAA;AACjC,EAAAC,gBAAU,MAAM;AAAE,IAAA,UAAA,CAAW,OAAA,GAAU,OAAA;AAAA,EAAQ,CAAC,CAAA;AAEhD,EAAAA,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,MAAM,QAAQ,QAAA,CAAS,OAAA;AACvB,IAAA,IAAI,CAAC,KAAA,EAAO;AAEZ,IAAA,YAAA,CAAa,UAAU,QAAA,CAAS,aAAA;AAEhC,IAAA,MAAM,OAAA,GAAU,eAAA,CAAgB,KAAK,CAAA,CAAE,CAAC,CAAA;AACxC,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,OAAA,CAAQ,KAAA,EAAM;AAAA,IAChB,CAAA,MAAO;AACL,MAAA,KAAA,CAAM,QAAA,GAAW,EAAA;AACjB,MAAA,KAAA,CAAM,KAAA,EAAM;AAAA,IACd;AAEA,IAAA,MAAM,SAAA,GAAY,CAAC,CAAA,KAAqB;AACtC,MAAA,IAAI,CAAA,CAAE,QAAQ,QAAA,EAAU;AACtB,QAAA,CAAA,CAAE,eAAA,EAAgB;AAClB,QAAA,UAAA,CAAW,OAAA,EAAQ;AACnB,QAAA;AAAA,MACF;AACA,MAAA,IAAI,CAAA,CAAE,QAAQ,KAAA,EAAO;AAErB,MAAA,MAAM,KAAA,GAAQ,gBAAgB,KAAK,CAAA;AACnC,MAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA;AAAA,MACF;AACA,MAAA,MAAM,KAAA,GAAQ,MAAM,CAAC,CAAA;AACrB,MAAA,MAAM,IAAA,GAAO,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA;AACnC,MAAA,MAAM,SAAS,QAAA,CAAS,aAAA;AAExB,MAAA,IAAI,CAAA,CAAE,aAAa,MAAA,KAAW,KAAA,IAAS,CAAC,KAAA,CAAM,QAAA,CAAS,MAAM,CAAA,CAAA,EAAI;AAC/D,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,IAAA,CAAK,KAAA,EAAM;AAAA,MACb,CAAA,MAAA,IAAW,CAAC,CAAA,CAAE,QAAA,KAAa,MAAA,KAAW,QAAQ,CAAC,KAAA,CAAM,QAAA,CAAS,MAAM,CAAA,CAAA,EAAI;AACtE,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,KAAA,CAAM,KAAA,EAAM;AAAA,MACd;AAAA,IACF,CAAA;AAEA,IAAA,QAAA,CAAS,gBAAA,CAAiB,SAAA,EAAW,SAAA,EAAW,IAAI,CAAA;AACpD,IAAA,OAAO,MAAM;AACX,MAAA,QAAA,CAAS,mBAAA,CAAoB,SAAA,EAAW,SAAA,EAAW,IAAI,CAAA;AACvD,MAAA,YAAA,CAAa,SAAS,KAAA,IAAQ;AAAA,IAChC,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAA,OAAO,QAAA;AACT;ACxFO,SAAS,aAAA,CAAc,EAAE,IAAA,EAAM,KAAA,EAAO,aAAa,YAAA,EAAc,WAAA,EAAa,SAAA,EAAW,QAAA,EAAS,EAAuB;AAC9H,EAAA,MAAM,SAASZ,WAAAA,EAAM;AACrB,EAAA,MAAM,OAAA,GAAU,GAAG,MAAM,CAAA,MAAA,CAAA;AACzB,EAAA,MAAM,MAAA,GAAS,GAAG,MAAM,CAAA,KAAA,CAAA;AAGxB,EAAA,MAAM,WAAW,aAAA,CAAc,EAAE,IAAA,EAAM,OAAA,EAAS,UAAU,CAAA;AAE1D,EAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,EAAA,uBACED,cAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAU,kFAAA;AAAA,MACV,OAAA,EAAS,QAAA;AAAA,MAET,QAAA,kBAAAD,eAAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,GAAA,EAAK,QAAA;AAAA,UACL,IAAA,EAAK,QAAA;AAAA,UACL,YAAA,EAAW,MAAA;AAAA,UACX,iBAAA,EAAiB,OAAA;AAAA,UACjB,kBAAA,EAAkB,cAAc,MAAA,GAAS,MAAA;AAAA,UACzC,OAAA,EAAS,CAAA,CAAA,KAAK,CAAA,CAAE,eAAA,EAAgB;AAAA,UAChC,SAAA,EAAW,EAAA;AAAA,YACT,+EAAA;AAAA,YACA,gCAAA;AAAA,YACA;AAAA,WACF;AAAA,UAEA,QAAA,EAAA;AAAA,4BAAAC,eAAC,IAAA,EAAA,EAAG,EAAA,EAAI,OAAA,EAAS,SAAA,EAAU,8DAA8D,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,YAC9F,WAAA,oBAAeA,cAAAA,CAAC,GAAA,EAAA,EAAE,IAAI,MAAA,EAAQ,SAAA,EAAU,wCAAwC,QAAA,EAAA,WAAA,EAAY,CAAA;AAAA,4BAC7FD,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iBAAA,EACb,QAAA,EAAA;AAAA,8BAAAC,cAAAA,CAAC,UAAO,OAAA,EAAQ,WAAA,EAAY,WAAU,QAAA,EAAS,OAAA,EAAS,UAAW,QAAA,EAAA,WAAA,EAAY,CAAA;AAAA,8BAC/EA,eAAC,MAAA,EAAA,EAAO,OAAA,EAAQ,WAAU,SAAA,EAAU,QAAA,EAAS,OAAA,EAAS,SAAA,EAAY,QAAA,EAAA,YAAA,EAAa;AAAA,aAAA,EACjF;AAAA;AAAA;AAAA;AACF;AAAA,GACF;AAEJ;ACtCe,SAAR,YAAA,CAA8B,EAAE,QAAA,EAAU,SAAA,EAAU,EAAsB;AAC/E,EAAA,MAAM,UAAA,GAAaO,8BAAA,CAAa,CAAA,CAAA,KAAK,CAAA,CAAE,UAAU,CAAA;AACjD,EAAA,MAAM,OAAA,GAAUA,8BAAA,CAAa,CAAA,CAAA,KAAK,CAAA,CAAE,OAAO,CAAA;AAE3C,EAAA,MAAM,IAAI,QAAA,EAAS;AACnB,EAAA,MAAM,CAAC,kBAAA,EAAoB,qBAAqB,CAAA,GAAII,eAAS,KAAK,CAAA;AAElE,EAAA,IAAI,CAAC,YAAY,OAAO,IAAA;AAExB,EAAA,MAAM,eAAe,UAAA,CAAW,YAAA;AAGhC,EAAA,MAAM,gBAAgB,MAAM;AAC1B,IAAA,IAAI,gBAAgB,CAAA,EAAG;AACrB,MAAA,qBAAA,CAAsB,IAAI,CAAA;AAAA,IAC5B,CAAA,MAAO;AACL,MAAA,OAAA,EAAQ;AAAA,IACV;AAAA,EACF,CAAA;AAEA,EAAA,uBACEZ,eAAAA,CAAC,KAAA,EAAA,EAAI,WAAW,EAAA,CAAG,2DAAA,EAA6D,SAAS,CAAA,EAEtF,QAAA,EAAA;AAAA,IAAA,QAAA,oBACCA,eAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAQ,SAAA;AAAA,QACR,IAAA,EAAK,SAAA;AAAA,QACL,SAAA,EAAU,+BAAA;AAAA,QACV,OAAA,EAAS,aAAA;AAAA,QAET,QAAA,EAAA;AAAA,0BAAAC,cAAAA,CAACgC,gBAAA,EAAA,EAAK,IAAA,EAAM,EAAA,EAAI,aAAa,CAAA,EAAG,CAAA;AAAA,UAC/B,EAAE,SAAS,CAAA;AAAA,UACX,YAAA,IAAgB,qBACfjC,eAAAA,CAAC,UAAK,SAAA,EAAW,EAAA,CAAG,gEAAgE,CAAA,EAAG,QAAA,EAAA;AAAA,YAAA,OAAA;AAAA,YAClF,YAAA;AAAA,YAAa,GAAA;AAAA,YAAE,EAAE,mBAAmB;AAAA,WAAA,EACzC;AAAA;AAAA;AAAA,KAEJ;AAAA,IAID,CAAC,4BACAC,cAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,WAAA,EAAU,QAAA;AAAA,QACV,SAAA,EAAU,4FAAA;AAAA,QAEV,0BAAAA,cAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,kCAAA,EAAoC,QAAA,EAAA,CAAA,CAAE,cAAc,CAAA,EAAE;AAAA;AAAA,KACxE;AAAA,oBAGFA,cAAAA;AAAA,MAAC,aAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,kBAAA;AAAA,QACN,KAAA,EAAO,EAAE,gBAAgB,CAAA;AAAA,QACzB,aAAa,CAAA,CAAE,2BAAA,EAA6B,EAAE,KAAA,EAAO,cAAc,CAAA;AAAA,QACnE,YAAA,EAAc,EAAE,mBAAmB,CAAA;AAAA,QACnC,WAAA,EAAa,EAAE,oBAAoB,CAAA;AAAA,QACnC,WAAW,MAAM;AAAE,UAAA,OAAA,EAAQ;AAAG,UAAA,qBAAA,CAAsB,KAAK,CAAA;AAAA,QAAE,CAAA;AAAA,QAC3D,QAAA,EAAU,MAAM,qBAAA,CAAsB,KAAK;AAAA;AAAA;AAC7C,GAAA,EACF,CAAA;AAEJ;AC1DA,IAAMiC,WAAAA,GAA4C;AAAA,EAC9C,IAAA,EAAMxC,qBAAAA;AAAA,EACN,KAAA,EAAOC,sBAAAA;AAAA,EACP,IAAA,EAAMC,qBAAAA;AAAA,EACN,MAAA,EAAQC,uBAAAA;AAAA,EACR,MAAA,EAAQC;AACZ,CAAA;AAWO,SAAS,mBAAA,CAAoB,EAAE,QAAA,EAAU,SAAA,EAAU,EAA6B;AACnF,EAAA,MAAM,IAAI,QAAA,EAAS;AACnB,EAAA,MAAM,EAAE,UAAA,EAAY,eAAA,EAAgB,GAAIU,8BAAA;AAAA,IACpCG,kBAAAA,CAAW,QAAM,EAAE,UAAA,EAAY,EAAE,UAAA,EAAY,eAAA,EAAiB,CAAA,CAAE,eAAA,EAAgB,CAAE;AAAA,GACtF;AAEA,EAAA,IAAI,CAAC,YAAY,OAAO,IAAA;AAExB,EAAA,MAAM,QAA2B,UAAA,CAAW,MAAA,CAAO,KAAK,CAAA,CAAA,KAAK,CAAA,CAAE,OAAO,eAAe,CAAA;AAErF,EAAA,IAAI,CAAC,KAAA,EAAO;AACR,IAAA,uBACIX,eAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACG,SAAA,EAAW,EAAA;AAAA,UACP,uEAAA;AAAA,UACA,mCAAA;AAAA,UACA;AAAA,SACJ;AAAA,QAEA,QAAA,EAAA;AAAA,0BAAAC,cAAAA,CAACF,4BAAA,EAAe,IAAA,EAAM,IAAI,SAAA,EAAU,wBAAA,EAAyB,eAAY,MAAA,EAAO,CAAA;AAAA,0BAChFE,cAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,qCAAA,EACX,QAAA,EAAA,CAAA,CAAE,qBAAqB,CAAA,EAC5B;AAAA;AAAA;AAAA,KACJ;AAAA,EAER;AAEA,EAAA,MAAM,IAAA,GAAOiC,WAAAA,CAAW,KAAA,CAAM,IAAI,CAAA,IAAKnC,0BAAAA;AACvC,EAAA,MAAM,WAAW,CAAA,CAAE,CAAA,OAAA,EAAUK,6BAAS,KAAA,CAAM,IAAI,CAAC,CAAA,CAAE,CAAA;AACnD,EAAA,MAAM,MAAA,GAASkB,8BAAAA,CAAW,KAAA,CAAM,GAAG,CAAA;AACnC,EAAA,MAAM,OAAA,GAAU,UAAA,CAAW,IAAA,CAAK,QAAA,KAAa,KAAA,CAAM,EAAA;AACnD,EAAA,MAAM,aAAA,GAAgB,MAAM,gBAAA,IAAoB,QAAA;AAEhD,EAAA,uBACItB,eAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACG,SAAA,EAAW,EAAA;AAAA,QACP,sDAAA;AAAA,QACA,mCAAA;AAAA,QACA;AAAA,OACJ;AAAA,MACA,IAAA,EAAK,QAAA;AAAA,MACL,WAAA,EAAU,QAAA;AAAA,MAEV,QAAA,EAAA;AAAA,wBAAAC,cAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACG,SAAA,EAAW,EAAA;AAAA,cACP,kEAAA;AAAA,cACA,KAAA,CAAM,IAAA,KAAS,OAAA,GAAU,qBAAA,GAAwB;AAAA,aACrD;AAAA,YAEA,QAAA,kBAAAA,eAAC,IAAA,EAAA,EAAK,IAAA,EAAM,IAAI,WAAA,EAAa,IAAA,EAAM,eAAY,MAAA,EAAO;AAAA;AAAA,SAC1D;AAAA,wBAEAD,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,8BAAA,EACX,QAAA,EAAA;AAAA,0BAAAC,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,8EAAA,EACX,QAAA,EAAA,QAAA,EACL,CAAA;AAAA,0BACAA,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,0CAAA,EACX,YAAE,wBAAA,EAA0B,EAAE,MAAA,EAAQ,CAAA,EAC3C;AAAA,SAAA,EACJ,CAAA;AAAA,wBAEAD,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wCAAA,EACV,QAAA,EAAA;AAAA,UAAA,OAAA,oBACGA,eAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,gGAAA,EACZ,QAAA,EAAA;AAAA,4BAAAC,eAAC,MAAA,EAAA,EAAK,SAAA,EAAU,uBACZ,QAAA,kBAAAA,cAAAA,CAAC,YAAS,CAAA,EACd,CAAA;AAAA,YACC,EAAE,uBAAuB;AAAA,WAAA,EAC9B,CAAA;AAAA,UAEH,aAAA,oBACGA,cAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,gEAAA,EACX,QAAA,EAAA,CAAA,CAAE,4BAA4B,CAAA,EACnC;AAAA,SAAA,EAER;AAAA;AAAA;AAAA,GACJ;AAER;AC7FO,SAAS,YAAY,EAAE,UAAA,GAAa,IAAA,EAAM,KAAA,EAAO,WAAU,EAAqB;AACnF,EAAA,MAAM,IAAI,QAAA,EAAS;AACnB,EAAA,MAAM,UAAA,GAAaO,8BAAA,CAAa,CAAA,CAAA,KAAK,CAAA,CAAE,UAAU,CAAA;AACjD,EAAA,MAAM,SAAA,GAAYK,aAAyB,IAAI,CAAA;AAE/C,EAAA,MAAM,OAAA,GAA8B,UAAA,EAAY,WAAA,IAAe,EAAC;AAChE,EAAA,MAAM,UAAU,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,CAAC,KAAK,CAAA,GAAI,OAAA;AAEhD,EAAA,MAAM,OAAA,GAAU,CAAC,GAAG,OAAO,EAAE,OAAA,EAAQ;AAErC,EAAAC,gBAAU,MAAM;AACZ,IAAA,IAAI,CAAC,UAAA,EAAY;AACjB,IAAA,IAAI,SAAA,CAAU,OAAA,EAAS,SAAA,CAAU,OAAA,CAAQ,SAAA,GAAY,CAAA;AAAA,EACzD,CAAA,EAAG,CAAC,OAAA,CAAQ,MAAA,EAAQ,UAAU,CAAC,CAAA;AAE/B,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACtB,IAAA,uBACIb,cAAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QACG,SAAA,EAAW,EAAA;AAAA,UACP,2DAAA;AAAA,UACA,6BAAA;AAAA,UACA;AAAA,SACJ;AAAA,QAEC,YAAE,eAAe;AAAA;AAAA,KACtB;AAAA,EAER;AAEA,EAAA,uBACIA,cAAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACG,GAAA,EAAK,SAAA;AAAA,MACL,YAAA,EAAY,EAAE,eAAe,CAAA;AAAA,MAC7B,SAAA,EAAW,EAAA;AAAA,QACP,qBAAA;AAAA,QACA,UAAA,IAAc,6BAAA;AAAA,QACd;AAAA,OACJ;AAAA,MAEC,QAAA,EAAA,OAAA,CAAQ,GAAA,CAAI,CAAC,KAAA,EAAO,CAAA,KAAM;AACvB,QAAA,MAAM,WAAW,CAAA,KAAM,CAAA;AACvB,QAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,CAAA,GAAI,CAAC,CAAA;AAC1B,QAAA,MAAM,eAAA,GAAkB,CAAC,IAAA,IAAQ,IAAA,CAAK,eAAe,KAAA,CAAM,UAAA;AAC3D,QAAA,uBACID,eAAAA,CAAC,IAAA,EAAA,EAA4B,SAAA,EAAU,qBAAA,EAClC,QAAA,EAAA;AAAA,UAAA,eAAA,oBACGA,eAAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACG,SAAA,EAAU,8BAAA;AAAA,cACV,aAAA,EAAa,OAAO,MAAA,GAAS,MAAA;AAAA,cAE7B,QAAA,EAAA;AAAA,gCAAAC,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,6DAAA,EACX,QAAA,EAAA,CAAA,CAAE,cAAA,EAAgB,EAAE,CAAA,EAAG,KAAA,CAAM,UAAA,EAAY,CAAA,EAC9C,CAAA;AAAA,gCACAA,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iCAAA,EAAkC;AAAA;AAAA;AAAA,WACtD;AAAA,0BAEJA,cAAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAc,QAAA,EAAoB;AAAA,SAAA,EAAA,EAZzC,CAAA,EAAG,KAAA,CAAM,EAAE,CAAA,CAAA,EAAI,CAAC,CAAA,CAazB,CAAA;AAAA,MAER,CAAC;AAAA;AAAA,GACL;AAER;AAOA,SAAS,UAAA,CAAW,EAAE,KAAA,EAAO,QAAA,EAAS,EAAoB;AACtD,EAAA,MAAM,IAAI,QAAA,EAAS;AACnB,EAAA,MAAM,SAAS,KAAA,CAAM,IAAA,GAAOqB,8BAAAA,CAAW,KAAA,CAAM,IAAI,CAAA,GAAI,QAAA;AACrD,EAAA,MAAM,IAAA,GAAOA,8BAAAA,CAAW,KAAA,CAAM,EAAE,CAAA;AAChC,EAAA,MAAM,aAAa,CAAA,CAAE,CAAA,OAAA,EAAUnB,8BAAU,KAAA,CAAM,SAAS,CAAC,CAAA,CAAE,CAAA;AAE3D,EAAA,IAAI,KAAA;AACJ,EAAA,QAAQ,MAAM,IAAA;AAAM,IAChB,KAAK,MAAA;AACD,MAAA,KAAA,GAAQ,CAAA,CAAE,cAAA,EAAgB,EAAE,EAAA,EAAI,MAAM,CAAA;AACtC,MAAA;AAAA,IACJ,KAAK,QAAA;AACD,MAAA,KAAA,GAAQ,CAAA,CAAE,gBAAA,EAAkB,EAAE,EAAA,EAAI,MAAM,CAAA;AACxC,MAAA;AAAA,IACJ,KAAK,cAAA;AACD,MAAA,KAAA,GAAQ,CAAA,CAAE,sBAAA,EAAwB,EAAE,EAAA,EAAI,MAAM,CAAA;AAC9C,MAAA;AAAA,IACJ,KAAK,MAAA;AACD,MAAA,KAAA,GAAQ,EAAE,cAAA,EAAgB,EAAE,MAAM,MAAA,EAAQ,EAAA,EAAI,MAAM,CAAA;AACpD,MAAA;AAAA,IACJ,KAAK,SAAA;AACD,MAAA,KAAA,GAAQ,CAAA,CAAE,iBAAA,EAAmB,EAAE,IAAA,EAAM,QAAQ,CAAA;AAC7C,MAAA;AAAA,IACJ,KAAK,MAAA;AAAA,IACL;AACI,MAAA,KAAA,GAAQ,CAAA,CAAE,gBAAgB,EAAE,KAAA,EAAO,YAAY,IAAA,EAAM,MAAA,EAAQ,EAAA,EAAI,IAAA,EAAM,CAAA;AAAA;AAG/E,EAAA,MAAM,QAAA,GACF,MAAM,IAAA,KAAS,MAAA,GAAiB,oBAChC,KAAA,CAAM,IAAA,KAAS,SAAiB,mBAAA,GAChC,KAAA,CAAM,SAAS,cAAA,GAAiB,WAAA,GAChC,MAAM,IAAA,KAAS,QAAA,GAAiB,iBAChC,KAAA,CAAM,IAAA,KAAS,YAAiB,YAAA,GACA,mBAAA;AAEpC,EAAA,uBACIH,eAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACG,SAAA,EAAW,EAAA;AAAA,QACP,+DAAA;AAAA,QACA,qCAAA;AAAA,QACA,WACM,wCAAA,GACA,oCAAA;AAAA,QACN,KAAA,CAAM,cAAc,OAAA,IAAW,mCAAA;AAAA,QAC/B,KAAA,CAAM,cAAc,OAAA,IAAW;AAAA,OACnC;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAAC,cAAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACG,aAAA,EAAY,MAAA;AAAA,YACZ,SAAA,EAAW,EAAA,CAAG,mCAAA,EAAqC,QAAQ;AAAA;AAAA,SAC/D;AAAA,wBACAA,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mBAAmB,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,QACxC,KAAA,CAAM,SAAS,MAAA,oBACZA,eAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qEAAoE,QAAA,EAAA,KAAA,EAEpF;AAAA;AAAA;AAAA,GAER;AAER;AC7IA,IAAMkC,KAAAA,GAAO,CAAA;AACb,IAAMC,KAAAA,GAAO,EAAA;AAEN,SAAS,eAAA,CAAgB,EAAE,SAAA,EAAU,GAA4B,EAAC,EAAG;AACxE,EAAA,MAAM,aAAapB,aAAAA,CAAQ,MAAMqB,uCAAqB,OAAO,CAAA,EAAG,EAAE,CAAA;AAElE,EAAA,uBACIrC,eAAAA,CAAC,KAAA,EAAA,EAAI,WAAW,EAAA,CAAG,kGAAA,EAAoG,SAAS,CAAA,EAC5H,QAAA,EAAA;AAAA,oBAAAC,cAAAA,CAAC,YAAA,EAAA,EACG,QAAA,kBAAAA,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sCAAA,EACV,QAAA,EAAA,UAAA,CAAW,MAAA,CAAO,GAAA,CAAI,CAAA,KAAA,qBACnBA,cAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QAEG,KAAA,EAAO;AAAA,UACH,QAAA,EAAU,UAAA;AAAA,UACV,MAAM,CAAA,EAAI,KAAA,CAAM,GAAA,CAAI,CAAA,GAAIkC,QAAQ,GAAG,CAAA,CAAA,CAAA;AAAA,UACnC,GAAA,EAAK,IAAKC,KAAAA,GAAO,CAAA,GAAI,MAAM,GAAA,CAAI,CAAA,IAAKA,QAAQ,GAAG,CAAA,CAAA,CAAA;AAAA,UAC/C,KAAA,EAAO,CAAA,EAAG,GAAA,GAAMD,KAAI,CAAA,CAAA,CAAA;AAAA,UACpB,MAAA,EAAQ,CAAA,EAAG,GAAA,GAAMC,KAAI,CAAA,CAAA;AAAA,SACzB;AAAA,QACA,SAAA,EAAU,kCAAA;AAAA,QAEV,QAAA,kBAAAnC,cAAAA;AAAA,UAAC,SAAA;AAAA,UAAA;AAAA,YACG,KAAA;AAAA,YACA,UAAA,EAAY,KAAA;AAAA,YACZ,OAAA,EAAS,UAAA,CAAW,IAAA,CAAK,QAAA,KAAa,KAAA,CAAM,EAAA;AAAA,YAC5C,SAAS,MAAM;AAAA,YAAE;AAAA;AAAA;AACrB,OAAA;AAAA,MAfK,KAAA,CAAM;AAAA,KAiBlB,GACL,CAAA,EACJ,CAAA;AAAA,oBAGAA,cAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACG,KAAA,EAAO;AAAA,UACH,QAAA,EAAU,UAAA;AAAA,UACV,MAAM,CAAA,EAAI,UAAA,CAAW,KAAK,GAAA,CAAI,CAAA,GAAIkC,QAAQ,GAAG,CAAA,CAAA,CAAA;AAAA,UAC7C,GAAA,EAAK,IAAKC,KAAAA,GAAO,CAAA,GAAI,WAAW,IAAA,CAAK,GAAA,CAAI,CAAA,IAAKA,KAAAA,GAAQ,GAAG,CAAA,CAAA,CAAA;AAAA,UACzD,KAAA,EAAO,CAAA,EAAG,GAAA,GAAMD,KAAI,CAAA,CAAA,CAAA;AAAA,UACpB,MAAA,EAAQ,CAAA,EAAG,GAAA,GAAMC,KAAI,CAAA,CAAA,CAAA;AAAA,UACrB,MAAA,EAAQ;AAAA,SACZ;AAAA,QACA,SAAA,EAAU,sDAAA;AAAA,QAEV,QAAA,kBAAAnC,eAAC,KAAA,EAAA,EAAI,SAAA,EAAU,mBACX,QAAA,kBAAAA,cAAAA,CAAC,YAAS,CAAA,EACd;AAAA;AAAA;AACJ,GAAA,EACJ,CAAA;AAER;ACvCO,SAAS,UAAA,CAAW,EAAE,QAAA,EAAU,YAAA,EAAc,WAAU,EAAoB;AAC/E,EAAA,MAAM,IAAI,QAAA,EAAS;AACnB,EAAA,MAAM,UAAA,GAAaO,8BAAA,CAAa,CAAA,CAAA,KAAK,CAAA,CAAE,UAAU,CAAA;AACjD,EAAA,IAAI,CAAC,YAAY,OAAO,IAAA;AAExB,EAAA,MAAM,EAAE,YAAA,EAAc,UAAA,EAAW,GAAI,UAAA;AACrC,EAAA,MAAM,eAAA,GAAkB,WAAW,eAAA,IAAmBuB,gCAAA;AAEtD,EAAA,uBACI/B,eAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACG,SAAA,EAAW,EAAA;AAAA,QACP,2FAAA;AAAA,QACA,WACM,oDAAA,GACA,6CAAA;AAAA,QACN;AAAA,OACJ;AAAA,MACA,WAAA,EAAU,QAAA;AAAA,MACV,aAAA,EAAY,MAAA;AAAA,MAEZ,QAAA,EAAA;AAAA,wBAAAA,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,mCAAA,EACX,QAAA,EAAA;AAAA,0BAAAC,cAAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACG,SAAA,EAAW,EAAA;AAAA,gBACP,wDAAA;AAAA,gBACA,WAAW,mBAAA,GAAsB;AAAA,eACrC;AAAA,cAEC,qBAAW,CAAA,CAAE,UAAU,CAAA,GAAK,YAAA,IAAgB,EAAE,cAAc;AAAA;AAAA,WACjE;AAAA,UAGC,OAAO,UAAA,KAAe,QAAA,oBACnBA,eAAC,MAAA,EAAA,EAAK,SAAA,EAAU,yEAAA,EACX,QAAA,EAAA,CAAA,CAAE,cAAA,EAAgB,EAAE,CAAA,EAAG,UAAA,EAAY,CAAA,EACxC;AAAA,SAAA,EAER,CAAA;AAAA,QAEC,QAAA,oBACGD,eAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,yBAAA,EAA0B,YAAA,EAAY,CAAA,CAAE,uBAAA,EAAyB,EAAE,SAAA,EAAW,YAAA,EAAc,KAAA,EAAO,eAAA,EAAiB,CAAA,EAC/H,QAAA,EAAA;AAAA,0BAAAC,cAAAA,CAAC6B,iBAAA,EAAI,IAAA,EAAM,IAAI,SAAA,EAAU,mBAAA,EAAoB,eAAY,MAAA,EAAO,CAAA;AAAA,0BAChE9B,eAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kDAAA,EACX,QAAA,EAAA;AAAA,YAAA,YAAA;AAAA,YAAa,GAAA;AAAA,YAAE;AAAA,WAAA,EACpB;AAAA,SAAA,EACJ;AAAA;AAAA;AAAA,GAER;AAER;ACvDA,IAAM,SAAA,uBAAqC,GAAA,CAAgB,CAAC,QAAQ,cAAA,EAAgB,SAAA,EAAW,QAAQ,CAAC,CAAA;AAExG,IAAM,YAAA,GAA2C;AAAA,EAC7C,IAAA,EAAc,mEAAA;AAAA,EACd,YAAA,EAAc,2CAAA;AAAA,EACd,OAAA,EAAc,8CAAA;AAAA,EACd,MAAA,EAAc;AAClB,CAAA;AAEO,SAAS,UAAA,CAAW,EAAE,SAAA,EAAU,EAAoB;AACvD,EAAA,MAAM,IAAI,QAAA,EAAS;AACnB,EAAA,MAAM,UAAA,GAAaQ,8BAAA,CAAa,CAAA,CAAA,KAAK,CAAA,CAAE,UAAU,CAAA;AACjD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAII,eAAmD,IAAI,CAAA;AAEjF,EAAAE,gBAAU,MAAM;AACZ,IAAA,MAAM,WAAW,UAAA,EAAY,QAAA;AAC7B,IAAA,IAAI,CAAC,QAAA,EAAU;AACf,IAAA,IAAI,CAAC,SAAA,CAAU,GAAA,CAAI,QAAA,CAAS,IAAI,CAAA,EAAG;AACnC,IAAA,QAAA,CAAS,EAAE,MAAM,QAAA,CAAS,IAAA,EAAoB,KAAK,MAAA,CAAO,QAAA,CAAS,EAAE,CAAA,EAAG,CAAA;AAAA,EAC5E,CAAA,EAAG,CAAC,UAAA,EAAY,QAAA,EAAU,EAAE,CAAC,CAAA;AAE7B,EAAAA,gBAAU,MAAM;AACZ,IAAA,IAAI,CAAC,KAAA,EAAO;AACZ,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,QAAA,CAAS,IAAI,GAAG,IAAI,CAAA;AACnD,IAAA,OAAO,MAAM,aAAa,KAAK,CAAA;AAAA,EACnC,CAAA,EAAG,CAAC,KAAA,EAAO,GAAG,CAAC,CAAA;AAEf,EAAA,uBACIb,cAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACG,IAAA,EAAK,QAAA;AAAA,MACL,WAAA,EAAU,QAAA;AAAA,MACV,aAAA,EAAY,MAAA;AAAA,MACZ,SAAA,EAAW,EAAA,CAAG,yCAAA,EAA2C,SAAS,CAAA;AAAA,MAElE,0BAAAA,cAAAA,CAACwB,4BAAAA,EAAA,EAAgB,IAAA,EAAK,MAAA,EACjB,mCACGxB,cAAAA;AAAA,QAACyB,mBAAAA,CAAO,GAAA;AAAA,QAAP;AAAA,UAEG,OAAA,EAAS,EAAE,OAAA,EAAS,CAAA,EAAG,GAAG,EAAA,EAAG;AAAA,UAC7B,OAAA,EAAS,EAAE,OAAA,EAAS,CAAA,EAAG,GAAG,CAAA,EAAE;AAAA,UAC5B,IAAA,EAAM,EAAE,OAAA,EAAS,CAAA,EAAG,GAAG,EAAA,EAAG;AAAA,UAC1B,UAAA,EAAY,EAAE,QAAA,EAAU,IAAA,EAAK;AAAA,UAC7B,SAAA,EAAW,EAAA;AAAA,YACP,uGAAA;AAAA,YACA,YAAA,CAAa,MAAM,IAAI;AAAA,WAC3B;AAAA,UAEC,QAAA,EAAA,CAAA,CAAE,CAAA,WAAA,EAAc,KAAA,CAAM,IAAI,CAAA,CAAE;AAAA,SAAA;AAAA,QAVxB,KAAA,CAAM;AAAA,OAWf,EAER;AAAA;AAAA,GACJ;AAER;AClDO,SAAS,aAAA,CAAc,EAAE,SAAA,EAAU,EAAuB;AAC7D,EAAA,MAAM,UAAA,GAAalB,8BAAA,CAAa,CAAA,CAAA,KAAK,CAAA,CAAE,UAAU,CAAA;AACjD,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAII,eAAS,KAAK,CAAA;AACtC,EAAA,MAAM,OAAA,GAAU,CAAA,EAAGV,WAAAA,EAAO,CAAA,MAAA,CAAA;AAC1B,EAAA,MAAM,QAAA,GAAW,cAAc,EAAE,IAAA,EAAM,SAAS,MAAM,OAAA,CAAQ,KAAK,CAAA,EAAG,CAAA;AAEtE,EAAA,MAAM,QAAA,GAAW,UAAA,EAAY,WAAA,EAAa,EAAA,CAAG,EAAE,CAAA;AAE/C,EAAA,IAAI,CAAC,UAAU,OAAO,IAAA;AAEtB,EAAA,uBACIF,eAAAA,CAAAS,mBAAAA,EAAA,EACI,QAAA,EAAA;AAAA,oBAAAR,cAAAA,CAAC,eAAY,QAAA,EAAoB,OAAA,EAAS,MAAM,OAAA,CAAQ,IAAI,GAAG,SAAA,EAAsB,CAAA;AAAA,oBAErFA,eAACwB,4BAAAA,EAAA,EACI,kCACGzB,eAAAA,CAAAS,qBAAA,EACI,QAAA,EAAA;AAAA,sBAAAR,cAAAA;AAAA,QAACyB,mBAAAA,CAAO,GAAA;AAAA,QAAP;AAAA,UAEG,OAAA,EAAS,EAAE,OAAA,EAAS,CAAA,EAAE;AAAA,UACtB,OAAA,EAAS,EAAE,OAAA,EAAS,CAAA,EAAE;AAAA,UACtB,IAAA,EAAM,EAAE,OAAA,EAAS,CAAA,EAAE;AAAA,UACnB,UAAA,EAAY,EAAE,QAAA,EAAU,GAAA,EAAI;AAAA,UAC5B,SAAA,EAAU,iDAAA;AAAA,UACV,OAAA,EAAS,MAAM,OAAA,CAAQ,KAAK,CAAA;AAAA,UAC5B,aAAA,EAAY;AAAA,SAAA;AAAA,QAPR;AAAA,OAQR;AAAA,sBACA1B,eAAAA;AAAA,QAAC0B,mBAAAA,CAAO,GAAA;AAAA,QAAP;AAAA,UAEG,OAAA,EAAS,EAAE,CAAA,EAAG,MAAA,EAAO;AAAA,UACrB,OAAA,EAAS,EAAE,CAAA,EAAG,CAAA,EAAE;AAAA,UAChB,IAAA,EAAM,EAAE,CAAA,EAAG,MAAA,EAAO;AAAA,UAClB,YAAY,EAAE,IAAA,EAAM,UAAU,SAAA,EAAW,GAAA,EAAK,SAAS,EAAA,EAAG;AAAA,UAC1D,GAAA,EAAK,QAAA;AAAA,UACL,SAAA,EAAU,6HAAA;AAAA,UACV,IAAA,EAAK,QAAA;AAAA,UACL,YAAA,EAAW,MAAA;AAAA,UACX,iBAAA,EAAiB,OAAA;AAAA,UAEjB,QAAA,EAAA;AAAA,4BAAAzB,eAAC,WAAA,EAAA,EAAY,OAAA,EAAkB,SAAS,MAAM,OAAA,CAAQ,KAAK,CAAA,EAAG,CAAA;AAAA,4BAC9DA,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yCAAA,EACX,0BAAAA,cAAAA,CAAC,WAAA,EAAA,EAAY,UAAA,EAAY,KAAA,EAAO,CAAA,EACpC;AAAA;AAAA,SAAA;AAAA,QAdI;AAAA;AAeR,KAAA,EACJ,CAAA,EAER;AAAA,GAAA,EACJ,CAAA;AAER;AAEA,SAAS,WAAA,CAAY,EAAE,OAAA,EAAS,OAAA,EAAQ,EAA6C;AACjF,EAAA,MAAM,IAAI,QAAA,EAAS;AACnB,EAAA,uBACID,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gFAAA,EACX,QAAA,EAAA;AAAA,oBAAAC,cAAAA,CAAC,UAAK,EAAA,EAAI,OAAA,EAAS,WAAU,gEAAA,EACxB,QAAA,EAAA,CAAA,CAAE,eAAe,CAAA,EACtB,CAAA;AAAA,oBACAA,cAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACG,OAAA,EAAS,OAAA;AAAA,QACT,SAAA,EAAU,gPAAA;AAAA,QACV,YAAA,EAAY,EAAE,eAAe,CAAA;AAAA,QAE7B,0BAAAA,cAAAA,CAACqC,aAAA,EAAA,EAAE,IAAA,EAAM,EAAA,EAAI,eAAY,MAAA,EAAO;AAAA;AAAA;AACpC,GAAA,EACJ,CAAA;AAER;AAQA,SAAS,WAAA,CAAY,EAAE,QAAA,EAAU,OAAA,EAAS,WAAU,EAAqB;AACrE,EAAA,MAAM,IAAI,QAAA,EAAS;AACnB,EAAA,MAAM,IAAA,GAAOhB,8BAAAA,CAAW,QAAA,CAAS,EAAE,CAAA;AACnC,EAAA,IAAI,KAAA;AACJ,EAAA,QAAQ,SAAS,IAAA;AAAM,IACnB,KAAK,MAAA;AAAiB,MAAA,KAAA,GAAQ,UAAK,IAAI,CAAA,CAAA;AAAI,MAAA;AAAA,IAC3C,KAAK,QAAA;AAAiB,MAAA,KAAA,GAAQ,UAAK,IAAI,CAAA,CAAA;AAAI,MAAA;AAAA,IAC3C,KAAK,cAAA;AAAiB,MAAA,KAAA,GAAQ,UAAK,IAAI,CAAA,CAAA;AAAI,MAAA;AAAA,IAC3C,KAAK,MAAA;AAAiB,MAAA,KAAA,GAAQ,CAAA,UAAA,CAAA;AAAS,MAAA;AAAA,IACvC,KAAK,SAAA;AAAiB,MAAA,KAAA,GAAQ,CAAA,UAAA,CAAA;AAAS,MAAA;AAAA,IACvC,SAAS;AACL,MAAA,MAAM,aAAa,CAAA,CAAE,CAAA,OAAA,EAAUnB,8BAAU,QAAA,CAAS,SAAS,CAAC,CAAA,CAAE,CAAA;AAC9D,MAAA,MAAM,SAAS,QAAA,CAAS,IAAA,GAAOmB,8BAAAA,CAAW,QAAA,CAAS,IAAI,CAAA,GAAI,EAAA;AAC3D,MAAA,KAAA,GAAQ,MAAA,GAAS,CAAA,EAAG,UAAU,CAAA,EAAG,MAAM,CAAA,MAAA,EAAI,IAAI,CAAA,CAAA,GAAK,CAAA,EAAG,UAAU,CAAA,MAAA,EAAI,IAAI,CAAA,CAAA;AAAA,IAC7E;AAAA;AAGJ,EAAA,uBACItB,eAAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACG,OAAA;AAAA,MACA,SAAA,EAAW,EAAA;AAAA,QACP,oDAAA;AAAA,QACA,2CAAA;AAAA,QACA,yCAAA;AAAA,QACA,oEAAA;AAAA,QACA,2DAAA;AAAA,QACA,iFAAA;AAAA,QACA;AAAA,OACJ;AAAA,MACA,YAAA,EAAY,EAAE,iBAAiB,CAAA;AAAA,MAE/B,QAAA,EAAA;AAAA,wBAAAC,cAAAA,CAAC,UAAM,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,wBACbA,cAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,2BAAA,EAA4B,aAAA,EAAY,QAAO,QAAA,EAAA,QAAA,EAAC;AAAA;AAAA;AAAA,GACpE;AAER;ACjHO,IAAM,aAAA,GAAgB,CAAC,iBAAA,EAAmB,SAAA,EAAW,eAAe,OAAO;AAoB3E,SAAS,UAAU,EAAE,QAAA,EAAU,IAAA,EAAM,MAAA,EAAQ,WAAU,EAAmB;AAC7E,EAAA,MAAM,IAAI,QAAA,EAAS;AACnB,EAAA,MAAM,UAAA,GAAaO,8BAAA,CAAa,CAAA,CAAA,KAAK,CAAA,CAAE,UAAU,CAAA;AACjD,EAAA,MAAM,eAAA,GAAkBA,8BAAA,CAAa,CAAA,CAAA,KAAK,CAAA,CAAE,eAAe,CAAA;AAG3D,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAII,cAAAA,CAAgC,EAAE,CAAA;AAE1D,EAAA,MAAM,SAAS,CAAC,CAAC,cAAc,QAAA,KAAa,IAAA,IAAQ,WAAW,IAAA,KAAS,QAAA;AACxE,EAAA,MAAM,QAAA,GAAW,SAAS,UAAA,CAAW,MAAA,CAAO,KAAK,CAAA,CAAA,KAAK,CAAA,CAAE,EAAA,KAAO,eAAe,CAAA,GAAI,MAAA;AAClF,EAAA,MAAM,OAAA,GAAuC;AAAA,IACzC,eAAA,EAAiB,MAAA,IAAU,UAAA,CAAW,YAAA,KAAiB,CAAA;AAAA,IACvD,SAAS,CAAC,CAAC,YAAY,UAAA,EAAY,IAAA,CAAK,aAAa,QAAA,CAAS,EAAA;AAAA,IAC9D,WAAA,EAAa,CAAC,CAAC,QAAA;AAAA,IACf,KAAA,EAAO,UAAU,CAAC;AAAA,GACtB;AACA,EAAA,MAAM,UAAU,aAAA,CAAc,IAAA,CAAK,CAAA,EAAA,KAAM,OAAA,CAAQ,EAAE,CAAA,IAAK,CAAC,IAAA,CAAK,QAAA,CAAS,EAAE,CAAA,IAAK,CAAC,KAAK,QAAA,CAAS,EAAE,CAAC,CAAA,IAAK,IAAA;AAErG,EAAA,MAAM,SAAA,GAAYC,aAAO,MAAM,CAAA;AAC/B,EAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AACpB,EAAA,MAAM,QAAA,GAAW,CAAC,EAAA,KAAmB;AACjC,IAAA,OAAA,CAAQ,CAAA,CAAA,KAAM,CAAA,CAAE,QAAA,CAAS,EAAE,CAAA,GAAI,IAAI,CAAC,GAAG,CAAA,EAAG,EAAE,CAAE,CAAA;AAC9C,IAAA,SAAA,CAAU,QAAQ,EAAE,CAAA;AAAA,EACxB,CAAA;AAIA,EAAA,MAAM,QAAA,GAAWA,aAA0B,IAAI,CAAA;AAC/C,EAAAC,gBAAU,MAAM;AACZ,IAAA,MAAM,OAAO,QAAA,CAAS,OAAA;AACtB,IAAA,QAAA,CAAS,OAAA,GAAU,OAAA;AACnB,IAAA,IAAI,IAAA,IAAQ,SAAS,OAAA,IAAW,CAAC,KAAK,QAAA,CAAS,IAAI,CAAA,EAAG,QAAA,CAAS,IAAI,CAAA;AAAA,EAEvE,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAEZ,EAAA,uBACIb,cAAAA,CAAC,KAAA,EAAA,EAAI,IAAA,EAAK,UAAS,WAAA,EAAU,QAAA,EAAS,aAAA,EAAY,MAAA,EAAO,WAAW,EAAA,CAAG,yCAAA,EAA2C,SAAS,CAAA,EACtH,qCACGD,eAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACG,aAAA,EAAY,WAAA;AAAA,MACZ,WAAA,EAAW,OAAA;AAAA,MACX,SAAA,EAAU,uJAAA;AAAA,MAEV,QAAA,EAAA;AAAA,wBAAAC,cAAAA,CAAC,OAAE,SAAA,EAAU,sDAAA,EAAwD,YAAE,CAAA,MAAA,EAAS,OAAO,EAAE,CAAA,EAAE,CAAA;AAAA,wBAC3FA,cAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACG,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAS,MAAM,QAAA,CAAS,OAAO,CAAA;AAAA,YAC/B,YAAA,EAAY,EAAE,eAAe,CAAA;AAAA,YAC7B,SAAA,EAAU,wMAAA;AAAA,YAEV,0BAAAA,cAAAA,CAACqC,aAAAA,EAAA,EAAE,IAAA,EAAM,EAAA,EAAI,eAAY,MAAA,EAAO;AAAA;AAAA;AACpC;AAAA;AAAA,GACJ,EAER,CAAA;AAER;AC/EO,IAAM,uBAAA,GAA0B;AAMhC,IAAM,gBAAA,GAAmB;AAWzB,IAAM,kBAAA,GAAqB;AAIlC,IAAM,iBAAA,GAAoB,EAAA;AA4DnB,SAAS,WAAW,IAAA,EAA2C;AAClE,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI1B,eAAS,KAAK,CAAA;AACpD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,eAAuB,IAAI,CAAA;AACrD,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAIA,eAAS,CAAC,CAAA;AAI9C,EAAA,MAAM,OAAA,GAAUC,aAAO,IAAI,CAAA;AAC3B,EAAA,OAAA,CAAQ,OAAA,GAAU,IAAA;AAKlB,EAAA,MAAM,OAAA,GAAUA,aAAO,KAAK,CAAA;AAC5B,EAAA,MAAM,KAAA,GAAQA,aAAO,CAAC,CAAA;AACtB,EAAA,MAAM,MAAA,GAASA,YAAAA,iBAAO,IAAI,GAAA,EAAoC,CAAA;AAC9D,EAAA,MAAM,OAAA,GAAUA,aAA4B,IAAI,CAAA;AAEhD,EAAA,MAAM,cAAc,MAAM;AACtB,IAAA,MAAA,CAAO,OAAA,CAAQ,QAAQ,YAAY,CAAA;AACnC,IAAA,MAAA,CAAO,QAAQ,KAAA,EAAM;AAAA,EACzB,CAAA;AAIA,EAAAC,eAAAA,CAAU,MAAM,MAAM;AAClB,IAAA,KAAA,CAAM,OAAA,EAAA;AACN,IAAA,WAAA,EAAY;AACZ,IAAA,OAAA,CAAQ,OAAA,GAAU,KAAA;AAClB,IAAA,OAAA,CAAQ,OAAA,GAAU,IAAA;AAAA,EACtB,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,EAAE,YAAY,OAAA,GAAU,IAAA,EAAM,YAAY,KAAA,EAAO,WAAA,GAAc,OAAM,GAAI,IAAA;AAE/E,EAAAA,gBAAU,MAAM;AACZ,IAAA,MAAM,IAAI,OAAA,CAAQ,OAAA;AAClB,IAAA,MAAM,QAAQ,CAAA,CAAE,UAAA;AAChB,IAAA,IAAI,CAAC,KAAA,IAAS,CAAC,WAAW,KAAA,CAAM,IAAA,KAAS,EAAE,OAAA,EAAS;AACpD,IAAA,IAAI,OAAA,CAAQ,OAAA,IAAW,SAAA,IAAa,WAAA,EAAa;AAGjD,IAAA,IAAIyB,6BAAA,CAAU,KAAK,CAAA,EAAG;AAEtB,IAAA,MAAM,GAAA,GAAM,EAAE,KAAA,CAAM,OAAA;AACpB,IAAA,MAAM,KAAA,GAAQ,MAAM,KAAA,CAAM,OAAA,KAAY,GAAA;AACtC,IAAA,MAAM,OAAO,CAAC,EAAA,KAAe,IAAI,OAAA,CAAc,CAAC,OAAA,KAAY;AACxD,MAAA,MAAM,EAAA,GAAK,WAAW,MAAM;AAAE,QAAA,MAAA,CAAO,OAAA,CAAQ,OAAO,EAAE,CAAA;AAAG,QAAA,OAAA,EAAQ;AAAA,MAAE,GAAG,EAAE,CAAA;AACxE,MAAA,MAAA,CAAO,OAAA,CAAQ,IAAI,EAAE,CAAA;AAAA,IACzB,CAAC,CAAA;AACD,IAAA,MAAM,SAAS,MAAM;AACjB,MAAA,OAAA,CAAQ,OAAA,GAAU,KAAA;AAClB,MAAA,OAAA,CAAQ,OAAA,GAAU,IAAA;AAClB,MAAA,cAAA,CAAe,KAAK,CAAA;AACpB,MAAA,OAAA,CAAQ,OAAA,CAAQ,qBAAqB,KAAK,CAAA;AAAA,IAC9C,CAAA;AAEA,IAAA,OAAA,CAAQ,OAAA,GAAU,IAAA;AAClB,IAAA,cAAA,CAAe,IAAI,CAAA;AACnB,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAA,CAAA,CAAE,qBAAqB,IAAI,CAAA;AAE3B,IAAA,IAAI,aAAA,GAAgB,KAAA;AACpB,IAAA,OAAA,CAAQ,UAAU,MAAM;AAAE,MAAA,aAAA,GAAgB,IAAA;AAAA,IAAK,CAAA;AAE/C,IAAA,MAAM,UAAA,GAAa,EAAE,YAAA,IAAgB,uBAAA;AACrC,IAAA,MAAM,MAAA,GAAS,EAAE,MAAA,IAAU,gBAAA;AAC3B,IAAA,MAAM,QAAA,GAAW,EAAE,QAAA,IAAY,kBAAA;AAE9B,IAAA,CAAC,YAAY;AACV,MAAA,IAAI;AACA,QAAA,MAAM,CAAC,IAAI,CAAA,GAAI,MAAM,QAAQ,GAAA,CAAI;AAAA,UAC7B,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,iBAAA,EAAmB,UAAU,CAAC,CAAA,CAAE,IAAA,CAAK,MAAM,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,CAAA,CAAE,OAAO,CAAC,CAAA;AAAA,UACpF,KAAK,UAAU;AAAA,SAClB,CAAA;AACD,QAAA,IAAI,CAAC,OAAM,EAAG;AACd,QAAA,IAAI,CAAC,IAAA,EAAM,MAAA,EAAQ,QAAQ,MAAM,IAAI,MAAM,6BAA6B,CAAA;AAExE,QAAA,MAAM,EAAE,QAAO,GAAI,IAAA;AACnB,QAAA,MAAM,IAAA,GAAO,MAAA,CAAO,MAAA,CAAO,MAAA,GAAS,CAAC,CAAA;AAGrC,QAAA,MAAM,QAAQ,IAAA,CAAK,eAAA,GAAkB,MAAA,CAAO,MAAA,GAAS,IAAI,MAAA,CAAO,MAAA;AAEhE,QAAA,MAAM,SAAS,MAAM;AACjB,UAAA,WAAA,EAAY;AACZ,UAAA,OAAA,CAAQ,OAAA,CAAQ,aAAa,IAAI,CAAA;AACjC,UAAA,MAAA,EAAO;AACP,UAAA,MAAM,MAAA,GAAS,KAAK,UAAA,IAAc,IAAA;AAClC,UAAA,IAAI,MAAA,EAAQ,OAAA,CAAQ,OAAA,CAAQ,MAAA,GAAS,QAAQ,IAAI,CAAA;AAAA,QACrD,CAAA;AACA,QAAA,OAAA,CAAQ,UAAU,MAAM;AAAE,UAAA,IAAI,KAAA,IAAS,MAAA,EAAO;AAAA,QAAE,CAAA;AAChD,QAAA,IAAI,aAAA,EAAe;AAAE,UAAA,MAAA,EAAO;AAAG,UAAA;AAAA,QAAO;AAEtC,QAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,EAAO,CAAA,EAAA,EAAK;AAC5B,UAAA,OAAA,CAAQ,OAAA,CAAQ,YAAA,CAAa,MAAA,CAAO,CAAC,CAAC,CAAA;AACtC,UAAA,MAAM,IAAA,CAAK,CAAA,KAAM,KAAA,GAAQ,CAAA,GAAI,WAAW,MAAM,CAAA;AAG9C,UAAA,IAAI,CAAC,OAAM,EAAG;AAAA,QAClB;AACA,QAAA,MAAA,EAAO;AAAA,MACX,SAAS,GAAA,EAAK;AACV,QAAA,IAAI,CAAC,OAAM,EAAG;AAId,QAAA,WAAA,EAAY;AACZ,QAAA,MAAA,EAAO;AACP,QAAA,QAAA,CAAS,GAAA,YAAe,QAAQ,GAAA,GAAM,IAAI,MAAM,MAAA,CAAO,GAAG,CAAC,CAAC,CAAA;AAAA,MAChE;AAAA,IACJ,CAAA,GAAG;AAAA,EAEP,CAAA,EAAG,CAAC,UAAA,EAAY,IAAA,EAAM,SAAS,SAAA,EAAW,WAAA,EAAa,UAAU,CAAC,CAAA;AAElE,EAAA,MAAM,KAAA,GAAQC,kBAAY,MAAM;AAC5B,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAA,aAAA,CAAc,CAAC,CAAA,KAAM,CAAA,GAAI,CAAC,CAAA;AAAA,EAC9B,CAAA,EAAG,EAAE,CAAA;AACL,EAAA,MAAM,IAAA,GAAOA,kBAAY,MAAM;AAAE,IAAA,OAAA,CAAQ,OAAA,IAAU;AAAA,EAAE,CAAA,EAAG,EAAE,CAAA;AAE1D,EAAA,OAAO,EAAE,WAAA,EAAa,KAAA,EAAO,KAAA,EAAO,IAAA,EAAK;AAC7C;;;ACjMO,IAAM,eAAA,GAAkB;AAAA;AAAA,EAE7B,cAAA;AAAA,EACA,gBAAA;AAAA,EACA,cAAA;AAAA,EACA,uBAAA;AAAA;AAAA,EAEA,cAAA;AAAA,EACA,gBAAA;AAAA,EACA,YAAA;AAAA;AAAA,EAEA,gBAAA;AAAA,EACA,sBAAA;AAAA,EACA,qBAAA;AAAA;AAAA,EAEA,iBAAA;AAAA;AAAA,EAEA,UAAA;AAAA,EACA,WAAA;AAAA;AAAA,EAEA,iBAAA;AAAA,EACA,iBAAA;AAAA,EACA,eAAA;AAAA,EACA,kBAAA;AAAA,EACA,kBAAA;AAAA,EACA,uBAAA;AAAA,EACA;AACF","file":"index.cjs","sourcesContent":["import { clsx, type ClassValue } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","import { Piece } from '@scriptonita/chess-football-engine'\nimport { cn } from '../../lib/utils'\nimport {\n ChessKing,\n ChessQueen,\n ChessRook,\n ChessBishop,\n ChessKnight,\n ShieldQuestion,\n type LucideIcon,\n} from 'lucide-react'\n\ninterface GamePieceProps {\n piece: Piece\n isSelected: boolean\n hasBall: boolean\n onClick: (e: React.MouseEvent) => void\n /**\n * True while the piece is travelling between squares. The chip lifts\n * slightly and its ground shadow drops away, so the move reads as the\n * piece being picked up and slid across the turf rather than dragged.\n */\n isMoving?: boolean\n}\n\nconst PIECE_ICON: Record<Piece['type'], LucideIcon> = {\n king: ChessKing,\n queen: ChessQueen,\n rook: ChessRook,\n bishop: ChessBishop,\n knight: ChessKnight,\n}\n\n// Embossed glyph: with the light source at the top-left (same as the chip's\n// radial gradient), a raised figure catches a thin highlight on its upper edge\n// and casts a short shadow below. Tuned per side so it reads on both chips.\nconst EMBOSS_FILTER: Record<Piece['side'], string> = {\n white: 'drop-shadow(0 -0.75px 0 rgba(255,255,255,0.65)) drop-shadow(0 1.25px 1px rgba(0,0,0,0.45))',\n black: 'drop-shadow(0 -0.5px 0 rgba(255,255,255,0.3)) drop-shadow(0 1.25px 1.5px rgba(0,0,0,0.8))',\n}\n\n/**\n * \"Already moved this turn\" is said ONE way: the glyph fades to grey, and the\n * chip is left alone. It used to be said three times at once — desaturate +\n * darken the whole piece, then 70 % opacity on top — and the opacity was the\n * problem: a translucent black chip takes on the green beneath it and all but\n * vanishes into the pitch. An opaque chip keeps the exact silhouette contrast of\n * a piece that has not moved; only its figure is muted.\n *\n * The black-side grey is as dark as it can go while the piece (chip or glyph,\n * whichever stands out more) stays at 3:1 or better on every pitch green either\n * app ships — see the contrast test.\n */\nexport const MOVED_GLYPH_COLOR: Record<Piece['side'], string> = {\n white: '#8b8b94',\n black: '#bdbdc3',\n}\n\nexport const PieceIcon = ({ type, side, moved = false }: { type: Piece['type']; side: Piece['side']; moved?: boolean }) => {\n const Icon = PIECE_ICON[type] ?? ShieldQuestion\n // Size scales with the board container width (cqw); clamp keeps the glyph\n // readable on small screens and avoids overflow on very large ones.\n const style: React.CSSProperties = {\n width: 'clamp(16px, 7.4cqw, 44px)',\n height: 'clamp(16px, 7.4cqw, 44px)',\n filter: EMBOSS_FILTER[side],\n ...(moved ? { color: MOVED_GLYPH_COLOR[side] } : null),\n }\n return <Icon style={style} strokeWidth={2} aria-hidden=\"true\" />\n}\n\n// 3D piece styling: radial gradient for top-left light source + layered\n// box-shadows (inner highlight, inner bottom shade, outer drop shadows) to\n// suggest a chip floating slightly above the board. Used as-is by standalone\n// chips (e.g. the ball-holder badge in the board toolbar).\nexport const WHITE_PIECE_STYLE: React.CSSProperties = {\n background: 'radial-gradient(circle at 30% 25%, #ffffff 0%, #f4f4f5 55%, #d4d4d8 100%)',\n boxShadow: [\n 'inset 0 1.5px 1px rgba(255,255,255,0.95)',\n 'inset 0 -2px 3px rgba(0,0,0,0.18)',\n '0 4px 6px rgba(0,0,0,0.45)',\n '0 1px 2px rgba(0,0,0,0.35)',\n ].join(', '),\n border: '1px solid rgba(0,0,0,0.18)',\n color: '#09090b',\n}\n\nexport const BLACK_PIECE_STYLE: React.CSSProperties = {\n background: 'radial-gradient(circle at 30% 25%, #52525b 0%, #1c1c1f 55%, #050507 100%)',\n boxShadow: [\n 'inset 0 1.5px 1px rgba(255,255,255,0.22)',\n 'inset 0 -2px 3px rgba(0,0,0,0.6)',\n '0 4px 6px rgba(0,0,0,0.55)',\n '0 1px 2px rgba(0,0,0,0.4)',\n ].join(', '),\n border: '1px solid rgba(0,0,0,0.55)',\n color: '#fafafa',\n}\n\n// On the board the ground shadow is a separate blurred layer (see below), so\n// the chip itself only keeps its bevel plus a tight contact edge — stacking the\n// toolbar's drop shadows on top would double up and read as smudged.\nconst ON_BOARD_CHIP_STYLE: Record<Piece['side'], React.CSSProperties> = {\n white: {\n ...WHITE_PIECE_STYLE,\n boxShadow: [\n 'inset 0 1.5px 1px rgba(255,255,255,0.95)',\n 'inset 0 -2px 3px rgba(0,0,0,0.18)',\n '0 1px 1px rgba(0,0,0,0.35)',\n ].join(', '),\n },\n black: {\n ...BLACK_PIECE_STYLE,\n boxShadow: [\n 'inset 0 1.5px 1px rgba(255,255,255,0.22)',\n 'inset 0 -2px 3px rgba(0,0,0,0.6)',\n '0 1px 1px rgba(0,0,0,0.5)',\n ].join(', '),\n },\n}\n\nexport default function GamePiece({ piece, isSelected, hasBall, onClick, isMoving = false }: GamePieceProps) {\n const chipStyle = ON_BOARD_CHIP_STYLE[piece.side]\n\n return (\n <div\n onClick={onClick}\n data-moved={piece.hasMovedThisTurn ? 'true' : 'false'}\n className={cn(\n \"relative w-[88%] h-[88%] rounded-full cursor-pointer z-10 transition-transform duration-200 ease-out motion-reduce:transition-none\",\n // `--primary` was the package's one remaining shadcn token, and\n // CrazyGames had to define it by hand just to make the selection\n // ring visible. It is part of the design system now.\n isSelected && \"ring-4 ring-accent-green scale-110 z-30\",\n isMoving && \"scale-[1.08] z-40\",\n )}\n >\n {/* Ground shadow — light comes from the top-left, so it falls to the\n bottom-right. While moving the chip is \"lifted\": the shadow drops\n further away, spreads and fades, then snaps back on landing. */}\n <div\n aria-hidden=\"true\"\n data-testid=\"piece-shadow\"\n data-lifted={isMoving ? 'true' : 'false'}\n className={cn(\n \"absolute inset-0 rounded-full bg-black pointer-events-none transition-all duration-200 ease-out motion-reduce:transition-none\",\n isMoving\n ? \"translate-x-[9%] translate-y-[24%] scale-[1.04] opacity-35 blur-[5px]\"\n : \"translate-x-[4%] translate-y-[9%] scale-95 opacity-50 blur-[3px]\",\n )}\n />\n\n <div\n data-testid=\"piece-chip\"\n style={chipStyle}\n className=\"absolute inset-0 rounded-full flex items-center justify-center\"\n >\n <PieceIcon type={piece.type} side={piece.side} moved={piece.hasMovedThisTurn} />\n\n {hasBall && (\n <div className=\"absolute inset-0 rounded-full ring-2 ring-orange-400 pointer-events-none\" />\n )}\n\n {isSelected && (\n <div className=\"absolute inset-0 rounded-full animate-pulse motion-reduce:animate-none ring-2 ring-yellow-400 ring-offset-2 ring-offset-transparent\" />\n )}\n </div>\n </div>\n )\n}\n","import { useId } from 'react'\nimport { cn } from '../../lib/utils'\n\ninterface FootballProps {\n className?: string\n}\n\n// The ball takes the app's `--ball-color` token. It used to be a hardcoded sky\n// blue — the very hue of `--pass-highlight` — so with pass targets lit up the\n// ball dissolved into its own highlights, while both apps defined a\n// `--ball-color` nobody read. The rim is the same colour shaded, so the sphere\n// keeps its volume whatever the token is.\nconst BALL_COLOR = 'var(--ball-color, #ffffff)'\nconst BALL_SHADE = 'color-mix(in srgb, var(--ball-color, #ffffff) 74%, #000000)'\n\nexport const Football = ({ className }: FootballProps) => {\n const bodyId = useId()\n const hiId = `${bodyId}-h`\n\n return (\n <svg\n viewBox=\"0 0 100 100\"\n className={cn('w-full h-full drop-shadow-md', className)}\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <defs>\n <radialGradient id={bodyId} cx=\"36%\" cy=\"32%\" r=\"68%\">\n <stop offset=\"0%\" style={{ stopColor: '#ffffff' }} />\n <stop offset=\"55%\" style={{ stopColor: BALL_COLOR }} />\n <stop offset=\"100%\" style={{ stopColor: BALL_SHADE }} />\n </radialGradient>\n <radialGradient id={hiId} cx=\"32%\" cy=\"28%\" r=\"22%\">\n <stop offset=\"0%\" stopColor=\"#ffffff\" stopOpacity=\"0.85\" />\n <stop offset=\"100%\" stopColor=\"#ffffff\" stopOpacity=\"0\" />\n </radialGradient>\n </defs>\n\n <circle cx=\"50\" cy=\"50\" r=\"47\" fill={`url(#${bodyId})`} stroke=\"#18181b\" strokeWidth=\"1.5\" />\n\n <g stroke=\"#18181b\" strokeWidth=\"1.4\" strokeLinecap=\"round\" fill=\"none\">\n <line x1=\"50\" y1=\"41\" x2=\"50\" y2=\"30\" />\n <line x1=\"41.44\" y1=\"47.22\" x2=\"30.97\" y2=\"43.82\" />\n <line x1=\"44.71\" y1=\"57.28\" x2=\"38.24\" y2=\"66.18\" />\n <line x1=\"55.29\" y1=\"57.28\" x2=\"61.76\" y2=\"66.18\" />\n <line x1=\"58.56\" y1=\"47.22\" x2=\"69.03\" y2=\"43.82\" />\n\n <line x1=\"50\" y1=\"15.5\" x2=\"50\" y2=\"4.5\" />\n <line x1=\"17.18\" y1=\"39.34\" x2=\"6.71\" y2=\"35.94\" />\n <line x1=\"29.72\" y1=\"77.91\" x2=\"23.25\" y2=\"86.81\" />\n <line x1=\"70.28\" y1=\"77.91\" x2=\"76.75\" y2=\"86.81\" />\n <line x1=\"82.82\" y1=\"39.34\" x2=\"93.29\" y2=\"35.94\" />\n </g>\n\n <g fill=\"#18181b\" stroke=\"#18181b\" strokeWidth=\"0.6\" strokeLinejoin=\"round\">\n <polygon points=\"50,41 41.44,47.22 44.71,57.28 55.29,57.28 58.56,47.22\" />\n <polygon points=\"50,30 57.61,24.47 54.70,15.53 45.30,15.53 42.39,24.47\" />\n <polygon points=\"30.97,43.82 28.06,34.88 18.66,34.88 15.75,43.82 23.36,49.35\" />\n <polygon points=\"38.24,66.18 29.84,66.18 25.93,75.12 33.54,80.65 41.15,75.12\" />\n <polygon points=\"61.76,66.18 58.85,75.12 66.46,80.65 74.07,75.12 71.16,66.18\" />\n <polygon points=\"69.03,43.82 76.64,49.35 84.25,43.82 81.34,34.88 71.94,34.88\" />\n </g>\n\n <circle cx=\"50\" cy=\"50\" r=\"47\" fill={`url(#${hiId})`} pointerEvents=\"none\" />\n </svg>\n )\n}\n","import { createContext, useContext, type ReactNode } from 'react'\nimport { MotionConfig } from 'framer-motion'\nimport { SHORT_KEY, LONG_KEY, type PieceShortKey, type PieceLongKey } from '@scriptonita/chess-football-engine'\n\n/**\n * A translator scoped to the `game` namespace: `t('yourTurn')`, `t('move')`, …\n * Each host app supplies one bound to its own i18n library:\n * - Next.js (next-intl): const t = useTranslations('game')\n * - Vite (react-i18next): (key) => t(`game.${key}`)\n */\nexport type GameTranslator = (key: string, values?: Record<string, unknown>) => string\n\n/**\n * Static leaf keys the package's components read via `useGameT` with a literal `t('…')` call.\n * Keep in sync with those call sites — recipe:\n * grep -rhoE \"t\\('[a-zA-Z0-9_.]+'\" src/components | sed -E \"s/t\\('//;s/'//\" | sort -u\n * (the dynamic `pieces.*` / `eventToast.*` families are derived separately below;\n * `hints.*` is read through a template literal in `game-hints.tsx`, one key per `GameHintId`).\n */\nconst STATIC_I18N_KEYS = [\n 'actionPointsAriaLabel',\n 'actionPointsShort',\n 'ballHolder',\n 'boardAriaLabel',\n 'endTurn',\n 'endTurnConfirm',\n 'endTurnConfirmDescription',\n 'endTurnConfirmYes',\n 'endTurnKeepPlaying',\n 'hints.dismiss',\n 'hints.hasBall',\n 'hints.lastActionPoint',\n 'hints.selectPiece',\n 'hints.start',\n 'history.empty',\n 'history.goal',\n 'history.interception',\n 'history.move',\n 'history.offside',\n 'history.pass',\n 'history.tackle',\n 'history.title',\n 'history.close',\n 'history.turn',\n 'history.viewAll',\n 'move',\n 'offsideWarning',\n 'pass',\n 'scoreAriaLabel',\n 'selectedPiece.alreadyMoved',\n 'selectedPiece.atSquare',\n 'selectedPiece.empty',\n 'selectedPiece.hasBall',\n 'shortcuts.arrows',\n 'shortcuts.buttonLabel',\n 'shortcuts.cancel',\n 'shortcuts.move',\n 'shortcuts.pass',\n 'shortcuts.select',\n 'shortcuts.title',\n 'square.empty',\n 'square.emptyWithBall',\n 'square.moveOrPassTarget',\n 'square.moveTarget',\n 'square.passTarget',\n 'square.piece',\n 'square.pieceWithBall',\n 'square.selected',\n 'teamBlack',\n 'teamWhite',\n 'waitingRival',\n 'yourTurn',\n] as const\n\n/** `pieces.*` — one key per short and long piece label the engine exposes (move-history, selected-piece-detail). */\ntype PieceI18nKey = `pieces.${PieceShortKey | PieceLongKey}`\nconst PIECE_I18N_KEYS: PieceI18nKey[] = [...Object.values(SHORT_KEY), ...Object.values(LONG_KEY)].map(\n (label) => `pieces.${label}` as PieceI18nKey,\n)\n\n/** `eventToast.*` — one key per toastable event (see `ToastEvent` in `event-toast.tsx`). */\ntype EventToastI18nKey = `eventToast.${'goal' | 'interception' | 'offside' | 'tackle'}`\nconst EVENT_TOAST_I18N_KEYS: EventToastI18nKey[] = [\n 'eventToast.goal',\n 'eventToast.interception',\n 'eventToast.offside',\n 'eventToast.tackle',\n]\n\n/** Union of every `game`-namespace key the package reads. */\nexport type GameI18nKey = (typeof STATIC_I18N_KEYS)[number] | PieceI18nKey | EventToastI18nKey\n\n/**\n * Manifest of every `game`-namespace key the package's components read via `useGameT`.\n * Host apps use it to assert their translation catalogs cover the package (AD-4).\n * The `pieces.*` family is derived from the engine's `SHORT_KEY`/`LONG_KEY` so it can't\n * drift when a piece is added; static keys and `eventToast.*` are listed above.\n * No key names an automated-opponent brand — the roster owns opponent identity.\n */\nexport const GAME_I18N_KEYS: readonly GameI18nKey[] = [\n ...STATIC_I18N_KEYS,\n ...PIECE_I18N_KEYS,\n ...EVENT_TOAST_I18N_KEYS,\n]\n\n/**\n * Identity fallback: renders the key itself when the host app has no catalog\n * entry for it. It shouts in development because a missing key is invisible in\n * production until a player screenshots `⚠ game.offsideWarning` on the pitch.\n * `GAME_I18N_KEYS` exists so a test catches this before a human does.\n */\nconst nodeEnv = (globalThis as { process?: { env?: { NODE_ENV?: string } } }).process?.env?.NODE_ENV\n\nconst fallback: GameTranslator = (key) => {\n if (nodeEnv && nodeEnv !== 'production') {\n console.warn(`[chess-football-ui] missing game i18n key: \"${key}\" (no GameI18nProvider?)`)\n }\n return key\n}\n\nconst GameI18nContext = createContext<GameTranslator>(fallback)\n\nexport function GameI18nProvider({ t, children }: { t: GameTranslator; children: ReactNode }) {\n return (\n <GameI18nContext.Provider value={t}>\n <MotionConfig reducedMotion=\"user\">\n {children}\n </MotionConfig>\n </GameI18nContext.Provider>\n )\n}\n\n/** Returns the `game`-scoped translator provided by the host app (identity fallback). */\nexport function useGameT(): GameTranslator {\n return useContext(GameI18nContext)\n}\n","import { useGameStore } from '../../store/use-game-store'\nimport { PieceIcon, WHITE_PIECE_STYLE, BLACK_PIECE_STYLE } from './game-piece'\nimport { Football } from './football'\nimport { useGameT } from '../../i18n'\nimport { cn } from '../../lib/utils'\n\ninterface BallHolderChipProps {\n className?: string\n}\n\n/**\n * §12b: a persistent, always-visible answer to \"whose ball is it\" — the piece\n * type currently holding the ball, drawn as a mini chip. Additive to the subtle\n * per-piece ring on the board. Renders nothing while the ball is loose.\n *\n * GameBoard shows it in its own toolbar by default; apps with a side panel can\n * pass `toolbar={false}` to the board and place this chip wherever it reads best.\n */\nexport function BallHolderChip({ className }: BallHolderChipProps) {\n const t = useGameT()\n const boardState = useGameStore(s => s.boardState)\n const holder = boardState?.pieces.find(p => p.id === boardState.ball.holderId) ?? null\n if (!holder) return null\n\n return (\n <div className={cn('flex items-center gap-1.5 min-h-[1.75rem]', className)} aria-live=\"polite\">\n <div\n style={holder.side === 'white' ? WHITE_PIECE_STYLE : BLACK_PIECE_STYLE}\n className=\"relative w-7 h-7 flex items-center justify-center rounded-full shrink-0\"\n >\n <PieceIcon type={holder.type} side={holder.side} />\n <div className=\"absolute -bottom-1 -right-1 w-3.5 h-3.5 flex items-center justify-center rounded-full bg-bg-secondary border border-border-subtle\">\n <div className=\"w-2.5 h-2.5\"><Football /></div>\n </div>\n </div>\n <span className=\"font-inter text-[11px] text-fg-secondary\">\n {t('ballHolder')}: {t(`pieces.${holder.type}`)}\n </span>\n </div>\n )\n}\n","import { useGameT } from '../../i18n'\nimport { cn } from '../../lib/utils'\n\ninterface KeyboardShortcutsListProps {\n className?: string\n}\n\n/**\n * §12: the legend of the board's keyboard shortcuts. GameBoard shows it in a\n * popover behind a \"?\" button in its toolbar; apps that pass `toolbar={false}`\n * can render the list inline in a side panel instead.\n */\nexport function KeyboardShortcutsList({ className }: KeyboardShortcutsListProps) {\n const t = useGameT()\n return (\n <ul className={cn('font-mono text-[10px] text-fg-secondary leading-relaxed', className)}>\n <li><kbd className=\"text-fg-primary\">↑↓←→</kbd> {t('shortcuts.arrows')}</li>\n <li><kbd className=\"text-fg-primary\">Enter</kbd> {t('shortcuts.select')}</li>\n <li><kbd className=\"text-fg-primary\">M</kbd> {t('shortcuts.move')}</li>\n <li><kbd className=\"text-fg-primary\">P</kbd> {t('shortcuts.pass')}</li>\n <li><kbd className=\"text-fg-primary\">Esc</kbd> {t('shortcuts.cancel')}</li>\n </ul>\n )\n}\n","import { useId } from 'react'\nimport { cn } from '../../lib/utils'\n\n// ─── Squares ─────────────────────────────────────────────────────────────────\n\nexport const PITCH_COLS = 9\nexport const PITCH_ROWS = 12\n\n/** The two goal boxes: files c–g on the first two and last two ranks. */\nexport const isGoalAreaSquare = (x: number, y: number): boolean =>\n x >= 2 && x <= 6 && ((y >= 0 && y <= 1) || (y >= PITCH_ROWS - 2 && y <= PITCH_ROWS - 1))\n\n/**\n * Goal-box shading: an inset box-shadow that darkens the square *over* its own\n * green, so the box reads as a distinct zone (the king's area) while the\n * checkerboard alternation stays visible — opponents enter it square by square\n * and need to read their moves there. An inset shadow (rather than a flat\n * replacement colour) keeps the app's tokens in charge of the hue and composes\n * with Tailwind's `ring-*` utilities on the live board's highlighted squares.\n */\nexport const GOAL_AREA_SHADE_CLASS = 'shadow-[inset_0_0_0_100vmax_rgba(0,0,0,0.32)]'\n\n/**\n * Base classes of one pitch square. Every board renderer — the live GameBoard,\n * StaticGameBoard, and any app-side mini board built on PitchSurface — derives\n * its squares from here, so the field reads identically everywhere. Colours\n * come from the app's `field-green-*` design tokens.\n */\nexport function pitchSquareClass(x: number, y: number): string {\n const isEven = (x + y) % 2 === 0\n return cn(\n 'relative aspect-square w-full',\n isEven ? 'bg-field-green-1' : 'bg-field-green-2',\n isGoalAreaSquare(x, y) && GOAL_AREA_SHADE_CLASS,\n )\n}\n\n// ─── Grass ───────────────────────────────────────────────────────────────────\n//\n// A seamless fractal-noise tile, inlined as an SVG data URI and repeated as a\n// background. `stitchTiles` makes the repeat seamless, so the grain reads as\n// one continuous surface across the whole pitch instead of per-square. Blended\n// with `mix-blend-mode: overlay`, mid-grey is neutral: the noise only nudges\n// the underlying green lighter/darker, so both square shades (and the darker\n// goal boxes) keep their own colour while gaining a turf-like texture. The\n// browser rasterises the tile once and caches it — no per-frame filter cost.\nconst GRAIN_TILE_SVG =\n '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"160\" height=\"160\">' +\n '<filter id=\"g\" x=\"0\" y=\"0\" width=\"100%\" height=\"100%\" color-interpolation-filters=\"sRGB\">' +\n '<feTurbulence type=\"fractalNoise\" baseFrequency=\"0.9\" numOctaves=\"3\" seed=\"7\" stitchTiles=\"stitch\"/>' +\n '<feColorMatrix type=\"saturate\" values=\"0\"/>' +\n '</filter>' +\n '<rect width=\"100%\" height=\"100%\" filter=\"url(#g)\"/>' +\n '</svg>'\n\nexport const GRAIN_TILE_URL = `url(\"data:image/svg+xml;utf8,${encodeURIComponent(GRAIN_TILE_SVG)}\")`\n\n// Stadium-light falloff: a faint highlight around the upper middle of the pitch\n// and darker edges, so the surface reads as a lit plane the pieces sit on\n// rather than a flat fill. Kept subtle so move/pass highlights stay legible.\nconst VIGNETTE =\n 'radial-gradient(120% 95% at 50% 38%, rgba(255,255,255,0.06) 0%, rgba(255,255,255,0) 42%, rgba(0,0,0,0.26) 100%)'\n\ninterface GrassOverlayProps {\n className?: string\n}\n\n/**\n * Decorative turf texture for the pitch. Absolutely positioned over the square\n * grid and click-through, so it sits between the squares and the pieces without\n * affecting hit-testing or the per-square highlight classes.\n */\nexport function GrassOverlay({ className }: GrassOverlayProps) {\n return (\n <div\n aria-hidden=\"true\"\n data-testid=\"grass-overlay\"\n className={cn('absolute inset-0 pointer-events-none overflow-hidden', className)}\n >\n <div\n data-layer=\"grain\"\n className=\"absolute inset-0 mix-blend-overlay opacity-60\"\n style={{ backgroundImage: GRAIN_TILE_URL, backgroundSize: '160px 160px' }}\n />\n <div data-layer=\"light\" className=\"absolute inset-0\" style={{ background: VIGNETTE }} />\n </div>\n )\n}\n\n// ─── Chalk markings ──────────────────────────────────────────────────────────\n//\n// Coordinates are in board cells (viewBox 0 0 9 12, y grows downwards), so the\n// markings stretch with the grid at any size.\n\nconst CHALK = '#f6f5ee'\n\ninterface PitchMarkingsProps {\n className?: string\n children?: React.ReactNode\n}\n\n/**\n * The painted pitch lines — touchline, goal boxes, halfway line, centre circle,\n * spots and the two \"D\" arcs — drawn to look like chalk on grass: a roughened,\n * slightly displaced edge and a noise-driven alpha so the coverage is powdery\n * rather than a crisp vector stroke. A faint, wider unfiltered pass underneath\n * acts as the dust halo the line leaves on the turf.\n *\n * Static and cached by the browser as its own layer; anything dynamic that\n * shares the board's coordinate space (e.g. the pass-trajectory preview) should\n * live in a separate <svg> so a hover repaint never re-runs this filter.\n */\nexport function PitchMarkings({ className, children }: PitchMarkingsProps) {\n const id = useId()\n const filterId = `${id}-chalk`\n\n return (\n <svg\n viewBox=\"0 0 9 12\"\n preserveAspectRatio=\"none\"\n className={cn('absolute inset-0 w-full h-full pointer-events-none', className)}\n aria-hidden=\"true\"\n data-testid=\"pitch-markings\"\n >\n <defs>\n <filter\n id={filterId}\n filterUnits=\"userSpaceOnUse\"\n x=\"-0.5\"\n y=\"-0.5\"\n width=\"10\"\n height=\"13\"\n colorInterpolationFilters=\"sRGB\"\n >\n {/* Wobble the edge: low-frequency noise pushes the stroke by up to ~0.04 cells. */}\n <feTurbulence type=\"fractalNoise\" baseFrequency=\"5.5\" numOctaves=\"2\" seed=\"3\" result=\"edgeNoise\" />\n <feDisplacementMap\n in=\"SourceGraphic\"\n in2=\"edgeNoise\"\n scale=\"0.045\"\n xChannelSelector=\"R\"\n yChannelSelector=\"G\"\n result=\"rough\"\n />\n {/* Powdery coverage: a second noise becomes an alpha mask in the 0.55–1 range. */}\n <feTurbulence type=\"fractalNoise\" baseFrequency=\"14\" numOctaves=\"3\" seed=\"11\" result=\"dust\" />\n <feColorMatrix\n in=\"dust\"\n type=\"matrix\"\n values=\"0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0.75 0 0 0 0.55\"\n result=\"dustMask\"\n />\n <feComposite in=\"rough\" in2=\"dustMask\" operator=\"arithmetic\" k1=\"1\" k2=\"0\" k3=\"0\" k4=\"0\" />\n </filter>\n </defs>\n\n {/* Dust halo: wider, faint, unfiltered so it stays cheap. */}\n <g data-layer=\"halo\" fill=\"none\" stroke={CHALK} strokeOpacity=\"0.09\" strokeWidth=\"0.16\" strokeLinecap=\"round\">\n <Markings />\n </g>\n\n <g\n data-layer=\"chalk\"\n filter={`url(#${filterId})`}\n fill=\"none\"\n stroke={CHALK}\n strokeOpacity=\"0.82\"\n strokeWidth=\"0.07\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <Markings />\n </g>\n\n {children}\n </svg>\n )\n}\n\nfunction Markings() {\n return (\n <>\n {/* Touchline / goal lines */}\n <rect x=\"0.06\" y=\"0.06\" width=\"8.88\" height=\"11.88\" />\n {/* Goal boxes */}\n <rect x=\"2\" y=\"0.06\" width=\"5\" height=\"1.94\" />\n <rect x=\"2\" y=\"10\" width=\"5\" height=\"1.94\" />\n {/* Halfway line */}\n <line x1=\"0.06\" y1=\"6\" x2=\"8.94\" y2=\"6\" />\n {/* Centre circle + spot */}\n <circle cx=\"4.5\" cy=\"6\" r=\"1.5\" />\n <circle cx=\"4.5\" cy=\"6\" r=\"0.09\" fill={CHALK} fillOpacity=\"0.9\" stroke=\"none\" />\n {/* Penalty spots */}\n <circle cx=\"4.5\" cy=\"1.5\" r=\"0.08\" fill={CHALK} fillOpacity=\"0.9\" stroke=\"none\" />\n <circle cx=\"4.5\" cy=\"10.5\" r=\"0.08\" fill={CHALK} fillOpacity=\"0.9\" stroke=\"none\" />\n {/* The \"D\" arcs */}\n <path d=\"M 3.086,2 A 1.5,1.5 0 0 0 5.914,2\" />\n <path d=\"M 3.086,10 A 1.5,1.5 0 0 1 5.914,10\" />\n </>\n )\n}\n\n// ─── Surface ─────────────────────────────────────────────────────────────────\n\ninterface PitchSurfaceProps {\n className?: string\n /**\n * Extra classes for a given square (e.g. a highlighted area in a rules\n * diagram). Falsy return values are ignored.\n */\n squareClassName?: (x: number, y: number) => string | false | null | undefined\n /** Layers rendered above the markings — pieces, ball, overlays. */\n children?: React.ReactNode\n}\n\n/**\n * The complete, non-interactive pitch: squares, turf grain and chalk lines, in\n * that order, inside a container-query wrapper so pieces can size themselves\n * with `cqw`. Callers put their own frame (border/radius) around it and their\n * own piece layer inside it. The interactive GameBoard renders its own square\n * grid (it needs per-square handlers) but builds every square from the same\n * `pitchSquareClass`, and stacks the same GrassOverlay + PitchMarkings.\n */\nexport function PitchSurface({ className, squareClassName, children }: PitchSurfaceProps) {\n const squares = []\n for (let y = PITCH_ROWS - 1; y >= 0; y--) {\n for (let x = 0; x < PITCH_COLS; x++) {\n squares.push(\n <div key={`${x}-${y}`} className={cn(pitchSquareClass(x, y), squareClassName?.(x, y))} />,\n )\n }\n }\n return (\n <div className={cn('relative', className)} style={{ containerType: 'inline-size' }}>\n <div className=\"grid grid-cols-9 gap-[1px]\" data-testid=\"pitch-squares\">\n {squares}\n </div>\n <GrassOverlay />\n <PitchMarkings />\n {children}\n </div>\n )\n}\n","import { useGameStore } from '../../store/use-game-store'\nimport { useShallow } from 'zustand/react/shallow'\nimport { getValidMoves, getValidPasses, getPath, isInEnemyArea } from '@scriptonita/chess-football-engine'\nimport { cn } from '../../lib/utils'\nimport { motion, AnimatePresence, useReducedMotion } from 'framer-motion'\nimport GamePiece from './game-piece'\nimport { BallHolderChip } from './ball-holder-chip'\nimport { KeyboardShortcutsList } from './keyboard-shortcuts'\nimport { useEffect, useId, useMemo, useRef, useState } from 'react'\nimport { Side, Position, MoveHistoryEntry, Piece, LONG_KEY, squareName } from '@scriptonita/chess-football-engine'\nimport { Football } from './football'\nimport { GrassOverlay, PitchMarkings, pitchSquareClass } from './pitch'\nimport { FILE_LABELS, RANK_LABELS } from '@scriptonita/chess-football-engine'\nimport { Move, HelpCircle } from 'lucide-react'\nimport { useGameT } from '../../i18n'\n\ninterface GameBoardProps {\n userSide: Side | null\n /** When true, render A-I / 1-12 coordinate guides around the board (tablet+ only). */\n showCoordinates?: boolean\n /** When true, the board is keyboard-operable (arrows move a cursor, Enter acts). */\n keyboardNav?: boolean\n /**\n * Desktop-only row above the grid with the ball-holder chip and the keyboard\n * shortcuts button. Pass `false` when the app renders `BallHolderChip` and\n * `KeyboardShortcutsList` itself (e.g. in a side panel) so nothing is shown twice.\n */\n toolbar?: boolean\n /**\n * Forgive a near-miss on touch: with a piece selected, a tap on an empty,\n * non-target square that touches exactly ONE legal target resolves to that\n * target. A phone square is ~35–40 px — under the 44 px a fingertip needs — and\n * cannot be made bigger (9 files across the screen), so the miss is absorbed\n * instead. Never applies to mouse or keyboard, nor when the tap is ambiguous.\n * Opt-in: an app that sees unwanted plays turns it off without a release.\n */\n forgivingTaps?: boolean\n className?: string\n}\n\n// Board dimensions\nconst COLS = 9\nconst ROWS = 12\n\nconst clamp = (v: number, lo: number, hi: number) => Math.max(lo, Math.min(hi, v))\n\n// Pieces and the ball are positioned with translate transforms instead of\n// animating `left`/`top`: each wrapper is exactly one cell wide/tall, so a\n// percentage translate of N×100% lands on cell N, and the animation runs on the\n// compositor (no layout/paint per frame) — that is what makes the slide smooth.\nconst cellX = (x: number) => `${x * 100}%`\nconst cellY = (y: number) => `${(ROWS - 1 - y) * 100}%`\n\n// A click this soon after a touchstart is that touch's own synthesized click.\nconst TOUCH_CLICK_WINDOW_MS = 800\n\n// Critically-damped springs (ratio ≈ 1.0): a firm push-off, a long glide and\n// a soft landing with no bounce — a chip sliding across turf, not a rubber\n// ball. Settles in roughly half a second regardless of distance, so a long\n// rook run still reads as one motion. A carried ball uses the piece's curve\n// so it never drifts ahead of or behind its holder; a free ball (pass) is\n// lighter and snappier.\nconst PIECE_SLIDE = { type: 'spring' as const, stiffness: 190, damping: 28, mass: 1 }\nconst BALL_SLIDE = { type: 'spring' as const, stiffness: 300, damping: 26, mass: 0.6 }\n\nexport default function GameBoard({ userSide, showCoordinates = false, keyboardNav = true, toolbar = true, forgivingTaps = false, className }: GameBoardProps) {\n const t = useGameT()\n const boardId = useId()\n const prefersReducedMotion = useReducedMotion()\n // Selector + useShallow: without it every `set` on the store re-renders all\n // 108 squares, including sets this component does not care about.\n const {\n boardState,\n selectedPieceId,\n interactionMode,\n setSelectedPieceId,\n setInteractionMode,\n movePiece,\n passBall,\n } = useGameStore(\n useShallow(s => ({\n boardState: s.boardState,\n selectedPieceId: s.selectedPieceId,\n interactionMode: s.interactionMode,\n setSelectedPieceId: s.setSelectedPieceId,\n setInteractionMode: s.setInteractionMode,\n movePiece: s.movePiece,\n passBall: s.passBall,\n })),\n )\n\n const [cursor, setCursor] = useState<Position | null>(null)\n const [disambiguateAt, setDisambiguateAt] = useState<Position | null>(null)\n const [shortcutsOpen, setShortcutsOpen] = useState(false)\n const shortcutsRef = useRef<HTMLDivElement>(null)\n useEffect(() => {\n if (!shortcutsOpen) return\n const onPointerDown = (e: MouseEvent) => {\n if (shortcutsRef.current && !shortcutsRef.current.contains(e.target as Node)) {\n setShortcutsOpen(false)\n }\n }\n document.addEventListener('mousedown', onPointerDown)\n return () => document.removeEventListener('mousedown', onPointerDown)\n }, [shortcutsOpen])\n const [invalidClickAt, setInvalidClickAt] = useState<(Position & { nonce: number }) | null>(null)\n const invalidClickNonceRef = useRef(0)\n const triggerInvalidClickShake = (x: number, y: number) => {\n invalidClickNonceRef.current += 1\n setInvalidClickAt({ x, y, nonce: invalidClickNonceRef.current })\n }\n const [hoveredPassAt, setHoveredPassAt] = useState<Position | null>(null)\n const lastTouchAtRef = useRef(0)\n\n // Pieces currently travelling between squares (framer-motion drives the\n // slide; this only toggles the lift/shadow cue on GamePiece).\n const [movingIds, setMovingIds] = useState<ReadonlySet<string>>(() => new Set())\n const setMoving = (id: string, moving: boolean) =>\n setMovingIds(prev => {\n if (prev.has(id) === moving) return prev\n const next = new Set(prev)\n if (moving) next.add(id); else next.delete(id)\n return next\n })\n\n useEffect(() => {\n if (!invalidClickAt) return\n const id = setTimeout(() => setInvalidClickAt(null), 100)\n return () => clearTimeout(id)\n }, [invalidClickAt])\n\n const prevBallRef = useRef(boardState?.ball)\n const prevBall = prevBallRef.current\n useEffect(() => {\n prevBallRef.current = boardState?.ball\n })\n\n // §4: sequential replay of a just-finished opponent turn — when the turn\n // hands back to userSide and the opponent recorded more than one action,\n // briefly step through each origin/destination before settling on the\n // real last move, so a multi-action turn doesn't read as a single jump.\n const prevTurnRef = useRef(boardState?.turn)\n const [replay, setReplay] = useState<{ steps: MoveHistoryEntry[]; index: number } | null>(null)\n useEffect(() => {\n const prevTurn = prevTurnRef.current\n prevTurnRef.current = boardState?.turn\n if (!boardState || prevTurn === boardState.turn) return\n\n // Turn moved on again before a replay finished (e.g. a very fast\n // opponent turn) — the in-flight replay is now stale, drop it.\n if (boardState.turn !== userSide) {\n setReplay(null)\n return\n }\n if (prefersReducedMotion || userSide === null) return\n\n const lastEntry = boardState.moveHistory.at(-1)\n if (!lastEntry) return\n const steps = boardState.moveHistory.filter(\n m => m.turnNumber === lastEntry.turnNumber && m.pieceSide !== userSide,\n )\n if (steps.length > 1) setReplay({ steps, index: 0 })\n }, [boardState, userSide, prefersReducedMotion])\n\n useEffect(() => {\n if (!replay) return\n if (replay.index >= replay.steps.length - 1) {\n const id = setTimeout(() => setReplay(null), 350)\n return () => clearTimeout(id)\n }\n const id = setTimeout(() => setReplay(r => (r ? { ...r, index: r.index + 1 } : null)), 350)\n return () => clearTimeout(id)\n }, [replay])\n\n // `interactionMode` was written by both apps (their Move/Pass selector) and\n // read by nobody: the board highlighted every target regardless and still\n // popped the disambiguation popover. Honouring it turns that selector into\n // a real filter — and on touch, into a way to act without the popover.\n const validMoves = useMemo(() => {\n if (!boardState || interactionMode === 'pass') return []\n const sp = boardState.pieces.find(p => p.id === selectedPieceId)\n if (sp && !sp.hasMovedThisTurn) {\n return getValidMoves(sp, boardState)\n }\n return []\n }, [boardState, selectedPieceId, interactionMode])\n\n const validPasses = useMemo(() => {\n if (!boardState || interactionMode === 'move') return []\n const sp = boardState.pieces.find(p => p.id === selectedPieceId)\n if (sp && boardState.ball.holderId === sp.id) {\n return getValidPasses(sp, boardState)\n }\n return []\n }, [boardState, selectedPieceId, interactionMode])\n\n if (!boardState) return null\n\n const lastMove = boardState.lastMove\n const ball = boardState.ball\n const ballMoved =\n !!prevBall &&\n (prevBall.pos.x !== ball.pos.x || prevBall.pos.y !== ball.pos.y)\n const isPickupOnMove =\n !!prevBall &&\n !prevBall.holderId &&\n !!ball.holderId &&\n lastMove?.type === 'move' &&\n lastMove?.playerId === ball.holderId &&\n ballMoved\n\n const PICKUP_DURATION = 0.5\n const pickupCarrierId = isPickupOnMove ? ball.holderId : null\n let pickupProportion = 0.5\n if (isPickupOnMove && prevBall && lastMove?.from) {\n const totalSteps = Math.max(\n Math.abs(lastMove.to.x - lastMove.from.x),\n Math.abs(lastMove.to.y - lastMove.from.y),\n )\n const stepsToBall = Math.max(\n Math.abs(prevBall.pos.x - lastMove.from.x),\n Math.abs(prevBall.pos.y - lastMove.from.y),\n )\n pickupProportion = totalSteps > 0\n ? Math.min(0.85, Math.max(0.15, stepsToBall / totalSteps))\n : 0.5\n }\n\n // §8: Offside risk — ball carrier (non-king) in enemy area during user's turn\n const ballCarrier = ball.holderId\n ? boardState.pieces.find(p => p.id === ball.holderId) ?? null\n : null\n const isOffsideRisk =\n !!ballCarrier &&\n ballCarrier.type !== 'king' &&\n userSide !== null &&\n ballCarrier.side === userSide &&\n boardState.turn === userSide &&\n isInEnemyArea(ballCarrier.pos, ballCarrier.side)\n\n // §16: pass-trajectory preview — dashed line from the ball carrier to the\n // hovered valid-pass square, red if an opposing piece would intercept it.\n // Mirrors applyPass's own rules (game-engine.ts): the path INCLUDES the\n // destination (an enemy sitting there still intercepts/scores), and a\n // knight's pass only ever checks the destination — no traversal, since a\n // knight throw doesn't travel the straight/diagonal line getPath assumes.\n const passCarrier = boardState.pieces.find(p => p.id === selectedPieceId && boardState.ball.holderId === p.id) ?? null\n const trajectoryPath = (hoveredPassAt && passCarrier)\n ? (passCarrier.type === 'knight' ? [hoveredPassAt] : getPath(passCarrier.pos, hoveredPassAt))\n : null\n const trajectoryIntercepted = !!(trajectoryPath && passCarrier && trajectoryPath\n .some(sq => boardState.pieces.some(p => p.pos.x === sq.x && p.pos.y === sq.y && p.side !== passCarrier.side)))\n\n // The one legal target touching (x, y), or null when there is none or several:\n // a tap between two targets says nothing about which one was meant.\n const soleAdjacentTarget = (x: number, y: number): Position | null => {\n const near = [...validMoves, ...validPasses].filter(\n (t, i, all) =>\n Math.max(Math.abs(t.x - x), Math.abs(t.y - y)) === 1 &&\n all.findIndex(o => o.x === t.x && o.y === t.y) === i,\n )\n return near.length === 1 ? near[0] : null\n }\n\n const handleSquareClick = (x: number, y: number, fromTouch = false) => {\n if (replay) return // §4: don't act while the opponent-turn replay is playing\n setCursor(null)\n const isValidMove = validMoves.some(m => m.x === x && m.y === y)\n const isValidPass = validPasses.some(p => p.x === x && p.y === y)\n\n if (!isValidMove && !isValidPass && fromTouch && forgivingTaps && selectedPieceId) {\n const target = soleAdjacentTarget(x, y)\n if (target) {\n handleSquareClick(target.x, target.y)\n return\n }\n }\n\n if (isValidMove && isValidPass) {\n setDisambiguateAt({ x, y })\n return\n }\n if (isValidMove && selectedPieceId) {\n movePiece(selectedPieceId, { x, y })\n setDisambiguateAt(null)\n setInvalidClickAt(null)\n } else if (isValidPass) {\n passBall({ x, y })\n setDisambiguateAt(null)\n setInvalidClickAt(null)\n } else {\n // §16: subtle shake when a piece is selected but the target square\n // isn't a legal move/pass — no-op clicks on empty board stay silent.\n if (selectedPieceId) {\n triggerInvalidClickShake(x, y)\n }\n setDisambiguateAt(null)\n }\n }\n\n const handlePieceClick = (pieceId: string, x: number, y: number, e: React.MouseEvent) => {\n e.stopPropagation()\n if (replay) return // §4: don't act while the opponent-turn replay is playing\n const pieceAt = boardState.pieces.find(p => p.id === pieceId)\n if (!pieceAt) return\n\n const isValidMove = validMoves.some(m => m.x === x && m.y === y)\n const isValidPass = validPasses.some(p => p.x === x && p.y === y)\n\n if (isValidMove || isValidPass) {\n handleSquareClick(x, y)\n } else if (boardState.turn === pieceAt.side && userSide === pieceAt.side) {\n if (selectedPieceId === pieceAt.id) {\n setSelectedPieceId(null)\n } else {\n setSelectedPieceId(pieceAt.id)\n }\n setDisambiguateAt(null)\n setInvalidClickAt(null)\n } else if (selectedPieceId) {\n // §16: clicking an occupied square (own non-selectable or opponent\n // piece) that isn't a legal target is just as \"invalid\" as clicking\n // an illegal empty square — keep the feedback consistent.\n triggerInvalidClickShake(x, y)\n setDisambiguateAt(null)\n }\n }\n\n const defaultCursor = (): Position => {\n const sel = boardState.pieces.find(p => p.id === selectedPieceId)\n return sel ? { ...sel.pos } : { ...boardState.ball.pos }\n }\n\n const activate = (x: number, y: number) => {\n const pieceAt = boardState.pieces.find(p => p.pos.x === x && p.pos.y === y)\n if (pieceAt) {\n handlePieceClick(pieceAt.id, x, y, { stopPropagation() {} } as React.MouseEvent)\n } else {\n handleSquareClick(x, y)\n }\n }\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (!keyboardNav || replay) return\n const step = (dx: number, dy: number) => {\n e.preventDefault()\n setCursor(c => {\n const base = c ?? defaultCursor()\n return { x: clamp(base.x + dx, 0, COLS - 1), y: clamp(base.y + dy, 0, ROWS - 1) }\n })\n }\n switch (e.key) {\n case 'ArrowUp': step(0, 1); break\n case 'ArrowDown': step(0, -1); break\n case 'ArrowLeft': step(-1, 0); break\n case 'ArrowRight': step(1, 0); break\n case 'Enter':\n case ' ': {\n e.preventDefault()\n const c = cursor ?? defaultCursor()\n setCursor(c)\n activate(c.x, c.y)\n break\n }\n // Bare M / P only: Cmd+P is Print and Ctrl+M is a browser shortcut,\n // and both used to resolve the popover behind the user's back.\n case 'm': case 'M':\n if (e.ctrlKey || e.metaKey || e.altKey) break\n if (disambiguateAt && selectedPieceId) {\n movePiece(selectedPieceId, disambiguateAt)\n setDisambiguateAt(null)\n }\n break\n case 'p': case 'P':\n if (e.ctrlKey || e.metaKey || e.altKey) break\n if (disambiguateAt) {\n passBall(disambiguateAt)\n setDisambiguateAt(null)\n }\n break\n case 'Escape':\n if (shortcutsOpen) {\n setShortcutsOpen(false)\n } else if (disambiguateAt) {\n setDisambiguateAt(null)\n } else {\n setSelectedPieceId(null)\n setInteractionMode(null)\n }\n break\n }\n }\n\n const cellId = (x: number, y: number) => `${boardId}-sq-${x}-${y}`\n\n /**\n * The square's accessible name: coordinate first (so a screen reader user\n * always knows where the cursor is), then what is on it, then why it is\n * highlighted. Fragments are joined with \", \" rather than composed into one\n * template so every part stays independently translatable.\n */\n const squareLabel = (\n x: number,\n y: number,\n pieceAt: Piece | undefined,\n isValidMove: boolean,\n isValidPass: boolean,\n ) => {\n const square = squareName({ x, y })\n const ballHere = ball.pos.x === x && ball.pos.y === y\n const parts: string[] = []\n\n if (pieceAt) {\n const piece = t(`pieces.${LONG_KEY[pieceAt.type]}`)\n const team = pieceAt.side === 'white' ? t('teamWhite') : t('teamBlack')\n parts.push(t(ballHere ? 'square.pieceWithBall' : 'square.piece', { square, piece, team }))\n } else {\n parts.push(t(ballHere ? 'square.emptyWithBall' : 'square.empty', { square }))\n }\n\n if (isValidMove && isValidPass) parts.push(t('square.moveOrPassTarget'))\n else if (isValidMove) parts.push(t('square.moveTarget'))\n else if (isValidPass) parts.push(t('square.passTarget'))\n\n if (pieceAt && pieceAt.id === selectedPieceId) parts.push(t('square.selected'))\n\n return parts.join(', ')\n }\n\n // One `role=\"row\"` per rank. `display: contents` keeps the rows out of the\n // layout so the 9x12 CSS grid is unchanged — only the accessibility tree\n // gains the row structure `role=\"grid\"` requires.\n const renderRows = () => {\n const rows = []\n for (let y = ROWS - 1; y >= 0; y--) {\n const squares = []\n for (let x = 0; x < COLS; x++) {\n const isValidMove = validMoves.some(m => m.x === x && m.y === y)\n const isValidPass = validPasses.some(p => p.x === x && p.y === y)\n const isAmbiguous = isValidMove && isValidPass\n\n // §4: while a sequential replay is in progress, the highlighted\n // origin/destination trail follows the current replay step\n // instead of the real last move.\n const displayedLastMove = replay ? replay.steps[replay.index] : lastMove\n const isLastMoveOrigin = displayedLastMove?.from && displayedLastMove.from.x === x && displayedLastMove.from.y === y\n const isLastMoveDest = displayedLastMove?.to && displayedLastMove.to.x === x && displayedLastMove.to.y === y\n const isLastMove = isLastMoveOrigin || isLastMoveDest\n\n // §8: enemy goal area for offside warning\n const isEnemyGoalArea = userSide !== null\n && (x >= 2 && x <= 6)\n && (userSide === 'white' ? (y >= 10 && y <= 11) : (y >= 0 && y <= 1))\n\n const pieceAt = boardState.pieces.find(p => p.pos.x === x && p.pos.y === y)\n const isCursor = keyboardNav && cursor?.x === x && cursor?.y === y\n const isDisambiguateTarget = disambiguateAt?.x === x && disambiguateAt?.y === y\n\n squares.push(\n <div\n key={`${x}-${y}`}\n id={cellId(x, y)}\n role=\"gridcell\"\n aria-label={squareLabel(x, y, pieceAt, isValidMove, isValidPass)}\n aria-selected={!!pieceAt && pieceAt.id === selectedPieceId}\n onClick={() => handleSquareClick(x, y, Date.now() - lastTouchAtRef.current < TOUCH_CLICK_WINDOW_MS)}\n onMouseEnter={() => { if (isValidPass) setHoveredPassAt({ x, y }) }}\n onMouseLeave={() => setHoveredPassAt(null)}\n // The preview hung off onMouseEnter alone, so it never\n // appeared on the touch devices that are most of the\n // CrazyGames audience. A first touch previews the\n // trajectory; handleSquareClick then confirms it.\n onTouchStart={() => {\n lastTouchAtRef.current = Date.now()\n if (isValidPass) setHoveredPassAt({ x, y })\n }}\n className={cn(\n pitchSquareClass(x, y),\n \"flex items-center justify-center cursor-pointer\",\n !isValidMove && !isValidPass && isLastMove && \"bg-last-move-highlight/20\",\n // §8: pulsing warning ring on enemy goal area\n isOffsideRisk && isEnemyGoalArea && !isValidMove && !isValidPass && \"ring-2 ring-inset ring-warning/60\",\n // Move and pass used raw yellow-400/sky-400 here while\n // the popover a few lines below used the\n // move-highlight/pass-highlight tokens — two palettes\n // for the same two concepts. One palette now: tokens.\n isAmbiguous && \"ring-[3px] ring-inset ring-move-highlight/90 bg-move-highlight/20\",\n !isAmbiguous && isValidMove && \"ring-[3px] ring-inset ring-move-highlight/80 bg-move-highlight/15\",\n !isAmbiguous && isValidPass && \"ring-[3px] ring-inset ring-pass-highlight/80 bg-pass-highlight/15\",\n )}\n >\n {/* Colour alone does not distinguish move from pass for a\n colour-blind player, so the marks differ in shape too:\n a filled dot moves, a hollow ring passes. */}\n {!isAmbiguous && isValidMove && !pieceAt && (\n <div data-testid=\"move-marker\" className=\"w-3 h-3 rounded-full bg-move-highlight/65\" />\n )}\n {!isAmbiguous && isValidPass && !pieceAt && (\n <div data-testid=\"pass-marker\" className=\"w-3.5 h-3.5 rounded-full border-2 border-pass-highlight/80\" />\n )}\n {isAmbiguous && !pieceAt && (\n <div className=\"flex items-center gap-0.5\">\n <div data-testid=\"move-marker\" className=\"w-2.5 h-2.5 rounded-full bg-move-highlight/80\" />\n <div data-testid=\"pass-marker\" className=\"w-2.5 h-2.5 rounded-full border-2 border-pass-highlight/90\" />\n </div>\n )}\n\n {isCursor && (\n <div className=\"absolute inset-0 ring-2 ring-inset ring-white pointer-events-none z-20\" aria-hidden=\"true\" />\n )}\n\n {isDisambiguateTarget && selectedPieceId && (\n <div\n className={cn(\n \"absolute z-50 flex gap-1 bg-bg-secondary border border-border-subtle rounded-md p-1 shadow-xl pointer-events-auto whitespace-nowrap\",\n // The board container is `overflow-hidden` (for its rounded\n // corners), so a popover that spills past an edge gets clipped.\n // Anchor it inside the board on edge columns / the top row.\n y === ROWS - 1 ? \"top-full mt-1\" : \"bottom-full mb-1\",\n x === 0\n ? \"left-0\"\n : x === COLS - 1\n ? \"right-0\"\n : \"left-1/2 -translate-x-1/2\",\n )}\n onClick={e => e.stopPropagation()}\n >\n <button\n className=\"flex items-center gap-1 px-2 py-1 rounded text-[11px] font-semibold font-inter text-move-highlight bg-move-highlight/10 hover:bg-move-highlight/20 transition-colors\"\n onClick={() => { movePiece(selectedPieceId, { x, y }); setDisambiguateAt(null) }}\n >\n <Move size={11} strokeWidth={2} />\n {t('move')}\n </button>\n <button\n className=\"flex items-center gap-1 px-2 py-1 rounded text-[11px] font-semibold font-inter text-pass-highlight bg-pass-highlight/10 hover:bg-pass-highlight/20 transition-colors\"\n onClick={() => { passBall({ x, y }); setDisambiguateAt(null) }}\n >\n <span className=\"w-3 h-3 inline-flex\"><Football /></span>\n {t('pass')}\n </button>\n </div>\n )}\n </div>\n )\n }\n rows.push(\n <div key={`row-${y}`} role=\"row\" className=\"contents\">\n {squares}\n </div>,\n )\n }\n return rows\n }\n\n const board = (\n <div\n data-testid=\"board-root\"\n className={cn(\n // §6: Mobile edge-to-edge — thin 2px margin, no border, no radius\n // The frame was hardcoded #1a3317 in three files, hand-tuned for\n // the webapp's darker grass and visibly wrong against the\n // CrazyGames pitch. It is a token now (see README).\n \"w-full mx-0.5 bg-field-frame overflow-hidden\",\n // §5+§6: Desktop — centered, rounded, bordered, height-based max-width\n \"md:mx-auto md:rounded-xl md:shadow-2xl md:border-4 md:border-field-frame\",\n \"md:max-w-[min(700px,calc((100dvh_-_150px)*0.75))]\",\n !showCoordinates && className,\n )}\n >\n {/* §12: desktop-only board toolbar — sits in its own row above the grid so\n nothing here ever overlaps a playable square. Left: persistent ball-holder\n chip. Right: keyboard-shortcuts legend, when the board is keyboard-operable.\n Apps with a side panel can opt out (toolbar={false}) and place both\n components themselves. */}\n {toolbar && (\n <div className=\"hidden md:flex items-center justify-between gap-2 px-2.5 py-1\" data-testid=\"board-toolbar\">\n <BallHolderChip />\n\n {keyboardNav && (\n <div\n ref={shortcutsRef}\n className=\"relative\"\n // The board's own key handler lives on the grid, which\n // is not an ancestor of this button — so Escape has to\n // be handled here or the popover can't be closed from\n // the keyboard at all.\n onKeyDown={e => {\n if (e.key === 'Escape' && shortcutsOpen) {\n e.stopPropagation()\n setShortcutsOpen(false)\n }\n }}\n >\n <button\n type=\"button\"\n onClick={(e) => { e.stopPropagation(); setShortcutsOpen(o => !o) }}\n aria-label={t('shortcuts.buttonLabel')}\n aria-expanded={shortcutsOpen}\n className=\"w-11 h-11 flex items-center justify-center rounded-full bg-bg-secondary/80 border border-border-subtle text-fg-muted hover:text-fg-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-green\"\n >\n <HelpCircle size={16} strokeWidth={2} aria-hidden=\"true\" />\n </button>\n {shortcutsOpen && (\n <div\n className=\"absolute top-full right-0 mt-1 z-50 w-max max-w-[220px] bg-bg-secondary border border-border-subtle rounded-md shadow-xl p-2.5 pointer-events-auto\"\n onClick={e => e.stopPropagation()}\n >\n <p className=\"font-inter text-[11px] font-semibold text-fg-primary mb-1.5\">{t('shortcuts.title')}</p>\n <KeyboardShortcutsList />\n </div>\n )}\n </div>\n )}\n </div>\n )}\n\n <div className=\"relative\" style={{ containerType: 'inline-size' }}>\n {/* `role=\"grid\"` sits on the grid element itself, not on the\n wrapper: the wrapper also holds the toolbar, and a button is\n not a valid child of a grid. It replaces the previous\n `role=\"application\"`, which suppressed the screen reader's\n reading mode without offering any structure in exchange. */}\n <div\n role=\"grid\"\n aria-label={t('boardAriaLabel')}\n aria-rowcount={ROWS}\n aria-colcount={COLS}\n className={cn(\n \"grid grid-cols-9 gap-[1px]\",\n keyboardNav && \"focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-accent-green\",\n )}\n {...(keyboardNav\n ? {\n tabIndex: 0,\n onKeyDown: handleKeyDown,\n 'aria-activedescendant': cursor ? cellId(cursor.x, cursor.y) : undefined,\n }\n : {})}\n >\n {renderRows()}\n </div>\n\n {/* Turf grain + stadium light: decorative, click-through. */}\n <GrassOverlay />\n\n {/* Chalk pitch lines — static, so the browser caches the filter as its own layer. */}\n <PitchMarkings />\n\n {/* Dynamic board-space overlays live in their own <svg> so hover\n repaints never re-run the chalk filter above. */}\n <svg\n viewBox=\"0 0 9 12\"\n preserveAspectRatio=\"none\"\n className=\"absolute inset-0 w-full h-full pointer-events-none\"\n aria-hidden=\"true\"\n >\n {hoveredPassAt && passCarrier && (\n <line\n data-testid=\"pass-trajectory-line\"\n x1={passCarrier.pos.x + 0.5}\n y1={ROWS - 1 - passCarrier.pos.y + 0.5}\n x2={hoveredPassAt.x + 0.5}\n y2={ROWS - 1 - hoveredPassAt.y + 0.5}\n stroke={trajectoryIntercepted ? 'var(--danger)' : 'var(--pass-highlight)'}\n strokeWidth=\"0.08\"\n strokeDasharray=\"0.15 0.1\"\n strokeLinecap=\"round\"\n />\n )}\n </svg>\n\n {/* Visual layer only: every piece is already announced by its\n grid cell, so exposing it twice would double the board. */}\n <div className=\"absolute inset-0 pointer-events-none\" data-testid=\"pieces-layer\" aria-hidden=\"true\">\n <AnimatePresence mode=\"sync\">\n {boardState.pieces.map(piece => {\n const isPickupCarrier = pickupCarrierId === piece.id\n const pieceTransition = isPickupCarrier\n ? { duration: PICKUP_DURATION, ease: 'linear' as const }\n : PIECE_SLIDE\n return (\n <motion.div\n key={piece.id}\n data-piece-id={piece.id}\n initial={false}\n animate={{ x: cellX(piece.pos.x), y: cellY(piece.pos.y) }}\n transition={pieceTransition}\n onAnimationStart={() => setMoving(piece.id, true)}\n onAnimationComplete={() => setMoving(piece.id, false)}\n style={{\n position: 'absolute',\n left: 0,\n top: 0,\n width: `${100 / COLS}%`,\n height: `${100 / ROWS}%`,\n willChange: 'transform',\n }}\n className=\"flex items-center justify-center pointer-events-auto\"\n >\n <GamePiece\n piece={piece}\n isSelected={selectedPieceId === piece.id}\n hasBall={boardState.ball.holderId === piece.id}\n isMoving={movingIds.has(piece.id)}\n onClick={(e: React.MouseEvent) => handlePieceClick(piece.id, piece.pos.x, piece.pos.y, e)}\n />\n </motion.div>\n )\n })}\n </AnimatePresence>\n\n {(() => {\n const targetX = cellX(ball.pos.x)\n const targetY = cellY(ball.pos.y)\n let animate: any\n let transition: any\n if (isPickupOnMove && prevBall) {\n const prevX = cellX(prevBall.pos.x)\n const prevY = cellY(prevBall.pos.y)\n const pulseStart = Math.max(0.05, pickupProportion - 0.06)\n animate = {\n x: [prevX, prevX, prevX, targetX],\n y: [prevY, prevY, prevY, targetY],\n scale: [1, 1, 1.35, 1],\n }\n transition = { duration: PICKUP_DURATION, times: [0, pulseStart, pickupProportion, 1], ease: 'linear' }\n } else {\n animate = { x: targetX, y: targetY, scale: 1 }\n transition = ball.holderId ? PIECE_SLIDE : BALL_SLIDE\n }\n return (\n <motion.div\n key=\"ball\"\n initial={false}\n animate={animate}\n transition={transition}\n style={{\n position: 'absolute',\n left: 0,\n top: 0,\n width: `${100 / COLS}%`,\n height: `${100 / ROWS}%`,\n zIndex: 50,\n willChange: 'transform',\n }}\n className=\"flex items-center justify-center pointer-events-none\"\n >\n <div className=\"w-[60%] h-[60%]\"><Football /></div>\n </motion.div>\n )\n })()}\n\n {/* §16: subtle shake feedback on an illegal move/pass target */}\n {invalidClickAt && (\n <motion.div\n key={invalidClickAt.nonce}\n data-testid=\"invalid-action-shake\"\n aria-hidden=\"true\"\n initial={false}\n animate={prefersReducedMotion ? { opacity: [0.9, 0] } : { x: [0, -3, 3, -3, 3, 0] }}\n transition={{ duration: 0.08 }}\n style={{\n position: 'absolute',\n left: `${(invalidClickAt.x / COLS) * 100}%`,\n top: `${((ROWS - 1 - invalidClickAt.y) / ROWS) * 100}%`,\n width: `${100 / COLS}%`,\n height: `${100 / ROWS}%`,\n }}\n className=\"ring-2 ring-inset ring-danger/70 rounded-sm\"\n />\n )}\n </div>\n\n {/* §8: Offside warning chip overlaid on board bottom */}\n {isOffsideRisk && (\n <div className=\"absolute bottom-2 left-1/2 -translate-x-1/2 z-30 flex items-center gap-1.5 px-3 py-1.5 bg-warning/20 border border-warning/50 rounded-full font-inter text-xs font-semibold text-warning pointer-events-none whitespace-nowrap backdrop-blur-sm\">\n ⚠ {t('offsideWarning')}\n </div>\n )}\n\n </div>\n </div>\n )\n\n if (!showCoordinates) return board\n\n const ranksTopToBottom = [...RANK_LABELS].reverse()\n return (\n <div className={cn('w-full max-w-[540px] md:max-w-none mx-auto', className)}>\n <div\n className=\"grid gap-1 select-none\"\n style={{\n gridTemplateColumns: '20px 1fr 20px',\n gridTemplateRows: '14px 1fr 14px',\n }}\n >\n <span aria-hidden=\"true\" />\n <FileRow files={FILE_LABELS} />\n <span aria-hidden=\"true\" />\n\n <RankColumn ranks={ranksTopToBottom} />\n <div>{board}</div>\n <RankColumn ranks={ranksTopToBottom} />\n\n <span aria-hidden=\"true\" />\n <FileRow files={FILE_LABELS} />\n <span aria-hidden=\"true\" />\n </div>\n </div>\n )\n}\n\nfunction FileRow({ files }: { files: readonly string[] }) {\n return (\n <div className=\"grid grid-cols-9 gap-[1px] px-[2px]\">\n {files.map(f => (\n <span key={f} aria-hidden=\"true\" className=\"flex items-center justify-center font-mono text-[9px] text-fg-muted/80 uppercase tracking-[0.5px]\">\n {f}\n </span>\n ))}\n </div>\n )\n}\n\nfunction RankColumn({ ranks }: { ranks: readonly number[] }) {\n return (\n <div className=\"grid grid-rows-12 gap-[1px] py-[2px]\">\n {ranks.map(r => (\n <span key={r} aria-hidden=\"true\" className=\"flex items-center justify-center font-mono text-[9px] text-fg-muted/80 tabular-nums\">\n {r}\n </span>\n ))}\n </div>\n )\n}\n","import { useEffect, useState, type ReactNode } from 'react'\nimport { cn } from '../../lib/utils'\n\ninterface AvatarProps { className?: string; children: ReactNode }\ninterface AvatarImageProps { src?: string; alt?: string; className?: string }\ninterface AvatarFallbackProps { className?: string; children: ReactNode }\n\nexport function Avatar({ className, children }: AvatarProps) {\n return <div className={cn('relative w-9 h-9 rounded-full overflow-hidden shrink-0', className)}>{children}</div>\n}\n\nexport function AvatarImage({ src, alt, className }: AvatarImageProps) {\n // Without onError a broken URL renders an empty box stacked over the initials\n // fallback, so the fallback never shows. Drop out and let it through.\n const [failed, setFailed] = useState(false)\n useEffect(() => { setFailed(false) }, [src])\n\n if (!src || failed) return null\n return (\n <img\n src={src}\n alt={alt ?? ''}\n onError={() => setFailed(true)}\n className={cn('w-full h-full object-cover', className)}\n />\n )\n}\n\nexport function AvatarFallback({ className, children }: AvatarFallbackProps) {\n return (\n <div className={cn('absolute inset-0 flex items-center justify-center text-xs font-semibold', className)}>\n {children}\n </div>\n )\n}\n","import { useEffect, useRef, useState } from 'react'\nimport { motion } from 'framer-motion'\nimport { Zap, Crown } from 'lucide-react'\nimport { cn } from '../lib/utils'\nimport { useGameT } from '../i18n'\n\ninterface ActionPointsProps {\n total: number\n remaining: number\n size?: number\n className?: string\n kingMustRelease?: boolean\n}\n\nexport function ActionPoints({ total, remaining, size = 20, className, kingMustRelease }: ActionPointsProps) {\n const t = useGameT()\n\n // §16: brief \"spent\" pop on every pip that just went from active to inactive\n // (a forced turn end — interception, goal — can drop AP straight to 0, not\n // just by one). Cleared immediately if `remaining` rises again before the\n // pop finishes (an AP rollback), not left dangling for the old timeout.\n const prevRemainingRef = useRef(remaining)\n const [spentRange, setSpentRange] = useState<[number, number] | null>(null)\n useEffect(() => {\n const prev = prevRemainingRef.current\n prevRemainingRef.current = remaining\n if (remaining < prev) {\n setSpentRange([remaining, prev - 1])\n const id = setTimeout(() => setSpentRange(null), 300)\n return () => clearTimeout(id)\n }\n setSpentRange(null)\n }, [remaining])\n\n return (\n <div className={cn('flex items-center gap-1.5', className)} aria-label={t('actionPointsAriaLabel', { remaining, total })}>\n {Array.from({ length: total }).map((_, i) => {\n const isActive = i < remaining\n const showCrown = kingMustRelease && i === total - 1\n const justSpent = !!spentRange && i >= spentRange[0] && i <= spentRange[1]\n\n return (\n <motion.span\n key={i}\n data-testid={`ap-pip-${i}`}\n data-spent={justSpent || undefined}\n className=\"inline-flex\"\n animate={justSpent ? { scale: [1.5, 1] } : undefined}\n transition={{ duration: 0.3 }}\n >\n {showCrown ? (\n <Crown\n size={size}\n strokeWidth={2}\n className=\"text-yellow-400 fill-yellow-400 transition-colors duration-150\"\n aria-hidden=\"true\"\n />\n ) : (\n <Zap\n size={size}\n strokeWidth={2}\n className={cn(\n 'transition-colors duration-150',\n isActive ? 'text-accent-green fill-accent-green' : 'text-fg-muted fill-none',\n )}\n aria-hidden=\"true\"\n />\n )}\n </motion.span>\n )\n })}\n </div>\n )\n}\n","import { cn } from '../../lib/utils'\n\ninterface PlayerIdentityProps {\n name: string\n team: string\n /**\n * `full` — the side panels and the mobile scoreboard: name on its own line,\n * team beneath it. `compact` — the tablet/desktop mini-scoreboard, where the\n * pair shares one line.\n */\n variant?: 'full' | 'compact'\n isActive?: boolean\n align?: 'left' | 'right'\n /** Rendered inline after the team label (e.g. the active-turn pulse dot). */\n adornment?: React.ReactNode\n className?: string\n}\n\n/**\n * One player's name and team.\n *\n * `Scoreboard` set this in Inter 13px semibold with the team in mono 10px, and\n * `MiniScoreboard` in mono 10px uppercase joined by a middot — so the same\n * player changed appearance on a viewport change. Both now render this, and the\n * only difference left is the deliberate one: how much room there is.\n */\nexport function PlayerIdentity({\n name,\n team,\n variant = 'full',\n isActive = false,\n align = 'left',\n adornment,\n className,\n}: PlayerIdentityProps) {\n if (variant === 'compact') {\n return (\n <span\n className={cn(\n 'font-inter text-[11px] font-medium truncate max-w-[160px]',\n isActive ? 'text-fg-secondary' : 'text-fg-muted',\n className,\n )}\n >\n {name}\n <span className=\"font-mono uppercase tracking-[0.5px] text-fg-muted\"> · {team}</span>\n </span>\n )\n }\n\n return (\n <div className={cn('flex flex-col gap-1 min-w-0', align === 'right' && 'items-end', className)}>\n <span\n className={cn(\n 'font-inter text-[13px] font-semibold leading-none truncate transition-colors duration-300',\n isActive ? 'text-fg-primary' : 'text-fg-muted',\n )}\n >\n {name}\n </span>\n <div className={cn('flex items-center gap-1', align === 'right' && 'flex-row-reverse')}>\n <span className=\"font-mono text-[10px] text-fg-muted uppercase tracking-[0.5px]\">{team}</span>\n {adornment}\n </div>\n </div>\n )\n}\n","import { useGameStore, DEFAULT_MAX_AP } from '../../store/use-game-store'\nimport { cn } from '../../lib/utils'\nimport { Avatar, AvatarFallback, AvatarImage } from '../ui/avatar'\nimport { ActionPoints } from '../action-points'\nimport { useGameT } from '../../i18n'\nimport { PlayerIdentity } from './player-identity'\n\ninterface ScoreboardProps {\n creatorUsername: string\n opponentUsername: string\n creatorAvatarUrl?: string\n opponentAvatarUrl?: string\n userSide?: 'white' | 'black' | null\n className?: string\n}\n\nfunction initials(name: string) {\n return (name?.split(' ').map(w => w[0]).join('').toUpperCase() || '?').slice(0, 2)\n}\n\nexport default function Scoreboard({\n creatorUsername,\n opponentUsername,\n creatorAvatarUrl,\n opponentAvatarUrl,\n userSide,\n className,\n}: ScoreboardProps) {\n const t = useGameT()\n const boardState = useGameStore(s => s.boardState)\n if (!boardState?.score) return null\n\n const { score, turn, actionPoints, kingMustRelease } = boardState\n\n // El creador siempre juega con blancas\n const myScore = userSide === 'white' ? score.white : score.black\n const rivalScore = userSide === 'white' ? score.black : score.white\n const myName = userSide === 'white' ? creatorUsername : opponentUsername\n const rivalName = userSide === 'white' ? opponentUsername : creatorUsername\n const myAvatar = userSide === 'white' ? creatorAvatarUrl : opponentAvatarUrl\n const rivalAvatar= userSide === 'white' ? opponentAvatarUrl : creatorAvatarUrl\n const myTeam = userSide === 'white' ? t('teamWhite') : t('teamBlack')\n const rivalTeam = userSide === 'white' ? t('teamBlack') : t('teamWhite')\n const isMyTurn = turn === userSide\n const myKingMustRelease = isMyTurn && kingMustRelease === turn\n const rivalKingMustRelease = !isMyTurn && kingMustRelease === turn\n\n const maxAP = boardState.maxActionPoints ?? DEFAULT_MAX_AP\n\n return (\n <div className={cn('w-full bg-bg-secondary flex items-center justify-between px-5 py-2.5', className)}>\n {/* Jugador local */}\n <PlayerInfo\n name={myName}\n team={myTeam}\n avatarUrl={myAvatar}\n isActive={isMyTurn}\n actionPoints={isMyTurn ? actionPoints : 0}\n maxActionPoints={maxAP}\n kingMustRelease={myKingMustRelease}\n align=\"left\"\n />\n\n {/* Marcador central. La región live lleva el texto en un `sr-only` en vez\n de un `aria-label`: un `aria-label` sobre una región live silencia su\n contenido y el lector nunca llegaría a anunciar el gol. */}\n <div role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" className=\"flex items-center gap-3\">\n <span aria-hidden=\"true\" className=\"font-anton text-[32px] leading-none text-fg-primary tabular-nums\">\n {myScore}\n </span>\n <span aria-hidden=\"true\" className=\"font-anton text-2xl text-fg-muted\">—</span>\n <span aria-hidden=\"true\" className=\"font-anton text-[32px] leading-none text-fg-primary tabular-nums\">\n {rivalScore}\n </span>\n <span className=\"sr-only\">\n {t('scoreAriaLabel', { me: myName, myScore, rival: rivalName, rivalScore })}\n </span>\n </div>\n\n {/* Rival */}\n <PlayerInfo\n name={rivalName}\n team={rivalTeam}\n avatarUrl={rivalAvatar}\n isActive={!isMyTurn}\n actionPoints={!isMyTurn ? actionPoints : 0}\n maxActionPoints={maxAP}\n kingMustRelease={rivalKingMustRelease}\n align=\"right\"\n />\n </div>\n )\n}\n\ninterface PlayerInfoProps {\n name: string\n team: string\n avatarUrl?: string\n isActive: boolean\n actionPoints: number\n maxActionPoints: number\n kingMustRelease: boolean\n align: 'left' | 'right'\n}\n\nfunction PlayerInfo({ name, team, avatarUrl, isActive, actionPoints, maxActionPoints, kingMustRelease, align }: PlayerInfoProps) {\n return (\n <div className={cn('flex items-center gap-2.5', align === 'right' && 'flex-row-reverse')}>\n <Avatar className={cn(\n 'w-9 h-9 border-2 transition-colors duration-300',\n isActive ? 'border-accent-green' : 'border-border-subtle'\n )}>\n <AvatarImage src={avatarUrl} alt={name} className=\"object-cover\" />\n <AvatarFallback className=\"bg-bg-surface-elevated text-fg-secondary text-xs font-semibold\">\n {initials(name)}\n </AvatarFallback>\n </Avatar>\n\n <div className={cn('flex flex-col gap-1', align === 'right' && 'items-end')}>\n <PlayerIdentity\n name={name}\n team={team}\n isActive={isActive}\n align={align}\n adornment={isActive ? (\n <span className=\"w-1.5 h-1.5 rounded-full bg-accent-green animate-pulse motion-reduce:animate-none\" aria-hidden=\"true\" />\n ) : undefined}\n />\n <ActionPoints\n total={maxActionPoints}\n remaining={actionPoints}\n size={12}\n kingMustRelease={kingMustRelease}\n className=\"gap-0.5\"\n />\n </div>\n </div>\n )\n}\n","import { useGameStore } from '../../store/use-game-store'\nimport { cn } from '../../lib/utils'\nimport { useGameT } from '../../i18n'\nimport { PlayerIdentity } from './player-identity'\n\ninterface MiniScoreboardProps {\n creatorUsername: string\n opponentUsername: string\n userSide?: 'white' | 'black' | null\n className?: string\n}\n\n/**\n * Compact scoreboard shown above the board on tablet/desktop. Renders only the\n * grouped name + score per side — no avatars, since the side panels already show them.\n */\nexport function MiniScoreboard({\n creatorUsername,\n opponentUsername,\n userSide,\n className,\n}: MiniScoreboardProps) {\n const t = useGameT()\n const boardState = useGameStore(s => s.boardState)\n if (!boardState?.score) return null\n\n const { score, turn } = boardState\n\n const myScore = userSide === 'white' ? score.white : score.black\n const rivalScore = userSide === 'white' ? score.black : score.white\n const myName = userSide === 'white' ? creatorUsername : opponentUsername\n const rivalName = userSide === 'white' ? opponentUsername : creatorUsername\n const myTeam = userSide === 'white' ? t('teamWhite') : t('teamBlack')\n const rivalTeam = userSide === 'white' ? t('teamBlack') : t('teamWhite')\n const isMyTurn = turn === userSide\n\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n className={cn(\n 'w-full max-w-[540px] rounded-xl bg-bg-surface border border-border-subtle',\n 'flex items-center justify-between gap-4 px-5 py-3',\n className,\n )}\n >\n {/* El bloque visual se oculta al lector y se sustituye por una única\n frase con nombres y marcador: leído celda a celda, \"2\" \"vs\" \"1\"\n no dice de quién es cada cifra. */}\n <div className=\"contents\" aria-hidden=\"true\">\n <SideCell name={myName} team={myTeam} score={myScore} isActive={isMyTurn} align=\"left\" />\n\n <span className=\"font-anton text-base text-fg-muted uppercase tracking-[2px]\">\n vs\n </span>\n\n <SideCell name={rivalName} team={rivalTeam} score={rivalScore} isActive={!isMyTurn} align=\"right\" />\n </div>\n\n <span className=\"sr-only\">\n {t('scoreAriaLabel', { me: myName, myScore, rival: rivalName, rivalScore })}\n </span>\n </div>\n )\n}\n\ninterface SideCellProps {\n name: string\n team: string\n score: number\n isActive: boolean\n align: 'left' | 'right'\n}\n\nfunction SideCell({ name, team, score, isActive, align }: SideCellProps) {\n return (\n <div className={cn('flex flex-col min-w-0', align === 'right' ? 'items-end' : 'items-start')}>\n <PlayerIdentity name={name} team={team} variant=\"compact\" isActive={isActive} />\n <span className={cn(\n 'font-anton text-[32px] leading-none tabular-nums',\n isActive ? 'text-fg-primary' : 'text-fg-secondary',\n )}>\n {score}\n </span>\n </div>\n )\n}\n","import * as React from 'react'\nimport { cn } from '../../lib/utils'\n\ntype Variant = 'primary' | 'secondary' | 'ghost' | 'destructive'\ntype Size = 'default' | 'sm' | 'lg' | 'icon'\n\nconst VARIANT: Record<Variant, string> = {\n // White on `--accent-green` is 4.27:1 — under WCAG AA for the Anton 400 the\n // primary CTA is set in. `--accent-green-dark` clears it (~6.5:1), so the\n // resting state is the dark green and interaction brightens it rather than\n // darkening it. Hover/active are transient; the resting state is the one a\n // player reads.\n primary:\n 'bg-accent-green-dark text-fg-primary font-anton tracking-widest rounded-md ' +\n 'hover:bg-accent-green active:bg-accent-green-light',\n secondary:\n 'bg-bg-surface text-fg-primary font-inter font-semibold rounded-md ' +\n 'border border-border-subtle hover:bg-bg-surface-elevated active:bg-bg-secondary',\n ghost:\n 'bg-transparent text-fg-secondary font-inter font-medium rounded-md ' +\n 'hover:text-fg-primary active:text-fg-muted',\n destructive:\n 'bg-danger/10 text-danger font-inter font-semibold rounded-md ' +\n 'border border-danger hover:bg-danger/20 active:bg-danger/30',\n}\n\nconst SIZE: Record<Size, string> = {\n default: 'h-12 min-h-[44px] px-6 text-base',\n sm: 'h-9 min-h-[36px] px-4 text-sm',\n lg: 'h-13 min-h-[52px] px-8 text-lg',\n icon: 'h-11 w-11 min-h-[44px]',\n}\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: Variant\n size?: Size\n}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant = 'primary', size = 'default', ...props }, ref) => (\n <button\n ref={ref}\n className={cn(\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap transition-all duration-150',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-green focus-visible:ring-offset-2 focus-visible:ring-offset-bg-primary',\n 'disabled:pointer-events-none disabled:opacity-40',\n '[&_svg]:pointer-events-none [&_svg]:shrink-0',\n VARIANT[variant],\n SIZE[size],\n className,\n )}\n {...props}\n />\n ),\n)\nButton.displayName = 'Button'\n","import { useEffect, useRef } from 'react'\n\n/**\n * Selector for the elements a modal's Tab cycle may land on. `[tabindex=\"-1\"]`\n * is deliberately excluded: programmatically focusable nodes (like the panel\n * itself) must not become Tab stops.\n */\nconst FOCUSABLE = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(',')\n\n/**\n * Deliberately not an `offsetParent` check: that is `null` for anything inside a\n * `position: fixed` subtree (which every one of these dialogs is) and always\n * `null` under jsdom. Attribute-level hiding is what actually matters here.\n */\nfunction focusableWithin(panel: HTMLElement): HTMLElement[] {\n return Array.from(panel.querySelectorAll<HTMLElement>(FOCUSABLE)).filter(\n el => !el.closest('[hidden]') && !el.closest('[aria-hidden=\"true\"]'),\n )\n}\n\ninterface DialogA11yOptions {\n open: boolean\n onClose: () => void\n}\n\n/**\n * The four behaviours `aria-modal=\"true\"` promises but does not implement.\n * Declaring `aria-modal` without them is worse than not declaring it at all:\n * assistive tech stops exposing the page behind the dialog while the keyboard\n * happily walks straight into it.\n *\n * 1. Initial focus — the first focusable control, or the panel itself.\n * 2. Focus trap — Tab / Shift+Tab cycle inside the panel.\n * 3. Escape closes.\n * 4. Focus returns to whatever opened the dialog.\n *\n * Attach the returned ref to the dialog panel (the node carrying `role=\"dialog\"`).\n */\nexport function useDialogA11y({ open, onClose }: DialogA11yOptions) {\n const panelRef = useRef<HTMLDivElement | null>(null)\n const restoreToRef = useRef<HTMLElement | null>(null)\n\n // `onClose` is nearly always an inline arrow: keep it in a ref so the\n // key listener isn't torn down and re-attached on every parent render.\n const onCloseRef = useRef(onClose)\n useEffect(() => { onCloseRef.current = onClose })\n\n useEffect(() => {\n if (!open) return\n const panel = panelRef.current\n if (!panel) return\n\n restoreToRef.current = document.activeElement as HTMLElement | null\n\n const initial = focusableWithin(panel)[0]\n if (initial) {\n initial.focus()\n } else {\n panel.tabIndex = -1\n panel.focus()\n }\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.stopPropagation()\n onCloseRef.current()\n return\n }\n if (e.key !== 'Tab') return\n\n const items = focusableWithin(panel)\n if (items.length === 0) {\n e.preventDefault()\n return\n }\n const first = items[0]\n const last = items[items.length - 1]\n const active = document.activeElement\n\n if (e.shiftKey && (active === first || !panel.contains(active))) {\n e.preventDefault()\n last.focus()\n } else if (!e.shiftKey && (active === last || !panel.contains(active))) {\n e.preventDefault()\n first.focus()\n }\n }\n\n document.addEventListener('keydown', onKeyDown, true)\n return () => {\n document.removeEventListener('keydown', onKeyDown, true)\n restoreToRef.current?.focus?.()\n }\n }, [open])\n\n return panelRef\n}\n","import { useId } from 'react'\nimport { cn } from '../../lib/utils'\nimport { useDialogA11y } from '../../lib/use-dialog-a11y'\nimport { Button } from './button'\n\ninterface ConfirmDialogProps {\n open: boolean\n title: string\n description?: string\n confirmLabel: string\n cancelLabel: string\n onConfirm: () => void\n onCancel: () => void\n}\n\nexport function ConfirmDialog({ open, title, description, confirmLabel, cancelLabel, onConfirm, onCancel }: ConfirmDialogProps) {\n const baseId = useId()\n const titleId = `${baseId}-title`\n const descId = `${baseId}-desc`\n // Escape and the backdrop resolve to the same outcome as the cancel button:\n // the dialog is a question, and dismissing it is answering \"no\".\n const panelRef = useDialogA11y({ open, onClose: onCancel })\n\n if (!open) return null\n return (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm\"\n onClick={onCancel}\n >\n <div\n ref={panelRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n aria-describedby={description ? descId : undefined}\n onClick={e => e.stopPropagation()}\n className={cn(\n 'bg-bg-surface border border-border-subtle rounded-xl p-6 mx-4 max-w-sm w-full',\n 'flex flex-col gap-4 shadow-2xl',\n 'focus:outline-none',\n )}\n >\n <h2 id={titleId} className=\"font-anton text-lg text-fg-primary uppercase tracking-wide\">{title}</h2>\n {description && <p id={descId} className=\"font-inter text-sm text-fg-secondary\">{description}</p>}\n <div className=\"flex gap-2 pt-1\">\n <Button variant=\"secondary\" className=\"flex-1\" onClick={onCancel}>{cancelLabel}</Button>\n <Button variant=\"primary\" className=\"flex-1\" onClick={onConfirm}>{confirmLabel}</Button>\n </div>\n </div>\n </div>\n )\n}\n","import { useState } from 'react'\nimport { useGameStore } from '../../store/use-game-store'\nimport { Button } from '../ui/button'\nimport { ConfirmDialog } from '../ui/confirm-dialog'\nimport { Flag } from 'lucide-react'\nimport { cn } from '../../lib/utils'\nimport { useGameT } from '../../i18n'\n\ninterface GameControlsProps {\n isMyTurn: boolean\n className?: string\n}\n\nexport default function GameControls({ isMyTurn, className }: GameControlsProps) {\n const boardState = useGameStore(s => s.boardState)\n const endTurn = useGameStore(s => s.endTurn)\n\n const t = useGameT()\n const [showEndTurnConfirm, setShowEndTurnConfirm] = useState(false)\n\n if (!boardState) return null\n\n const actionPoints = boardState.actionPoints\n\n // Only ask for confirmation when ≥2 AP remain — with 0–1 AP left it's obvious\n const handleEndTurn = () => {\n if (actionPoints >= 2) {\n setShowEndTurnConfirm(true)\n } else {\n endTurn()\n }\n }\n\n return (\n <div className={cn('w-full bg-bg-secondary flex flex-col gap-3 px-5 pt-3 pb-5', className)}>\n {/* Finalizar turno */}\n {isMyTurn && (\n <Button\n variant=\"primary\"\n size=\"default\"\n className=\"w-full gap-2 tracking-[1.5px]\"\n onClick={handleEndTurn}\n >\n <Flag size={16} strokeWidth={2} />\n {t('endTurn')}\n {actionPoints >= 2 && (\n <span className={cn('ml-1 font-inter text-xs font-normal opacity-70 tracking-normal')}>\n · {actionPoints} {t('actionPointsShort')}\n </span>\n )}\n </Button>\n )}\n\n {/* Turno del rival */}\n {!isMyTurn && (\n <div\n role=\"status\"\n aria-live=\"polite\"\n className=\"flex items-center justify-center h-11 rounded-md bg-bg-surface border border-border-subtle\"\n >\n <span className=\"font-inter text-sm text-fg-muted\">{t('waitingRival')}</span>\n </div>\n )}\n\n <ConfirmDialog\n open={showEndTurnConfirm}\n title={t('endTurnConfirm')}\n description={t('endTurnConfirmDescription', { count: actionPoints })}\n confirmLabel={t('endTurnConfirmYes')}\n cancelLabel={t('endTurnKeepPlaying')}\n onConfirm={() => { endTurn(); setShowEndTurnConfirm(false) }}\n onCancel={() => setShowEndTurnConfirm(false)}\n />\n </div>\n )\n}\n","import {\n ChessKing,\n ChessQueen,\n ChessRook,\n ChessBishop,\n ChessKnight,\n ShieldQuestion,\n type LucideIcon,\n} from 'lucide-react'\nimport { useGameStore } from '../../store/use-game-store'\nimport { useShallow } from 'zustand/react/shallow'\nimport { Football } from './football'\nimport { cn } from '../../lib/utils'\nimport { LONG_KEY, squareName } from '@scriptonita/chess-football-engine'\nimport type { Piece, PieceType } from '@scriptonita/chess-football-engine'\nimport { useGameT } from '../../i18n'\n\nconst PIECE_ICON: Record<PieceType, LucideIcon> = {\n king: ChessKing,\n queen: ChessQueen,\n rook: ChessRook,\n bishop: ChessBishop,\n knight: ChessKnight,\n}\n\ninterface SelectedPieceDetailProps {\n isMyTurn: boolean\n className?: string\n}\n\n/**\n * Compact card that surfaces the selected piece's identity, position and current state.\n * Renders below the board on tablet/desktop to put the empty space to use.\n */\nexport function SelectedPieceDetail({ isMyTurn, className }: SelectedPieceDetailProps) {\n const t = useGameT()\n const { boardState, selectedPieceId } = useGameStore(\n useShallow(s => ({ boardState: s.boardState, selectedPieceId: s.selectedPieceId })),\n )\n\n if (!boardState) return null\n\n const piece: Piece | undefined = boardState.pieces.find(p => p.id === selectedPieceId)\n\n if (!piece) {\n return (\n <div\n className={cn(\n 'rounded-xl bg-bg-surface/40 border border-dashed border-border-subtle',\n 'px-4 py-3 flex items-center gap-3',\n className,\n )}\n >\n <ShieldQuestion size={20} className=\"text-fg-muted shrink-0\" aria-hidden=\"true\" />\n <span className=\"font-mono text-[11px] text-fg-muted\">\n {t('selectedPiece.empty')}\n </span>\n </div>\n )\n }\n\n const Icon = PIECE_ICON[piece.type] ?? ShieldQuestion\n const longName = t(`pieces.${LONG_KEY[piece.type]}`)\n const square = squareName(piece.pos)\n const hasBall = boardState.ball.holderId === piece.id\n const movedThisTurn = piece.hasMovedThisTurn && isMyTurn\n\n return (\n <div\n className={cn(\n 'rounded-xl bg-bg-surface border border-border-subtle',\n 'px-4 py-3 flex items-center gap-4',\n className,\n )}\n role=\"status\"\n aria-live=\"polite\"\n >\n <div\n className={cn(\n 'w-12 h-12 shrink-0 rounded-full flex items-center justify-center',\n piece.side === 'white' ? 'bg-white text-black' : 'bg-fg-primary/90 text-bg-primary',\n )}\n >\n <Icon size={26} strokeWidth={1.75} aria-hidden=\"true\" />\n </div>\n\n <div className=\"flex flex-col min-w-0 flex-1\">\n <span className=\"font-anton text-base text-fg-primary leading-none uppercase tracking-[0.5px]\">\n {longName}\n </span>\n <span className=\"font-mono text-[11px] text-fg-muted mt-1\">\n {t('selectedPiece.atSquare', { square })}\n </span>\n </div>\n\n <div className=\"flex flex-col items-end gap-1 shrink-0\">\n {hasBall && (\n <span className=\"flex items-center gap-1.5 font-mono text-[10px] text-pass-highlight uppercase tracking-[0.5px]\">\n <span className=\"w-3 h-3 inline-flex\">\n <Football />\n </span>\n {t('selectedPiece.hasBall')}\n </span>\n )}\n {movedThisTurn && (\n <span className=\"font-mono text-[10px] text-fg-muted uppercase tracking-[0.5px]\">\n {t('selectedPiece.alreadyMoved')}\n </span>\n )}\n </div>\n </div>\n )\n}\n","import { useEffect, useRef } from 'react'\nimport { useGameStore } from '../../store/use-game-store'\nimport { cn } from '../../lib/utils'\nimport { squareName, SHORT_KEY } from '@scriptonita/chess-football-engine'\nimport type { MoveHistoryEntry } from '@scriptonita/chess-football-engine'\nimport { useGameT } from '../../i18n'\n\ninterface MoveHistoryProps {\n /** When false, renders without the inner scroll wrapper (handy in tablet panels). */\n scrollable?: boolean\n /** Cap the number of entries displayed; useful in compact tablet panels. */\n limit?: number\n className?: string\n}\n\n/**\n * Move history list — chess-style notation grouped by turn.\n * Reads `boardState.moveHistory` and auto-scrolls to the latest entry.\n */\nexport function MoveHistory({ scrollable = true, limit, className }: MoveHistoryProps) {\n const t = useGameT()\n const boardState = useGameStore(s => s.boardState)\n const scrollRef = useRef<HTMLOListElement>(null)\n\n const history: MoveHistoryEntry[] = boardState?.moveHistory ?? []\n const visible = limit ? history.slice(-limit) : history\n // Latest at top of the list — easier to scan in narrow panels\n const ordered = [...visible].reverse()\n\n useEffect(() => {\n if (!scrollable) return\n if (scrollRef.current) scrollRef.current.scrollTop = 0\n }, [history.length, scrollable])\n\n if (ordered.length === 0) {\n return (\n <p\n className={cn(\n 'font-mono text-[11px] text-fg-muted text-center py-3 px-3',\n 'bg-bg-surface/40 rounded-md',\n className,\n )}\n >\n {t('history.empty')}\n </p>\n )\n }\n\n return (\n <ol\n ref={scrollRef}\n aria-label={t('history.title')}\n className={cn(\n 'flex flex-col gap-1',\n scrollable && 'h-full overflow-y-auto pr-1',\n className,\n )}\n >\n {ordered.map((entry, i) => {\n const isLatest = i === 0\n const prev = ordered[i - 1]\n const showTurnDivider = !prev || prev.turnNumber !== entry.turnNumber\n return (\n <li key={`${entry.at}-${i}`} className=\"flex flex-col gap-1\">\n {showTurnDivider && (\n <div\n className=\"flex items-center gap-2 pt-1\"\n aria-hidden={prev ? 'true' : undefined}\n >\n <span className=\"font-mono text-[9px] tracking-[1px] text-fg-muted uppercase\">\n {t('history.turn', { n: entry.turnNumber })}\n </span>\n <span className=\"flex-1 h-px bg-border-subtle/60\" />\n </div>\n )}\n <HistoryRow entry={entry} isLatest={isLatest} />\n </li>\n )\n })}\n </ol>\n )\n}\n\ninterface HistoryRowProps {\n entry: MoveHistoryEntry\n isLatest: boolean\n}\n\nfunction HistoryRow({ entry, isLatest }: HistoryRowProps) {\n const t = useGameT()\n const fromSq = entry.from ? squareName(entry.from) : '—'\n const toSq = squareName(entry.to)\n const pieceShort = t(`pieces.${SHORT_KEY[entry.pieceType]}`)\n\n let label: string\n switch (entry.type) {\n case 'pass':\n label = t('history.pass', { to: toSq })\n break\n case 'tackle':\n label = t('history.tackle', { to: toSq })\n break\n case 'interception':\n label = t('history.interception', { to: toSq })\n break\n case 'goal':\n label = t('history.goal', { from: fromSq, to: toSq })\n break\n case 'offside':\n label = t('history.offside', { from: fromSq })\n break\n case 'move':\n default:\n label = t('history.move', { piece: pieceShort, from: fromSq, to: toSq })\n }\n\n const dotColor =\n entry.type === 'goal' ? 'bg-accent-green' :\n entry.type === 'pass' ? 'bg-pass-highlight' :\n entry.type === 'interception' ? 'bg-danger' :\n entry.type === 'tackle' ? 'bg-danger/80' :\n entry.type === 'offside' ? 'bg-warning' :\n 'bg-move-highlight'\n\n return (\n <div\n className={cn(\n 'flex items-center gap-2.5 min-h-[32px] px-3 py-1.5 rounded-md',\n 'font-mono text-[11px] leading-tight',\n isLatest\n ? 'bg-bg-surface-elevated text-fg-primary'\n : 'bg-bg-surface/60 text-fg-secondary',\n entry.pieceSide === 'black' && 'border-l-2 border-l-fg-primary/30',\n entry.pieceSide === 'white' && 'border-l-2 border-l-fg-primary/80',\n )}\n >\n <span\n aria-hidden=\"true\"\n className={cn('w-1.5 h-1.5 rounded-full shrink-0', dotColor)}\n />\n <span className=\"truncate flex-1\">{label}</span>\n {entry.type === 'goal' && (\n <span className=\"font-anton text-[10px] tracking-[1px] uppercase text-accent-green\">\n GOL\n </span>\n )}\n </div>\n )\n}\n","import { cn } from '../../lib/utils'\nimport { useMemo } from 'react'\nimport { getInitialBoardState } from '../../store/use-game-store'\nimport { Football } from './football'\nimport GamePiece from './game-piece'\nimport { PitchSurface } from './pitch'\n\nconst COLS = 9\nconst ROWS = 12\n\nexport function StaticGameBoard({ className }: { className?: string } = {}) {\n const boardState = useMemo(() => getInitialBoardState('white'), [])\n\n return (\n <div className={cn('relative w-full overflow-hidden rounded-xl shadow-2xl border-4 border-field-frame bg-field-frame', className)}>\n <PitchSurface>\n <div className=\"absolute inset-0 pointer-events-none\">\n {boardState.pieces.map(piece => (\n <div\n key={piece.id}\n style={{\n position: 'absolute',\n left: `${(piece.pos.x / COLS) * 100}%`,\n top: `${((ROWS - 1 - piece.pos.y) / ROWS) * 100}%`,\n width: `${100 / COLS}%`,\n height: `${100 / ROWS}%`,\n }}\n className=\"flex items-center justify-center\"\n >\n <GamePiece\n piece={piece}\n isSelected={false}\n hasBall={boardState.ball.holderId === piece.id}\n onClick={() => { }}\n />\n </div>\n ))}\n </div>\n </PitchSurface>\n\n {/* Ball rendered OUTSIDE the containerType wrapper to escape its stacking context */}\n <div\n style={{\n position: 'absolute',\n left: `${(boardState.ball.pos.x / COLS) * 100}%`,\n top: `${((ROWS - 1 - boardState.ball.pos.y) / ROWS) * 100}%`,\n width: `${100 / COLS}%`,\n height: `${100 / ROWS}%`,\n zIndex: 50,\n }}\n className=\"flex items-center justify-center pointer-events-none\"\n >\n <div className=\"w-[60%] h-[60%]\">\n <Football />\n </div>\n </div>\n </div>\n )\n}\n","import { useGameStore, DEFAULT_MAX_AP } from '../../store/use-game-store'\nimport { cn } from '../../lib/utils'\nimport { useGameT } from '../../i18n'\nimport { Zap } from 'lucide-react'\n\ninterface TurnBannerProps {\n isMyTurn: boolean\n /** Override for the \"not my turn\" label (e.g. \"Bot pensando…\" in training mode). */\n waitingLabel?: string\n className?: string\n}\n\n/**\n * Full-width banner showing whose turn it is.\n * - My turn: accent-green background + \"TU TURNO\" + AP counter\n * - Opponent: neutral background + waiting label\n *\n * Absorbs the floating \"Bot pensando…\" toast in training mode when waitingLabel is set.\n */\nexport function TurnBanner({ isMyTurn, waitingLabel, className }: TurnBannerProps) {\n const t = useGameT()\n const boardState = useGameStore(s => s.boardState)\n if (!boardState) return null\n\n const { actionPoints, turnNumber } = boardState\n const maxActionPoints = boardState.maxActionPoints ?? DEFAULT_MAX_AP\n\n return (\n <div\n className={cn(\n 'w-full h-9 flex items-center justify-between px-4 shrink-0 transition-colors duration-300',\n isMyTurn\n ? 'bg-accent-green/15 border-b border-accent-green/30'\n : 'bg-bg-surface border-b border-border-subtle',\n className,\n )}\n aria-live=\"polite\"\n aria-atomic=\"true\"\n >\n <div className=\"flex items-baseline gap-2 min-w-0\">\n <span\n className={cn(\n 'font-anton text-sm tracking-[1.5px] uppercase truncate',\n isMyTurn ? 'text-accent-green' : 'text-fg-muted',\n )}\n >\n {isMyTurn ? t('yourTurn') : (waitingLabel ?? t('waitingRival'))}\n </span>\n {/* In a correspondence game \"you are on turn 14\" is first-order\n information. The engine exposes it and nothing rendered it. */}\n {typeof turnNumber === 'number' && (\n <span className=\"font-mono text-[10px] text-fg-muted uppercase tracking-[0.5px] shrink-0\">\n {t('history.turn', { n: turnNumber })}\n </span>\n )}\n </div>\n\n {isMyTurn && (\n <div className=\"flex items-center gap-1\" aria-label={t('actionPointsAriaLabel', { remaining: actionPoints, total: maxActionPoints })}>\n <Zap size={12} className=\"text-accent-green\" aria-hidden=\"true\" />\n <span className=\"font-mono text-xs text-fg-secondary tabular-nums\">\n {actionPoints}/{maxActionPoints}\n </span>\n </div>\n )}\n </div>\n )\n}\n","import { useEffect, useState } from 'react'\nimport { useGameStore } from '../../store/use-game-store'\nimport { cn } from '../../lib/utils'\nimport { AnimatePresence, motion } from 'framer-motion'\nimport { useGameT } from '../../i18n'\n\ninterface EventToastProps {\n className?: string\n}\n\ntype ToastEvent = 'goal' | 'interception' | 'offside' | 'tackle'\n\nconst TOASTABLE: ReadonlySet<string> = new Set<ToastEvent>(['goal', 'interception', 'offside', 'tackle'])\n\nconst TOAST_CONFIG: Record<ToastEvent, string> = {\n goal: 'bg-accent-green/20 border-accent-green/60 text-accent-green-light',\n interception: 'bg-danger/20 border-danger/50 text-danger',\n offside: 'bg-warning/20 border-warning/50 text-warning',\n tackle: 'bg-warning/20 border-warning/50 text-warning',\n}\n\nexport function EventToast({ className }: EventToastProps) {\n const t = useGameT()\n const boardState = useGameStore(s => s.boardState)\n const [toast, setToast] = useState<{ type: ToastEvent; key: string } | null>(null)\n\n useEffect(() => {\n const lastMove = boardState?.lastMove\n if (!lastMove) return\n if (!TOASTABLE.has(lastMove.type)) return\n setToast({ type: lastMove.type as ToastEvent, key: String(lastMove.at) })\n }, [boardState?.lastMove?.at])\n\n useEffect(() => {\n if (!toast) return\n const timer = setTimeout(() => setToast(null), 2500)\n return () => clearTimeout(timer)\n }, [toast?.key])\n\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n className={cn('pointer-events-none flex justify-center', className)}\n >\n <AnimatePresence mode=\"wait\">\n {toast && (\n <motion.div\n key={toast.key}\n initial={{ opacity: 0, y: -8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -8 }}\n transition={{ duration: 0.15 }}\n className={cn(\n 'px-4 py-2 rounded-full border font-inter text-sm font-semibold shadow-lg backdrop-blur-sm text-center',\n TOAST_CONFIG[toast.type],\n )}\n >\n {t(`eventToast.${toast.type}`)}\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n )\n}\n","import { useId, useState } from 'react'\nimport { useGameStore } from '../../store/use-game-store'\nimport { cn } from '../../lib/utils'\nimport { AnimatePresence, motion } from 'framer-motion'\nimport { MoveHistory } from './move-history'\nimport { squareName, SHORT_KEY } from '@scriptonita/chess-football-engine'\nimport type { MoveHistoryEntry } from '@scriptonita/chess-football-engine'\nimport { useGameT } from '../../i18n'\nimport { useDialogA11y } from '../../lib/use-dialog-a11y'\nimport { X } from 'lucide-react'\n\ninterface MobileHistoryProps {\n className?: string\n}\n\nexport function MobileHistory({ className }: MobileHistoryProps) {\n const boardState = useGameStore(s => s.boardState)\n const [open, setOpen] = useState(false)\n const titleId = `${useId()}-title`\n const panelRef = useDialogA11y({ open, onClose: () => setOpen(false) })\n\n const lastMove = boardState?.moveHistory?.at(-1)\n\n if (!lastMove) return null\n\n return (\n <>\n <HistoryChip lastMove={lastMove} onClick={() => setOpen(true)} className={className} />\n\n <AnimatePresence>\n {open && (\n <>\n <motion.div\n key=\"backdrop\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.2 }}\n className=\"fixed inset-0 z-40 bg-black/60 backdrop-blur-sm\"\n onClick={() => setOpen(false)}\n aria-hidden=\"true\"\n />\n <motion.div\n key=\"sheet\"\n initial={{ y: '100%' }}\n animate={{ y: 0 }}\n exit={{ y: '100%' }}\n transition={{ type: 'spring', stiffness: 300, damping: 32 }}\n ref={panelRef}\n className=\"fixed bottom-0 left-0 right-0 z-50 bg-bg-secondary rounded-t-2xl border-t border-border-subtle shadow-xl focus:outline-none\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n >\n <SheetHeader titleId={titleId} onClose={() => setOpen(false)} />\n <div className=\"px-4 pb-6 max-h-[50dvh] overflow-y-auto\">\n <MoveHistory scrollable={false} />\n </div>\n </motion.div>\n </>\n )}\n </AnimatePresence>\n </>\n )\n}\n\nfunction SheetHeader({ titleId, onClose }: { titleId: string; onClose: () => void }) {\n const t = useGameT()\n return (\n <div className=\"flex items-center justify-between px-5 pt-4 pb-3 border-b border-border-subtle\">\n <span id={titleId} className=\"font-mono text-[10px] tracking-[0.5px] uppercase text-fg-muted\">\n {t('history.title')}\n </span>\n <button\n onClick={onClose}\n className=\"w-11 h-11 -mr-2 flex items-center justify-center rounded-full bg-bg-surface hover:bg-bg-surface-elevated text-fg-muted hover:text-fg-primary transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-green\"\n aria-label={t('history.close')}\n >\n <X size={14} aria-hidden=\"true\" />\n </button>\n </div>\n )\n}\n\ninterface HistoryChipProps {\n lastMove: MoveHistoryEntry\n onClick: () => void\n className?: string\n}\n\nfunction HistoryChip({ lastMove, onClick, className }: HistoryChipProps) {\n const t = useGameT()\n const toSq = squareName(lastMove.to)\n let label: string\n switch (lastMove.type) {\n case 'pass': label = `⊕ ${toSq}`; break\n case 'tackle': label = `✕ ${toSq}`; break\n case 'interception': label = `⛔ ${toSq}`; break\n case 'goal': label = `⚽ GOL`; break\n case 'offside': label = `⚠ OFS`; break\n default: {\n const pieceShort = t(`pieces.${SHORT_KEY[lastMove.pieceType]}`)\n const fromSq = lastMove.from ? squareName(lastMove.from) : ''\n label = fromSq ? `${pieceShort}${fromSq}→${toSq}` : `${pieceShort}→${toSq}`\n }\n }\n\n return (\n <button\n onClick={onClick}\n className={cn(\n 'flex items-center gap-1.5 px-3 py-1.5 rounded-full',\n 'bg-bg-surface border border-border-subtle',\n 'font-mono text-[11px] text-fg-secondary',\n 'hover:text-fg-primary hover:bg-bg-surface-elevated active:scale-95',\n 'transition-all duration-150 motion-reduce:transition-none',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-green',\n className,\n )}\n aria-label={t('history.viewAll')}\n >\n <span>{label}</span>\n <span className=\"text-fg-muted text-[10px]\" aria-hidden=\"true\">▾</span>\n </button>\n )\n}\n","import { useEffect, useRef, useState } from 'react'\nimport { X } from 'lucide-react'\nimport type { Side } from '@scriptonita/chess-football-engine'\nimport { useGameStore } from '../../store/use-game-store'\nimport { useGameT } from '../../i18n'\nimport { cn } from '../../lib/utils'\n\n/**\n * The situations a first-time player gets one sentence about, the first time\n * each one happens. Ordered from most to least specific: when several apply at\n * once, the first one not yet seen wins.\n */\nexport const GAME_HINT_IDS = ['lastActionPoint', 'hasBall', 'selectPiece', 'start'] as const\n\nexport type GameHintId = (typeof GAME_HINT_IDS)[number]\n\ninterface GameHintsProps {\n /** The side the player controls; hints only show on that side's turn. */\n userSide: Side | null\n /** Hints the player has already been shown — the app owns where this lives. */\n seen: readonly GameHintId[]\n /** Called once per hint, when it is dismissed or its situation has passed. */\n onSeen: (id: GameHintId) => void\n className?: string\n}\n\n/**\n * Contextual, dismissible one-liners that teach the game while it is being\n * played, instead of asking a new player to read the rules first. Reads the\n * game store to recognise each situation; the host app decides when to mount\n * it (e.g. only during the first match) and where to persist `seen`.\n */\nexport function GameHints({ userSide, seen, onSeen, className }: GameHintsProps) {\n const t = useGameT()\n const boardState = useGameStore(s => s.boardState)\n const selectedPieceId = useGameStore(s => s.selectedPieceId)\n // Closed or outlived during this mount. Kept locally as well as reported, so a\n // hint never flickers back while the app persists `seen` asynchronously.\n const [done, setDone] = useState<readonly GameHintId[]>([])\n\n const myTurn = !!boardState && userSide !== null && boardState.turn === userSide\n const selected = myTurn ? boardState.pieces.find(p => p.id === selectedPieceId) : undefined\n const applies: Record<GameHintId, boolean> = {\n lastActionPoint: myTurn && boardState.actionPoints === 1,\n hasBall: !!selected && boardState?.ball.holderId === selected.id,\n selectPiece: !!selected,\n start: myTurn && !selected,\n }\n const current = GAME_HINT_IDS.find(id => applies[id] && !seen.includes(id) && !done.includes(id)) ?? null\n\n const onSeenRef = useRef(onSeen)\n onSeenRef.current = onSeen\n const markSeen = (id: GameHintId) => {\n setDone(d => (d.includes(id) ? d : [...d, id]))\n onSeenRef.current(id)\n }\n\n // A hint whose situation has passed did its job: the player has now seen\n // what it described, so it must not come back the next time.\n const shownRef = useRef<GameHintId | null>(null)\n useEffect(() => {\n const prev = shownRef.current\n shownRef.current = current\n if (prev && prev !== current && !done.includes(prev)) markSeen(prev)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [current])\n\n return (\n <div role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" className={cn('pointer-events-none flex justify-center', className)}>\n {current && (\n <div\n data-testid=\"game-hint\"\n data-hint={current}\n className=\"pointer-events-auto flex items-center gap-1 max-w-sm pl-4 pr-0.5 rounded-xl bg-bg-secondary/95 border border-border-subtle shadow-lg backdrop-blur-sm\"\n >\n <p className=\"py-2 font-inter text-sm leading-snug text-fg-primary\">{t(`hints.${current}`)}</p>\n <button\n type=\"button\"\n onClick={() => markSeen(current)}\n aria-label={t('hints.dismiss')}\n className=\"shrink-0 w-11 h-11 flex items-center justify-center rounded-full text-fg-muted hover:text-fg-primary transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-green\"\n >\n <X size={16} aria-hidden=\"true\" />\n </button>\n </div>\n )}\n </div>\n )\n}\n","import { useCallback, useEffect, useRef, useState } from 'react'\nimport { checkGoal } from '@scriptonita/chess-football-engine'\nimport type { BoardState, Side } from '@scriptonita/chess-football-engine'\n\n/**\n * Pause between the turn changing hands and the bot's first action. Long enough\n * for \"the rival is playing\" to register, short enough to stay under the ~400 ms\n * at which waiting starts to feel like waiting.\n */\nexport const BOT_TURN_START_DELAY_MS = 400\n\n/**\n * How long each bot action stays on screen before the next one. The piece/ball\n * springs settle in 300–500 ms, so 900 ms leaves a clear beat between actions.\n */\nexport const BOT_TURN_STEP_MS = 900\n\n/**\n * How long the LAST action stays before the turn is handed over. Nothing follows\n * it, so it only needs its animation to land — the board then stays as it is,\n * under the player's control. The closing end-of-turn state is applied at that\n * same moment, without a step of its own (nothing moves in it).\n *\n * A full 5-AP turn is 400 + 4 × 900 + 500 = 4.5 s, which leaves half a second\n * of slack under 5 s for a slow search or a slow network.\n */\nexport const BOT_TURN_SETTLE_MS = 500\n\n// The turn provider is called a beat after the \"bot is playing\" state is set, so\n// a synchronous (local) search cannot block the frame that paints that state.\nconst PROVIDER_DEFER_MS = 30\n\n/**\n * What a turn provider must hand back. It is the shape of the engine's\n * `playBotTurn` result (engine ≥ 0.7.0), so a local provider returns that as-is;\n * a server-backed one rebuilds it from its response.\n */\nexport interface BotTurnPlayback {\n /** Board after each applied action, in order. Must not be empty. */\n states: BoardState[]\n /** True when the last state is a bare end-of-turn: it gets no display step. */\n closedByEndTurn?: boolean\n /** Side that scored during the turn, if any. */\n goalScored?: Side | null\n}\n\nexport interface UseBotTurnOptions {\n /** Current board; the bot plays when `boardState.turn === botSide`. */\n boardState: BoardState | null\n /** The side the bot plays. */\n botSide: Side\n /**\n * Where the turn comes from. Local apps call the engine's `playBotTurn`;\n * server-backed apps fetch it. Rejecting (or throwing) surfaces `error`.\n */\n getTurn: (boardState: BoardState, botSide: Side) => BotTurnPlayback | Promise<BotTurnPlayback>\n /** Apply one board state (usually the store's `setBoardState`). */\n onApplyState: (state: BoardState) => void\n /** Extra gate on top of the turn check (match loaded, board installed…). Default true. */\n enabled?: boolean\n /** True once the match is decided: the bot must not play. */\n matchOver?: boolean\n /** True while a goal celebration is on screen: the bot waits for the kickoff. */\n goalPending?: boolean\n /** Called once the turn has fully played out, if the bot scored in it. */\n onGoal?: (scorer: Side, lastState: BoardState) => void\n /** Notified when the bot starts (true) / stops (false) playing. */\n onProcessingChange?: (processing: boolean) => void\n /** Override the default pacing (tests, debug). */\n startDelayMs?: number\n stepMs?: number\n settleMs?: number\n}\n\nexport interface UseBotTurnResult {\n /** True from the moment the bot's turn starts until its last state is applied. */\n botThinking: boolean\n /** Set when the provider failed; the turn is still the bot's, so offer `retry`. */\n error: Error | null\n /** Clear the error and run the bot's turn again. */\n retry: () => void\n /** Jump straight to the end of the turn being replayed (a tap from an impatient player). */\n skip: () => void\n}\n\n/**\n * Owns a bot's turn end to end: the entry gates, the timed replay of its states,\n * cancellation on unmount, error + retry, and skip. It used to live once per app\n * (and, in one of them, once per route) with different timings in each copy.\n */\nexport function useBotTurn(opts: UseBotTurnOptions): UseBotTurnResult {\n const [botThinking, setBotThinking] = useState(false)\n const [error, setError] = useState<Error | null>(null)\n const [retryNonce, setRetryNonce] = useState(0)\n\n // Read the latest options inside the narrowly-keyed effect so callbacks and\n // board values never go stale.\n const optsRef = useRef(opts)\n optsRef.current = opts\n\n // `pending` is a ref, not the `botThinking` state: React StrictMode replays\n // mount → unmount → mount while state survives, so gating on state would\n // leave the bot \"thinking\" forever after the simulated unmount cancelled it.\n const pending = useRef(false)\n const runId = useRef(0)\n const timers = useRef(new Set<ReturnType<typeof setTimeout>>())\n const skipRef = useRef<(() => void) | null>(null)\n\n const clearTimers = () => {\n timers.current.forEach(clearTimeout)\n timers.current.clear()\n }\n\n // The game store is a module-global singleton: a timer that outlives this\n // screen would write the old match's board into the next one.\n useEffect(() => () => {\n runId.current++\n clearTimers()\n pending.current = false\n skipRef.current = null\n }, [])\n\n const { boardState, enabled = true, matchOver = false, goalPending = false } = opts\n\n useEffect(() => {\n const o = optsRef.current\n const board = o.boardState\n if (!board || !enabled || board.turn !== o.botSide) return\n if (pending.current || matchOver || goalPending) return\n // A goal is waiting to be celebrated and the board is about to reset:\n // playing over it would overwrite the kickoff.\n if (checkGoal(board)) return\n\n const run = ++runId.current\n const alive = () => runId.current === run\n const wait = (ms: number) => new Promise<void>((resolve) => {\n const id = setTimeout(() => { timers.current.delete(id); resolve() }, ms)\n timers.current.add(id)\n })\n const settle = () => {\n pending.current = false\n skipRef.current = null\n setBotThinking(false)\n optsRef.current.onProcessingChange?.(false)\n }\n\n pending.current = true\n setBotThinking(true)\n setError(null)\n o.onProcessingChange?.(true)\n\n let skipRequested = false\n skipRef.current = () => { skipRequested = true }\n\n const startDelay = o.startDelayMs ?? BOT_TURN_START_DELAY_MS\n const stepMs = o.stepMs ?? BOT_TURN_STEP_MS\n const settleMs = o.settleMs ?? BOT_TURN_SETTLE_MS\n\n ;(async () => {\n try {\n const [turn] = await Promise.all([\n wait(Math.min(PROVIDER_DEFER_MS, startDelay)).then(() => o.getTurn(board, o.botSide)),\n wait(startDelay),\n ])\n if (!alive()) return\n if (!turn?.states?.length) throw new Error('Bot turn returned no states')\n\n const { states } = turn\n const last = states[states.length - 1]\n // The closing end-of-turn state rides along with the finish instead\n // of taking a display step.\n const shown = turn.closedByEndTurn ? states.length - 1 : states.length\n\n const finish = () => {\n clearTimers()\n optsRef.current.onApplyState(last)\n settle()\n const scorer = turn.goalScored ?? null\n if (scorer) optsRef.current.onGoal?.(scorer, last)\n }\n skipRef.current = () => { if (alive()) finish() }\n if (skipRequested) { finish(); return }\n\n for (let i = 0; i < shown; i++) {\n optsRef.current.onApplyState(states[i])\n await wait(i === shown - 1 ? settleMs : stepMs)\n // `skip` and unmount both clear the timers, so a cancelled wait\n // never resolves and this loop simply stops here.\n if (!alive()) return\n }\n finish()\n } catch (err) {\n if (!alive()) return\n // The turn is still the bot's and nothing this effect depends on\n // changed, so it will not re-run by itself: without an error the\n // player can retry, the match would stall on the bot's turn.\n clearTimers()\n settle()\n setError(err instanceof Error ? err : new Error(String(err)))\n }\n })()\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [boardState?.turn, enabled, matchOver, goalPending, retryNonce])\n\n const retry = useCallback(() => {\n setError(null)\n setRetryNonce((n) => n + 1)\n }, [])\n const skip = useCallback(() => { skipRef.current?.() }, [])\n\n return { botThinking, error, retry, skip }\n}\n","/**\n * Every CSS custom property the package's Tailwind classes resolve against.\n *\n * A token the host app does not define fails *silently*: Tailwind emits the\n * rule, the variable resolves to nothing, and the declaration is dropped. That\n * is how `--last-move-highlight` went missing in the CrazyGames SPA — the\n * last-move highlight and the bot's turn replay simply never rendered, with no\n * error anywhere.\n *\n * This is the visual counterpart to `GAME_I18N_KEYS`: assert it in each app.\n *\n * ```ts\n * import { REQUIRED_TOKENS } from '@scriptonita/chess-football-ui'\n *\n * const css = readFileSync('src/index.css', 'utf8')\n * expect(REQUIRED_TOKENS.filter(t => !css.includes(`${t}:`))).toEqual([])\n * ```\n */\nexport const REQUIRED_TOKENS = [\n // Surfaces\n '--bg-primary',\n '--bg-secondary',\n '--bg-surface',\n '--bg-surface-elevated',\n // Text\n '--fg-primary',\n '--fg-secondary',\n '--fg-muted',\n // Accent (the primary CTA rests on the dark step — see Button)\n '--accent-green',\n '--accent-green-light',\n '--accent-green-dark',\n // Borders\n '--border-subtle',\n // Semantic\n '--danger',\n '--warning',\n // Board\n '--field-green-1',\n '--field-green-2',\n '--field-frame',\n '--move-highlight',\n '--pass-highlight',\n '--last-move-highlight',\n '--ball-color',\n] as const\n\nexport type RequiredToken = (typeof REQUIRED_TOKENS)[number]\n"]}