@pompidup/kingdomino-engine 3.4.0 → 3.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/domain/types/game.ts","../src/core/useCases/gameDebug.ts","../src/core/useCases/gameEvents.ts","../src/adapterServerside/consoleLogger.ts","../src/datasources/buildings.json","../src/adapterServerside/jsonBuildings.ts","../src/datasources/dominoes.json","../src/adapterServerside/jsonDominoes.ts","../src/datasources/modes.json","../src/adapterServerside/jsonModes.ts","../src/datasources/rules.json","../src/adapterServerside/jsonRules.ts","../src/adapterServerside/shuffle.ts","../src/adapterServerside/uuid.ts","../src/core/domain/errors/domainErrors.ts","../src/core/i18n/translations.ts","../src/utils/result.ts","../src/application/handlers/addExtraRulesHandler.ts","../src/application/handlers/addPlayersHandler.ts","../src/application/handlers/calculateScoreHandler.ts","../src/application/handlers/canPlaceDominoHandler.ts","../src/application/handlers/chooseDominoHandler.ts","../src/application/handlers/createGameHandler.ts","../src/application/handlers/discardDominoHandler.ts","../src/application/handlers/getDynastyResultHandler.ts","../src/application/handlers/getExtraRulesHandler.ts","../src/application/handlers/getModesHandler.ts","../src/application/handlers/getResultHandler.ts","../src/application/handlers/getValidPlacementsHandler.ts","../src/application/handlers/placeDominoHandler.ts","../src/core/useCases/serialization.ts","../src/application/handlers/serializeGameHandler.ts","../src/application/handlers/startGameHandler.ts","../src/application/handlers/placeKnightHandler.ts","../src/application/handlers/constructBuildingHandler.ts","../src/application/handlers/useDragonHandler.ts","../src/application/handlers/skipOptionalActionHandler.ts","../src/core/domain/types/domino.ts","../src/core/domain/types/kingdom.ts","../src/core/domain/types/player.ts","../src/core/domain/entities/rule.ts","../src/utils/seededShuffle.ts","../src/core/useCases/addExtraRules.ts","../src/core/domain/entities/economy.ts","../src/core/domain/entities/domino.ts","../src/core/domain/entities/kingdom.ts","../src/core/domain/entities/player.ts","../src/core/useCases/addPlayers.ts","../src/core/useCases/calculateScore.ts","../src/core/domain/entities/lord.ts","../src/core/useCases/chooseDomino.ts","../src/core/domain/entities/game.ts","../src/core/domain/entities/mode.ts","../src/core/useCases/createGame.ts","../src/core/useCases/getValidPlacements.ts","../src/core/useCases/discardDomino.ts","../src/core/useCases/getDynastyResult.ts","../src/core/useCases/getExtraRules.ts","../src/core/useCases/getModes.ts","../src/core/useCases/getResult.ts","../src/core/useCases/placeDomino.ts","../src/core/domain/entities/knight.ts","../src/core/useCases/placeKnight.ts","../src/core/domain/entities/building.ts","../src/core/domain/entities/queen.ts","../src/core/useCases/constructBuilding.ts","../src/core/useCases/useDragon.ts","../src/core/useCases/skipOptionalAction.ts","../src/core/useCases/startGame.ts","../src/config.ts","../src/core/domain/entities/validateGameState.ts","../src/core/useCases/botRegistry.ts","../src/core/useCases/bot.ts","../src/core/useCases/gameActionLog.ts","../src/core/useCases/gameHistory.ts","../src/index.ts"],"sourcesContent":["import type { Result } from \"@utils/result.js\";\nimport type { Domino, RevealsDomino } from \"./domino.js\";\nimport type { Lord } from \"./lord.js\";\nimport type { GameMode } from \"./mode.js\";\nimport type { Player, PlayerActions } from \"./player.js\";\nimport type { QueenDominoState } from \"./queendomino.js\";\nimport type { SelectedRules } from \"./rule.js\";\nimport type { ObjectValues } from \"./utils.js\";\n\n/**\n * Represents the complete state of a Kingdomino game.\n * This is the main aggregate containing all game data.\n */\nexport type Game = {\n /** Unique identifier for the game */\n id: string;\n /** Remaining dominoes in the draw pile */\n dominoes: Domino[];\n /** Currently revealed dominoes available for picking */\n currentDominoes: RevealsDomino[];\n /** Players participating in the game with their kingdoms */\n players: Player[];\n /** Lords (player tokens) used for turn order and domino selection */\n lords: Lord[];\n /** Current turn number (1-based) */\n turn: number;\n /** Next required action or game step */\n nextAction: NextAction | NextStep;\n /** Active rules for this game */\n rules: SelectedRules;\n /** Game mode being played */\n mode: GameMode;\n /** Optional seed for deterministic shuffle (replays, sharing) */\n seed?: string;\n /** Queendomino-specific state (only present in QueenDomino mode) */\n queendomino?: QueenDominoState;\n};\n\n/**\n * Available game steps representing phases of game setup and completion.\n */\nexport const gameSteps = {\n /** Waiting for players to be added */\n addPlayers: \"addPlayers\",\n /** Optional rules selection phase */\n options: \"options\",\n /** Ready to start the game */\n start: \"start\",\n /** Game has ended, results available */\n result: \"result\",\n} as const;\n\n/** Union type of all possible game steps */\nexport type GameSteps = ObjectValues<typeof gameSteps>;\n\n/**\n * Represents a player action that needs to be performed.\n * Used during active gameplay.\n */\nexport type NextAction = {\n /** Discriminator for action type */\n type: \"action\";\n /** ID of the lord who must perform the action */\n nextLord: string;\n /** The action the lord must perform */\n nextAction: PlayerActions;\n};\n\n/**\n * Represents a game phase transition.\n * Used during setup and game end.\n */\nexport type NextStep = {\n /** Discriminator for step type */\n type: \"step\";\n /** The current game step/phase */\n step: GameSteps;\n};\n\n/** Game state where a player action is required */\nexport type GameWithNextAction = Game & { nextAction: NextAction };\n\n/** Game state where a phase transition is occurring */\nexport type GameWithNextStep = Game & { nextAction: NextStep };\n\n/** Union of all possible game states */\nexport type GameState = GameWithNextAction | GameWithNextStep;\n\n/** Result wrapper for game state operations */\nexport type GameStateResult = Result<GameState>;\n\n/**\n * Type guard to check if the game requires a player action.\n * @param game - The game state to check\n * @returns True if the game is waiting for a player action\n */\nexport const isGameWithNextAction = (\n game: GameWithNextAction | GameWithNextStep\n): game is GameWithNextAction => {\n return game.nextAction.type === \"action\";\n};\n\n/**\n * Type guard to check if the game is in a phase transition.\n * @param game - The game state to check\n * @returns True if the game is transitioning between phases\n */\nexport const isGameWithNextStep = (\n game: GameWithNextAction | GameWithNextStep\n): game is GameWithNextStep => {\n return game.nextAction.type === \"step\";\n};\n\n/**\n * Represents the score calculation for a kingdom.\n */\nexport type Score = {\n /** Total points earned */\n points: number;\n /** Size of the largest contiguous property */\n maxPropertiesSize: number;\n /** Total number of crowns in the kingdom */\n totalCrowns: number;\n};\n\n/**\n * Score result for a specific player.\n */\nexport type ScoreResult = {\n /** Player's unique identifier */\n playerId: string;\n /** Player's display name */\n playerName: string;\n /** Detailed score breakdown */\n details: Score;\n};\n\n/**\n * Final result including ranking position.\n */\nexport type FinalResult = ScoreResult & {\n /** Player's final position (1 = winner) */\n position: number;\n};\n\n/** Game state with final results calculated */\nexport type GameWithResults = Game & { result: FinalResult[] };\n","import { isGameWithNextAction } from \"@core/domain/types/game.js\";\nimport type { GameState } from \"@core/domain/types/index.js\";\nimport type { GameEngine } from \"@core/portUserside/engine.js\";\n\n// ─── Types ──────────────────────────────────────────────────────────\n\n/**\n * Debug log verbosity level.\n * - `minimal`: method name + phase only\n * - `standard`: + game state summary + key params\n * - `verbose`: + full game state JSON dump\n */\nexport type DebugLogLevel = \"minimal\" | \"standard\" | \"verbose\";\n\n/**\n * Summary of the current game state, extracted for quick inspection.\n */\nexport type GameStateSummary = {\n gameId: string;\n turn: number;\n nextAction: string;\n playersCount: number;\n dominoesRemaining: number;\n currentDominoesCount: number;\n lordsCount: number;\n};\n\n/**\n * A single debug log entry emitted by the debug wrapper.\n */\nexport type DebugLogEntry = {\n timestamp: string;\n method: string;\n phase: \"before\" | \"after\" | \"error\";\n summary: GameStateSummary | null;\n params?: Record<string, unknown>;\n error?: string;\n durationMs?: number;\n fullState?: GameState;\n};\n\n/**\n * Custom debug logger interface.\n * Consumers can provide their own to redirect debug output.\n */\nexport type DebugLogger = {\n log: (entry: DebugLogEntry) => void;\n};\n\n/**\n * Configuration for the debug wrapper.\n */\nexport type DebugOptions = {\n /** Custom debug logger. Defaults to console-based logger. */\n logger?: DebugLogger;\n /** Verbosity level. Defaults to \"standard\". */\n level?: DebugLogLevel;\n};\n\n// ─── Helpers ────────────────────────────────────────────────────────\n\n/**\n * Extracts a concise summary from a game state object.\n */\nexport const summarizeGameState = (game: GameState): GameStateSummary => {\n const nextAction = isGameWithNextAction(game)\n ? `action:${game.nextAction.nextAction}`\n : `step:${game.nextAction.step}`;\n\n return {\n gameId: game.id,\n turn: game.turn,\n nextAction,\n playersCount: game.players.length,\n dominoesRemaining: game.dominoes.length,\n currentDominoesCount: game.currentDominoes.length,\n lordsCount: game.lords.length,\n };\n};\n\nconst defaultDebugLogger: DebugLogger = {\n log: (entry: DebugLogEntry) => {\n const phase = entry.phase.toUpperCase().padEnd(5);\n const base = `[KDomino:Debug] ${entry.timestamp} ${phase} ${entry.method}`;\n\n if (entry.phase === \"error\") {\n console.error(`${base} | error: ${entry.error}`);\n return;\n }\n\n if (entry.summary) {\n const s = entry.summary;\n console.log(\n `${base} | turn=${s.turn} next=${s.nextAction} players=${s.playersCount} dominoes=${s.dominoesRemaining}`,\n );\n } else {\n console.log(base);\n }\n },\n};\n\nconst isGameState = (value: unknown): value is GameState => {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"id\" in value &&\n \"nextAction\" in value &&\n \"players\" in value &&\n \"dominoes\" in value\n );\n};\n\ntype CommandWithGame = { game: GameState; [key: string]: unknown };\n\nconst hasGameInCommand = (cmd: unknown): cmd is CommandWithGame => {\n return (\n typeof cmd === \"object\" &&\n cmd !== null &&\n \"game\" in cmd &&\n isGameState((cmd as CommandWithGame).game)\n );\n};\n\nconst extractParams = (cmd: unknown): Record<string, unknown> | undefined => {\n if (typeof cmd !== \"object\" || cmd === null) return undefined;\n\n const record = cmd as Record<string, unknown>;\n const params: Record<string, unknown> = {};\n\n if (\"mode\" in record) params.mode = record.mode;\n if (\"lordId\" in record) params.lordId = record.lordId;\n if (\"dominoPick\" in record) params.dominoPick = record.dominoPick;\n if (\"position\" in record) params.position = record.position;\n if (\"rotation\" in record) params.rotation = record.rotation;\n if (\"players\" in record) params.players = record.players;\n if (\"extraRules\" in record) params.extraRules = record.extraRules;\n\n return Object.keys(params).length > 0 ? params : undefined;\n};\n\n// ─── Wrapper ────────────────────────────────────────────────────────\n\nconst wrapMethod = <TArgs, TResult>(\n method: string,\n fn: (cmd: TArgs) => TResult,\n logger: DebugLogger,\n level: DebugLogLevel,\n): ((cmd: TArgs) => TResult) => {\n return (cmd: TArgs) => {\n const timestamp = new Date().toISOString();\n\n // Before\n const beforeSummary =\n level !== \"minimal\" && hasGameInCommand(cmd)\n ? summarizeGameState(cmd.game)\n : null;\n\n const beforeEntry: DebugLogEntry = {\n timestamp,\n method,\n phase: \"before\",\n summary: beforeSummary,\n params: level !== \"minimal\" ? extractParams(cmd) : undefined,\n };\n\n logger.log(beforeEntry);\n\n // Execute\n const start = performance.now();\n let result: TResult;\n try {\n result = fn(cmd);\n } catch (err) {\n const durationMs = Math.round((performance.now() - start) * 100) / 100;\n const errorEntry: DebugLogEntry = {\n timestamp: new Date().toISOString(),\n method,\n phase: \"error\",\n summary: beforeSummary,\n error: err instanceof Error ? err.message : String(err),\n durationMs,\n };\n logger.log(errorEntry);\n throw err;\n }\n\n const durationMs = Math.round((performance.now() - start) * 100) / 100;\n\n // After\n const afterSummary =\n level !== \"minimal\" && isGameState(result)\n ? summarizeGameState(result as GameState)\n : null;\n\n const afterEntry: DebugLogEntry = {\n timestamp: new Date().toISOString(),\n method,\n phase: \"after\",\n summary: afterSummary,\n durationMs,\n fullState:\n level === \"verbose\" && isGameState(result)\n ? (result as GameState)\n : undefined,\n };\n\n logger.log(afterEntry);\n\n return result;\n };\n};\n\n/**\n * Wraps a GameEngine to emit detailed debug log entries before and after each method call.\n * Useful for UI developers to inspect engine behavior at every step.\n *\n * @param engine - The base game engine to wrap\n * @param options - Debug configuration (logger, verbosity level)\n * @returns A new GameEngine that emits debug logs\n *\n * @example\n * ```typescript\n * const debugEngine = wrapWithDebug(engine, { level: \"verbose\" });\n * let game = debugEngine.createGame({ mode: \"Classic\" });\n * // Console: [KDomino:Debug] ... BEFORE createGame\n * // Console: [KDomino:Debug] ... AFTER createGame | turn=0 ...\n * ```\n */\nexport const wrapWithDebug = (\n engine: GameEngine,\n options?: DebugOptions,\n): GameEngine => {\n const logger = options?.logger ?? defaultDebugLogger;\n const level = options?.level ?? \"standard\";\n\n return {\n getModes: wrapMethod(\"getModes\", engine.getModes, logger, level),\n getExtraRules: wrapMethod(\n \"getExtraRules\",\n engine.getExtraRules,\n logger,\n level,\n ),\n createGame: wrapMethod(\"createGame\", engine.createGame, logger, level),\n addPlayers: wrapMethod(\"addPlayers\", engine.addPlayers, logger, level),\n addExtraRules: wrapMethod(\n \"addExtraRules\",\n engine.addExtraRules,\n logger,\n level,\n ),\n startGame: wrapMethod(\"startGame\", engine.startGame, logger, level),\n chooseDomino: wrapMethod(\n \"chooseDomino\",\n engine.chooseDomino,\n logger,\n level,\n ),\n placeDomino: wrapMethod(\"placeDomino\", engine.placeDomino, logger, level),\n discardDomino: wrapMethod(\n \"discardDomino\",\n engine.discardDomino,\n logger,\n level,\n ),\n getResults: wrapMethod(\"getResults\", engine.getResults, logger, level),\n calculateScore: wrapMethod(\n \"calculateScore\",\n engine.calculateScore,\n logger,\n level,\n ),\n getValidPlacements: wrapMethod(\n \"getValidPlacements\",\n engine.getValidPlacements,\n logger,\n level,\n ),\n canPlaceDomino: wrapMethod(\n \"canPlaceDomino\",\n engine.canPlaceDomino,\n logger,\n level,\n ),\n serialize: wrapMethod(\"serialize\", engine.serialize, logger, level),\n deserialize: wrapMethod(\"deserialize\", engine.deserialize, logger, level),\n getDynastyResults: wrapMethod(\n \"getDynastyResults\",\n engine.getDynastyResults,\n logger,\n level,\n ),\n placeKnight: wrapMethod(\n \"placeKnight\",\n engine.placeKnight,\n logger,\n level,\n ),\n constructBuilding: wrapMethod(\n \"constructBuilding\",\n engine.constructBuilding,\n logger,\n level,\n ),\n useDragon: wrapMethod(\"useDragon\", engine.useDragon, logger, level),\n skipOptionalAction: wrapMethod(\n \"skipOptionalAction\",\n engine.skipOptionalAction,\n logger,\n level,\n ),\n };\n};\n","import type {\n GameState,\n GameWithNextAction,\n GameWithNextStep,\n} from \"@core/domain/types/index.js\";\nimport { isGameWithNextStep } from \"@core/domain/types/game.js\";\nimport type { GameEngine } from \"@core/portUserside/engine.js\";\n\n// ─── Event Types ─────────────────────────────────────────────────────\n\n/**\n * Optional callbacks for game events.\n * Consumers provide these to react to state changes (UI updates, animations, logging).\n * All callbacks are optional — only the ones you provide will be called.\n *\n * @example\n * ```typescript\n * const engine = createGameEngine({\n * events: {\n * onDominoPlaced: ({ game, lordId }) => {\n * console.log(`Lord ${lordId} placed a domino`);\n * animatePlacement(game);\n * },\n * onTurnEnd: ({ turn }) => console.log(`Turn ${turn} ended`),\n * onGameEnd: () => showResultsScreen(),\n * },\n * });\n * ```\n */\nexport type GameEventCallbacks = {\n /** Called after a new game is created */\n onGameCreated?: (event: { game: GameWithNextStep }) => void;\n /** Called after players are added to the game */\n onPlayersAdded?: (event: { game: GameWithNextStep }) => void;\n /** Called after the game starts (first dominoes revealed) */\n onGameStarted?: (event: { game: GameWithNextAction }) => void;\n /** Called after a lord picks a domino */\n onDominoPicked?: (event: {\n game: GameState;\n lordId: string;\n dominoNumber: number;\n }) => void;\n /** Called after a lord places a domino on their kingdom */\n onDominoPlaced?: (event: { game: GameState; lordId: string }) => void;\n /** Called after a lord discards a domino (no valid placement) */\n onDominoDiscarded?: (event: { game: GameState; lordId: string }) => void;\n /** Called when a new turn begins */\n onTurnStart?: (event: { game: GameState; turn: number }) => void;\n /** Called when a turn ends (all lords have played) */\n onTurnEnd?: (event: { game: GameState; turn: number }) => void;\n /** Called when the game reaches the result phase */\n onGameEnd?: (event: { game: GameState }) => void;\n};\n\n// ─── Wrapper ─────────────────────────────────────────────────────────\n\nconst isGameEnded = (game: GameState): boolean =>\n isGameWithNextStep(game) && game.nextAction.step === \"result\";\n\n/**\n * Wraps a GameEngine to emit event callbacks after each state-changing method.\n * Read-only methods (getModes, calculateScore, etc.) are passed through unchanged.\n *\n * Derived events:\n * - `onTurnEnd` + `onTurnStart`: emitted when `chooseDomino` causes a turn increment\n * - `onGameEnd`: emitted when `placeDomino` or `discardDomino` transitions to the \"result\" step\n *\n * @param engine - The base game engine to wrap\n * @param callbacks - Optional event callbacks\n * @returns A new GameEngine that emits events\n */\nexport const wrapWithEvents = (\n engine: GameEngine,\n callbacks: GameEventCallbacks\n): GameEngine => ({\n // Read-only methods — pass through\n getModes: (cmd) => engine.getModes(cmd),\n getExtraRules: (cmd) => engine.getExtraRules(cmd),\n calculateScore: (cmd) => engine.calculateScore(cmd),\n getValidPlacements: (cmd) => engine.getValidPlacements(cmd),\n canPlaceDomino: (cmd) => engine.canPlaceDomino(cmd),\n serialize: (cmd) => engine.serialize(cmd),\n deserialize: (cmd) => engine.deserialize(cmd),\n getResults: (cmd) => engine.getResults(cmd),\n getDynastyResults: (cmd) => engine.getDynastyResults(cmd),\n\n // State-changing methods — emit events after execution\n createGame: (cmd) => {\n const game = engine.createGame(cmd);\n callbacks.onGameCreated?.({ game });\n return game;\n },\n\n addPlayers: (cmd) => {\n const game = engine.addPlayers(cmd);\n callbacks.onPlayersAdded?.({ game });\n return game;\n },\n\n addExtraRules: (cmd) => engine.addExtraRules(cmd),\n\n startGame: (cmd) => {\n const game = engine.startGame(cmd);\n callbacks.onGameStarted?.({ game });\n callbacks.onTurnStart?.({ game, turn: game.turn });\n return game;\n },\n\n chooseDomino: (cmd) => {\n const turnBefore = cmd.game.turn;\n const game = engine.chooseDomino(cmd);\n callbacks.onDominoPicked?.({\n game,\n lordId: cmd.lordId,\n dominoNumber: cmd.dominoPick,\n });\n\n // Detect turn transition\n if (game.turn !== turnBefore) {\n callbacks.onTurnEnd?.({ game, turn: turnBefore });\n callbacks.onTurnStart?.({ game, turn: game.turn });\n }\n\n return game;\n },\n\n placeDomino: (cmd) => {\n const game = engine.placeDomino(cmd);\n callbacks.onDominoPlaced?.({ game, lordId: cmd.lordId });\n\n if (isGameEnded(game)) {\n callbacks.onGameEnd?.({ game });\n }\n\n return game;\n },\n\n discardDomino: (cmd) => {\n const game = engine.discardDomino(cmd);\n callbacks.onDominoDiscarded?.({ game, lordId: cmd.lordId });\n\n if (isGameEnded(game)) {\n callbacks.onGameEnd?.({ game });\n }\n\n return game;\n },\n\n // Queendomino methods — pass through (no specific events yet)\n placeKnight: (cmd) => engine.placeKnight(cmd),\n constructBuilding: (cmd) => engine.constructBuilding(cmd),\n useDragon: (cmd) => engine.useDragon(cmd),\n skipOptionalAction: (cmd) => engine.skipOptionalAction(cmd),\n});\n","import type { Logger } from \"@core/portServerside/logger.js\";\n\n/**\n * Creates a lightweight console-based logger.\n * This is the default logger used when no custom logger is provided.\n * @param isLoggingEnabled - Whether logging is enabled\n * @returns A Logger instance that outputs to console\n */\nexport const consoleLogger = (isLoggingEnabled: boolean): Logger => {\n const formatMessage = (level: string, message: string): string => {\n const timestamp = new Date().toISOString();\n return `${timestamp} [KDomino_Engine] ${level}: ${message}`;\n };\n\n return {\n info: (message: string) => {\n if (isLoggingEnabled) {\n console.log(formatMessage(\"info\", message));\n }\n },\n error: (message: string) => {\n if (isLoggingEnabled) {\n console.error(formatMessage(\"error\", message));\n }\n },\n };\n};\n\n/**\n * A silent logger that does nothing.\n * Useful for testing or when logging should be completely disabled.\n */\nexport const silentLogger: Logger = {\n info: () => {},\n error: () => {},\n};\n","[\n { \"id\": 1, \"name\": \"The Bakery\", \"cost\": 1, \"immediateBonus\": { \"type\": \"coins\", \"amount\": 2 }, \"crowns\": 0, \"towers\": 0 },\n { \"id\": 2, \"name\": \"The Bakery\", \"cost\": 1, \"immediateBonus\": { \"type\": \"coins\", \"amount\": 2 }, \"crowns\": 0, \"towers\": 0 },\n { \"id\": 3, \"name\": \"The Sawmill\", \"cost\": 2, \"crowns\": 0, \"towers\": 0, \"endGameScoring\": { \"type\": \"perTerrain\", \"terrain\": \"forest\", \"points\": 1 } },\n { \"id\": 4, \"name\": \"The Fishmonger's\", \"cost\": 2, \"immediateBonus\": { \"type\": \"coins\", \"amount\": 1 }, \"crowns\": 0, \"towers\": 0, \"endGameScoring\": { \"type\": \"perTerrain\", \"terrain\": \"sea\", \"points\": 1 } },\n { \"id\": 5, \"name\": \"The Fishmonger's\", \"cost\": 2, \"immediateBonus\": { \"type\": \"coins\", \"amount\": 1 }, \"crowns\": 0, \"towers\": 0, \"endGameScoring\": { \"type\": \"perTerrain\", \"terrain\": \"sea\", \"points\": 1 } },\n { \"id\": 6, \"name\": \"The Weaving Shop\", \"cost\": 3, \"crowns\": 1, \"towers\": 0, \"endGameScoring\": { \"type\": \"perTerrain\", \"terrain\": \"wheat\", \"points\": 1 } },\n { \"id\": 7, \"name\": \"The Magic School\", \"cost\": 4, \"crowns\": 1, \"towers\": 0, \"endGameScoring\": { \"type\": \"perCrown\", \"points\": 1 } },\n { \"id\": 8, \"name\": \"The Fountain\", \"cost\": 3, \"crowns\": 0, \"towers\": 1, \"endGameScoring\": { \"type\": \"perTower\", \"points\": 2 } },\n { \"id\": 9, \"name\": \"The Church\", \"cost\": 4, \"crowns\": 1, \"towers\": 0, \"endGameScoring\": { \"type\": \"perBuilding\", \"points\": 2 } },\n { \"id\": 10, \"name\": \"The Bath\", \"cost\": 2, \"immediateBonus\": { \"type\": \"coins\", \"amount\": 1 }, \"crowns\": 0, \"towers\": 0, \"endGameScoring\": { \"type\": \"flat\", \"points\": 4 } },\n { \"id\": 11, \"name\": \"The Guard Tower\", \"cost\": 1, \"crowns\": 0, \"towers\": 1, \"endGameScoring\": { \"type\": \"flat\", \"points\": 2 } },\n { \"id\": 12, \"name\": \"The Guard Tower\", \"cost\": 1, \"crowns\": 0, \"towers\": 1, \"endGameScoring\": { \"type\": \"flat\", \"points\": 2 } },\n { \"id\": 13, \"name\": \"The Big Tower\", \"cost\": 3, \"crowns\": 0, \"towers\": 2, \"endGameScoring\": { \"type\": \"flat\", \"points\": 4 } },\n { \"id\": 14, \"name\": \"The Guardhouse\", \"cost\": 2, \"crowns\": 0, \"towers\": 1, \"endGameScoring\": { \"type\": \"perBuilding\", \"points\": 1 } },\n { \"id\": 15, \"name\": \"The Fortified Castle\", \"cost\": 5, \"crowns\": 2, \"towers\": 1, \"endGameScoring\": { \"type\": \"flat\", \"points\": 6 } },\n { \"id\": 16, \"name\": \"The Travelling Castle\", \"cost\": 3, \"crowns\": 1, \"towers\": 1, \"endGameScoring\": { \"type\": \"perTower\", \"points\": 1 } },\n { \"id\": 17, \"name\": \"The Travelling Group\", \"cost\": 2, \"immediateBonus\": { \"type\": \"coins\", \"amount\": 1 }, \"crowns\": 0, \"towers\": 0, \"endGameScoring\": { \"type\": \"perBuilding\", \"points\": 1 } },\n { \"id\": 18, \"name\": \"The Harbour\", \"cost\": 3, \"crowns\": 0, \"towers\": 0, \"endGameScoring\": { \"type\": \"perTerrain\", \"terrain\": \"sea\", \"points\": 2 } }\n]\n","import type {\n BuildingTile,\n EndGameScoring,\n EndGameScoringType,\n ImmediateBonus,\n ImmediateBonusType,\n} from \"@core/domain/types/building.js\";\nimport type { BuildingsRepository } from \"@core/portServerside/buildingsRepository.js\";\nimport buildingsJson from \"../datasources/buildings.json\" with { type: \"json\" };\n\nconst jsonBuildings = (): BuildingsRepository => {\n const buildings: BuildingTile[] = buildingsJson.map((b) => {\n const tile: BuildingTile = {\n id: b.id,\n name: b.name,\n cost: b.cost,\n crowns: b.crowns,\n towers: b.towers,\n };\n\n if (b.immediateBonus) {\n tile.immediateBonus = {\n type: b.immediateBonus.type as ImmediateBonusType,\n amount: b.immediateBonus.amount,\n } satisfies ImmediateBonus;\n }\n\n if (\"endGameScoring\" in b && b.endGameScoring) {\n tile.endGameScoring = {\n type: b.endGameScoring.type as EndGameScoringType,\n points: b.endGameScoring.points,\n ...(\"terrain\" in b.endGameScoring && {\n terrain: b.endGameScoring.terrain,\n }),\n } satisfies EndGameScoring;\n }\n\n return tile;\n });\n\n return {\n getAll: () => buildings,\n };\n};\n\nexport default jsonBuildings;\n","{\n \"Classic\": [\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 1\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 2\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 3\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 4\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 5\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 6\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 7\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 8\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 9\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 10\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 11\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 12\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 13\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 14\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 15\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 16\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 17\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 18\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 19\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 20\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 21\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 22\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 0\n },\n \"number\": 23\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 24\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 25\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 26\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 27\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 28\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 29\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 30\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 31\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 32\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 33\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 34\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 35\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 1\n },\n \"number\": 36\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 1\n },\n \"number\": 37\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 1\n },\n \"number\": 38\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 39\n },\n {\n \"left\": {\n \"type\": \"mine\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 40\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 2\n },\n \"number\": 41\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 2\n },\n \"number\": 42\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 2\n },\n \"number\": 43\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 2\n },\n \"number\": 44\n },\n {\n \"left\": {\n \"type\": \"mine\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 45\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 2\n },\n \"number\": 46\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 2\n },\n \"number\": 47\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 3\n },\n \"number\": 48\n }\n ],\n \"QueenDomino\": [\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 1\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 2\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 3\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 4\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 5\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 6\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 7\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 8\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 9\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 10\n },\n {\n \"left\": {\n \"type\": \"mine\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 0\n },\n \"number\": 11\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 12\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 13\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"number\": 14\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 15\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 16\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"number\": 17\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 18\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 19\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 20\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"number\": 21\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"number\": 22\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 23\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 24\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 25\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"number\": 26\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 27\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 1,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 28\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 0\n },\n \"number\": 29\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"number\": 30\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 1\n },\n \"number\": 31\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 1,\n \"hasConstructionSquare\": true\n },\n \"number\": 32\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 1\n },\n \"number\": 33\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 1,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 1\n },\n \"number\": 34\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 1\n },\n \"number\": 35\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 2,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 36\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"number\": 37\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 38\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 39\n },\n {\n \"left\": {\n \"type\": \"mine\",\n \"crowns\": 2,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 40\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 2\n },\n \"number\": 41\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 1,\n \"hasConstructionSquare\": true\n },\n \"number\": 42\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 1\n },\n \"number\": 43\n },\n {\n \"left\": {\n \"type\": \"mine\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 1\n },\n \"number\": 44\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 2\n },\n \"number\": 45\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 2,\n \"hasConstructionSquare\": true\n },\n \"number\": 46\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 3\n },\n \"number\": 47\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 3\n },\n \"number\": 48\n }\n ]\n}\n","import type { Domino, Ground, Tile } from \"@core/domain/types/domino.js\";\nimport type { GameMode } from \"@core/domain/types/mode.js\";\nimport type { DominoesRepository } from \"@core/portServerside/dominoesRepository.js\";\nimport dominoesJson from \"../datasources/dominoes.json\" with { type: \"json\" };\n\nconst mapTile = (raw: {\n type: string;\n crowns: number;\n hasConstructionSquare?: boolean;\n}): Tile => {\n const tile: Tile = {\n type: raw.type as Ground,\n crowns: raw.crowns,\n };\n if (raw.hasConstructionSquare) {\n tile.hasConstructionSquare = true;\n }\n return tile;\n};\n\nconst jsonDominoes = (): DominoesRepository => {\n const dominoes: Record<string, Domino[]> = {};\n\n for (const [key, value] of Object.entries(dominoesJson)) {\n const currentDominoes: Domino[] = [];\n value.forEach((domino) => {\n currentDominoes.push({\n left: mapTile(domino.left),\n right: mapTile(domino.right),\n number: domino.number,\n });\n });\n\n dominoes[key] = currentDominoes;\n }\n\n return {\n getForMode: (mode: GameMode) => {\n return dominoes[mode.name] || [];\n },\n };\n};\n\nexport default jsonDominoes;\n","[\n {\n \"name\": \"Classic\",\n \"description\": \"Original KingDomino rules\"\n },\n {\n \"name\": \"QueenDomino\",\n \"description\": \"Queendomino expansion with buildings, knights, coins, the Queen and the Dragon\"\n }\n]\n","import type { GameMode } from \"@core/domain/types/mode.js\";\nimport type { ModeRepository } from \"@core/portServerside/modeRepository.js\";\nimport modesJson from \"../datasources/modes.json\" with { type: \"json\" };\n\nconst jsonModes = (): ModeRepository => {\n const modes: GameMode[] = [];\n\n modesJson.forEach((mode) => {\n modes.push({\n name: mode.name,\n description: mode.description,\n });\n });\n\n return {\n getAvailables: () => {\n return modes;\n },\n };\n};\n\nexport default jsonModes;\n","{\n \"commun\": [\n {\n \"playersLimit\": 1,\n \"lordsPerPlayer\": 1,\n \"maxDominoes\": 48,\n \"dominoesPerTurn\": 4,\n \"maxTurns\": 12,\n \"maxKingdomSize\": 5\n },\n {\n \"playersLimit\": 2,\n \"lordsPerPlayer\": 2,\n \"maxDominoes\": 24,\n \"dominoesPerTurn\": 4,\n \"maxTurns\": 6,\n \"maxKingdomSize\": 5\n },\n {\n \"playersLimit\": 3,\n \"lordsPerPlayer\": 1,\n \"maxDominoes\": 48,\n \"dominoesPerTurn\": 4,\n \"maxTurns\": 12,\n \"maxKingdomSize\": 5\n },\n {\n \"playersLimit\": 4,\n \"lordsPerPlayer\": 1,\n \"maxDominoes\": 48,\n \"dominoesPerTurn\": 4,\n \"maxTurns\": 12,\n \"maxKingdomSize\": 5\n }\n ],\n \"extra\": [\n {\n \"name\": \"The middle Kingdom\",\n \"description\": \"Gain 10 additional points if your castle is in the middle of the kingdom.\",\n \"mode\": [\n { \"name\": \"Classic\", \"description\": \"King Domino classic mode\" },\n { \"name\": \"QueenDomino\", \"description\": \"Queendomino expansion with buildings, knights, coins, the Queen and the Dragon\" }\n ]\n },\n {\n \"name\": \"Harmony\",\n \"description\": \"Gain 5 additional points if your kingdom is complete (no discarded dominoes).\",\n \"mode\": [\n { \"name\": \"Classic\", \"description\": \"King Domino classic mode\" },\n { \"name\": \"QueenDomino\", \"description\": \"Queendomino expansion with buildings, knights, coins, the Queen and the Dragon\" }\n ]\n },\n {\n \"name\": \"The Mighty Duel\",\n \"description\": \"Use all 48 dominoes and build a 7x7 kingdom. For 2 players only.\",\n \"mode\": [\n { \"name\": \"Classic\", \"description\": \"King Domino classic mode\" },\n { \"name\": \"QueenDomino\", \"description\": \"Queendomino expansion with buildings, knights, coins, the Queen and the Dragon\" }\n ],\n \"playersLimit\": 2\n },\n {\n \"name\": \"Dynasty\",\n \"description\": \"Play 3 games in a row. The player with the highest total points wins.\",\n \"mode\": [\n { \"name\": \"Classic\", \"description\": \"King Domino classic mode\" },\n { \"name\": \"QueenDomino\", \"description\": \"Queendomino expansion with buildings, knights, coins, the Queen and the Dragon\" }\n ]\n }\n ]\n}\n","import type { Rules } from \"@core/domain/types/rule.js\";\nimport type { RuleRepository } from \"@core/portServerside/ruleRepository.js\";\nimport rulesJson from \"../datasources/rules.json\" with { type: \"json\" };\n\nconst jsonRules = (): RuleRepository => {\n const rules: Rules = {\n basic: {},\n extraRules: [],\n };\n\n const commonRules = rulesJson.commun;\n const extraRules = rulesJson.extra;\n\n commonRules.forEach((rule) => {\n rules.basic[rule.playersLimit] = {\n lords: rule.lordsPerPlayer,\n maxDominoes: rule.maxDominoes,\n dominoesPerTurn: rule.dominoesPerTurn,\n maxTurns: rule.maxTurns,\n maxKingdomSize: rule.maxKingdomSize,\n };\n });\n\n extraRules.forEach((rule) => {\n rules.extraRules.push({\n name: rule.name,\n description: rule.description,\n mode: rule.mode,\n ...(\"playersLimit\" in rule && { playersLimit: rule.playersLimit }),\n });\n });\n\n return {\n getAll: () => {\n return rules;\n },\n getAllExtra: () => {\n return rules.extraRules;\n },\n };\n};\n\nexport default jsonRules;\n","import type { ShuffleMethod } from \"@core/portServerside/shuffleMethod.js\";\n\nexport const shuffleMethod: ShuffleMethod = <T>(array: T[]) => {\n for (let i = array.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [array[i], array[j]] = [array[j] as T, array[i] as T];\n }\n return array;\n};\n","import type { UuidMethod } from \"@core/portServerside/uuidMethod.js\";\n\nexport const uuidMethod: UuidMethod = () => {\n return globalThis.crypto.randomUUID();\n};\n","/**\n * Error codes for domain-level errors.\n * These codes can be used for i18n and programmatic error handling.\n */\nexport const ErrorCode = {\n // Game flow errors\n INVALID_STEP: \"INVALID_STEP\",\n STEP_EXECUTION_FAILED: \"STEP_EXECUTION_FAILED\",\n ACTION_EXECUTION_FAILED: \"ACTION_EXECUTION_FAILED\",\n\n // Entity not found errors\n LORD_NOT_FOUND: \"LORD_NOT_FOUND\",\n PLAYER_NOT_FOUND: \"PLAYER_NOT_FOUND\",\n DOMINO_NOT_FOUND: \"DOMINO_NOT_FOUND\",\n MODE_NOT_FOUND: \"MODE_NOT_FOUND\",\n\n // Validation errors\n INVALID_PLAYER_COUNT: \"INVALID_PLAYER_COUNT\",\n INVALID_PLAYER_NAME: \"INVALID_PLAYER_NAME\",\n INVALID_PLACEMENT: \"INVALID_PLACEMENT\",\n PLACEMENT_NOT_EMPTY: \"PLACEMENT_NOT_EMPTY\",\n PLACEMENT_NOT_ADJACENT: \"PLACEMENT_NOT_ADJACENT\",\n PLACEMENT_INVALID_TERRAIN: \"PLACEMENT_INVALID_TERRAIN\",\n PLACEMENT_OUT_OF_BOUNDS: \"PLACEMENT_OUT_OF_BOUNDS\",\n PLACEMENT_EXCEEDS_KINGDOM_SIZE: \"PLACEMENT_EXCEEDS_KINGDOM_SIZE\",\n\n // Action errors\n NOT_YOUR_TURN: \"NOT_YOUR_TURN\",\n CANNOT_PICK: \"CANNOT_PICK\",\n CANNOT_PLACE: \"CANNOT_PLACE\",\n DOMINO_ALREADY_PICKED: \"DOMINO_ALREADY_PICKED\",\n\n // History errors\n UNDO_UNAVAILABLE: \"UNDO_UNAVAILABLE\",\n REDO_UNAVAILABLE: \"REDO_UNAVAILABLE\",\n\n // Queendomino errors\n CANNOT_PLACE_KNIGHT: \"CANNOT_PLACE_KNIGHT\",\n MAX_KNIGHTS_REACHED: \"MAX_KNIGHTS_REACHED\",\n KNIGHT_TERRITORY_OCCUPIED: \"KNIGHT_TERRITORY_OCCUPIED\",\n CANNOT_AFFORD_BUILDING: \"CANNOT_AFFORD_BUILDING\",\n NO_CONSTRUCTION_SQUARE: \"NO_CONSTRUCTION_SQUARE\",\n DRAGON_UNAVAILABLE: \"DRAGON_UNAVAILABLE\",\n QUEEN_HOLDER_CANNOT_USE_DRAGON: \"QUEEN_HOLDER_CANNOT_USE_DRAGON\",\n BUILDING_NOT_FOUND: \"BUILDING_NOT_FOUND\",\n INVALID_OPTIONAL_ACTION: \"INVALID_OPTIONAL_ACTION\",\n} as const;\n\nexport type ErrorCodeType = (typeof ErrorCode)[keyof typeof ErrorCode];\n\n/**\n * Structured domain error with code and context.\n */\nexport interface DomainError {\n /** Error code for programmatic handling */\n code: ErrorCodeType;\n /** Human-readable error message */\n message: string;\n /** Optional context data for debugging */\n context?: Record<string, unknown>;\n}\n\n/**\n * Creates a domain error object.\n */\nexport const createDomainError = (\n code: ErrorCodeType,\n message: string,\n context?: Record<string, unknown>,\n): DomainError => ({\n code,\n message,\n context,\n});\n\n/**\n * Base class for domain errors thrown by handlers.\n */\nexport class DomainException extends Error {\n public readonly code: ErrorCodeType;\n public readonly context?: Record<string, unknown>;\n\n constructor(error: DomainError) {\n super(error.message);\n this.name = \"DomainException\";\n this.code = error.code;\n this.context = error.context;\n }\n}\n\n/**\n * Error thrown when the game is in an invalid step for the requested action.\n */\nexport class InvalidStepError extends DomainException {\n constructor(message: string, context?: Record<string, unknown>) {\n super({\n code: ErrorCode.INVALID_STEP,\n message,\n context,\n });\n this.name = \"InvalidStepError\";\n }\n}\n\n/**\n * Error thrown when a step execution fails.\n */\nexport class StepExecutionError extends DomainException {\n constructor(\n message: string,\n code: ErrorCodeType = ErrorCode.STEP_EXECUTION_FAILED,\n context?: Record<string, unknown>,\n ) {\n super({\n code,\n message,\n context,\n });\n this.name = \"StepExecutionError\";\n }\n}\n\n/**\n * Error thrown when an action execution fails.\n */\nexport class ActionExecutionError extends DomainException {\n constructor(\n message: string,\n code: ErrorCodeType = ErrorCode.ACTION_EXECUTION_FAILED,\n context?: Record<string, unknown>,\n ) {\n super({\n code,\n message,\n context,\n });\n this.name = \"ActionExecutionError\";\n }\n}\n\n/**\n * Error thrown when a required entity is not found.\n */\nexport class NotFoundError extends DomainException {\n constructor(\n message: string,\n code: ErrorCodeType = ErrorCode.LORD_NOT_FOUND,\n context?: Record<string, unknown>,\n ) {\n super({\n code,\n message,\n context,\n });\n this.name = \"NotFoundError\";\n }\n}\n\n/**\n * Error thrown when validation fails.\n */\nexport class ValidationError extends DomainException {\n constructor(\n message: string,\n code: ErrorCodeType,\n context?: Record<string, unknown>,\n ) {\n super({\n code,\n message,\n context,\n });\n this.name = \"ValidationError\";\n }\n}\n\n/**\n * Error thrown when undo is requested but no previous state exists.\n */\nexport class UndoError extends DomainException {\n constructor(message = \"No state to undo\", context?: Record<string, unknown>) {\n super({\n code: ErrorCode.UNDO_UNAVAILABLE,\n message,\n context,\n });\n this.name = \"UndoError\";\n }\n}\n\n/**\n * Error thrown when redo is requested but no future state exists.\n */\nexport class RedoError extends DomainException {\n constructor(message = \"No state to redo\", context?: Record<string, unknown>) {\n super({\n code: ErrorCode.REDO_UNAVAILABLE,\n message,\n context,\n });\n this.name = \"RedoError\";\n }\n}\n","import {\n ErrorCode,\n type ErrorCodeType,\n} from \"@core/domain/errors/domainErrors.js\";\n\n/**\n * Translation keys for internationalization support.\n * Use these keys instead of hardcoded strings for translatable content.\n */\nexport const TranslationKey = {\n // Error messages\n ERROR_INVALID_STEP: \"error.invalidStep\",\n ERROR_STEP_EXECUTION_FAILED: \"error.stepExecutionFailed\",\n ERROR_ACTION_EXECUTION_FAILED: \"error.actionExecutionFailed\",\n ERROR_LORD_NOT_FOUND: \"error.lordNotFound\",\n ERROR_PLAYER_NOT_FOUND: \"error.playerNotFound\",\n ERROR_DOMINO_NOT_FOUND: \"error.dominoNotFound\",\n ERROR_MODE_NOT_FOUND: \"error.modeNotFound\",\n ERROR_INVALID_PLACEMENT: \"error.invalidPlacement\",\n ERROR_PLACEMENT_NOT_EMPTY: \"error.placementNotEmpty\",\n ERROR_PLACEMENT_NOT_ADJACENT: \"error.placementNotAdjacent\",\n ERROR_PLACEMENT_INVALID_TERRAIN: \"error.placementInvalidTerrain\",\n ERROR_PLACEMENT_OUT_OF_BOUNDS: \"error.placementOutOfBounds\",\n ERROR_PLACEMENT_EXCEEDS_KINGDOM_SIZE: \"error.placementExceedsKingdomSize\",\n ERROR_NOT_YOUR_TURN: \"error.notYourTurn\",\n ERROR_CANNOT_PICK: \"error.cannotPick\",\n ERROR_CANNOT_PLACE: \"error.cannotPlace\",\n ERROR_DOMINO_ALREADY_PICKED: \"error.dominoAlreadyPicked\",\n ERROR_INVALID_PLAYER_COUNT: \"error.invalidPlayerCount\",\n ERROR_INVALID_PLAYER_NAME: \"error.invalidPlayerName\",\n ERROR_UNDO_UNAVAILABLE: \"error.undoUnavailable\",\n ERROR_REDO_UNAVAILABLE: \"error.redoUnavailable\",\n\n // Game mode names\n MODE_CLASSIC: \"mode.classic\",\n\n // Extra rule names\n RULE_MIDDLE_KINGDOM: \"rule.middleKingdom\",\n RULE_HARMONY: \"rule.harmony\",\n\n // Ground types\n GROUND_CASTLE: \"ground.castle\",\n GROUND_WHEAT: \"ground.wheat\",\n GROUND_FOREST: \"ground.forest\",\n GROUND_SEA: \"ground.sea\",\n GROUND_PLAIN: \"ground.plain\",\n GROUND_SWAMP: \"ground.swamp\",\n GROUND_MINE: \"ground.mine\",\n\n // Game phases\n PHASE_ADD_PLAYERS: \"phase.addPlayers\",\n PHASE_OPTIONS: \"phase.options\",\n PHASE_START: \"phase.start\",\n PHASE_RESULT: \"phase.result\",\n\n // Actions\n ACTION_PICK_DOMINO: \"action.pickDomino\",\n ACTION_PLACE_DOMINO: \"action.placeDomino\",\n ACTION_PASS: \"action.pass\",\n\n // Queendomino errors\n ERROR_CANNOT_PLACE_KNIGHT: \"error.cannotPlaceKnight\",\n ERROR_MAX_KNIGHTS_REACHED: \"error.maxKnightsReached\",\n ERROR_KNIGHT_TERRITORY_OCCUPIED: \"error.knightTerritoryOccupied\",\n ERROR_CANNOT_AFFORD_BUILDING: \"error.cannotAffordBuilding\",\n ERROR_NO_CONSTRUCTION_SQUARE: \"error.noConstructionSquare\",\n ERROR_DRAGON_UNAVAILABLE: \"error.dragonUnavailable\",\n ERROR_QUEEN_HOLDER_CANNOT_USE_DRAGON: \"error.queenHolderCannotUseDragon\",\n ERROR_BUILDING_NOT_FOUND: \"error.buildingNotFound\",\n ERROR_INVALID_OPTIONAL_ACTION: \"error.invalidOptionalAction\",\n} as const;\n\nexport type TranslationKeyType =\n (typeof TranslationKey)[keyof typeof TranslationKey];\n\n/**\n * Default English translations.\n */\nexport const defaultTranslations: Record<TranslationKeyType, string> = {\n // Error messages\n [TranslationKey.ERROR_INVALID_STEP]: \"Invalid game step\",\n [TranslationKey.ERROR_STEP_EXECUTION_FAILED]: \"Step execution failed\",\n [TranslationKey.ERROR_ACTION_EXECUTION_FAILED]: \"Action execution failed\",\n [TranslationKey.ERROR_LORD_NOT_FOUND]: \"Lord not found\",\n [TranslationKey.ERROR_PLAYER_NOT_FOUND]: \"Player not found\",\n [TranslationKey.ERROR_DOMINO_NOT_FOUND]: \"Domino not found\",\n [TranslationKey.ERROR_MODE_NOT_FOUND]: \"Game mode not found\",\n [TranslationKey.ERROR_INVALID_PLACEMENT]: \"Invalid placement\",\n [TranslationKey.ERROR_PLACEMENT_NOT_EMPTY]: \"Position is not empty\",\n [TranslationKey.ERROR_PLACEMENT_NOT_ADJACENT]:\n \"Not adjacent to existing tiles\",\n [TranslationKey.ERROR_PLACEMENT_INVALID_TERRAIN]:\n \"Terrain type does not match\",\n [TranslationKey.ERROR_PLACEMENT_OUT_OF_BOUNDS]: \"Placement is out of bounds\",\n [TranslationKey.ERROR_PLACEMENT_EXCEEDS_KINGDOM_SIZE]:\n \"Placement exceeds kingdom size\",\n [TranslationKey.ERROR_NOT_YOUR_TURN]: \"It is not your turn\",\n [TranslationKey.ERROR_CANNOT_PICK]: \"Cannot pick a domino now\",\n [TranslationKey.ERROR_CANNOT_PLACE]: \"Cannot place a domino now\",\n [TranslationKey.ERROR_DOMINO_ALREADY_PICKED]:\n \"Domino has already been picked\",\n [TranslationKey.ERROR_INVALID_PLAYER_COUNT]:\n \"Invalid number of players (1-4 required)\",\n [TranslationKey.ERROR_INVALID_PLAYER_NAME]:\n \"Player name must be at least 3 characters\",\n [TranslationKey.ERROR_UNDO_UNAVAILABLE]: \"No state to undo\",\n [TranslationKey.ERROR_REDO_UNAVAILABLE]: \"No state to redo\",\n\n // Game mode names\n [TranslationKey.MODE_CLASSIC]: \"Classic\",\n\n // Extra rule names\n [TranslationKey.RULE_MIDDLE_KINGDOM]: \"The Middle Kingdom\",\n [TranslationKey.RULE_HARMONY]: \"Harmony\",\n\n // Ground types\n [TranslationKey.GROUND_CASTLE]: \"Castle\",\n [TranslationKey.GROUND_WHEAT]: \"Wheat Field\",\n [TranslationKey.GROUND_FOREST]: \"Forest\",\n [TranslationKey.GROUND_SEA]: \"Sea\",\n [TranslationKey.GROUND_PLAIN]: \"Plain\",\n [TranslationKey.GROUND_SWAMP]: \"Swamp\",\n [TranslationKey.GROUND_MINE]: \"Mine\",\n\n // Game phases\n [TranslationKey.PHASE_ADD_PLAYERS]: \"Add Players\",\n [TranslationKey.PHASE_OPTIONS]: \"Game Options\",\n [TranslationKey.PHASE_START]: \"Start Game\",\n [TranslationKey.PHASE_RESULT]: \"Game Results\",\n\n // Actions\n [TranslationKey.ACTION_PICK_DOMINO]: \"Pick Domino\",\n [TranslationKey.ACTION_PLACE_DOMINO]: \"Place Domino\",\n [TranslationKey.ACTION_PASS]: \"Pass\",\n\n // Queendomino errors\n [TranslationKey.ERROR_CANNOT_PLACE_KNIGHT]: \"Cannot place knight here\",\n [TranslationKey.ERROR_MAX_KNIGHTS_REACHED]: \"Maximum number of knights reached (3)\",\n [TranslationKey.ERROR_KNIGHT_TERRITORY_OCCUPIED]: \"This territory already has a knight\",\n [TranslationKey.ERROR_CANNOT_AFFORD_BUILDING]: \"Not enough coins to purchase this building\",\n [TranslationKey.ERROR_NO_CONSTRUCTION_SQUARE]: \"No open construction square available\",\n [TranslationKey.ERROR_DRAGON_UNAVAILABLE]: \"The Dragon is not available this round\",\n [TranslationKey.ERROR_QUEEN_HOLDER_CANNOT_USE_DRAGON]: \"The Queen holder cannot use the Dragon\",\n [TranslationKey.ERROR_BUILDING_NOT_FOUND]: \"Building not found on the Builders Board\",\n [TranslationKey.ERROR_INVALID_OPTIONAL_ACTION]: \"Invalid optional action for this game state\",\n};\n\n/**\n * Maps ErrorCode values to their corresponding TranslationKey values.\n * Used by handlers to translate error codes into localized messages.\n */\nexport const errorCodeToTranslationKey: Record<\n ErrorCodeType,\n TranslationKeyType\n> = {\n [ErrorCode.INVALID_STEP]: TranslationKey.ERROR_INVALID_STEP,\n [ErrorCode.STEP_EXECUTION_FAILED]: TranslationKey.ERROR_STEP_EXECUTION_FAILED,\n [ErrorCode.ACTION_EXECUTION_FAILED]:\n TranslationKey.ERROR_ACTION_EXECUTION_FAILED,\n [ErrorCode.LORD_NOT_FOUND]: TranslationKey.ERROR_LORD_NOT_FOUND,\n [ErrorCode.PLAYER_NOT_FOUND]: TranslationKey.ERROR_PLAYER_NOT_FOUND,\n [ErrorCode.DOMINO_NOT_FOUND]: TranslationKey.ERROR_DOMINO_NOT_FOUND,\n [ErrorCode.MODE_NOT_FOUND]: TranslationKey.ERROR_MODE_NOT_FOUND,\n [ErrorCode.INVALID_PLAYER_COUNT]: TranslationKey.ERROR_INVALID_PLAYER_COUNT,\n [ErrorCode.INVALID_PLAYER_NAME]: TranslationKey.ERROR_INVALID_PLAYER_NAME,\n [ErrorCode.INVALID_PLACEMENT]: TranslationKey.ERROR_INVALID_PLACEMENT,\n [ErrorCode.PLACEMENT_NOT_EMPTY]: TranslationKey.ERROR_PLACEMENT_NOT_EMPTY,\n [ErrorCode.PLACEMENT_NOT_ADJACENT]:\n TranslationKey.ERROR_PLACEMENT_NOT_ADJACENT,\n [ErrorCode.PLACEMENT_INVALID_TERRAIN]:\n TranslationKey.ERROR_PLACEMENT_INVALID_TERRAIN,\n [ErrorCode.PLACEMENT_OUT_OF_BOUNDS]:\n TranslationKey.ERROR_PLACEMENT_OUT_OF_BOUNDS,\n [ErrorCode.PLACEMENT_EXCEEDS_KINGDOM_SIZE]:\n TranslationKey.ERROR_PLACEMENT_EXCEEDS_KINGDOM_SIZE,\n [ErrorCode.NOT_YOUR_TURN]: TranslationKey.ERROR_NOT_YOUR_TURN,\n [ErrorCode.CANNOT_PICK]: TranslationKey.ERROR_CANNOT_PICK,\n [ErrorCode.CANNOT_PLACE]: TranslationKey.ERROR_CANNOT_PLACE,\n [ErrorCode.DOMINO_ALREADY_PICKED]: TranslationKey.ERROR_DOMINO_ALREADY_PICKED,\n [ErrorCode.UNDO_UNAVAILABLE]: TranslationKey.ERROR_UNDO_UNAVAILABLE,\n [ErrorCode.REDO_UNAVAILABLE]: TranslationKey.ERROR_REDO_UNAVAILABLE,\n [ErrorCode.CANNOT_PLACE_KNIGHT]: TranslationKey.ERROR_CANNOT_PLACE_KNIGHT,\n [ErrorCode.MAX_KNIGHTS_REACHED]: TranslationKey.ERROR_MAX_KNIGHTS_REACHED,\n [ErrorCode.KNIGHT_TERRITORY_OCCUPIED]: TranslationKey.ERROR_KNIGHT_TERRITORY_OCCUPIED,\n [ErrorCode.CANNOT_AFFORD_BUILDING]: TranslationKey.ERROR_CANNOT_AFFORD_BUILDING,\n [ErrorCode.NO_CONSTRUCTION_SQUARE]: TranslationKey.ERROR_NO_CONSTRUCTION_SQUARE,\n [ErrorCode.DRAGON_UNAVAILABLE]: TranslationKey.ERROR_DRAGON_UNAVAILABLE,\n [ErrorCode.QUEEN_HOLDER_CANNOT_USE_DRAGON]: TranslationKey.ERROR_QUEEN_HOLDER_CANNOT_USE_DRAGON,\n [ErrorCode.BUILDING_NOT_FOUND]: TranslationKey.ERROR_BUILDING_NOT_FOUND,\n [ErrorCode.INVALID_OPTIONAL_ACTION]: TranslationKey.ERROR_INVALID_OPTIONAL_ACTION,\n};\n\n/**\n * Translates an error code to a localized message.\n * Convenience function combining errorCodeToTranslationKey lookup and translation.\n */\nexport const translateErrorCode = (\n translator: Translator,\n code: ErrorCodeType,\n params?: Record<string, string | number>,\n): string => {\n const key = errorCodeToTranslationKey[code];\n return translator.t(key, params);\n};\n\n/**\n * Translator interface for custom translations.\n */\nexport interface Translator {\n /**\n * Translate a key to the current language.\n * @param key - The translation key\n * @param params - Optional parameters for interpolation\n * @returns The translated string\n */\n t(key: TranslationKeyType, params?: Record<string, string | number>): string;\n}\n\n/**\n * Creates a translator with the provided translations.\n * Falls back to default English translations for missing keys.\n *\n * @param translations - Custom translations to use\n * @returns A translator instance\n */\nexport const createTranslator = (\n translations: Partial<Record<TranslationKeyType, string>> = {},\n): Translator => {\n const mergedTranslations = { ...defaultTranslations, ...translations };\n\n return {\n t(\n key: TranslationKeyType,\n params?: Record<string, string | number>,\n ): string {\n let text = mergedTranslations[key] || key;\n\n // Simple parameter interpolation: {{param}}\n if (params) {\n for (const [paramKey, value] of Object.entries(params)) {\n text = text.replace(\n new RegExp(`\\\\{\\\\{${paramKey}\\\\}\\\\}`, \"g\"),\n String(value),\n );\n }\n }\n\n return text;\n },\n };\n};\n\n/**\n * Default translator using English translations.\n */\nexport const defaultTranslator: Translator = createTranslator();\n","export type Result<T> = Ok<T> | Err;\n\nexport interface Ok<T> {\n readonly tag: \"Ok\";\n readonly value: T;\n}\n\nexport interface Err {\n readonly tag: \"Err\";\n readonly error: string;\n}\n\nexport const ok = <T>(value: T): Ok<T> => ({ tag: \"Ok\", value });\nexport const err = (error: string): Err => ({ tag: \"Err\", error });\n\nexport const isOk = <T>(result: Result<T>): result is Ok<T> =>\n result.tag === \"Ok\";\nexport const isErr = <T>(result: Result<T>): result is Err =>\n result.tag === \"Err\";\n\nexport const unwrap = <T>(result: Ok<T> | Err): T => {\n if (result.tag === \"Err\") {\n throw new Error(result.error);\n }\n return result.value;\n};\n","import type { AddExtraRulesCommand } from \"@application/commands/addExtraRulesCommand.js\";\nimport {\n ErrorCode,\n type ErrorCodeType,\n InvalidStepError,\n StepExecutionError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport {\n type GameWithNextStep,\n isGameWithNextStep,\n} from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { AddExtraRulesUseCase } from \"@core/useCases/addExtraRules.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype AddExtraRulesHandler = (command: AddExtraRulesCommand) => GameWithNextStep;\n\nexport const addExtraRulesHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: AddExtraRulesUseCase,\n ): AddExtraRulesHandler =>\n (command: AddExtraRulesCommand) => {\n const { game, extraRules } = command;\n logger.info(`Adding extra rules to game: ${game.id}`);\n logger.info(`Extra rules: ${extraRules}`);\n\n if (!isGameWithNextStep(game)) {\n logger.error(\n `Invalid game, required nextAction type: 'step' but got: ${game.nextAction.type}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n { expected: \"step\", actual: game.nextAction.type, gameId: game.id },\n );\n }\n\n if (game.nextAction.step !== \"options\") {\n logger.error(\n `Required game with options step but got: ${game.nextAction.step}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n { expected: \"options\", actual: game.nextAction.step, gameId: game.id },\n );\n }\n\n const result = useCase(game, extraRules);\n\n if (isErr(result)) {\n logger.error(`Error adding extra rules: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new StepExecutionError(translateErrorCode(translator, code), code, {\n gameId: game.id,\n extraRules: command.extraRules,\n });\n }\n\n logger.info(`Extra rules added to game: ${game.id}`);\n return result.value;\n };\n","import type { AddPlayersCommand } from \"@application/commands/addPlayersCommand.js\";\nimport {\n ErrorCode,\n type ErrorCodeType,\n InvalidStepError,\n StepExecutionError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport {\n type GameWithNextStep,\n isGameWithNextStep,\n} from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { AddPlayersUseCase } from \"@core/useCases/addPlayers.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype AddPlayersHandler = (command: AddPlayersCommand) => GameWithNextStep;\n\nexport const addPlayersHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: AddPlayersUseCase,\n ): AddPlayersHandler =>\n (command: AddPlayersCommand) => {\n const { game, players } = command;\n\n logger.info(`Adding players to game: ${game.id}`);\n\n if (!isGameWithNextStep(game)) {\n logger.error(\n `Invalid game, required nextAction type: 'step' but got: ${game.nextAction.type}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n { expected: \"step\", actual: game.nextAction.type, gameId: game.id },\n );\n }\n\n if (game.nextAction.step !== \"addPlayers\") {\n logger.error(\n `Required game with addPlayers step but got: ${game.nextAction.step}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n {\n expected: \"addPlayers\",\n actual: game.nextAction.step,\n gameId: game.id,\n },\n );\n }\n\n const result = useCase(game, players);\n\n if (isErr(result)) {\n logger.error(`Error adding players: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new StepExecutionError(translateErrorCode(translator, code), code, {\n gameId: game.id,\n players: command.players,\n });\n }\n\n logger.info(`Players added to game: ${game.id}`);\n return result.value;\n };\n","import type { CalculateScoreCommand } from \"@application/commands/calculateScoreCommand.js\";\nimport type { Score } from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { CalculateScoreUseCase } from \"@core/useCases/calculateScore.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype CalculateScoreHandler = (command: CalculateScoreCommand) => Score;\n\nexport const calculateScoreHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: CalculateScoreUseCase,\n ): CalculateScoreHandler =>\n (command) => {\n const { kingdom } = command;\n logger.info(`Calculating score for kingdom`);\n const result = useCase(kingdom);\n\n if (isErr(result)) {\n logger.error(`Error calculating score: ${result.error}`);\n throw new Error(result.error);\n }\n\n logger.info(`Score calculated: ${result.value}`);\n return result.value;\n };\n","import type { CanPlaceDominoCommand } from \"@application/commands/canPlaceDominoCommand.js\";\nimport type { Domino, Kingdom } from \"@core/domain/types/index.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\n\ntype CanPlaceDominoUseCase = (\n kingdom: Kingdom,\n domino: Domino,\n maxKingdomSize?: number,\n) => boolean;\n\ntype CanPlaceDominoHandler = (command: CanPlaceDominoCommand) => boolean;\n\n/**\n * Creates a handler for checking if a domino can be placed.\n */\nexport const canPlaceDominoHandler = (\n logger: Logger,\n translator: Translator,\n useCase: CanPlaceDominoUseCase,\n): CanPlaceDominoHandler => {\n return (command) => {\n logger.info(`Checking if domino ${command.domino.number} can be placed`);\n const canPlace = useCase(\n command.kingdom,\n command.domino,\n command.maxKingdomSize,\n );\n logger.info(`Can place domino: ${canPlace}`);\n return canPlace;\n };\n};\n","import type { ChooseDominoCommand } from \"@application/commands/chooseDominoCommand.js\";\nimport {\n ActionExecutionError,\n ErrorCode,\n type ErrorCodeType,\n InvalidStepError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport {\n type GameWithNextAction,\n isGameWithNextAction,\n} from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { ChooseDominoUseCase } from \"@core/useCases/chooseDomino.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype ChooseDominoHandler = (command: ChooseDominoCommand) => GameWithNextAction;\n\nexport const chooseDominoHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: ChooseDominoUseCase,\n ): ChooseDominoHandler =>\n (command: ChooseDominoCommand) => {\n const { game, lordId, dominoPick } = command;\n logger.info(\n `Choosing domino: ${dominoPick} for lord: ${lordId} in game: ${game.id}`,\n );\n\n if (!isGameWithNextAction(game)) {\n logger.error(\n `Invalid game, required nextAction type: 'action' but got: ${game.nextAction.type}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n { expected: \"action\", actual: game.nextAction.type, gameId: game.id },\n );\n }\n\n if (game.nextAction.nextAction !== \"pickDomino\") {\n logger.error(\n `Required game with pickDomino action but got: ${game.nextAction.nextAction}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n {\n expected: \"pickDomino\",\n actual: game.nextAction.nextAction,\n gameId: game.id,\n },\n );\n }\n\n const result = useCase(game, lordId, dominoPick);\n\n if (isErr(result)) {\n logger.error(`Error choosing domino: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new ActionExecutionError(\n translateErrorCode(translator, code),\n code,\n {\n gameId: game.id,\n lordId: command.lordId,\n dominoPick: command.dominoPick,\n },\n );\n }\n\n logger.info(\n `Domino chosen: ${dominoPick} for lord: ${lordId} in game: ${game.id}`,\n );\n return result.value;\n };\n","import type { CreateGameCommand } from \"@application/commands/createGameCommand.js\";\nimport {\n type ErrorCodeType,\n StepExecutionError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport type { GameWithNextStep } from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { CreateGameUseCase } from \"@core/useCases/createGame.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype CreateGameHandler = (command: CreateGameCommand) => GameWithNextStep;\n\nexport const createGameHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: CreateGameUseCase,\n ): CreateGameHandler =>\n (command: CreateGameCommand) => {\n logger.info(`Creating game with mode: ${command.mode}`);\n const result = useCase(command.mode, command.seed);\n\n if (isErr(result)) {\n logger.error(`Error creating game: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new StepExecutionError(translateErrorCode(translator, code), code, {\n mode: command.mode,\n });\n }\n\n logger.info(`Game created: ${result.value.id}`);\n return result.value;\n };\n","import type { DiscardDominoCommand } from \"@application/commands/discardDominoCommand.js\";\nimport {\n ActionExecutionError,\n ErrorCode,\n type ErrorCodeType,\n InvalidStepError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport {\n type GameState,\n isGameWithNextAction,\n} from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { DiscardDominoUseCase } from \"@core/useCases/discardDomino.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype DiscardDominoHandler = (command: DiscardDominoCommand) => GameState;\n\nexport const discardDominoHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: DiscardDominoUseCase,\n ): DiscardDominoHandler =>\n (command: DiscardDominoCommand) => {\n const { game, lordId } = command;\n logger.info(`Discarding domino for lord: ${lordId} in game: ${game.id}`);\n\n if (!isGameWithNextAction(game)) {\n logger.error(\n `Invalid game, required nextAction type: 'action' but got: ${game.nextAction.type}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n { expected: \"action\", actual: game.nextAction.type, gameId: game.id },\n );\n }\n\n if (game.nextAction.nextAction !== \"placeDomino\") {\n logger.error(\n `Required game with placeDomino action but got: ${game.nextAction.nextAction}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n {\n expected: \"placeDomino\",\n actual: game.nextAction.nextAction,\n gameId: game.id,\n },\n );\n }\n\n const result = useCase(game, lordId);\n\n if (isErr(result)) {\n logger.error(`Error discarding domino: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new ActionExecutionError(\n translateErrorCode(translator, code),\n code,\n { gameId: game.id, lordId: command.lordId },\n );\n }\n\n if (isGameWithNextAction(result.value)) {\n logger.info(`Domino discarded: ${lordId} in game: ${game.id}`);\n return result.value;\n }\n\n logger.info(`Domino discarded: ${lordId} in game: ${game.id}`);\n return result.value;\n };\n","import type { GetDynastyResultCommand } from \"@application/commands/getDynastyResultCommand.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type {\n DynastyResult,\n GetDynastyResultUseCase,\n} from \"@core/useCases/getDynastyResult.js\";\n\ntype GetDynastyResultHandler = (\n command: GetDynastyResultCommand,\n) => DynastyResult[];\n\nexport const getDynastyResultHandler = (\n logger: Logger,\n translator: Translator,\n useCase: GetDynastyResultUseCase,\n): GetDynastyResultHandler => {\n return (command) => {\n logger.info(\n `Calculating dynasty results for ${command.games.length} games`,\n );\n const results = useCase(command.games);\n logger.info(`Dynasty results calculated`);\n return results;\n };\n};\n","import type { GetExtraRulesCommand } from \"@application/commands/getExtraRulesCommand.js\";\nimport {\n ErrorCode,\n type ErrorCodeType,\n NotFoundError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport type { ExtraRule } from \"@core/domain/types/rule.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { GetExtraRulesUseCase } from \"@core/useCases/getExtraRules.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype GetExtraRulesHandler = (command: GetExtraRulesCommand) => ExtraRule[];\n\nexport const getExtraRulesHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: GetExtraRulesUseCase,\n ): GetExtraRulesHandler =>\n (command: GetExtraRulesCommand) => {\n const { mode, players } = command;\n logger.info(\n `Getting extra rules for mode: ${mode} and players: ${players}`,\n );\n const result = useCase(mode, players);\n\n if (isErr(result)) {\n logger.error(`Error getting extra rules: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new NotFoundError(translateErrorCode(translator, code), code, {\n mode: command.mode,\n });\n }\n\n logger.info(`Extra rules retrieved: ${result.value}`);\n return result.value;\n };\n","import type { GetModesCommand } from \"@application/commands/getModesCommand.js\";\nimport {\n ErrorCode,\n type ErrorCodeType,\n NotFoundError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport type { GameMode } from \"@core/domain/types/mode.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { GetModesUseCase } from \"@core/useCases/getModes.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype GetModesHandler = (command: GetModesCommand) => GameMode[];\n\nexport const getModesHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: GetModesUseCase,\n ): GetModesHandler =>\n (_command: GetModesCommand) => {\n logger.info(\"Getting modes\");\n const result = useCase();\n\n if (isErr(result)) {\n logger.error(`Error getting modes: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new NotFoundError(translateErrorCode(translator, code), code);\n }\n\n logger.info(`Modes retrieved: ${result.value}`);\n return result.value;\n };\n","import type { GetResultCommand } from \"@application/commands/getResultCommand.js\";\nimport {\n ErrorCode,\n type ErrorCodeType,\n InvalidStepError,\n NotFoundError,\n StepExecutionError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport {\n type GameWithResults,\n isGameWithNextStep,\n type ScoreResult,\n} from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { CalculateScoreUseCase } from \"@core/useCases/calculateScore.js\";\nimport type { GetResultUseCase } from \"@core/useCases/getResult.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype GetResultHandler = (command: GetResultCommand) => GameWithResults;\n\nexport const getResultHandler =\n (\n logger: Logger,\n translator: Translator,\n useCases: {\n getResultUseCase: GetResultUseCase;\n calculateScoreUseCase: CalculateScoreUseCase;\n },\n ): GetResultHandler =>\n (command: GetResultCommand) => {\n const { getResultUseCase, calculateScoreUseCase } = useCases;\n const { game } = command;\n logger.info(`Getting result for game: ${game.id}`);\n\n if (!isGameWithNextStep(game)) {\n logger.error(\n `Invalid game, required nextAction type: 'step' but got: ${game.nextAction.type}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n { expected: \"step\", actual: game.nextAction.type, gameId: game.id },\n );\n }\n\n if (game.nextAction.step !== \"result\") {\n logger.error(\n `Required game with result step but got: ${game.nextAction.step}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n { expected: \"result\", actual: game.nextAction.step, gameId: game.id },\n );\n }\n\n const { players } = game;\n\n const scoreResult: ScoreResult[] = players.map((player) => {\n const { kingdom } = player;\n const result = calculateScoreUseCase(kingdom);\n\n if (isErr(result)) {\n logger.error(`Error when calculating score: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new StepExecutionError(\n translateErrorCode(translator, code),\n code,\n {\n gameId: game.id,\n },\n );\n }\n\n return {\n playerId: player.id,\n playerName: player.name,\n details: {\n ...result.value,\n },\n };\n });\n\n const result = getResultUseCase(game, scoreResult);\n\n if (isErr(result)) {\n logger.error(`Error getting result: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new NotFoundError(translateErrorCode(translator, code), code, {\n gameId: game.id,\n });\n }\n\n logger.info(`Result retrieved for game: ${game.id}`);\n return result.value;\n };\n","import type { GetValidPlacementsCommand } from \"@application/commands/getValidPlacementsCommand.js\";\nimport type { Domino, Kingdom } from \"@core/domain/types/index.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { ValidPlacement } from \"@core/useCases/getValidPlacements.js\";\n\ntype GetValidPlacementsUseCase = (\n kingdom: Kingdom,\n domino: Domino,\n maxKingdomSize?: number,\n) => ValidPlacement[];\n\ntype GetValidPlacementsHandler = (\n command: GetValidPlacementsCommand,\n) => ValidPlacement[];\n\n/**\n * Creates a handler for getting valid placements.\n */\nexport const getValidPlacementsHandler = (\n logger: Logger,\n translator: Translator,\n useCase: GetValidPlacementsUseCase,\n): GetValidPlacementsHandler => {\n return (command) => {\n logger.info(\n `Getting valid placements for domino: ${command.domino.number}`,\n );\n const placements = useCase(\n command.kingdom,\n command.domino,\n command.maxKingdomSize,\n );\n logger.info(`Found ${placements.length} valid placements`);\n return placements;\n };\n};\n","import type { PlaceDominoCommand } from \"@application/commands/placeDominoCommand.js\";\nimport {\n ActionExecutionError,\n ErrorCode,\n type ErrorCodeType,\n InvalidStepError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport {\n type GameState,\n isGameWithNextAction,\n} from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { PlaceDominoUseCase } from \"@core/useCases/placeDomino.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype PlaceDominoHandler = (command: PlaceDominoCommand) => GameState;\n\nexport const placeDominoHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: PlaceDominoUseCase,\n ): PlaceDominoHandler =>\n (command: PlaceDominoCommand) => {\n const { game, lordId, position, rotation } = command;\n logger.info(\n `Placing domino: ${lordId} in position: ${JSON.stringify(\n position,\n )} with rotation: ${rotation} in game: ${game.id}`,\n );\n\n if (!isGameWithNextAction(game)) {\n logger.error(\n `Invalid game, required nextAction type: 'action' but got: ${game.nextAction.type}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n { expected: \"action\", actual: game.nextAction.type, gameId: game.id },\n );\n }\n\n if (game.nextAction.nextAction !== \"placeDomino\") {\n logger.error(\n `Required game with placeDomino action but got: ${game.nextAction.nextAction}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n {\n expected: \"placeDomino\",\n actual: game.nextAction.nextAction,\n gameId: game.id,\n },\n );\n }\n\n const result = useCase(game, lordId, position, rotation);\n\n if (isErr(result)) {\n logger.error(`Error placing domino: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new ActionExecutionError(\n translateErrorCode(translator, code),\n code,\n {\n gameId: game.id,\n lordId: command.lordId,\n position: command.position,\n rotation: command.rotation,\n },\n );\n }\n\n if (isGameWithNextAction(result.value)) {\n logger.info(\n `Domino placed: ${lordId} in position: ${JSON.stringify(\n position,\n )} with rotation: ${rotation} in game: ${game.id}`,\n );\n return result.value;\n }\n\n logger.info(\n `Domino placed: ${lordId} in position: ${JSON.stringify(\n position,\n )} with rotation: ${rotation} in game: ${game.id}`,\n );\n return result.value;\n };\n","import type { GameState } from \"@core/domain/types/index.js\";\nimport { ok, err, type Result } from \"@utils/result.js\";\n\n/**\n * Serialization format version for backwards compatibility.\n */\nconst SERIALIZATION_VERSION = 1;\n\n/**\n * Serialized game data structure.\n */\ninterface SerializedGame {\n version: number;\n data: GameState;\n timestamp: string;\n}\n\n/**\n * Serializes a game state to a JSON string.\n * The serialized string includes version information for future compatibility.\n *\n * @param game - The game state to serialize\n * @returns JSON string representation of the game\n */\nexport const serializeGame = (game: GameState): string => {\n const serialized: SerializedGame = {\n version: SERIALIZATION_VERSION,\n data: game,\n timestamp: new Date().toISOString(),\n };\n return JSON.stringify(serialized);\n};\n\n/**\n * Deserializes a JSON string back to a game state.\n * Validates the structure and version before returning.\n *\n * @param json - The JSON string to deserialize\n * @returns Result containing the game state or an error\n */\nexport const deserializeGame = (json: string): Result<GameState> => {\n try {\n const parsed = JSON.parse(json) as SerializedGame;\n\n // Validate structure\n if (!parsed.version || !parsed.data) {\n return err(\"Invalid serialized game format\");\n }\n\n // Check version compatibility\n if (parsed.version > SERIALIZATION_VERSION) {\n return err(\n `Unsupported serialization version: ${parsed.version}. Current version: ${SERIALIZATION_VERSION}`\n );\n }\n\n // Validate essential game properties\n const game = parsed.data;\n if (!game.id || !game.players || !game.lords || !game.nextAction) {\n return err(\"Invalid game state structure\");\n }\n\n return ok(game);\n } catch (error) {\n return err(`Failed to parse game JSON: ${(error as Error).message}`);\n }\n};\n\n/**\n * Creates a save point for the current game state.\n * Includes metadata for debugging and restore purposes.\n */\nexport interface GameSavePoint {\n /** Serialized game data */\n serialized: string;\n /** When the save was created */\n createdAt: string;\n /** Game ID for reference */\n gameId: string;\n /** Current turn number */\n turn: number;\n}\n\n/**\n * Creates a save point from a game state.\n *\n * @param game - The game state to save\n * @returns A save point object with metadata\n */\nexport const createSavePoint = (game: GameState): GameSavePoint => {\n return {\n serialized: serializeGame(game),\n createdAt: new Date().toISOString(),\n gameId: game.id,\n turn: game.turn,\n };\n};\n\n/**\n * Restores a game state from a save point.\n *\n * @param savePoint - The save point to restore from\n * @returns Result containing the restored game state or an error\n */\nexport const restoreFromSavePoint = (\n savePoint: GameSavePoint\n): Result<GameState> => {\n return deserializeGame(savePoint.serialized);\n};\n","import type {\n DeserializeGameCommand,\n SerializeGameCommand,\n} from \"@application/commands/serializeGameCommand.js\";\nimport {\n type ErrorCodeType,\n StepExecutionError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport type { GameState } from \"@core/domain/types/index.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport {\n deserializeGame,\n serializeGame,\n} from \"@core/useCases/serialization.js\";\nimport { isErr, unwrap } from \"@utils/result.js\";\n\ntype SerializeGameHandler = (command: SerializeGameCommand) => string;\ntype DeserializeGameHandler = (command: DeserializeGameCommand) => GameState;\n\n/**\n * Creates a handler for serializing game state.\n */\nexport const serializeGameHandler = (\n logger: Logger,\n _translator: Translator,\n): SerializeGameHandler => {\n return (command) => {\n logger.info(`Serializing game: ${command.game.id}`);\n const serialized = serializeGame(command.game);\n logger.info(`Game serialized successfully`);\n return serialized;\n };\n};\n\n/**\n * Creates a handler for deserializing game state.\n */\nexport const deserializeGameHandler = (\n logger: Logger,\n translator: Translator,\n): DeserializeGameHandler => {\n return (command) => {\n logger.info(`Deserializing game from JSON`);\n const result = deserializeGame(command.json);\n\n if (isErr(result)) {\n logger.error(`Failed to deserialize game: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new StepExecutionError(translateErrorCode(translator, code), code);\n }\n\n const game = unwrap(result);\n logger.info(`Game deserialized successfully: ${game.id}`);\n return game;\n };\n};\n","import type { StartGameCommand } from \"@application/commands/startGameCommand.js\";\nimport {\n ErrorCode,\n type ErrorCodeType,\n InvalidStepError,\n StepExecutionError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport {\n type GameWithNextAction,\n isGameWithNextStep,\n} from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { StartGameUseCase } from \"@core/useCases/startGame.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype StartGameHandler = (command: StartGameCommand) => GameWithNextAction;\n\nexport const startGameHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: StartGameUseCase,\n ): StartGameHandler =>\n (command: StartGameCommand) => {\n const { game } = command;\n logger.info(`Starting game: ${game.id}`);\n\n if (!isGameWithNextStep(game)) {\n logger.error(\n `Invalid game, required nextAction type: 'step' but got: ${game.nextAction.type}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n { expected: \"step\", actual: game.nextAction.type, gameId: game.id },\n );\n }\n\n if (\n game.nextAction.step !== \"start\" &&\n game.nextAction.step !== \"options\"\n ) {\n logger.error(\n `Required game with start step or options step but got: ${game.nextAction.step}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n {\n expected: \"start|options\",\n actual: game.nextAction.step,\n gameId: game.id,\n },\n );\n }\n\n const result = useCase(game);\n\n if (isErr(result)) {\n logger.error(`Error starting game: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new StepExecutionError(translateErrorCode(translator, code), code, {\n gameId: game.id,\n });\n }\n\n logger.info(`Game started: ${game.id}`);\n return result.value;\n };\n","import type { PlaceKnightCommand } from \"@application/commands/placeKnightCommand.js\";\nimport {\n ActionExecutionError,\n ErrorCode,\n type ErrorCodeType,\n InvalidStepError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport type { GameState } from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { PlaceKnightUseCase } from \"@core/useCases/placeKnight.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype PlaceKnightHandler = (command: PlaceKnightCommand) => GameState;\n\nexport const placeKnightHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: PlaceKnightUseCase,\n ): PlaceKnightHandler =>\n (command: PlaceKnightCommand) => {\n const { game, lordId, position } = command;\n logger.info(\n `Placing knight for lord: ${lordId} at position: ${JSON.stringify(\n position,\n )} in game: ${game.id}`,\n );\n\n if (game.nextAction.nextAction !== \"placeKnight\") {\n logger.error(\n `Required game with placeKnight action but got: ${game.nextAction.nextAction}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n {\n expected: \"placeKnight\",\n actual: game.nextAction.nextAction,\n gameId: game.id,\n },\n );\n }\n\n const result = useCase(game, lordId, position);\n\n if (isErr(result)) {\n logger.error(`Error placing knight: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new ActionExecutionError(\n translateErrorCode(translator, code),\n code,\n {\n gameId: game.id,\n lordId: command.lordId,\n position: command.position,\n },\n );\n }\n\n logger.info(\n `Knight placed for lord: ${lordId} at position: ${JSON.stringify(\n position,\n )} in game: ${game.id}`,\n );\n return result.value;\n };\n","import type { ConstructBuildingCommand } from \"@application/commands/constructBuildingCommand.js\";\nimport {\n ActionExecutionError,\n ErrorCode,\n type ErrorCodeType,\n InvalidStepError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport type { GameState } from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { ConstructBuildingUseCase } from \"@core/useCases/constructBuilding.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype ConstructBuildingHandler = (command: ConstructBuildingCommand) => GameState;\n\nexport const constructBuildingHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: ConstructBuildingUseCase,\n ): ConstructBuildingHandler =>\n (command: ConstructBuildingCommand) => {\n const { game, lordId, buildingId, position } = command;\n logger.info(\n `Constructing building: ${buildingId} for lord: ${lordId} at position: ${JSON.stringify(\n position,\n )} in game: ${game.id}`,\n );\n\n if (game.nextAction.nextAction !== \"constructBuilding\") {\n logger.error(\n `Required game with constructBuilding action but got: ${game.nextAction.nextAction}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n {\n expected: \"constructBuilding\",\n actual: game.nextAction.nextAction,\n gameId: game.id,\n },\n );\n }\n\n const result = useCase(game, lordId, buildingId, position);\n\n if (isErr(result)) {\n logger.error(`Error constructing building: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new ActionExecutionError(\n translateErrorCode(translator, code),\n code,\n {\n gameId: game.id,\n lordId: command.lordId,\n buildingId: command.buildingId,\n position: command.position,\n },\n );\n }\n\n logger.info(\n `Building constructed: ${buildingId} for lord: ${lordId} at position: ${JSON.stringify(\n position,\n )} in game: ${game.id}`,\n );\n return result.value;\n };\n","import type { UseDragonCommand } from \"@application/commands/useDragonCommand.js\";\nimport {\n ActionExecutionError,\n ErrorCode,\n type ErrorCodeType,\n InvalidStepError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport type { GameState } from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { UseDragonUseCase } from \"@core/useCases/useDragon.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype UseDragonHandler = (command: UseDragonCommand) => GameState;\n\nexport const useDragonHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: UseDragonUseCase,\n ): UseDragonHandler =>\n (command: UseDragonCommand) => {\n const { game, lordId, buildingId } = command;\n logger.info(\n `Using dragon on building: ${buildingId} for lord: ${lordId} in game: ${game.id}`,\n );\n\n if (game.nextAction.nextAction !== \"useDragon\") {\n logger.error(\n `Required game with useDragon action but got: ${game.nextAction.nextAction}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n {\n expected: \"useDragon\",\n actual: game.nextAction.nextAction,\n gameId: game.id,\n },\n );\n }\n\n const result = useCase(game, lordId, buildingId);\n\n if (isErr(result)) {\n logger.error(`Error using dragon: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new ActionExecutionError(\n translateErrorCode(translator, code),\n code,\n {\n gameId: game.id,\n lordId: command.lordId,\n buildingId: command.buildingId,\n },\n );\n }\n\n logger.info(\n `Dragon used on building: ${buildingId} for lord: ${lordId} in game: ${game.id}`,\n );\n return result.value;\n };\n","import type { SkipOptionalActionCommand } from \"@application/commands/skipOptionalActionCommand.js\";\nimport {\n ActionExecutionError,\n ErrorCode,\n type ErrorCodeType,\n} from \"@core/domain/errors/domainErrors.js\";\nimport type { GameState } from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { SkipOptionalActionUseCase } from \"@core/useCases/skipOptionalAction.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype SkipOptionalActionHandler = (command: SkipOptionalActionCommand) => GameState;\n\nexport const skipOptionalActionHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: SkipOptionalActionUseCase,\n ): SkipOptionalActionHandler =>\n (command: SkipOptionalActionCommand) => {\n const { game, lordId } = command;\n logger.info(\n `Skipping optional action for lord: ${lordId} in game: ${game.id}`,\n );\n\n const result = useCase(game, lordId);\n\n if (isErr(result)) {\n logger.error(`Error skipping optional action: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new ActionExecutionError(\n translateErrorCode(translator, code),\n code,\n { gameId: game.id, lordId: command.lordId },\n );\n }\n\n logger.info(\n `Optional action skipped for lord: ${lordId} in game: ${game.id}`,\n );\n return result.value;\n };\n","/**\n * All possible ground/terrain types in Kingdomino.\n * Each type can form contiguous properties for scoring.\n */\nexport const GROUND = [\n \"castle\",\n \"wheat\",\n \"forest\",\n \"sea\",\n \"plain\",\n \"swamp\",\n \"mine\",\n] as const;\n\n/** Union type of all terrain types */\nexport type Ground = (typeof GROUND)[number];\n\n/** Special ground type for empty/unplaced tiles */\nexport type EmptyGround = \"empty\";\n\n/** Number of crowns on a tile (0-3) */\nexport type Crown = number;\n\n/**\n * Represents a single tile with terrain and crowns.\n * Two tiles form a domino.\n */\nexport type Tile = {\n /** The terrain type of this tile */\n type: Ground;\n /** Number of crowns (0-3), multiplier for scoring */\n crowns: Crown;\n /** Whether this tile has a construction square for buildings (Queendomino) */\n hasConstructionSquare?: boolean;\n};\n\n/**\n * Represents an empty/unplaced tile on the kingdom grid.\n */\nexport type EmptyTile = {\n /** Always \"empty\" for unplaced tiles */\n type: EmptyGround;\n /** Empty tiles have no crowns */\n crowns: 0;\n};\n\n/**\n * Represents a domino piece consisting of two connected tiles.\n * Dominoes are the main game pieces that players place on their kingdoms.\n */\nexport type Domino = {\n /** The left tile of the domino */\n left: Tile;\n /** The right tile of the domino */\n right: Tile;\n /** Unique number identifying this domino (1-48 in Classic mode) */\n number: number;\n};\n\n/**\n * Represents a domino that has been revealed for player selection.\n * Contains selection state for the current turn.\n */\nexport type RevealsDomino = {\n /** The actual domino piece */\n domino: Domino;\n /** Whether this domino has been picked by a lord */\n picked: boolean;\n /** ID of the lord who picked this domino, or null if unpicked */\n lordId: string | null;\n /** Display position in the revealed set (for UI ordering) */\n position: number;\n};\n","import type { EmptyTile, Tile } from \"./domino.js\";\n\n/**\n * Represents a position on the kingdom grid.\n * Origin (0,0) is at the top-left corner.\n */\nexport type Position = {\n /** Column index (0-8, left to right) */\n x: number;\n /** Row index (0-8, top to bottom) */\n y: number;\n};\n\n/**\n * Rotation angle for domino placement.\n * - 0: Horizontal, left tile at position, right tile to the east\n * - 90: Vertical, left tile at position, right tile to the south\n * - 180: Horizontal, right tile at position, left tile to the east\n * - 270: Vertical, right tile at position, left tile to the south\n */\nexport type Rotation = 0 | 90 | 180 | 270;\n\n/**\n * Represents a player's kingdom as a 2D grid of tiles.\n * The grid is 9x9 to allow for the 5x5 maximum kingdom size\n * with the castle at any position.\n */\nexport type Kingdom = (Tile | EmptyTile)[][];\n\n/**\n * The size of the kingdom grid (9x9).\n * This allows for a 5x5 kingdom with the castle placed anywhere.\n */\nexport const GRIDSIZE = 9;\n\n/**\n * Maximum kingdom size (5x5 in standard rules, 7x7 for Mighty Duel).\n */\nexport const MAX_KINGDOM_SIZE = 5;\n","import type { PlacedBuilding } from \"./building.js\";\nimport type { Kingdom, Position } from \"./kingdom.js\";\nimport type { ObjectValues } from \"./utils.js\";\n\n/**\n * Represents a knight placed on a player's kingdom (Queendomino).\n */\nexport type Knight = {\n /** ID of the player who owns this knight */\n playerId: string;\n /** Position on the kingdom grid where the knight is placed */\n position: Position;\n};\n\n/**\n * Represents a player in the game.\n */\nexport type Player = {\n /** Unique identifier for the player */\n id: string;\n /** Display name of the player */\n name: string;\n /** The player's kingdom grid where dominoes are placed */\n kingdom: Kingdom;\n /** If set, this player is controlled by a bot with the named strategy */\n bot?: { strategyName: string };\n /** Number of coins the player has (Queendomino) */\n coins?: number;\n /** Number of towers the player has (Queendomino) */\n towers?: number;\n /** Knights placed on the kingdom (Queendomino) */\n knights?: Knight[];\n /** Buildings placed on the kingdom (Queendomino) */\n buildings?: PlacedBuilding[];\n};\n\n/**\n * Payload for creating a new player.\n */\nexport type PlayerPayload = {\n /** Display name for the player (minimum 3 characters) */\n name: string;\n};\n\n/** Array of player creation payloads */\nexport type PlayersPayload = PlayerPayload[];\n\n/** Array of players */\nexport type Players = Player[];\n\n/**\n * Available actions a player can perform during their turn.\n */\nexport const playerActions = {\n /** Place a previously picked domino on the kingdom */\n placeDomino: \"placeDomino\",\n /** Pick a domino from the revealed set */\n pickDomino: \"pickDomino\",\n /** Pass/discard when no valid placement exists */\n pass: \"pass\",\n /** Place a knight on the just-placed domino (Queendomino, optional) */\n placeKnight: \"placeKnight\",\n /** Construct a building on a construction square (Queendomino, optional) */\n constructBuilding: \"constructBuilding\",\n /** Use the Dragon to burn a building tile (Queendomino, optional) */\n useDragon: \"useDragon\",\n /** Skip the current optional action (Queendomino) */\n skipOptionalAction: \"skipOptionalAction\",\n} as const;\n\n/** Union type of all player actions */\nexport type PlayerActions = ObjectValues<typeof playerActions>;\n","import { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport type { ExtraRule } from \"@core/domain/types/rule.js\";\nimport { ok, err, type Result } from \"@utils/result.js\";\n\nexport const getAvailablesExtraRules = (\n extraRules: ExtraRule[],\n mode: string,\n numberOfPlayers: number\n): Result<ExtraRule[]> => {\n const availableExtraRules = extraRules.filter((rule) => {\n return (\n rule.mode.filter((m) => m.name === mode).length > 0 &&\n (!rule.playersLimit || rule.playersLimit === numberOfPlayers)\n );\n });\n\n if (availableExtraRules.length === 0) {\n return err(ErrorCode.STEP_EXECUTION_FAILED);\n }\n\n return ok(availableExtraRules);\n};\n\nexport const toExtraRule = (\n rule: string,\n extraRules: ExtraRule[]\n): Result<ExtraRule> => {\n const foundRule = extraRules.find((r) => r.name === rule);\n\n if (!foundRule) {\n return err(ErrorCode.STEP_EXECUTION_FAILED);\n }\n\n return ok(foundRule);\n};\n","import type { ShuffleMethod } from \"@core/portServerside/shuffleMethod.js\";\n\nconst hashSeed = (str: string): number => {\n let hash = 2166136261;\n for (let i = 0; i < str.length; i++) {\n hash ^= str.charCodeAt(i);\n hash = Math.imul(hash, 16777619);\n }\n return hash >>> 0;\n};\n\nconst mulberry32 = (seed: number): (() => number) => {\n let state = seed;\n return () => {\n state |= 0;\n state = (state + 0x6d2b79f5) | 0;\n let t = Math.imul(state ^ (state >>> 15), 1 | state);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n};\n\nexport const createSeededShuffle = (\n seed: string,\n salt: string\n): ShuffleMethod => {\n const numericSeed = hashSeed(`${seed}|${salt}`);\n const random = mulberry32(numericSeed);\n\n return <T>(array: T[]): T[] => {\n const result = [...array];\n for (let i = result.length - 1; i > 0; i--) {\n const j = Math.floor(random() * (i + 1));\n [result[i], result[j]] = [result[j] as T, result[i] as T];\n }\n return result;\n };\n};\n","import {\n gameSteps,\n type ExtraRule,\n type GameWithNextStep,\n type NextStep,\n} from \"@core/domain/types/index.js\";\nimport { isErr, ok, type Result } from \"@utils/result.js\";\nimport type { RuleRepository } from \"@core/portServerside/ruleRepository.js\";\nimport type { DominoesRepository } from \"@core/portServerside/dominoesRepository.js\";\nimport type { ShuffleMethod } from \"@core/portServerside/shuffleMethod.js\";\nimport { toExtraRule } from \"@core/domain/entities/rule.js\";\nimport { createSeededShuffle } from \"@utils/seededShuffle.js\";\n\nexport type AddExtraRulesUseCase = (\n game: GameWithNextStep,\n rules: string[]\n) => Result<GameWithNextStep>;\n\nexport const addExtraRulesUseCase =\n (deps: {\n ruleRepository: RuleRepository;\n dominoesRepository: DominoesRepository;\n shuffleMethod: ShuffleMethod;\n }): AddExtraRulesUseCase =>\n (game, rules) => {\n const { ruleRepository, dominoesRepository, shuffleMethod } = deps;\n const availableExtraRules = ruleRepository.getAllExtra();\n\n const newExtraRules: ExtraRule[] = [];\n\n for (const rule of rules) {\n const result = toExtraRule(rule, availableExtraRules);\n\n if (isErr(result)) {\n return result;\n }\n\n newExtraRules.push(result.value);\n }\n\n // The Mighty Duel overrides basic rules for 2-player games\n let updatedBasic = game.rules.basic;\n let updatedDominoes = game.dominoes;\n const hasMightyDuel = newExtraRules.some((r) => r.name === \"The Mighty Duel\");\n if (hasMightyDuel) {\n updatedBasic = {\n ...updatedBasic,\n maxDominoes: 48,\n maxTurns: 12,\n maxKingdomSize: 7,\n };\n // Reload and shuffle all 48 dominoes\n const allDominoes = dominoesRepository.getForMode(game.mode);\n if (allDominoes) {\n const shuffle = game.seed\n ? createSeededShuffle(game.seed, \"mighty-duel\")\n : shuffleMethod;\n updatedDominoes = shuffle(allDominoes);\n }\n }\n\n const updatedRules = {\n basic: updatedBasic,\n extra: newExtraRules,\n };\n\n const next: NextStep = {\n type: \"step\",\n step: gameSteps.start,\n };\n\n const updatedGame: GameWithNextStep = {\n ...game,\n dominoes: updatedDominoes,\n rules: updatedRules,\n nextAction: next,\n };\n\n return ok(updatedGame);\n };\n","import type { Player } from \"@core/domain/types/player.js\";\n\n/** Default starting coins for each player in Queendomino */\nexport const STARTING_COINS = 7;\n\n/** Maximum number of knights a player can place */\nexport const MAX_KNIGHTS = 3;\n\nexport const initializeCoins = (): number => STARTING_COINS;\n\nexport const addCoins = (player: Player, amount: number): Player => ({\n ...player,\n coins: (player.coins ?? 0) + amount,\n});\n\nexport const removeCoins = (player: Player, amount: number): Player => ({\n ...player,\n coins: (player.coins ?? 0) - amount,\n});\n\nexport const canAfford = (player: Player, cost: number): boolean =>\n (player.coins ?? 0) >= cost;\n\nexport const addTowers = (player: Player, amount: number): Player => ({\n ...player,\n towers: (player.towers ?? 0) + amount,\n});\n\nexport const getTowerCount = (player: Player): number => player.towers ?? 0;\n","import {\n GROUND,\n type Crown,\n type EmptyGround,\n type EmptyTile,\n type Ground,\n type Tile,\n} from \"@core/domain/types/domino.js\";\n\nconst isGround = (ground: any): ground is Ground => {\n return GROUND.includes(ground);\n};\n\nexport const createTile = (\n ground: Ground | EmptyGround,\n crowns: Crown = 0\n): Tile | EmptyTile => {\n if (isGround(ground)) {\n return { type: ground, crowns } as Tile;\n }\n return { type: ground, crowns: 0 } as EmptyTile;\n};\n","import {\n type Domino,\n type EmptyTile,\n GRIDSIZE,\n MAX_KINGDOM_SIZE,\n type Kingdom,\n type Position,\n type Rotation,\n type Tile,\n} from \"@core/domain/types/index.js\";\nimport { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport {err, isErr, isOk, ok, type Result} from \"@utils/result.js\";\nimport {createTile} from \"./domino.js\";\n\nexport const createEmptyKingdom = (): Kingdom => {\n const emptyTile = createTile(\"empty\");\n return Array.from({length: GRIDSIZE}, () =>\n Array.from({length: GRIDSIZE}, () => emptyTile)\n );\n};\n\nexport const placeCastle = (kingdom: Kingdom): Kingdom => {\n const castle = createTile(\"castle\");\n const newKingdom = deepCopyKingdom(kingdom);\n newKingdom[4]![4] = castle;\n return newKingdom;\n};\n\nexport const placeTile = (\n kingdom: Kingdom,\n position: Position,\n tile: Tile\n): Kingdom => {\n const newKingdom = deepCopyKingdom(kingdom);\n newKingdom[position.y]![position.x] = tile;\n return newKingdom;\n};\n\nexport const getTile = (\n kingdom: Kingdom,\n position: Position\n): Result<Tile | EmptyTile> => {\n const tile = kingdom[position.y]?.[position.x];\n if (!tile) {\n return err(ErrorCode.PLACEMENT_OUT_OF_BOUNDS);\n }\n return ok(tile);\n};\n\nexport const calculateDominoPosition = (\n position: Position,\n rotation: Rotation,\n domino: Domino\n): [{ tile: Tile; position: Position }, { tile: Tile; position: Position }] => {\n let firstTile: {\n tile: Tile;\n position: Position;\n };\n let secondTile: {\n tile: Tile;\n position: Position;\n };\n\n switch (rotation) {\n case 0: // horizontal, left to right\n firstTile = {\n tile: domino.left,\n position: {\n x: position.x,\n y: position.y,\n },\n };\n secondTile = {\n tile: domino.right,\n position: {\n x: position.x + 1,\n y: position.y,\n },\n };\n break;\n case 90: // vertical, top to bottom\n firstTile = {\n tile: domino.left,\n position: {\n x: position.x,\n y: position.y,\n },\n };\n secondTile = {\n tile: domino.right,\n position: {\n x: position.x,\n y: position.y + 1,\n },\n };\n break;\n case 180: // horizontal, right to left\n firstTile = {\n tile: domino.right,\n position: {\n x: position.x,\n y: position.y,\n },\n };\n secondTile = {\n tile: domino.left,\n position: {\n x: position.x + 1,\n y: position.y,\n },\n };\n break;\n case 270: // vertical, bottom to top\n firstTile = {\n tile: domino.right,\n position: {\n x: position.x,\n y: position.y,\n },\n };\n secondTile = {\n tile: domino.left,\n position: {\n x: position.x,\n y: position.y + 1,\n },\n };\n break;\n }\n\n return [firstTile, secondTile];\n};\n\nexport const placeDomino = (\n kingdom: Kingdom,\n position: Position,\n rotation: Rotation,\n domino: Domino,\n maxKingdomSize: number = MAX_KINGDOM_SIZE\n): Result<Kingdom> => {\n const [firstTile, secondTile] = calculateDominoPosition(\n position,\n rotation,\n domino\n );\n\n const isFreePlaceResult = isFreePlace(\n kingdom,\n firstTile.position,\n secondTile.position\n );\n if (isErr(isFreePlaceResult)) {\n return isFreePlaceResult;\n }\n\n if (exceedsMaxSize(kingdom, firstTile.position, secondTile.position, maxKingdomSize)) {\n return err(ErrorCode.PLACEMENT_EXCEEDS_KINGDOM_SIZE);\n }\n\n const adjacentTiles = isAdjacent(\n kingdom,\n firstTile.position,\n secondTile.position\n );\n\n if (adjacentTiles.length === 0) {\n return err(ErrorCode.PLACEMENT_NOT_ADJACENT);\n }\n\n const hasValidAdjacentTiles = hasValidAdjacent(adjacentTiles, [\n firstTile.tile,\n secondTile.tile,\n ]);\n\n if (!hasValidAdjacentTiles) {\n return err(ErrorCode.PLACEMENT_INVALID_TERRAIN);\n }\n\n return ok(placeTiles(kingdom, [firstTile, secondTile]));\n};\n\nconst placeTiles = (\n kingdom: Kingdom,\n tiles: { tile: Tile; position: Position }[]\n) => {\n let newKingdom = deepCopyKingdom(kingdom);\n for (const { tile, position } of tiles) {\n newKingdom = placeTile(newKingdom, position, tile);\n }\n return newKingdom;\n};\n\nconst isFreePlace = (\n kingdom: Kingdom,\n firstPosition: Position,\n secondPosition: Position\n): Result<boolean> => {\n const firstTile = getTile(kingdom, firstPosition);\n const secondTile = getTile(kingdom, secondPosition);\n\n if (isErr(firstTile)) {\n return firstTile;\n }\n\n if (isErr(secondTile)) {\n return secondTile;\n }\n\n if (firstTile.value.type !== \"empty\" || secondTile.value.type !== \"empty\") {\n return err(ErrorCode.PLACEMENT_NOT_EMPTY);\n }\n\n return ok(true);\n};\n\nconst isAdjacent = (\n kingdom: Kingdom,\n firstPosition: Position,\n secondPosition: Position\n): Tile[] => {\n const offsets = [\n { x: -1, y: 0 },\n { x: 1, y: 0 },\n { x: 0, y: -1 },\n { x: 0, y: 1 },\n ];\n\n const isOwnPosition = (x: number, y: number) =>\n (x === firstPosition.x && y === firstPosition.y) ||\n (x === secondPosition.x && y === secondPosition.y);\n\n const adjacentTiles: Tile[] = [];\n\n for (const pos of [firstPosition, secondPosition]) {\n for (const offset of offsets) {\n const nx = pos.x + offset.x;\n const ny = pos.y + offset.y;\n if (isOwnPosition(nx, ny)) continue;\n const tile = getTile(kingdom, { x: nx, y: ny });\n if (isOk(tile) && tile.value.type !== \"empty\") {\n adjacentTiles.push(tile.value);\n }\n }\n }\n\n return adjacentTiles;\n};\n\nconst hasValidAdjacent = (\n adjacentTiles: (Tile | EmptyTile)[],\n tiles: Tile[]\n): boolean => {\n return adjacentTiles.some((adjacentTile) => {\n return tiles.some((tile) => {\n return tile.type === adjacentTile.type || adjacentTile.type === \"castle\";\n });\n });\n};\n\nexport const checkCastleIsInMiddle = (kingdom: Kingdom): boolean => {\n // Find castle coordinates\n let castleX: number | undefined;\n let castleY: number | undefined;\n\n for (let y = 0; y < kingdom.length; y++) {\n const x = kingdom[y]!.findIndex((tile) => tile.type === \"castle\");\n if (x !== -1) {\n castleX = x;\n castleY = y;\n break;\n }\n }\n\n if (castleX === undefined || castleY === undefined) {\n return false;\n }\n\n const bbox = getBoundingBox(kingdom);\n if (!bbox) return false;\n\n // Castle must be at the exact center of the bounding box\n const centerX = (bbox.minX + bbox.maxX) / 2;\n const centerY = (bbox.minY + bbox.maxY) / 2;\n\n return castleX === centerX && castleY === centerY;\n};\n\nexport const getBoundingBox = (\n kingdom: Kingdom\n): { minX: number; maxX: number; minY: number; maxY: number } | null => {\n let minX = Infinity;\n let maxX = -Infinity;\n let minY = Infinity;\n let maxY = -Infinity;\n\n for (let y = 0; y < kingdom.length; y++) {\n for (let x = 0; x < kingdom[y]!.length; x++) {\n if (kingdom[y]![x]!.type !== \"empty\") {\n if (x < minX) minX = x;\n if (x > maxX) maxX = x;\n if (y < minY) minY = y;\n if (y > maxY) maxY = y;\n }\n }\n }\n\n if (minX === Infinity) return null;\n return { minX, maxX, minY, maxY };\n};\n\nconst exceedsMaxSize = (\n kingdom: Kingdom,\n firstPosition: Position,\n secondPosition: Position,\n maxSize: number = MAX_KINGDOM_SIZE\n): boolean => {\n const bbox = getBoundingBox(kingdom);\n\n let minX = bbox?.minX ?? Infinity;\n let maxX = bbox?.maxX ?? -Infinity;\n let minY = bbox?.minY ?? Infinity;\n let maxY = bbox?.maxY ?? -Infinity;\n\n for (const pos of [firstPosition, secondPosition]) {\n if (pos.x < minX) minX = pos.x;\n if (pos.x > maxX) maxX = pos.x;\n if (pos.y < minY) minY = pos.y;\n if (pos.y > maxY) maxY = pos.y;\n }\n\n return (maxX - minX + 1) > maxSize || (maxY - minY + 1) > maxSize;\n};\n\nexport const countDominoes = (kingdom: Kingdom): number => {\n const notEmpties = kingdom.flat().filter((tile) => tile.type !== \"empty\");\n // -1 because the castle is not a domino\n return (notEmpties.length - 1) / 2;\n};\n\nconst deepCopyKingdom = (kingdom: Kingdom): Kingdom => {\n return kingdom.map((line) => line.map((tile) => ({ ...tile })));\n};\n","import { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport { type Result, err, ok, isErr } from \"@utils/result.js\";\nimport type { Player } from \"@core/domain/types/player.js\";\nimport type { Kingdom } from \"@core/domain/types/kingdom.js\";\n\nconst MINPLAYERSNAMELENGTH = 3;\n\nexport const validatePlayer = (name: string): Result<string> => {\n if (!name || name.trim().length < MINPLAYERSNAMELENGTH) {\n return err(ErrorCode.INVALID_PLAYER_NAME);\n }\n\n return ok(name);\n};\n\nexport const createPlayer = (\n playerName: string,\n id: string,\n kingdom: Kingdom,\n bot?: { strategyName: string }\n): Result<Player> => {\n const name = validatePlayer(playerName);\n\n if (isErr(name)) {\n return name;\n }\n\n return ok({\n name: name.value,\n id,\n kingdom,\n ...(bot && { bot }),\n });\n};\n","import { STARTING_COINS } from \"@core/domain/entities/economy.js\";\nimport {\n createEmptyKingdom,\n placeCastle,\n} from \"@core/domain/entities/kingdom.js\";\nimport { createPlayer } from \"@core/domain/entities/player.js\";\nimport type {\n GameWithNextStep,\n NextStep,\n Players,\n} from \"@core/domain/types/index.js\";\nimport type { RuleRepository } from \"@core/portServerside/ruleRepository.js\";\nimport type { ShuffleMethod } from \"@core/portServerside/shuffleMethod.js\";\nimport type { UuidMethod } from \"@core/portServerside/uuidMethod.js\";\nimport { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport { err, isErr, ok, type Result } from \"@utils/result.js\";\nimport { createSeededShuffle } from \"@utils/seededShuffle.js\";\nimport type { PlayerInput } from \"@application/commands/addPlayersCommand.js\";\n\nexport type AddPlayersUseCase = (\n game: GameWithNextStep,\n players: PlayerInput[]\n) => Result<GameWithNextStep>;\n\nconst normalizePlayerInput = (\n input: PlayerInput\n): { name: string; bot?: { strategyName: string } } => {\n if (typeof input === \"string\") {\n return { name: input };\n }\n return { name: input.name, bot: input.bot };\n};\n\nexport const addPlayersUseCase =\n (deps: {\n uuidMethod: UuidMethod;\n shuffleMethod: ShuffleMethod;\n ruleRepository: RuleRepository;\n }): AddPlayersUseCase =>\n (game, players) => {\n const { uuidMethod, shuffleMethod, ruleRepository } = deps;\n\n if (!players || players.length < 1 || players.length > 4) {\n return err(ErrorCode.INVALID_PLAYER_COUNT);\n }\n\n const newPlayers: Players = [];\n\n for (const player of players) {\n const { name, bot } = normalizePlayerInput(player);\n let kingdom = createEmptyKingdom();\n kingdom = placeCastle(kingdom);\n let id = uuidMethod();\n const newPlayer = createPlayer(name, id, kingdom, bot);\n\n if (isErr(newPlayer)) {\n return newPlayer;\n }\n\n // Initialize Queendomino-specific player state\n if (game.mode.name === \"QueenDomino\") {\n newPlayer.value.coins = STARTING_COINS;\n newPlayer.value.towers = 0;\n newPlayer.value.knights = [];\n newPlayer.value.buildings = [];\n }\n\n newPlayers.push(newPlayer.value);\n }\n\n // set rules\n const rules = ruleRepository.getAll();\n const basicRules = rules.basic[newPlayers.length];\n\n if (!basicRules) {\n return err(ErrorCode.STEP_EXECUTION_FAILED);\n }\n\n // updateDominoes\n const dominoes = game.dominoes;\n const { maxDominoes } = basicRules;\n const shuffle = game.seed\n ? createSeededShuffle(game.seed, \"dominoes\")\n : shuffleMethod;\n const shuffledDominoes = shuffle(dominoes);\n const splicedDominoes = shuffledDominoes.slice(0, maxDominoes);\n const next: NextStep = {\n type: \"step\",\n step: \"options\",\n };\n\n const updatedGame: GameWithNextStep = {\n ...game,\n players: newPlayers,\n dominoes: splicedDominoes,\n rules: {\n ...game.rules,\n basic: basicRules,\n },\n nextAction: next,\n };\n\n return ok(updatedGame);\n };\n","import type { Kingdom, Score } from \"@core/domain/types/index.js\";\nimport { ok, type Result } from \"@utils/result.js\";\n\nexport type CalculateScoreUseCase = (kingdom: Kingdom) => Result<Score>;\n\ntype Property = {\n size: number;\n crowns: number;\n};\n\nexport const calculateScoreUseCase: CalculateScoreUseCase = (kingdom) => {\n const rows = kingdom.length;\n const cols = kingdom[0]!.length;\n const visited: boolean[][] = kingdom.map((row) => row.map(() => false));\n const properties: Property[] = [];\n\n const directions = [\n [-1, 0],\n [1, 0],\n [0, -1],\n [0, 1],\n ];\n\n for (let y = 0; y < rows; y++) {\n for (let x = 0; x < cols; x++) {\n const tile = kingdom[y]![x]!;\n if (visited[y]![x] || tile.type === \"empty\" || tile.type === \"castle\") {\n continue;\n }\n\n // BFS flood-fill for this property\n const type = tile.type;\n let size = 0;\n let crowns = 0;\n const queue: [number, number][] = [[x, y]];\n visited[y]![x] = true;\n\n while (queue.length > 0) {\n const [cx, cy] = queue.pop()!;\n const current = kingdom[cy]![cx]!;\n size++;\n crowns += current.crowns;\n\n for (const [dx, dy] of directions) {\n const nx = cx + (dx as number);\n const ny = cy + (dy as number);\n if (\n nx >= 0 &&\n ny >= 0 &&\n nx < cols &&\n ny < rows &&\n !visited[ny]![nx] &&\n kingdom[ny]![nx]!.type === type\n ) {\n visited[ny]![nx] = true;\n queue.push([nx, ny]);\n }\n }\n }\n\n properties.push({ size, crowns });\n }\n }\n\n if (properties.length === 0) {\n return ok({\n points: 0,\n maxPropertiesSize: 0,\n totalCrowns: 0,\n });\n }\n\n let points = 0;\n let maxPropertiesSize = 0;\n let totalCrowns = 0;\n\n for (const property of properties) {\n points += property.size * property.crowns;\n if (property.size > maxPropertiesSize) {\n maxPropertiesSize = property.size;\n }\n totalCrowns += property.crowns;\n }\n\n return ok({\n points,\n maxPropertiesSize,\n totalCrowns,\n });\n};\n","import type { NextAction } from \"@core/domain/types/game.js\";\nimport type { Lord } from \"@core/domain/types/lord.js\";\nimport { type PlayerActions, playerActions } from \"@core/domain/types/player.js\";\n\nexport const createLord = (id: string, playerId: string): Lord => {\n return {\n id,\n playerId,\n turnEnded: false,\n hasPick: false,\n hasPlace: true,\n };\n};\n\nconst hasPick = (lord: Lord): boolean => lord.hasPick;\nconst hasPlace = (lord: Lord): boolean => lord.hasPlace;\nconst hasTurnEnded = (lord: Lord): boolean => lord.turnEnded;\n\nexport const canPass = (lord: Lord): boolean => {\n return !hasPick(lord) && !hasPlace(lord) && !hasTurnEnded(lord);\n};\n\nexport const canPick = (lord: Lord): boolean => {\n return !hasPick(lord) && hasPlace(lord) && !hasTurnEnded(lord);\n};\n\nexport const canPlaceAndDominoPickedIsDefined = (\n lord: Lord\n): lord is Required<Lord & Pick<Lord, \"dominoPicked\">> => {\n return (\n !hasPick(lord) &&\n !hasPlace(lord) &&\n !hasTurnEnded(lord) &&\n lord.dominoPicked !== undefined\n );\n};\n\nexport const updateLordOrder = (lords: Lord[]): Lord[] => {\n return [...lords].sort((a, b) => {\n return (a.dominoPicked?.number ?? 0) - (b.dominoPicked?.number ?? 0);\n });\n};\n\nexport const resetLordsActions = (lords: Lord[]): Lord[] => {\n return lords.map((lord) => ({\n ...lord,\n turnEnded: false,\n hasPick: false,\n hasPlace: false,\n }));\n};\n\nexport const nextLordWithAction = (lords: Lord[]): NextAction => {\n const nextLord = findNextLord(lords);\n\n return {\n type: \"action\",\n nextLord: nextLord.id,\n nextAction: hasPlace(nextLord)\n ? playerActions.pickDomino\n : playerActions.placeDomino,\n };\n};\n\nconst findNextLord = (lords: Lord[]): Lord => {\n const lord = lords.find((lord) => !hasTurnEnded(lord));\n if (!lord) {\n return lords[0]!;\n }\n return lord;\n};\n\nexport const allLordsHavePlayed = (lords: Lord[]): boolean => {\n return lords.every((lord) => lord.turnEnded);\n};\n\n/**\n * Queendomino optional action sequence after placeDomino:\n * placeKnight → constructBuilding → useDragon → pickDomino\n *\n * Given the current optional action, returns the next one in the sequence.\n */\nconst QUEENDOMINO_ACTION_SEQUENCE: PlayerActions[] = [\n playerActions.placeKnight,\n playerActions.constructBuilding,\n playerActions.useDragon,\n playerActions.pickDomino,\n];\n\nexport const nextQueenDominoAction = (\n currentAction: PlayerActions,\n): PlayerActions => {\n const index = QUEENDOMINO_ACTION_SEQUENCE.indexOf(currentAction);\n if (index === -1 || index >= QUEENDOMINO_ACTION_SEQUENCE.length - 1) {\n return playerActions.pickDomino;\n }\n return QUEENDOMINO_ACTION_SEQUENCE[index + 1]!;\n};\n","import {\n allLordsHavePlayed,\n canPick,\n nextLordWithAction,\n resetLordsActions,\n updateLordOrder,\n} from \"@core/domain/entities/lord.js\";\nimport type { GameWithNextAction } from \"@core/domain/types/game.js\";\nimport { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport { err, ok, type Result } from \"@utils/result.js\";\n\nexport type ChooseDominoUseCase = (\n game: GameWithNextAction,\n lordId: string,\n dominoPick: number\n) => Result<GameWithNextAction>;\n\nexport const chooseDominoUseCase: ChooseDominoUseCase = (\n game,\n lordId,\n dominoPick\n) => {\n const currentLord = game.lords.find(\n (lord) => lord.id === game.nextAction.nextLord\n );\n\n if (!currentLord) {\n return err(ErrorCode.LORD_NOT_FOUND);\n }\n\n if (currentLord.id !== lordId) {\n return err(ErrorCode.NOT_YOUR_TURN);\n }\n\n if (!canPick(currentLord)) {\n return err(ErrorCode.CANNOT_PICK);\n }\n\n // Check if dominoPick is valid choice\n const selectedDomino = game.currentDominoes.find(\n (domino) => domino.domino.number === dominoPick\n );\n\n if (!selectedDomino) {\n return err(ErrorCode.DOMINO_NOT_FOUND);\n }\n\n if (selectedDomino.picked) {\n return err(ErrorCode.DOMINO_ALREADY_PICKED);\n }\n\n // update currentDominoes\n const updatedCurrentDominoes = game.currentDominoes.map((domino) =>\n domino.domino.number === dominoPick\n ? { ...domino, picked: true, lordId: currentLord.id }\n : domino\n );\n\n // update lords\n const updatedLords = game.lords.map((lord) =>\n lord.id === currentLord.id\n ? { ...lord, hasPick: true, turnEnded: true, dominoPicked: selectedDomino.domino }\n : lord\n );\n\n const turnEnded = allLordsHavePlayed(updatedLords);\n\n if (turnEnded) {\n const lords = resetLordsActions(updateLordOrder(updatedLords));\n const updatedTurn = game.turn + 1;\n const next = nextLordWithAction(lords);\n const dominoesCopy = [...game.dominoes];\n const dominoesDrawn = dominoesCopy.splice(\n 0,\n game.rules.basic.dominoesPerTurn\n );\n dominoesDrawn.sort((a, b) => a.number - b.number);\n const updatedCurrentDominoes = dominoesDrawn.map((domino, index) => {\n return {\n domino,\n picked: false,\n lordId: null,\n position: index + 1,\n };\n });\n\n return ok({\n ...game,\n currentDominoes: updatedCurrentDominoes,\n dominoes: dominoesCopy,\n lords,\n turn: updatedTurn,\n nextAction: next,\n });\n }\n\n const next = nextLordWithAction(updatedLords);\n\n // update state\n const updatedState = {\n ...game,\n currentDominoes: updatedCurrentDominoes,\n lords: updatedLords,\n nextAction: next,\n };\n\n return ok(updatedState);\n};\n","import type { BuildingTile } from \"@core/domain/types/building.js\";\nimport {\n gameSteps,\n type Domino,\n type GameMode,\n type GameWithNextStep,\n} from \"@core/domain/types/index.js\";\nimport type { QueenDominoState } from \"@core/domain/types/queendomino.js\";\n\nexport const create = (payload: {\n id: string;\n mode: GameMode;\n dominoes: Domino[];\n seed?: string;\n buildings?: BuildingTile[];\n}): GameWithNextStep => {\n const { id, mode, dominoes, seed, buildings } = payload;\n\n let queendomino: QueenDominoState | undefined;\n if (mode.name === \"QueenDomino\" && buildings) {\n queendomino = {\n buildersBoard: {\n slots: [],\n drawPile: buildings,\n },\n queenHolderId: null,\n dragonAvailable: true,\n dragonUsedThisRound: false,\n };\n }\n\n return {\n id,\n dominoes,\n currentDominoes: [],\n players: [],\n lords: [],\n turn: 0,\n nextAction: {\n type: \"step\",\n step: gameSteps.addPlayers,\n },\n rules: {\n basic: {\n lords: 0,\n maxDominoes: 0,\n dominoesPerTurn: 0,\n maxTurns: 0,\n maxKingdomSize: 5,\n },\n extra: [],\n },\n mode,\n ...(seed !== undefined && { seed }),\n ...(queendomino !== undefined && { queendomino }),\n };\n};\n","import { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport { err, ok, type Result } from \"@utils/result.js\";\nimport type { GameMode } from \"@core/domain/types/mode.js\";\n\nconst findMode = (\n mode: string,\n availableMode: GameMode[]\n): GameMode | undefined => {\n return availableMode.find((m) => m.name === mode);\n};\n\nexport const createMode = (\n mode: string,\n availableMode: GameMode[]\n): Result<GameMode> => {\n const foundMode = findMode(mode, availableMode);\n if (foundMode) {\n return ok(foundMode);\n }\n\n return err(ErrorCode.MODE_NOT_FOUND);\n};\n","import { create } from \"@core/domain/entities/game.js\";\nimport { createMode } from \"@core/domain/entities/mode.js\";\nimport { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport type { BuildingTile } from \"@core/domain/types/building.js\";\nimport type { GameWithNextStep } from \"@core/domain/types/game.js\";\nimport type { BuildingsRepository } from \"@core/portServerside/buildingsRepository.js\";\nimport type { DominoesRepository } from \"@core/portServerside/dominoesRepository.js\";\nimport type { ModeRepository } from \"@core/portServerside/modeRepository.js\";\nimport type { UuidMethod } from \"@core/portServerside/uuidMethod.js\";\nimport { err, isErr, ok, type Result } from \"@utils/result.js\";\n\nexport type CreateGameUseCase = (\n mode: string,\n seed?: string,\n) => Result<GameWithNextStep>;\n\nexport const createGameUseCase =\n (deps: {\n modeRepository: ModeRepository;\n dominoesRepository: DominoesRepository;\n uuidMethod: UuidMethod;\n buildingsRepository?: BuildingsRepository;\n }): CreateGameUseCase =>\n (mode, seed) => {\n const { modeRepository, dominoesRepository, uuidMethod, buildingsRepository } = deps;\n const id = uuidMethod();\n const gameSeed = seed ?? uuidMethod();\n const availableMode = modeRepository.getAvailables();\n const newMode = createMode(mode, availableMode);\n\n if (isErr(newMode)) {\n return newMode;\n }\n\n const dominoes = dominoesRepository.getForMode(newMode.value);\n\n if (!dominoes || dominoes.length === 0) {\n return err(ErrorCode.DOMINO_NOT_FOUND);\n }\n\n const isQueenDomino = newMode.value.name === \"QueenDomino\";\n let buildings: BuildingTile[] | undefined;\n\n if (isQueenDomino && buildingsRepository) {\n buildings = buildingsRepository.getAll();\n }\n\n const payload = {\n id,\n mode: newMode.value,\n dominoes,\n seed: gameSeed,\n buildings,\n };\n\n const newGame = create(payload);\n\n return ok(newGame);\n };\n","import type { Kingdom, Position, Rotation, Domino } from \"@core/domain/types/index.js\";\nimport { GRIDSIZE, MAX_KINGDOM_SIZE } from \"@core/domain/types/kingdom.js\";\nimport { placeDomino } from \"@core/domain/entities/kingdom.js\";\nimport { isOk } from \"@utils/result.js\";\n\n/**\n * Represents a valid placement position with rotation.\n */\nexport type ValidPlacement = {\n position: Position;\n rotation: Rotation;\n};\n\nexport type GetValidPlacementsUseCase = (\n kingdom: Kingdom,\n domino: Domino,\n maxKingdomSize?: number\n) => ValidPlacement[];\n\n/**\n * Finds all valid placements for a domino on a kingdom grid.\n * Tests all positions and rotations to determine where the domino can be placed.\n *\n * @param kingdom - The current state of the kingdom grid\n * @param domino - The domino to place\n * @param maxKingdomSize - Maximum kingdom size (default: 5)\n * @returns Array of valid placements (position + rotation combinations)\n */\nexport const getValidPlacementsUseCase: GetValidPlacementsUseCase = (\n kingdom,\n domino,\n maxKingdomSize = MAX_KINGDOM_SIZE\n) => {\n const validPlacements: ValidPlacement[] = [];\n const rotations: Rotation[] = [0, 90, 180, 270];\n\n // Try each position on the grid\n for (let y = 0; y < GRIDSIZE; y++) {\n for (let x = 0; x < GRIDSIZE; x++) {\n const position: Position = { x, y };\n\n // Try each rotation\n for (const rotation of rotations) {\n const result = placeDomino(kingdom, position, rotation, domino, maxKingdomSize);\n if (isOk(result)) {\n validPlacements.push({ position, rotation });\n }\n }\n }\n }\n\n return validPlacements;\n};\n\n/**\n * Checks if a domino can be placed anywhere on the kingdom.\n *\n * @param kingdom - The current state of the kingdom grid\n * @param domino - The domino to check\n * @param maxKingdomSize - Maximum kingdom size (default: 5)\n * @returns True if at least one valid placement exists\n */\nexport const canPlaceDominoUseCase = (\n kingdom: Kingdom,\n domino: Domino,\n maxKingdomSize: number = MAX_KINGDOM_SIZE\n): boolean => {\n const rotations: Rotation[] = [0, 90, 180, 270];\n\n // Check each position on the grid\n for (let y = 0; y < GRIDSIZE; y++) {\n for (let x = 0; x < GRIDSIZE; x++) {\n const position: Position = { x, y };\n\n // Check each rotation - return early if any placement is valid\n for (const rotation of rotations) {\n const result = placeDomino(kingdom, position, rotation, domino, maxKingdomSize);\n if (isOk(result)) {\n return true;\n }\n }\n }\n }\n\n return false;\n};\n","import {\n allLordsHavePlayed,\n canPass,\n nextLordWithAction,\n} from \"@core/domain/entities/lord.js\";\nimport {\n gameSteps,\n type GameState,\n type GameStateResult,\n type GameWithNextAction,\n type NextAction,\n type NextStep,\n} from \"@core/domain/types/game.js\";\nimport { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport { canPlaceDominoUseCase } from \"./getValidPlacements.js\";\nimport { err, ok } from \"@utils/result.js\";\n\nexport type DiscardDominoUseCase = (\n game: GameWithNextAction,\n lordId: string\n) => GameStateResult;\n\nexport const discardDominoUseCase: DiscardDominoUseCase = (game, lordId) => {\n const nextAction = game.nextAction;\n\n const currentLord = game.lords.find(\n (lord) => lord.id === nextAction.nextLord\n );\n\n if (!currentLord) {\n return err(ErrorCode.LORD_NOT_FOUND);\n }\n\n if (currentLord.id !== lordId) {\n return err(ErrorCode.NOT_YOUR_TURN);\n }\n\n if (!canPass(currentLord)) {\n return err(ErrorCode.CANNOT_PLACE);\n }\n\n if (currentLord.dominoPicked) {\n const currentPlayer = game.players.find(\n (player) => player.id === currentLord.playerId\n );\n\n if (currentPlayer && canPlaceDominoUseCase(currentPlayer.kingdom, currentLord.dominoPicked, game.rules.basic.maxKingdomSize)) {\n return err(ErrorCode.CANNOT_PLACE);\n }\n }\n\n const maxTurns = game.rules.basic.maxTurns;\n const currentTurn = game.turn;\n const isLastTurn = currentTurn === maxTurns;\n\n const updatedLord = game.lords.map((lord) => {\n if (lord.id === currentLord.id) {\n if (isLastTurn) {\n return {\n ...lord,\n turnEnded: true,\n hasPlace: true,\n };\n }\n\n return {\n ...lord,\n hasPlace: true,\n };\n }\n return lord;\n });\n\n let updatedGame: GameState;\n\n const resultStep: NextStep = {\n type: \"step\",\n step: gameSteps.result,\n };\n\n if (isLastTurn && allLordsHavePlayed(updatedLord)) {\n updatedGame = {\n ...game,\n lords: updatedLord,\n nextAction: resultStep,\n };\n } else {\n updatedGame = {\n ...game,\n lords: updatedLord,\n nextAction: <NextAction>nextLordWithAction(updatedLord),\n };\n }\n\n return ok(updatedGame);\n};\n","import type { FinalResult, GameWithResults } from \"@core/domain/types/index.js\";\n\nexport type DynastyResult = {\n playerId: string;\n playerName: string;\n totalPoints: number;\n gamesPoints: number[];\n position: number;\n};\n\nexport type GetDynastyResultUseCase = (\n games: GameWithResults[]\n) => DynastyResult[];\n\nexport const getDynastyResultUseCase: GetDynastyResultUseCase = (games) => {\n // Collect all unique players\n const playerMap = new Map<string, { name: string; points: number[] }>();\n\n for (const game of games) {\n for (const result of game.result) {\n const existing = playerMap.get(result.playerId);\n if (existing) {\n existing.points.push(result.details.points);\n } else {\n playerMap.set(result.playerId, {\n name: result.playerName,\n points: [result.details.points],\n });\n }\n }\n }\n\n // Calculate totals and sort\n const results: Omit<DynastyResult, \"position\">[] = [];\n for (const [playerId, data] of playerMap) {\n results.push({\n playerId,\n playerName: data.name,\n totalPoints: data.points.reduce((sum, p) => sum + p, 0),\n gamesPoints: data.points,\n });\n }\n\n results.sort((a, b) => b.totalPoints - a.totalPoints);\n\n // Assign positions with tie detection\n const finalResults: DynastyResult[] = [];\n for (let i = 0; i < results.length; i++) {\n const current = results[i]!;\n const previous = i > 0 ? finalResults[i - 1]! : null;\n const position =\n previous && current.totalPoints === previous.totalPoints\n ? previous.position\n : i + 1;\n finalResults.push({ ...current, position });\n }\n\n return finalResults;\n};\n","import { getAvailablesExtraRules } from \"@core/domain/entities/rule.js\";\nimport type { GameMode } from \"@core/domain/types/mode.js\";\nimport type { ExtraRule } from \"@core/domain/types/rule.js\";\nimport type { RuleRepository } from \"@core/portServerside/ruleRepository.js\";\nimport { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport { err, type Result } from \"@utils/result.js\";\n\nexport type GetExtraRulesUseCase = (\n mode: GameMode[\"name\"],\n players: number\n) => Result<ExtraRule[]>;\n\nexport const getExtraRulesUseCase =\n (deps: { ruleRepository: RuleRepository }): GetExtraRulesUseCase =>\n (mode: GameMode[\"name\"], players: number): Result<ExtraRule[]> => {\n const { ruleRepository } = deps;\n\n const allExtraRules = ruleRepository.getAllExtra();\n\n if (!allExtraRules) {\n return err(ErrorCode.STEP_EXECUTION_FAILED);\n }\n\n return getAvailablesExtraRules(allExtraRules, mode, players);\n };\n","import type { GameMode } from \"@core/domain/types/mode.js\";\nimport type { ModeRepository } from \"@core/portServerside/modeRepository.js\";\nimport { ok, type Result } from \"@utils/result.js\";\n\nexport type GetModesUseCase = () => Result<GameMode[]>;\n\nexport const getModesUseCase =\n (deps: { modeRepository: ModeRepository }): GetModesUseCase =>\n (): Result<GameMode[]> => {\n const { modeRepository } = deps;\n return ok(modeRepository.getAvailables());\n };\n","import {\n checkCastleIsInMiddle,\n countDominoes,\n} from \"@core/domain/entities/kingdom.js\";\nimport type {\n FinalResult,\n GameWithNextStep,\n GameWithResults,\n ScoreResult,\n} from \"@core/domain/types/index.js\";\nimport { err, ok, type Result } from \"@utils/result.js\";\n\nexport type GetResultUseCase = (\n game: GameWithNextStep,\n scoreResult: ScoreResult[]\n) => Result<GameWithResults>;\n\nexport const getResultUseCase: GetResultUseCase = (game, scoreResult) => {\n const { rules } = game;\n const { basic, extra } = rules;\n\n const finalScoreResult = scoreResult.map((score): ScoreResult => {\n let finalScore = score.details.points;\n\n const player = game.players.find((p) => p.id === score.playerId);\n if (!player) {\n return score;\n }\n\n const { kingdom } = player;\n\n if (extra.length > 0) {\n extra.forEach((extraRule) => {\n if (extraRule.name === \"The middle Kingdom\") {\n const castleIsInMiddle = checkCastleIsInMiddle(kingdom);\n if (castleIsInMiddle) {\n finalScore += 10;\n }\n }\n\n if (extraRule.name === \"Harmony\") {\n const totalDominoes = countDominoes(kingdom);\n const dominoLimit = basic.maxDominoes;\n const totalPlayers = game.players.length;\n const dominoesPerPlayer = dominoLimit / totalPlayers;\n if (totalDominoes === dominoesPerPlayer) {\n finalScore += 5;\n }\n }\n });\n }\n\n return {\n ...score,\n details: {\n ...score.details,\n points: finalScore,\n },\n };\n });\n\n // Order players by score, then by maxPropertiesSize (per official rules, no further tiebreaker)\n finalScoreResult.sort((a, b) => {\n if (a.details.points !== b.details.points) {\n return b.details.points - a.details.points;\n }\n return b.details.maxPropertiesSize - a.details.maxPropertiesSize;\n });\n\n const result: FinalResult[] = [];\n\n let isTie = false;\n result.push({\n playerId: finalScoreResult[0]!.playerId,\n playerName: finalScoreResult[0]!.playerName,\n details: finalScoreResult[0]!.details,\n position: 1,\n });\n\n for (let i = 1; i < finalScoreResult.length; i++) {\n const currentScore = finalScoreResult[i];\n const previousScore = finalScoreResult[i - 1];\n if (\n previousScore &&\n currentScore &&\n currentScore.details.points === previousScore.details.points &&\n currentScore.details.maxPropertiesSize ===\n previousScore.details.maxPropertiesSize\n ) {\n isTie = true;\n }\n\n if (isTie) {\n result.push({\n ...currentScore!,\n position: result[i - 1]!.position,\n });\n } else {\n result.push({\n ...currentScore!,\n position: i + 1,\n });\n }\n\n isTie = false;\n }\n\n return ok({\n ...game,\n result: result,\n });\n};\n","import { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport { err, isErr, ok } from \"@utils/result.js\";\nimport {\n gameSteps,\n type GameState,\n type GameStateResult,\n type GameWithNextAction,\n type NextAction,\n type NextStep,\n} from \"@core/domain/types/game.js\";\nimport {\n allLordsHavePlayed,\n canPlaceAndDominoPickedIsDefined,\n nextLordWithAction,\n} from \"@core/domain/entities/lord.js\";\nimport { placeDomino } from \"@core/domain/entities/kingdom.js\";\nimport { playerActions } from \"@core/domain/types/player.js\";\nimport type {\n Position,\n Rotation,\n} from \"@core/domain/types/kingdom.js\";\n\nexport type PlaceDominoUseCase = (\n game: GameWithNextAction,\n lordId: string,\n position: Position,\n rotation: Rotation\n) => GameStateResult;\n\nexport const placeDominoUseCase: PlaceDominoUseCase = (\n game,\n lordId,\n position,\n rotation\n) => {\n const nextAction = game.nextAction;\n\n const currentLord = game.lords.find(\n (lord) => lord.id === nextAction.nextLord\n );\n\n if (!currentLord) {\n return err(ErrorCode.LORD_NOT_FOUND);\n }\n\n if (currentLord.id !== lordId) {\n return err(ErrorCode.NOT_YOUR_TURN);\n }\n\n if (!canPlaceAndDominoPickedIsDefined(currentLord)) {\n return err(ErrorCode.CANNOT_PLACE);\n }\n\n const domino = currentLord.dominoPicked;\n\n const currentPlayer = game.players.find(\n (player) => player.id === currentLord.playerId\n );\n\n if (!currentPlayer) {\n return err(ErrorCode.PLAYER_NOT_FOUND);\n }\n\n const updatedKingdom = placeDomino(\n currentPlayer.kingdom,\n position,\n rotation,\n domino,\n game.rules.basic.maxKingdomSize\n );\n\n if (isErr(updatedKingdom)) {\n return updatedKingdom;\n }\n\n const updatedPlayers = game.players.map((player) => {\n if (player.id === currentPlayer.id) {\n player.kingdom = updatedKingdom.value;\n }\n return player;\n });\n\n const maxTurns = game.rules.basic.maxTurns;\n const currentTurn = game.turn;\n const isLastTurn = currentTurn === maxTurns;\n\n const updatedLords = game.lords.map((lord) => {\n if (lord.id === currentLord.id) {\n if (isLastTurn) {\n return {\n ...lord,\n turnEnded: true,\n hasPlace: true,\n };\n }\n return {\n ...lord,\n hasPlace: true,\n };\n }\n return lord;\n });\n\n let updatedGame: GameState;\n\n const resultStep: NextStep = {\n type: \"step\",\n step: gameSteps.result,\n };\n\n const isQueenDomino = game.mode.name === \"QueenDomino\";\n\n if (isLastTurn && allLordsHavePlayed(updatedLords)) {\n updatedGame = {\n ...game,\n lords: updatedLords,\n nextAction: resultStep,\n players: updatedPlayers,\n };\n } else if (isQueenDomino && !isLastTurn) {\n // In QueenDomino, after placing a domino, the same lord gets optional actions\n updatedGame = {\n ...game,\n lords: updatedLords,\n nextAction: {\n type: \"action\",\n nextLord: currentLord.id,\n nextAction: playerActions.placeKnight,\n },\n players: updatedPlayers,\n };\n } else if (isQueenDomino && isLastTurn) {\n // Last turn in QueenDomino: optional actions before checking if all lords done\n const queenDominoAction: NextAction = {\n type: \"action\",\n nextLord: currentLord.id,\n nextAction: playerActions.placeKnight,\n };\n updatedGame = {\n ...game,\n lords: updatedLords,\n nextAction: queenDominoAction,\n players: updatedPlayers,\n };\n } else {\n updatedGame = {\n ...game,\n lords: updatedLords,\n nextAction: <NextAction>nextLordWithAction(updatedLords),\n players: updatedPlayers,\n };\n }\n\n return ok(updatedGame);\n};\n","import type { Kingdom, Position } from \"@core/domain/types/kingdom.js\";\nimport type { Knight, Player } from \"@core/domain/types/player.js\";\nimport { addCoins, MAX_KNIGHTS } from \"./economy.js\";\n\n/**\n * Count construction squares in the contiguous territory containing the given position.\n * Uses BFS flood-fill on same terrain type.\n */\nexport const countConstructionSquaresInTerritory = (\n kingdom: Kingdom,\n position: Position,\n): number => {\n const rows = kingdom.length;\n const cols = kingdom[0]?.length ?? 0;\n const startTile = kingdom[position.y]?.[position.x];\n\n if (\n !startTile ||\n startTile.type === \"empty\" ||\n startTile.type === \"castle\"\n ) {\n return 0;\n }\n\n const terrainType = startTile.type;\n const visited: boolean[][] = kingdom.map((row) => row.map(() => false));\n const queue: [number, number][] = [[position.x, position.y]];\n visited[position.y]![position.x] = true;\n let count = 0;\n\n const directions = [\n [-1, 0],\n [1, 0],\n [0, -1],\n [0, 1],\n ];\n\n while (queue.length > 0) {\n const [cx, cy] = queue.pop()!;\n const tile = kingdom[cy]![cx]!;\n\n if (\n tile.type !== \"empty\" &&\n tile.type !== \"castle\" &&\n \"hasConstructionSquare\" in tile &&\n tile.hasConstructionSquare\n ) {\n count++;\n }\n\n for (const [dx, dy] of directions) {\n const nx = cx + (dx as number);\n const ny = cy + (dy as number);\n if (\n nx >= 0 &&\n ny >= 0 &&\n nx < cols &&\n ny < rows &&\n !visited[ny]![nx] &&\n kingdom[ny]![nx]!.type === terrainType\n ) {\n visited[ny]![nx] = true;\n queue.push([nx, ny]);\n }\n }\n }\n\n return count;\n};\n\n/**\n * Get the terrain type at a position to identify the territory.\n */\nconst getTerritoryTerrain = (\n kingdom: Kingdom,\n position: Position,\n): string | null => {\n const tile = kingdom[position.y]?.[position.x];\n if (!tile || tile.type === \"empty\" || tile.type === \"castle\") return null;\n return tile.type;\n};\n\n/**\n * Check if a territory (identified by BFS from position) already has a knight.\n */\nconst territoryHasKnight = (\n kingdom: Kingdom,\n position: Position,\n knights: Knight[],\n): boolean => {\n const terrain = getTerritoryTerrain(kingdom, position);\n if (!terrain) return false;\n\n // BFS to find all positions in this territory\n const rows = kingdom.length;\n const cols = kingdom[0]?.length ?? 0;\n const visited: boolean[][] = kingdom.map((row) => row.map(() => false));\n const queue: [number, number][] = [[position.x, position.y]];\n visited[position.y]![position.x] = true;\n const territoryPositions = new Set<string>();\n\n const directions = [\n [-1, 0],\n [1, 0],\n [0, -1],\n [0, 1],\n ];\n\n while (queue.length > 0) {\n const [cx, cy] = queue.pop()!;\n territoryPositions.add(`${cx},${cy}`);\n\n for (const [dx, dy] of directions) {\n const nx = cx + (dx as number);\n const ny = cy + (dy as number);\n if (\n nx >= 0 &&\n ny >= 0 &&\n nx < cols &&\n ny < rows &&\n !visited[ny]![nx] &&\n kingdom[ny]![nx]!.type === terrain\n ) {\n visited[ny]![nx] = true;\n queue.push([nx, ny]);\n }\n }\n }\n\n return knights.some((k) =>\n territoryPositions.has(`${k.position.x},${k.position.y}`),\n );\n};\n\nexport const canPlaceKnight = (\n player: Player,\n kingdom: Kingdom,\n position: Position,\n): boolean => {\n const knights = player.knights ?? [];\n if (knights.length >= MAX_KNIGHTS) return false;\n\n const tile = kingdom[position.y]?.[position.x];\n if (!tile || tile.type === \"empty\" || tile.type === \"castle\") return false;\n\n if (territoryHasKnight(kingdom, position, knights)) return false;\n\n return true;\n};\n\nexport const placeKnight = (\n player: Player,\n kingdom: Kingdom,\n position: Position,\n): Player => {\n const knight: Knight = { playerId: player.id, position };\n const knights = [...(player.knights ?? []), knight];\n const taxAmount = countConstructionSquaresInTerritory(kingdom, position);\n const updatedPlayer = addCoins({ ...player, knights }, taxAmount);\n\n return updatedPlayer;\n};\n","import { canPlaceKnight, placeKnight } from \"@core/domain/entities/knight.js\";\nimport { nextQueenDominoAction } from \"@core/domain/entities/lord.js\";\nimport { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport type { GameStateResult, GameWithNextAction } from \"@core/domain/types/game.js\";\nimport type { Position } from \"@core/domain/types/kingdom.js\";\nimport { playerActions } from \"@core/domain/types/player.js\";\nimport { err, ok } from \"@utils/result.js\";\n\nexport type PlaceKnightUseCase = (\n game: GameWithNextAction,\n lordId: string,\n position: Position,\n) => GameStateResult;\n\nexport const placeKnightUseCase: PlaceKnightUseCase = (\n game,\n lordId,\n position,\n) => {\n const currentAction = game.nextAction;\n\n if (currentAction.nextLord !== lordId) {\n return err(ErrorCode.NOT_YOUR_TURN);\n }\n\n if (currentAction.nextAction !== playerActions.placeKnight) {\n return err(ErrorCode.INVALID_OPTIONAL_ACTION);\n }\n\n const currentLord = game.lords.find((l) => l.id === lordId);\n if (!currentLord) return err(ErrorCode.LORD_NOT_FOUND);\n\n const currentPlayer = game.players.find(\n (p) => p.id === currentLord.playerId,\n );\n if (!currentPlayer) return err(ErrorCode.PLAYER_NOT_FOUND);\n\n if (!canPlaceKnight(currentPlayer, currentPlayer.kingdom, position)) {\n return err(ErrorCode.CANNOT_PLACE_KNIGHT);\n }\n\n const updatedPlayer = placeKnight(\n currentPlayer,\n currentPlayer.kingdom,\n position,\n );\n\n const updatedPlayers = game.players.map((p) =>\n p.id === currentPlayer.id ? updatedPlayer : p,\n );\n\n const nextAction = nextQueenDominoAction(playerActions.placeKnight);\n\n return ok({\n ...game,\n players: updatedPlayers,\n nextAction: {\n type: \"action\",\n nextLord: lordId,\n nextAction: nextAction,\n },\n });\n};\n","import type {\n BuildersBoard,\n BuildingTile,\n PlacedBuilding,\n} from \"@core/domain/types/building.js\";\nimport type { Kingdom, Position } from \"@core/domain/types/kingdom.js\";\nimport type { Player } from \"@core/domain/types/player.js\";\nimport type { ShuffleMethod } from \"@core/portServerside/shuffleMethod.js\";\nimport { addCoins, addTowers, canAfford, removeCoins } from \"./economy.js\";\n\n/** Number of visible building slots on the Builders Board */\nconst BOARD_SLOTS = 4;\n\nexport const createBuildersBoard = (\n tiles: BuildingTile[],\n shuffle: ShuffleMethod,\n): BuildersBoard => {\n const shuffled = shuffle([...tiles]);\n const slots = shuffled.slice(0, BOARD_SLOTS);\n const drawPile = shuffled.slice(BOARD_SLOTS);\n\n return {\n slots,\n drawPile,\n };\n};\n\nexport const refillBuildersBoard = (board: BuildersBoard): BuildersBoard => {\n const newSlots = [...board.slots];\n const newDrawPile = [...board.drawPile];\n\n for (let i = 0; i < newSlots.length; i++) {\n if (newSlots[i] === null && newDrawPile.length > 0) {\n newSlots[i] = newDrawPile.shift()!;\n }\n }\n\n return { slots: newSlots, drawPile: newDrawPile };\n};\n\nexport const findBuildingOnBoard = (\n board: BuildersBoard,\n buildingId: number,\n): { building: BuildingTile; slotIndex: number } | null => {\n for (let i = 0; i < board.slots.length; i++) {\n const slot = board.slots[i];\n if (slot && slot.id === buildingId) {\n return { building: slot, slotIndex: i };\n }\n }\n return null;\n};\n\nexport const removeBuildingFromBoard = (\n board: BuildersBoard,\n slotIndex: number,\n): BuildersBoard => {\n const newSlots = [...board.slots];\n newSlots[slotIndex] = null;\n return { ...board, slots: newSlots };\n};\n\nexport const purchaseBuilding = (\n board: BuildersBoard,\n player: Player,\n buildingId: number,\n): {\n updatedBoard: BuildersBoard;\n updatedPlayer: Player;\n building: BuildingTile;\n} | null => {\n const found = findBuildingOnBoard(board, buildingId);\n if (!found) return null;\n\n const { building, slotIndex } = found;\n if (!canAfford(player, building.cost)) return null;\n\n let updatedPlayer = removeCoins(player, building.cost);\n\n // Apply immediate bonus\n if (building.immediateBonus) {\n switch (building.immediateBonus.type) {\n case \"coins\":\n updatedPlayer = addCoins(updatedPlayer, building.immediateBonus.amount);\n break;\n case \"tower\":\n updatedPlayer = addTowers(\n updatedPlayer,\n building.immediateBonus.amount,\n );\n break;\n }\n }\n\n // Add towers from the building itself\n if (building.towers > 0) {\n updatedPlayer = addTowers(updatedPlayer, building.towers);\n }\n\n const updatedBoard = removeBuildingFromBoard(board, slotIndex);\n\n return { updatedBoard, updatedPlayer, building };\n};\n\nexport const hasOpenConstructionSquare = (\n kingdom: Kingdom,\n placedBuildings: PlacedBuilding[],\n): boolean => {\n const occupiedPositions = new Set(\n placedBuildings.map((b) => `${b.position.x},${b.position.y}`),\n );\n\n for (let y = 0; y < kingdom.length; y++) {\n const row = kingdom[y]!;\n for (let x = 0; x < row.length; x++) {\n const tile = row[x]!;\n if (\n tile.type !== \"empty\" &&\n tile.type !== \"castle\" &&\n \"hasConstructionSquare\" in tile &&\n tile.hasConstructionSquare &&\n !occupiedPositions.has(`${x},${y}`)\n ) {\n return true;\n }\n }\n }\n return false;\n};\n\nexport const isValidConstructionPosition = (\n kingdom: Kingdom,\n placedBuildings: PlacedBuilding[],\n position: Position,\n): boolean => {\n const tile = kingdom[position.y]?.[position.x];\n if (!tile || tile.type === \"empty\" || tile.type === \"castle\") return false;\n if (!(\"hasConstructionSquare\" in tile) || !tile.hasConstructionSquare)\n return false;\n\n const occupied = placedBuildings.some(\n (b) => b.position.x === position.x && b.position.y === position.y,\n );\n return !occupied;\n};\n\nexport const placeBuildingOnKingdom = (\n kingdom: Kingdom,\n building: BuildingTile,\n position: Position,\n): Kingdom => {\n // Add building crowns to the tile\n const newKingdom = kingdom.map((row) => [...row]);\n const tile = newKingdom[position.y]![position.x]!;\n\n if (tile.type !== \"empty\" && tile.type !== \"castle\") {\n newKingdom[position.y]![position.x] = {\n ...tile,\n crowns: tile.crowns + building.crowns,\n };\n }\n\n return newKingdom;\n};\n\nexport const destroyWithDragon = (\n board: BuildersBoard,\n buildingId: number,\n player: Player,\n): {\n updatedBoard: BuildersBoard;\n updatedPlayer: Player;\n} | null => {\n const found = findBuildingOnBoard(board, buildingId);\n if (!found) return null;\n\n const { building, slotIndex } = found;\n if (!canAfford(player, building.cost)) return null;\n\n const updatedPlayer = removeCoins(player, building.cost);\n const updatedBoard = removeBuildingFromBoard(board, slotIndex);\n\n return { updatedBoard, updatedPlayer };\n};\n","import type { Kingdom } from \"@core/domain/types/kingdom.js\";\nimport type { Player } from \"@core/domain/types/player.js\";\nimport { getTowerCount } from \"./economy.js\";\n\n/**\n * Determine which player should hold the Queen.\n * The player with the most towers gets the Queen.\n * If tied, the Queen doesn't move (returns current holder).\n */\nexport const determineQueenHolder = (\n players: Player[],\n currentHolderId: string | null,\n): string | null => {\n let maxTowers = 0;\n let leaderId: string | null = null;\n let isTied = false;\n\n for (const player of players) {\n const towers = getTowerCount(player);\n if (towers > maxTowers) {\n maxTowers = towers;\n leaderId = player.id;\n isTied = false;\n } else if (towers === maxTowers && towers > 0 && leaderId !== null) {\n isTied = true;\n }\n }\n\n if (isTied || maxTowers === 0) {\n return currentHolderId;\n }\n\n return leaderId;\n};\n\ntype Property = {\n size: number;\n crowns: number;\n};\n\n/**\n * Find all properties (contiguous territories) in a kingdom using BFS.\n * Returns array of { size, crowns } for each property.\n */\nconst findProperties = (kingdom: Kingdom): Property[] => {\n const rows = kingdom.length;\n const cols = kingdom[0]?.length ?? 0;\n const visited: boolean[][] = kingdom.map((row) => row.map(() => false));\n const properties: Property[] = [];\n\n const directions = [\n [-1, 0],\n [1, 0],\n [0, -1],\n [0, 1],\n ];\n\n for (let y = 0; y < rows; y++) {\n for (let x = 0; x < cols; x++) {\n const tile = kingdom[y]![x]!;\n if (\n visited[y]![x] ||\n tile.type === \"empty\" ||\n tile.type === \"castle\"\n ) {\n continue;\n }\n\n const terrainType = tile.type;\n let size = 0;\n let crowns = 0;\n const queue: [number, number][] = [[x, y]];\n visited[y]![x] = true;\n\n while (queue.length > 0) {\n const [cx, cy] = queue.pop()!;\n const current = kingdom[cy]![cx]!;\n size++;\n crowns += current.crowns;\n\n for (const [dx, dy] of directions) {\n const nx = cx + (dx as number);\n const ny = cy + (dy as number);\n if (\n nx >= 0 &&\n ny >= 0 &&\n nx < cols &&\n ny < rows &&\n !visited[ny]![nx] &&\n kingdom[ny]![nx]!.type === terrainType\n ) {\n visited[ny]![nx] = true;\n queue.push([nx, ny]);\n }\n }\n }\n\n properties.push({ size, crowns });\n }\n }\n\n return properties;\n};\n\n/**\n * Calculate the Queen bonus: +1 crown to the territory with the most crowns.\n * Returns the additional points the Queen grants.\n */\nexport const getQueenBonus = (kingdom: Kingdom): number => {\n const properties = findProperties(kingdom);\n if (properties.length === 0) return 0;\n\n // Find the property with the most crowns\n let maxCrowns = 0;\n let maxCrownProperty: Property | null = null;\n\n for (const prop of properties) {\n if (prop.crowns > maxCrowns) {\n maxCrowns = prop.crowns;\n maxCrownProperty = prop;\n }\n }\n\n if (!maxCrownProperty || maxCrownProperty.crowns === 0) return 0;\n\n // Queen adds +1 crown to this territory\n // Original score: size * crowns\n // New score: size * (crowns + 1)\n // Bonus = size * (crowns + 1) - size * crowns = size\n return maxCrownProperty.size;\n};\n\n/**\n * Calculate end-game building bonus points for a player.\n */\nexport const calculateBuildingEndGameBonus = (\n player: Player,\n): number => {\n const buildings = player.buildings ?? [];\n let bonus = 0;\n\n for (const placed of buildings) {\n const scoring = placed.building.endGameScoring;\n if (!scoring) continue;\n\n switch (scoring.type) {\n case \"flat\":\n bonus += scoring.points;\n break;\n case \"perBuilding\":\n bonus += buildings.length * scoring.points;\n break;\n case \"perTower\":\n bonus += getTowerCount(player) * scoring.points;\n break;\n case \"perCrown\": {\n const totalCrowns = countKingdomCrowns(player.kingdom);\n bonus += totalCrowns * scoring.points;\n break;\n }\n case \"perTerrain\": {\n if (scoring.terrain) {\n const count = countTerrainTiles(player.kingdom, scoring.terrain);\n bonus += count * scoring.points;\n }\n break;\n }\n }\n }\n\n return bonus;\n};\n\nconst countKingdomCrowns = (kingdom: Kingdom): number => {\n let total = 0;\n for (const row of kingdom) {\n for (const tile of row) {\n if (tile.type !== \"empty\" && tile.type !== \"castle\") {\n total += tile.crowns;\n }\n }\n }\n return total;\n};\n\nconst countTerrainTiles = (kingdom: Kingdom, terrain: string): number => {\n let count = 0;\n for (const row of kingdom) {\n for (const tile of row) {\n if (tile.type === terrain) {\n count++;\n }\n }\n }\n return count;\n};\n","import {\n isValidConstructionPosition,\n placeBuildingOnKingdom,\n purchaseBuilding,\n} from \"@core/domain/entities/building.js\";\nimport { nextQueenDominoAction } from \"@core/domain/entities/lord.js\";\nimport { determineQueenHolder } from \"@core/domain/entities/queen.js\";\nimport { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport type { PlacedBuilding } from \"@core/domain/types/building.js\";\nimport type {\n GameStateResult,\n GameWithNextAction,\n} from \"@core/domain/types/game.js\";\nimport type { Position } from \"@core/domain/types/kingdom.js\";\nimport { playerActions } from \"@core/domain/types/player.js\";\nimport { err, ok } from \"@utils/result.js\";\n\nexport type ConstructBuildingUseCase = (\n game: GameWithNextAction,\n lordId: string,\n buildingId: number,\n position: Position,\n) => GameStateResult;\n\nexport const constructBuildingUseCase: ConstructBuildingUseCase = (\n game,\n lordId,\n buildingId,\n position,\n) => {\n const currentAction = game.nextAction;\n\n if (currentAction.nextLord !== lordId) {\n return err(ErrorCode.NOT_YOUR_TURN);\n }\n\n if (currentAction.nextAction !== playerActions.constructBuilding) {\n return err(ErrorCode.INVALID_OPTIONAL_ACTION);\n }\n\n if (!game.queendomino) {\n return err(ErrorCode.INVALID_OPTIONAL_ACTION);\n }\n\n const currentLord = game.lords.find((l) => l.id === lordId);\n if (!currentLord) return err(ErrorCode.LORD_NOT_FOUND);\n\n const currentPlayer = game.players.find(\n (p) => p.id === currentLord.playerId,\n );\n if (!currentPlayer) return err(ErrorCode.PLAYER_NOT_FOUND);\n\n // Validate construction position\n if (\n !isValidConstructionPosition(\n currentPlayer.kingdom,\n currentPlayer.buildings ?? [],\n position,\n )\n ) {\n return err(ErrorCode.NO_CONSTRUCTION_SQUARE);\n }\n\n // Purchase the building\n const purchaseResult = purchaseBuilding(\n game.queendomino.buildersBoard,\n currentPlayer,\n buildingId,\n );\n\n if (!purchaseResult) {\n return err(ErrorCode.CANNOT_AFFORD_BUILDING);\n }\n\n const { updatedBoard, updatedPlayer, building } = purchaseResult;\n\n // Place building on kingdom (adds crowns)\n const updatedKingdom = placeBuildingOnKingdom(\n updatedPlayer.kingdom,\n building,\n position,\n );\n\n const placedBuilding: PlacedBuilding = { building, position };\n const finalPlayer = {\n ...updatedPlayer,\n kingdom: updatedKingdom,\n buildings: [...(updatedPlayer.buildings ?? []), placedBuilding],\n };\n\n const updatedPlayers = game.players.map((p) =>\n p.id === currentPlayer.id ? finalPlayer : p,\n );\n\n // Recalculate Queen holder\n const newQueenHolder = determineQueenHolder(\n updatedPlayers,\n game.queendomino.queenHolderId,\n );\n\n const nextAction = nextQueenDominoAction(playerActions.constructBuilding);\n\n return ok({\n ...game,\n players: updatedPlayers,\n queendomino: {\n ...game.queendomino,\n buildersBoard: updatedBoard,\n queenHolderId: newQueenHolder,\n },\n nextAction: {\n type: \"action\",\n nextLord: lordId,\n nextAction: nextAction,\n },\n });\n};\n","import { destroyWithDragon } from \"@core/domain/entities/building.js\";\nimport {\n allLordsHavePlayed,\n nextLordWithAction,\n} from \"@core/domain/entities/lord.js\";\nimport { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport {\n gameSteps,\n type GameStateResult,\n type GameWithNextAction,\n type NextAction,\n} from \"@core/domain/types/game.js\";\nimport { playerActions } from \"@core/domain/types/player.js\";\nimport { err, ok } from \"@utils/result.js\";\n\nexport type UseDragonUseCase = (\n game: GameWithNextAction,\n lordId: string,\n buildingId: number,\n) => GameStateResult;\n\nexport const useDragonUseCase: UseDragonUseCase = (\n game,\n lordId,\n buildingId,\n) => {\n const currentAction = game.nextAction;\n\n if (currentAction.nextLord !== lordId) {\n return err(ErrorCode.NOT_YOUR_TURN);\n }\n\n if (currentAction.nextAction !== playerActions.useDragon) {\n return err(ErrorCode.INVALID_OPTIONAL_ACTION);\n }\n\n if (!game.queendomino) {\n return err(ErrorCode.INVALID_OPTIONAL_ACTION);\n }\n\n if (!game.queendomino.dragonAvailable || game.queendomino.dragonUsedThisRound) {\n return err(ErrorCode.DRAGON_UNAVAILABLE);\n }\n\n const currentLord = game.lords.find((l) => l.id === lordId);\n if (!currentLord) return err(ErrorCode.LORD_NOT_FOUND);\n\n const currentPlayer = game.players.find(\n (p) => p.id === currentLord.playerId,\n );\n if (!currentPlayer) return err(ErrorCode.PLAYER_NOT_FOUND);\n\n // Queen holder cannot use dragon\n if (game.queendomino.queenHolderId === currentPlayer.id) {\n return err(ErrorCode.QUEEN_HOLDER_CANNOT_USE_DRAGON);\n }\n\n const result = destroyWithDragon(\n game.queendomino.buildersBoard,\n buildingId,\n currentPlayer,\n );\n\n if (!result) {\n return err(ErrorCode.BUILDING_NOT_FOUND);\n }\n\n const { updatedBoard, updatedPlayer } = result;\n\n const updatedPlayers = game.players.map((p) =>\n p.id === currentPlayer.id ? updatedPlayer : p,\n );\n\n // After dragon, advance to pickDomino (or result)\n const maxTurns = game.rules.basic.maxTurns;\n const isLastTurn = game.turn === maxTurns;\n\n if (isLastTurn && allLordsHavePlayed(game.lords)) {\n return ok({\n ...game,\n players: updatedPlayers,\n queendomino: {\n ...game.queendomino,\n buildersBoard: updatedBoard,\n dragonUsedThisRound: true,\n },\n nextAction: { type: \"step\", step: gameSteps.result },\n });\n }\n\n return ok({\n ...game,\n players: updatedPlayers,\n queendomino: {\n ...game.queendomino,\n buildersBoard: updatedBoard,\n dragonUsedThisRound: true,\n },\n nextAction: <NextAction>nextLordWithAction(game.lords),\n });\n};\n","import {\n allLordsHavePlayed,\n nextLordWithAction,\n nextQueenDominoAction,\n} from \"@core/domain/entities/lord.js\";\nimport { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport {\n gameSteps,\n type GameStateResult,\n type GameWithNextAction,\n type NextAction,\n} from \"@core/domain/types/game.js\";\nimport { playerActions } from \"@core/domain/types/player.js\";\nimport { err, ok } from \"@utils/result.js\";\n\nexport type SkipOptionalActionUseCase = (\n game: GameWithNextAction,\n lordId: string,\n) => GameStateResult;\n\nexport const skipOptionalActionUseCase: SkipOptionalActionUseCase = (\n game,\n lordId,\n) => {\n const currentAction = game.nextAction;\n\n if (currentAction.nextLord !== lordId) {\n return err(ErrorCode.NOT_YOUR_TURN);\n }\n\n const action = currentAction.nextAction;\n const isOptional =\n action === playerActions.placeKnight ||\n action === playerActions.constructBuilding ||\n action === playerActions.useDragon;\n\n if (!isOptional) {\n return err(ErrorCode.INVALID_OPTIONAL_ACTION);\n }\n\n const nextAction = nextQueenDominoAction(action);\n\n if (nextAction === playerActions.pickDomino) {\n // Done with optional actions, advance to next lord or result\n const maxTurns = game.rules.basic.maxTurns;\n const isLastTurn = game.turn === maxTurns;\n\n if (isLastTurn && allLordsHavePlayed(game.lords)) {\n return ok({\n ...game,\n nextAction: { type: \"step\", step: gameSteps.result },\n });\n }\n\n return ok({\n ...game,\n nextAction: <NextAction>nextLordWithAction(game.lords),\n });\n }\n\n return ok({\n ...game,\n nextAction: {\n type: \"action\",\n nextLord: lordId,\n nextAction: nextAction,\n },\n });\n};\n","import { createBuildersBoard } from \"@core/domain/entities/building.js\";\nimport { createLord } from \"@core/domain/entities/lord\";\nimport type {\n GameWithNextAction,\n GameWithNextStep,\n NextAction,\n} from \"@core/domain/types/game.js\";\nimport type { Lord } from \"@core/domain/types/lord.js\";\nimport { playerActions } from \"@core/domain/types/player.js\";\nimport type { ShuffleMethod } from \"@core/portServerside/shuffleMethod.js\";\nimport type { UuidMethod } from \"@core/portServerside/uuidMethod.js\";\nimport { ok, type Result } from \"@utils/result.js\";\nimport { createSeededShuffle } from \"@utils/seededShuffle.js\";\n\nexport type StartGameUseCase = (\n game: GameWithNextStep\n) => Result<GameWithNextAction>;\n\nexport const startGameUseCase =\n (deps: {\n uuidMethod: UuidMethod;\n shuffleMethod: ShuffleMethod;\n }): StartGameUseCase =>\n (game) => {\n const { uuidMethod, shuffleMethod } = deps;\n const {\n rules: {\n basic: { lords: maxLords, dominoesPerTurn },\n },\n players,\n dominoes,\n } = game;\n\n const numberOfPlayers = players.length;\n\n const newLords: Lord[] = [];\n\n for (let i = 0; i < numberOfPlayers; i++) {\n for (let j = 0; j < maxLords; j++) {\n const lord = createLord(uuidMethod(), players[i]!.id);\n newLords.push(lord);\n }\n }\n\n const shuffle = game.seed\n ? createSeededShuffle(game.seed, \"lords\")\n : shuffleMethod;\n const shuffledLords = shuffle(newLords);\n const dominoesCopy = [...dominoes];\n const dominoesDrawn = dominoesCopy.splice(0, dominoesPerTurn);\n dominoesDrawn.sort((a, b) => a.number - b.number);\n const nextAction: NextAction = {\n type: \"action\",\n nextLord: shuffledLords[0]!.id,\n nextAction: playerActions.pickDomino,\n };\n\n // Setup Builders Board for QueenDomino mode\n let queendomino = game.queendomino;\n if (queendomino && game.mode.name === \"QueenDomino\") {\n const buildingShuffle = game.seed\n ? createSeededShuffle(game.seed, \"buildings\")\n : shuffleMethod;\n const board = createBuildersBoard(\n queendomino.buildersBoard.drawPile,\n buildingShuffle,\n );\n queendomino = { ...queendomino, buildersBoard: board };\n }\n\n const newState: GameWithNextAction = {\n ...game,\n lords: shuffledLords,\n nextAction,\n dominoes: dominoesCopy,\n currentDominoes: dominoesDrawn.map((domino, index) => {\n return {\n domino,\n picked: false,\n lordId: null,\n position: index + 1,\n };\n }),\n ...(queendomino !== undefined && { queendomino }),\n };\n\n return ok(newState);\n };\n","import { consoleLogger, silentLogger } from \"@adapter/consoleLogger.js\";\nimport jsonBuildings from \"@adapter/jsonBuildings.js\";\nimport jsonDominoes from \"@adapter/jsonDominoes.js\";\nimport jsonModes from \"@adapter/jsonModes.js\";\nimport jsonRules from \"@adapter/jsonRules.js\";\nimport { shuffleMethod } from \"@adapter/shuffle.js\";\nimport { uuidMethod } from \"@adapter/uuid.js\";\nimport { addExtraRulesHandler } from \"@application/handlers/addExtraRulesHandler.js\";\nimport { addPlayersHandler } from \"@application/handlers/addPlayersHandler.js\";\nimport { calculateScoreHandler } from \"@application/handlers/calculateScoreHandler.js\";\nimport { canPlaceDominoHandler } from \"@application/handlers/canPlaceDominoHandler.js\";\nimport { chooseDominoHandler } from \"@application/handlers/chooseDominoHandler.js\";\nimport { createGameHandler } from \"@application/handlers/createGameHandler.js\";\nimport { discardDominoHandler } from \"@application/handlers/discardDominoHandler.js\";\nimport { getDynastyResultHandler } from \"@application/handlers/getDynastyResultHandler.js\";\nimport { getExtraRulesHandler } from \"@application/handlers/getExtraRulesHandler.js\";\nimport { getModesHandler } from \"@application/handlers/getModesHandler.js\";\nimport { getResultHandler } from \"@application/handlers/getResultHandler.js\";\nimport { getValidPlacementsHandler } from \"@application/handlers/getValidPlacementsHandler.js\";\nimport { placeDominoHandler } from \"@application/handlers/placeDominoHandler.js\";\nimport {\n deserializeGameHandler,\n serializeGameHandler,\n} from \"@application/handlers/serializeGameHandler.js\";\nimport { startGameHandler } from \"@application/handlers/startGameHandler.js\";\nimport { placeKnightHandler } from \"@application/handlers/placeKnightHandler.js\";\nimport { constructBuildingHandler } from \"@application/handlers/constructBuildingHandler.js\";\nimport { useDragonHandler } from \"@application/handlers/useDragonHandler.js\";\nimport { skipOptionalActionHandler } from \"@application/handlers/skipOptionalActionHandler.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport type { GameEngine } from \"@core/portUserside/engine.js\";\nimport { defaultTranslator } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { ShuffleMethod } from \"@core/portServerside/shuffleMethod.js\";\nimport type { UuidMethod } from \"@core/portServerside/uuidMethod.js\";\nimport { addExtraRulesUseCase } from \"@core/useCases/addExtraRules.js\";\nimport { addPlayersUseCase } from \"@core/useCases/addPlayers.js\";\nimport { calculateScoreUseCase } from \"@core/useCases/calculateScore.js\";\nimport { chooseDominoUseCase } from \"@core/useCases/chooseDomino.js\";\nimport { createGameUseCase } from \"@core/useCases/createGame.js\";\nimport { discardDominoUseCase } from \"@core/useCases/discardDomino.js\";\nimport type { DebugOptions } from \"@core/useCases/gameDebug.js\";\nimport type { GameEventCallbacks } from \"@core/useCases/gameEvents.js\";\nimport { getDynastyResultUseCase } from \"@core/useCases/getDynastyResult.js\";\nimport { getExtraRulesUseCase } from \"@core/useCases/getExtraRules.js\";\nimport { getModesUseCase } from \"@core/useCases/getModes.js\";\nimport { getResultUseCase } from \"@core/useCases/getResult.js\";\nimport {\n canPlaceDominoUseCase,\n getValidPlacementsUseCase,\n} from \"@core/useCases/getValidPlacements.js\";\nimport { placeDominoUseCase } from \"@core/useCases/placeDomino.js\";\nimport { placeKnightUseCase } from \"@core/useCases/placeKnight.js\";\nimport { constructBuildingUseCase } from \"@core/useCases/constructBuilding.js\";\nimport { useDragonUseCase } from \"@core/useCases/useDragon.js\";\nimport { skipOptionalActionUseCase } from \"@core/useCases/skipOptionalAction.js\";\nimport { startGameUseCase } from \"@core/useCases/startGame.js\";\n\n/**\n * Configuration options for the game engine.\n */\nexport type EngineConfig = {\n /** Custom UUID generation method. Defaults to crypto.randomUUID() */\n uuidMethod?: UuidMethod;\n /** Custom shuffle method. Defaults to Fisher-Yates algorithm */\n shuffleMethod?: ShuffleMethod;\n /** Enable console logging. Defaults to false */\n logging?: boolean;\n /** Custom logger instance. When provided, takes precedence over 'logging' option */\n logger?: Logger;\n /** Optional event callbacks for UI/animation integration */\n events?: GameEventCallbacks;\n /** Custom translator for i18n error messages. Defaults to English */\n translator?: Translator;\n /** Enable debug mode with detailed logging. Pass `true` for defaults or a `DebugOptions` object. */\n debug?: boolean | DebugOptions;\n};\n\nexport type ConfiguredHandlers = {\n createGameHandler: GameEngine[\"createGame\"];\n getModesHandler: GameEngine[\"getModes\"];\n getExtraRulesHandler: GameEngine[\"getExtraRules\"];\n addPlayersHandler: GameEngine[\"addPlayers\"];\n addExtraRulesHandler: GameEngine[\"addExtraRules\"];\n startGameHandler: GameEngine[\"startGame\"];\n chooseDominoHandler: GameEngine[\"chooseDomino\"];\n placeDominoHandler: GameEngine[\"placeDomino\"];\n discardDominoHandler: GameEngine[\"discardDomino\"];\n getResultHandler: GameEngine[\"getResults\"];\n calculateScoreHandler: GameEngine[\"calculateScore\"];\n getValidPlacementsHandler: GameEngine[\"getValidPlacements\"];\n canPlaceDominoHandler: GameEngine[\"canPlaceDomino\"];\n serializeGameHandler: GameEngine[\"serialize\"];\n deserializeGameHandler: GameEngine[\"deserialize\"];\n getDynastyResultHandler: GameEngine[\"getDynastyResults\"];\n placeKnightHandler: GameEngine[\"placeKnight\"];\n constructBuildingHandler: GameEngine[\"constructBuilding\"];\n useDragonHandler: GameEngine[\"useDragon\"];\n skipOptionalActionHandler: GameEngine[\"skipOptionalAction\"];\n};\n\nexport const configureEngine = (config: Partial<EngineConfig>): ConfiguredHandlers => {\n const modeRepository = jsonModes();\n const dominoesRepository = jsonDominoes();\n const buildingsRepository = jsonBuildings();\n const ruleRepository = jsonRules();\n const uuid = config.uuidMethod || uuidMethod;\n const shuffle = config.shuffleMethod || shuffleMethod;\n const translator = config.translator || defaultTranslator;\n\n // Logger priority: custom logger > logging flag > silent\n const logger = config.logger\n ? config.logger\n : config.logging\n ? consoleLogger(true)\n : silentLogger;\n\n return {\n createGameHandler: createGameHandler(\n logger,\n translator,\n createGameUseCase({\n modeRepository,\n dominoesRepository,\n uuidMethod: uuid,\n buildingsRepository,\n }),\n ),\n getModesHandler: getModesHandler(\n logger,\n translator,\n getModesUseCase({ modeRepository }),\n ),\n getExtraRulesHandler: getExtraRulesHandler(\n logger,\n translator,\n getExtraRulesUseCase({ ruleRepository }),\n ),\n addPlayersHandler: addPlayersHandler(\n logger,\n translator,\n addPlayersUseCase({\n uuidMethod: uuid,\n shuffleMethod: shuffle,\n ruleRepository,\n }),\n ),\n addExtraRulesHandler: addExtraRulesHandler(\n logger,\n translator,\n addExtraRulesUseCase({\n ruleRepository,\n dominoesRepository,\n shuffleMethod: shuffle,\n }),\n ),\n startGameHandler: startGameHandler(\n logger,\n translator,\n startGameUseCase({ uuidMethod: uuid, shuffleMethod: shuffle }),\n ),\n chooseDominoHandler: chooseDominoHandler(\n logger,\n translator,\n chooseDominoUseCase,\n ),\n placeDominoHandler: placeDominoHandler(\n logger,\n translator,\n placeDominoUseCase,\n ),\n discardDominoHandler: discardDominoHandler(\n logger,\n translator,\n discardDominoUseCase,\n ),\n getResultHandler: getResultHandler(logger, translator, {\n getResultUseCase,\n calculateScoreUseCase,\n }),\n calculateScoreHandler: calculateScoreHandler(\n logger,\n translator,\n calculateScoreUseCase,\n ),\n getValidPlacementsHandler: getValidPlacementsHandler(\n logger,\n translator,\n getValidPlacementsUseCase,\n ),\n canPlaceDominoHandler: canPlaceDominoHandler(\n logger,\n translator,\n canPlaceDominoUseCase,\n ),\n serializeGameHandler: serializeGameHandler(logger, translator),\n deserializeGameHandler: deserializeGameHandler(logger, translator),\n getDynastyResultHandler: getDynastyResultHandler(\n logger,\n translator,\n getDynastyResultUseCase,\n ),\n placeKnightHandler: placeKnightHandler(\n logger,\n translator,\n placeKnightUseCase,\n ),\n constructBuildingHandler: constructBuildingHandler(\n logger,\n translator,\n constructBuildingUseCase,\n ),\n useDragonHandler: useDragonHandler(\n logger,\n translator,\n useDragonUseCase,\n ),\n skipOptionalActionHandler: skipOptionalActionHandler(\n logger,\n translator,\n skipOptionalActionUseCase,\n ),\n };\n};\n","import { GROUND } from \"@core/domain/types/domino.js\";\nimport type { Game } from \"@core/domain/types/game.js\";\nimport { gameSteps } from \"@core/domain/types/game.js\";\nimport { GRIDSIZE } from \"@core/domain/types/kingdom.js\";\nimport { playerActions } from \"@core/domain/types/player.js\";\nimport type { ValidationIssue, ValidationSeverity } from \"@core/domain/types/validation.js\";\n\nconst issue = (\n path: string,\n code: string,\n message: string,\n severity: ValidationSeverity = \"error\",\n): ValidationIssue => ({ path, code, message, severity });\n\nconst isNonEmptyString = (value: unknown): value is string =>\n typeof value === \"string\" && value.length > 0;\n\nconst isNonNegativeInteger = (value: unknown): value is number =>\n typeof value === \"number\" && Number.isInteger(value) && value >= 0;\n\nconst isPositiveInteger = (value: unknown): value is number =>\n typeof value === \"number\" && Number.isInteger(value) && value > 0;\n\nconst validGrounds = new Set<string>([...GROUND, \"empty\"]);\nconst validPlayerActions = new Set<string>(Object.values(playerActions));\nconst validGameSteps = new Set<string>(Object.values(gameSteps));\n\n// --- Validation sub-functions ---\n\nconst validateGameStructure = (game: Game): ValidationIssue[] => {\n const issues: ValidationIssue[] = [];\n\n if (!isNonEmptyString(game.id)) {\n issues.push(issue(\"id\", \"INVALID_ID\", \"Game id must be a non-empty string\"));\n }\n if (!isNonNegativeInteger(game.turn)) {\n issues.push(issue(\"turn\", \"INVALID_TURN\", \"Turn must be a non-negative integer\"));\n }\n if (!Array.isArray(game.dominoes)) {\n issues.push(issue(\"dominoes\", \"INVALID_DOMINOES\", \"Dominoes must be an array\"));\n }\n if (!Array.isArray(game.currentDominoes)) {\n issues.push(issue(\"currentDominoes\", \"INVALID_CURRENT_DOMINOES\", \"CurrentDominoes must be an array\"));\n }\n if (!Array.isArray(game.players)) {\n issues.push(issue(\"players\", \"INVALID_PLAYERS\", \"Players must be an array\"));\n }\n if (!Array.isArray(game.lords)) {\n issues.push(issue(\"lords\", \"INVALID_LORDS\", \"Lords must be an array\"));\n }\n if (!game.rules || typeof game.rules !== \"object\") {\n issues.push(issue(\"rules\", \"INVALID_RULES\", \"Rules must be an object\"));\n } else {\n if (!game.rules.basic || typeof game.rules.basic !== \"object\") {\n issues.push(issue(\"rules.basic\", \"INVALID_BASIC_RULES\", \"Rules.basic must be an object\"));\n }\n if (!Array.isArray(game.rules.extra)) {\n issues.push(issue(\"rules.extra\", \"INVALID_EXTRA_RULES\", \"Rules.extra must be an array\"));\n }\n }\n if (!game.mode || typeof game.mode !== \"object\") {\n issues.push(issue(\"mode\", \"INVALID_MODE\", \"Mode must be an object\"));\n } else {\n if (!isNonEmptyString(game.mode.name)) {\n issues.push(issue(\"mode.name\", \"INVALID_MODE_NAME\", \"Mode name must be a non-empty string\"));\n }\n }\n if (!game.nextAction || typeof game.nextAction !== \"object\") {\n issues.push(issue(\"nextAction\", \"INVALID_NEXT_ACTION\", \"NextAction must be an object\"));\n } else if (game.nextAction.type !== \"action\" && game.nextAction.type !== \"step\") {\n issues.push(issue(\"nextAction.type\", \"INVALID_NEXT_ACTION_TYPE\", \"NextAction.type must be 'action' or 'step'\"));\n }\n\n return issues;\n};\n\nconst validateTile = (tile: unknown, path: string): ValidationIssue[] => {\n const issues: ValidationIssue[] = [];\n if (!tile || typeof tile !== \"object\") {\n issues.push(issue(path, \"INVALID_TILE\", `Tile at ${path} must be an object`));\n return issues;\n }\n const t = tile as Record<string, unknown>;\n if (typeof t.type !== \"string\" || !validGrounds.has(t.type)) {\n issues.push(issue(`${path}.type`, \"INVALID_TILE_TYPE\", `Invalid terrain type at ${path}`));\n }\n if (typeof t.crowns !== \"number\" || t.crowns < 0) {\n issues.push(issue(`${path}.crowns`, \"INVALID_TILE_CROWNS\", `Invalid crowns at ${path}`));\n }\n return issues;\n};\n\nconst validatePlayers = (game: Game): ValidationIssue[] => {\n const issues: ValidationIssue[] = [];\n if (!Array.isArray(game.players)) return issues;\n\n const playerIds = new Set<string>();\n for (let i = 0; i < game.players.length; i++) {\n const player = game.players[i]!;\n const path = `players[${i}]`;\n\n if (!isNonEmptyString(player.id)) {\n issues.push(issue(`${path}.id`, \"INVALID_PLAYER_ID\", `Player id must be a non-empty string`));\n } else if (playerIds.has(player.id)) {\n issues.push(issue(`${path}.id`, \"DUPLICATE_PLAYER_ID\", `Duplicate player id: ${player.id}`));\n } else {\n playerIds.add(player.id);\n }\n\n if (typeof player.name !== \"string\" || player.name.length < 3) {\n issues.push(issue(`${path}.name`, \"INVALID_PLAYER_NAME\", `Player name must be at least 3 characters`));\n }\n\n // Kingdom validation\n if (!Array.isArray(player.kingdom)) {\n issues.push(issue(`${path}.kingdom`, \"INVALID_KINGDOM\", `Kingdom must be a 2D array`));\n continue;\n }\n if (player.kingdom.length !== GRIDSIZE) {\n issues.push(issue(`${path}.kingdom`, \"INVALID_KINGDOM_GRID\", `Kingdom must have ${GRIDSIZE} rows, got ${player.kingdom.length}`));\n continue;\n }\n\n let castleCount = 0;\n for (let y = 0; y < player.kingdom.length; y++) {\n const row = player.kingdom[y]!;\n if (!Array.isArray(row) || row.length !== GRIDSIZE) {\n issues.push(issue(`${path}.kingdom[${y}]`, \"INVALID_KINGDOM_ROW\", `Kingdom row ${y} must have ${GRIDSIZE} columns`));\n continue;\n }\n for (let x = 0; x < row.length; x++) {\n const cell = row[x]!;\n issues.push(...validateTile(cell, `${path}.kingdom[${y}][${x}]`));\n if (cell && typeof cell === \"object\" && (cell as Record<string, unknown>).type === \"castle\") {\n castleCount++;\n }\n }\n }\n if (castleCount === 0) {\n issues.push(issue(`${path}.kingdom`, \"MISSING_CASTLE\", `Kingdom must have exactly one castle tile`, \"warning\"));\n } else if (castleCount > 1) {\n issues.push(issue(`${path}.kingdom`, \"MULTIPLE_CASTLES\", `Kingdom has ${castleCount} castle tiles, expected 1`));\n }\n }\n\n return issues;\n};\n\nconst validateDominoes = (game: Game): ValidationIssue[] => {\n const issues: ValidationIssue[] = [];\n const allNumbers = new Set<number>();\n\n // Validate draw pile dominoes\n if (Array.isArray(game.dominoes)) {\n for (let i = 0; i < game.dominoes.length; i++) {\n const domino = game.dominoes[i]!;\n const path = `dominoes[${i}]`;\n\n if (!isPositiveInteger(domino.number)) {\n issues.push(issue(`${path}.number`, \"INVALID_DOMINO_NUMBER\", `Domino number must be a positive integer`));\n } else if (allNumbers.has(domino.number)) {\n issues.push(issue(`${path}.number`, \"DUPLICATE_DOMINO_NUMBER\", `Duplicate domino number: ${domino.number}`));\n } else {\n allNumbers.add(domino.number);\n }\n issues.push(...validateTile(domino.left, `${path}.left`));\n issues.push(...validateTile(domino.right, `${path}.right`));\n }\n }\n\n // Validate current (revealed) dominoes\n if (Array.isArray(game.currentDominoes)) {\n for (let i = 0; i < game.currentDominoes.length; i++) {\n const revealed = game.currentDominoes[i]!;\n const path = `currentDominoes[${i}]`;\n\n if (!revealed.domino || typeof revealed.domino !== \"object\") {\n issues.push(issue(`${path}.domino`, \"INVALID_REVEALED_DOMINO\", `Revealed domino must be an object`));\n continue;\n }\n\n const domino = revealed.domino;\n if (!isPositiveInteger(domino.number)) {\n issues.push(issue(`${path}.domino.number`, \"INVALID_DOMINO_NUMBER\", `Domino number must be a positive integer`));\n } else if (allNumbers.has(domino.number)) {\n issues.push(issue(`${path}.domino.number`, \"DUPLICATE_DOMINO_NUMBER\", `Duplicate domino number: ${domino.number}`));\n } else {\n allNumbers.add(domino.number);\n }\n issues.push(...validateTile(domino.left, `${path}.domino.left`));\n issues.push(...validateTile(domino.right, `${path}.domino.right`));\n\n // picked/lordId consistency\n if (revealed.picked && revealed.lordId === null) {\n issues.push(issue(`${path}`, \"PICKED_WITHOUT_LORD\", `Domino is marked as picked but has no lordId`));\n }\n if (!revealed.picked && revealed.lordId !== null) {\n issues.push(issue(`${path}`, \"UNPICKED_WITH_LORD\", `Domino is not picked but has a lordId`));\n }\n }\n }\n\n // Validate dominos picked by lords\n // Note: lord.dominoPicked is a copy of the domino from currentDominoes,\n // so the same number legitimately appears in both places.\n if (Array.isArray(game.lords)) {\n const lordPickedNumbers = new Set<number>();\n for (let i = 0; i < game.lords.length; i++) {\n const lord = game.lords[i]!;\n if (lord.dominoPicked) {\n const path = `lords[${i}].dominoPicked`;\n const domino = lord.dominoPicked;\n if (!isPositiveInteger(domino.number)) {\n issues.push(issue(`${path}.number`, \"INVALID_DOMINO_NUMBER\", `Domino number must be a positive integer`));\n } else if (lordPickedNumbers.has(domino.number)) {\n issues.push(issue(`${path}.number`, \"DUPLICATE_DOMINO_NUMBER\", `Duplicate domino number among lords: ${domino.number}`));\n } else {\n lordPickedNumbers.add(domino.number);\n }\n issues.push(...validateTile(domino.left, `${path}.left`));\n issues.push(...validateTile(domino.right, `${path}.right`));\n }\n }\n }\n\n return issues;\n};\n\nconst validateLords = (game: Game): ValidationIssue[] => {\n const issues: ValidationIssue[] = [];\n if (!Array.isArray(game.lords)) return issues;\n\n const playerIds = new Set<string>(\n Array.isArray(game.players) ? game.players.map((p) => p.id) : [],\n );\n const lordIds = new Set<string>();\n\n for (let i = 0; i < game.lords.length; i++) {\n const lord = game.lords[i]!;\n const path = `lords[${i}]`;\n\n if (!isNonEmptyString(lord.id)) {\n issues.push(issue(`${path}.id`, \"INVALID_LORD_ID\", `Lord id must be a non-empty string`));\n } else if (lordIds.has(lord.id)) {\n issues.push(issue(`${path}.id`, \"DUPLICATE_LORD_ID\", `Duplicate lord id: ${lord.id}`));\n } else {\n lordIds.add(lord.id);\n }\n\n if (!isNonEmptyString(lord.playerId)) {\n issues.push(issue(`${path}.playerId`, \"INVALID_LORD_PLAYER_ID\", `Lord playerId must be a non-empty string`));\n } else if (playerIds.size > 0 && !playerIds.has(lord.playerId)) {\n issues.push(issue(`${path}.playerId`, \"LORD_PLAYER_NOT_FOUND\", `Lord references non-existent player: ${lord.playerId}`));\n }\n\n if (lord.turnEnded && (!lord.hasPick || !lord.hasPlace)) {\n issues.push(issue(path, \"INCONSISTENT_LORD_FLAGS\", `Lord has turnEnded=true but hasPick=${lord.hasPick}, hasPlace=${lord.hasPlace}`, \"warning\"));\n }\n }\n\n return issues;\n};\n\nconst validateGameFlow = (game: Game): ValidationIssue[] => {\n const issues: ValidationIssue[] = [];\n if (!game.nextAction || typeof game.nextAction !== \"object\") return issues;\n\n const nextAction = game.nextAction;\n\n if (nextAction.type === \"action\") {\n const action = nextAction as { type: \"action\"; nextLord?: unknown; nextAction?: unknown };\n\n if (!isNonEmptyString(action.nextLord)) {\n issues.push(issue(\"nextAction.nextLord\", \"INVALID_NEXT_LORD\", \"nextLord must be a non-empty string\"));\n } else if (Array.isArray(game.lords) && !game.lords.some((l) => l.id === action.nextLord)) {\n issues.push(issue(\"nextAction.nextLord\", \"NEXT_LORD_NOT_FOUND\", `nextLord references non-existent lord: ${action.nextLord as string}`));\n }\n\n if (typeof action.nextAction !== \"string\" || !validPlayerActions.has(action.nextAction as string)) {\n issues.push(issue(\"nextAction.nextAction\", \"INVALID_PLAYER_ACTION\", `nextAction must be one of: ${[...validPlayerActions].join(\", \")}`));\n }\n } else if (nextAction.type === \"step\") {\n const step = nextAction as { type: \"step\"; step?: unknown };\n\n if (typeof step.step !== \"string\" || !validGameSteps.has(step.step as string)) {\n issues.push(issue(\"nextAction.step\", \"INVALID_GAME_STEP\", `step must be one of: ${[...validGameSteps].join(\", \")}`));\n }\n }\n\n return issues;\n};\n\nconst isSetupPhase = (game: Game): boolean => {\n if (game.nextAction?.type !== \"step\") return false;\n const step = (game.nextAction as { step: string }).step;\n return step === \"addPlayers\" || step === \"options\" || step === \"start\";\n};\n\nconst validateRules = (game: Game): ValidationIssue[] => {\n const issues: ValidationIssue[] = [];\n if (!game.rules || typeof game.rules !== \"object\") return issues;\n\n // During setup phases (before players are added), basic rules may have zero values\n const allowZero = isSetupPhase(game);\n\n const basic = game.rules.basic;\n if (basic && typeof basic === \"object\") {\n const fields = [\"lords\", \"maxDominoes\", \"dominoesPerTurn\", \"maxTurns\", \"maxKingdomSize\"] as const;\n for (const field of fields) {\n const check = allowZero ? isNonNegativeInteger : isPositiveInteger;\n if (!check(basic[field])) {\n issues.push(issue(`rules.basic.${field}`, \"INVALID_BASIC_RULE_VALUE\", `rules.basic.${field} must be a positive integer`));\n }\n }\n }\n\n if (Array.isArray(game.rules.extra)) {\n for (let i = 0; i < game.rules.extra.length; i++) {\n const rule = game.rules.extra[i]!;\n if (!isNonEmptyString(rule.name)) {\n issues.push(issue(`rules.extra[${i}].name`, \"INVALID_EXTRA_RULE_NAME\", `Extra rule name must be a non-empty string`));\n }\n }\n }\n\n return issues;\n};\n\n/**\n * Validates the integrity of a game state.\n *\n * Use this function after deserializing or restoring a persisted game state\n * to detect corruptions before resuming gameplay.\n *\n * @param game - The game state to validate\n * @returns An array of validation issues. Empty array means the state is valid.\n *\n * @example\n * ```typescript\n * const issues = validateGameState(game);\n * if (issues.length > 0) {\n * console.error(\"Game state is corrupted:\", issues);\n * }\n * ```\n */\nexport const validateGameState = (game: Game): ValidationIssue[] => {\n const issues: ValidationIssue[] = [];\n\n issues.push(...validateGameStructure(game));\n issues.push(...validatePlayers(game));\n issues.push(...validateDominoes(game));\n issues.push(...validateLords(game));\n issues.push(...validateGameFlow(game));\n issues.push(...validateRules(game));\n\n return issues;\n};\n","import type { BotStrategy } from \"./bot.js\";\nimport {\n randomStrategy,\n greedyStrategy,\n advancedStrategy,\n expertStrategy,\n} from \"./bot.js\";\n\n/**\n * Built-in strategy names.\n */\nexport type StrategyName = \"random\" | \"greedy\" | \"advanced\" | \"expert\";\n\nconst defaultStrategies: Record<string, BotStrategy> = {\n random: randomStrategy,\n greedy: greedyStrategy,\n advanced: advancedStrategy,\n expert: expertStrategy,\n};\n\n/**\n * Resolves a strategy by name. Checks custom strategies first, then defaults.\n * Returns undefined if the name is not found.\n */\nexport const getStrategy = (\n name: string,\n custom?: Record<string, BotStrategy>\n): BotStrategy | undefined => {\n return custom?.[name] ?? defaultStrategies[name];\n};\n\n/**\n * Returns the list of built-in strategy names.\n */\nexport const getStrategyNames = (): string[] => Object.keys(defaultStrategies);\n","import type {\n Domino,\n RevealsDomino,\n Kingdom,\n GameWithNextAction,\n GameState,\n Score,\n} from \"@core/domain/types/index.js\";\nimport { isGameWithNextAction } from \"@core/domain/types/game.js\";\nimport type { ValidPlacement } from \"./getValidPlacements.js\";\nimport type { GameEngine } from \"@core/portUserside/engine.js\";\nimport { placeDomino } from \"@core/domain/entities/kingdom.js\";\nimport { calculateScoreUseCase } from \"./calculateScore.js\";\nimport { getValidPlacementsUseCase } from \"./getValidPlacements.js\";\nimport { isOk } from \"@utils/result.js\";\nimport { getStrategy } from \"./botRegistry.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────\n\n/**\n * Context provided to a bot strategy when choosing a domino to pick.\n */\nexport type PickContext = {\n game: GameWithNextAction;\n lordId: string;\n availableDominoes: RevealsDomino[];\n};\n\n/**\n * Context provided to a bot strategy when choosing where to place a domino.\n */\nexport type PlaceContext = {\n game: GameWithNextAction;\n lordId: string;\n domino: Domino;\n kingdom: Kingdom;\n validPlacements: ValidPlacement[];\n};\n\n/**\n * A bot strategy that decides which domino to pick and where to place it.\n * Strategies are stateless — all information comes from the context.\n */\nexport type BotStrategy = {\n chooseDomino: (context: PickContext) => number;\n choosePlacement: (context: PlaceContext) => ValidPlacement | null;\n};\n\n// ─── Helpers ─────────────────────────────────────────────────────────\n\nconst scoreKingdom = (kingdom: Kingdom): number => {\n const result = calculateScoreUseCase(kingdom);\n return isOk(result) ? result.value.points : 0;\n};\n\nconst simulatePlacement = (\n kingdom: Kingdom,\n domino: Domino,\n placement: ValidPlacement,\n maxKingdomSize: number\n): Kingdom | null => {\n const result = placeDomino(\n kingdom,\n placement.position,\n placement.rotation,\n domino,\n maxKingdomSize\n );\n return isOk(result) ? result.value : null;\n};\n\nconst bestPlacementScore = (\n kingdom: Kingdom,\n domino: Domino,\n placements: ValidPlacement[],\n maxKingdomSize: number\n): { placement: ValidPlacement; score: number; kingdom: Kingdom } | null => {\n let best: { placement: ValidPlacement; score: number; kingdom: Kingdom } | null = null;\n\n for (const placement of placements) {\n const newKingdom = simulatePlacement(kingdom, domino, placement, maxKingdomSize);\n if (!newKingdom) continue;\n const score = scoreKingdom(newKingdom);\n if (!best || score > best.score) {\n best = { placement, score, kingdom: newKingdom };\n }\n }\n\n return best;\n};\n\nconst getMaxKingdomSize = (game: GameWithNextAction): number =>\n game.rules.basic.maxKingdomSize;\n\nconst getLordAndPlayer = (game: GameWithNextAction, lordId: string) => {\n const lord = game.lords.find((l) => l.id === lordId);\n const player = lord\n ? game.players.find((p) => p.id === lord.playerId)\n : undefined;\n return { lord, player };\n};\n\nconst getNextBatchDominoes = (game: GameWithNextAction): Domino[] => {\n const perTurn = game.rules.basic.dominoesPerTurn;\n return [...game.dominoes]\n .slice(0, perTurn)\n .sort((a, b) => a.number - b.number);\n};\n\n// ─── Random Strategy ─────────────────────────────────────────────────\n\n/**\n * Bot strategy that makes random choices.\n * Picks a random available domino and places it at a random valid position.\n */\nexport const randomStrategy: BotStrategy = {\n chooseDomino: (context) => {\n const { availableDominoes } = context;\n const idx = Math.floor(Math.random() * availableDominoes.length);\n return availableDominoes[idx]!.domino.number;\n },\n\n choosePlacement: (context) => {\n const { validPlacements } = context;\n if (validPlacements.length === 0) return null;\n const idx = Math.floor(Math.random() * validPlacements.length);\n return validPlacements[idx]!;\n },\n};\n\n// ─── Greedy Strategy ─────────────────────────────────────────────────\n\n/**\n * Bot strategy that maximizes the immediate score.\n * Evaluates every valid placement and picks the one yielding the highest score.\n * When picking a domino, simulates the best placement for each option.\n */\nexport const greedyStrategy: BotStrategy = {\n chooseDomino: (context) => {\n const { game, lordId, availableDominoes } = context;\n const { player } = getLordAndPlayer(game, lordId);\n if (!player) return availableDominoes[0]!.domino.number;\n\n const maxSize = getMaxKingdomSize(game);\n let bestScore = -1;\n let bestPick = availableDominoes[0]!.domino.number;\n\n for (const rd of availableDominoes) {\n const placements = getValidPlacementsUseCase(\n player.kingdom,\n rd.domino,\n maxSize\n );\n const result = bestPlacementScore(\n player.kingdom,\n rd.domino,\n placements,\n maxSize\n );\n const score = result ? result.score : 0;\n if (score > bestScore) {\n bestScore = score;\n bestPick = rd.domino.number;\n }\n }\n\n return bestPick;\n },\n\n choosePlacement: (context) => {\n const { game, domino, kingdom, validPlacements } = context;\n if (validPlacements.length === 0) return null;\n\n const maxSize = getMaxKingdomSize(game);\n const result = bestPlacementScore(kingdom, domino, validPlacements, maxSize);\n return result ? result.placement : validPlacements[0]!;\n },\n};\n\n// ─── Advanced Strategy ───────────────────────────────────────────────\n\nconst evaluateWithLookahead = (\n kingdom: Kingdom,\n maxSize: number,\n nextDominoes: Domino[]\n): number => {\n if (nextDominoes.length === 0) return 0;\n\n let bestNextScore = 0;\n for (const nextDomino of nextDominoes) {\n const nextPlacements = getValidPlacementsUseCase(kingdom, nextDomino, maxSize);\n const result = bestPlacementScore(kingdom, nextDomino, nextPlacements, maxSize);\n if (result && result.score > bestNextScore) {\n bestNextScore = result.score;\n }\n }\n\n return bestNextScore;\n};\n\n/**\n * Bot strategy with 1-turn lookahead.\n * When making decisions, considers not just the immediate score but also\n * the best possible score achievable in the next turn by peeking at\n * the upcoming domino batch from the draw pile.\n */\nexport const advancedStrategy: BotStrategy = {\n chooseDomino: (context) => {\n const { game, lordId, availableDominoes } = context;\n const { player } = getLordAndPlayer(game, lordId);\n if (!player) return availableDominoes[0]!.domino.number;\n\n const maxSize = getMaxKingdomSize(game);\n const nextBatch = getNextBatchDominoes(game);\n\n let bestCombinedScore = -1;\n let bestPick = availableDominoes[0]!.domino.number;\n\n for (const rd of availableDominoes) {\n const placements = getValidPlacementsUseCase(\n player.kingdom,\n rd.domino,\n maxSize\n );\n const result = bestPlacementScore(\n player.kingdom,\n rd.domino,\n placements,\n maxSize\n );\n\n const immediateScore = result ? result.score : scoreKingdom(player.kingdom);\n const kingdomAfter = result ? result.kingdom : player.kingdom;\n const futureScore = evaluateWithLookahead(kingdomAfter, maxSize, nextBatch);\n const combined = immediateScore + futureScore * 0.8;\n\n if (combined > bestCombinedScore) {\n bestCombinedScore = combined;\n bestPick = rd.domino.number;\n }\n }\n\n return bestPick;\n },\n\n choosePlacement: (context) => {\n const { game, domino, kingdom, validPlacements } = context;\n if (validPlacements.length === 0) return null;\n\n const maxSize = getMaxKingdomSize(game);\n const nextBatch = getNextBatchDominoes(game);\n\n let bestCombinedScore = -1;\n let bestPlacement: ValidPlacement = validPlacements[0]!;\n\n for (const placement of validPlacements) {\n const newKingdom = simulatePlacement(kingdom, domino, placement, maxSize);\n if (!newKingdom) continue;\n\n const immediateScore = scoreKingdom(newKingdom);\n const futureScore = evaluateWithLookahead(newKingdom, maxSize, nextBatch);\n const combined = immediateScore + futureScore * 0.8;\n\n if (combined > bestCombinedScore) {\n bestCombinedScore = combined;\n bestPlacement = placement;\n }\n }\n\n return bestPlacement;\n },\n};\n\n// ─── Expert Strategy ─────────────────────────────────────────────────\n\n/** Maximum placements to evaluate per domino at each depth level (beam width) */\nconst EXPERT_BEAM_WIDTH = 2;\n\n/** Maximum search depth for the expert strategy */\nconst EXPERT_MAX_DEPTH = 2;\n\n/**\n * Ranks placements by immediate score gain (greedy heuristic)\n * and returns only the top N candidates for deeper evaluation.\n */\nconst topPlacements = (\n kingdom: Kingdom,\n domino: Domino,\n placements: ValidPlacement[],\n maxSize: number,\n limit: number\n): ValidPlacement[] => {\n if (placements.length <= limit) return placements;\n\n const scored = placements\n .map((p) => {\n const k = simulatePlacement(kingdom, domino, p, maxSize);\n return { placement: p, score: k ? scoreKingdom(k) : 0 };\n })\n .sort((a, b) => b.score - a.score);\n\n return scored.slice(0, limit).map((s) => s.placement);\n};\n\nconst expertEvaluate = (\n kingdom: Kingdom,\n remainingDominoes: Domino[],\n dominoesPerTurn: number,\n maxSize: number,\n depth: number\n): number => {\n if (depth <= 0 || remainingDominoes.length === 0) {\n return scoreKingdom(kingdom);\n }\n\n // Get next batch (sorted by number, as the engine does)\n const batch = [...remainingDominoes]\n .slice(0, dominoesPerTurn)\n .sort((a, b) => a.number - b.number);\n const afterBatch = remainingDominoes.slice(dominoesPerTurn);\n\n let bestScore = scoreKingdom(kingdom);\n\n for (const domino of batch) {\n const allPlacements = getValidPlacementsUseCase(kingdom, domino, maxSize);\n\n if (allPlacements.length === 0) {\n const score = expertEvaluate(\n kingdom,\n afterBatch,\n dominoesPerTurn,\n maxSize,\n depth - 1\n );\n if (score > bestScore) bestScore = score;\n continue;\n }\n\n // Prune: only evaluate top candidates by greedy score\n const candidates = topPlacements(\n kingdom,\n domino,\n allPlacements,\n maxSize,\n EXPERT_BEAM_WIDTH\n );\n\n for (const placement of candidates) {\n const newKingdom = simulatePlacement(kingdom, domino, placement, maxSize);\n if (!newKingdom) continue;\n\n const score = expertEvaluate(\n newKingdom,\n afterBatch,\n dominoesPerTurn,\n maxSize,\n depth - 1\n );\n if (score > bestScore) bestScore = score;\n }\n }\n\n return bestScore;\n};\n\n/**\n * Bot strategy that searches the game tree with beam-search pruning.\n * Explores all remaining turns, but limits the number of placements\n * evaluated per domino to the top candidates (by greedy score).\n * Since kingdoms are independent, this is a solo optimization (no adversarial search needed).\n */\nexport const expertStrategy: BotStrategy = {\n chooseDomino: (context) => {\n const { game, lordId, availableDominoes } = context;\n const { player } = getLordAndPlayer(game, lordId);\n if (!player) return availableDominoes[0]!.domino.number;\n\n const maxSize = getMaxKingdomSize(game);\n const perTurn = game.rules.basic.dominoesPerTurn;\n const turnsLeft = Math.min(\n game.rules.basic.maxTurns - game.turn,\n EXPERT_MAX_DEPTH\n );\n\n let bestScore = -1;\n let bestPick = availableDominoes[0]!.domino.number;\n\n for (const rd of availableDominoes) {\n const allPlacements = getValidPlacementsUseCase(\n player.kingdom,\n rd.domino,\n maxSize\n );\n\n if (allPlacements.length === 0) {\n const score = expertEvaluate(\n player.kingdom,\n game.dominoes,\n perTurn,\n maxSize,\n turnsLeft\n );\n if (score > bestScore) {\n bestScore = score;\n bestPick = rd.domino.number;\n }\n continue;\n }\n\n const candidates = topPlacements(\n player.kingdom,\n rd.domino,\n allPlacements,\n maxSize,\n EXPERT_BEAM_WIDTH\n );\n\n for (const placement of candidates) {\n const newKingdom = simulatePlacement(\n player.kingdom,\n rd.domino,\n placement,\n maxSize\n );\n if (!newKingdom) continue;\n\n const score = expertEvaluate(\n newKingdom,\n game.dominoes,\n perTurn,\n maxSize,\n turnsLeft\n );\n if (score > bestScore) {\n bestScore = score;\n bestPick = rd.domino.number;\n }\n }\n }\n\n return bestPick;\n },\n\n choosePlacement: (context) => {\n const { game, domino, kingdom, validPlacements } = context;\n if (validPlacements.length === 0) return null;\n\n const maxSize = getMaxKingdomSize(game);\n const perTurn = game.rules.basic.dominoesPerTurn;\n const turnsLeft = Math.min(\n game.rules.basic.maxTurns - game.turn,\n EXPERT_MAX_DEPTH\n );\n\n let bestScore = -1;\n let bestPlacement: ValidPlacement = validPlacements[0]!;\n\n for (const placement of validPlacements) {\n const newKingdom = simulatePlacement(kingdom, domino, placement, maxSize);\n if (!newKingdom) continue;\n\n const score = expertEvaluate(\n newKingdom,\n game.dominoes,\n perTurn,\n maxSize,\n turnsLeft\n );\n if (score > bestScore) {\n bestScore = score;\n bestPlacement = placement;\n }\n }\n\n return bestPlacement;\n },\n};\n\n// ─── playBotTurn ─────────────────────────────────────────────────────\n\n/**\n * Executes a single bot turn using the given strategy and engine.\n * Reads the current game state to determine the required action,\n * asks the strategy for a decision, and executes it via the engine.\n *\n * @param engine - The game engine instance\n * @param game - Current game state (must require a player action)\n * @param strategy - The bot strategy to use for decisions\n * @returns Updated game state after the bot's action\n */\nexport const playBotTurn = (\n engine: GameEngine,\n game: GameWithNextAction,\n strategy: BotStrategy\n): GameState => {\n const lordId = game.nextAction.nextLord;\n const action = game.nextAction.nextAction;\n\n if (action === \"pickDomino\") {\n const availableDominoes = game.currentDominoes.filter((d) => !d.picked);\n const dominoPick = strategy.chooseDomino({\n game,\n lordId,\n availableDominoes,\n });\n return engine.chooseDomino({ game, lordId, dominoPick });\n }\n\n if (action === \"placeDomino\") {\n const { lord, player } = getLordAndPlayer(game, lordId);\n if (!lord?.dominoPicked || !player) {\n return engine.discardDomino({ game, lordId });\n }\n\n const domino = lord.dominoPicked;\n const kingdom = player.kingdom;\n const maxSize = getMaxKingdomSize(game);\n const validPlacements = getValidPlacementsUseCase(kingdom, domino, maxSize);\n\n const placement = strategy.choosePlacement({\n game,\n lordId,\n domino,\n kingdom,\n validPlacements,\n });\n\n if (!placement) {\n return engine.discardDomino({ game, lordId });\n }\n\n return engine.placeDomino({\n game,\n lordId,\n position: placement.position,\n rotation: placement.rotation,\n });\n }\n\n // action === \"pass\"\n return engine.discardDomino({ game, lordId });\n};\n\n// ─── Mixed human/bot helpers ────────────────────────────────────────\n\n/**\n * Checks if the current turn belongs to a bot player.\n */\nexport const isBotTurn = (game: GameWithNextAction): boolean => {\n const lordId = game.nextAction.nextLord;\n const lord = game.lords.find((l) => l.id === lordId);\n const player = lord\n ? game.players.find((p) => p.id === lord.playerId)\n : undefined;\n return !!player?.bot;\n};\n\n/**\n * Plays all consecutive bot turns until a human turn or game end is reached.\n * Resolves each bot's strategy by name from the registry (or custom map).\n * Falls back to randomStrategy if the strategy name is not found.\n *\n * @param engine - The game engine instance\n * @param game - Current game state\n * @param customStrategies - Optional custom strategy map (name → BotStrategy)\n * @returns Updated game state paused at the next human turn or game end\n */\nexport const playBotTurns = (\n engine: GameEngine,\n game: GameState,\n customStrategies?: Record<string, BotStrategy>\n): GameState => {\n let current = game;\n\n while (isGameWithNextAction(current) && isBotTurn(current)) {\n const lordId = current.nextAction.nextLord;\n const lord = current.lords.find((l) => l.id === lordId);\n const player = lord\n ? current.players.find((p) => p.id === lord.playerId)\n : undefined;\n const strategyName = player?.bot?.strategyName ?? \"random\";\n const strategy =\n getStrategy(strategyName, customStrategies) ?? randomStrategy;\n current = playBotTurn(engine, current, strategy);\n }\n\n return current;\n};\n","import type {\n GameState,\n Position,\n Rotation,\n} from \"@core/domain/types/index.js\";\nimport type { GameEngine } from \"@core/portUserside/engine.js\";\nimport type { PlayerInput } from \"@application/commands/addPlayersCommand.js\";\n\n// ─── Types ──────────────────────────────────────────────────────────\n\n/**\n * The types of state-changing actions that can be recorded.\n */\nexport type ActionType =\n | \"createGame\"\n | \"addPlayers\"\n | \"addExtraRules\"\n | \"startGame\"\n | \"chooseDomino\"\n | \"placeDomino\"\n | \"discardDomino\";\n\n/**\n * Payload types for each action, containing only the command parameters\n * (excluding the game state, which is too large to store).\n */\nexport type ActionPayloadMap = {\n createGame: { mode: string; seed?: string };\n addPlayers: { players: PlayerInput[] };\n addExtraRules: { extraRules: string[] };\n startGame: Record<string, never>;\n chooseDomino: { lordId: string; dominoPick: number };\n placeDomino: { lordId: string; position: Position; rotation: Rotation };\n discardDomino: { lordId: string };\n};\n\n/**\n * A single recorded action in the game log.\n */\nexport type ActionEntry<T extends ActionType = ActionType> = {\n /** Auto-incrementing index (0-based) */\n id: number;\n /** Timestamp when the action was recorded (Date.now()) */\n timestamp: number;\n /** The type of action performed */\n action: T;\n /** Command parameters (excludes game state) */\n payload: ActionPayloadMap[T];\n /** Turn number after the action was applied */\n turn: number;\n};\n\n/**\n * An immutable log of all actions performed during a game.\n * Can be used to replay a game or analyze player decisions.\n *\n * @example\n * ```typescript\n * const { engine, getLog } = wrapWithActionLog(baseEngine);\n * let game = engine.createGame({ mode: 'Classic' });\n * game = engine.addPlayers({ game, players: ['Alice', 'Bob'] });\n * // ... play the game ...\n * const log = getLog();\n * console.log(log.entries); // all actions recorded\n * ```\n */\nexport type GameActionLog = {\n /** The game ID this log belongs to */\n gameId: string;\n /** Immutable array of recorded actions */\n entries: readonly ActionEntry[];\n};\n\n// ─── Construction ───────────────────────────────────────────────────\n\n/**\n * Creates an empty action log for a game.\n */\nexport const createActionLog = (gameId: string): GameActionLog => ({\n gameId,\n entries: [],\n});\n\n/**\n * Appends an action to the log (immutable — returns a new log).\n */\nexport const appendAction = (\n log: GameActionLog,\n entry: Omit<ActionEntry, \"id\" | \"timestamp\">,\n): GameActionLog => ({\n ...log,\n entries: [\n ...log.entries,\n {\n ...entry,\n id: log.entries.length,\n timestamp: Date.now(),\n },\n ],\n});\n\n// ─── Queries ────────────────────────────────────────────────────────\n\n/**\n * Returns all entries in the log.\n */\nexport const getActions = (log: GameActionLog): readonly ActionEntry[] =>\n log.entries;\n\n/**\n * Returns entries filtered by action type.\n */\nexport const getActionsByType = (\n log: GameActionLog,\n type: ActionType,\n): readonly ActionEntry[] => log.entries.filter((e) => e.action === type);\n\n/**\n * Returns entries filtered by turn number.\n */\nexport const getActionsByTurn = (\n log: GameActionLog,\n turn: number,\n): readonly ActionEntry[] => log.entries.filter((e) => e.turn === turn);\n\n// ─── Engine Wrapper ─────────────────────────────────────────────────\n\n/**\n * Wraps a GameEngine to automatically record every state-changing action.\n * Read-only methods are passed through unchanged.\n *\n * @param engine - The base game engine to wrap\n * @returns An object with the wrapped engine and a getLog() accessor\n *\n * @example\n * ```typescript\n * const { engine: logged, getLog } = wrapWithActionLog(baseEngine);\n * let game = logged.createGame({ mode: 'Classic' });\n * // ... play ...\n * const log = getLog(); // retrieve the full action log\n * ```\n */\nexport const wrapWithActionLog = (\n engine: GameEngine,\n): { engine: GameEngine; getLog: () => GameActionLog } => {\n let log = createActionLog(\"\");\n\n const record = <T extends ActionType>(\n action: T,\n payload: ActionPayloadMap[T],\n turn: number,\n ): void => {\n log = appendAction(log, { action, payload, turn });\n };\n\n const wrappedEngine: GameEngine = {\n // Read-only methods — pass through\n getModes: (cmd) => engine.getModes(cmd),\n getExtraRules: (cmd) => engine.getExtraRules(cmd),\n calculateScore: (cmd) => engine.calculateScore(cmd),\n getValidPlacements: (cmd) => engine.getValidPlacements(cmd),\n canPlaceDomino: (cmd) => engine.canPlaceDomino(cmd),\n serialize: (cmd) => engine.serialize(cmd),\n deserialize: (cmd) => engine.deserialize(cmd),\n getResults: (cmd) => engine.getResults(cmd),\n getDynastyResults: (cmd) => engine.getDynastyResults(cmd),\n\n // State-changing methods — record after execution\n createGame: (cmd) => {\n const game = engine.createGame(cmd);\n log = createActionLog(game.id);\n record(\"createGame\", { mode: cmd.mode, seed: cmd.seed }, game.turn);\n return game;\n },\n\n addPlayers: (cmd) => {\n const game = engine.addPlayers(cmd);\n record(\"addPlayers\", { players: cmd.players }, game.turn);\n return game;\n },\n\n addExtraRules: (cmd) => {\n const game = engine.addExtraRules(cmd);\n record(\"addExtraRules\", { extraRules: cmd.extraRules }, game.turn);\n return game;\n },\n\n startGame: (cmd) => {\n const game = engine.startGame(cmd);\n record(\"startGame\", {}, game.turn);\n return game;\n },\n\n chooseDomino: (cmd) => {\n const game = engine.chooseDomino(cmd);\n record(\n \"chooseDomino\",\n { lordId: cmd.lordId, dominoPick: cmd.dominoPick },\n game.turn,\n );\n return game;\n },\n\n placeDomino: (cmd) => {\n const game = engine.placeDomino(cmd);\n record(\n \"placeDomino\",\n {\n lordId: cmd.lordId,\n position: cmd.position,\n rotation: cmd.rotation,\n },\n game.turn,\n );\n return game;\n },\n\n discardDomino: (cmd) => {\n const game = engine.discardDomino(cmd);\n record(\"discardDomino\", { lordId: cmd.lordId }, game.turn);\n return game;\n },\n\n // Queendomino methods — pass through (no action log recording yet)\n placeKnight: (cmd) => engine.placeKnight(cmd),\n constructBuilding: (cmd) => engine.constructBuilding(cmd),\n useDragon: (cmd) => engine.useDragon(cmd),\n skipOptionalAction: (cmd) => engine.skipOptionalAction(cmd),\n };\n\n return {\n engine: wrappedEngine,\n getLog: () => log,\n };\n};\n\n// ─── Replay ─────────────────────────────────────────────────────────\n\n/**\n * Replays all actions from a log on a fresh engine to reconstruct the final game state.\n * The engine should use the same configuration (especially shuffleMethod) as the original game\n * to guarantee deterministic results when a seed is present.\n *\n * @param engine - A game engine instance (should match original config)\n * @param log - The action log to replay\n * @returns The final game state after replaying all actions\n */\nexport const replayActions = (\n engine: GameEngine,\n log: GameActionLog,\n): GameState => {\n if (log.entries.length === 0) {\n throw new Error(\"Cannot replay an empty action log\");\n }\n\n const firstEntry = log.entries[0];\n if (firstEntry?.action !== \"createGame\") {\n throw new Error(\"Action log must start with a createGame action\");\n }\n\n const firstPayload = firstEntry.payload as ActionPayloadMap[\"createGame\"];\n let game: GameState = engine.createGame({\n mode: firstPayload.mode,\n seed: firstPayload.seed,\n });\n\n for (let i = 1; i < log.entries.length; i++) {\n const entry = log.entries[i];\n if (!entry) continue;\n\n switch (entry.action) {\n case \"createGame\": {\n const payload = entry.payload as ActionPayloadMap[\"createGame\"];\n game = engine.createGame({ mode: payload.mode, seed: payload.seed });\n break;\n }\n case \"addPlayers\": {\n const payload = entry.payload as ActionPayloadMap[\"addPlayers\"];\n game = engine.addPlayers({ game, players: payload.players });\n break;\n }\n case \"addExtraRules\": {\n const payload = entry.payload as ActionPayloadMap[\"addExtraRules\"];\n game = engine.addExtraRules({\n game,\n extraRules: payload.extraRules,\n });\n break;\n }\n case \"startGame\": {\n game = engine.startGame({ game });\n break;\n }\n case \"chooseDomino\": {\n const payload = entry.payload as ActionPayloadMap[\"chooseDomino\"];\n game = engine.chooseDomino({\n game,\n lordId: payload.lordId,\n dominoPick: payload.dominoPick,\n });\n break;\n }\n case \"placeDomino\": {\n const payload = entry.payload as ActionPayloadMap[\"placeDomino\"];\n game = engine.placeDomino({\n game,\n lordId: payload.lordId,\n position: payload.position,\n rotation: payload.rotation,\n });\n break;\n }\n case \"discardDomino\": {\n const payload = entry.payload as ActionPayloadMap[\"discardDomino\"];\n game = engine.discardDomino({\n game,\n lordId: payload.lordId,\n });\n break;\n }\n }\n }\n\n return game;\n};\n","import type { GameState } from \"@core/domain/types/index.js\";\nimport { UndoError, RedoError } from \"@core/domain/errors/domainErrors.js\";\n\n/**\n * Manages a history of game states for undo/redo support.\n * Uses a snapshot-based approach: each state is stored as a full GameState.\n *\n * @example\n * ```typescript\n * let history = createGameHistory(initialGame);\n * const newGame = engine.chooseDomino({ game: history.current, ... });\n * history = pushState(history, newGame);\n * history = undo(history); // back to initialGame\n * history = redo(history); // forward to newGame\n * ```\n */\nexport type GameHistory = {\n /** The current game state */\n current: GameState;\n /** Stack of previous states (most recent last) */\n past: GameState[];\n /** Stack of undone states (most recent last) */\n future: GameState[];\n};\n\n/**\n * Creates a new game history initialized with a game state.\n *\n * @param initialState - The starting game state\n * @returns A new GameHistory with empty past and future\n */\nexport const createGameHistory = (initialState: GameState): GameHistory => ({\n current: initialState,\n past: [],\n future: [],\n});\n\n/**\n * Records a new game state in the history.\n * The current state is pushed to the past stack, and the future stack is cleared\n * (branching from a previous undo point discards the old future).\n *\n * @param history - The current history\n * @param newState - The new game state to record\n * @returns Updated history with the new state as current\n */\nexport const pushState = (\n history: GameHistory,\n newState: GameState\n): GameHistory => ({\n current: newState,\n past: [...history.past, history.current],\n future: [],\n});\n\n/**\n * Reverts to the previous game state.\n * The current state is moved to the future stack for potential redo.\n *\n * @param history - The current history\n * @returns Updated history with the previous state as current\n * @throws {UndoError} If there is no previous state to revert to\n */\nexport const undo = (history: GameHistory): GameHistory => {\n if (history.past.length === 0) {\n throw new UndoError();\n }\n\n const previous = history.past[history.past.length - 1]!;\n return {\n current: previous,\n past: history.past.slice(0, -1),\n future: [...history.future, history.current],\n };\n};\n\n/**\n * Re-applies a previously undone game state.\n * The current state is moved to the past stack.\n *\n * @param history - The current history\n * @returns Updated history with the next undone state as current\n * @throws {RedoError} If there is no undone state to re-apply\n */\nexport const redo = (history: GameHistory): GameHistory => {\n if (history.future.length === 0) {\n throw new RedoError();\n }\n\n const next = history.future[history.future.length - 1]!;\n return {\n current: next,\n past: [...history.past, history.current],\n future: history.future.slice(0, -1),\n };\n};\n\n/**\n * Checks whether an undo operation is available.\n */\nexport const canUndo = (history: GameHistory): boolean =>\n history.past.length > 0;\n\n/**\n * Checks whether a redo operation is available.\n */\nexport const canRedo = (history: GameHistory): boolean =>\n history.future.length > 0;\n\n/**\n * Clears the undo/redo history, keeping only the current state.\n *\n * @param history - The current history\n * @returns A new history with empty past and future\n */\nexport const clearHistory = (history: GameHistory): GameHistory => ({\n current: history.current,\n past: [],\n future: [],\n});\n\n/**\n * Returns the number of states in the past and future stacks.\n */\nexport const getHistorySize = (\n history: GameHistory\n): { past: number; future: number } => ({\n past: history.past.length,\n future: history.future.length,\n});\n","import type { GameEngine } from \"@core/portUserside/engine\";\nimport { type DebugOptions, wrapWithDebug } from \"@core/useCases/gameDebug.js\";\nimport { wrapWithEvents } from \"@core/useCases/gameEvents.js\";\nimport { configureEngine, type EngineConfig } from \"./config.js\";\n\n// Commands\nexport * from \"@application/commands/index.js\";\nexport { validateGameState } from \"@core/domain/entities/validateGameState.js\";\n// Domain errors\nexport * from \"@core/domain/errors/domainErrors.js\";\n// Domain types\nexport * from \"@core/domain/types/index.js\";\n// i18n\nexport * from \"@core/i18n/translations.js\";\n// Ports\nexport * from \"@core/portServerside/index.js\";\nexport * from \"@core/portUserside/engine.js\";\n// Bot / AI player\nexport {\n advancedStrategy,\n type BotStrategy,\n expertStrategy,\n greedyStrategy,\n isBotTurn,\n type PickContext,\n type PlaceContext,\n playBotTurn,\n playBotTurns,\n randomStrategy,\n} from \"@core/useCases/bot.js\";\n// Bot strategy registry\nexport {\n getStrategy,\n getStrategyNames,\n type StrategyName,\n} from \"@core/useCases/botRegistry.js\";\n// Action log (game history / replay)\nexport {\n type ActionEntry,\n type ActionPayloadMap,\n type ActionType,\n appendAction,\n createActionLog,\n type GameActionLog,\n getActions,\n getActionsByTurn,\n getActionsByType,\n replayActions,\n wrapWithActionLog,\n} from \"@core/useCases/gameActionLog.js\";\n// Debug mode\nexport {\n type DebugLogEntry,\n type DebugLogger,\n type DebugLogLevel,\n type DebugOptions,\n type GameStateSummary,\n summarizeGameState,\n wrapWithDebug,\n} from \"@core/useCases/gameDebug.js\";\n// Game events\nexport {\n type GameEventCallbacks,\n wrapWithEvents,\n} from \"@core/useCases/gameEvents.js\";\n// History (undo/redo)\nexport {\n canRedo,\n canUndo,\n clearHistory,\n createGameHistory,\n type GameHistory,\n getHistorySize,\n pushState,\n redo,\n undo,\n} from \"@core/useCases/gameHistory.js\";\nexport type { DynastyResult } from \"@core/useCases/getDynastyResult.js\";\n// Use cases (for advanced usage)\nexport type { ValidPlacement } from \"@core/useCases/getValidPlacements.js\";\nexport type { PlaceKnightUseCase } from \"@core/useCases/placeKnight.js\";\nexport type { ConstructBuildingUseCase } from \"@core/useCases/constructBuilding.js\";\nexport type { UseDragonUseCase } from \"@core/useCases/useDragon.js\";\nexport type { SkipOptionalActionUseCase } from \"@core/useCases/skipOptionalAction.js\";\nexport {\n createSavePoint,\n deserializeGame,\n type GameSavePoint,\n restoreFromSavePoint,\n serializeGame,\n} from \"@core/useCases/serialization.js\";\n// Configuration\nexport type { EngineConfig };\n\n/**\n * Creates a new Kingdomino game engine instance.\n *\n * @param config - Configuration options for the engine\n * @returns A fully configured GameEngine instance\n *\n * @example\n * ```typescript\n * // Basic usage\n * const engine = createGameEngine({});\n *\n * // With logging\n * const engine = createGameEngine({ logging: true });\n *\n * // With event callbacks\n * const engine = createGameEngine({\n * events: {\n * onDominoPlaced: ({ lordId }) => console.log(`${lordId} placed`),\n * onGameEnd: () => console.log('Game over!'),\n * },\n * });\n * ```\n */\nexport const createGameEngine = (config: Partial<EngineConfig>): GameEngine => {\n const {\n createGameHandler,\n getModesHandler,\n getExtraRulesHandler,\n addPlayersHandler,\n addExtraRulesHandler,\n startGameHandler,\n chooseDominoHandler,\n placeDominoHandler,\n discardDominoHandler,\n getResultHandler,\n calculateScoreHandler,\n getValidPlacementsHandler,\n canPlaceDominoHandler,\n serializeGameHandler,\n deserializeGameHandler,\n getDynastyResultHandler,\n placeKnightHandler,\n constructBuildingHandler,\n useDragonHandler,\n skipOptionalActionHandler,\n } = configureEngine(config);\n\n let engine: GameEngine = {\n getModes: (command) => getModesHandler(command),\n getExtraRules: (command) => getExtraRulesHandler(command),\n createGame: (command) => createGameHandler(command),\n addPlayers: (command) => addPlayersHandler(command),\n addExtraRules: (command) => addExtraRulesHandler(command),\n startGame: (command) => startGameHandler(command),\n chooseDomino: (command) => chooseDominoHandler(command),\n placeDomino: (command) => placeDominoHandler(command),\n discardDomino: (command) => discardDominoHandler(command),\n getResults: (command) => getResultHandler(command),\n calculateScore: (command) => calculateScoreHandler(command),\n getValidPlacements: (command) => getValidPlacementsHandler(command),\n canPlaceDomino: (command) => canPlaceDominoHandler(command),\n serialize: (command) => serializeGameHandler(command),\n deserialize: (command) => deserializeGameHandler(command),\n getDynastyResults: (command) => getDynastyResultHandler(command),\n placeKnight: (command) => placeKnightHandler(command),\n constructBuilding: (command) => constructBuildingHandler(command),\n useDragon: (command) => useDragonHandler(command),\n skipOptionalAction: (command) => skipOptionalActionHandler(command),\n };\n\n if (config.events) {\n engine = wrapWithEvents(engine, config.events);\n }\n\n if (config.debug) {\n const debugOptions: DebugOptions | undefined =\n typeof config.debug === \"object\" ? config.debug : undefined;\n engine = wrapWithDebug(engine, debugOptions);\n }\n\n return engine;\n};\n"],"mappings":"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","names":["err","durationMs","getResultUseCase","calculateScoreUseCase","result","shuffleMethod","uuidMethod","shuffleMethod","lord","next","updatedCurrentDominoes","uuidMethod","uuidMethod","shuffleMethod","createGameHandler","getModesHandler","getExtraRulesHandler","addPlayersHandler","addExtraRulesHandler","startGameHandler","chooseDominoHandler","placeDominoHandler","discardDominoHandler","getResultHandler","calculateScoreHandler","getValidPlacementsHandler","canPlaceDominoHandler","serializeGameHandler","deserializeGameHandler","getDynastyResultHandler","placeKnightHandler","constructBuildingHandler","useDragonHandler","skipOptionalActionHandler"]}
1
+ {"version":3,"sources":["../src/core/domain/types/game.ts","../src/core/useCases/gameDebug.ts","../src/core/useCases/gameEvents.ts","../src/adapterServerside/consoleLogger.ts","../src/datasources/buildings.json","../src/adapterServerside/jsonBuildings.ts","../src/datasources/cavemen.json","../src/adapterServerside/jsonCavemen.ts","../src/datasources/dominoes.json","../src/adapterServerside/jsonDominoes.ts","../src/datasources/modes.json","../src/adapterServerside/jsonModes.ts","../src/datasources/questTiles.json","../src/adapterServerside/jsonQuestTiles.ts","../src/datasources/rules.json","../src/adapterServerside/jsonRules.ts","../src/adapterServerside/shuffle.ts","../src/adapterServerside/uuid.ts","../src/core/domain/errors/domainErrors.ts","../src/core/i18n/translations.ts","../src/utils/result.ts","../src/application/handlers/addExtraRulesHandler.ts","../src/application/handlers/addPlayersHandler.ts","../src/application/handlers/calculateScoreHandler.ts","../src/application/handlers/canPlaceDominoHandler.ts","../src/application/handlers/chooseDominoHandler.ts","../src/application/handlers/constructBuildingHandler.ts","../src/application/handlers/createGameHandler.ts","../src/application/handlers/discardDominoHandler.ts","../src/application/handlers/getDynastyResultHandler.ts","../src/application/handlers/getExtraRulesHandler.ts","../src/application/handlers/getModesHandler.ts","../src/application/handlers/getResultHandler.ts","../src/application/handlers/getValidPlacementsHandler.ts","../src/application/handlers/placeDominoHandler.ts","../src/application/handlers/placeFireTokenHandler.ts","../src/application/handlers/placeGiantHandler.ts","../src/application/handlers/placeKnightHandler.ts","../src/application/handlers/recruitCavemanHandler.ts","../src/application/handlers/sendGiantHandler.ts","../src/core/useCases/serialization.ts","../src/application/handlers/serializeGameHandler.ts","../src/application/handlers/skipOptionalActionHandler.ts","../src/application/handlers/startGameHandler.ts","../src/application/handlers/useDragonHandler.ts","../src/core/domain/entities/rule.ts","../src/core/domain/types/ageOfGiants.ts","../src/core/domain/types/domino.ts","../src/core/domain/types/kingdom.ts","../src/core/domain/types/origins.ts","../src/core/domain/types/player.ts","../src/utils/seededShuffle.ts","../src/core/useCases/addExtraRules.ts","../src/core/domain/entities/ageOfGiantsHelpers.ts","../src/core/domain/entities/economy.ts","../src/core/domain/entities/domino.ts","../src/core/domain/entities/kingdom.ts","../src/core/domain/entities/originsHelpers.ts","../src/core/domain/entities/player.ts","../src/core/useCases/addPlayers.ts","../src/core/useCases/calculateScore.ts","../src/core/domain/entities/lord.ts","../src/core/useCases/chooseDomino.ts","../src/core/domain/entities/building.ts","../src/core/domain/entities/queen.ts","../src/core/useCases/constructBuilding.ts","../src/core/domain/entities/fireToken.ts","../src/core/domain/entities/giant.ts","../src/core/domain/entities/game.ts","../src/core/domain/entities/mode.ts","../src/core/useCases/createGame.ts","../src/core/useCases/getValidPlacements.ts","../src/core/useCases/discardDomino.ts","../src/core/useCases/getDynastyResult.ts","../src/core/useCases/getExtraRules.ts","../src/core/useCases/getModes.ts","../src/core/domain/entities/caveman.ts","../src/core/domain/entities/originsScore.ts","../src/core/domain/entities/questScore.ts","../src/core/domain/entities/resource.ts","../src/core/domain/entities/totem.ts","../src/core/useCases/getResult.ts","../src/core/useCases/placeDomino.ts","../src/core/useCases/placeFireToken.ts","../src/core/useCases/placeGiant.ts","../src/core/domain/entities/knight.ts","../src/core/useCases/placeKnight.ts","../src/core/useCases/recruitCaveman.ts","../src/core/useCases/sendGiant.ts","../src/core/useCases/skipOptionalAction.ts","../src/core/useCases/startGame.ts","../src/core/useCases/useDragon.ts","../src/config.ts","../src/core/domain/entities/validateGameState.ts","../src/core/useCases/botRegistry.ts","../src/core/useCases/bot.ts","../src/core/useCases/gameActionLog.ts","../src/core/useCases/gameHistory.ts","../src/index.ts"],"sourcesContent":["import type { Result } from \"@utils/result.js\";\nimport type { AgeOfGiantsState } from \"./ageOfGiants.js\";\nimport type { Domino, RevealsDomino } from \"./domino.js\";\nimport type { Lord } from \"./lord.js\";\nimport type { GameMode } from \"./mode.js\";\nimport type { OriginsState } from \"./origins.js\";\nimport type { Player, PlayerActions } from \"./player.js\";\nimport type { QueenDominoState } from \"./queendomino.js\";\nimport type { SelectedRules } from \"./rule.js\";\nimport type { ObjectValues } from \"./utils.js\";\n\n/**\n * Represents the complete state of a Kingdomino game.\n * This is the main aggregate containing all game data.\n */\nexport type Game = {\n /** Unique identifier for the game */\n id: string;\n /** Remaining dominoes in the draw pile */\n dominoes: Domino[];\n /** Currently revealed dominoes available for picking */\n currentDominoes: RevealsDomino[];\n /** Players participating in the game with their kingdoms */\n players: Player[];\n /** Lords (player tokens) used for turn order and domino selection */\n lords: Lord[];\n /** Current turn number (1-based) */\n turn: number;\n /** Next required action or game step */\n nextAction: NextAction | NextStep;\n /** Active rules for this game */\n rules: SelectedRules;\n /** Game mode being played */\n mode: GameMode;\n /** Optional seed for deterministic shuffle (replays, sharing) */\n seed?: string;\n /** Queendomino-specific state (only present in QueenDomino mode) */\n queendomino?: QueenDominoState;\n /** Origins-specific state (only present in KingdominoOrigins modes) */\n origins?: OriginsState;\n /** Age of Giants-specific state (only present in AgeOfGiants modes) */\n ageOfGiants?: AgeOfGiantsState;\n};\n\n/**\n * Available game steps representing phases of game setup and completion.\n */\nexport const gameSteps = {\n /** Waiting for players to be added */\n addPlayers: \"addPlayers\",\n /** Optional rules selection phase */\n options: \"options\",\n /** Ready to start the game */\n start: \"start\",\n /** Game has ended, results available */\n result: \"result\",\n} as const;\n\n/** Union type of all possible game steps */\nexport type GameSteps = ObjectValues<typeof gameSteps>;\n\n/**\n * Represents a player action that needs to be performed.\n * Used during active gameplay.\n */\nexport type NextAction = {\n /** Discriminator for action type */\n type: \"action\";\n /** ID of the lord who must perform the action */\n nextLord: string;\n /** The action the lord must perform */\n nextAction: PlayerActions;\n};\n\n/**\n * Represents a game phase transition.\n * Used during setup and game end.\n */\nexport type NextStep = {\n /** Discriminator for step type */\n type: \"step\";\n /** The current game step/phase */\n step: GameSteps;\n};\n\n/** Game state where a player action is required */\nexport type GameWithNextAction = Game & { nextAction: NextAction };\n\n/** Game state where a phase transition is occurring */\nexport type GameWithNextStep = Game & { nextAction: NextStep };\n\n/** Union of all possible game states */\nexport type GameState = GameWithNextAction | GameWithNextStep;\n\n/** Result wrapper for game state operations */\nexport type GameStateResult = Result<GameState>;\n\n/**\n * Type guard to check if the game requires a player action.\n * @param game - The game state to check\n * @returns True if the game is waiting for a player action\n */\nexport const isGameWithNextAction = (\n game: GameWithNextAction | GameWithNextStep,\n): game is GameWithNextAction => {\n return game.nextAction.type === \"action\";\n};\n\n/**\n * Type guard to check if the game is in a phase transition.\n * @param game - The game state to check\n * @returns True if the game is transitioning between phases\n */\nexport const isGameWithNextStep = (\n game: GameWithNextAction | GameWithNextStep,\n): game is GameWithNextStep => {\n return game.nextAction.type === \"step\";\n};\n\n/**\n * Represents the score calculation for a kingdom.\n */\nexport type Score = {\n /** Total points earned */\n points: number;\n /** Size of the largest contiguous property */\n maxPropertiesSize: number;\n /** Total number of crowns in the kingdom */\n totalCrowns: number;\n};\n\n/**\n * Score result for a specific player.\n */\nexport type ScoreResult = {\n /** Player's unique identifier */\n playerId: string;\n /** Player's display name */\n playerName: string;\n /** Detailed score breakdown */\n details: Score;\n};\n\n/**\n * Final result including ranking position.\n */\nexport type FinalResult = ScoreResult & {\n /** Player's final position (1 = winner) */\n position: number;\n};\n\n/** Game state with final results calculated */\nexport type GameWithResults = Game & { result: FinalResult[] };\n","import { isGameWithNextAction } from \"@core/domain/types/game.js\";\nimport type { GameState } from \"@core/domain/types/index.js\";\nimport type { GameEngine } from \"@core/portUserside/engine.js\";\n\n// ─── Types ──────────────────────────────────────────────────────────\n\n/**\n * Debug log verbosity level.\n * - `minimal`: method name + phase only\n * - `standard`: + game state summary + key params\n * - `verbose`: + full game state JSON dump\n */\nexport type DebugLogLevel = \"minimal\" | \"standard\" | \"verbose\";\n\n/**\n * Summary of the current game state, extracted for quick inspection.\n */\nexport type GameStateSummary = {\n gameId: string;\n turn: number;\n nextAction: string;\n playersCount: number;\n dominoesRemaining: number;\n currentDominoesCount: number;\n lordsCount: number;\n};\n\n/**\n * A single debug log entry emitted by the debug wrapper.\n */\nexport type DebugLogEntry = {\n timestamp: string;\n method: string;\n phase: \"before\" | \"after\" | \"error\";\n summary: GameStateSummary | null;\n params?: Record<string, unknown>;\n error?: string;\n durationMs?: number;\n fullState?: GameState;\n};\n\n/**\n * Custom debug logger interface.\n * Consumers can provide their own to redirect debug output.\n */\nexport type DebugLogger = {\n log: (entry: DebugLogEntry) => void;\n};\n\n/**\n * Configuration for the debug wrapper.\n */\nexport type DebugOptions = {\n /** Custom debug logger. Defaults to console-based logger. */\n logger?: DebugLogger;\n /** Verbosity level. Defaults to \"standard\". */\n level?: DebugLogLevel;\n};\n\n// ─── Helpers ────────────────────────────────────────────────────────\n\n/**\n * Extracts a concise summary from a game state object.\n */\nexport const summarizeGameState = (game: GameState): GameStateSummary => {\n const nextAction = isGameWithNextAction(game)\n ? `action:${game.nextAction.nextAction}`\n : `step:${game.nextAction.step}`;\n\n return {\n gameId: game.id,\n turn: game.turn,\n nextAction,\n playersCount: game.players.length,\n dominoesRemaining: game.dominoes.length,\n currentDominoesCount: game.currentDominoes.length,\n lordsCount: game.lords.length,\n };\n};\n\nconst defaultDebugLogger: DebugLogger = {\n log: (entry: DebugLogEntry) => {\n const phase = entry.phase.toUpperCase().padEnd(5);\n const base = `[KDomino:Debug] ${entry.timestamp} ${phase} ${entry.method}`;\n\n if (entry.phase === \"error\") {\n console.error(`${base} | error: ${entry.error}`);\n return;\n }\n\n if (entry.summary) {\n const s = entry.summary;\n console.log(\n `${base} | turn=${s.turn} next=${s.nextAction} players=${s.playersCount} dominoes=${s.dominoesRemaining}`,\n );\n } else {\n console.log(base);\n }\n },\n};\n\nconst isGameState = (value: unknown): value is GameState => {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"id\" in value &&\n \"nextAction\" in value &&\n \"players\" in value &&\n \"dominoes\" in value\n );\n};\n\ntype CommandWithGame = { game: GameState; [key: string]: unknown };\n\nconst hasGameInCommand = (cmd: unknown): cmd is CommandWithGame => {\n return (\n typeof cmd === \"object\" &&\n cmd !== null &&\n \"game\" in cmd &&\n isGameState((cmd as CommandWithGame).game)\n );\n};\n\nconst extractParams = (cmd: unknown): Record<string, unknown> | undefined => {\n if (typeof cmd !== \"object\" || cmd === null) return undefined;\n\n const record = cmd as Record<string, unknown>;\n const params: Record<string, unknown> = {};\n\n if (\"mode\" in record) params.mode = record.mode;\n if (\"lordId\" in record) params.lordId = record.lordId;\n if (\"dominoPick\" in record) params.dominoPick = record.dominoPick;\n if (\"position\" in record) params.position = record.position;\n if (\"rotation\" in record) params.rotation = record.rotation;\n if (\"players\" in record) params.players = record.players;\n if (\"extraRules\" in record) params.extraRules = record.extraRules;\n\n return Object.keys(params).length > 0 ? params : undefined;\n};\n\n// ─── Wrapper ────────────────────────────────────────────────────────\n\nconst wrapMethod = <TArgs, TResult>(\n method: string,\n fn: (cmd: TArgs) => TResult,\n logger: DebugLogger,\n level: DebugLogLevel,\n): ((cmd: TArgs) => TResult) => {\n return (cmd: TArgs) => {\n const timestamp = new Date().toISOString();\n\n // Before\n const beforeSummary =\n level !== \"minimal\" && hasGameInCommand(cmd)\n ? summarizeGameState(cmd.game)\n : null;\n\n const beforeEntry: DebugLogEntry = {\n timestamp,\n method,\n phase: \"before\",\n summary: beforeSummary,\n params: level !== \"minimal\" ? extractParams(cmd) : undefined,\n };\n\n logger.log(beforeEntry);\n\n // Execute\n const start = performance.now();\n let result: TResult;\n try {\n result = fn(cmd);\n } catch (err) {\n const durationMs = Math.round((performance.now() - start) * 100) / 100;\n const errorEntry: DebugLogEntry = {\n timestamp: new Date().toISOString(),\n method,\n phase: \"error\",\n summary: beforeSummary,\n error: err instanceof Error ? err.message : String(err),\n durationMs,\n };\n logger.log(errorEntry);\n throw err;\n }\n\n const durationMs = Math.round((performance.now() - start) * 100) / 100;\n\n // After\n const afterSummary =\n level !== \"minimal\" && isGameState(result)\n ? summarizeGameState(result as GameState)\n : null;\n\n const afterEntry: DebugLogEntry = {\n timestamp: new Date().toISOString(),\n method,\n phase: \"after\",\n summary: afterSummary,\n durationMs,\n fullState:\n level === \"verbose\" && isGameState(result)\n ? (result as GameState)\n : undefined,\n };\n\n logger.log(afterEntry);\n\n return result;\n };\n};\n\n/**\n * Wraps a GameEngine to emit detailed debug log entries before and after each method call.\n * Useful for UI developers to inspect engine behavior at every step.\n *\n * @param engine - The base game engine to wrap\n * @param options - Debug configuration (logger, verbosity level)\n * @returns A new GameEngine that emits debug logs\n *\n * @example\n * ```typescript\n * const debugEngine = wrapWithDebug(engine, { level: \"verbose\" });\n * let game = debugEngine.createGame({ mode: \"Classic\" });\n * // Console: [KDomino:Debug] ... BEFORE createGame\n * // Console: [KDomino:Debug] ... AFTER createGame | turn=0 ...\n * ```\n */\nexport const wrapWithDebug = (\n engine: GameEngine,\n options?: DebugOptions,\n): GameEngine => {\n const logger = options?.logger ?? defaultDebugLogger;\n const level = options?.level ?? \"standard\";\n\n return {\n getModes: wrapMethod(\"getModes\", engine.getModes, logger, level),\n getExtraRules: wrapMethod(\n \"getExtraRules\",\n engine.getExtraRules,\n logger,\n level,\n ),\n createGame: wrapMethod(\"createGame\", engine.createGame, logger, level),\n addPlayers: wrapMethod(\"addPlayers\", engine.addPlayers, logger, level),\n addExtraRules: wrapMethod(\n \"addExtraRules\",\n engine.addExtraRules,\n logger,\n level,\n ),\n startGame: wrapMethod(\"startGame\", engine.startGame, logger, level),\n chooseDomino: wrapMethod(\n \"chooseDomino\",\n engine.chooseDomino,\n logger,\n level,\n ),\n placeDomino: wrapMethod(\"placeDomino\", engine.placeDomino, logger, level),\n discardDomino: wrapMethod(\n \"discardDomino\",\n engine.discardDomino,\n logger,\n level,\n ),\n getResults: wrapMethod(\"getResults\", engine.getResults, logger, level),\n calculateScore: wrapMethod(\n \"calculateScore\",\n engine.calculateScore,\n logger,\n level,\n ),\n getValidPlacements: wrapMethod(\n \"getValidPlacements\",\n engine.getValidPlacements,\n logger,\n level,\n ),\n canPlaceDomino: wrapMethod(\n \"canPlaceDomino\",\n engine.canPlaceDomino,\n logger,\n level,\n ),\n serialize: wrapMethod(\"serialize\", engine.serialize, logger, level),\n deserialize: wrapMethod(\"deserialize\", engine.deserialize, logger, level),\n getDynastyResults: wrapMethod(\n \"getDynastyResults\",\n engine.getDynastyResults,\n logger,\n level,\n ),\n placeKnight: wrapMethod(\"placeKnight\", engine.placeKnight, logger, level),\n constructBuilding: wrapMethod(\n \"constructBuilding\",\n engine.constructBuilding,\n logger,\n level,\n ),\n useDragon: wrapMethod(\"useDragon\", engine.useDragon, logger, level),\n skipOptionalAction: wrapMethod(\n \"skipOptionalAction\",\n engine.skipOptionalAction,\n logger,\n level,\n ),\n placeFireToken: wrapMethod(\n \"placeFireToken\",\n engine.placeFireToken,\n logger,\n level,\n ),\n recruitCaveman: wrapMethod(\n \"recruitCaveman\",\n engine.recruitCaveman,\n logger,\n level,\n ),\n placeGiant: wrapMethod(\"placeGiant\", engine.placeGiant, logger, level),\n sendGiant: wrapMethod(\"sendGiant\", engine.sendGiant, logger, level),\n };\n};\n","import { isGameWithNextStep } from \"@core/domain/types/game.js\";\nimport type {\n GameState,\n GameWithNextAction,\n GameWithNextStep,\n} from \"@core/domain/types/index.js\";\nimport type { GameEngine } from \"@core/portUserside/engine.js\";\n\n// ─── Event Types ─────────────────────────────────────────────────────\n\n/**\n * Optional callbacks for game events.\n * Consumers provide these to react to state changes (UI updates, animations, logging).\n * All callbacks are optional — only the ones you provide will be called.\n *\n * @example\n * ```typescript\n * const engine = createGameEngine({\n * events: {\n * onDominoPlaced: ({ game, lordId }) => {\n * console.log(`Lord ${lordId} placed a domino`);\n * animatePlacement(game);\n * },\n * onTurnEnd: ({ turn }) => console.log(`Turn ${turn} ended`),\n * onGameEnd: () => showResultsScreen(),\n * },\n * });\n * ```\n */\nexport type GameEventCallbacks = {\n /** Called after a new game is created */\n onGameCreated?: (event: { game: GameWithNextStep }) => void;\n /** Called after players are added to the game */\n onPlayersAdded?: (event: { game: GameWithNextStep }) => void;\n /** Called after the game starts (first dominoes revealed) */\n onGameStarted?: (event: { game: GameWithNextAction }) => void;\n /** Called after a lord picks a domino */\n onDominoPicked?: (event: {\n game: GameState;\n lordId: string;\n dominoNumber: number;\n }) => void;\n /** Called after a lord places a domino on their kingdom */\n onDominoPlaced?: (event: { game: GameState; lordId: string }) => void;\n /** Called after a lord discards a domino (no valid placement) */\n onDominoDiscarded?: (event: { game: GameState; lordId: string }) => void;\n /** Called when a new turn begins */\n onTurnStart?: (event: { game: GameState; turn: number }) => void;\n /** Called when a turn ends (all lords have played) */\n onTurnEnd?: (event: { game: GameState; turn: number }) => void;\n /** Called when the game reaches the result phase */\n onGameEnd?: (event: { game: GameState }) => void;\n /** Called after a lord places a knight on their kingdom (QueenDomino) */\n onKnightPlaced?: (event: { game: GameState; lordId: string }) => void;\n /** Called after a lord constructs a building (QueenDomino) */\n onBuildingConstructed?: (event: {\n game: GameState;\n lordId: string;\n buildingId: number;\n }) => void;\n /** Called after a lord uses the dragon to destroy a building (QueenDomino) */\n onDragonUsed?: (event: {\n game: GameState;\n lordId: string;\n buildingId: number;\n }) => void;\n /** Called after a lord places a fire token on their kingdom (Origins) */\n onFireTokenPlaced?: (event: { game: GameState; lordId: string }) => void;\n /** Called after a lord recruits a caveman from the cave board (Origins Tribe) */\n onCavemanRecruited?: (event: {\n game: GameState;\n lordId: string;\n cavemanId: number;\n }) => void;\n /** Called after a lord places a giant on a crown in their kingdom */\n onGiantPlaced?: (event: { game: GameState; lordId: string }) => void;\n /** Called after a lord sends a giant to an opponent's kingdom */\n onGiantSent?: (event: {\n game: GameState;\n lordId: string;\n targetPlayerId: string;\n }) => void;\n};\n\n// ─── Wrapper ─────────────────────────────────────────────────────────\n\nconst isGameEnded = (game: GameState): boolean =>\n isGameWithNextStep(game) && game.nextAction.step === \"result\";\n\n/**\n * Wraps a GameEngine to emit event callbacks after each state-changing method.\n * Read-only methods (getModes, calculateScore, etc.) are passed through unchanged.\n *\n * Derived events:\n * - `onTurnEnd` + `onTurnStart`: emitted when `chooseDomino` causes a turn increment\n * - `onGameEnd`: emitted when `placeDomino` or `discardDomino` transitions to the \"result\" step\n *\n * @param engine - The base game engine to wrap\n * @param callbacks - Optional event callbacks\n * @returns A new GameEngine that emits events\n */\nexport const wrapWithEvents = (\n engine: GameEngine,\n callbacks: GameEventCallbacks,\n): GameEngine => ({\n // Read-only methods — pass through\n getModes: (cmd) => engine.getModes(cmd),\n getExtraRules: (cmd) => engine.getExtraRules(cmd),\n calculateScore: (cmd) => engine.calculateScore(cmd),\n getValidPlacements: (cmd) => engine.getValidPlacements(cmd),\n canPlaceDomino: (cmd) => engine.canPlaceDomino(cmd),\n serialize: (cmd) => engine.serialize(cmd),\n deserialize: (cmd) => engine.deserialize(cmd),\n getResults: (cmd) => engine.getResults(cmd),\n getDynastyResults: (cmd) => engine.getDynastyResults(cmd),\n\n // State-changing methods — emit events after execution\n createGame: (cmd) => {\n const game = engine.createGame(cmd);\n callbacks.onGameCreated?.({ game });\n return game;\n },\n\n addPlayers: (cmd) => {\n const game = engine.addPlayers(cmd);\n callbacks.onPlayersAdded?.({ game });\n return game;\n },\n\n addExtraRules: (cmd) => engine.addExtraRules(cmd),\n\n startGame: (cmd) => {\n const game = engine.startGame(cmd);\n callbacks.onGameStarted?.({ game });\n callbacks.onTurnStart?.({ game, turn: game.turn });\n return game;\n },\n\n chooseDomino: (cmd) => {\n const turnBefore = cmd.game.turn;\n const game = engine.chooseDomino(cmd);\n callbacks.onDominoPicked?.({\n game,\n lordId: cmd.lordId,\n dominoNumber: cmd.dominoPick,\n });\n\n // Detect turn transition\n if (game.turn !== turnBefore) {\n callbacks.onTurnEnd?.({ game, turn: turnBefore });\n callbacks.onTurnStart?.({ game, turn: game.turn });\n }\n\n return game;\n },\n\n placeDomino: (cmd) => {\n const game = engine.placeDomino(cmd);\n callbacks.onDominoPlaced?.({ game, lordId: cmd.lordId });\n\n if (isGameEnded(game)) {\n callbacks.onGameEnd?.({ game });\n }\n\n return game;\n },\n\n discardDomino: (cmd) => {\n const game = engine.discardDomino(cmd);\n callbacks.onDominoDiscarded?.({ game, lordId: cmd.lordId });\n\n if (isGameEnded(game)) {\n callbacks.onGameEnd?.({ game });\n }\n\n return game;\n },\n\n // Queendomino methods — emit events after execution\n placeKnight: (cmd) => {\n const game = engine.placeKnight(cmd);\n callbacks.onKnightPlaced?.({ game, lordId: cmd.lordId });\n return game;\n },\n\n constructBuilding: (cmd) => {\n const game = engine.constructBuilding(cmd);\n callbacks.onBuildingConstructed?.({\n game,\n lordId: cmd.lordId,\n buildingId: cmd.buildingId,\n });\n return game;\n },\n\n useDragon: (cmd) => {\n const game = engine.useDragon(cmd);\n callbacks.onDragonUsed?.({\n game,\n lordId: cmd.lordId,\n buildingId: cmd.buildingId,\n });\n return game;\n },\n\n skipOptionalAction: (cmd) => engine.skipOptionalAction(cmd),\n\n // Origins methods — emit events after execution\n placeFireToken: (cmd) => {\n const game = engine.placeFireToken(cmd);\n callbacks.onFireTokenPlaced?.({ game, lordId: cmd.lordId });\n return game;\n },\n\n recruitCaveman: (cmd) => {\n const game = engine.recruitCaveman(cmd);\n callbacks.onCavemanRecruited?.({\n game,\n lordId: cmd.lordId,\n cavemanId: cmd.cavemanId,\n });\n return game;\n },\n\n // Age of Giants methods — emit events after execution\n placeGiant: (cmd) => {\n const game = engine.placeGiant(cmd);\n callbacks.onGiantPlaced?.({ game, lordId: cmd.lordId });\n return game;\n },\n\n sendGiant: (cmd) => {\n const game = engine.sendGiant(cmd);\n callbacks.onGiantSent?.({\n game,\n lordId: cmd.lordId,\n targetPlayerId: cmd.targetPlayerId,\n });\n return game;\n },\n});\n","import type { Logger } from \"@core/portServerside/logger.js\";\n\n/**\n * Creates a lightweight console-based logger.\n * This is the default logger used when no custom logger is provided.\n * @param isLoggingEnabled - Whether logging is enabled\n * @returns A Logger instance that outputs to console\n */\nexport const consoleLogger = (isLoggingEnabled: boolean): Logger => {\n const formatMessage = (level: string, message: string): string => {\n const timestamp = new Date().toISOString();\n return `${timestamp} [KDomino_Engine] ${level}: ${message}`;\n };\n\n return {\n info: (message: string) => {\n if (isLoggingEnabled) {\n console.log(formatMessage(\"info\", message));\n }\n },\n error: (message: string) => {\n if (isLoggingEnabled) {\n console.error(formatMessage(\"error\", message));\n }\n },\n };\n};\n\n/**\n * A silent logger that does nothing.\n * Useful for testing or when logging should be completely disabled.\n */\nexport const silentLogger: Logger = {\n info: () => {},\n error: () => {},\n};\n","[\n { \"id\": 1, \"name\": \"The Bakery\", \"cost\": 1, \"immediateBonus\": { \"type\": \"coins\", \"amount\": 2 }, \"crowns\": 0, \"towers\": 0 },\n { \"id\": 2, \"name\": \"The Bakery\", \"cost\": 1, \"immediateBonus\": { \"type\": \"coins\", \"amount\": 2 }, \"crowns\": 0, \"towers\": 0 },\n { \"id\": 3, \"name\": \"The Sawmill\", \"cost\": 2, \"crowns\": 0, \"towers\": 0, \"endGameScoring\": { \"type\": \"perTerrain\", \"terrain\": \"forest\", \"points\": 1 } },\n { \"id\": 4, \"name\": \"The Fishmonger's\", \"cost\": 2, \"immediateBonus\": { \"type\": \"coins\", \"amount\": 1 }, \"crowns\": 0, \"towers\": 0, \"endGameScoring\": { \"type\": \"perTerrain\", \"terrain\": \"sea\", \"points\": 1 } },\n { \"id\": 5, \"name\": \"The Fishmonger's\", \"cost\": 2, \"immediateBonus\": { \"type\": \"coins\", \"amount\": 1 }, \"crowns\": 0, \"towers\": 0, \"endGameScoring\": { \"type\": \"perTerrain\", \"terrain\": \"sea\", \"points\": 1 } },\n { \"id\": 6, \"name\": \"The Weaving Shop\", \"cost\": 3, \"crowns\": 1, \"towers\": 0, \"endGameScoring\": { \"type\": \"perTerrain\", \"terrain\": \"wheat\", \"points\": 1 } },\n { \"id\": 7, \"name\": \"The Magic School\", \"cost\": 4, \"crowns\": 1, \"towers\": 0, \"endGameScoring\": { \"type\": \"perCrown\", \"points\": 1 } },\n { \"id\": 8, \"name\": \"The Fountain\", \"cost\": 3, \"crowns\": 0, \"towers\": 1, \"endGameScoring\": { \"type\": \"perTower\", \"points\": 2 } },\n { \"id\": 9, \"name\": \"The Church\", \"cost\": 4, \"crowns\": 1, \"towers\": 0, \"endGameScoring\": { \"type\": \"perBuilding\", \"points\": 2 } },\n { \"id\": 10, \"name\": \"The Bath\", \"cost\": 2, \"immediateBonus\": { \"type\": \"coins\", \"amount\": 1 }, \"crowns\": 0, \"towers\": 0, \"endGameScoring\": { \"type\": \"flat\", \"points\": 4 } },\n { \"id\": 11, \"name\": \"The Guard Tower\", \"cost\": 1, \"crowns\": 0, \"towers\": 1, \"endGameScoring\": { \"type\": \"flat\", \"points\": 2 } },\n { \"id\": 12, \"name\": \"The Guard Tower\", \"cost\": 1, \"crowns\": 0, \"towers\": 1, \"endGameScoring\": { \"type\": \"flat\", \"points\": 2 } },\n { \"id\": 13, \"name\": \"The Big Tower\", \"cost\": 3, \"crowns\": 0, \"towers\": 2, \"endGameScoring\": { \"type\": \"flat\", \"points\": 4 } },\n { \"id\": 14, \"name\": \"The Guardhouse\", \"cost\": 2, \"crowns\": 0, \"towers\": 1, \"endGameScoring\": { \"type\": \"perBuilding\", \"points\": 1 } },\n { \"id\": 15, \"name\": \"The Fortified Castle\", \"cost\": 5, \"crowns\": 2, \"towers\": 1, \"endGameScoring\": { \"type\": \"flat\", \"points\": 6 } },\n { \"id\": 16, \"name\": \"The Travelling Castle\", \"cost\": 3, \"crowns\": 1, \"towers\": 1, \"endGameScoring\": { \"type\": \"perTower\", \"points\": 1 } },\n { \"id\": 17, \"name\": \"The Travelling Group\", \"cost\": 2, \"immediateBonus\": { \"type\": \"coins\", \"amount\": 1 }, \"crowns\": 0, \"towers\": 0, \"endGameScoring\": { \"type\": \"perBuilding\", \"points\": 1 } },\n { \"id\": 18, \"name\": \"The Harbour\", \"cost\": 3, \"crowns\": 0, \"towers\": 0, \"endGameScoring\": { \"type\": \"perTerrain\", \"terrain\": \"sea\", \"points\": 2 } }\n]\n","import type {\n BuildingTile,\n EndGameScoring,\n EndGameScoringType,\n ImmediateBonus,\n ImmediateBonusType,\n} from \"@core/domain/types/building.js\";\nimport type { BuildingsRepository } from \"@core/portServerside/buildingsRepository.js\";\nimport buildingsJson from \"../datasources/buildings.json\" with { type: \"json\" };\n\nconst jsonBuildings = (): BuildingsRepository => {\n const buildings: BuildingTile[] = buildingsJson.map((b) => {\n const tile: BuildingTile = {\n id: b.id,\n name: b.name,\n cost: b.cost,\n crowns: b.crowns,\n towers: b.towers,\n };\n\n if (b.immediateBonus) {\n tile.immediateBonus = {\n type: b.immediateBonus.type as ImmediateBonusType,\n amount: b.immediateBonus.amount,\n } satisfies ImmediateBonus;\n }\n\n if (\"endGameScoring\" in b && b.endGameScoring) {\n tile.endGameScoring = {\n type: b.endGameScoring.type as EndGameScoringType,\n points: b.endGameScoring.points,\n ...(\"terrain\" in b.endGameScoring && {\n terrain: b.endGameScoring.terrain,\n }),\n } satisfies EndGameScoring;\n }\n\n return tile;\n });\n\n return {\n getAll: () => buildings,\n };\n};\n\nexport default jsonBuildings;\n","[\n { \"kind\": \"hunterGatherer\", \"id\": 1, \"hunterType\": \"mammothHunter\", \"pointsPerMatch\": 3 },\n { \"kind\": \"hunterGatherer\", \"id\": 2, \"hunterType\": \"mammothHunter\", \"pointsPerMatch\": 3 },\n { \"kind\": \"hunterGatherer\", \"id\": 3, \"hunterType\": \"fisherman\", \"pointsPerMatch\": 3 },\n { \"kind\": \"hunterGatherer\", \"id\": 4, \"hunterType\": \"fisherman\", \"pointsPerMatch\": 3 },\n { \"kind\": \"hunterGatherer\", \"id\": 5, \"hunterType\": \"mushroomPicker\", \"pointsPerMatch\": 3 },\n { \"kind\": \"hunterGatherer\", \"id\": 6, \"hunterType\": \"mushroomPicker\", \"pointsPerMatch\": 3 },\n { \"kind\": \"hunterGatherer\", \"id\": 7, \"hunterType\": \"flintCollector\", \"pointsPerMatch\": 3 },\n { \"kind\": \"hunterGatherer\", \"id\": 8, \"hunterType\": \"flintCollector\", \"pointsPerMatch\": 3 },\n { \"kind\": \"hunterGatherer\", \"id\": 9, \"hunterType\": \"trapper\", \"pointsPerMatch\": 2 },\n { \"kind\": \"hunterGatherer\", \"id\": 10, \"hunterType\": \"trapper\", \"pointsPerMatch\": 2 },\n { \"kind\": \"hunterGatherer\", \"id\": 11, \"hunterType\": \"gatherer\", \"pointsPerMatch\": 1 },\n { \"kind\": \"hunterGatherer\", \"id\": 12, \"hunterType\": \"gatherer\", \"pointsPerMatch\": 1 },\n { \"kind\": \"hunterGatherer\", \"id\": 13, \"hunterType\": \"fireLady\", \"pointsPerMatch\": 1 },\n { \"kind\": \"hunterGatherer\", \"id\": 14, \"hunterType\": \"fireLady\", \"pointsPerMatch\": 1 },\n { \"kind\": \"warrior\", \"id\": 15, \"warriorType\": \"small\", \"power\": 1 },\n { \"kind\": \"warrior\", \"id\": 16, \"warriorType\": \"small\", \"power\": 1 },\n { \"kind\": \"warrior\", \"id\": 17, \"warriorType\": \"small\", \"power\": 1 },\n { \"kind\": \"warrior\", \"id\": 18, \"warriorType\": \"small\", \"power\": 1 },\n { \"kind\": \"warrior\", \"id\": 19, \"warriorType\": \"amazon\", \"power\": 2 },\n { \"kind\": \"warrior\", \"id\": 20, \"warriorType\": \"amazon\", \"power\": 2 },\n { \"kind\": \"warrior\", \"id\": 21, \"warriorType\": \"amazon\", \"power\": 2 },\n { \"kind\": \"warrior\", \"id\": 22, \"warriorType\": \"oafish\", \"power\": 3 }\n]\n","import type {\n CavemanTile,\n HunterGathererKind,\n HunterGathererTile,\n WarriorTile,\n WarriorType,\n} from \"@core/domain/types/origins.js\";\nimport type { CavemenRepository } from \"@core/portServerside/cavemenRepository.js\";\nimport cavemenJson from \"../datasources/cavemen.json\" with { type: \"json\" };\n\nconst mapCaveman = (raw: {\n kind: string;\n id: number;\n hunterType?: string;\n pointsPerMatch?: number;\n warriorType?: string;\n power?: number;\n}): CavemanTile => {\n if (raw.kind === \"hunterGatherer\") {\n return {\n kind: \"hunterGatherer\",\n id: raw.id,\n hunterType: raw.hunterType as HunterGathererKind,\n pointsPerMatch: raw.pointsPerMatch!,\n } satisfies HunterGathererTile;\n }\n return {\n kind: \"warrior\",\n id: raw.id,\n warriorType: raw.warriorType as WarriorType,\n power: raw.power!,\n } satisfies WarriorTile;\n};\n\nconst jsonCavemen = (): CavemenRepository => {\n const cavemen: CavemanTile[] = cavemenJson.map(mapCaveman);\n\n return {\n getAll: () => [...cavemen],\n };\n};\n\nexport default jsonCavemen;\n","{\n \"Classic\": [\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 1\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 2\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 3\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 4\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 5\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 6\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 7\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 8\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 9\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 10\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 11\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 12\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 13\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 14\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 15\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 16\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 17\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 18\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 19\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 20\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 21\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 22\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 0\n },\n \"number\": 23\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 24\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 25\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 26\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 27\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 28\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 29\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 30\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 31\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 32\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 33\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 34\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 35\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 1\n },\n \"number\": 36\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 1\n },\n \"number\": 37\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 1\n },\n \"number\": 38\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 39\n },\n {\n \"left\": {\n \"type\": \"mine\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 40\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 2\n },\n \"number\": 41\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 2\n },\n \"number\": 42\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 2\n },\n \"number\": 43\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 2\n },\n \"number\": 44\n },\n {\n \"left\": {\n \"type\": \"mine\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 45\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 2\n },\n \"number\": 46\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 2\n },\n \"number\": 47\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 3\n },\n \"number\": 48\n }\n ],\n \"QueenDomino\": [\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 1\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 2\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 3\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 4\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 5\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 6\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 7\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 8\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 9\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 10\n },\n {\n \"left\": {\n \"type\": \"mine\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 0\n },\n \"number\": 11\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 12\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 13\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"number\": 14\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 15\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 16\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"number\": 17\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 18\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 19\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 20\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"number\": 21\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"number\": 22\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 23\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 24\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 25\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"number\": 26\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 27\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 1,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 28\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 0\n },\n \"number\": 29\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"number\": 30\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 1\n },\n \"number\": 31\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 1,\n \"hasConstructionSquare\": true\n },\n \"number\": 32\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 1\n },\n \"number\": 33\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 1,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 1\n },\n \"number\": 34\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 1\n },\n \"number\": 35\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 2,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 36\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"number\": 37\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 38\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 39\n },\n {\n \"left\": {\n \"type\": \"mine\",\n \"crowns\": 2,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 40\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 2\n },\n \"number\": 41\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 1,\n \"hasConstructionSquare\": true\n },\n \"number\": 42\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 1\n },\n \"number\": 43\n },\n {\n \"left\": {\n \"type\": \"mine\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 1\n },\n \"number\": 44\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 2\n },\n \"number\": 45\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 2,\n \"hasConstructionSquare\": true\n },\n \"number\": 46\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 3\n },\n \"number\": 47\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 3\n },\n \"number\": 48\n }\n ],\n \"KingdominoOrigins\": [\n {\n \"left\": {\n \"type\": \"grassland\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"grassland\",\n \"crowns\": 0\n },\n \"number\": 1\n },\n {\n \"left\": {\n \"type\": \"grassland\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"lake\",\n \"crowns\": 0\n },\n \"number\": 2\n },\n {\n \"left\": {\n \"type\": \"grassland\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"jungle\",\n \"crowns\": 0\n },\n \"number\": 3\n },\n {\n \"left\": {\n \"type\": \"grassland\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"quarry\",\n \"crowns\": 0\n },\n \"number\": 4\n },\n {\n \"left\": {\n \"type\": \"grassland\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"desert\",\n \"crowns\": 0\n },\n \"number\": 5\n },\n {\n \"left\": {\n \"type\": \"grassland\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"grassland\",\n \"crowns\": 0\n },\n \"number\": 6\n },\n {\n \"left\": {\n \"type\": \"lake\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"lake\",\n \"crowns\": 0\n },\n \"number\": 7\n },\n {\n \"left\": {\n \"type\": \"lake\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"jungle\",\n \"crowns\": 0\n },\n \"number\": 8\n },\n {\n \"left\": {\n \"type\": \"lake\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"quarry\",\n \"crowns\": 0\n },\n \"number\": 9\n },\n {\n \"left\": {\n \"type\": \"lake\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"desert\",\n \"crowns\": 0\n },\n \"number\": 10\n },\n {\n \"left\": {\n \"type\": \"jungle\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"jungle\",\n \"crowns\": 0\n },\n \"number\": 11\n },\n {\n \"left\": {\n \"type\": \"jungle\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"quarry\",\n \"crowns\": 0\n },\n \"number\": 12\n },\n {\n \"left\": {\n \"type\": \"jungle\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"desert\",\n \"crowns\": 0\n },\n \"number\": 13\n },\n {\n \"left\": {\n \"type\": \"quarry\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"quarry\",\n \"crowns\": 0\n },\n \"number\": 14\n },\n {\n \"left\": {\n \"type\": \"quarry\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"desert\",\n \"crowns\": 0\n },\n \"number\": 15\n },\n {\n \"left\": {\n \"type\": \"desert\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"desert\",\n \"crowns\": 0\n },\n \"number\": 16\n },\n {\n \"left\": {\n \"type\": \"grassland\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"grassland\",\n \"crowns\": 0\n },\n \"number\": 17\n },\n {\n \"left\": {\n \"type\": \"grassland\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"lake\",\n \"crowns\": 0\n },\n \"number\": 18\n },\n {\n \"left\": {\n \"type\": \"grassland\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"jungle\",\n \"crowns\": 0\n },\n \"number\": 19\n },\n {\n \"left\": {\n \"type\": \"volcano\",\n \"crowns\": 0,\n \"volcanoCraters\": 1\n },\n \"right\": {\n \"type\": \"grassland\",\n \"crowns\": 0\n },\n \"number\": 20\n },\n {\n \"left\": {\n \"type\": \"lake\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"jungle\",\n \"crowns\": 0\n },\n \"number\": 21\n },\n {\n \"left\": {\n \"type\": \"lake\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"desert\",\n \"crowns\": 0\n },\n \"number\": 22\n },\n {\n \"left\": {\n \"type\": \"jungle\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"quarry\",\n \"crowns\": 0\n },\n \"number\": 23\n },\n {\n \"left\": {\n \"type\": \"volcano\",\n \"crowns\": 0,\n \"volcanoCraters\": 1\n },\n \"right\": {\n \"type\": \"lake\",\n \"crowns\": 0\n },\n \"number\": 24\n },\n {\n \"left\": {\n \"type\": \"grassland\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"grassland\",\n \"crowns\": 0\n },\n \"number\": 25\n },\n {\n \"left\": {\n \"type\": \"grassland\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"lake\",\n \"crowns\": 1\n },\n \"number\": 26\n },\n {\n \"left\": {\n \"type\": \"volcano\",\n \"crowns\": 0,\n \"volcanoCraters\": 1\n },\n \"right\": {\n \"type\": \"jungle\",\n \"crowns\": 0\n },\n \"number\": 27\n },\n {\n \"left\": {\n \"type\": \"lake\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"quarry\",\n \"crowns\": 0\n },\n \"number\": 28\n },\n {\n \"left\": {\n \"type\": \"jungle\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"desert\",\n \"crowns\": 0\n },\n \"number\": 29\n },\n {\n \"left\": {\n \"type\": \"volcano\",\n \"crowns\": 0,\n \"volcanoCraters\": 1\n },\n \"right\": {\n \"type\": \"quarry\",\n \"crowns\": 0\n },\n \"number\": 30\n },\n {\n \"left\": {\n \"type\": \"desert\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"grassland\",\n \"crowns\": 0\n },\n \"number\": 31\n },\n {\n \"left\": {\n \"type\": \"quarry\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"lake\",\n \"crowns\": 0\n },\n \"number\": 32\n },\n {\n \"left\": {\n \"type\": \"volcano\",\n \"crowns\": 0,\n \"volcanoCraters\": 2\n },\n \"right\": {\n \"type\": \"grassland\",\n \"crowns\": 0\n },\n \"number\": 33\n },\n {\n \"left\": {\n \"type\": \"jungle\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"jungle\",\n \"crowns\": 0\n },\n \"number\": 34\n },\n {\n \"left\": {\n \"type\": \"lake\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"desert\",\n \"crowns\": 0\n },\n \"number\": 35\n },\n {\n \"left\": {\n \"type\": \"volcano\",\n \"crowns\": 0,\n \"volcanoCraters\": 2\n },\n \"right\": {\n \"type\": \"jungle\",\n \"crowns\": 0\n },\n \"number\": 36\n },\n {\n \"left\": {\n \"type\": \"grassland\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"quarry\",\n \"crowns\": 1\n },\n \"number\": 37\n },\n {\n \"left\": {\n \"type\": \"volcano\",\n \"crowns\": 0,\n \"volcanoCraters\": 1\n },\n \"right\": {\n \"type\": \"desert\",\n \"crowns\": 1\n },\n \"number\": 38\n },\n {\n \"left\": {\n \"type\": \"lake\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"jungle\",\n \"crowns\": 1\n },\n \"number\": 39\n },\n {\n \"left\": {\n \"type\": \"volcano\",\n \"crowns\": 0,\n \"volcanoCraters\": 2\n },\n \"right\": {\n \"type\": \"quarry\",\n \"crowns\": 1\n },\n \"number\": 40\n },\n {\n \"left\": {\n \"type\": \"desert\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"grassland\",\n \"crowns\": 1\n },\n \"number\": 41\n },\n {\n \"left\": {\n \"type\": \"quarry\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"grassland\",\n \"crowns\": 0\n },\n \"number\": 42\n },\n {\n \"left\": {\n \"type\": \"volcano\",\n \"crowns\": 0,\n \"volcanoCraters\": 2\n },\n \"right\": {\n \"type\": \"lake\",\n \"crowns\": 1\n },\n \"number\": 43\n },\n {\n \"left\": {\n \"type\": \"jungle\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"desert\",\n \"crowns\": 0\n },\n \"number\": 44\n },\n {\n \"left\": {\n \"type\": \"lake\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"grassland\",\n \"crowns\": 0\n },\n \"number\": 45\n },\n {\n \"left\": {\n \"type\": \"desert\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"quarry\",\n \"crowns\": 1\n },\n \"number\": 46\n },\n {\n \"left\": {\n \"type\": \"volcano\",\n \"crowns\": 0,\n \"volcanoCraters\": 3\n },\n \"right\": {\n \"type\": \"grassland\",\n \"crowns\": 2\n },\n \"number\": 47\n },\n {\n \"left\": {\n \"type\": \"jungle\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"quarry\",\n \"crowns\": 2\n },\n \"number\": 48\n }\n ],\n \"AgeOfGiants\": [\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 1\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 2\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 3\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 4\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 5\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 6\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 7\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 8\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 9\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 10\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 11\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 12\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 13\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 14\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 15\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 16\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 17\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 18\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 19\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 20\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 21\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 22\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 0\n },\n \"number\": 23\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 24\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 25\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 26\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 27\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 28\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 29\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 30\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 31\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 32\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 33\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 34\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 35\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 1\n },\n \"number\": 36\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 1\n },\n \"number\": 37\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 1\n },\n \"number\": 38\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 39\n },\n {\n \"left\": {\n \"type\": \"mine\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 40\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 2\n },\n \"number\": 41\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 2\n },\n \"number\": 42\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 2\n },\n \"number\": 43\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 2\n },\n \"number\": 44\n },\n {\n \"left\": {\n \"type\": \"mine\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 45\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 2\n },\n \"number\": 46\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 2\n },\n \"number\": 47\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 3\n },\n \"number\": 48\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 1,\n \"hasGiant\": true\n },\n \"number\": 0.01,\n \"letter\": \"A\"\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 1,\n \"hasGiant\": true\n },\n \"number\": 0.02,\n \"letter\": \"B\"\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 1,\n \"hasGiant\": true\n },\n \"number\": 0.03,\n \"letter\": \"C\"\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 1,\n \"hasGiant\": true\n },\n \"number\": 0.04,\n \"letter\": \"D\"\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 1,\n \"hasGiant\": true\n },\n \"number\": 0.05,\n \"letter\": \"E\"\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 1,\n \"hasGiant\": true\n },\n \"number\": 0.06,\n \"letter\": \"F\"\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1,\n \"hasFootprint\": true\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 49\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1,\n \"hasFootprint\": true\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 50\n },\n {\n \"left\": {\n \"type\": \"mine\",\n \"crowns\": 1,\n \"hasFootprint\": true\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 51\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1,\n \"hasFootprint\": true\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 52\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 1,\n \"hasFootprint\": true\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 53\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 2,\n \"hasFootprint\": true\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 54\n }\n ],\n \"AgeOfGiants-QueenDomino\": [\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 1\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 2\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 3\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 4\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 5\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 6\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 7\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 8\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 9\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 10\n },\n {\n \"left\": {\n \"type\": \"mine\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 0\n },\n \"number\": 11\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 12\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 13\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"number\": 14\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 15\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 16\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"number\": 17\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"number\": 18\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 19\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 20\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"number\": 21\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"number\": 22\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 23\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 24\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 25\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"number\": 26\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 27\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 1,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 28\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 0\n },\n \"number\": 29\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"number\": 30\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 1\n },\n \"number\": 31\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 1,\n \"hasConstructionSquare\": true\n },\n \"number\": 32\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 1\n },\n \"number\": 33\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 1,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 1\n },\n \"number\": 34\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 1\n },\n \"number\": 35\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 2,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 36\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0,\n \"hasConstructionSquare\": true\n },\n \"number\": 37\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 38\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 39\n },\n {\n \"left\": {\n \"type\": \"mine\",\n \"crowns\": 2,\n \"hasConstructionSquare\": true\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 40\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 2\n },\n \"number\": 41\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 1,\n \"hasConstructionSquare\": true\n },\n \"number\": 42\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 1\n },\n \"number\": 43\n },\n {\n \"left\": {\n \"type\": \"mine\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 1\n },\n \"number\": 44\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 2\n },\n \"number\": 45\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 2,\n \"hasConstructionSquare\": true\n },\n \"number\": 46\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 3\n },\n \"number\": 47\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 2\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 3\n },\n \"number\": 48\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 1,\n \"hasGiant\": true\n },\n \"number\": 0.01,\n \"letter\": \"A\"\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 1,\n \"hasGiant\": true\n },\n \"number\": 0.02,\n \"letter\": \"B\"\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"swamp\",\n \"crowns\": 1,\n \"hasGiant\": true\n },\n \"number\": 0.03,\n \"letter\": \"C\"\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"mine\",\n \"crowns\": 1,\n \"hasGiant\": true\n },\n \"number\": 0.04,\n \"letter\": \"D\"\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 1,\n \"hasGiant\": true\n },\n \"number\": 0.05,\n \"letter\": \"E\"\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 0\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 1,\n \"hasGiant\": true\n },\n \"number\": 0.06,\n \"letter\": \"F\"\n },\n {\n \"left\": {\n \"type\": \"forest\",\n \"crowns\": 1,\n \"hasFootprint\": true\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 49\n },\n {\n \"left\": {\n \"type\": \"wheat\",\n \"crowns\": 1,\n \"hasFootprint\": true\n },\n \"right\": {\n \"type\": \"sea\",\n \"crowns\": 0\n },\n \"number\": 50\n },\n {\n \"left\": {\n \"type\": \"mine\",\n \"crowns\": 1,\n \"hasFootprint\": true\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 51\n },\n {\n \"left\": {\n \"type\": \"sea\",\n \"crowns\": 1,\n \"hasFootprint\": true\n },\n \"right\": {\n \"type\": \"forest\",\n \"crowns\": 0\n },\n \"number\": 52\n },\n {\n \"left\": {\n \"type\": \"swamp\",\n \"crowns\": 1,\n \"hasFootprint\": true\n },\n \"right\": {\n \"type\": \"plain\",\n \"crowns\": 0\n },\n \"number\": 53\n },\n {\n \"left\": {\n \"type\": \"plain\",\n \"crowns\": 2,\n \"hasFootprint\": true\n },\n \"right\": {\n \"type\": \"wheat\",\n \"crowns\": 0\n },\n \"number\": 54\n }\n ]\n}","import type { Domino, Ground, Tile } from \"@core/domain/types/domino.js\";\nimport type { GameMode } from \"@core/domain/types/mode.js\";\nimport type { DominoesRepository } from \"@core/portServerside/dominoesRepository.js\";\nimport dominoesJson from \"../datasources/dominoes.json\" with { type: \"json\" };\n\nconst mapTile = (raw: {\n type: string;\n crowns: number;\n hasConstructionSquare?: boolean;\n volcanoCraters?: number;\n hasGiant?: boolean;\n hasFootprint?: boolean;\n}): Tile => {\n const tile: Tile = {\n type: raw.type as Ground,\n crowns: raw.crowns,\n };\n if (raw.hasConstructionSquare) {\n tile.hasConstructionSquare = true;\n }\n if (raw.volcanoCraters) {\n tile.volcanoCraters = raw.volcanoCraters;\n }\n if (raw.hasGiant) {\n tile.hasGiant = true;\n }\n if (raw.hasFootprint) {\n tile.hasFootprint = true;\n }\n return tile;\n};\n\n/** Maps Origins sub-mode names to the shared domino data key */\nconst ORIGINS_MODE_PREFIX = \"KingdominoOrigins\";\nconst resolveDataKey = (modeName: string): string => {\n if (modeName.startsWith(ORIGINS_MODE_PREFIX)) {\n return ORIGINS_MODE_PREFIX;\n }\n return modeName;\n};\n\nconst jsonDominoes = (): DominoesRepository => {\n const dominoes: Record<string, Domino[]> = {};\n\n for (const [key, value] of Object.entries(dominoesJson)) {\n const currentDominoes: Domino[] = [];\n value.forEach((domino) => {\n const d: Domino = {\n left: mapTile(domino.left),\n right: mapTile(domino.right),\n number: domino.number,\n };\n if (\"letter\" in domino && typeof domino.letter === \"string\") {\n d.letter = domino.letter;\n }\n currentDominoes.push(d);\n });\n\n dominoes[key] = currentDominoes;\n }\n\n return {\n getForMode: (mode: GameMode) => {\n const key = resolveDataKey(mode.name);\n return dominoes[key] || [];\n },\n };\n};\n\nexport default jsonDominoes;\n","[\n {\n \"name\": \"Classic\",\n \"description\": \"Original KingDomino rules\"\n },\n {\n \"name\": \"QueenDomino\",\n \"description\": \"Queendomino expansion with buildings, knights, coins, the Queen and the Dragon\"\n },\n {\n \"name\": \"KingdominoOrigins-Discovery\",\n \"description\": \"Kingdomino Origins - Discovery mode with volcanoes, fire tokens and fire-based scoring\"\n },\n {\n \"name\": \"KingdominoOrigins-Totem\",\n \"description\": \"Kingdomino Origins - Totem mode with resources, totem majority and fire mechanics\"\n },\n {\n \"name\": \"KingdominoOrigins-Tribe\",\n \"description\": \"Kingdomino Origins - Tribe mode with resources, cave board, cavemen recruitment and fire mechanics\"\n },\n {\n \"name\": \"AgeOfGiants\",\n \"description\": \"Age of Giants extension with giants, quest tiles, 5-player support and 12 new dominos on top of Classic Kingdomino\"\n },\n {\n \"name\": \"AgeOfGiants-QueenDomino\",\n \"description\": \"Age of Giants extension combined with Queendomino, adding giants and quest tiles to the Queendomino experience\"\n }\n]\n","import type { GameMode } from \"@core/domain/types/mode.js\";\nimport type { ModeRepository } from \"@core/portServerside/modeRepository.js\";\nimport modesJson from \"../datasources/modes.json\" with { type: \"json\" };\n\nconst jsonModes = (): ModeRepository => {\n const modes: GameMode[] = [];\n\n modesJson.forEach((mode) => {\n modes.push({\n name: mode.name,\n description: mode.description,\n });\n });\n\n return {\n getAvailables: () => {\n return modes;\n },\n };\n};\n\nexport default jsonModes;\n","[\n {\n \"id\": 1,\n \"type\": \"localTrade\",\n \"name\": \"Local Trade - Wheat\",\n \"description\": \"Each wheat tile adjacent (orthogonal + diagonal) to your castle scores 5 bonus points.\",\n \"points\": 5,\n \"terrain\": \"wheat\"\n },\n {\n \"id\": 2,\n \"type\": \"localTrade\",\n \"name\": \"Local Trade - Forest\",\n \"description\": \"Each forest tile adjacent (orthogonal + diagonal) to your castle scores 5 bonus points.\",\n \"points\": 5,\n \"terrain\": \"forest\"\n },\n {\n \"id\": 3,\n \"type\": \"localTrade\",\n \"name\": \"Local Trade - Sea\",\n \"description\": \"Each sea tile adjacent (orthogonal + diagonal) to your castle scores 5 bonus points.\",\n \"points\": 5,\n \"terrain\": \"sea\"\n },\n {\n \"id\": 4,\n \"type\": \"localTrade\",\n \"name\": \"Local Trade - Plain\",\n \"description\": \"Each plain tile adjacent (orthogonal + diagonal) to your castle scores 5 bonus points.\",\n \"points\": 5,\n \"terrain\": \"plain\"\n },\n {\n \"id\": 5,\n \"type\": \"kingdomBorders\",\n \"name\": \"Kingdom Borders - Wheat\",\n \"description\": \"Each wheat tile in the 4 corners of your kingdom scores 5 bonus points.\",\n \"points\": 5,\n \"terrain\": \"wheat\"\n },\n {\n \"id\": 6,\n \"type\": \"kingdomBorders\",\n \"name\": \"Kingdom Borders - Forest\",\n \"description\": \"Each forest tile in the 4 corners of your kingdom scores 5 bonus points.\",\n \"points\": 5,\n \"terrain\": \"forest\"\n },\n {\n \"id\": 7,\n \"type\": \"kingdomBorders\",\n \"name\": \"Kingdom Borders - Sea\",\n \"description\": \"Each sea tile in the 4 corners of your kingdom scores 5 bonus points.\",\n \"points\": 5,\n \"terrain\": \"sea\"\n },\n {\n \"id\": 8,\n \"type\": \"kingdomBorders\",\n \"name\": \"Kingdom Borders - Plain\",\n \"description\": \"Each plain tile in the 4 corners of your kingdom scores 5 bonus points.\",\n \"points\": 5,\n \"terrain\": \"plain\"\n },\n {\n \"id\": 9,\n \"type\": \"harmony\",\n \"name\": \"Harmony\",\n \"description\": \"Score 5 bonus points if your kingdom is complete (no discarded dominos).\",\n \"points\": 5\n },\n {\n \"id\": 10,\n \"type\": \"middleKingdom\",\n \"name\": \"Middle Kingdom\",\n \"description\": \"Score 10 bonus points if your castle is in the center of your kingdom.\",\n \"points\": 10\n },\n {\n \"id\": 11,\n \"type\": \"lostCorner\",\n \"name\": \"Lost Corner\",\n \"description\": \"Score 20 bonus points if your castle is in one of the 4 corners of your kingdom.\",\n \"points\": 20\n },\n {\n \"id\": 12,\n \"type\": \"megalomania\",\n \"name\": \"Megalomania\",\n \"description\": \"Score 10 bonus points for each alignment of 3 or more tiles with crowns (horizontal, vertical, or diagonal).\",\n \"points\": 10\n },\n {\n \"id\": 13,\n \"type\": \"megalomania\",\n \"name\": \"Megalomania\",\n \"description\": \"Score 10 bonus points for each alignment of 3 or more tiles with crowns (horizontal, vertical, or diagonal).\",\n \"points\": 10\n },\n {\n \"id\": 14,\n \"type\": \"austereKing\",\n \"name\": \"Austere King\",\n \"description\": \"Score 10 bonus points for each property of 5+ wheat, forest, sea, or plain tiles with zero crowns.\",\n \"points\": 10\n },\n {\n \"id\": 15,\n \"type\": \"austereKing\",\n \"name\": \"Austere King\",\n \"description\": \"Score 10 bonus points for each property of 5+ wheat, forest, sea, or plain tiles with zero crowns.\",\n \"points\": 10\n },\n {\n \"id\": 16,\n \"type\": \"lostCorner\",\n \"name\": \"Lost Corner\",\n \"description\": \"Score 20 bonus points if your castle is in one of the 4 corners of your kingdom.\",\n \"points\": 20\n },\n {\n \"id\": 17,\n \"type\": \"harmony\",\n \"name\": \"Harmony\",\n \"description\": \"Score 5 bonus points if your kingdom is complete (no discarded dominos).\",\n \"points\": 5\n }\n]\n","import type { QuestTile, QuestType } from \"@core/domain/types/ageOfGiants.js\";\nimport type { Ground } from \"@core/domain/types/domino.js\";\nimport type { QuestTilesRepository } from \"@core/portServerside/questTilesRepository.js\";\nimport questTilesJson from \"../datasources/questTiles.json\" with {\n type: \"json\",\n};\n\nconst mapQuestTile = (raw: {\n id: number;\n type: string;\n name: string;\n description: string;\n points: number;\n terrain?: string;\n}): QuestTile => {\n const tile: QuestTile = {\n id: raw.id,\n type: raw.type as QuestType,\n name: raw.name,\n description: raw.description,\n points: raw.points,\n };\n if (raw.terrain) {\n tile.terrain = raw.terrain as Ground;\n }\n return tile;\n};\n\nconst jsonQuestTiles = (): QuestTilesRepository => {\n const questTiles: QuestTile[] = questTilesJson.map(mapQuestTile);\n\n return {\n getAll: () => [...questTiles],\n };\n};\n\nexport default jsonQuestTiles;\n","{\n \"commun\": [\n {\n \"playersLimit\": 1,\n \"lordsPerPlayer\": 1,\n \"maxDominoes\": 48,\n \"dominoesPerTurn\": 4,\n \"maxTurns\": 12,\n \"maxKingdomSize\": 5\n },\n {\n \"playersLimit\": 2,\n \"lordsPerPlayer\": 2,\n \"maxDominoes\": 24,\n \"dominoesPerTurn\": 4,\n \"maxTurns\": 6,\n \"maxKingdomSize\": 5\n },\n {\n \"playersLimit\": 3,\n \"lordsPerPlayer\": 1,\n \"maxDominoes\": 48,\n \"dominoesPerTurn\": 4,\n \"maxTurns\": 12,\n \"maxKingdomSize\": 5\n },\n {\n \"playersLimit\": 4,\n \"lordsPerPlayer\": 1,\n \"maxDominoes\": 48,\n \"dominoesPerTurn\": 4,\n \"maxTurns\": 12,\n \"maxKingdomSize\": 5\n }\n ],\n \"aog\": [\n {\n \"playersLimit\": 2,\n \"lordsPerPlayer\": 2,\n \"maxDominoes\": 30,\n \"dominoesPerTurn\": 5,\n \"maxTurns\": 6,\n \"maxKingdomSize\": 5,\n \"dominoesDiscardedPerTurn\": 1\n },\n {\n \"playersLimit\": 3,\n \"lordsPerPlayer\": 1,\n \"maxDominoes\": 60,\n \"dominoesPerTurn\": 5,\n \"maxTurns\": 12,\n \"maxKingdomSize\": 5,\n \"dominoesDiscardedPerTurn\": 2\n },\n {\n \"playersLimit\": 4,\n \"lordsPerPlayer\": 1,\n \"maxDominoes\": 60,\n \"dominoesPerTurn\": 5,\n \"maxTurns\": 12,\n \"maxKingdomSize\": 5,\n \"dominoesDiscardedPerTurn\": 1\n },\n {\n \"playersLimit\": 5,\n \"lordsPerPlayer\": 1,\n \"maxDominoes\": 60,\n \"dominoesPerTurn\": 5,\n \"maxTurns\": 12,\n \"maxKingdomSize\": 5,\n \"dominoesDiscardedPerTurn\": 0\n }\n ],\n \"extra\": [\n {\n \"name\": \"The middle Kingdom\",\n \"description\": \"Gain 10 additional points if your castle is in the middle of the kingdom.\",\n \"mode\": [\n { \"name\": \"Classic\", \"description\": \"King Domino classic mode\" },\n { \"name\": \"QueenDomino\", \"description\": \"Queendomino expansion with buildings, knights, coins, the Queen and the Dragon\" }\n ]\n },\n {\n \"name\": \"Harmony\",\n \"description\": \"Gain 5 additional points if your kingdom is complete (no discarded dominoes).\",\n \"mode\": [\n { \"name\": \"Classic\", \"description\": \"King Domino classic mode\" },\n { \"name\": \"QueenDomino\", \"description\": \"Queendomino expansion with buildings, knights, coins, the Queen and the Dragon\" }\n ]\n },\n {\n \"name\": \"The Mighty Duel\",\n \"description\": \"Use all 48 dominoes and build a 7x7 kingdom. For 2 players only.\",\n \"mode\": [\n { \"name\": \"Classic\", \"description\": \"King Domino classic mode\" },\n { \"name\": \"QueenDomino\", \"description\": \"Queendomino expansion with buildings, knights, coins, the Queen and the Dragon\" }\n ],\n \"playersLimit\": 2\n },\n {\n \"name\": \"Dynasty\",\n \"description\": \"Play 3 games in a row. The player with the highest total points wins.\",\n \"mode\": [\n { \"name\": \"Classic\", \"description\": \"King Domino classic mode\" },\n { \"name\": \"QueenDomino\", \"description\": \"Queendomino expansion with buildings, knights, coins, the Queen and the Dragon\" }\n ]\n },\n {\n \"name\": \"Empire of Fire\",\n \"description\": \"Gain 10 additional points if your hut is in the center of your territory.\",\n \"mode\": [\n { \"name\": \"KingdominoOrigins-Discovery\", \"description\": \"Kingdomino Origins - Discovery mode\" },\n { \"name\": \"KingdominoOrigins-Totem\", \"description\": \"Kingdomino Origins - Totem mode\" },\n { \"name\": \"KingdominoOrigins-Tribe\", \"description\": \"Kingdomino Origins - Tribe mode\" }\n ]\n },\n {\n \"name\": \"Homo Habilis\",\n \"description\": \"Gain 5 additional points if your 5x5 territory is complete (no discarded dominoes).\",\n \"mode\": [\n { \"name\": \"KingdominoOrigins-Discovery\", \"description\": \"Kingdomino Origins - Discovery mode\" },\n { \"name\": \"KingdominoOrigins-Totem\", \"description\": \"Kingdomino Origins - Totem mode\" },\n { \"name\": \"KingdominoOrigins-Tribe\", \"description\": \"Kingdomino Origins - Tribe mode\" }\n ]\n },\n {\n \"name\": \"Neolithic\",\n \"description\": \"Use all 48 dominoes and build a 7x7 territory. For 2 players only.\",\n \"mode\": [\n { \"name\": \"KingdominoOrigins-Discovery\", \"description\": \"Kingdomino Origins - Discovery mode\" },\n { \"name\": \"KingdominoOrigins-Totem\", \"description\": \"Kingdomino Origins - Totem mode\" },\n { \"name\": \"KingdominoOrigins-Tribe\", \"description\": \"Kingdomino Origins - Tribe mode\" }\n ],\n \"playersLimit\": 2\n },\n {\n \"name\": \"Dynasty\",\n \"description\": \"Play 3 games in a row. The player with the highest total points wins.\",\n \"mode\": [\n { \"name\": \"KingdominoOrigins-Discovery\", \"description\": \"Kingdomino Origins - Discovery mode\" },\n { \"name\": \"KingdominoOrigins-Totem\", \"description\": \"Kingdomino Origins - Totem mode\" },\n { \"name\": \"KingdominoOrigins-Tribe\", \"description\": \"Kingdomino Origins - Tribe mode\" }\n ]\n },\n {\n \"name\": \"Dynasty\",\n \"description\": \"Play 3 games in a row. The player with the highest total points wins.\",\n \"mode\": [\n { \"name\": \"AgeOfGiants\", \"description\": \"Age of Giants extension on Classic Kingdomino\" },\n { \"name\": \"AgeOfGiants-QueenDomino\", \"description\": \"Age of Giants extension on Queendomino\" }\n ]\n }\n ]\n}\n","import type { Rules } from \"@core/domain/types/rule.js\";\nimport type { RuleRepository } from \"@core/portServerside/ruleRepository.js\";\nimport rulesJson from \"../datasources/rules.json\" with { type: \"json\" };\n\nconst jsonRules = (): RuleRepository => {\n const rules: Rules = {\n basic: {},\n extraRules: [],\n };\n\n const commonRules = rulesJson.commun;\n const aogRules = rulesJson.aog;\n const extraRules = rulesJson.extra;\n\n commonRules.forEach((rule) => {\n rules.basic[rule.playersLimit] = {\n lords: rule.lordsPerPlayer,\n maxDominoes: rule.maxDominoes,\n dominoesPerTurn: rule.dominoesPerTurn,\n maxTurns: rule.maxTurns,\n maxKingdomSize: rule.maxKingdomSize,\n };\n });\n\n if (aogRules) {\n rules.aogBasic = {};\n aogRules.forEach((rule) => {\n rules.aogBasic![rule.playersLimit] = {\n lords: rule.lordsPerPlayer,\n maxDominoes: rule.maxDominoes,\n dominoesPerTurn: rule.dominoesPerTurn,\n maxTurns: rule.maxTurns,\n maxKingdomSize: rule.maxKingdomSize,\n dominoesDiscardedPerTurn: rule.dominoesDiscardedPerTurn,\n };\n });\n }\n\n extraRules.forEach((rule) => {\n rules.extraRules.push({\n name: rule.name,\n description: rule.description,\n mode: rule.mode,\n ...(\"playersLimit\" in rule && { playersLimit: rule.playersLimit }),\n });\n });\n\n return {\n getAll: () => {\n return rules;\n },\n getAllExtra: () => {\n return rules.extraRules;\n },\n };\n};\n\nexport default jsonRules;\n","import type { ShuffleMethod } from \"@core/portServerside/shuffleMethod.js\";\n\nexport const shuffleMethod: ShuffleMethod = <T>(array: T[]) => {\n for (let i = array.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [array[i], array[j]] = [array[j] as T, array[i] as T];\n }\n return array;\n};\n","import type { UuidMethod } from \"@core/portServerside/uuidMethod.js\";\n\nexport const uuidMethod: UuidMethod = () => {\n return globalThis.crypto.randomUUID();\n};\n","/**\n * Error codes for domain-level errors.\n * These codes can be used for i18n and programmatic error handling.\n */\nexport const ErrorCode = {\n // Game flow errors\n INVALID_STEP: \"INVALID_STEP\",\n STEP_EXECUTION_FAILED: \"STEP_EXECUTION_FAILED\",\n ACTION_EXECUTION_FAILED: \"ACTION_EXECUTION_FAILED\",\n\n // Entity not found errors\n LORD_NOT_FOUND: \"LORD_NOT_FOUND\",\n PLAYER_NOT_FOUND: \"PLAYER_NOT_FOUND\",\n DOMINO_NOT_FOUND: \"DOMINO_NOT_FOUND\",\n MODE_NOT_FOUND: \"MODE_NOT_FOUND\",\n\n // Validation errors\n INVALID_PLAYER_COUNT: \"INVALID_PLAYER_COUNT\",\n INVALID_PLAYER_NAME: \"INVALID_PLAYER_NAME\",\n INVALID_PLACEMENT: \"INVALID_PLACEMENT\",\n PLACEMENT_NOT_EMPTY: \"PLACEMENT_NOT_EMPTY\",\n PLACEMENT_NOT_ADJACENT: \"PLACEMENT_NOT_ADJACENT\",\n PLACEMENT_INVALID_TERRAIN: \"PLACEMENT_INVALID_TERRAIN\",\n PLACEMENT_OUT_OF_BOUNDS: \"PLACEMENT_OUT_OF_BOUNDS\",\n PLACEMENT_EXCEEDS_KINGDOM_SIZE: \"PLACEMENT_EXCEEDS_KINGDOM_SIZE\",\n\n // Action errors\n NOT_YOUR_TURN: \"NOT_YOUR_TURN\",\n CANNOT_PICK: \"CANNOT_PICK\",\n CANNOT_PLACE: \"CANNOT_PLACE\",\n DOMINO_ALREADY_PICKED: \"DOMINO_ALREADY_PICKED\",\n\n // History errors\n UNDO_UNAVAILABLE: \"UNDO_UNAVAILABLE\",\n REDO_UNAVAILABLE: \"REDO_UNAVAILABLE\",\n\n // Queendomino errors\n CANNOT_PLACE_KNIGHT: \"CANNOT_PLACE_KNIGHT\",\n MAX_KNIGHTS_REACHED: \"MAX_KNIGHTS_REACHED\",\n KNIGHT_TERRITORY_OCCUPIED: \"KNIGHT_TERRITORY_OCCUPIED\",\n CANNOT_AFFORD_BUILDING: \"CANNOT_AFFORD_BUILDING\",\n NO_CONSTRUCTION_SQUARE: \"NO_CONSTRUCTION_SQUARE\",\n DRAGON_UNAVAILABLE: \"DRAGON_UNAVAILABLE\",\n QUEEN_HOLDER_CANNOT_USE_DRAGON: \"QUEEN_HOLDER_CANNOT_USE_DRAGON\",\n BUILDING_NOT_FOUND: \"BUILDING_NOT_FOUND\",\n INVALID_OPTIONAL_ACTION: \"INVALID_OPTIONAL_ACTION\",\n\n // Age of Giants errors\n GIANT_POOL_EMPTY: \"GIANT_POOL_EMPTY\",\n GIANT_NOT_FOUND: \"GIANT_NOT_FOUND\",\n INVALID_GIANT_PLACEMENT: \"INVALID_GIANT_PLACEMENT\",\n NOT_AOG_MODE: \"NOT_AOG_MODE\",\n\n // Origins errors\n FIRE_TOKEN_POOL_EMPTY: \"FIRE_TOKEN_POOL_EMPTY\",\n FIRE_TOKEN_INVALID_POSITION: \"FIRE_TOKEN_INVALID_POSITION\",\n NO_PENDING_FIRE_TOKEN: \"NO_PENDING_FIRE_TOKEN\",\n CANNOT_RECRUIT_CAVEMAN: \"CANNOT_RECRUIT_CAVEMAN\",\n INSUFFICIENT_RESOURCES: \"INSUFFICIENT_RESOURCES\",\n INVALID_CAVEMAN_PLACEMENT: \"INVALID_CAVEMAN_PLACEMENT\",\n CAVEMAN_NOT_FOUND: \"CAVEMAN_NOT_FOUND\",\n NOT_TRIBE_MODE: \"NOT_TRIBE_MODE\",\n} as const;\n\nexport type ErrorCodeType = (typeof ErrorCode)[keyof typeof ErrorCode];\n\n/**\n * Structured domain error with code and context.\n */\nexport interface DomainError {\n /** Error code for programmatic handling */\n code: ErrorCodeType;\n /** Human-readable error message */\n message: string;\n /** Optional context data for debugging */\n context?: Record<string, unknown>;\n}\n\n/**\n * Creates a domain error object.\n */\nexport const createDomainError = (\n code: ErrorCodeType,\n message: string,\n context?: Record<string, unknown>,\n): DomainError => ({\n code,\n message,\n context,\n});\n\n/**\n * Base class for domain errors thrown by handlers.\n */\nexport class DomainException extends Error {\n public readonly code: ErrorCodeType;\n public readonly context?: Record<string, unknown>;\n\n constructor(error: DomainError) {\n super(error.message);\n this.name = \"DomainException\";\n this.code = error.code;\n this.context = error.context;\n }\n}\n\n/**\n * Error thrown when the game is in an invalid step for the requested action.\n */\nexport class InvalidStepError extends DomainException {\n constructor(message: string, context?: Record<string, unknown>) {\n super({\n code: ErrorCode.INVALID_STEP,\n message,\n context,\n });\n this.name = \"InvalidStepError\";\n }\n}\n\n/**\n * Error thrown when a step execution fails.\n */\nexport class StepExecutionError extends DomainException {\n constructor(\n message: string,\n code: ErrorCodeType = ErrorCode.STEP_EXECUTION_FAILED,\n context?: Record<string, unknown>,\n ) {\n super({\n code,\n message,\n context,\n });\n this.name = \"StepExecutionError\";\n }\n}\n\n/**\n * Error thrown when an action execution fails.\n */\nexport class ActionExecutionError extends DomainException {\n constructor(\n message: string,\n code: ErrorCodeType = ErrorCode.ACTION_EXECUTION_FAILED,\n context?: Record<string, unknown>,\n ) {\n super({\n code,\n message,\n context,\n });\n this.name = \"ActionExecutionError\";\n }\n}\n\n/**\n * Error thrown when a required entity is not found.\n */\nexport class NotFoundError extends DomainException {\n constructor(\n message: string,\n code: ErrorCodeType = ErrorCode.LORD_NOT_FOUND,\n context?: Record<string, unknown>,\n ) {\n super({\n code,\n message,\n context,\n });\n this.name = \"NotFoundError\";\n }\n}\n\n/**\n * Error thrown when validation fails.\n */\nexport class ValidationError extends DomainException {\n constructor(\n message: string,\n code: ErrorCodeType,\n context?: Record<string, unknown>,\n ) {\n super({\n code,\n message,\n context,\n });\n this.name = \"ValidationError\";\n }\n}\n\n/**\n * Error thrown when undo is requested but no previous state exists.\n */\nexport class UndoError extends DomainException {\n constructor(message = \"No state to undo\", context?: Record<string, unknown>) {\n super({\n code: ErrorCode.UNDO_UNAVAILABLE,\n message,\n context,\n });\n this.name = \"UndoError\";\n }\n}\n\n/**\n * Error thrown when redo is requested but no future state exists.\n */\nexport class RedoError extends DomainException {\n constructor(message = \"No state to redo\", context?: Record<string, unknown>) {\n super({\n code: ErrorCode.REDO_UNAVAILABLE,\n message,\n context,\n });\n this.name = \"RedoError\";\n }\n}\n","import {\n ErrorCode,\n type ErrorCodeType,\n} from \"@core/domain/errors/domainErrors.js\";\n\n/**\n * Translation keys for internationalization support.\n * Use these keys instead of hardcoded strings for translatable content.\n */\nexport const TranslationKey = {\n // Error messages\n ERROR_INVALID_STEP: \"error.invalidStep\",\n ERROR_STEP_EXECUTION_FAILED: \"error.stepExecutionFailed\",\n ERROR_ACTION_EXECUTION_FAILED: \"error.actionExecutionFailed\",\n ERROR_LORD_NOT_FOUND: \"error.lordNotFound\",\n ERROR_PLAYER_NOT_FOUND: \"error.playerNotFound\",\n ERROR_DOMINO_NOT_FOUND: \"error.dominoNotFound\",\n ERROR_MODE_NOT_FOUND: \"error.modeNotFound\",\n ERROR_INVALID_PLACEMENT: \"error.invalidPlacement\",\n ERROR_PLACEMENT_NOT_EMPTY: \"error.placementNotEmpty\",\n ERROR_PLACEMENT_NOT_ADJACENT: \"error.placementNotAdjacent\",\n ERROR_PLACEMENT_INVALID_TERRAIN: \"error.placementInvalidTerrain\",\n ERROR_PLACEMENT_OUT_OF_BOUNDS: \"error.placementOutOfBounds\",\n ERROR_PLACEMENT_EXCEEDS_KINGDOM_SIZE: \"error.placementExceedsKingdomSize\",\n ERROR_NOT_YOUR_TURN: \"error.notYourTurn\",\n ERROR_CANNOT_PICK: \"error.cannotPick\",\n ERROR_CANNOT_PLACE: \"error.cannotPlace\",\n ERROR_DOMINO_ALREADY_PICKED: \"error.dominoAlreadyPicked\",\n ERROR_INVALID_PLAYER_COUNT: \"error.invalidPlayerCount\",\n ERROR_INVALID_PLAYER_NAME: \"error.invalidPlayerName\",\n ERROR_UNDO_UNAVAILABLE: \"error.undoUnavailable\",\n ERROR_REDO_UNAVAILABLE: \"error.redoUnavailable\",\n\n // Game mode names\n MODE_CLASSIC: \"mode.classic\",\n\n // Extra rule names\n RULE_MIDDLE_KINGDOM: \"rule.middleKingdom\",\n RULE_HARMONY: \"rule.harmony\",\n\n // Ground types\n GROUND_CASTLE: \"ground.castle\",\n GROUND_WHEAT: \"ground.wheat\",\n GROUND_FOREST: \"ground.forest\",\n GROUND_SEA: \"ground.sea\",\n GROUND_PLAIN: \"ground.plain\",\n GROUND_SWAMP: \"ground.swamp\",\n GROUND_MINE: \"ground.mine\",\n\n // Game phases\n PHASE_ADD_PLAYERS: \"phase.addPlayers\",\n PHASE_OPTIONS: \"phase.options\",\n PHASE_START: \"phase.start\",\n PHASE_RESULT: \"phase.result\",\n\n // Actions\n ACTION_PICK_DOMINO: \"action.pickDomino\",\n ACTION_PLACE_DOMINO: \"action.placeDomino\",\n ACTION_PASS: \"action.pass\",\n\n // Queendomino errors\n ERROR_CANNOT_PLACE_KNIGHT: \"error.cannotPlaceKnight\",\n ERROR_MAX_KNIGHTS_REACHED: \"error.maxKnightsReached\",\n ERROR_KNIGHT_TERRITORY_OCCUPIED: \"error.knightTerritoryOccupied\",\n ERROR_CANNOT_AFFORD_BUILDING: \"error.cannotAffordBuilding\",\n ERROR_NO_CONSTRUCTION_SQUARE: \"error.noConstructionSquare\",\n ERROR_DRAGON_UNAVAILABLE: \"error.dragonUnavailable\",\n ERROR_QUEEN_HOLDER_CANNOT_USE_DRAGON: \"error.queenHolderCannotUseDragon\",\n ERROR_BUILDING_NOT_FOUND: \"error.buildingNotFound\",\n ERROR_INVALID_OPTIONAL_ACTION: \"error.invalidOptionalAction\",\n\n // Age of Giants errors\n ERROR_GIANT_POOL_EMPTY: \"error.giantPoolEmpty\",\n ERROR_GIANT_NOT_FOUND: \"error.giantNotFound\",\n ERROR_INVALID_GIANT_PLACEMENT: \"error.invalidGiantPlacement\",\n ERROR_NOT_AOG_MODE: \"error.notAogMode\",\n\n // Origins errors\n ERROR_FIRE_TOKEN_POOL_EMPTY: \"error.fireTokenPoolEmpty\",\n ERROR_FIRE_TOKEN_INVALID_POSITION: \"error.fireTokenInvalidPosition\",\n ERROR_NO_PENDING_FIRE_TOKEN: \"error.noPendingFireToken\",\n ERROR_CANNOT_RECRUIT_CAVEMAN: \"error.cannotRecruitCaveman\",\n ERROR_INSUFFICIENT_RESOURCES: \"error.insufficientResources\",\n ERROR_INVALID_CAVEMAN_PLACEMENT: \"error.invalidCavemanPlacement\",\n ERROR_CAVEMAN_NOT_FOUND: \"error.cavemanNotFound\",\n ERROR_NOT_TRIBE_MODE: \"error.notTribeMode\",\n} as const;\n\nexport type TranslationKeyType =\n (typeof TranslationKey)[keyof typeof TranslationKey];\n\n/**\n * Default English translations.\n */\nexport const defaultTranslations: Record<TranslationKeyType, string> = {\n // Error messages\n [TranslationKey.ERROR_INVALID_STEP]: \"Invalid game step\",\n [TranslationKey.ERROR_STEP_EXECUTION_FAILED]: \"Step execution failed\",\n [TranslationKey.ERROR_ACTION_EXECUTION_FAILED]: \"Action execution failed\",\n [TranslationKey.ERROR_LORD_NOT_FOUND]: \"Lord not found\",\n [TranslationKey.ERROR_PLAYER_NOT_FOUND]: \"Player not found\",\n [TranslationKey.ERROR_DOMINO_NOT_FOUND]: \"Domino not found\",\n [TranslationKey.ERROR_MODE_NOT_FOUND]: \"Game mode not found\",\n [TranslationKey.ERROR_INVALID_PLACEMENT]: \"Invalid placement\",\n [TranslationKey.ERROR_PLACEMENT_NOT_EMPTY]: \"Position is not empty\",\n [TranslationKey.ERROR_PLACEMENT_NOT_ADJACENT]:\n \"Not adjacent to existing tiles\",\n [TranslationKey.ERROR_PLACEMENT_INVALID_TERRAIN]:\n \"Terrain type does not match\",\n [TranslationKey.ERROR_PLACEMENT_OUT_OF_BOUNDS]: \"Placement is out of bounds\",\n [TranslationKey.ERROR_PLACEMENT_EXCEEDS_KINGDOM_SIZE]:\n \"Placement exceeds kingdom size\",\n [TranslationKey.ERROR_NOT_YOUR_TURN]: \"It is not your turn\",\n [TranslationKey.ERROR_CANNOT_PICK]: \"Cannot pick a domino now\",\n [TranslationKey.ERROR_CANNOT_PLACE]: \"Cannot place a domino now\",\n [TranslationKey.ERROR_DOMINO_ALREADY_PICKED]:\n \"Domino has already been picked\",\n [TranslationKey.ERROR_INVALID_PLAYER_COUNT]:\n \"Invalid number of players (1-4 required)\",\n [TranslationKey.ERROR_INVALID_PLAYER_NAME]:\n \"Player name must be at least 3 characters\",\n [TranslationKey.ERROR_UNDO_UNAVAILABLE]: \"No state to undo\",\n [TranslationKey.ERROR_REDO_UNAVAILABLE]: \"No state to redo\",\n\n // Game mode names\n [TranslationKey.MODE_CLASSIC]: \"Classic\",\n\n // Extra rule names\n [TranslationKey.RULE_MIDDLE_KINGDOM]: \"The Middle Kingdom\",\n [TranslationKey.RULE_HARMONY]: \"Harmony\",\n\n // Ground types\n [TranslationKey.GROUND_CASTLE]: \"Castle\",\n [TranslationKey.GROUND_WHEAT]: \"Wheat Field\",\n [TranslationKey.GROUND_FOREST]: \"Forest\",\n [TranslationKey.GROUND_SEA]: \"Sea\",\n [TranslationKey.GROUND_PLAIN]: \"Plain\",\n [TranslationKey.GROUND_SWAMP]: \"Swamp\",\n [TranslationKey.GROUND_MINE]: \"Mine\",\n\n // Game phases\n [TranslationKey.PHASE_ADD_PLAYERS]: \"Add Players\",\n [TranslationKey.PHASE_OPTIONS]: \"Game Options\",\n [TranslationKey.PHASE_START]: \"Start Game\",\n [TranslationKey.PHASE_RESULT]: \"Game Results\",\n\n // Actions\n [TranslationKey.ACTION_PICK_DOMINO]: \"Pick Domino\",\n [TranslationKey.ACTION_PLACE_DOMINO]: \"Place Domino\",\n [TranslationKey.ACTION_PASS]: \"Pass\",\n\n // Queendomino errors\n [TranslationKey.ERROR_CANNOT_PLACE_KNIGHT]: \"Cannot place knight here\",\n [TranslationKey.ERROR_MAX_KNIGHTS_REACHED]:\n \"Maximum number of knights reached (3)\",\n [TranslationKey.ERROR_KNIGHT_TERRITORY_OCCUPIED]:\n \"This territory already has a knight\",\n [TranslationKey.ERROR_CANNOT_AFFORD_BUILDING]:\n \"Not enough coins to purchase this building\",\n [TranslationKey.ERROR_NO_CONSTRUCTION_SQUARE]:\n \"No open construction square available\",\n [TranslationKey.ERROR_DRAGON_UNAVAILABLE]:\n \"The Dragon is not available this round\",\n [TranslationKey.ERROR_QUEEN_HOLDER_CANNOT_USE_DRAGON]:\n \"The Queen holder cannot use the Dragon\",\n [TranslationKey.ERROR_BUILDING_NOT_FOUND]:\n \"Building not found on the Builders Board\",\n [TranslationKey.ERROR_INVALID_OPTIONAL_ACTION]:\n \"Invalid optional action for this game state\",\n\n // Age of Giants errors\n [TranslationKey.ERROR_GIANT_POOL_EMPTY]: \"No giants remaining in the pool\",\n [TranslationKey.ERROR_GIANT_NOT_FOUND]: \"Giant not found on the kingdom\",\n [TranslationKey.ERROR_INVALID_GIANT_PLACEMENT]:\n \"Invalid position for giant placement — must be an uncovered crown\",\n [TranslationKey.ERROR_NOT_AOG_MODE]: \"Age of Giants mode is not enabled\",\n\n // Origins errors\n [TranslationKey.ERROR_FIRE_TOKEN_POOL_EMPTY]:\n \"No fire tokens remaining in the pool\",\n [TranslationKey.ERROR_FIRE_TOKEN_INVALID_POSITION]:\n \"Invalid position for fire token placement\",\n [TranslationKey.ERROR_NO_PENDING_FIRE_TOKEN]:\n \"No pending fire token to place\",\n [TranslationKey.ERROR_CANNOT_RECRUIT_CAVEMAN]: \"Cannot recruit a caveman\",\n [TranslationKey.ERROR_INSUFFICIENT_RESOURCES]:\n \"Insufficient resources for this action\",\n [TranslationKey.ERROR_INVALID_CAVEMAN_PLACEMENT]:\n \"Invalid position for caveman placement\",\n [TranslationKey.ERROR_CAVEMAN_NOT_FOUND]: \"Caveman not found\",\n [TranslationKey.ERROR_NOT_TRIBE_MODE]: \"Tribe mode is not enabled\",\n};\n\n/**\n * Maps ErrorCode values to their corresponding TranslationKey values.\n * Used by handlers to translate error codes into localized messages.\n */\nexport const errorCodeToTranslationKey: Record<\n ErrorCodeType,\n TranslationKeyType\n> = {\n [ErrorCode.INVALID_STEP]: TranslationKey.ERROR_INVALID_STEP,\n [ErrorCode.STEP_EXECUTION_FAILED]: TranslationKey.ERROR_STEP_EXECUTION_FAILED,\n [ErrorCode.ACTION_EXECUTION_FAILED]:\n TranslationKey.ERROR_ACTION_EXECUTION_FAILED,\n [ErrorCode.LORD_NOT_FOUND]: TranslationKey.ERROR_LORD_NOT_FOUND,\n [ErrorCode.PLAYER_NOT_FOUND]: TranslationKey.ERROR_PLAYER_NOT_FOUND,\n [ErrorCode.DOMINO_NOT_FOUND]: TranslationKey.ERROR_DOMINO_NOT_FOUND,\n [ErrorCode.MODE_NOT_FOUND]: TranslationKey.ERROR_MODE_NOT_FOUND,\n [ErrorCode.INVALID_PLAYER_COUNT]: TranslationKey.ERROR_INVALID_PLAYER_COUNT,\n [ErrorCode.INVALID_PLAYER_NAME]: TranslationKey.ERROR_INVALID_PLAYER_NAME,\n [ErrorCode.INVALID_PLACEMENT]: TranslationKey.ERROR_INVALID_PLACEMENT,\n [ErrorCode.PLACEMENT_NOT_EMPTY]: TranslationKey.ERROR_PLACEMENT_NOT_EMPTY,\n [ErrorCode.PLACEMENT_NOT_ADJACENT]:\n TranslationKey.ERROR_PLACEMENT_NOT_ADJACENT,\n [ErrorCode.PLACEMENT_INVALID_TERRAIN]:\n TranslationKey.ERROR_PLACEMENT_INVALID_TERRAIN,\n [ErrorCode.PLACEMENT_OUT_OF_BOUNDS]:\n TranslationKey.ERROR_PLACEMENT_OUT_OF_BOUNDS,\n [ErrorCode.PLACEMENT_EXCEEDS_KINGDOM_SIZE]:\n TranslationKey.ERROR_PLACEMENT_EXCEEDS_KINGDOM_SIZE,\n [ErrorCode.NOT_YOUR_TURN]: TranslationKey.ERROR_NOT_YOUR_TURN,\n [ErrorCode.CANNOT_PICK]: TranslationKey.ERROR_CANNOT_PICK,\n [ErrorCode.CANNOT_PLACE]: TranslationKey.ERROR_CANNOT_PLACE,\n [ErrorCode.DOMINO_ALREADY_PICKED]: TranslationKey.ERROR_DOMINO_ALREADY_PICKED,\n [ErrorCode.UNDO_UNAVAILABLE]: TranslationKey.ERROR_UNDO_UNAVAILABLE,\n [ErrorCode.REDO_UNAVAILABLE]: TranslationKey.ERROR_REDO_UNAVAILABLE,\n [ErrorCode.CANNOT_PLACE_KNIGHT]: TranslationKey.ERROR_CANNOT_PLACE_KNIGHT,\n [ErrorCode.MAX_KNIGHTS_REACHED]: TranslationKey.ERROR_MAX_KNIGHTS_REACHED,\n [ErrorCode.KNIGHT_TERRITORY_OCCUPIED]:\n TranslationKey.ERROR_KNIGHT_TERRITORY_OCCUPIED,\n [ErrorCode.CANNOT_AFFORD_BUILDING]:\n TranslationKey.ERROR_CANNOT_AFFORD_BUILDING,\n [ErrorCode.NO_CONSTRUCTION_SQUARE]:\n TranslationKey.ERROR_NO_CONSTRUCTION_SQUARE,\n [ErrorCode.DRAGON_UNAVAILABLE]: TranslationKey.ERROR_DRAGON_UNAVAILABLE,\n [ErrorCode.QUEEN_HOLDER_CANNOT_USE_DRAGON]:\n TranslationKey.ERROR_QUEEN_HOLDER_CANNOT_USE_DRAGON,\n [ErrorCode.BUILDING_NOT_FOUND]: TranslationKey.ERROR_BUILDING_NOT_FOUND,\n [ErrorCode.INVALID_OPTIONAL_ACTION]:\n TranslationKey.ERROR_INVALID_OPTIONAL_ACTION,\n [ErrorCode.GIANT_POOL_EMPTY]: TranslationKey.ERROR_GIANT_POOL_EMPTY,\n [ErrorCode.GIANT_NOT_FOUND]: TranslationKey.ERROR_GIANT_NOT_FOUND,\n [ErrorCode.INVALID_GIANT_PLACEMENT]:\n TranslationKey.ERROR_INVALID_GIANT_PLACEMENT,\n [ErrorCode.NOT_AOG_MODE]: TranslationKey.ERROR_NOT_AOG_MODE,\n [ErrorCode.FIRE_TOKEN_POOL_EMPTY]: TranslationKey.ERROR_FIRE_TOKEN_POOL_EMPTY,\n [ErrorCode.FIRE_TOKEN_INVALID_POSITION]:\n TranslationKey.ERROR_FIRE_TOKEN_INVALID_POSITION,\n [ErrorCode.NO_PENDING_FIRE_TOKEN]: TranslationKey.ERROR_NO_PENDING_FIRE_TOKEN,\n [ErrorCode.CANNOT_RECRUIT_CAVEMAN]:\n TranslationKey.ERROR_CANNOT_RECRUIT_CAVEMAN,\n [ErrorCode.INSUFFICIENT_RESOURCES]:\n TranslationKey.ERROR_INSUFFICIENT_RESOURCES,\n [ErrorCode.INVALID_CAVEMAN_PLACEMENT]:\n TranslationKey.ERROR_INVALID_CAVEMAN_PLACEMENT,\n [ErrorCode.CAVEMAN_NOT_FOUND]: TranslationKey.ERROR_CAVEMAN_NOT_FOUND,\n [ErrorCode.NOT_TRIBE_MODE]: TranslationKey.ERROR_NOT_TRIBE_MODE,\n};\n\n/**\n * Translates an error code to a localized message.\n * Convenience function combining errorCodeToTranslationKey lookup and translation.\n */\nexport const translateErrorCode = (\n translator: Translator,\n code: ErrorCodeType,\n params?: Record<string, string | number>,\n): string => {\n const key = errorCodeToTranslationKey[code];\n return translator.t(key, params);\n};\n\n/**\n * Translator interface for custom translations.\n */\nexport interface Translator {\n /**\n * Translate a key to the current language.\n * @param key - The translation key\n * @param params - Optional parameters for interpolation\n * @returns The translated string\n */\n t(key: TranslationKeyType, params?: Record<string, string | number>): string;\n}\n\n/**\n * Creates a translator with the provided translations.\n * Falls back to default English translations for missing keys.\n *\n * @param translations - Custom translations to use\n * @returns A translator instance\n */\nexport const createTranslator = (\n translations: Partial<Record<TranslationKeyType, string>> = {},\n): Translator => {\n const mergedTranslations = { ...defaultTranslations, ...translations };\n\n return {\n t(\n key: TranslationKeyType,\n params?: Record<string, string | number>,\n ): string {\n let text = mergedTranslations[key] || key;\n\n // Simple parameter interpolation: {{param}}\n if (params) {\n for (const [paramKey, value] of Object.entries(params)) {\n text = text.replace(\n new RegExp(`\\\\{\\\\{${paramKey}\\\\}\\\\}`, \"g\"),\n String(value),\n );\n }\n }\n\n return text;\n },\n };\n};\n\n/**\n * Default translator using English translations.\n */\nexport const defaultTranslator: Translator = createTranslator();\n","export type Result<T> = Ok<T> | Err;\n\nexport interface Ok<T> {\n readonly tag: \"Ok\";\n readonly value: T;\n}\n\nexport interface Err {\n readonly tag: \"Err\";\n readonly error: string;\n}\n\nexport const ok = <T>(value: T): Ok<T> => ({ tag: \"Ok\", value });\nexport const err = (error: string): Err => ({ tag: \"Err\", error });\n\nexport const isOk = <T>(result: Result<T>): result is Ok<T> =>\n result.tag === \"Ok\";\nexport const isErr = <T>(result: Result<T>): result is Err =>\n result.tag === \"Err\";\n\nexport const unwrap = <T>(result: Ok<T> | Err): T => {\n if (result.tag === \"Err\") {\n throw new Error(result.error);\n }\n return result.value;\n};\n","import type { AddExtraRulesCommand } from \"@application/commands/addExtraRulesCommand.js\";\nimport {\n ErrorCode,\n type ErrorCodeType,\n InvalidStepError,\n StepExecutionError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport {\n type GameWithNextStep,\n isGameWithNextStep,\n} from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { AddExtraRulesUseCase } from \"@core/useCases/addExtraRules.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype AddExtraRulesHandler = (command: AddExtraRulesCommand) => GameWithNextStep;\n\nexport const addExtraRulesHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: AddExtraRulesUseCase,\n ): AddExtraRulesHandler =>\n (command: AddExtraRulesCommand) => {\n const { game, extraRules } = command;\n logger.info(`Adding extra rules to game: ${game.id}`);\n logger.info(`Extra rules: ${extraRules}`);\n\n if (!isGameWithNextStep(game)) {\n logger.error(\n `Invalid game, required nextAction type: 'step' but got: ${game.nextAction.type}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n { expected: \"step\", actual: game.nextAction.type, gameId: game.id },\n );\n }\n\n if (game.nextAction.step !== \"options\") {\n logger.error(\n `Required game with options step but got: ${game.nextAction.step}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n { expected: \"options\", actual: game.nextAction.step, gameId: game.id },\n );\n }\n\n const result = useCase(game, extraRules);\n\n if (isErr(result)) {\n logger.error(`Error adding extra rules: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new StepExecutionError(translateErrorCode(translator, code), code, {\n gameId: game.id,\n extraRules: command.extraRules,\n });\n }\n\n logger.info(`Extra rules added to game: ${game.id}`);\n return result.value;\n };\n","import type { AddPlayersCommand } from \"@application/commands/addPlayersCommand.js\";\nimport {\n ErrorCode,\n type ErrorCodeType,\n InvalidStepError,\n StepExecutionError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport {\n type GameWithNextStep,\n isGameWithNextStep,\n} from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { AddPlayersUseCase } from \"@core/useCases/addPlayers.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype AddPlayersHandler = (command: AddPlayersCommand) => GameWithNextStep;\n\nexport const addPlayersHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: AddPlayersUseCase,\n ): AddPlayersHandler =>\n (command: AddPlayersCommand) => {\n const { game, players } = command;\n\n logger.info(`Adding players to game: ${game.id}`);\n\n if (!isGameWithNextStep(game)) {\n logger.error(\n `Invalid game, required nextAction type: 'step' but got: ${game.nextAction.type}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n { expected: \"step\", actual: game.nextAction.type, gameId: game.id },\n );\n }\n\n if (game.nextAction.step !== \"addPlayers\") {\n logger.error(\n `Required game with addPlayers step but got: ${game.nextAction.step}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n {\n expected: \"addPlayers\",\n actual: game.nextAction.step,\n gameId: game.id,\n },\n );\n }\n\n const result = useCase(game, players);\n\n if (isErr(result)) {\n logger.error(`Error adding players: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new StepExecutionError(translateErrorCode(translator, code), code, {\n gameId: game.id,\n players: command.players,\n });\n }\n\n logger.info(`Players added to game: ${game.id}`);\n return result.value;\n };\n","import type { CalculateScoreCommand } from \"@application/commands/calculateScoreCommand.js\";\nimport type { Score } from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { CalculateScoreUseCase } from \"@core/useCases/calculateScore.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype CalculateScoreHandler = (command: CalculateScoreCommand) => Score;\n\nexport const calculateScoreHandler =\n (\n logger: Logger,\n _translator: Translator,\n useCase: CalculateScoreUseCase,\n ): CalculateScoreHandler =>\n (command) => {\n const { kingdom } = command;\n logger.info(`Calculating score for kingdom`);\n const result = useCase(kingdom);\n\n if (isErr(result)) {\n logger.error(`Error calculating score: ${result.error}`);\n throw new Error(result.error);\n }\n\n logger.info(`Score calculated: ${result.value}`);\n return result.value;\n };\n","import type { CanPlaceDominoCommand } from \"@application/commands/canPlaceDominoCommand.js\";\nimport type { Domino, Kingdom } from \"@core/domain/types/index.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\n\ntype CanPlaceDominoUseCase = (\n kingdom: Kingdom,\n domino: Domino,\n maxKingdomSize?: number,\n) => boolean;\n\ntype CanPlaceDominoHandler = (command: CanPlaceDominoCommand) => boolean;\n\n/**\n * Creates a handler for checking if a domino can be placed.\n */\nexport const canPlaceDominoHandler = (\n logger: Logger,\n _translator: Translator,\n useCase: CanPlaceDominoUseCase,\n): CanPlaceDominoHandler => {\n return (command) => {\n logger.info(`Checking if domino ${command.domino.number} can be placed`);\n const canPlace = useCase(\n command.kingdom,\n command.domino,\n command.maxKingdomSize,\n );\n logger.info(`Can place domino: ${canPlace}`);\n return canPlace;\n };\n};\n","import type { ChooseDominoCommand } from \"@application/commands/chooseDominoCommand.js\";\nimport {\n ActionExecutionError,\n ErrorCode,\n type ErrorCodeType,\n InvalidStepError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport {\n type GameWithNextAction,\n isGameWithNextAction,\n} from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { ChooseDominoUseCase } from \"@core/useCases/chooseDomino.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype ChooseDominoHandler = (command: ChooseDominoCommand) => GameWithNextAction;\n\nexport const chooseDominoHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: ChooseDominoUseCase,\n ): ChooseDominoHandler =>\n (command: ChooseDominoCommand) => {\n const { game, lordId, dominoPick } = command;\n logger.info(\n `Choosing domino: ${dominoPick} for lord: ${lordId} in game: ${game.id}`,\n );\n\n if (!isGameWithNextAction(game)) {\n logger.error(\n `Invalid game, required nextAction type: 'action' but got: ${game.nextAction.type}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n { expected: \"action\", actual: game.nextAction.type, gameId: game.id },\n );\n }\n\n if (game.nextAction.nextAction !== \"pickDomino\") {\n logger.error(\n `Required game with pickDomino action but got: ${game.nextAction.nextAction}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n {\n expected: \"pickDomino\",\n actual: game.nextAction.nextAction,\n gameId: game.id,\n },\n );\n }\n\n const result = useCase(game, lordId, dominoPick);\n\n if (isErr(result)) {\n logger.error(`Error choosing domino: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new ActionExecutionError(\n translateErrorCode(translator, code),\n code,\n {\n gameId: game.id,\n lordId: command.lordId,\n dominoPick: command.dominoPick,\n },\n );\n }\n\n logger.info(\n `Domino chosen: ${dominoPick} for lord: ${lordId} in game: ${game.id}`,\n );\n return result.value;\n };\n","import type { ConstructBuildingCommand } from \"@application/commands/constructBuildingCommand.js\";\nimport {\n ActionExecutionError,\n ErrorCode,\n type ErrorCodeType,\n InvalidStepError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport type { GameState } from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { ConstructBuildingUseCase } from \"@core/useCases/constructBuilding.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype ConstructBuildingHandler = (\n command: ConstructBuildingCommand,\n) => GameState;\n\nexport const constructBuildingHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: ConstructBuildingUseCase,\n ): ConstructBuildingHandler =>\n (command: ConstructBuildingCommand) => {\n const { game, lordId, buildingId, position } = command;\n logger.info(\n `Constructing building: ${buildingId} for lord: ${lordId} at position: ${JSON.stringify(\n position,\n )} in game: ${game.id}`,\n );\n\n if (game.nextAction.nextAction !== \"constructBuilding\") {\n logger.error(\n `Required game with constructBuilding action but got: ${game.nextAction.nextAction}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n {\n expected: \"constructBuilding\",\n actual: game.nextAction.nextAction,\n gameId: game.id,\n },\n );\n }\n\n const result = useCase(game, lordId, buildingId, position);\n\n if (isErr(result)) {\n logger.error(`Error constructing building: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new ActionExecutionError(\n translateErrorCode(translator, code),\n code,\n {\n gameId: game.id,\n lordId: command.lordId,\n buildingId: command.buildingId,\n position: command.position,\n },\n );\n }\n\n logger.info(\n `Building constructed: ${buildingId} for lord: ${lordId} at position: ${JSON.stringify(\n position,\n )} in game: ${game.id}`,\n );\n return result.value;\n };\n","import type { CreateGameCommand } from \"@application/commands/createGameCommand.js\";\nimport {\n type ErrorCodeType,\n StepExecutionError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport type { GameWithNextStep } from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { CreateGameUseCase } from \"@core/useCases/createGame.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype CreateGameHandler = (command: CreateGameCommand) => GameWithNextStep;\n\nexport const createGameHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: CreateGameUseCase,\n ): CreateGameHandler =>\n (command: CreateGameCommand) => {\n logger.info(`Creating game with mode: ${command.mode}`);\n const result = useCase(command.mode, command.seed);\n\n if (isErr(result)) {\n logger.error(`Error creating game: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new StepExecutionError(translateErrorCode(translator, code), code, {\n mode: command.mode,\n });\n }\n\n logger.info(`Game created: ${result.value.id}`);\n return result.value;\n };\n","import type { DiscardDominoCommand } from \"@application/commands/discardDominoCommand.js\";\nimport {\n ActionExecutionError,\n ErrorCode,\n type ErrorCodeType,\n InvalidStepError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport {\n type GameState,\n isGameWithNextAction,\n} from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { DiscardDominoUseCase } from \"@core/useCases/discardDomino.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype DiscardDominoHandler = (command: DiscardDominoCommand) => GameState;\n\nexport const discardDominoHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: DiscardDominoUseCase,\n ): DiscardDominoHandler =>\n (command: DiscardDominoCommand) => {\n const { game, lordId } = command;\n logger.info(`Discarding domino for lord: ${lordId} in game: ${game.id}`);\n\n if (!isGameWithNextAction(game)) {\n logger.error(\n `Invalid game, required nextAction type: 'action' but got: ${game.nextAction.type}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n { expected: \"action\", actual: game.nextAction.type, gameId: game.id },\n );\n }\n\n if (game.nextAction.nextAction !== \"placeDomino\") {\n logger.error(\n `Required game with placeDomino action but got: ${game.nextAction.nextAction}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n {\n expected: \"placeDomino\",\n actual: game.nextAction.nextAction,\n gameId: game.id,\n },\n );\n }\n\n const result = useCase(game, lordId);\n\n if (isErr(result)) {\n logger.error(`Error discarding domino: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new ActionExecutionError(\n translateErrorCode(translator, code),\n code,\n { gameId: game.id, lordId: command.lordId },\n );\n }\n\n if (isGameWithNextAction(result.value)) {\n logger.info(`Domino discarded: ${lordId} in game: ${game.id}`);\n return result.value;\n }\n\n logger.info(`Domino discarded: ${lordId} in game: ${game.id}`);\n return result.value;\n };\n","import type { GetDynastyResultCommand } from \"@application/commands/getDynastyResultCommand.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type {\n DynastyResult,\n GetDynastyResultUseCase,\n} from \"@core/useCases/getDynastyResult.js\";\n\ntype GetDynastyResultHandler = (\n command: GetDynastyResultCommand,\n) => DynastyResult[];\n\nexport const getDynastyResultHandler = (\n logger: Logger,\n _translator: Translator,\n useCase: GetDynastyResultUseCase,\n): GetDynastyResultHandler => {\n return (command) => {\n logger.info(\n `Calculating dynasty results for ${command.games.length} games`,\n );\n const results = useCase(command.games);\n logger.info(`Dynasty results calculated`);\n return results;\n };\n};\n","import type { GetExtraRulesCommand } from \"@application/commands/getExtraRulesCommand.js\";\nimport {\n type ErrorCodeType,\n NotFoundError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport type { ExtraRule } from \"@core/domain/types/rule.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { GetExtraRulesUseCase } from \"@core/useCases/getExtraRules.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype GetExtraRulesHandler = (command: GetExtraRulesCommand) => ExtraRule[];\n\nexport const getExtraRulesHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: GetExtraRulesUseCase,\n ): GetExtraRulesHandler =>\n (command: GetExtraRulesCommand) => {\n const { mode, players } = command;\n logger.info(\n `Getting extra rules for mode: ${mode} and players: ${players}`,\n );\n const result = useCase(mode, players);\n\n if (isErr(result)) {\n logger.error(`Error getting extra rules: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new NotFoundError(translateErrorCode(translator, code), code, {\n mode: command.mode,\n });\n }\n\n logger.info(`Extra rules retrieved: ${result.value}`);\n return result.value;\n };\n","import type { GetModesCommand } from \"@application/commands/getModesCommand.js\";\nimport {\n type ErrorCodeType,\n NotFoundError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport type { GameMode } from \"@core/domain/types/mode.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { GetModesUseCase } from \"@core/useCases/getModes.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype GetModesHandler = (command: GetModesCommand) => GameMode[];\n\nexport const getModesHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: GetModesUseCase,\n ): GetModesHandler =>\n (_command: GetModesCommand) => {\n logger.info(\"Getting modes\");\n const result = useCase();\n\n if (isErr(result)) {\n logger.error(`Error getting modes: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new NotFoundError(translateErrorCode(translator, code), code);\n }\n\n logger.info(`Modes retrieved: ${result.value}`);\n return result.value;\n };\n","import type { GetResultCommand } from \"@application/commands/getResultCommand.js\";\nimport {\n ErrorCode,\n type ErrorCodeType,\n InvalidStepError,\n NotFoundError,\n StepExecutionError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport {\n type GameWithResults,\n isGameWithNextStep,\n type ScoreResult,\n} from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { CalculateScoreUseCase } from \"@core/useCases/calculateScore.js\";\nimport type { GetResultUseCase } from \"@core/useCases/getResult.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype GetResultHandler = (command: GetResultCommand) => GameWithResults;\n\nexport const getResultHandler =\n (\n logger: Logger,\n translator: Translator,\n useCases: {\n getResultUseCase: GetResultUseCase;\n calculateScoreUseCase: CalculateScoreUseCase;\n },\n ): GetResultHandler =>\n (command: GetResultCommand) => {\n const { getResultUseCase, calculateScoreUseCase } = useCases;\n const { game } = command;\n logger.info(`Getting result for game: ${game.id}`);\n\n if (!isGameWithNextStep(game)) {\n logger.error(\n `Invalid game, required nextAction type: 'step' but got: ${game.nextAction.type}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n { expected: \"step\", actual: game.nextAction.type, gameId: game.id },\n );\n }\n\n if (game.nextAction.step !== \"result\") {\n logger.error(\n `Required game with result step but got: ${game.nextAction.step}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n { expected: \"result\", actual: game.nextAction.step, gameId: game.id },\n );\n }\n\n const { players } = game;\n\n const scoreResult: ScoreResult[] = players.map((player) => {\n const { kingdom } = player;\n // Pass giant positions to reduce crowns covered by giants in scoring\n const giantPositions = player.giants?.map((g) => g.position);\n const result = calculateScoreUseCase(kingdom, giantPositions);\n\n if (isErr(result)) {\n logger.error(`Error when calculating score: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new StepExecutionError(\n translateErrorCode(translator, code),\n code,\n {\n gameId: game.id,\n },\n );\n }\n\n return {\n playerId: player.id,\n playerName: player.name,\n details: {\n ...result.value,\n },\n };\n });\n\n const result = getResultUseCase(game, scoreResult);\n\n if (isErr(result)) {\n logger.error(`Error getting result: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new NotFoundError(translateErrorCode(translator, code), code, {\n gameId: game.id,\n });\n }\n\n logger.info(`Result retrieved for game: ${game.id}`);\n return result.value;\n };\n","import type { GetValidPlacementsCommand } from \"@application/commands/getValidPlacementsCommand.js\";\nimport type { Domino, Kingdom } from \"@core/domain/types/index.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { ValidPlacement } from \"@core/useCases/getValidPlacements.js\";\n\ntype GetValidPlacementsUseCase = (\n kingdom: Kingdom,\n domino: Domino,\n maxKingdomSize?: number,\n) => ValidPlacement[];\n\ntype GetValidPlacementsHandler = (\n command: GetValidPlacementsCommand,\n) => ValidPlacement[];\n\n/**\n * Creates a handler for getting valid placements.\n */\nexport const getValidPlacementsHandler = (\n logger: Logger,\n _translator: Translator,\n useCase: GetValidPlacementsUseCase,\n): GetValidPlacementsHandler => {\n return (command) => {\n logger.info(\n `Getting valid placements for domino: ${command.domino.number}`,\n );\n const placements = useCase(\n command.kingdom,\n command.domino,\n command.maxKingdomSize,\n );\n logger.info(`Found ${placements.length} valid placements`);\n return placements;\n };\n};\n","import type { PlaceDominoCommand } from \"@application/commands/placeDominoCommand.js\";\nimport {\n ActionExecutionError,\n ErrorCode,\n type ErrorCodeType,\n InvalidStepError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport {\n type GameState,\n isGameWithNextAction,\n} from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { PlaceDominoUseCase } from \"@core/useCases/placeDomino.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype PlaceDominoHandler = (command: PlaceDominoCommand) => GameState;\n\nexport const placeDominoHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: PlaceDominoUseCase,\n ): PlaceDominoHandler =>\n (command: PlaceDominoCommand) => {\n const { game, lordId, position, rotation } = command;\n logger.info(\n `Placing domino: ${lordId} in position: ${JSON.stringify(\n position,\n )} with rotation: ${rotation} in game: ${game.id}`,\n );\n\n if (!isGameWithNextAction(game)) {\n logger.error(\n `Invalid game, required nextAction type: 'action' but got: ${game.nextAction.type}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n { expected: \"action\", actual: game.nextAction.type, gameId: game.id },\n );\n }\n\n if (game.nextAction.nextAction !== \"placeDomino\") {\n logger.error(\n `Required game with placeDomino action but got: ${game.nextAction.nextAction}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n {\n expected: \"placeDomino\",\n actual: game.nextAction.nextAction,\n gameId: game.id,\n },\n );\n }\n\n const result = useCase(game, lordId, position, rotation);\n\n if (isErr(result)) {\n logger.error(`Error placing domino: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new ActionExecutionError(\n translateErrorCode(translator, code),\n code,\n {\n gameId: game.id,\n lordId: command.lordId,\n position: command.position,\n rotation: command.rotation,\n },\n );\n }\n\n if (isGameWithNextAction(result.value)) {\n logger.info(\n `Domino placed: ${lordId} in position: ${JSON.stringify(\n position,\n )} with rotation: ${rotation} in game: ${game.id}`,\n );\n return result.value;\n }\n\n logger.info(\n `Domino placed: ${lordId} in position: ${JSON.stringify(\n position,\n )} with rotation: ${rotation} in game: ${game.id}`,\n );\n return result.value;\n };\n","import type { PlaceFireTokenCommand } from \"@application/commands/placeFireTokenCommand.js\";\nimport {\n ActionExecutionError,\n ErrorCode,\n type ErrorCodeType,\n InvalidStepError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport type { GameState } from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { PlaceFireTokenUseCase } from \"@core/useCases/placeFireToken.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype PlaceFireTokenHandler = (command: PlaceFireTokenCommand) => GameState;\n\nexport const placeFireTokenHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: PlaceFireTokenUseCase,\n ): PlaceFireTokenHandler =>\n (command: PlaceFireTokenCommand) => {\n const { game, lordId, position } = command;\n logger.info(\n `Placing fire token for lord: ${lordId} at position: ${JSON.stringify(\n position,\n )} in game: ${game.id}`,\n );\n\n if (game.nextAction.nextAction !== \"placeFireToken\") {\n logger.error(\n `Required game with placeFireToken action but got: ${game.nextAction.nextAction}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n {\n expected: \"placeFireToken\",\n actual: game.nextAction.nextAction,\n gameId: game.id,\n },\n );\n }\n\n const result = useCase(game, lordId, position);\n\n if (isErr(result)) {\n logger.error(`Error placing fire token: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new ActionExecutionError(\n translateErrorCode(translator, code),\n code,\n {\n gameId: game.id,\n lordId: command.lordId,\n position: command.position,\n },\n );\n }\n\n logger.info(\n `Fire token placed for lord: ${lordId} at position: ${JSON.stringify(\n position,\n )} in game: ${game.id}`,\n );\n return result.value;\n };\n","import type { PlaceGiantCommand } from \"@application/commands/placeGiantCommand.js\";\nimport {\n ActionExecutionError,\n ErrorCode,\n type ErrorCodeType,\n InvalidStepError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport type { GameState } from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { PlaceGiantUseCase } from \"@core/useCases/placeGiant.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype PlaceGiantHandler = (command: PlaceGiantCommand) => GameState;\n\nexport const placeGiantHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: PlaceGiantUseCase,\n ): PlaceGiantHandler =>\n (command: PlaceGiantCommand) => {\n const { game, lordId, position } = command;\n logger.info(\n `Placing giant for lord: ${lordId} at position: ${JSON.stringify(position)} in game: ${game.id}`,\n );\n\n if (game.nextAction.nextAction !== \"placeGiant\") {\n logger.error(\n `Required game with placeGiant action but got: ${game.nextAction.nextAction}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n {\n expected: \"placeGiant\",\n actual: game.nextAction.nextAction,\n gameId: game.id,\n },\n );\n }\n\n const result = useCase(game, lordId, position);\n\n if (isErr(result)) {\n logger.error(`Error placing giant: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new ActionExecutionError(\n translateErrorCode(translator, code),\n code,\n { gameId: game.id, lordId, position },\n );\n }\n\n logger.info(`Giant placed for lord: ${lordId} in game: ${game.id}`);\n return result.value;\n };\n","import type { PlaceKnightCommand } from \"@application/commands/placeKnightCommand.js\";\nimport {\n ActionExecutionError,\n ErrorCode,\n type ErrorCodeType,\n InvalidStepError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport type { GameState } from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { PlaceKnightUseCase } from \"@core/useCases/placeKnight.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype PlaceKnightHandler = (command: PlaceKnightCommand) => GameState;\n\nexport const placeKnightHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: PlaceKnightUseCase,\n ): PlaceKnightHandler =>\n (command: PlaceKnightCommand) => {\n const { game, lordId, position } = command;\n logger.info(\n `Placing knight for lord: ${lordId} at position: ${JSON.stringify(\n position,\n )} in game: ${game.id}`,\n );\n\n if (game.nextAction.nextAction !== \"placeKnight\") {\n logger.error(\n `Required game with placeKnight action but got: ${game.nextAction.nextAction}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n {\n expected: \"placeKnight\",\n actual: game.nextAction.nextAction,\n gameId: game.id,\n },\n );\n }\n\n const result = useCase(game, lordId, position);\n\n if (isErr(result)) {\n logger.error(`Error placing knight: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new ActionExecutionError(\n translateErrorCode(translator, code),\n code,\n {\n gameId: game.id,\n lordId: command.lordId,\n position: command.position,\n },\n );\n }\n\n logger.info(\n `Knight placed for lord: ${lordId} at position: ${JSON.stringify(\n position,\n )} in game: ${game.id}`,\n );\n return result.value;\n };\n","import type { RecruitCavemanCommand } from \"@application/commands/recruitCavemanCommand.js\";\nimport {\n ActionExecutionError,\n ErrorCode,\n type ErrorCodeType,\n InvalidStepError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport type { GameState } from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { RecruitCavemanUseCase } from \"@core/useCases/recruitCaveman.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype RecruitCavemanHandler = (command: RecruitCavemanCommand) => GameState;\n\nexport const recruitCavemanHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: RecruitCavemanUseCase,\n ): RecruitCavemanHandler =>\n (command: RecruitCavemanCommand) => {\n const { game, lordId, cavemanId, position, resourcePositions } = command;\n logger.info(\n `Recruiting caveman ${cavemanId} for lord: ${lordId} in game: ${game.id}`,\n );\n\n if (game.nextAction.nextAction !== \"recruitCaveman\") {\n logger.error(\n `Required game with recruitCaveman action but got: ${game.nextAction.nextAction}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n {\n expected: \"recruitCaveman\",\n actual: game.nextAction.nextAction,\n gameId: game.id,\n },\n );\n }\n\n const result = useCase(\n game,\n lordId,\n cavemanId,\n position,\n resourcePositions,\n );\n\n if (isErr(result)) {\n logger.error(`Error recruiting caveman: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new ActionExecutionError(\n translateErrorCode(translator, code),\n code,\n {\n gameId: game.id,\n lordId,\n cavemanId,\n position,\n },\n );\n }\n\n logger.info(\n `Caveman ${cavemanId} recruited for lord: ${lordId} in game: ${game.id}`,\n );\n return result.value;\n };\n","import type { SendGiantCommand } from \"@application/commands/sendGiantCommand.js\";\nimport {\n ActionExecutionError,\n ErrorCode,\n type ErrorCodeType,\n InvalidStepError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport type { GameState } from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { SendGiantUseCase } from \"@core/useCases/sendGiant.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype SendGiantHandler = (command: SendGiantCommand) => GameState;\n\nexport const sendGiantHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: SendGiantUseCase,\n ): SendGiantHandler =>\n (command: SendGiantCommand) => {\n const { game, lordId, giantIndex, targetPlayerId, targetCrownPosition } =\n command;\n logger.info(\n `Sending giant for lord: ${lordId} to player: ${targetPlayerId} in game: ${game.id}`,\n );\n\n if (game.nextAction.nextAction !== \"sendGiant\") {\n logger.error(\n `Required game with sendGiant action but got: ${game.nextAction.nextAction}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n {\n expected: \"sendGiant\",\n actual: game.nextAction.nextAction,\n gameId: game.id,\n },\n );\n }\n\n const result = useCase(\n game,\n lordId,\n giantIndex,\n targetPlayerId,\n targetCrownPosition,\n );\n\n if (isErr(result)) {\n logger.error(`Error sending giant: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new ActionExecutionError(\n translateErrorCode(translator, code),\n code,\n { gameId: game.id, lordId, targetPlayerId, targetCrownPosition },\n );\n }\n\n logger.info(\n `Giant sent from lord: ${lordId} to player: ${targetPlayerId} in game: ${game.id}`,\n );\n return result.value;\n };\n","import type { GameState } from \"@core/domain/types/index.js\";\nimport { err, ok, type Result } from \"@utils/result.js\";\n\n/**\n * Serialization format version for backwards compatibility.\n */\nconst SERIALIZATION_VERSION = 1;\n\n/**\n * Serialized game data structure.\n */\ninterface SerializedGame {\n version: number;\n data: GameState;\n timestamp: string;\n}\n\n/**\n * Serializes a game state to a JSON string.\n * The serialized string includes version information for future compatibility.\n *\n * @param game - The game state to serialize\n * @returns JSON string representation of the game\n */\nexport const serializeGame = (game: GameState): string => {\n const serialized: SerializedGame = {\n version: SERIALIZATION_VERSION,\n data: game,\n timestamp: new Date().toISOString(),\n };\n return JSON.stringify(serialized);\n};\n\n/**\n * Deserializes a JSON string back to a game state.\n * Validates the structure and version before returning.\n *\n * @param json - The JSON string to deserialize\n * @returns Result containing the game state or an error\n */\nexport const deserializeGame = (json: string): Result<GameState> => {\n try {\n const parsed = JSON.parse(json) as SerializedGame;\n\n // Validate structure\n if (!parsed.version || !parsed.data) {\n return err(\"Invalid serialized game format\");\n }\n\n // Check version compatibility\n if (parsed.version > SERIALIZATION_VERSION) {\n return err(\n `Unsupported serialization version: ${parsed.version}. Current version: ${SERIALIZATION_VERSION}`,\n );\n }\n\n // Validate essential game properties\n const game = parsed.data;\n if (!game.id || !game.players || !game.lords || !game.nextAction) {\n return err(\"Invalid game state structure\");\n }\n\n return ok(game);\n } catch (error) {\n return err(`Failed to parse game JSON: ${(error as Error).message}`);\n }\n};\n\n/**\n * Creates a save point for the current game state.\n * Includes metadata for debugging and restore purposes.\n */\nexport interface GameSavePoint {\n /** Serialized game data */\n serialized: string;\n /** When the save was created */\n createdAt: string;\n /** Game ID for reference */\n gameId: string;\n /** Current turn number */\n turn: number;\n}\n\n/**\n * Creates a save point from a game state.\n *\n * @param game - The game state to save\n * @returns A save point object with metadata\n */\nexport const createSavePoint = (game: GameState): GameSavePoint => {\n return {\n serialized: serializeGame(game),\n createdAt: new Date().toISOString(),\n gameId: game.id,\n turn: game.turn,\n };\n};\n\n/**\n * Restores a game state from a save point.\n *\n * @param savePoint - The save point to restore from\n * @returns Result containing the restored game state or an error\n */\nexport const restoreFromSavePoint = (\n savePoint: GameSavePoint,\n): Result<GameState> => {\n return deserializeGame(savePoint.serialized);\n};\n","import type {\n DeserializeGameCommand,\n SerializeGameCommand,\n} from \"@application/commands/serializeGameCommand.js\";\nimport {\n type ErrorCodeType,\n StepExecutionError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport type { GameState } from \"@core/domain/types/index.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport {\n deserializeGame,\n serializeGame,\n} from \"@core/useCases/serialization.js\";\nimport { isErr, unwrap } from \"@utils/result.js\";\n\ntype SerializeGameHandler = (command: SerializeGameCommand) => string;\ntype DeserializeGameHandler = (command: DeserializeGameCommand) => GameState;\n\n/**\n * Creates a handler for serializing game state.\n */\nexport const serializeGameHandler = (\n logger: Logger,\n _translator: Translator,\n): SerializeGameHandler => {\n return (command) => {\n logger.info(`Serializing game: ${command.game.id}`);\n const serialized = serializeGame(command.game);\n logger.info(`Game serialized successfully`);\n return serialized;\n };\n};\n\n/**\n * Creates a handler for deserializing game state.\n */\nexport const deserializeGameHandler = (\n logger: Logger,\n translator: Translator,\n): DeserializeGameHandler => {\n return (command) => {\n logger.info(`Deserializing game from JSON`);\n const result = deserializeGame(command.json);\n\n if (isErr(result)) {\n logger.error(`Failed to deserialize game: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new StepExecutionError(translateErrorCode(translator, code), code);\n }\n\n const game = unwrap(result);\n logger.info(`Game deserialized successfully: ${game.id}`);\n return game;\n };\n};\n","import type { SkipOptionalActionCommand } from \"@application/commands/skipOptionalActionCommand.js\";\nimport {\n ActionExecutionError,\n type ErrorCodeType,\n} from \"@core/domain/errors/domainErrors.js\";\nimport type { GameState } from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { SkipOptionalActionUseCase } from \"@core/useCases/skipOptionalAction.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype SkipOptionalActionHandler = (\n command: SkipOptionalActionCommand,\n) => GameState;\n\nexport const skipOptionalActionHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: SkipOptionalActionUseCase,\n ): SkipOptionalActionHandler =>\n (command: SkipOptionalActionCommand) => {\n const { game, lordId } = command;\n logger.info(\n `Skipping optional action for lord: ${lordId} in game: ${game.id}`,\n );\n\n const result = useCase(game, lordId);\n\n if (isErr(result)) {\n logger.error(`Error skipping optional action: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new ActionExecutionError(\n translateErrorCode(translator, code),\n code,\n { gameId: game.id, lordId: command.lordId },\n );\n }\n\n logger.info(\n `Optional action skipped for lord: ${lordId} in game: ${game.id}`,\n );\n return result.value;\n };\n","import type { StartGameCommand } from \"@application/commands/startGameCommand.js\";\nimport {\n ErrorCode,\n type ErrorCodeType,\n InvalidStepError,\n StepExecutionError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport {\n type GameWithNextAction,\n isGameWithNextStep,\n} from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { StartGameUseCase } from \"@core/useCases/startGame.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype StartGameHandler = (command: StartGameCommand) => GameWithNextAction;\n\nexport const startGameHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: StartGameUseCase,\n ): StartGameHandler =>\n (command: StartGameCommand) => {\n const { game } = command;\n logger.info(`Starting game: ${game.id}`);\n\n if (!isGameWithNextStep(game)) {\n logger.error(\n `Invalid game, required nextAction type: 'step' but got: ${game.nextAction.type}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n { expected: \"step\", actual: game.nextAction.type, gameId: game.id },\n );\n }\n\n if (\n game.nextAction.step !== \"start\" &&\n game.nextAction.step !== \"options\"\n ) {\n logger.error(\n `Required game with start step or options step but got: ${game.nextAction.step}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n {\n expected: \"start|options\",\n actual: game.nextAction.step,\n gameId: game.id,\n },\n );\n }\n\n const result = useCase(game);\n\n if (isErr(result)) {\n logger.error(`Error starting game: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new StepExecutionError(translateErrorCode(translator, code), code, {\n gameId: game.id,\n });\n }\n\n logger.info(`Game started: ${game.id}`);\n return result.value;\n };\n","import type { UseDragonCommand } from \"@application/commands/useDragonCommand.js\";\nimport {\n ActionExecutionError,\n ErrorCode,\n type ErrorCodeType,\n InvalidStepError,\n} from \"@core/domain/errors/domainErrors.js\";\nimport type { GameState } from \"@core/domain/types/game.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { translateErrorCode } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { UseDragonUseCase } from \"@core/useCases/useDragon.js\";\nimport { isErr } from \"@utils/result.js\";\n\ntype UseDragonHandler = (command: UseDragonCommand) => GameState;\n\nexport const useDragonHandler =\n (\n logger: Logger,\n translator: Translator,\n useCase: UseDragonUseCase,\n ): UseDragonHandler =>\n (command: UseDragonCommand) => {\n const { game, lordId, buildingId } = command;\n logger.info(\n `Using dragon on building: ${buildingId} for lord: ${lordId} in game: ${game.id}`,\n );\n\n if (game.nextAction.nextAction !== \"useDragon\") {\n logger.error(\n `Required game with useDragon action but got: ${game.nextAction.nextAction}`,\n );\n throw new InvalidStepError(\n translateErrorCode(translator, ErrorCode.INVALID_STEP),\n {\n expected: \"useDragon\",\n actual: game.nextAction.nextAction,\n gameId: game.id,\n },\n );\n }\n\n const result = useCase(game, lordId, buildingId);\n\n if (isErr(result)) {\n logger.error(`Error using dragon: ${result.error}`);\n const code = result.error as ErrorCodeType;\n throw new ActionExecutionError(\n translateErrorCode(translator, code),\n code,\n {\n gameId: game.id,\n lordId: command.lordId,\n buildingId: command.buildingId,\n },\n );\n }\n\n logger.info(\n `Dragon used on building: ${buildingId} for lord: ${lordId} in game: ${game.id}`,\n );\n return result.value;\n };\n","import { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport type { ExtraRule } from \"@core/domain/types/rule.js\";\nimport { err, ok, type Result } from \"@utils/result.js\";\n\nexport const getAvailablesExtraRules = (\n extraRules: ExtraRule[],\n mode: string,\n numberOfPlayers: number,\n): Result<ExtraRule[]> => {\n const availableExtraRules = extraRules.filter((rule) => {\n return (\n rule.mode.filter((m) => m.name === mode).length > 0 &&\n (!rule.playersLimit || rule.playersLimit === numberOfPlayers)\n );\n });\n\n if (availableExtraRules.length === 0) {\n return err(ErrorCode.STEP_EXECUTION_FAILED);\n }\n\n return ok(availableExtraRules);\n};\n\nexport const toExtraRule = (\n rule: string,\n extraRules: ExtraRule[],\n): Result<ExtraRule> => {\n const foundRule = extraRules.find((r) => r.name === rule);\n\n if (!foundRule) {\n return err(ErrorCode.STEP_EXECUTION_FAILED);\n }\n\n return ok(foundRule);\n};\n","import type { Ground } from \"./domino.js\";\nimport type { Position } from \"./kingdom.js\";\nimport type { ObjectValues } from \"./utils.js\";\n\n// ─── Giants ─────────────────────────────────────────────────────────\n\n/**\n * A giant placed on a player's kingdom, covering a crown.\n * The covered crown does not count for scoring.\n */\nexport type PlacedGiant = {\n /** Position on the kingdom grid where the giant covers a crown */\n position: Position;\n};\n\n// ─── Quest Tiles ────────────────────────────────────────────────────\n\n/**\n * All quest tile types available in Age of Giants.\n */\nexport const questTypes = {\n /** 5pts per matching terrain tile adjacent (8-dir) to castle */\n localTrade: \"localTrade\",\n /** 5pts per matching terrain tile in the 4 corners of the kingdom */\n kingdomBorders: \"kingdomBorders\",\n /** 5pts if kingdom is complete (no discarded dominos) */\n harmony: \"harmony\",\n /** 10pts if castle is in the center of the kingdom */\n middleKingdom: \"middleKingdom\",\n /** 20pts if castle is in one of the 4 corners of the kingdom */\n lostCorner: \"lostCorner\",\n /** 10pts per alignment of 3+ tiles with crowns (H/V/diagonal) */\n megalomania: \"megalomania\",\n /** 10pts per property of 5+ wheat/forest/sea/plain tiles with 0 crowns */\n austereKing: \"austereKing\",\n} as const;\n\nexport type QuestType = ObjectValues<typeof questTypes>;\n\n/**\n * A quest tile drawn at game start.\n * Provides a specific end-of-game bonus scoring condition.\n */\nexport type QuestTile = {\n /** Unique identifier for the quest tile */\n id: number;\n /** Type of quest determining the scoring rule */\n type: QuestType;\n /** Display name of the quest */\n name: string;\n /** Description of the scoring condition */\n description: string;\n /** Points awarded per match (e.g., 5 for localTrade, 10 for megalomania) */\n points: number;\n /** Target terrain type (only for localTrade and kingdomBorders quests) */\n terrain?: Ground;\n};\n\n// ─── Age of Giants Game State ───────────────────────────────────────\n\n/**\n * Complete Age of Giants-specific game state.\n * Stored as an optional field on Game and only present in AoG modes.\n */\nexport type AgeOfGiantsState = {\n /** Number of giant figurines remaining in the pool (starts at 6) */\n giantPool: number;\n /** The 2 quest tiles drawn for this game */\n questTiles: QuestTile[];\n};\n","/**\n * All possible ground/terrain types in Kingdomino.\n * Each type can form contiguous properties for scoring.\n */\nexport const GROUND = [\n \"castle\",\n \"wheat\",\n \"forest\",\n \"sea\",\n \"plain\",\n \"swamp\",\n \"mine\",\n \"grassland\",\n \"lake\",\n \"jungle\",\n \"quarry\",\n \"desert\",\n \"volcano\",\n] as const;\n\n/** Union type of all terrain types */\nexport type Ground = (typeof GROUND)[number];\n\n/** Special ground type for empty/unplaced tiles */\nexport type EmptyGround = \"empty\";\n\n/** Number of crowns on a tile (0-3) */\nexport type Crown = number;\n\n/**\n * Represents a single tile with terrain and crowns.\n * Two tiles form a domino.\n */\nexport type Tile = {\n /** The terrain type of this tile */\n type: Ground;\n /** Number of crowns (0-3), multiplier for scoring. In Origins, represents fire symbols. */\n crowns: Crown;\n /** Whether this tile has a construction square for buildings (Queendomino) */\n hasConstructionSquare?: boolean;\n /** Number of volcanic craters on this tile (Origins, 1-3). Determines fire token type. */\n volcanoCraters?: number;\n /** Whether this tile has a giant icon (Age of Giants, letter dominos A-F) */\n hasGiant?: boolean;\n /** Whether this tile has footprint icons (Age of Giants, dominos 49-54) */\n hasFootprint?: boolean;\n};\n\n/**\n * Represents an empty/unplaced tile on the kingdom grid.\n */\nexport type EmptyTile = {\n /** Always \"empty\" for unplaced tiles */\n type: EmptyGround;\n /** Empty tiles have no crowns */\n crowns: 0;\n};\n\n/**\n * Represents a domino piece consisting of two connected tiles.\n * Dominoes are the main game pieces that players place on their kingdoms.\n */\nexport type Domino = {\n /** The left tile of the domino */\n left: Tile;\n /** The right tile of the domino */\n right: Tile;\n /** Unique number identifying this domino (1-48 in Classic mode). Letter dominos use fractional numbers (A=0.01...F=0.06). */\n number: number;\n /** Display letter for Age of Giants giant dominos (A-F). Undefined for numbered dominos. */\n letter?: string;\n};\n\n/**\n * Represents a domino that has been revealed for player selection.\n * Contains selection state for the current turn.\n */\nexport type RevealsDomino = {\n /** The actual domino piece */\n domino: Domino;\n /** Whether this domino has been picked by a lord */\n picked: boolean;\n /** ID of the lord who picked this domino, or null if unpicked */\n lordId: string | null;\n /** Display position in the revealed set (for UI ordering) */\n position: number;\n};\n","import type { EmptyTile, Tile } from \"./domino.js\";\n\n/**\n * Represents a position on the kingdom grid.\n * Origin (0,0) is at the top-left corner.\n */\nexport type Position = {\n /** Column index (0-8, left to right) */\n x: number;\n /** Row index (0-8, top to bottom) */\n y: number;\n};\n\n/**\n * Rotation angle for domino placement.\n * - 0: Horizontal, left tile at position, right tile to the east\n * - 90: Vertical, left tile at position, right tile to the south\n * - 180: Horizontal, right tile at position, left tile to the east\n * - 270: Vertical, right tile at position, left tile to the south\n */\nexport type Rotation = 0 | 90 | 180 | 270;\n\n/**\n * Represents a player's kingdom as a 2D grid of tiles.\n * The grid is 9x9 to allow for the 5x5 maximum kingdom size\n * with the castle at any position.\n */\nexport type Kingdom = (Tile | EmptyTile)[][];\n\n/**\n * The size of the kingdom grid (9x9).\n * This allows for a 5x5 kingdom with the castle placed anywhere.\n */\nexport const GRIDSIZE = 9;\n\n/**\n * Maximum kingdom size (5x5 in standard rules, 7x7 for Mighty Duel).\n */\nexport const MAX_KINGDOM_SIZE = 5;\n","import type { Position } from \"./kingdom.js\";\nimport type { ObjectValues } from \"./utils.js\";\n\n// ─── Origins Sub-Modes ───────────────────────────────────────────────\n\n/**\n * The three gameplay modes within Kingdomino Origins.\n * Discovery is the base, Totem adds resources/totems, Tribe adds cavemen.\n */\nexport const originsSubModes = {\n discovery: \"Discovery\",\n totem: \"Totem\",\n tribe: \"Tribe\",\n} as const;\n\nexport type OriginsSubMode = ObjectValues<typeof originsSubModes>;\n\n// ─── Fire Tokens ─────────────────────────────────────────────────────\n\n/**\n * Represents the pool of available fire tokens.\n * Discovery Mode starts with: 5×1-fire, 4×2-fire, 1×3-fire = 10 total.\n */\nexport type FireTokenPool = {\n ones: number;\n twos: number;\n threes: number;\n};\n\n/**\n * A fire token that has been placed on a player's kingdom.\n */\nexport type PlacedFireToken = {\n /** Number of fires on this token (1, 2, or 3) */\n fires: 1 | 2 | 3;\n /** Position on the kingdom grid */\n position: Position;\n};\n\n/**\n * Tracks which volcano granted the current pending fire token,\n * so the placement validation knows the launch position.\n */\nexport type PendingFireToken = {\n /** Number of fires on the token to place */\n fires: 1 | 2 | 3;\n /** Position of the volcano that granted this token */\n volcanoPosition: Position;\n};\n\n// ─── Resources ───────────────────────────────────────────────────────\n\n/**\n * Types of wooden resources in Origins.\n * Each maps to a specific terrain type.\n */\nexport const resourceTypes = {\n mammoth: \"mammoth\",\n fish: \"fish\",\n mushroom: \"mushroom\",\n flint: \"flint\",\n} as const;\n\nexport type ResourceType = ObjectValues<typeof resourceTypes>;\n\n/**\n * A wooden resource placed on a player's kingdom tile.\n */\nexport type Resource = {\n /** Type of resource */\n type: ResourceType;\n /** Position on the kingdom grid */\n position: Position;\n};\n\n// ─── Totems ──────────────────────────────────────────────────────────\n\n/**\n * Tracks which player holds each totem tile.\n * null means no player currently holds that totem.\n */\nexport type TotemState = Record<ResourceType, string | null>;\n\n/**\n * Point values for each totem tile at end of game.\n */\nexport type TotemBonus = Record<ResourceType, number>;\n\n// ─── Cavemen ─────────────────────────────────────────────────────────\n\n/**\n * The 7 kinds of hunter-gatherers.\n * Each has a specific scoring rule based on surrounding resources.\n */\nexport const hunterGathererKinds = {\n /** Scores per mammoth adjacent */\n mammothHunter: \"mammothHunter\",\n /** Scores per fish adjacent */\n fisherman: \"fisherman\",\n /** Scores per mushroom adjacent */\n mushroomPicker: \"mushroomPicker\",\n /** Scores per flint adjacent */\n flintCollector: \"flintCollector\",\n /** Scores per unique resource type adjacent */\n trapper: \"trapper\",\n /** Scores per total resource adjacent (any type) */\n gatherer: \"gatherer\",\n /** Scores per fire symbol adjacent (Fire Lady) */\n fireLady: \"fireLady\",\n} as const;\n\nexport type HunterGathererKind = ObjectValues<typeof hunterGathererKinds>;\n\n/**\n * Warrior size categories with their power values.\n */\nexport const warriorTypes = {\n small: \"small\",\n amazon: \"amazon\",\n oafish: \"oafish\",\n} as const;\n\nexport type WarriorType = ObjectValues<typeof warriorTypes>;\n\n/**\n * Power values for each warrior type.\n */\nexport const WARRIOR_POWER: Record<WarriorType, number> = {\n small: 1,\n amazon: 2,\n oafish: 3,\n};\n\n/**\n * A hunter-gatherer caveman tile.\n */\nexport type HunterGathererTile = {\n kind: \"hunterGatherer\";\n id: number;\n /** Specific hunter-gatherer type determining scoring rule */\n hunterType: HunterGathererKind;\n /** Points per matching adjacent resource/symbol */\n pointsPerMatch: number;\n};\n\n/**\n * A warrior caveman tile.\n */\nexport type WarriorTile = {\n kind: \"warrior\";\n id: number;\n /** Warrior size category */\n warriorType: WarriorType;\n /** Combat power (1, 2, or 3) */\n power: number;\n};\n\n/** Discriminated union of all caveman tile types. */\nexport type CavemanTile = HunterGathererTile | WarriorTile;\n\n/**\n * A caveman tile placed on a player's kingdom.\n */\nexport type PlacedCaveman = {\n caveman: CavemanTile;\n position: Position;\n};\n\n/**\n * The Cave board used in Tribe mode.\n * Shows 4 visible caveman tiles and a face-down draw pile.\n */\nexport type CaveBoard = {\n /** Up to 4 visible caveman tiles available for recruitment */\n visible: CavemanTile[];\n /** Face-down draw pile */\n drawPile: CavemanTile[];\n};\n\n// ─── Origins Game State ──────────────────────────────────────────────\n\n/**\n * Complete Origins-specific game state.\n * Stored as an optional field on Game and only present in Origins modes.\n */\nexport type OriginsState = {\n /** Which Origins sub-mode is being played */\n subMode: OriginsSubMode;\n /** Available fire tokens pool */\n fireTokenPool: FireTokenPool;\n /** Pending fire token to place (set after placing a volcano domino) */\n pendingFireToken?: PendingFireToken;\n /** Totem holder state (Totem mode only) */\n totems?: TotemState;\n /** Cave board state (Tribe mode only) */\n caveBoard?: CaveBoard;\n};\n","import type { PlacedGiant } from \"./ageOfGiants.js\";\nimport type { PlacedBuilding } from \"./building.js\";\nimport type { Kingdom, Position } from \"./kingdom.js\";\nimport type { PlacedCaveman, PlacedFireToken, Resource } from \"./origins.js\";\nimport type { ObjectValues } from \"./utils.js\";\n\n/**\n * Represents a knight placed on a player's kingdom (Queendomino).\n */\nexport type Knight = {\n /** ID of the player who owns this knight */\n playerId: string;\n /** Position on the kingdom grid where the knight is placed */\n position: Position;\n};\n\n/**\n * Represents a player in the game.\n */\nexport type Player = {\n /** Unique identifier for the player */\n id: string;\n /** Display name of the player */\n name: string;\n /** The player's kingdom grid where dominoes are placed */\n kingdom: Kingdom;\n /** If set, this player is controlled by a bot with the named strategy */\n bot?: { strategyName: string };\n /** Number of coins the player has (Queendomino) */\n coins?: number;\n /** Number of towers the player has (Queendomino) */\n towers?: number;\n /** Knights placed on the kingdom (Queendomino) */\n knights?: Knight[];\n /** Buildings placed on the kingdom (Queendomino) */\n buildings?: PlacedBuilding[];\n /** Fire tokens placed on the kingdom (Origins) */\n fireTokens?: PlacedFireToken[];\n /** Wooden resources on the kingdom (Origins Totem/Tribe) */\n resources?: Resource[];\n /** Cavemen placed on the kingdom (Origins Tribe) */\n cavemen?: PlacedCaveman[];\n /** Giants placed on the kingdom covering crowns (Age of Giants) */\n giants?: PlacedGiant[];\n};\n\n/**\n * Payload for creating a new player.\n */\nexport type PlayerPayload = {\n /** Display name for the player (minimum 3 characters) */\n name: string;\n};\n\n/** Array of player creation payloads */\nexport type PlayersPayload = PlayerPayload[];\n\n/** Array of players */\nexport type Players = Player[];\n\n/**\n * Available actions a player can perform during their turn.\n */\nexport const playerActions = {\n /** Place a previously picked domino on the kingdom */\n placeDomino: \"placeDomino\",\n /** Pick a domino from the revealed set */\n pickDomino: \"pickDomino\",\n /** Pass/discard when no valid placement exists */\n pass: \"pass\",\n /** Place a knight on the just-placed domino (Queendomino, optional) */\n placeKnight: \"placeKnight\",\n /** Construct a building on a construction square (Queendomino, optional) */\n constructBuilding: \"constructBuilding\",\n /** Use the Dragon to burn a building tile (Queendomino, optional) */\n useDragon: \"useDragon\",\n /** Skip the current optional action (Queendomino/Origins/AoG) */\n skipOptionalAction: \"skipOptionalAction\",\n /** Place a giant on a crown after placing a giant domino (Age of Giants, mandatory) */\n placeGiant: \"placeGiant\",\n /** Send a giant to an opponent after placing a footprint domino (Age of Giants, optional) */\n sendGiant: \"sendGiant\",\n /** Place a fire token after placing a volcano domino (Origins, optional) */\n placeFireToken: \"placeFireToken\",\n /** Recruit a caveman from the cave board (Origins Tribe, optional) */\n recruitCaveman: \"recruitCaveman\",\n} as const;\n\n/** Union type of all player actions */\nexport type PlayerActions = ObjectValues<typeof playerActions>;\n","import type { ShuffleMethod } from \"@core/portServerside/shuffleMethod.js\";\n\nconst hashSeed = (str: string): number => {\n let hash = 2166136261;\n for (let i = 0; i < str.length; i++) {\n hash ^= str.charCodeAt(i);\n hash = Math.imul(hash, 16777619);\n }\n return hash >>> 0;\n};\n\nconst mulberry32 = (seed: number): (() => number) => {\n let state = seed;\n return () => {\n state |= 0;\n state = (state + 0x6d2b79f5) | 0;\n let t = Math.imul(state ^ (state >>> 15), 1 | state);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n};\n\nexport const createSeededShuffle = (\n seed: string,\n salt: string,\n): ShuffleMethod => {\n const numericSeed = hashSeed(`${seed}|${salt}`);\n const random = mulberry32(numericSeed);\n\n return <T>(array: T[]): T[] => {\n const result = [...array];\n for (let i = result.length - 1; i > 0; i--) {\n const j = Math.floor(random() * (i + 1));\n [result[i], result[j]] = [result[j] as T, result[i] as T];\n }\n return result;\n };\n};\n","import { toExtraRule } from \"@core/domain/entities/rule.js\";\nimport {\n type ExtraRule,\n type GameWithNextStep,\n gameSteps,\n type NextStep,\n} from \"@core/domain/types/index.js\";\nimport type { DominoesRepository } from \"@core/portServerside/dominoesRepository.js\";\nimport type { RuleRepository } from \"@core/portServerside/ruleRepository.js\";\nimport type { ShuffleMethod } from \"@core/portServerside/shuffleMethod.js\";\nimport { isErr, ok, type Result } from \"@utils/result.js\";\nimport { createSeededShuffle } from \"@utils/seededShuffle.js\";\n\nexport type AddExtraRulesUseCase = (\n game: GameWithNextStep,\n rules: string[],\n) => Result<GameWithNextStep>;\n\nexport const addExtraRulesUseCase =\n (deps: {\n ruleRepository: RuleRepository;\n dominoesRepository: DominoesRepository;\n shuffleMethod: ShuffleMethod;\n }): AddExtraRulesUseCase =>\n (game, rules) => {\n const { ruleRepository, dominoesRepository, shuffleMethod } = deps;\n const availableExtraRules = ruleRepository.getAllExtra();\n\n const newExtraRules: ExtraRule[] = [];\n\n for (const rule of rules) {\n const result = toExtraRule(rule, availableExtraRules);\n\n if (isErr(result)) {\n return result;\n }\n\n newExtraRules.push(result.value);\n }\n\n // The Mighty Duel overrides basic rules for 2-player games\n let updatedBasic = game.rules.basic;\n let updatedDominoes = game.dominoes;\n const hasMightyDuel = newExtraRules.some(\n (r) => r.name === \"The Mighty Duel\",\n );\n if (hasMightyDuel) {\n updatedBasic = {\n ...updatedBasic,\n maxDominoes: 48,\n maxTurns: 12,\n maxKingdomSize: 7,\n };\n // Reload and shuffle all 48 dominoes\n const allDominoes = dominoesRepository.getForMode(game.mode);\n if (allDominoes) {\n const shuffle = game.seed\n ? createSeededShuffle(game.seed, \"mighty-duel\")\n : shuffleMethod;\n updatedDominoes = shuffle(allDominoes);\n }\n }\n\n const updatedRules = {\n basic: updatedBasic,\n extra: newExtraRules,\n };\n\n const next: NextStep = {\n type: \"step\",\n step: gameSteps.start,\n };\n\n const updatedGame: GameWithNextStep = {\n ...game,\n dominoes: updatedDominoes,\n rules: updatedRules,\n nextAction: next,\n };\n\n return ok(updatedGame);\n };\n","import type { Domino } from \"@core/domain/types/domino.js\";\n\nconst AOG_MODE_PREFIX = \"AgeOfGiants\";\n\n/**\n * Checks whether the given mode name is an Age of Giants mode.\n */\nexport const isAgeOfGiantsMode = (modeName: string): boolean =>\n modeName.startsWith(AOG_MODE_PREFIX);\n\n/**\n * Checks whether the mode is Age of Giants combined with QueenDomino.\n */\nexport const isAgeOfGiantsQueenDominoMode = (modeName: string): boolean =>\n modeName === \"AgeOfGiants-QueenDomino\";\n\n/**\n * Checks whether a domino is a \"giant domino\" (has a giant icon on one of its tiles).\n * Giant dominos trigger the mandatory placeGiant action.\n */\nexport const isGiantDomino = (domino: Domino): boolean =>\n (domino.left.hasGiant ?? false) || (domino.right.hasGiant ?? false);\n\n/**\n * Checks whether a domino is a \"footprint domino\" (has footprint icons on one of its tiles).\n * Footprint dominos trigger the optional sendGiant action.\n */\nexport const isFootprintDomino = (domino: Domino): boolean =>\n (domino.left.hasFootprint ?? false) || (domino.right.hasFootprint ?? false);\n","import type { Player } from \"@core/domain/types/player.js\";\n\n/** Default starting coins for each player in Queendomino */\nexport const STARTING_COINS = 7;\n\n/** Maximum number of knights a player can place */\nexport const MAX_KNIGHTS = 3;\n\nexport const initializeCoins = (): number => STARTING_COINS;\n\nexport const addCoins = (player: Player, amount: number): Player => ({\n ...player,\n coins: (player.coins ?? 0) + amount,\n});\n\nexport const removeCoins = (player: Player, amount: number): Player => ({\n ...player,\n coins: (player.coins ?? 0) - amount,\n});\n\nexport const canAfford = (player: Player, cost: number): boolean =>\n (player.coins ?? 0) >= cost;\n\nexport const addTowers = (player: Player, amount: number): Player => ({\n ...player,\n towers: (player.towers ?? 0) + amount,\n});\n\nexport const getTowerCount = (player: Player): number => player.towers ?? 0;\n","import {\n type Crown,\n type EmptyGround,\n type EmptyTile,\n GROUND,\n type Ground,\n type Tile,\n} from \"@core/domain/types/domino.js\";\n\nconst isGround = (ground: unknown): ground is Ground => {\n return GROUND.includes(ground as Ground);\n};\n\nexport const createTile = (\n ground: Ground | EmptyGround,\n crowns: Crown = 0,\n): Tile | EmptyTile => {\n if (isGround(ground)) {\n return { type: ground, crowns } as Tile;\n }\n return { type: ground, crowns: 0 } as EmptyTile;\n};\n","import { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport {\n type Domino,\n type EmptyTile,\n GRIDSIZE,\n type Kingdom,\n MAX_KINGDOM_SIZE,\n type Position,\n type Rotation,\n type Tile,\n} from \"@core/domain/types/index.js\";\nimport { err, isErr, isOk, ok, type Result } from \"@utils/result.js\";\nimport { createTile } from \"./domino.js\";\n\nexport const createEmptyKingdom = (): Kingdom => {\n const emptyTile = createTile(\"empty\");\n return Array.from({ length: GRIDSIZE }, () =>\n Array.from({ length: GRIDSIZE }, () => emptyTile),\n );\n};\n\nexport const placeCastle = (kingdom: Kingdom): Kingdom => {\n const castle = createTile(\"castle\");\n const newKingdom = deepCopyKingdom(kingdom);\n newKingdom[4]![4] = castle;\n return newKingdom;\n};\n\nexport const placeTile = (\n kingdom: Kingdom,\n position: Position,\n tile: Tile,\n): Kingdom => {\n const newKingdom = deepCopyKingdom(kingdom);\n newKingdom[position.y]![position.x] = tile;\n return newKingdom;\n};\n\nexport const getTile = (\n kingdom: Kingdom,\n position: Position,\n): Result<Tile | EmptyTile> => {\n const tile = kingdom[position.y]?.[position.x];\n if (!tile) {\n return err(ErrorCode.PLACEMENT_OUT_OF_BOUNDS);\n }\n return ok(tile);\n};\n\nexport const calculateDominoPosition = (\n position: Position,\n rotation: Rotation,\n domino: Domino,\n): [{ tile: Tile; position: Position }, { tile: Tile; position: Position }] => {\n let firstTile: {\n tile: Tile;\n position: Position;\n };\n let secondTile: {\n tile: Tile;\n position: Position;\n };\n\n switch (rotation) {\n case 0: // horizontal, left to right\n firstTile = {\n tile: domino.left,\n position: {\n x: position.x,\n y: position.y,\n },\n };\n secondTile = {\n tile: domino.right,\n position: {\n x: position.x + 1,\n y: position.y,\n },\n };\n break;\n case 90: // vertical, top to bottom\n firstTile = {\n tile: domino.left,\n position: {\n x: position.x,\n y: position.y,\n },\n };\n secondTile = {\n tile: domino.right,\n position: {\n x: position.x,\n y: position.y + 1,\n },\n };\n break;\n case 180: // horizontal, right to left\n firstTile = {\n tile: domino.right,\n position: {\n x: position.x,\n y: position.y,\n },\n };\n secondTile = {\n tile: domino.left,\n position: {\n x: position.x + 1,\n y: position.y,\n },\n };\n break;\n case 270: // vertical, bottom to top\n firstTile = {\n tile: domino.right,\n position: {\n x: position.x,\n y: position.y,\n },\n };\n secondTile = {\n tile: domino.left,\n position: {\n x: position.x,\n y: position.y + 1,\n },\n };\n break;\n }\n\n return [firstTile, secondTile];\n};\n\nexport const placeDomino = (\n kingdom: Kingdom,\n position: Position,\n rotation: Rotation,\n domino: Domino,\n maxKingdomSize: number = MAX_KINGDOM_SIZE,\n): Result<Kingdom> => {\n const [firstTile, secondTile] = calculateDominoPosition(\n position,\n rotation,\n domino,\n );\n\n const isFreePlaceResult = isFreePlace(\n kingdom,\n firstTile.position,\n secondTile.position,\n );\n if (isErr(isFreePlaceResult)) {\n return isFreePlaceResult;\n }\n\n if (\n exceedsMaxSize(\n kingdom,\n firstTile.position,\n secondTile.position,\n maxKingdomSize,\n )\n ) {\n return err(ErrorCode.PLACEMENT_EXCEEDS_KINGDOM_SIZE);\n }\n\n const adjacentPairs = isAdjacent(kingdom, firstTile, secondTile);\n\n if (adjacentPairs.length === 0) {\n return err(ErrorCode.PLACEMENT_NOT_ADJACENT);\n }\n\n if (!hasValidAdjacent(adjacentPairs)) {\n return err(ErrorCode.PLACEMENT_INVALID_TERRAIN);\n }\n\n return ok(placeTiles(kingdom, [firstTile, secondTile]));\n};\n\nconst placeTiles = (\n kingdom: Kingdom,\n tiles: { tile: Tile; position: Position }[],\n) => {\n let newKingdom = deepCopyKingdom(kingdom);\n for (const { tile, position } of tiles) {\n newKingdom = placeTile(newKingdom, position, tile);\n }\n return newKingdom;\n};\n\nconst isFreePlace = (\n kingdom: Kingdom,\n firstPosition: Position,\n secondPosition: Position,\n): Result<boolean> => {\n const firstTile = getTile(kingdom, firstPosition);\n const secondTile = getTile(kingdom, secondPosition);\n\n if (isErr(firstTile)) {\n return firstTile;\n }\n\n if (isErr(secondTile)) {\n return secondTile;\n }\n\n if (firstTile.value.type !== \"empty\" || secondTile.value.type !== \"empty\") {\n return err(ErrorCode.PLACEMENT_NOT_EMPTY);\n }\n\n return ok(true);\n};\n\ntype AdjacentPair = { neighbor: Tile; own: Tile };\n\nconst isAdjacent = (\n kingdom: Kingdom,\n firstTile: { tile: Tile; position: Position },\n secondTile: { tile: Tile; position: Position },\n): AdjacentPair[] => {\n const offsets = [\n { x: -1, y: 0 },\n { x: 1, y: 0 },\n { x: 0, y: -1 },\n { x: 0, y: 1 },\n ];\n\n const isOwnPosition = (x: number, y: number) =>\n (x === firstTile.position.x && y === firstTile.position.y) ||\n (x === secondTile.position.x && y === secondTile.position.y);\n\n const pairs: AdjacentPair[] = [];\n\n for (const own of [firstTile, secondTile]) {\n for (const offset of offsets) {\n const nx = own.position.x + offset.x;\n const ny = own.position.y + offset.y;\n if (isOwnPosition(nx, ny)) continue;\n const tile = getTile(kingdom, { x: nx, y: ny });\n if (isOk(tile) && tile.value.type !== \"empty\") {\n pairs.push({ neighbor: tile.value, own: own.tile });\n }\n }\n }\n\n return pairs;\n};\n\nconst hasValidAdjacent = (pairs: AdjacentPair[]): boolean => {\n return pairs.some(\n ({ neighbor, own }) =>\n neighbor.type === \"castle\" || neighbor.type === own.type,\n );\n};\n\nexport const checkCastleIsInMiddle = (kingdom: Kingdom): boolean => {\n // Find castle coordinates\n let castleX: number | undefined;\n let castleY: number | undefined;\n\n for (let y = 0; y < kingdom.length; y++) {\n const x = kingdom[y]!.findIndex((tile) => tile.type === \"castle\");\n if (x !== -1) {\n castleX = x;\n castleY = y;\n break;\n }\n }\n\n if (castleX === undefined || castleY === undefined) {\n return false;\n }\n\n const bbox = getBoundingBox(kingdom);\n if (!bbox) return false;\n\n // Castle must be at the exact center of the bounding box\n const centerX = (bbox.minX + bbox.maxX) / 2;\n const centerY = (bbox.minY + bbox.maxY) / 2;\n\n return castleX === centerX && castleY === centerY;\n};\n\nexport const getBoundingBox = (\n kingdom: Kingdom,\n): { minX: number; maxX: number; minY: number; maxY: number } | null => {\n let minX = Infinity;\n let maxX = -Infinity;\n let minY = Infinity;\n let maxY = -Infinity;\n\n for (let y = 0; y < kingdom.length; y++) {\n for (let x = 0; x < kingdom[y]!.length; x++) {\n if (kingdom[y]![x]!.type !== \"empty\") {\n if (x < minX) minX = x;\n if (x > maxX) maxX = x;\n if (y < minY) minY = y;\n if (y > maxY) maxY = y;\n }\n }\n }\n\n if (minX === Infinity) return null;\n return { minX, maxX, minY, maxY };\n};\n\nconst exceedsMaxSize = (\n kingdom: Kingdom,\n firstPosition: Position,\n secondPosition: Position,\n maxSize: number = MAX_KINGDOM_SIZE,\n): boolean => {\n const bbox = getBoundingBox(kingdom);\n\n let minX = bbox?.minX ?? Infinity;\n let maxX = bbox?.maxX ?? -Infinity;\n let minY = bbox?.minY ?? Infinity;\n let maxY = bbox?.maxY ?? -Infinity;\n\n for (const pos of [firstPosition, secondPosition]) {\n if (pos.x < minX) minX = pos.x;\n if (pos.x > maxX) maxX = pos.x;\n if (pos.y < minY) minY = pos.y;\n if (pos.y > maxY) maxY = pos.y;\n }\n\n return maxX - minX + 1 > maxSize || maxY - minY + 1 > maxSize;\n};\n\nexport const countDominoes = (kingdom: Kingdom): number => {\n const notEmpties = kingdom.flat().filter((tile) => tile.type !== \"empty\");\n // -1 because the castle is not a domino\n return (notEmpties.length - 1) / 2;\n};\n\nconst deepCopyKingdom = (kingdom: Kingdom): Kingdom => {\n return kingdom.map((line) => line.map((tile) => ({ ...tile })));\n};\n","import type { OriginsSubMode } from \"@core/domain/types/origins.js\";\n\nconst ORIGINS_MODE_PREFIX = \"KingdominoOrigins-\";\n\n/**\n * Checks whether the given mode name is an Origins mode.\n */\nexport const isOriginsMode = (modeName: string): boolean =>\n modeName.startsWith(ORIGINS_MODE_PREFIX);\n\n/**\n * Extracts the sub-mode from an Origins mode name.\n * Returns undefined if not an Origins mode.\n */\nexport const getOriginsSubMode = (\n modeName: string,\n): OriginsSubMode | undefined => {\n if (!isOriginsMode(modeName)) return undefined;\n return modeName.slice(ORIGINS_MODE_PREFIX.length) as OriginsSubMode;\n};\n\n/**\n * Checks whether the mode is a Totem or Tribe mode (modes that use resources).\n */\nexport const isResourceMode = (modeName: string): boolean => {\n const sub = getOriginsSubMode(modeName);\n return sub === \"Totem\" || sub === \"Tribe\";\n};\n\n/**\n * Checks whether the mode is the Tribe mode (has cave board + cavemen).\n */\nexport const isTribeMode = (modeName: string): boolean => {\n return getOriginsSubMode(modeName) === \"Tribe\";\n};\n\n/**\n * Checks whether the mode is the Totem mode (has totem majority tiles).\n */\nexport const isTotemMode = (modeName: string): boolean => {\n return getOriginsSubMode(modeName) === \"Totem\";\n};\n","import { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport type { Kingdom } from \"@core/domain/types/kingdom.js\";\nimport type { Player } from \"@core/domain/types/player.js\";\nimport { err, isErr, ok, type Result } from \"@utils/result.js\";\n\nconst MINPLAYERSNAMELENGTH = 3;\n\nexport const validatePlayer = (name: string): Result<string> => {\n if (!name || name.trim().length < MINPLAYERSNAMELENGTH) {\n return err(ErrorCode.INVALID_PLAYER_NAME);\n }\n\n return ok(name);\n};\n\nexport const createPlayer = (\n playerName: string,\n id: string,\n kingdom: Kingdom,\n bot?: { strategyName: string },\n): Result<Player> => {\n const name = validatePlayer(playerName);\n\n if (isErr(name)) {\n return name;\n }\n\n return ok({\n name: name.value,\n id,\n kingdom,\n ...(bot && { bot }),\n });\n};\n","import type { PlayerInput } from \"@application/commands/addPlayersCommand.js\";\nimport {\n isAgeOfGiantsMode,\n isAgeOfGiantsQueenDominoMode,\n} from \"@core/domain/entities/ageOfGiantsHelpers.js\";\nimport { STARTING_COINS } from \"@core/domain/entities/economy.js\";\nimport {\n createEmptyKingdom,\n placeCastle,\n} from \"@core/domain/entities/kingdom.js\";\nimport {\n isOriginsMode,\n isResourceMode,\n isTribeMode,\n} from \"@core/domain/entities/originsHelpers.js\";\nimport { createPlayer } from \"@core/domain/entities/player.js\";\nimport { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport type {\n GameWithNextStep,\n NextStep,\n Players,\n} from \"@core/domain/types/index.js\";\nimport type { RuleRepository } from \"@core/portServerside/ruleRepository.js\";\nimport type { ShuffleMethod } from \"@core/portServerside/shuffleMethod.js\";\nimport type { UuidMethod } from \"@core/portServerside/uuidMethod.js\";\nimport { err, isErr, ok, type Result } from \"@utils/result.js\";\nimport { createSeededShuffle } from \"@utils/seededShuffle.js\";\n\nexport type AddPlayersUseCase = (\n game: GameWithNextStep,\n players: PlayerInput[],\n) => Result<GameWithNextStep>;\n\nconst normalizePlayerInput = (\n input: PlayerInput,\n): { name: string; bot?: { strategyName: string } } => {\n if (typeof input === \"string\") {\n return { name: input };\n }\n return { name: input.name, bot: input.bot };\n};\n\nexport const addPlayersUseCase =\n (deps: {\n uuidMethod: UuidMethod;\n shuffleMethod: ShuffleMethod;\n ruleRepository: RuleRepository;\n }): AddPlayersUseCase =>\n (game, players) => {\n const { uuidMethod, shuffleMethod, ruleRepository } = deps;\n\n const isAoG = isAgeOfGiantsMode(game.mode.name);\n const maxPlayers = isAoG ? 5 : 4;\n const minPlayers = isAoG ? 2 : 1;\n\n if (\n !players ||\n players.length < minPlayers ||\n players.length > maxPlayers\n ) {\n return err(ErrorCode.INVALID_PLAYER_COUNT);\n }\n\n const newPlayers: Players = [];\n\n for (const player of players) {\n const { name, bot } = normalizePlayerInput(player);\n let kingdom = createEmptyKingdom();\n kingdom = placeCastle(kingdom);\n const id = uuidMethod();\n const newPlayer = createPlayer(name, id, kingdom, bot);\n\n if (isErr(newPlayer)) {\n return newPlayer;\n }\n\n // Initialize Queendomino-specific player state\n if (game.mode.name === \"QueenDomino\") {\n newPlayer.value.coins = STARTING_COINS;\n newPlayer.value.towers = 0;\n newPlayer.value.knights = [];\n newPlayer.value.buildings = [];\n }\n\n // Initialize Age of Giants-specific player state\n if (isAoG) {\n newPlayer.value.giants = [];\n // AoG-QueenDomino also needs Queendomino player state\n if (isAgeOfGiantsQueenDominoMode(game.mode.name)) {\n newPlayer.value.coins = STARTING_COINS;\n newPlayer.value.towers = 0;\n newPlayer.value.knights = [];\n newPlayer.value.buildings = [];\n }\n }\n\n // Initialize Origins-specific player state\n if (isOriginsMode(game.mode.name)) {\n newPlayer.value.fireTokens = [];\n if (isResourceMode(game.mode.name)) {\n newPlayer.value.resources = [];\n }\n if (isTribeMode(game.mode.name)) {\n newPlayer.value.cavemen = [];\n }\n }\n\n newPlayers.push(newPlayer.value);\n }\n\n // set rules\n const rules = ruleRepository.getAll();\n const basicRules =\n isAoG && rules.aogBasic\n ? rules.aogBasic[newPlayers.length]\n : rules.basic[newPlayers.length];\n\n if (!basicRules) {\n return err(ErrorCode.STEP_EXECUTION_FAILED);\n }\n\n // updateDominoes\n const dominoes = game.dominoes;\n const { maxDominoes } = basicRules;\n const shuffle = game.seed\n ? createSeededShuffle(game.seed, \"dominoes\")\n : shuffleMethod;\n const shuffledDominoes = shuffle(dominoes);\n const splicedDominoes = shuffledDominoes.slice(0, maxDominoes);\n const next: NextStep = {\n type: \"step\",\n step: \"options\",\n };\n\n const updatedGame: GameWithNextStep = {\n ...game,\n players: newPlayers,\n dominoes: splicedDominoes,\n rules: {\n ...game.rules,\n basic: basicRules,\n },\n nextAction: next,\n };\n\n return ok(updatedGame);\n };\n","import type { Kingdom, Position, Score } from \"@core/domain/types/index.js\";\nimport { ok, type Result } from \"@utils/result.js\";\n\nexport type CalculateScoreUseCase = (\n kingdom: Kingdom,\n giantPositions?: Position[],\n) => Result<Score>;\n\ntype Property = {\n size: number;\n crowns: number;\n};\n\nexport const calculateScoreUseCase: CalculateScoreUseCase = (\n kingdom,\n giantPositions,\n) => {\n const rows = kingdom.length;\n const cols = kingdom[0]!.length;\n const visited: boolean[][] = kingdom.map((row) => row.map(() => false));\n const properties: Property[] = [];\n\n // Build a set for fast giant position lookup\n const giantSet = new Set<string>();\n if (giantPositions) {\n for (const pos of giantPositions) {\n giantSet.add(`${pos.x},${pos.y}`);\n }\n }\n\n const directions = [\n [-1, 0],\n [1, 0],\n [0, -1],\n [0, 1],\n ];\n\n for (let y = 0; y < rows; y++) {\n for (let x = 0; x < cols; x++) {\n const tile = kingdom[y]![x]!;\n if (visited[y]![x] || tile.type === \"empty\" || tile.type === \"castle\") {\n continue;\n }\n\n // BFS flood-fill for this property\n const type = tile.type;\n let size = 0;\n let crowns = 0;\n const queue: [number, number][] = [[x, y]];\n visited[y]![x] = true;\n\n while (queue.length > 0) {\n const [cx, cy] = queue.pop()!;\n const current = kingdom[cy]![cx]!;\n size++;\n\n // Count crowns, but subtract 1 for each giant covering this position\n let tileCrowns = current.crowns;\n if (giantSet.has(`${cx},${cy}`)) {\n tileCrowns = Math.max(0, tileCrowns - 1);\n }\n crowns += tileCrowns;\n\n for (const [dx, dy] of directions) {\n const nx = cx + (dx as number);\n const ny = cy + (dy as number);\n if (\n nx >= 0 &&\n ny >= 0 &&\n nx < cols &&\n ny < rows &&\n !visited[ny]![nx] &&\n kingdom[ny]![nx]!.type === type\n ) {\n visited[ny]![nx] = true;\n queue.push([nx, ny]);\n }\n }\n }\n\n properties.push({ size, crowns });\n }\n }\n\n if (properties.length === 0) {\n return ok({\n points: 0,\n maxPropertiesSize: 0,\n totalCrowns: 0,\n });\n }\n\n let points = 0;\n let maxPropertiesSize = 0;\n let totalCrowns = 0;\n\n for (const property of properties) {\n points += property.size * property.crowns;\n if (property.size > maxPropertiesSize) {\n maxPropertiesSize = property.size;\n }\n totalCrowns += property.crowns;\n }\n\n return ok({\n points,\n maxPropertiesSize,\n totalCrowns,\n });\n};\n","import type { NextAction } from \"@core/domain/types/game.js\";\nimport type { Lord } from \"@core/domain/types/lord.js\";\nimport {\n type PlayerActions,\n playerActions,\n} from \"@core/domain/types/player.js\";\n\nexport const createLord = (id: string, playerId: string): Lord => {\n return {\n id,\n playerId,\n turnEnded: false,\n hasPick: false,\n hasPlace: true,\n };\n};\n\nconst hasPick = (lord: Lord): boolean => lord.hasPick;\nconst hasPlace = (lord: Lord): boolean => lord.hasPlace;\nconst hasTurnEnded = (lord: Lord): boolean => lord.turnEnded;\n\nexport const canPass = (lord: Lord): boolean => {\n return !hasPick(lord) && !hasPlace(lord) && !hasTurnEnded(lord);\n};\n\nexport const canPick = (lord: Lord): boolean => {\n return !hasPick(lord) && hasPlace(lord) && !hasTurnEnded(lord);\n};\n\nexport const canPlaceAndDominoPickedIsDefined = (\n lord: Lord,\n): lord is Required<Lord & Pick<Lord, \"dominoPicked\">> => {\n return (\n !hasPick(lord) &&\n !hasPlace(lord) &&\n !hasTurnEnded(lord) &&\n lord.dominoPicked !== undefined\n );\n};\n\nexport const updateLordOrder = (lords: Lord[]): Lord[] => {\n return [...lords].sort((a, b) => {\n return (a.dominoPicked?.number ?? 0) - (b.dominoPicked?.number ?? 0);\n });\n};\n\nexport const resetLordsActions = (lords: Lord[]): Lord[] => {\n return lords.map((lord) => ({\n ...lord,\n turnEnded: false,\n hasPick: false,\n hasPlace: false,\n }));\n};\n\nexport const nextLordWithAction = (lords: Lord[]): NextAction => {\n const nextLord = findNextLord(lords);\n\n return {\n type: \"action\",\n nextLord: nextLord.id,\n nextAction: hasPlace(nextLord)\n ? playerActions.pickDomino\n : playerActions.placeDomino,\n };\n};\n\nconst findNextLord = (lords: Lord[]): Lord => {\n const lord = lords.find((lord) => !hasTurnEnded(lord));\n if (!lord) {\n return lords[0]!;\n }\n return lord;\n};\n\nexport const allLordsHavePlayed = (lords: Lord[]): boolean => {\n return lords.every((lord) => lord.turnEnded);\n};\n\n/**\n * Queendomino optional action sequence after placeDomino:\n * placeKnight → constructBuilding → useDragon → pickDomino\n *\n * Given the current optional action, returns the next one in the sequence.\n */\nconst QUEENDOMINO_ACTION_SEQUENCE: PlayerActions[] = [\n playerActions.placeKnight,\n playerActions.constructBuilding,\n playerActions.useDragon,\n playerActions.pickDomino,\n];\n\nexport const nextQueenDominoAction = (\n currentAction: PlayerActions,\n): PlayerActions => {\n const index = QUEENDOMINO_ACTION_SEQUENCE.indexOf(currentAction);\n if (index === -1 || index >= QUEENDOMINO_ACTION_SEQUENCE.length - 1) {\n return playerActions.pickDomino;\n }\n return QUEENDOMINO_ACTION_SEQUENCE[index + 1]!;\n};\n\n/**\n * Age of Giants action sequence after placeDomino (when placeGiant/sendGiant is triggered):\n * placeGiant or sendGiant → pickDomino\n *\n * When combined with QueenDomino:\n * placeGiant or sendGiant → placeKnight → constructBuilding → useDragon → pickDomino\n */\nconst AOG_QD_ACTION_SEQUENCE: PlayerActions[] = [\n playerActions.placeGiant, // or sendGiant (handled dynamically)\n playerActions.placeKnight,\n playerActions.constructBuilding,\n playerActions.useDragon,\n playerActions.pickDomino,\n];\n\n/**\n * Returns the next action after an AoG action.\n * @param currentAction - The current AoG action being completed or skipped\n * @param isQueenDomino - Whether the game combines AoG with QueenDomino\n */\nexport const nextAgeOfGiantsAction = (\n currentAction: PlayerActions,\n isQueenDomino: boolean,\n): PlayerActions => {\n if (!isQueenDomino) {\n // Simple AoG: after giant action, go to pickDomino\n return playerActions.pickDomino;\n }\n\n // AoG + QueenDomino: use the combined sequence\n const sequence = AOG_QD_ACTION_SEQUENCE;\n // Map sendGiant to the same position as placeGiant in the sequence\n const normalizedAction =\n currentAction === playerActions.sendGiant\n ? playerActions.placeGiant\n : currentAction;\n\n const index = sequence.indexOf(normalizedAction);\n if (index === -1 || index >= sequence.length - 1) {\n return playerActions.pickDomino;\n }\n return sequence[index + 1]!;\n};\n\n/**\n * Origins Discovery/Totem action sequence after placeDomino:\n * placeFireToken → pickDomino\n *\n * In Origins, placing a fire token is optional (only after placing a volcano domino).\n */\nconst ORIGINS_DISCOVERY_SEQUENCE: PlayerActions[] = [\n playerActions.placeFireToken,\n playerActions.pickDomino,\n];\n\n/**\n * Origins Tribe action sequence after placeDomino:\n * placeFireToken → pickDomino → recruitCaveman\n *\n * recruitCaveman happens after picking a new domino (unique to Tribe mode).\n */\nconst ORIGINS_TRIBE_SEQUENCE: PlayerActions[] = [\n playerActions.placeFireToken,\n playerActions.pickDomino,\n playerActions.recruitCaveman,\n];\n\n/**\n * Returns the next Origins action in the sequence.\n * @param currentAction - The current action being completed or skipped\n * @param isTribe - Whether the game is in Tribe mode\n */\nexport const nextOriginsAction = (\n currentAction: PlayerActions,\n isTribe: boolean,\n): PlayerActions => {\n const sequence = isTribe\n ? ORIGINS_TRIBE_SEQUENCE\n : ORIGINS_DISCOVERY_SEQUENCE;\n const index = sequence.indexOf(currentAction);\n if (index === -1 || index >= sequence.length - 1) {\n // Fallback: if we're past the end, signal turn done\n return playerActions.pickDomino;\n }\n return sequence[index + 1]!;\n};\n","import {\n allLordsHavePlayed,\n canPick,\n nextLordWithAction,\n resetLordsActions,\n updateLordOrder,\n} from \"@core/domain/entities/lord.js\";\nimport { isTribeMode } from \"@core/domain/entities/originsHelpers.js\";\nimport { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport type { GameWithNextAction } from \"@core/domain/types/game.js\";\nimport { playerActions } from \"@core/domain/types/player.js\";\nimport { err, ok, type Result } from \"@utils/result.js\";\n\nexport type ChooseDominoUseCase = (\n game: GameWithNextAction,\n lordId: string,\n dominoPick: number,\n) => Result<GameWithNextAction>;\n\nexport const chooseDominoUseCase: ChooseDominoUseCase = (\n game,\n lordId,\n dominoPick,\n) => {\n const currentLord = game.lords.find(\n (lord) => lord.id === game.nextAction.nextLord,\n );\n\n if (!currentLord) {\n return err(ErrorCode.LORD_NOT_FOUND);\n }\n\n if (currentLord.id !== lordId) {\n return err(ErrorCode.NOT_YOUR_TURN);\n }\n\n if (!canPick(currentLord)) {\n return err(ErrorCode.CANNOT_PICK);\n }\n\n // Check if dominoPick is valid choice\n const selectedDomino = game.currentDominoes.find(\n (domino) => domino.domino.number === dominoPick,\n );\n\n if (!selectedDomino) {\n return err(ErrorCode.DOMINO_NOT_FOUND);\n }\n\n if (selectedDomino.picked) {\n return err(ErrorCode.DOMINO_ALREADY_PICKED);\n }\n\n // update currentDominoes\n const updatedCurrentDominoes = game.currentDominoes.map((domino) =>\n domino.domino.number === dominoPick\n ? { ...domino, picked: true, lordId: currentLord.id }\n : domino,\n );\n\n const isTribe = isTribeMode(game.mode.name);\n\n // update lords - always mark turn ended\n const updatedLords = game.lords.map((lord) =>\n lord.id === currentLord.id\n ? {\n ...lord,\n hasPick: true,\n turnEnded: true,\n dominoPicked: selectedDomino.domino,\n }\n : lord,\n );\n\n const turnEnded = allLordsHavePlayed(updatedLords);\n\n if (turnEnded) {\n // All lords have picked - perform turn transition\n const lords = resetLordsActions(updateLordOrder(updatedLords));\n const updatedTurn = game.turn + 1;\n const dominoesCopy = [...game.dominoes];\n const dominoesDrawn = dominoesCopy.splice(\n 0,\n game.rules.basic.dominoesPerTurn,\n );\n dominoesDrawn.sort((a, b) => a.number - b.number);\n\n // Age of Giants: discard some dominos from the sorted line before selection\n const discardCount = game.rules.basic.dominoesDiscardedPerTurn ?? 0;\n if (discardCount > 0) {\n dominoesDrawn.splice(0, discardCount);\n }\n\n const newCurrentDominoes = dominoesDrawn.map((domino, index) => ({\n domino,\n picked: false,\n lordId: null,\n position: index + 1,\n }));\n\n if (isTribe) {\n // In Tribe mode, route to recruitCaveman before advancing to new turn\n return ok({\n ...game,\n currentDominoes: newCurrentDominoes,\n dominoes: dominoesCopy,\n lords,\n turn: updatedTurn,\n nextAction: {\n type: \"action\",\n nextLord: currentLord.id,\n nextAction: playerActions.recruitCaveman,\n },\n });\n }\n\n const next = nextLordWithAction(lords);\n return ok({\n ...game,\n currentDominoes: newCurrentDominoes,\n dominoes: dominoesCopy,\n lords,\n turn: updatedTurn,\n nextAction: next,\n });\n }\n\n if (isTribe) {\n // In Tribe mode, route to recruitCaveman before next lord picks\n return ok({\n ...game,\n currentDominoes: updatedCurrentDominoes,\n lords: updatedLords,\n nextAction: {\n type: \"action\",\n nextLord: currentLord.id,\n nextAction: playerActions.recruitCaveman,\n },\n });\n }\n\n const next = nextLordWithAction(updatedLords);\n\n return ok({\n ...game,\n currentDominoes: updatedCurrentDominoes,\n lords: updatedLords,\n nextAction: next,\n });\n};\n","import type {\n BuildersBoard,\n BuildingTile,\n PlacedBuilding,\n} from \"@core/domain/types/building.js\";\nimport type { Kingdom, Position } from \"@core/domain/types/kingdom.js\";\nimport type { Player } from \"@core/domain/types/player.js\";\nimport type { ShuffleMethod } from \"@core/portServerside/shuffleMethod.js\";\nimport { addCoins, addTowers, canAfford, removeCoins } from \"./economy.js\";\n\n/** Number of visible building slots on the Builders Board */\nconst BOARD_SLOTS = 4;\n\nexport const createBuildersBoard = (\n tiles: BuildingTile[],\n shuffle: ShuffleMethod,\n): BuildersBoard => {\n const shuffled = shuffle([...tiles]);\n const slots = shuffled.slice(0, BOARD_SLOTS);\n const drawPile = shuffled.slice(BOARD_SLOTS);\n\n return {\n slots,\n drawPile,\n };\n};\n\nexport const refillBuildersBoard = (board: BuildersBoard): BuildersBoard => {\n const newSlots = [...board.slots];\n const newDrawPile = [...board.drawPile];\n\n for (let i = 0; i < newSlots.length; i++) {\n if (newSlots[i] === null && newDrawPile.length > 0) {\n newSlots[i] = newDrawPile.shift()!;\n }\n }\n\n return { slots: newSlots, drawPile: newDrawPile };\n};\n\nexport const findBuildingOnBoard = (\n board: BuildersBoard,\n buildingId: number,\n): { building: BuildingTile; slotIndex: number } | null => {\n for (let i = 0; i < board.slots.length; i++) {\n const slot = board.slots[i];\n if (slot && slot.id === buildingId) {\n return { building: slot, slotIndex: i };\n }\n }\n return null;\n};\n\nexport const removeBuildingFromBoard = (\n board: BuildersBoard,\n slotIndex: number,\n): BuildersBoard => {\n const newSlots = [...board.slots];\n newSlots[slotIndex] = null;\n return { ...board, slots: newSlots };\n};\n\nexport const purchaseBuilding = (\n board: BuildersBoard,\n player: Player,\n buildingId: number,\n): {\n updatedBoard: BuildersBoard;\n updatedPlayer: Player;\n building: BuildingTile;\n} | null => {\n const found = findBuildingOnBoard(board, buildingId);\n if (!found) return null;\n\n const { building, slotIndex } = found;\n if (!canAfford(player, building.cost)) return null;\n\n let updatedPlayer = removeCoins(player, building.cost);\n\n // Apply immediate bonus\n if (building.immediateBonus) {\n switch (building.immediateBonus.type) {\n case \"coins\":\n updatedPlayer = addCoins(updatedPlayer, building.immediateBonus.amount);\n break;\n case \"tower\":\n updatedPlayer = addTowers(\n updatedPlayer,\n building.immediateBonus.amount,\n );\n break;\n }\n }\n\n // Add towers from the building itself\n if (building.towers > 0) {\n updatedPlayer = addTowers(updatedPlayer, building.towers);\n }\n\n const updatedBoard = removeBuildingFromBoard(board, slotIndex);\n\n return { updatedBoard, updatedPlayer, building };\n};\n\nexport const hasOpenConstructionSquare = (\n kingdom: Kingdom,\n placedBuildings: PlacedBuilding[],\n): boolean => {\n const occupiedPositions = new Set(\n placedBuildings.map((b) => `${b.position.x},${b.position.y}`),\n );\n\n for (let y = 0; y < kingdom.length; y++) {\n const row = kingdom[y]!;\n for (let x = 0; x < row.length; x++) {\n const tile = row[x]!;\n if (\n tile.type !== \"empty\" &&\n tile.type !== \"castle\" &&\n \"hasConstructionSquare\" in tile &&\n tile.hasConstructionSquare &&\n !occupiedPositions.has(`${x},${y}`)\n ) {\n return true;\n }\n }\n }\n return false;\n};\n\nexport const isValidConstructionPosition = (\n kingdom: Kingdom,\n placedBuildings: PlacedBuilding[],\n position: Position,\n): boolean => {\n const tile = kingdom[position.y]?.[position.x];\n if (!tile || tile.type === \"empty\" || tile.type === \"castle\") return false;\n if (!(\"hasConstructionSquare\" in tile) || !tile.hasConstructionSquare)\n return false;\n\n const occupied = placedBuildings.some(\n (b) => b.position.x === position.x && b.position.y === position.y,\n );\n return !occupied;\n};\n\nexport const placeBuildingOnKingdom = (\n kingdom: Kingdom,\n building: BuildingTile,\n position: Position,\n): Kingdom => {\n // Add building crowns to the tile\n const newKingdom = kingdom.map((row) => [...row]);\n const tile = newKingdom[position.y]![position.x]!;\n\n if (tile.type !== \"empty\" && tile.type !== \"castle\") {\n newKingdom[position.y]![position.x] = {\n ...tile,\n crowns: tile.crowns + building.crowns,\n };\n }\n\n return newKingdom;\n};\n\nexport const destroyWithDragon = (\n board: BuildersBoard,\n buildingId: number,\n player: Player,\n): {\n updatedBoard: BuildersBoard;\n updatedPlayer: Player;\n} | null => {\n const found = findBuildingOnBoard(board, buildingId);\n if (!found) return null;\n\n const { building, slotIndex } = found;\n if (!canAfford(player, building.cost)) return null;\n\n const updatedPlayer = removeCoins(player, building.cost);\n const updatedBoard = removeBuildingFromBoard(board, slotIndex);\n\n return { updatedBoard, updatedPlayer };\n};\n","import type { Kingdom } from \"@core/domain/types/kingdom.js\";\nimport type { Player } from \"@core/domain/types/player.js\";\nimport { getTowerCount } from \"./economy.js\";\n\n/**\n * Determine which player should hold the Queen.\n * The player with the most towers gets the Queen.\n * If tied, the Queen doesn't move (returns current holder).\n */\nexport const determineQueenHolder = (\n players: Player[],\n currentHolderId: string | null,\n): string | null => {\n let maxTowers = 0;\n let leaderId: string | null = null;\n let isTied = false;\n\n for (const player of players) {\n const towers = getTowerCount(player);\n if (towers > maxTowers) {\n maxTowers = towers;\n leaderId = player.id;\n isTied = false;\n } else if (towers === maxTowers && towers > 0 && leaderId !== null) {\n isTied = true;\n }\n }\n\n if (isTied || maxTowers === 0) {\n return currentHolderId;\n }\n\n return leaderId;\n};\n\ntype Property = {\n size: number;\n crowns: number;\n};\n\n/**\n * Find all properties (contiguous territories) in a kingdom using BFS.\n * Returns array of { size, crowns } for each property.\n */\nconst findProperties = (kingdom: Kingdom): Property[] => {\n const rows = kingdom.length;\n const cols = kingdom[0]?.length ?? 0;\n const visited: boolean[][] = kingdom.map((row) => row.map(() => false));\n const properties: Property[] = [];\n\n const directions = [\n [-1, 0],\n [1, 0],\n [0, -1],\n [0, 1],\n ];\n\n for (let y = 0; y < rows; y++) {\n for (let x = 0; x < cols; x++) {\n const tile = kingdom[y]![x]!;\n if (visited[y]![x] || tile.type === \"empty\" || tile.type === \"castle\") {\n continue;\n }\n\n const terrainType = tile.type;\n let size = 0;\n let crowns = 0;\n const queue: [number, number][] = [[x, y]];\n visited[y]![x] = true;\n\n while (queue.length > 0) {\n const [cx, cy] = queue.pop()!;\n const current = kingdom[cy]![cx]!;\n size++;\n crowns += current.crowns;\n\n for (const [dx, dy] of directions) {\n const nx = cx + (dx as number);\n const ny = cy + (dy as number);\n if (\n nx >= 0 &&\n ny >= 0 &&\n nx < cols &&\n ny < rows &&\n !visited[ny]![nx] &&\n kingdom[ny]![nx]!.type === terrainType\n ) {\n visited[ny]![nx] = true;\n queue.push([nx, ny]);\n }\n }\n }\n\n properties.push({ size, crowns });\n }\n }\n\n return properties;\n};\n\n/**\n * Calculate the Queen bonus: +1 crown to the territory with the most crowns.\n * Returns the additional points the Queen grants.\n */\nexport const getQueenBonus = (kingdom: Kingdom): number => {\n const properties = findProperties(kingdom);\n if (properties.length === 0) return 0;\n\n // Find the property with the most crowns\n let maxCrowns = 0;\n let maxCrownProperty: Property | null = null;\n\n for (const prop of properties) {\n if (prop.crowns > maxCrowns) {\n maxCrowns = prop.crowns;\n maxCrownProperty = prop;\n }\n }\n\n if (!maxCrownProperty || maxCrownProperty.crowns === 0) return 0;\n\n // Queen adds +1 crown to this territory\n // Original score: size * crowns\n // New score: size * (crowns + 1)\n // Bonus = size * (crowns + 1) - size * crowns = size\n return maxCrownProperty.size;\n};\n\n/**\n * Calculate end-game building bonus points for a player.\n */\nexport const calculateBuildingEndGameBonus = (player: Player): number => {\n const buildings = player.buildings ?? [];\n let bonus = 0;\n\n for (const placed of buildings) {\n const scoring = placed.building.endGameScoring;\n if (!scoring) continue;\n\n switch (scoring.type) {\n case \"flat\":\n bonus += scoring.points;\n break;\n case \"perBuilding\":\n bonus += buildings.length * scoring.points;\n break;\n case \"perTower\":\n bonus += getTowerCount(player) * scoring.points;\n break;\n case \"perCrown\": {\n const totalCrowns = countKingdomCrowns(player.kingdom);\n bonus += totalCrowns * scoring.points;\n break;\n }\n case \"perTerrain\": {\n if (scoring.terrain) {\n const count = countTerrainTiles(player.kingdom, scoring.terrain);\n bonus += count * scoring.points;\n }\n break;\n }\n }\n }\n\n return bonus;\n};\n\nconst countKingdomCrowns = (kingdom: Kingdom): number => {\n let total = 0;\n for (const row of kingdom) {\n for (const tile of row) {\n if (tile.type !== \"empty\" && tile.type !== \"castle\") {\n total += tile.crowns;\n }\n }\n }\n return total;\n};\n\nconst countTerrainTiles = (kingdom: Kingdom, terrain: string): number => {\n let count = 0;\n for (const row of kingdom) {\n for (const tile of row) {\n if (tile.type === terrain) {\n count++;\n }\n }\n }\n return count;\n};\n","import {\n isValidConstructionPosition,\n placeBuildingOnKingdom,\n purchaseBuilding,\n} from \"@core/domain/entities/building.js\";\nimport { nextQueenDominoAction } from \"@core/domain/entities/lord.js\";\nimport { determineQueenHolder } from \"@core/domain/entities/queen.js\";\nimport { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport type { PlacedBuilding } from \"@core/domain/types/building.js\";\nimport type {\n GameStateResult,\n GameWithNextAction,\n} from \"@core/domain/types/game.js\";\nimport type { Position } from \"@core/domain/types/kingdom.js\";\nimport { playerActions } from \"@core/domain/types/player.js\";\nimport { err, ok } from \"@utils/result.js\";\n\nexport type ConstructBuildingUseCase = (\n game: GameWithNextAction,\n lordId: string,\n buildingId: number,\n position: Position,\n) => GameStateResult;\n\nexport const constructBuildingUseCase: ConstructBuildingUseCase = (\n game,\n lordId,\n buildingId,\n position,\n) => {\n const currentAction = game.nextAction;\n\n if (currentAction.nextLord !== lordId) {\n return err(ErrorCode.NOT_YOUR_TURN);\n }\n\n if (currentAction.nextAction !== playerActions.constructBuilding) {\n return err(ErrorCode.INVALID_OPTIONAL_ACTION);\n }\n\n if (!game.queendomino) {\n return err(ErrorCode.INVALID_OPTIONAL_ACTION);\n }\n\n const currentLord = game.lords.find((l) => l.id === lordId);\n if (!currentLord) return err(ErrorCode.LORD_NOT_FOUND);\n\n const currentPlayer = game.players.find((p) => p.id === currentLord.playerId);\n if (!currentPlayer) return err(ErrorCode.PLAYER_NOT_FOUND);\n\n // Validate construction position\n if (\n !isValidConstructionPosition(\n currentPlayer.kingdom,\n currentPlayer.buildings ?? [],\n position,\n )\n ) {\n return err(ErrorCode.NO_CONSTRUCTION_SQUARE);\n }\n\n // Purchase the building\n const purchaseResult = purchaseBuilding(\n game.queendomino.buildersBoard,\n currentPlayer,\n buildingId,\n );\n\n if (!purchaseResult) {\n return err(ErrorCode.CANNOT_AFFORD_BUILDING);\n }\n\n const { updatedBoard, updatedPlayer, building } = purchaseResult;\n\n // Place building on kingdom (adds crowns)\n const updatedKingdom = placeBuildingOnKingdom(\n updatedPlayer.kingdom,\n building,\n position,\n );\n\n const placedBuilding: PlacedBuilding = { building, position };\n const finalPlayer = {\n ...updatedPlayer,\n kingdom: updatedKingdom,\n buildings: [...(updatedPlayer.buildings ?? []), placedBuilding],\n };\n\n const updatedPlayers = game.players.map((p) =>\n p.id === currentPlayer.id ? finalPlayer : p,\n );\n\n // Recalculate Queen holder\n const newQueenHolder = determineQueenHolder(\n updatedPlayers,\n game.queendomino.queenHolderId,\n );\n\n const nextAction = nextQueenDominoAction(playerActions.constructBuilding);\n\n return ok({\n ...game,\n players: updatedPlayers,\n queendomino: {\n ...game.queendomino,\n buildersBoard: updatedBoard,\n queenHolderId: newQueenHolder,\n },\n nextAction: {\n type: \"action\",\n nextLord: lordId,\n nextAction: nextAction,\n },\n });\n};\n","import { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport type { Kingdom, Position } from \"@core/domain/types/index.js\";\nimport type {\n FireTokenPool,\n PlacedFireToken,\n} from \"@core/domain/types/origins.js\";\nimport { err, ok, type Result } from \"@utils/result.js\";\n\n// ─── Fire Token Pool ─────────────────────────────────────────────────\n\n/**\n * Creates the initial fire token pool for an Origins game.\n * 10 tokens total: 5×1-fire, 4×2-fire, 1×3-fire.\n */\nexport const createFireTokenPool = (): FireTokenPool => ({\n ones: 5,\n twos: 4,\n threes: 1,\n});\n\n/**\n * Takes a fire token from the pool matching the given crater count.\n * Returns the updated pool, or an error if none available.\n */\nexport const takeFireToken = (\n pool: FireTokenPool,\n craters: number,\n): Result<{ fires: 1 | 2 | 3; updatedPool: FireTokenPool }> => {\n if (craters === 1 && pool.ones > 0) {\n return ok({ fires: 1, updatedPool: { ...pool, ones: pool.ones - 1 } });\n }\n if (craters === 2 && pool.twos > 0) {\n return ok({ fires: 2, updatedPool: { ...pool, twos: pool.twos - 1 } });\n }\n if (craters === 3 && pool.threes > 0) {\n return ok({ fires: 3, updatedPool: { ...pool, threes: pool.threes - 1 } });\n }\n return err(ErrorCode.FIRE_TOKEN_POOL_EMPTY);\n};\n\n/**\n * Checks whether a fire token of the given crater type is available.\n */\nexport const hasFireToken = (pool: FireTokenPool, craters: number): boolean => {\n if (craters === 1) return pool.ones > 0;\n if (craters === 2) return pool.twos > 0;\n if (craters === 3) return pool.threes > 0;\n return false;\n};\n\n// ─── Fire Token Placement ────────────────────────────────────────────\n\n/**\n * Computes all positions reachable in exactly N steps from a starting position,\n * using 8-directional movement (including diagonal) with direction changes allowed.\n */\nconst getReachablePositions = (\n from: Position,\n steps: number,\n gridSize: number,\n): Position[] => {\n if (steps === 0) return [from];\n\n // BFS: track positions reachable at each step count\n let current = new Set<string>();\n current.add(`${from.x},${from.y}`);\n\n for (let step = 0; step < steps; step++) {\n const next = new Set<string>();\n for (const key of current) {\n const [cx, cy] = key.split(\",\").map(Number) as [number, number];\n for (let dx = -1; dx <= 1; dx++) {\n for (let dy = -1; dy <= 1; dy++) {\n if (dx === 0 && dy === 0) continue;\n const nx = cx + dx;\n const ny = cy + dy;\n if (nx >= 0 && nx < gridSize && ny >= 0 && ny < gridSize) {\n next.add(`${nx},${ny}`);\n }\n }\n }\n }\n current = next;\n }\n\n return [...current].map((key) => {\n const [x, y] = key.split(\",\").map(Number) as [number, number];\n return { x, y };\n });\n};\n\n/**\n * Returns all valid positions where a fire token can be placed.\n * A fire token is launched from the volcano and travels exactly N squares\n * (8-directional, direction changes allowed).\n *\n * Landing position constraints:\n * - Must be on the grid and contain a placed tile (not empty)\n * - Must NOT be a volcano or castle tile\n * - Must NOT have a fire symbol (crowns > 0)\n * - Must NOT already have a fire token\n */\nexport const getValidFireTokenPositions = (\n kingdom: Kingdom,\n volcanoPosition: Position,\n fires: 1 | 2 | 3,\n existingFireTokens: PlacedFireToken[],\n): Position[] => {\n const gridSize = kingdom.length;\n const reachable = getReachablePositions(volcanoPosition, fires, gridSize);\n\n const fireTokenPositions = new Set(\n existingFireTokens.map((ft) => `${ft.position.x},${ft.position.y}`),\n );\n\n return reachable.filter((pos) => {\n const tile = kingdom[pos.y]?.[pos.x];\n if (!tile) return false;\n if (tile.type === \"empty\") return false;\n if (tile.type === \"volcano\") return false;\n if (tile.type === \"castle\") return false;\n if (tile.crowns > 0) return false;\n if (fireTokenPositions.has(`${pos.x},${pos.y}`)) return false;\n return true;\n });\n};\n\n/**\n * Checks whether a specific position is valid for fire token placement.\n */\nexport const isValidFireTokenPosition = (\n kingdom: Kingdom,\n position: Position,\n volcanoPosition: Position,\n fires: 1 | 2 | 3,\n existingFireTokens: PlacedFireToken[],\n): boolean => {\n const validPositions = getValidFireTokenPositions(\n kingdom,\n volcanoPosition,\n fires,\n existingFireTokens,\n );\n return validPositions.some((p) => p.x === position.x && p.y === position.y);\n};\n","import { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport type { PlacedGiant } from \"@core/domain/types/ageOfGiants.js\";\nimport type { Kingdom, Position } from \"@core/domain/types/kingdom.js\";\nimport type { Player } from \"@core/domain/types/player.js\";\nimport { err, ok, type Result } from \"@utils/result.js\";\n\nconst INITIAL_GIANT_POOL = 6;\n\n/**\n * Creates the initial giant pool (6 giants).\n */\nexport const createGiantPool = (): number => INITIAL_GIANT_POOL;\n\n/**\n * Takes a giant from the pool.\n * Returns the updated pool count, or an error if pool is empty.\n */\nexport const takeFromGiantPool = (pool: number): Result<number> => {\n if (pool <= 0) {\n return err(ErrorCode.GIANT_POOL_EMPTY);\n }\n return ok(pool - 1);\n};\n\n/**\n * Finds all positions in a kingdom that have at least 1 crown.\n */\nexport const findCrownsInKingdom = (kingdom: Kingdom): Position[] => {\n const crowns: Position[] = [];\n for (let y = 0; y < kingdom.length; y++) {\n const row = kingdom[y]!;\n for (let x = 0; x < row.length; x++) {\n const tile = row[x]!;\n if (tile.type !== \"empty\" && tile.type !== \"castle\" && tile.crowns > 0) {\n crowns.push({ x, y });\n }\n }\n }\n return crowns;\n};\n\n/**\n * Finds all crown positions not already covered by a giant.\n */\nexport const findCrownsNotCoveredByGiants = (\n kingdom: Kingdom,\n giants: PlacedGiant[],\n): Position[] => {\n const allCrowns = findCrownsInKingdom(kingdom);\n return allCrowns.filter(\n (crown) =>\n !giants.some((g) => g.position.x === crown.x && g.position.y === crown.y),\n );\n};\n\n/**\n * Checks whether a player has at least one giant on their kingdom.\n */\nexport const playerHasGiant = (player: Player): boolean =>\n (player.giants?.length ?? 0) > 0;\n\n/**\n * Places a giant on a crown in the player's kingdom.\n * Validates that the position has an uncovered crown.\n */\nexport const placeGiantOnCrown = (\n player: Player,\n position: Position,\n): Result<Player> => {\n const kingdom = player.kingdom;\n const tile = kingdom[position.y]?.[position.x];\n\n if (!tile || tile.type === \"empty\" || tile.type === \"castle\") {\n return err(ErrorCode.INVALID_GIANT_PLACEMENT);\n }\n\n if (tile.crowns <= 0) {\n return err(ErrorCode.INVALID_GIANT_PLACEMENT);\n }\n\n const giants = player.giants ?? [];\n\n // Check crown isn't already covered\n const alreadyCovered = giants.some(\n (g) => g.position.x === position.x && g.position.y === position.y,\n );\n if (alreadyCovered) {\n return err(ErrorCode.INVALID_GIANT_PLACEMENT);\n }\n\n const newGiant: PlacedGiant = { position };\n return ok({\n ...player,\n giants: [...giants, newGiant],\n });\n};\n\n/**\n * Sends a giant from the source player to the target player.\n * Removes the giant from the source and places it on a crown of the target.\n */\nexport const sendGiantToOpponent = (\n sourcePlayer: Player,\n targetPlayer: Player,\n giantIndex: number,\n targetCrownPosition: Position,\n): Result<{ source: Player; target: Player }> => {\n const sourceGiants = sourcePlayer.giants ?? [];\n\n if (giantIndex < 0 || giantIndex >= sourceGiants.length) {\n return err(ErrorCode.GIANT_NOT_FOUND);\n }\n\n // Validate target position has a crown\n const targetTile =\n targetPlayer.kingdom[targetCrownPosition.y]?.[targetCrownPosition.x];\n if (\n !targetTile ||\n targetTile.type === \"empty\" ||\n targetTile.type === \"castle\" ||\n targetTile.crowns <= 0\n ) {\n return err(ErrorCode.INVALID_GIANT_PLACEMENT);\n }\n\n // Check target crown isn't already covered\n const targetGiants = targetPlayer.giants ?? [];\n const alreadyCovered = targetGiants.some(\n (g) =>\n g.position.x === targetCrownPosition.x &&\n g.position.y === targetCrownPosition.y,\n );\n if (alreadyCovered) {\n return err(ErrorCode.INVALID_GIANT_PLACEMENT);\n }\n\n // Remove giant from source\n const updatedSourceGiants = sourceGiants.filter((_, i) => i !== giantIndex);\n\n // Place giant on target\n const newGiant: PlacedGiant = { position: targetCrownPosition };\n\n return ok({\n source: { ...sourcePlayer, giants: updatedSourceGiants },\n target: { ...targetPlayer, giants: [...targetGiants, newGiant] },\n });\n};\n","import type {\n AgeOfGiantsState,\n QuestTile,\n} from \"@core/domain/types/ageOfGiants.js\";\nimport type { BuildingTile } from \"@core/domain/types/building.js\";\nimport {\n type Domino,\n type GameMode,\n type GameWithNextStep,\n gameSteps,\n} from \"@core/domain/types/index.js\";\nimport type { CavemanTile, OriginsState } from \"@core/domain/types/origins.js\";\nimport type { QueenDominoState } from \"@core/domain/types/queendomino.js\";\nimport { isAgeOfGiantsMode } from \"./ageOfGiantsHelpers.js\";\nimport { createFireTokenPool } from \"./fireToken.js\";\nimport { createGiantPool } from \"./giant.js\";\nimport {\n getOriginsSubMode,\n isOriginsMode,\n isTotemMode,\n isTribeMode,\n} from \"./originsHelpers.js\";\n\nexport const create = (payload: {\n id: string;\n mode: GameMode;\n dominoes: Domino[];\n seed?: string;\n buildings?: BuildingTile[];\n cavemen?: CavemanTile[];\n questTiles?: QuestTile[];\n}): GameWithNextStep => {\n const { id, mode, dominoes, seed, buildings, cavemen, questTiles } = payload;\n\n let queendomino: QueenDominoState | undefined;\n if (\n (mode.name === \"QueenDomino\" || mode.name === \"AgeOfGiants-QueenDomino\") &&\n buildings\n ) {\n queendomino = {\n buildersBoard: {\n slots: [],\n drawPile: buildings,\n },\n queenHolderId: null,\n dragonAvailable: true,\n dragonUsedThisRound: false,\n };\n }\n\n let origins: OriginsState | undefined;\n if (isOriginsMode(mode.name)) {\n const subMode = getOriginsSubMode(mode.name)!;\n origins = {\n subMode,\n fireTokenPool: createFireTokenPool(),\n ...(isTotemMode(mode.name) && {\n totems: {\n mammoth: null,\n fish: null,\n mushroom: null,\n flint: null,\n },\n }),\n ...(isTribeMode(mode.name) &&\n cavemen && {\n caveBoard: {\n visible: [],\n drawPile: cavemen,\n },\n }),\n };\n }\n\n let ageOfGiants: AgeOfGiantsState | undefined;\n if (isAgeOfGiantsMode(mode.name) && questTiles) {\n ageOfGiants = {\n giantPool: createGiantPool(),\n questTiles,\n };\n }\n\n return {\n id,\n dominoes,\n currentDominoes: [],\n players: [],\n lords: [],\n turn: 0,\n nextAction: {\n type: \"step\",\n step: gameSteps.addPlayers,\n },\n rules: {\n basic: {\n lords: 0,\n maxDominoes: 0,\n dominoesPerTurn: 0,\n maxTurns: 0,\n maxKingdomSize: 5,\n },\n extra: [],\n },\n mode,\n ...(seed !== undefined && { seed }),\n ...(queendomino !== undefined && { queendomino }),\n ...(origins !== undefined && { origins }),\n ...(ageOfGiants !== undefined && { ageOfGiants }),\n };\n};\n","import { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport type { GameMode } from \"@core/domain/types/mode.js\";\nimport { err, ok, type Result } from \"@utils/result.js\";\n\nconst findMode = (\n mode: string,\n availableMode: GameMode[],\n): GameMode | undefined => {\n return availableMode.find((m) => m.name === mode);\n};\n\nexport const createMode = (\n mode: string,\n availableMode: GameMode[],\n): Result<GameMode> => {\n const foundMode = findMode(mode, availableMode);\n if (foundMode) {\n return ok(foundMode);\n }\n\n return err(ErrorCode.MODE_NOT_FOUND);\n};\n","import {\n isAgeOfGiantsMode,\n isAgeOfGiantsQueenDominoMode,\n} from \"@core/domain/entities/ageOfGiantsHelpers.js\";\nimport { create } from \"@core/domain/entities/game.js\";\nimport { createMode } from \"@core/domain/entities/mode.js\";\nimport { isTribeMode } from \"@core/domain/entities/originsHelpers.js\";\nimport { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport type { QuestTile } from \"@core/domain/types/ageOfGiants.js\";\nimport type { BuildingTile } from \"@core/domain/types/building.js\";\nimport type { GameWithNextStep } from \"@core/domain/types/game.js\";\nimport type { CavemanTile } from \"@core/domain/types/origins.js\";\nimport type { BuildingsRepository } from \"@core/portServerside/buildingsRepository.js\";\nimport type { CavemenRepository } from \"@core/portServerside/cavemenRepository.js\";\nimport type { DominoesRepository } from \"@core/portServerside/dominoesRepository.js\";\nimport type { ModeRepository } from \"@core/portServerside/modeRepository.js\";\nimport type { QuestTilesRepository } from \"@core/portServerside/questTilesRepository.js\";\nimport type { ShuffleMethod } from \"@core/portServerside/shuffleMethod.js\";\nimport type { UuidMethod } from \"@core/portServerside/uuidMethod.js\";\nimport { err, isErr, ok, type Result } from \"@utils/result.js\";\nimport { createSeededShuffle } from \"@utils/seededShuffle.js\";\n\nexport type CreateGameUseCase = (\n mode: string,\n seed?: string,\n) => Result<GameWithNextStep>;\n\nexport const createGameUseCase =\n (deps: {\n modeRepository: ModeRepository;\n dominoesRepository: DominoesRepository;\n uuidMethod: UuidMethod;\n shuffleMethod: ShuffleMethod;\n buildingsRepository?: BuildingsRepository;\n cavemenRepository?: CavemenRepository;\n questTilesRepository?: QuestTilesRepository;\n }): CreateGameUseCase =>\n (mode, seed) => {\n const {\n modeRepository,\n dominoesRepository,\n uuidMethod,\n shuffleMethod,\n buildingsRepository,\n cavemenRepository,\n questTilesRepository,\n } = deps;\n const id = uuidMethod();\n const gameSeed = seed ?? uuidMethod();\n const availableMode = modeRepository.getAvailables();\n const newMode = createMode(mode, availableMode);\n\n if (isErr(newMode)) {\n return newMode;\n }\n\n const dominoes = dominoesRepository.getForMode(newMode.value);\n\n if (!dominoes || dominoes.length === 0) {\n return err(ErrorCode.DOMINO_NOT_FOUND);\n }\n\n const isQueenDomino =\n newMode.value.name === \"QueenDomino\" ||\n isAgeOfGiantsQueenDominoMode(newMode.value.name);\n let buildings: BuildingTile[] | undefined;\n\n if (isQueenDomino && buildingsRepository) {\n buildings = buildingsRepository.getAll();\n }\n\n let cavemen: CavemanTile[] | undefined;\n if (isTribeMode(newMode.value.name) && cavemenRepository) {\n cavemen = cavemenRepository.getAll();\n }\n\n let questTiles: QuestTile[] | undefined;\n if (isAgeOfGiantsMode(newMode.value.name) && questTilesRepository) {\n const allQuests = questTilesRepository.getAll();\n // Draw 2 random quest tiles\n const questShuffle = gameSeed\n ? createSeededShuffle(gameSeed, \"quests\")\n : shuffleMethod;\n const shuffledQuests = questShuffle(allQuests);\n questTiles = shuffledQuests.slice(0, 2);\n }\n\n const payload = {\n id,\n mode: newMode.value,\n dominoes,\n seed: gameSeed,\n buildings,\n cavemen,\n questTiles,\n };\n\n const newGame = create(payload);\n\n return ok(newGame);\n };\n","import { placeDomino } from \"@core/domain/entities/kingdom.js\";\nimport type {\n Domino,\n Kingdom,\n Position,\n Rotation,\n} from \"@core/domain/types/index.js\";\nimport { GRIDSIZE, MAX_KINGDOM_SIZE } from \"@core/domain/types/kingdom.js\";\nimport { isOk } from \"@utils/result.js\";\n\n/**\n * Represents a valid placement position with rotation.\n */\nexport type ValidPlacement = {\n position: Position;\n rotation: Rotation;\n};\n\nexport type GetValidPlacementsUseCase = (\n kingdom: Kingdom,\n domino: Domino,\n maxKingdomSize?: number,\n) => ValidPlacement[];\n\n/**\n * Finds all valid placements for a domino on a kingdom grid.\n * Tests all positions and rotations to determine where the domino can be placed.\n *\n * @param kingdom - The current state of the kingdom grid\n * @param domino - The domino to place\n * @param maxKingdomSize - Maximum kingdom size (default: 5)\n * @returns Array of valid placements (position + rotation combinations)\n */\nexport const getValidPlacementsUseCase: GetValidPlacementsUseCase = (\n kingdom,\n domino,\n maxKingdomSize = MAX_KINGDOM_SIZE,\n) => {\n const validPlacements: ValidPlacement[] = [];\n const rotations: Rotation[] = [0, 90, 180, 270];\n\n // Try each position on the grid\n for (let y = 0; y < GRIDSIZE; y++) {\n for (let x = 0; x < GRIDSIZE; x++) {\n const position: Position = { x, y };\n\n // Try each rotation\n for (const rotation of rotations) {\n const result = placeDomino(\n kingdom,\n position,\n rotation,\n domino,\n maxKingdomSize,\n );\n if (isOk(result)) {\n validPlacements.push({ position, rotation });\n }\n }\n }\n }\n\n return validPlacements;\n};\n\n/**\n * Checks if a domino can be placed anywhere on the kingdom.\n *\n * @param kingdom - The current state of the kingdom grid\n * @param domino - The domino to check\n * @param maxKingdomSize - Maximum kingdom size (default: 5)\n * @returns True if at least one valid placement exists\n */\nexport const canPlaceDominoUseCase = (\n kingdom: Kingdom,\n domino: Domino,\n maxKingdomSize: number = MAX_KINGDOM_SIZE,\n): boolean => {\n const rotations: Rotation[] = [0, 90, 180, 270];\n\n // Check each position on the grid\n for (let y = 0; y < GRIDSIZE; y++) {\n for (let x = 0; x < GRIDSIZE; x++) {\n const position: Position = { x, y };\n\n // Check each rotation - return early if any placement is valid\n for (const rotation of rotations) {\n const result = placeDomino(\n kingdom,\n position,\n rotation,\n domino,\n maxKingdomSize,\n );\n if (isOk(result)) {\n return true;\n }\n }\n }\n }\n\n return false;\n};\n","import {\n allLordsHavePlayed,\n canPass,\n nextLordWithAction,\n} from \"@core/domain/entities/lord.js\";\nimport { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport {\n type GameState,\n type GameStateResult,\n type GameWithNextAction,\n gameSteps,\n type NextAction,\n type NextStep,\n} from \"@core/domain/types/game.js\";\nimport { err, ok } from \"@utils/result.js\";\nimport { canPlaceDominoUseCase } from \"./getValidPlacements.js\";\n\nexport type DiscardDominoUseCase = (\n game: GameWithNextAction,\n lordId: string,\n) => GameStateResult;\n\nexport const discardDominoUseCase: DiscardDominoUseCase = (game, lordId) => {\n const nextAction = game.nextAction;\n\n const currentLord = game.lords.find(\n (lord) => lord.id === nextAction.nextLord,\n );\n\n if (!currentLord) {\n return err(ErrorCode.LORD_NOT_FOUND);\n }\n\n if (currentLord.id !== lordId) {\n return err(ErrorCode.NOT_YOUR_TURN);\n }\n\n if (!canPass(currentLord)) {\n return err(ErrorCode.CANNOT_PLACE);\n }\n\n if (currentLord.dominoPicked) {\n const currentPlayer = game.players.find(\n (player) => player.id === currentLord.playerId,\n );\n\n if (\n currentPlayer &&\n canPlaceDominoUseCase(\n currentPlayer.kingdom,\n currentLord.dominoPicked,\n game.rules.basic.maxKingdomSize,\n )\n ) {\n return err(ErrorCode.CANNOT_PLACE);\n }\n }\n\n const maxTurns = game.rules.basic.maxTurns;\n const currentTurn = game.turn;\n const isLastTurn = currentTurn === maxTurns;\n\n const updatedLord = game.lords.map((lord) => {\n if (lord.id === currentLord.id) {\n if (isLastTurn) {\n return {\n ...lord,\n turnEnded: true,\n hasPlace: true,\n };\n }\n\n return {\n ...lord,\n hasPlace: true,\n };\n }\n return lord;\n });\n\n let updatedGame: GameState;\n\n const resultStep: NextStep = {\n type: \"step\",\n step: gameSteps.result,\n };\n\n if (isLastTurn && allLordsHavePlayed(updatedLord)) {\n updatedGame = {\n ...game,\n lords: updatedLord,\n nextAction: resultStep,\n };\n } else {\n updatedGame = {\n ...game,\n lords: updatedLord,\n nextAction: <NextAction>nextLordWithAction(updatedLord),\n };\n }\n\n return ok(updatedGame);\n};\n","import type { GameWithResults } from \"@core/domain/types/index.js\";\n\nexport type DynastyResult = {\n playerId: string;\n playerName: string;\n totalPoints: number;\n gamesPoints: number[];\n position: number;\n};\n\nexport type GetDynastyResultUseCase = (\n games: GameWithResults[],\n) => DynastyResult[];\n\nexport const getDynastyResultUseCase: GetDynastyResultUseCase = (games) => {\n // Collect all unique players\n const playerMap = new Map<string, { name: string; points: number[] }>();\n\n for (const game of games) {\n for (const result of game.result) {\n const existing = playerMap.get(result.playerId);\n if (existing) {\n existing.points.push(result.details.points);\n } else {\n playerMap.set(result.playerId, {\n name: result.playerName,\n points: [result.details.points],\n });\n }\n }\n }\n\n // Calculate totals and sort\n const results: Omit<DynastyResult, \"position\">[] = [];\n for (const [playerId, data] of playerMap) {\n results.push({\n playerId,\n playerName: data.name,\n totalPoints: data.points.reduce((sum, p) => sum + p, 0),\n gamesPoints: data.points,\n });\n }\n\n results.sort((a, b) => b.totalPoints - a.totalPoints);\n\n // Assign positions with tie detection\n const finalResults: DynastyResult[] = [];\n for (let i = 0; i < results.length; i++) {\n const current = results[i]!;\n const previous = i > 0 ? finalResults[i - 1]! : null;\n const position =\n previous && current.totalPoints === previous.totalPoints\n ? previous.position\n : i + 1;\n finalResults.push({ ...current, position });\n }\n\n return finalResults;\n};\n","import { getAvailablesExtraRules } from \"@core/domain/entities/rule.js\";\nimport { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport type { GameMode } from \"@core/domain/types/mode.js\";\nimport type { ExtraRule } from \"@core/domain/types/rule.js\";\nimport type { RuleRepository } from \"@core/portServerside/ruleRepository.js\";\nimport { err, type Result } from \"@utils/result.js\";\n\nexport type GetExtraRulesUseCase = (\n mode: GameMode[\"name\"],\n players: number,\n) => Result<ExtraRule[]>;\n\nexport const getExtraRulesUseCase =\n (deps: { ruleRepository: RuleRepository }): GetExtraRulesUseCase =>\n (mode: GameMode[\"name\"], players: number): Result<ExtraRule[]> => {\n const { ruleRepository } = deps;\n\n const allExtraRules = ruleRepository.getAllExtra();\n\n if (!allExtraRules) {\n return err(ErrorCode.STEP_EXECUTION_FAILED);\n }\n\n return getAvailablesExtraRules(allExtraRules, mode, players);\n };\n","import type { GameMode } from \"@core/domain/types/mode.js\";\nimport type { ModeRepository } from \"@core/portServerside/modeRepository.js\";\nimport { ok, type Result } from \"@utils/result.js\";\n\nexport type GetModesUseCase = () => Result<GameMode[]>;\n\nexport const getModesUseCase =\n (deps: { modeRepository: ModeRepository }): GetModesUseCase =>\n (): Result<GameMode[]> => {\n const { modeRepository } = deps;\n return ok(modeRepository.getAvailables());\n };\n","import type { Kingdom, Position } from \"@core/domain/types/kingdom.js\";\nimport type {\n CaveBoard,\n CavemanTile,\n PlacedCaveman,\n PlacedFireToken,\n Resource,\n ResourceType,\n} from \"@core/domain/types/origins.js\";\nimport type { ShuffleMethod } from \"@core/portServerside/shuffleMethod.js\";\n\nconst CAVE_BOARD_VISIBLE = 4;\n\n// ─── Cave Board Management ──────────────────────────────────────────\n\n/**\n * Creates a cave board from a list of caveman tiles.\n * Shuffles the tiles, reveals 4, and puts the rest in the draw pile.\n */\nexport const createCaveBoard = (\n tiles: CavemanTile[],\n shuffle: ShuffleMethod,\n): CaveBoard => {\n const shuffled = shuffle(tiles);\n return {\n visible: shuffled.slice(0, CAVE_BOARD_VISIBLE),\n drawPile: shuffled.slice(CAVE_BOARD_VISIBLE),\n };\n};\n\n/**\n * Takes a caveman from the visible slots and refills from draw pile.\n */\nexport const takeCavemanFromVisible = (\n board: CaveBoard,\n cavemanId: number,\n): { caveman: CavemanTile; updatedBoard: CaveBoard } | undefined => {\n const index = board.visible.findIndex((c) => c.id === cavemanId);\n if (index === -1) return undefined;\n\n const caveman = board.visible[index]!;\n const newVisible = [...board.visible];\n newVisible.splice(index, 1);\n\n // Refill from draw pile\n const newDrawPile = [...board.drawPile];\n if (newDrawPile.length > 0) {\n newVisible.push(newDrawPile.shift()!);\n }\n\n return {\n caveman,\n updatedBoard: { visible: newVisible, drawPile: newDrawPile },\n };\n};\n\n/**\n * Takes a caveman from the draw pile (face-down, player's choice).\n */\nexport const takeCavemanFromDrawPile = (\n board: CaveBoard,\n cavemanId: number,\n): { caveman: CavemanTile; updatedBoard: CaveBoard } | undefined => {\n const index = board.drawPile.findIndex((c) => c.id === cavemanId);\n if (index === -1) return undefined;\n\n const caveman = board.drawPile[index]!;\n const newDrawPile = [...board.drawPile];\n newDrawPile.splice(index, 1);\n\n return {\n caveman,\n updatedBoard: { visible: [...board.visible], drawPile: newDrawPile },\n };\n};\n\n// ─── Caveman Placement ───────────────────────────────────────────────\n\n/**\n * Checks if a position is valid for placing a caveman.\n * Must be on a placed tile with: no fire symbol, no fire token, no resource.\n */\nexport const isValidCavemanPosition = (\n kingdom: Kingdom,\n position: Position,\n fireTokens: PlacedFireToken[],\n resources: Resource[],\n cavemen: PlacedCaveman[],\n): boolean => {\n const tile = kingdom[position.y]?.[position.x];\n if (!tile) return false;\n if (tile.type === \"empty\" || tile.type === \"castle\") return false;\n\n // No fire symbols on tile\n if (tile.crowns > 0) return false;\n\n // No fire token at position\n if (\n fireTokens.some(\n (ft) => ft.position.x === position.x && ft.position.y === position.y,\n )\n )\n return false;\n\n // No resource at position\n if (\n resources.some(\n (r) => r.position.x === position.x && r.position.y === position.y,\n )\n )\n return false;\n\n // No existing caveman at position\n if (\n cavemen.some(\n (c) => c.position.x === position.x && c.position.y === position.y,\n )\n )\n return false;\n\n return true;\n};\n\n// ─── Caveman Scoring ─────────────────────────────────────────────────\n\n/**\n * All 8 directions (including diagonals) for adjacent resource counting.\n */\nconst EIGHT_DIRECTIONS = [\n [-1, -1],\n [-1, 0],\n [-1, 1],\n [0, -1],\n [0, 1],\n [1, -1],\n [1, 0],\n [1, 1],\n];\n\n/**\n * Calculates the score for a single hunter-gatherer based on surrounding resources/fire.\n */\nexport const calculateHunterGathererScore = (\n caveman: PlacedCaveman,\n kingdom: Kingdom,\n resources: Resource[],\n fireTokens: PlacedFireToken[],\n): number => {\n if (caveman.caveman.kind !== \"hunterGatherer\") return 0;\n\n const { hunterType, pointsPerMatch } = caveman.caveman;\n const { x, y } = caveman.position;\n let matches = 0;\n\n for (const [dx, dy] of EIGHT_DIRECTIONS) {\n const nx = x + (dx as number);\n const ny = y + (dy as number);\n\n switch (hunterType) {\n case \"mammothHunter\":\n if (\n resources.some(\n (r) =>\n r.position.x === nx &&\n r.position.y === ny &&\n r.type === \"mammoth\",\n )\n )\n matches++;\n break;\n case \"fisherman\":\n if (\n resources.some(\n (r) =>\n r.position.x === nx && r.position.y === ny && r.type === \"fish\",\n )\n )\n matches++;\n break;\n case \"mushroomPicker\":\n if (\n resources.some(\n (r) =>\n r.position.x === nx &&\n r.position.y === ny &&\n r.type === \"mushroom\",\n )\n )\n matches++;\n break;\n case \"flintCollector\":\n if (\n resources.some(\n (r) =>\n r.position.x === nx && r.position.y === ny && r.type === \"flint\",\n )\n )\n matches++;\n break;\n case \"trapper\": {\n // Count unique resource types adjacent\n const adjacentTypes = new Set<ResourceType>();\n for (const r of resources) {\n if (r.position.x === nx && r.position.y === ny) {\n adjacentTypes.add(r.type);\n }\n }\n matches += adjacentTypes.size;\n break;\n }\n case \"gatherer\":\n // Count all resources adjacent (any type)\n if (resources.some((r) => r.position.x === nx && r.position.y === ny))\n matches++;\n break;\n case \"fireLady\": {\n // Count fire symbols (on tiles + fire tokens)\n const tile = kingdom[ny]?.[nx];\n if (tile && tile.type !== \"empty\") {\n matches += tile.crowns;\n }\n if (\n fireTokens.some((ft) => ft.position.x === nx && ft.position.y === ny)\n ) {\n const token = fireTokens.find(\n (ft) => ft.position.x === nx && ft.position.y === ny,\n );\n if (token) matches += token.fires;\n }\n break;\n }\n }\n }\n\n return matches * pointsPerMatch;\n};\n\n/**\n * Calculates warrior group scoring.\n * Groups are connected warrior tiles (perpendicular only).\n * Score per group = number_of_warriors × total_power.\n */\nexport const calculateWarriorGroupScore = (\n cavemen: PlacedCaveman[],\n): number => {\n const warriors = cavemen.filter((c) => c.caveman.kind === \"warrior\");\n if (warriors.length === 0) return 0;\n\n const visited = new Set<string>();\n let totalScore = 0;\n\n const directions = [\n [-1, 0],\n [1, 0],\n [0, -1],\n [0, 1],\n ];\n\n for (const warrior of warriors) {\n const key = `${warrior.position.x},${warrior.position.y}`;\n if (visited.has(key)) continue;\n\n // BFS to find connected group\n let groupSize = 0;\n let groupPower = 0;\n const queue: PlacedCaveman[] = [warrior];\n visited.add(key);\n\n while (queue.length > 0) {\n const current = queue.pop()!;\n groupSize++;\n if (current.caveman.kind === \"warrior\") {\n groupPower += current.caveman.power;\n }\n\n for (const [dx, dy] of directions) {\n const nx = current.position.x + (dx as number);\n const ny = current.position.y + (dy as number);\n const nKey = `${nx},${ny}`;\n\n if (!visited.has(nKey)) {\n const neighbor = warriors.find(\n (w) => w.position.x === nx && w.position.y === ny,\n );\n if (neighbor) {\n visited.add(nKey);\n queue.push(neighbor);\n }\n }\n }\n }\n\n totalScore += groupSize * groupPower;\n }\n\n return totalScore;\n};\n\n/**\n * Calculates the total caveman bonus score for Tribe mode.\n */\nexport const calculateTribeCavemanScore = (\n cavemen: PlacedCaveman[],\n kingdom: Kingdom,\n resources: Resource[],\n fireTokens: PlacedFireToken[],\n): number => {\n let totalScore = 0;\n\n // Hunter-gatherer scores\n for (const caveman of cavemen) {\n if (caveman.caveman.kind === \"hunterGatherer\") {\n totalScore += calculateHunterGathererScore(\n caveman,\n kingdom,\n resources,\n fireTokens,\n );\n }\n }\n\n // Warrior group scores\n totalScore += calculateWarriorGroupScore(cavemen);\n\n return totalScore;\n};\n","import type { Kingdom } from \"@core/domain/types/kingdom.js\";\nimport type { PlacedFireToken } from \"@core/domain/types/origins.js\";\n\n/**\n * Calculates the fire token bonus for Origins scoring.\n *\n * For each region in the kingdom, fire tokens placed within that region\n * contribute their fire value as additional multiplier.\n * The bonus is: for each region, fire_tokens_in_region × region_size.\n *\n * This is added on top of the base score (which already accounts for\n * fire symbols printed on tiles via the crowns field).\n */\nexport const calculateOriginsFireBonus = (\n kingdom: Kingdom,\n placedFireTokens: PlacedFireToken[],\n): number => {\n if (placedFireTokens.length === 0) return 0;\n\n const rows = kingdom.length;\n const cols = kingdom[0]!.length;\n const visited: boolean[][] = kingdom.map((row) => row.map(() => false));\n\n const directions = [\n [-1, 0],\n [1, 0],\n [0, -1],\n [0, 1],\n ];\n\n // Build a map of fire token positions to fire values\n const tokenMap = new Map<string, number>();\n for (const token of placedFireTokens) {\n const key = `${token.position.x},${token.position.y}`;\n tokenMap.set(key, (tokenMap.get(key) ?? 0) + token.fires);\n }\n\n let totalBonus = 0;\n\n for (let y = 0; y < rows; y++) {\n for (let x = 0; x < cols; x++) {\n const tile = kingdom[y]![x]!;\n if (\n visited[y]![x] ||\n tile.type === \"empty\" ||\n tile.type === \"castle\" ||\n tile.type === \"volcano\"\n ) {\n continue;\n }\n\n // BFS flood-fill for this region\n const type = tile.type;\n let size = 0;\n let fireTokenFires = 0;\n const queue: [number, number][] = [[x, y]];\n visited[y]![x] = true;\n\n while (queue.length > 0) {\n const [cx, cy] = queue.pop()!;\n size++;\n\n // Check for fire token at this position\n const key = `${cx},${cy}`;\n if (tokenMap.has(key)) {\n fireTokenFires += tokenMap.get(key)!;\n }\n\n for (const [dx, dy] of directions) {\n const nx = cx + (dx as number);\n const ny = cy + (dy as number);\n if (\n nx >= 0 &&\n ny >= 0 &&\n nx < cols &&\n ny < rows &&\n !visited[ny]![nx] &&\n kingdom[ny]![nx]!.type === type\n ) {\n visited[ny]![nx] = true;\n queue.push([nx, ny]);\n }\n }\n }\n\n // Fire token bonus for this region: size × fire_token_fires\n totalBonus += size * fireTokenFires;\n }\n }\n\n return totalBonus;\n};\n","import type { PlacedGiant, QuestTile } from \"@core/domain/types/ageOfGiants.js\";\nimport { questTypes } from \"@core/domain/types/ageOfGiants.js\";\nimport type { Ground } from \"@core/domain/types/domino.js\";\nimport type { Kingdom } from \"@core/domain/types/kingdom.js\";\nimport { checkCastleIsInMiddle, countDominoes } from \"./kingdom.js\";\n\n/**\n * Finds the castle position in the kingdom.\n */\nconst findCastlePosition = (\n kingdom: Kingdom,\n): { x: number; y: number } | undefined => {\n for (let y = 0; y < kingdom.length; y++) {\n const row = kingdom[y]!;\n for (let x = 0; x < row.length; x++) {\n if (row[x]!.type === \"castle\") {\n return { x, y };\n }\n }\n }\n return undefined;\n};\n\n/**\n * Gets the bounding box of non-empty tiles in the kingdom.\n */\nconst getBoundingBox = (\n kingdom: Kingdom,\n): { minX: number; minY: number; maxX: number; maxY: number } | undefined => {\n let minX = Number.MAX_SAFE_INTEGER;\n let minY = Number.MAX_SAFE_INTEGER;\n let maxX = -1;\n let maxY = -1;\n\n for (let y = 0; y < kingdom.length; y++) {\n const row = kingdom[y]!;\n for (let x = 0; x < row.length; x++) {\n if (row[x]!.type !== \"empty\") {\n minX = Math.min(minX, x);\n minY = Math.min(minY, y);\n maxX = Math.max(maxX, x);\n maxY = Math.max(maxY, y);\n }\n }\n }\n\n if (maxX === -1) return undefined;\n return { minX, minY, maxX, maxY };\n};\n\n/**\n * Local Trade: 5pts per matching terrain tile adjacent (8-dir) to castle.\n */\nexport const calculateLocalTradeBonus = (\n kingdom: Kingdom,\n terrain: Ground,\n pointsPerMatch: number,\n): number => {\n const castle = findCastlePosition(kingdom);\n if (!castle) return 0;\n\n const directions = [\n [-1, -1],\n [-1, 0],\n [-1, 1],\n [0, -1],\n [0, 1],\n [1, -1],\n [1, 0],\n [1, 1],\n ];\n\n let count = 0;\n for (const [dy, dx] of directions) {\n const ny = castle.y + (dy as number);\n const nx = castle.x + (dx as number);\n const tile = kingdom[ny]?.[nx];\n if (tile && tile.type === terrain) {\n count++;\n }\n }\n\n return count * pointsPerMatch;\n};\n\n/**\n * Kingdom Borders: 5pts per matching terrain tile in the 4 corners of the kingdom bounding box.\n */\nexport const calculateKingdomBordersBonus = (\n kingdom: Kingdom,\n terrain: Ground,\n pointsPerMatch: number,\n): number => {\n const box = getBoundingBox(kingdom);\n if (!box) return 0;\n\n const corners = [\n { x: box.minX, y: box.minY },\n { x: box.maxX, y: box.minY },\n { x: box.minX, y: box.maxY },\n { x: box.maxX, y: box.maxY },\n ];\n\n let count = 0;\n for (const corner of corners) {\n const tile = kingdom[corner.y]?.[corner.x];\n if (tile && tile.type === terrain) {\n count++;\n }\n }\n\n return count * pointsPerMatch;\n};\n\n/**\n * Lost Corner: 20pts if castle is in one of the 4 corners of the kingdom bounding box.\n */\nexport const calculateLostCornerBonus = (\n kingdom: Kingdom,\n points: number,\n): number => {\n const castle = findCastlePosition(kingdom);\n if (!castle) return 0;\n\n const box = getBoundingBox(kingdom);\n if (!box) return 0;\n\n const isCorner =\n (castle.x === box.minX && castle.y === box.minY) ||\n (castle.x === box.maxX && castle.y === box.minY) ||\n (castle.x === box.minX && castle.y === box.maxY) ||\n (castle.x === box.maxX && castle.y === box.maxY);\n\n return isCorner ? points : 0;\n};\n\n/**\n * Megalomania: 10pts per alignment of 3+ tiles with uncovered crowns (H/V/diagonal).\n * Giants cover crowns, so we skip positions covered by giants.\n */\nexport const calculateMegalomaniaBonus = (\n kingdom: Kingdom,\n giants: PlacedGiant[],\n points: number,\n): number => {\n const rows = kingdom.length;\n const cols = kingdom[0]!.length;\n\n // Build a boolean grid: true if tile has uncovered crown\n const hasCrown: boolean[][] = Array.from({ length: rows }, () =>\n Array.from({ length: cols }, () => false),\n );\n\n for (let y = 0; y < rows; y++) {\n for (let x = 0; x < cols; x++) {\n const tile = kingdom[y]![x]!;\n if (tile.type !== \"empty\" && tile.type !== \"castle\" && tile.crowns > 0) {\n const coveredByGiant = giants.some(\n (g) => g.position.x === x && g.position.y === y,\n );\n if (!coveredByGiant) {\n hasCrown[y]![x] = true;\n }\n }\n }\n }\n\n let alignments = 0;\n\n // Directions: horizontal (1,0), vertical (0,1), diagonal (1,1), anti-diagonal (1,-1)\n const directions = [\n { dx: 1, dy: 0 }, // horizontal\n { dx: 0, dy: 1 }, // vertical\n { dx: 1, dy: 1 }, // diagonal\n { dx: 1, dy: -1 }, // anti-diagonal\n ];\n\n for (const { dx, dy } of directions) {\n // Track which cells have been counted in a run for this direction\n const counted: boolean[][] = Array.from({ length: rows }, () =>\n Array.from({ length: cols }, () => false),\n );\n\n for (let y = 0; y < rows; y++) {\n for (let x = 0; x < cols; x++) {\n if (counted[y]![x] || !hasCrown[y]![x]) continue;\n\n // Count consecutive crowns in this direction\n let length = 0;\n let cx = x;\n let cy = y;\n while (\n cx >= 0 &&\n cx < cols &&\n cy >= 0 &&\n cy < rows &&\n hasCrown[cy]![cx]\n ) {\n counted[cy]![cx] = true;\n length++;\n cx += dx;\n cy += dy;\n }\n\n if (length >= 3) {\n alignments++;\n }\n }\n }\n }\n\n return alignments * points;\n};\n\n/**\n * Austere King: 10pts per property of 5+ wheat/forest/sea/plain tiles with 0 crowns.\n */\nexport const calculateAustereKingBonus = (\n kingdom: Kingdom,\n points: number,\n): number => {\n const eligibleTerrains: Ground[] = [\"wheat\", \"forest\", \"sea\", \"plain\"];\n const rows = kingdom.length;\n const cols = kingdom[0]!.length;\n const visited: boolean[][] = Array.from({ length: rows }, () =>\n Array.from({ length: cols }, () => false),\n );\n\n const directions = [\n [-1, 0],\n [1, 0],\n [0, -1],\n [0, 1],\n ];\n\n let qualifyingProperties = 0;\n\n for (let y = 0; y < rows; y++) {\n for (let x = 0; x < cols; x++) {\n const tile = kingdom[y]![x]!;\n if (visited[y]![x] || !eligibleTerrains.includes(tile.type as Ground))\n continue;\n if (tile.type === \"empty\" || tile.type === \"castle\") continue;\n\n // BFS for this property\n const type = tile.type;\n let size = 0;\n let hasAnyCrown = false;\n const queue: [number, number][] = [[x, y]];\n visited[y]![x] = true;\n\n while (queue.length > 0) {\n const [cx, cy] = queue.pop()!;\n const current = kingdom[cy]![cx]!;\n size++;\n if (current.crowns > 0) hasAnyCrown = true;\n\n for (const [dy, dx] of directions) {\n const nx = cx + (dx as number);\n const ny = cy + (dy as number);\n if (\n nx >= 0 &&\n ny >= 0 &&\n nx < cols &&\n ny < rows &&\n !visited[ny]![nx] &&\n kingdom[ny]![nx]!.type === type\n ) {\n visited[ny]![nx] = true;\n queue.push([nx, ny]);\n }\n }\n }\n\n if (size >= 5 && !hasAnyCrown) {\n qualifyingProperties++;\n }\n }\n }\n\n return qualifyingProperties * points;\n};\n\n/**\n * Calculates the bonus for a single quest tile.\n */\nexport const calculateQuestBonus = (\n quest: QuestTile,\n kingdom: Kingdom,\n giants: PlacedGiant[],\n dominoLimit: number,\n playerCount: number,\n): number => {\n switch (quest.type) {\n case questTypes.localTrade:\n return calculateLocalTradeBonus(kingdom, quest.terrain!, quest.points);\n\n case questTypes.kingdomBorders:\n return calculateKingdomBordersBonus(\n kingdom,\n quest.terrain!,\n quest.points,\n );\n\n case questTypes.harmony: {\n const totalDominoes = countDominoes(kingdom);\n const dominoesPerPlayer = dominoLimit / playerCount;\n return totalDominoes === dominoesPerPlayer ? quest.points : 0;\n }\n\n case questTypes.middleKingdom:\n return checkCastleIsInMiddle(kingdom) ? quest.points : 0;\n\n case questTypes.lostCorner:\n return calculateLostCornerBonus(kingdom, quest.points);\n\n case questTypes.megalomania:\n return calculateMegalomaniaBonus(kingdom, giants, quest.points);\n\n case questTypes.austereKing:\n return calculateAustereKingBonus(kingdom, quest.points);\n\n default:\n return 0;\n }\n};\n","import type { Ground, Tile } from \"@core/domain/types/domino.js\";\nimport type { Position } from \"@core/domain/types/kingdom.js\";\nimport type { Resource, ResourceType } from \"@core/domain/types/origins.js\";\n\n/**\n * Maps terrain types to their corresponding resource type.\n * Returns null for terrains that don't produce resources.\n */\nexport const terrainToResource = (terrain: Ground): ResourceType | null => {\n switch (terrain) {\n case \"grassland\":\n return \"mammoth\";\n case \"lake\":\n return \"fish\";\n case \"jungle\":\n return \"mushroom\";\n case \"quarry\":\n return \"flint\";\n default:\n return null;\n }\n};\n\n/**\n * Checks whether a tile should receive a wooden resource.\n * A tile gets a resource if it has a resource-eligible terrain AND no fire symbols.\n */\nexport const shouldHaveResource = (tile: Tile): boolean => {\n const resourceType = terrainToResource(tile.type);\n return resourceType !== null && tile.crowns === 0;\n};\n\n/**\n * Creates a resource for a tile at the given position, if applicable.\n */\nexport const createResourceForTile = (\n tile: Tile,\n position: Position,\n): Resource | null => {\n const resourceType = terrainToResource(tile.type);\n if (resourceType === null || tile.crowns > 0) return null;\n return { type: resourceType, position };\n};\n\n/**\n * Destroys a resource at a given position (e.g., from fire token impact).\n * Returns the updated resources array.\n */\nexport const destroyResourceAtPosition = (\n resources: Resource[],\n position: Position,\n): Resource[] => {\n return resources.filter(\n (r) => !(r.position.x === position.x && r.position.y === position.y),\n );\n};\n\n/**\n * Counts resources by type for a player's resource list.\n */\nexport const countResourcesByType = (\n resources: Resource[],\n): Record<ResourceType, number> => {\n const counts: Record<ResourceType, number> = {\n mammoth: 0,\n fish: 0,\n mushroom: 0,\n flint: 0,\n };\n for (const r of resources) {\n counts[r.type]++;\n }\n return counts;\n};\n\n/**\n * Checks if a player has at least the required resources to spend.\n * @param resources - Player's current resources\n * @param positions - Positions of resources to spend\n * @param requiredDifferentTypes - How many different types are required\n */\nexport const canSpendResources = (\n resources: Resource[],\n positions: Position[],\n requiredDifferentTypes: number,\n): boolean => {\n const toSpend = positions.map((pos) =>\n resources.find((r) => r.position.x === pos.x && r.position.y === pos.y),\n );\n\n // All positions must have a resource\n if (toSpend.some((r) => r === undefined)) return false;\n\n // Must have the required number of different types\n const types = new Set(toSpend.map((r) => r!.type));\n return types.size >= requiredDifferentTypes;\n};\n\n/**\n * Removes resources at the given positions.\n */\nexport const spendResources = (\n resources: Resource[],\n positions: Position[],\n): Resource[] => {\n const posSet = new Set(positions.map((p) => `${p.x},${p.y}`));\n return resources.filter(\n (r) => !posSet.has(`${r.position.x},${r.position.y}`),\n );\n};\n","import type { ResourceType, TotemState } from \"@core/domain/types/origins.js\";\nimport type { Player } from \"@core/domain/types/player.js\";\nimport { countResourcesByType } from \"./resource.js\";\n\n/**\n * Bonus points for holding each totem at end of game.\n * Values from the Kingdomino Origins rules.\n */\nexport const TOTEM_BONUSES: Record<ResourceType, number> = {\n mammoth: 3,\n fish: 3,\n mushroom: 3,\n flint: 3,\n};\n\nconst RESOURCE_TYPES: ResourceType[] = [\"mammoth\", \"fish\", \"mushroom\", \"flint\"];\n\n/**\n * Determines which player holds each totem based on resource majority.\n * A player must have the strict majority (more than any other player).\n * In case of tie, the current holder keeps the totem. If no one holds it, it stays unclaimed.\n */\nexport const determineTotemHolders = (\n players: Player[],\n currentTotems: TotemState,\n): TotemState => {\n const result: TotemState = { ...currentTotems };\n\n for (const resourceType of RESOURCE_TYPES) {\n let maxCount = 0;\n let maxPlayerId: string | null = null;\n let isTied = false;\n\n for (const player of players) {\n const resources = player.resources ?? [];\n const counts = countResourcesByType(resources);\n const count = counts[resourceType];\n\n if (count > maxCount) {\n maxCount = count;\n maxPlayerId = player.id;\n isTied = false;\n } else if (count === maxCount && count > 0) {\n isTied = true;\n }\n }\n\n if (maxCount === 0) {\n // No one has this resource - totem stays unclaimed\n result[resourceType] = null;\n } else if (isTied) {\n // Tie: current holder keeps it, or stays with one of the tied players\n // Per rules: \"If there is a tie for the majority then you can choose which\n // of the players to give the totem to\" - we keep the current holder\n // If no current holder, give to first tied player\n if (\n result[resourceType] === null ||\n !players.some((p) => p.id === result[resourceType])\n ) {\n result[resourceType] = maxPlayerId;\n }\n } else {\n result[resourceType] = maxPlayerId;\n }\n }\n\n return result;\n};\n\n/**\n * Calculates totem scoring for a player in Totem mode:\n * - 1 point per remaining wooden resource\n * - Totem bonus for each totem the player holds\n */\nexport const calculateTotemScore = (\n player: Player,\n totemState: TotemState,\n): number => {\n let score = 0;\n\n // 1 point per remaining resource\n const resources = player.resources ?? [];\n score += resources.length;\n\n // Totem bonuses\n for (const resourceType of RESOURCE_TYPES) {\n if (totemState[resourceType] === player.id) {\n score += TOTEM_BONUSES[resourceType];\n }\n }\n\n return score;\n};\n","import { isAgeOfGiantsMode } from \"@core/domain/entities/ageOfGiantsHelpers.js\";\nimport { calculateTribeCavemanScore } from \"@core/domain/entities/caveman.js\";\nimport {\n checkCastleIsInMiddle,\n countDominoes,\n} from \"@core/domain/entities/kingdom.js\";\nimport {\n isOriginsMode,\n isTotemMode,\n isTribeMode,\n} from \"@core/domain/entities/originsHelpers.js\";\nimport { calculateOriginsFireBonus } from \"@core/domain/entities/originsScore.js\";\nimport { calculateQuestBonus } from \"@core/domain/entities/questScore.js\";\nimport { calculateTotemScore } from \"@core/domain/entities/totem.js\";\nimport type {\n FinalResult,\n GameWithNextStep,\n GameWithResults,\n ScoreResult,\n} from \"@core/domain/types/index.js\";\nimport { ok, type Result } from \"@utils/result.js\";\n\nexport type GetResultUseCase = (\n game: GameWithNextStep,\n scoreResult: ScoreResult[],\n) => Result<GameWithResults>;\n\nexport const getResultUseCase: GetResultUseCase = (game, scoreResult) => {\n const { rules } = game;\n const { basic, extra } = rules;\n\n const finalScoreResult = scoreResult.map((score): ScoreResult => {\n let finalScore = score.details.points;\n\n const player = game.players.find((p) => p.id === score.playerId);\n if (!player) {\n return score;\n }\n\n const { kingdom } = player;\n\n // Origins fire token scoring bonus\n if (\n isOriginsMode(game.mode.name) &&\n player.fireTokens &&\n player.fireTokens.length > 0\n ) {\n finalScore += calculateOriginsFireBonus(kingdom, player.fireTokens);\n }\n\n // Totem mode: resource points + totem bonuses\n if (isTotemMode(game.mode.name) && game.origins?.totems) {\n finalScore += calculateTotemScore(player, game.origins.totems);\n }\n\n // Tribe mode: caveman bonuses (no resource points, no totems)\n if (\n isTribeMode(game.mode.name) &&\n player.cavemen &&\n player.cavemen.length > 0\n ) {\n finalScore += calculateTribeCavemanScore(\n player.cavemen,\n kingdom,\n player.resources ?? [],\n player.fireTokens ?? [],\n );\n }\n\n // Age of Giants: quest tile bonuses\n if (isAgeOfGiantsMode(game.mode.name) && game.ageOfGiants?.questTiles) {\n const giants = player.giants ?? [];\n for (const quest of game.ageOfGiants.questTiles) {\n finalScore += calculateQuestBonus(\n quest,\n kingdom,\n giants,\n basic.maxDominoes,\n game.players.length,\n );\n }\n }\n\n if (extra.length > 0) {\n extra.forEach((extraRule) => {\n // Castle in middle: \"The middle Kingdom\" (Classic/QD) or \"Empire of Fire\" (Origins)\n if (\n extraRule.name === \"The middle Kingdom\" ||\n extraRule.name === \"Empire of Fire\"\n ) {\n const castleIsInMiddle = checkCastleIsInMiddle(kingdom);\n if (castleIsInMiddle) {\n finalScore += 10;\n }\n }\n\n // Complete kingdom: \"Harmony\" (Classic/QD) or \"Homo Habilis\" (Origins)\n if (extraRule.name === \"Harmony\" || extraRule.name === \"Homo Habilis\") {\n const totalDominoes = countDominoes(kingdom);\n const dominoLimit = basic.maxDominoes;\n const totalPlayers = game.players.length;\n const dominoesPerPlayer = dominoLimit / totalPlayers;\n if (totalDominoes === dominoesPerPlayer) {\n finalScore += 5;\n }\n }\n });\n }\n\n return {\n ...score,\n details: {\n ...score.details,\n points: finalScore,\n },\n };\n });\n\n // Order players by score, then by maxPropertiesSize (per official rules, no further tiebreaker)\n finalScoreResult.sort((a, b) => {\n if (a.details.points !== b.details.points) {\n return b.details.points - a.details.points;\n }\n return b.details.maxPropertiesSize - a.details.maxPropertiesSize;\n });\n\n const result: FinalResult[] = [];\n\n let isTie = false;\n result.push({\n playerId: finalScoreResult[0]!.playerId,\n playerName: finalScoreResult[0]!.playerName,\n details: finalScoreResult[0]!.details,\n position: 1,\n });\n\n for (let i = 1; i < finalScoreResult.length; i++) {\n const currentScore = finalScoreResult[i];\n const previousScore = finalScoreResult[i - 1];\n if (\n previousScore &&\n currentScore &&\n currentScore.details.points === previousScore.details.points &&\n currentScore.details.maxPropertiesSize ===\n previousScore.details.maxPropertiesSize\n ) {\n isTie = true;\n }\n\n if (isTie) {\n result.push({\n ...currentScore!,\n position: result[i - 1]!.position,\n });\n } else {\n result.push({\n ...currentScore!,\n position: i + 1,\n });\n }\n\n isTie = false;\n }\n\n return ok({\n ...game,\n result: result,\n });\n};\n","import {\n isAgeOfGiantsMode,\n isAgeOfGiantsQueenDominoMode,\n isFootprintDomino,\n isGiantDomino,\n} from \"@core/domain/entities/ageOfGiantsHelpers.js\";\nimport { takeFireToken } from \"@core/domain/entities/fireToken.js\";\nimport {\n findCrownsNotCoveredByGiants,\n playerHasGiant,\n} from \"@core/domain/entities/giant.js\";\nimport {\n calculateDominoPosition,\n placeDomino,\n} from \"@core/domain/entities/kingdom.js\";\nimport {\n allLordsHavePlayed,\n canPlaceAndDominoPickedIsDefined,\n nextLordWithAction,\n} from \"@core/domain/entities/lord.js\";\nimport {\n isOriginsMode,\n isResourceMode,\n} from \"@core/domain/entities/originsHelpers.js\";\nimport { createResourceForTile } from \"@core/domain/entities/resource.js\";\nimport { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport {\n type GameState,\n type GameStateResult,\n type GameWithNextAction,\n gameSteps,\n type NextAction,\n type NextStep,\n} from \"@core/domain/types/game.js\";\nimport type { Position, Rotation } from \"@core/domain/types/kingdom.js\";\nimport type { PendingFireToken, Resource } from \"@core/domain/types/origins.js\";\nimport {\n type PlayerActions,\n playerActions,\n} from \"@core/domain/types/player.js\";\nimport { err, isErr, isOk, ok } from \"@utils/result.js\";\n\nexport type PlaceDominoUseCase = (\n game: GameWithNextAction,\n lordId: string,\n position: Position,\n rotation: Rotation,\n) => GameStateResult;\n\n/**\n * Finds the volcano tile position(s) in a just-placed domino.\n * Returns the first volcano tile with craters, or undefined.\n */\nconst findVolcanoInDomino = (\n game: GameWithNextAction,\n position: Position,\n rotation: Rotation,\n): { craters: number; volcanoPosition: Position } | undefined => {\n const lord = game.lords.find((l) => l.id === game.nextAction.nextLord);\n if (!lord?.dominoPicked) return undefined;\n\n const [first, second] = calculateDominoPosition(\n position,\n rotation,\n lord.dominoPicked,\n );\n\n for (const placed of [first, second]) {\n if (\n placed.tile.type === \"volcano\" &&\n placed.tile.volcanoCraters &&\n placed.tile.volcanoCraters > 0\n ) {\n return {\n craters: placed.tile.volcanoCraters,\n volcanoPosition: placed.position,\n };\n }\n }\n return undefined;\n};\n\nexport const placeDominoUseCase: PlaceDominoUseCase = (\n game,\n lordId,\n position,\n rotation,\n) => {\n const nextAction = game.nextAction;\n\n const currentLord = game.lords.find(\n (lord) => lord.id === nextAction.nextLord,\n );\n\n if (!currentLord) {\n return err(ErrorCode.LORD_NOT_FOUND);\n }\n\n if (currentLord.id !== lordId) {\n return err(ErrorCode.NOT_YOUR_TURN);\n }\n\n if (!canPlaceAndDominoPickedIsDefined(currentLord)) {\n return err(ErrorCode.CANNOT_PLACE);\n }\n\n const domino = currentLord.dominoPicked;\n\n const currentPlayer = game.players.find(\n (player) => player.id === currentLord.playerId,\n );\n\n if (!currentPlayer) {\n return err(ErrorCode.PLAYER_NOT_FOUND);\n }\n\n const updatedKingdom = placeDomino(\n currentPlayer.kingdom,\n position,\n rotation,\n domino,\n game.rules.basic.maxKingdomSize,\n );\n\n if (isErr(updatedKingdom)) {\n return updatedKingdom;\n }\n\n // Collect resources from placed tiles (Totem/Tribe modes)\n const newResources: Resource[] = [];\n if (isResourceMode(game.mode.name)) {\n const [first, second] = calculateDominoPosition(position, rotation, domino);\n for (const placed of [first, second]) {\n const resource = createResourceForTile(placed.tile, placed.position);\n if (resource) {\n newResources.push(resource);\n }\n }\n }\n\n const updatedPlayers = game.players.map((player) => {\n if (player.id === currentPlayer.id) {\n const updated = { ...player, kingdom: updatedKingdom.value };\n if (newResources.length > 0 && updated.resources) {\n updated.resources = [...updated.resources, ...newResources];\n }\n return updated;\n }\n return player;\n });\n\n const maxTurns = game.rules.basic.maxTurns;\n const currentTurn = game.turn;\n const isLastTurn = currentTurn === maxTurns;\n\n const updatedLords = game.lords.map((lord) => {\n if (lord.id === currentLord.id) {\n if (isLastTurn) {\n return {\n ...lord,\n turnEnded: true,\n hasPlace: true,\n };\n }\n return {\n ...lord,\n hasPlace: true,\n };\n }\n return lord;\n });\n\n let updatedGame: GameState;\n\n const resultStep: NextStep = {\n type: \"step\",\n step: gameSteps.result,\n };\n\n const isQueenDomino = game.mode.name === \"QueenDomino\";\n const isOrigins = isOriginsMode(game.mode.name);\n const isAoG = isAgeOfGiantsMode(game.mode.name);\n const isAoGQD = isAgeOfGiantsQueenDominoMode(game.mode.name);\n\n if (\n isLastTurn &&\n allLordsHavePlayed(updatedLords) &&\n !isQueenDomino &&\n !isOrigins &&\n !isAoG\n ) {\n updatedGame = {\n ...game,\n lords: updatedLords,\n nextAction: resultStep,\n players: updatedPlayers,\n };\n } else if (isQueenDomino && !isLastTurn) {\n // In QueenDomino, after placing a domino, the same lord gets optional actions\n updatedGame = {\n ...game,\n lords: updatedLords,\n nextAction: {\n type: \"action\",\n nextLord: currentLord.id,\n nextAction: playerActions.placeKnight,\n },\n players: updatedPlayers,\n };\n } else if (isQueenDomino && isLastTurn) {\n // Last turn in QueenDomino: optional actions before checking if all lords done\n const queenDominoAction: NextAction = {\n type: \"action\",\n nextLord: currentLord.id,\n nextAction: playerActions.placeKnight,\n };\n updatedGame = {\n ...game,\n lords: updatedLords,\n nextAction: queenDominoAction,\n players: updatedPlayers,\n };\n } else if (isOrigins) {\n // Origins: check for volcano to grant fire token\n const volcano = findVolcanoInDomino(game, position, rotation);\n let updatedOrigins = game.origins;\n\n if (volcano && updatedOrigins) {\n const tokenResult = takeFireToken(\n updatedOrigins.fireTokenPool,\n volcano.craters,\n );\n if (isOk(tokenResult)) {\n // Grant fire token and set pending for placement\n const pendingFireToken: PendingFireToken = {\n fires: tokenResult.value.fires,\n volcanoPosition: volcano.volcanoPosition,\n };\n updatedOrigins = {\n ...updatedOrigins,\n fireTokenPool: tokenResult.value.updatedPool,\n pendingFireToken,\n };\n\n // Route to placeFireToken action\n updatedGame = {\n ...game,\n lords: updatedLords,\n players: updatedPlayers,\n origins: updatedOrigins,\n nextAction: {\n type: \"action\",\n nextLord: currentLord.id,\n nextAction: playerActions.placeFireToken,\n },\n };\n } else {\n // Pool empty for this crater type - skip fire token, go to pickDomino\n if (isLastTurn && allLordsHavePlayed(updatedLords)) {\n updatedGame = {\n ...game,\n lords: updatedLords,\n nextAction: resultStep,\n players: updatedPlayers,\n origins: updatedOrigins,\n };\n } else if (isLastTurn) {\n updatedGame = {\n ...game,\n lords: updatedLords,\n nextAction: resultStep,\n players: updatedPlayers,\n origins: updatedOrigins,\n };\n } else {\n updatedGame = {\n ...game,\n lords: updatedLords,\n nextAction: nextLordWithAction(updatedLords) as NextAction,\n players: updatedPlayers,\n origins: updatedOrigins,\n };\n }\n }\n } else {\n // No volcano placed - skip straight to next action\n if (isLastTurn && allLordsHavePlayed(updatedLords)) {\n updatedGame = {\n ...game,\n lords: updatedLords,\n nextAction: resultStep,\n players: updatedPlayers,\n };\n } else if (isLastTurn) {\n updatedGame = {\n ...game,\n lords: updatedLords,\n nextAction: resultStep,\n players: updatedPlayers,\n };\n } else {\n updatedGame = {\n ...game,\n lords: updatedLords,\n nextAction: nextLordWithAction(updatedLords) as NextAction,\n players: updatedPlayers,\n };\n }\n }\n } else if (isAoG) {\n // Age of Giants: check for giant/footprint domino effects\n const currentPlayer = updatedPlayers.find(\n (p) => p.id === currentLord.playerId,\n );\n const isGiant = isGiantDomino(domino);\n const isFootprint = isFootprintDomino(domino);\n\n let aogAction: PlayerActions | null = null;\n\n if (isGiant) {\n // Giant domino: must place giant on a crown (mandatory)\n // But auto-skip if player has no uncovered crowns or pool is empty\n const hasUncoveredCrowns =\n currentPlayer &&\n findCrownsNotCoveredByGiants(\n currentPlayer.kingdom,\n currentPlayer.giants ?? [],\n ).length > 0;\n const poolAvailable = (game.ageOfGiants?.giantPool ?? 0) > 0;\n\n if (hasUncoveredCrowns && poolAvailable) {\n aogAction = playerActions.placeGiant;\n }\n } else if (isFootprint) {\n // Footprint domino: may send a giant to opponent (optional)\n // But only if player has a giant in their kingdom\n if (currentPlayer && playerHasGiant(currentPlayer)) {\n aogAction = playerActions.sendGiant;\n }\n }\n\n if (aogAction) {\n updatedGame = {\n ...game,\n lords: updatedLords,\n players: updatedPlayers,\n nextAction: {\n type: \"action\",\n nextLord: currentLord.id,\n nextAction: aogAction,\n },\n };\n } else if (isAoGQD) {\n // No AoG action but still need QueenDomino actions\n updatedGame = {\n ...game,\n lords: updatedLords,\n players: updatedPlayers,\n nextAction: {\n type: \"action\",\n nextLord: currentLord.id,\n nextAction: playerActions.placeKnight,\n },\n };\n } else if (isLastTurn && allLordsHavePlayed(updatedLords)) {\n updatedGame = {\n ...game,\n lords: updatedLords,\n nextAction: resultStep,\n players: updatedPlayers,\n };\n } else {\n updatedGame = {\n ...game,\n lords: updatedLords,\n nextAction: nextLordWithAction(updatedLords) as NextAction,\n players: updatedPlayers,\n };\n }\n } else {\n updatedGame = {\n ...game,\n lords: updatedLords,\n nextAction: nextLordWithAction(updatedLords) as NextAction,\n players: updatedPlayers,\n };\n }\n\n return ok(updatedGame);\n};\n","import { isValidFireTokenPosition } from \"@core/domain/entities/fireToken.js\";\nimport {\n allLordsHavePlayed,\n nextLordWithAction,\n} from \"@core/domain/entities/lord.js\";\nimport { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport {\n type GameState,\n type GameStateResult,\n type GameWithNextAction,\n gameSteps,\n type NextAction,\n} from \"@core/domain/types/game.js\";\nimport type { Position } from \"@core/domain/types/kingdom.js\";\nimport type { PlacedFireToken } from \"@core/domain/types/origins.js\";\nimport { err, ok } from \"@utils/result.js\";\n\nexport type PlaceFireTokenUseCase = (\n game: GameWithNextAction,\n lordId: string,\n position: Position,\n) => GameStateResult;\n\nexport const placeFireTokenUseCase: PlaceFireTokenUseCase = (\n game,\n lordId,\n position,\n) => {\n const currentLord = game.lords.find(\n (lord) => lord.id === game.nextAction.nextLord,\n );\n\n if (!currentLord) {\n return err(ErrorCode.LORD_NOT_FOUND);\n }\n\n if (currentLord.id !== lordId) {\n return err(ErrorCode.NOT_YOUR_TURN);\n }\n\n if (!game.origins?.pendingFireToken) {\n return err(ErrorCode.NO_PENDING_FIRE_TOKEN);\n }\n\n const { fires, volcanoPosition } = game.origins.pendingFireToken;\n\n const currentPlayer = game.players.find(\n (player) => player.id === currentLord.playerId,\n );\n\n if (!currentPlayer) {\n return err(ErrorCode.PLAYER_NOT_FOUND);\n }\n\n const existingTokens = currentPlayer.fireTokens ?? [];\n\n if (\n !isValidFireTokenPosition(\n currentPlayer.kingdom,\n position,\n volcanoPosition,\n fires,\n existingTokens,\n )\n ) {\n return err(ErrorCode.FIRE_TOKEN_INVALID_POSITION);\n }\n\n // Place the fire token\n const newToken: PlacedFireToken = { fires, position };\n const updatedFireTokens = [...existingTokens, newToken];\n\n // Destroy resource at position if any (Totem/Tribe modes)\n let updatedResources = currentPlayer.resources;\n if (updatedResources) {\n updatedResources = updatedResources.filter(\n (r) => !(r.position.x === position.x && r.position.y === position.y),\n );\n }\n\n // Destroy caveman at position if any (Tribe mode)\n let updatedCavemen = currentPlayer.cavemen;\n if (updatedCavemen) {\n updatedCavemen = updatedCavemen.filter(\n (c) => !(c.position.x === position.x && c.position.y === position.y),\n );\n }\n\n const updatedPlayers = game.players.map((player) => {\n if (player.id === currentPlayer.id) {\n return {\n ...player,\n fireTokens: updatedFireTokens,\n ...(updatedResources !== undefined && { resources: updatedResources }),\n ...(updatedCavemen !== undefined && { cavemen: updatedCavemen }),\n };\n }\n return player;\n });\n\n // Clear pending fire token\n const updatedOrigins = {\n ...game.origins,\n pendingFireToken: undefined,\n };\n\n // Determine next action\n const isLastTurn = game.turn === game.rules.basic.maxTurns;\n\n let nextGameAction: GameState;\n\n if (isLastTurn && allLordsHavePlayed(game.lords)) {\n nextGameAction = {\n ...game,\n players: updatedPlayers,\n origins: updatedOrigins,\n nextAction: { type: \"step\", step: gameSteps.result },\n };\n } else if (isLastTurn) {\n nextGameAction = {\n ...game,\n players: updatedPlayers,\n origins: updatedOrigins,\n nextAction: { type: \"step\", step: gameSteps.result },\n };\n } else {\n nextGameAction = {\n ...game,\n players: updatedPlayers,\n origins: updatedOrigins,\n nextAction: nextLordWithAction(game.lords) as NextAction,\n };\n }\n\n return ok(nextGameAction);\n};\n","import { isAgeOfGiantsQueenDominoMode } from \"@core/domain/entities/ageOfGiantsHelpers.js\";\nimport {\n placeGiantOnCrown,\n takeFromGiantPool,\n} from \"@core/domain/entities/giant.js\";\nimport {\n allLordsHavePlayed,\n nextAgeOfGiantsAction,\n nextLordWithAction,\n} from \"@core/domain/entities/lord.js\";\nimport { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport {\n type GameStateResult,\n type GameWithNextAction,\n gameSteps,\n type NextAction,\n} from \"@core/domain/types/game.js\";\nimport type { Position } from \"@core/domain/types/kingdom.js\";\nimport { playerActions } from \"@core/domain/types/player.js\";\nimport { err, isErr, ok } from \"@utils/result.js\";\n\nexport type PlaceGiantUseCase = (\n game: GameWithNextAction,\n lordId: string,\n position: Position,\n) => GameStateResult;\n\nexport const placeGiantUseCase: PlaceGiantUseCase = (\n game,\n lordId,\n position,\n) => {\n const currentAction = game.nextAction;\n\n if (currentAction.nextAction !== playerActions.placeGiant) {\n return err(ErrorCode.INVALID_OPTIONAL_ACTION);\n }\n\n if (currentAction.nextLord !== lordId) {\n return err(ErrorCode.NOT_YOUR_TURN);\n }\n\n if (!game.ageOfGiants) {\n return err(ErrorCode.NOT_AOG_MODE);\n }\n\n // Take from giant pool\n const poolResult = takeFromGiantPool(game.ageOfGiants.giantPool);\n if (isErr(poolResult)) {\n return poolResult;\n }\n\n const currentLord = game.lords.find((l) => l.id === lordId);\n if (!currentLord) {\n return err(ErrorCode.LORD_NOT_FOUND);\n }\n\n const currentPlayer = game.players.find((p) => p.id === currentLord.playerId);\n if (!currentPlayer) {\n return err(ErrorCode.PLAYER_NOT_FOUND);\n }\n\n // Place giant on the chosen crown\n const placeResult = placeGiantOnCrown(currentPlayer, position);\n if (isErr(placeResult)) {\n return placeResult;\n }\n\n const updatedPlayers = game.players.map((p) =>\n p.id === currentPlayer.id ? placeResult.value : p,\n );\n\n const updatedAoG = {\n ...game.ageOfGiants,\n giantPool: poolResult.value,\n };\n\n // Determine next action\n const isAoGQD = isAgeOfGiantsQueenDominoMode(game.mode.name);\n const nextAction = nextAgeOfGiantsAction(playerActions.placeGiant, isAoGQD);\n\n if (nextAction === playerActions.pickDomino) {\n // No more optional actions — advance to next lord or result\n const isLastTurn = game.turn === game.rules.basic.maxTurns;\n if (isLastTurn && allLordsHavePlayed(game.lords)) {\n return ok({\n ...game,\n players: updatedPlayers,\n ageOfGiants: updatedAoG,\n nextAction: { type: \"step\", step: gameSteps.result },\n });\n }\n return ok({\n ...game,\n players: updatedPlayers,\n ageOfGiants: updatedAoG,\n nextAction: nextLordWithAction(game.lords) as NextAction,\n });\n }\n\n // More optional actions (e.g., placeKnight in AoG-QD)\n return ok({\n ...game,\n players: updatedPlayers,\n ageOfGiants: updatedAoG,\n nextAction: {\n type: \"action\",\n nextLord: lordId,\n nextAction: nextAction,\n },\n });\n};\n","import type { Kingdom, Position } from \"@core/domain/types/kingdom.js\";\nimport type { Knight, Player } from \"@core/domain/types/player.js\";\nimport { addCoins, MAX_KNIGHTS } from \"./economy.js\";\n\n/**\n * Count construction squares in the contiguous territory containing the given position.\n * Uses BFS flood-fill on same terrain type.\n */\nexport const countConstructionSquaresInTerritory = (\n kingdom: Kingdom,\n position: Position,\n): number => {\n const rows = kingdom.length;\n const cols = kingdom[0]?.length ?? 0;\n const startTile = kingdom[position.y]?.[position.x];\n\n if (!startTile || startTile.type === \"empty\" || startTile.type === \"castle\") {\n return 0;\n }\n\n const terrainType = startTile.type;\n const visited: boolean[][] = kingdom.map((row) => row.map(() => false));\n const queue: [number, number][] = [[position.x, position.y]];\n visited[position.y]![position.x] = true;\n let count = 0;\n\n const directions = [\n [-1, 0],\n [1, 0],\n [0, -1],\n [0, 1],\n ];\n\n while (queue.length > 0) {\n const [cx, cy] = queue.pop()!;\n const tile = kingdom[cy]![cx]!;\n\n if (\n tile.type !== \"empty\" &&\n tile.type !== \"castle\" &&\n \"hasConstructionSquare\" in tile &&\n tile.hasConstructionSquare\n ) {\n count++;\n }\n\n for (const [dx, dy] of directions) {\n const nx = cx + (dx as number);\n const ny = cy + (dy as number);\n if (\n nx >= 0 &&\n ny >= 0 &&\n nx < cols &&\n ny < rows &&\n !visited[ny]![nx] &&\n kingdom[ny]![nx]!.type === terrainType\n ) {\n visited[ny]![nx] = true;\n queue.push([nx, ny]);\n }\n }\n }\n\n return count;\n};\n\n/**\n * Get the terrain type at a position to identify the territory.\n */\nconst getTerritoryTerrain = (\n kingdom: Kingdom,\n position: Position,\n): string | null => {\n const tile = kingdom[position.y]?.[position.x];\n if (!tile || tile.type === \"empty\" || tile.type === \"castle\") return null;\n return tile.type;\n};\n\n/**\n * Check if a territory (identified by BFS from position) already has a knight.\n */\nconst territoryHasKnight = (\n kingdom: Kingdom,\n position: Position,\n knights: Knight[],\n): boolean => {\n const terrain = getTerritoryTerrain(kingdom, position);\n if (!terrain) return false;\n\n // BFS to find all positions in this territory\n const rows = kingdom.length;\n const cols = kingdom[0]?.length ?? 0;\n const visited: boolean[][] = kingdom.map((row) => row.map(() => false));\n const queue: [number, number][] = [[position.x, position.y]];\n visited[position.y]![position.x] = true;\n const territoryPositions = new Set<string>();\n\n const directions = [\n [-1, 0],\n [1, 0],\n [0, -1],\n [0, 1],\n ];\n\n while (queue.length > 0) {\n const [cx, cy] = queue.pop()!;\n territoryPositions.add(`${cx},${cy}`);\n\n for (const [dx, dy] of directions) {\n const nx = cx + (dx as number);\n const ny = cy + (dy as number);\n if (\n nx >= 0 &&\n ny >= 0 &&\n nx < cols &&\n ny < rows &&\n !visited[ny]![nx] &&\n kingdom[ny]![nx]!.type === terrain\n ) {\n visited[ny]![nx] = true;\n queue.push([nx, ny]);\n }\n }\n }\n\n return knights.some((k) =>\n territoryPositions.has(`${k.position.x},${k.position.y}`),\n );\n};\n\nexport const canPlaceKnight = (\n player: Player,\n kingdom: Kingdom,\n position: Position,\n): boolean => {\n const knights = player.knights ?? [];\n if (knights.length >= MAX_KNIGHTS) return false;\n\n const tile = kingdom[position.y]?.[position.x];\n if (!tile || tile.type === \"empty\" || tile.type === \"castle\") return false;\n\n if (territoryHasKnight(kingdom, position, knights)) return false;\n\n return true;\n};\n\nexport const placeKnight = (\n player: Player,\n kingdom: Kingdom,\n position: Position,\n): Player => {\n const knight: Knight = { playerId: player.id, position };\n const knights = [...(player.knights ?? []), knight];\n const taxAmount = countConstructionSquaresInTerritory(kingdom, position);\n const updatedPlayer = addCoins({ ...player, knights }, taxAmount);\n\n return updatedPlayer;\n};\n","import { canPlaceKnight, placeKnight } from \"@core/domain/entities/knight.js\";\nimport { nextQueenDominoAction } from \"@core/domain/entities/lord.js\";\nimport { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport type {\n GameStateResult,\n GameWithNextAction,\n} from \"@core/domain/types/game.js\";\nimport type { Position } from \"@core/domain/types/kingdom.js\";\nimport { playerActions } from \"@core/domain/types/player.js\";\nimport { err, ok } from \"@utils/result.js\";\n\nexport type PlaceKnightUseCase = (\n game: GameWithNextAction,\n lordId: string,\n position: Position,\n) => GameStateResult;\n\nexport const placeKnightUseCase: PlaceKnightUseCase = (\n game,\n lordId,\n position,\n) => {\n const currentAction = game.nextAction;\n\n if (currentAction.nextLord !== lordId) {\n return err(ErrorCode.NOT_YOUR_TURN);\n }\n\n if (currentAction.nextAction !== playerActions.placeKnight) {\n return err(ErrorCode.INVALID_OPTIONAL_ACTION);\n }\n\n const currentLord = game.lords.find((l) => l.id === lordId);\n if (!currentLord) return err(ErrorCode.LORD_NOT_FOUND);\n\n const currentPlayer = game.players.find((p) => p.id === currentLord.playerId);\n if (!currentPlayer) return err(ErrorCode.PLAYER_NOT_FOUND);\n\n if (!canPlaceKnight(currentPlayer, currentPlayer.kingdom, position)) {\n return err(ErrorCode.CANNOT_PLACE_KNIGHT);\n }\n\n const updatedPlayer = placeKnight(\n currentPlayer,\n currentPlayer.kingdom,\n position,\n );\n\n const updatedPlayers = game.players.map((p) =>\n p.id === currentPlayer.id ? updatedPlayer : p,\n );\n\n const nextAction = nextQueenDominoAction(playerActions.placeKnight);\n\n return ok({\n ...game,\n players: updatedPlayers,\n nextAction: {\n type: \"action\",\n nextLord: lordId,\n nextAction: nextAction,\n },\n });\n};\n","import {\n isValidCavemanPosition,\n takeCavemanFromDrawPile,\n takeCavemanFromVisible,\n} from \"@core/domain/entities/caveman.js\";\nimport {\n allLordsHavePlayed,\n nextLordWithAction,\n} from \"@core/domain/entities/lord.js\";\nimport {\n canSpendResources,\n spendResources,\n} from \"@core/domain/entities/resource.js\";\nimport { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport {\n type GameState,\n type GameStateResult,\n type GameWithNextAction,\n gameSteps,\n type NextAction,\n} from \"@core/domain/types/game.js\";\nimport type { Position } from \"@core/domain/types/kingdom.js\";\nimport { err, ok } from \"@utils/result.js\";\n\nexport type RecruitCavemanUseCase = (\n game: GameWithNextAction,\n lordId: string,\n cavemanId: number,\n position: Position,\n resourcePositions: Position[],\n) => GameStateResult;\n\nexport const recruitCavemanUseCase: RecruitCavemanUseCase = (\n game,\n lordId,\n cavemanId,\n position,\n resourcePositions,\n) => {\n const currentLord = game.lords.find(\n (lord) => lord.id === game.nextAction.nextLord,\n );\n\n if (!currentLord) {\n return err(ErrorCode.LORD_NOT_FOUND);\n }\n\n if (currentLord.id !== lordId) {\n return err(ErrorCode.NOT_YOUR_TURN);\n }\n\n if (!game.origins?.caveBoard) {\n return err(ErrorCode.NOT_TRIBE_MODE);\n }\n\n const currentPlayer = game.players.find((p) => p.id === currentLord.playerId);\n\n if (!currentPlayer) {\n return err(ErrorCode.PLAYER_NOT_FOUND);\n }\n\n const resources = currentPlayer.resources ?? [];\n const fireTokens = currentPlayer.fireTokens ?? [];\n const cavemen = currentPlayer.cavemen ?? [];\n\n // Determine if taking from visible (2 different resources) or draw pile (4 different)\n const isFromVisible = game.origins.caveBoard.visible.some(\n (c) => c.id === cavemanId,\n );\n const isFromDrawPile = game.origins.caveBoard.drawPile.some(\n (c) => c.id === cavemanId,\n );\n\n if (!isFromVisible && !isFromDrawPile) {\n return err(ErrorCode.CAVEMAN_NOT_FOUND);\n }\n\n const requiredDifferentTypes = isFromVisible ? 2 : 4;\n const requiredResourceCount = isFromVisible ? 2 : 4;\n\n if (resourcePositions.length !== requiredResourceCount) {\n return err(ErrorCode.INSUFFICIENT_RESOURCES);\n }\n\n if (\n !canSpendResources(resources, resourcePositions, requiredDifferentTypes)\n ) {\n return err(ErrorCode.INSUFFICIENT_RESOURCES);\n }\n\n // Validate caveman placement position\n if (\n !isValidCavemanPosition(\n currentPlayer.kingdom,\n position,\n fireTokens,\n resources,\n cavemen,\n )\n ) {\n return err(ErrorCode.INVALID_CAVEMAN_PLACEMENT);\n }\n\n // Take caveman from board\n let cavemanResult: ReturnType<typeof takeCavemanFromVisible>;\n if (isFromVisible) {\n cavemanResult = takeCavemanFromVisible(game.origins.caveBoard, cavemanId);\n } else {\n cavemanResult = takeCavemanFromDrawPile(game.origins.caveBoard, cavemanId);\n }\n\n if (!cavemanResult) {\n return err(ErrorCode.CAVEMAN_NOT_FOUND);\n }\n\n // Spend resources\n const updatedResources = spendResources(resources, resourcePositions);\n\n // Place caveman\n const updatedCavemen = [\n ...cavemen,\n { caveman: cavemanResult.caveman, position },\n ];\n\n const updatedPlayers = game.players.map((player) => {\n if (player.id === currentPlayer.id) {\n return {\n ...player,\n resources: updatedResources,\n cavemen: updatedCavemen,\n };\n }\n return player;\n });\n\n const updatedOrigins = {\n ...game.origins,\n caveBoard: cavemanResult.updatedBoard,\n };\n\n // Mark lord turn as ended and advance\n const updatedLords = game.lords.map((lord) => {\n if (lord.id === currentLord.id) {\n return { ...lord, turnEnded: true };\n }\n return lord;\n });\n\n const isLastTurn = game.turn === game.rules.basic.maxTurns;\n\n let nextGameAction: GameState;\n\n if (isLastTurn && allLordsHavePlayed(updatedLords)) {\n nextGameAction = {\n ...game,\n players: updatedPlayers,\n lords: updatedLords,\n origins: updatedOrigins,\n nextAction: { type: \"step\", step: gameSteps.result },\n };\n } else {\n nextGameAction = {\n ...game,\n players: updatedPlayers,\n lords: updatedLords,\n origins: updatedOrigins,\n nextAction: nextLordWithAction(updatedLords) as NextAction,\n };\n }\n\n return ok(nextGameAction);\n};\n","import { isAgeOfGiantsQueenDominoMode } from \"@core/domain/entities/ageOfGiantsHelpers.js\";\nimport { sendGiantToOpponent } from \"@core/domain/entities/giant.js\";\nimport {\n allLordsHavePlayed,\n nextAgeOfGiantsAction,\n nextLordWithAction,\n} from \"@core/domain/entities/lord.js\";\nimport { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport {\n type GameStateResult,\n type GameWithNextAction,\n gameSteps,\n type NextAction,\n} from \"@core/domain/types/game.js\";\nimport type { Position } from \"@core/domain/types/kingdom.js\";\nimport { playerActions } from \"@core/domain/types/player.js\";\nimport { err, isErr, ok } from \"@utils/result.js\";\n\nexport type SendGiantUseCase = (\n game: GameWithNextAction,\n lordId: string,\n giantIndex: number,\n targetPlayerId: string,\n targetCrownPosition: Position,\n) => GameStateResult;\n\nexport const sendGiantUseCase: SendGiantUseCase = (\n game,\n lordId,\n giantIndex,\n targetPlayerId,\n targetCrownPosition,\n) => {\n const currentAction = game.nextAction;\n\n if (currentAction.nextAction !== playerActions.sendGiant) {\n return err(ErrorCode.INVALID_OPTIONAL_ACTION);\n }\n\n if (currentAction.nextLord !== lordId) {\n return err(ErrorCode.NOT_YOUR_TURN);\n }\n\n if (!game.ageOfGiants) {\n return err(ErrorCode.NOT_AOG_MODE);\n }\n\n const currentLord = game.lords.find((l) => l.id === lordId);\n if (!currentLord) {\n return err(ErrorCode.LORD_NOT_FOUND);\n }\n\n const sourcePlayer = game.players.find((p) => p.id === currentLord.playerId);\n if (!sourcePlayer) {\n return err(ErrorCode.PLAYER_NOT_FOUND);\n }\n\n const targetPlayer = game.players.find((p) => p.id === targetPlayerId);\n if (!targetPlayer) {\n return err(ErrorCode.PLAYER_NOT_FOUND);\n }\n\n if (sourcePlayer.id === targetPlayer.id) {\n return err(ErrorCode.INVALID_GIANT_PLACEMENT);\n }\n\n const result = sendGiantToOpponent(\n sourcePlayer,\n targetPlayer,\n giantIndex,\n targetCrownPosition,\n );\n if (isErr(result)) {\n return result;\n }\n\n const updatedPlayers = game.players.map((p) => {\n if (p.id === result.value.source.id) return result.value.source;\n if (p.id === result.value.target.id) return result.value.target;\n return p;\n });\n\n // Determine next action\n const isAoGQD = isAgeOfGiantsQueenDominoMode(game.mode.name);\n const nextAction = nextAgeOfGiantsAction(playerActions.sendGiant, isAoGQD);\n\n if (nextAction === playerActions.pickDomino) {\n const isLastTurn = game.turn === game.rules.basic.maxTurns;\n if (isLastTurn && allLordsHavePlayed(game.lords)) {\n return ok({\n ...game,\n players: updatedPlayers,\n nextAction: { type: \"step\", step: gameSteps.result },\n });\n }\n return ok({\n ...game,\n players: updatedPlayers,\n nextAction: nextLordWithAction(game.lords) as NextAction,\n });\n }\n\n return ok({\n ...game,\n players: updatedPlayers,\n nextAction: {\n type: \"action\",\n nextLord: lordId,\n nextAction: nextAction,\n },\n });\n};\n","import { isAgeOfGiantsQueenDominoMode } from \"@core/domain/entities/ageOfGiantsHelpers.js\";\nimport {\n allLordsHavePlayed,\n nextAgeOfGiantsAction,\n nextLordWithAction,\n nextOriginsAction,\n nextQueenDominoAction,\n} from \"@core/domain/entities/lord.js\";\nimport { isTribeMode } from \"@core/domain/entities/originsHelpers.js\";\nimport { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport {\n type GameStateResult,\n type GameWithNextAction,\n gameSteps,\n type NextAction,\n} from \"@core/domain/types/game.js\";\nimport { playerActions } from \"@core/domain/types/player.js\";\nimport { err, ok } from \"@utils/result.js\";\n\nexport type SkipOptionalActionUseCase = (\n game: GameWithNextAction,\n lordId: string,\n) => GameStateResult;\n\nexport const skipOptionalActionUseCase: SkipOptionalActionUseCase = (\n game,\n lordId,\n) => {\n const currentAction = game.nextAction;\n\n if (currentAction.nextLord !== lordId) {\n return err(ErrorCode.NOT_YOUR_TURN);\n }\n\n const action = currentAction.nextAction;\n\n // Queendomino optional actions\n const isQueenDominoOptional =\n action === playerActions.placeKnight ||\n action === playerActions.constructBuilding ||\n action === playerActions.useDragon;\n\n // Origins optional actions\n const isOriginsOptional =\n action === playerActions.placeFireToken ||\n action === playerActions.recruitCaveman;\n\n // Age of Giants optional actions (sendGiant is optional; placeGiant is mandatory but auto-skipped when no crowns)\n const isAoGOptional =\n action === playerActions.sendGiant || action === playerActions.placeGiant;\n\n if (!isQueenDominoOptional && !isOriginsOptional && !isAoGOptional) {\n return err(ErrorCode.INVALID_OPTIONAL_ACTION);\n }\n\n if (isAoGOptional) {\n return handleAoGSkip(game, lordId, action);\n }\n\n if (isOriginsOptional) {\n return handleOriginsSkip(game, lordId, action);\n }\n\n // Queendomino skip logic\n const nextAction = nextQueenDominoAction(action);\n\n if (nextAction === playerActions.pickDomino) {\n return advanceToNextLordOrResult(game);\n }\n\n return ok({\n ...game,\n nextAction: {\n type: \"action\",\n nextLord: lordId,\n nextAction: nextAction,\n },\n });\n};\n\nconst handleOriginsSkip = (\n game: GameWithNextAction,\n lordId: string,\n action: string,\n): GameStateResult => {\n // Clear pending fire token if skipping fire token placement\n let updatedOrigins = game.origins;\n if (\n action === playerActions.placeFireToken &&\n updatedOrigins?.pendingFireToken\n ) {\n updatedOrigins = {\n ...updatedOrigins,\n pendingFireToken: undefined,\n };\n }\n\n const tribe = isTribeMode(game.mode.name);\n const nextAction = nextOriginsAction(\n action as typeof playerActions.placeFireToken,\n tribe,\n );\n\n const updatedGame = {\n ...game,\n ...(updatedOrigins !== undefined && { origins: updatedOrigins }),\n };\n\n // pickDomino means we're done with pre-pick optional actions\n if (nextAction === playerActions.pickDomino) {\n return advanceToNextLordOrResult(updatedGame);\n }\n\n // recruitCaveman is the final optional action in Tribe mode\n // The turn transition already happened in chooseDomino, just advance\n if (action === playerActions.recruitCaveman) {\n return advanceToNextLordOrResult(updatedGame);\n }\n\n return ok({\n ...updatedGame,\n nextAction: {\n type: \"action\",\n nextLord: lordId,\n nextAction: nextAction,\n },\n });\n};\n\nconst handleAoGSkip = (\n game: GameWithNextAction,\n lordId: string,\n action: string,\n): GameStateResult => {\n const isAoGQD = isAgeOfGiantsQueenDominoMode(game.mode.name);\n const nextAction = nextAgeOfGiantsAction(\n action as typeof playerActions.placeGiant | typeof playerActions.sendGiant,\n isAoGQD,\n );\n\n if (nextAction === playerActions.pickDomino) {\n return advanceToNextLordOrResult(game);\n }\n\n // More optional actions (e.g., QD actions in AoG-QD mode)\n return ok({\n ...game,\n nextAction: {\n type: \"action\",\n nextLord: lordId,\n nextAction: nextAction,\n },\n });\n};\n\nconst advanceToNextLordOrResult = (\n game: GameWithNextAction,\n): GameStateResult => {\n const maxTurns = game.rules.basic.maxTurns;\n const isLastTurn = game.turn === maxTurns;\n\n if (isLastTurn && allLordsHavePlayed(game.lords)) {\n return ok({\n ...game,\n nextAction: { type: \"step\", step: gameSteps.result },\n });\n }\n\n return ok({\n ...game,\n nextAction: nextLordWithAction(game.lords) as NextAction,\n });\n};\n","import { isAgeOfGiantsQueenDominoMode } from \"@core/domain/entities/ageOfGiantsHelpers.js\";\nimport { createBuildersBoard } from \"@core/domain/entities/building.js\";\nimport { createCaveBoard } from \"@core/domain/entities/caveman.js\";\nimport { createLord } from \"@core/domain/entities/lord\";\nimport { isTribeMode } from \"@core/domain/entities/originsHelpers.js\";\nimport type {\n GameWithNextAction,\n GameWithNextStep,\n NextAction,\n} from \"@core/domain/types/game.js\";\nimport type { Lord } from \"@core/domain/types/lord.js\";\nimport { playerActions } from \"@core/domain/types/player.js\";\nimport type { ShuffleMethod } from \"@core/portServerside/shuffleMethod.js\";\nimport type { UuidMethod } from \"@core/portServerside/uuidMethod.js\";\nimport { ok, type Result } from \"@utils/result.js\";\nimport { createSeededShuffle } from \"@utils/seededShuffle.js\";\n\nexport type StartGameUseCase = (\n game: GameWithNextStep,\n) => Result<GameWithNextAction>;\n\nexport const startGameUseCase =\n (deps: {\n uuidMethod: UuidMethod;\n shuffleMethod: ShuffleMethod;\n }): StartGameUseCase =>\n (game) => {\n const { uuidMethod, shuffleMethod } = deps;\n const {\n rules: {\n basic: { lords: maxLords, dominoesPerTurn },\n },\n players,\n dominoes,\n } = game;\n\n const numberOfPlayers = players.length;\n\n const newLords: Lord[] = [];\n\n for (let i = 0; i < numberOfPlayers; i++) {\n for (let j = 0; j < maxLords; j++) {\n const lord = createLord(uuidMethod(), players[i]!.id);\n newLords.push(lord);\n }\n }\n\n const shuffle = game.seed\n ? createSeededShuffle(game.seed, \"lords\")\n : shuffleMethod;\n const shuffledLords = shuffle(newLords);\n const dominoesCopy = [...dominoes];\n const dominoesDrawn = dominoesCopy.splice(0, dominoesPerTurn);\n dominoesDrawn.sort((a, b) => a.number - b.number);\n\n // Age of Giants: discard some dominos from the sorted line before selection\n const discardCount = game.rules.basic.dominoesDiscardedPerTurn ?? 0;\n if (discardCount > 0) {\n dominoesDrawn.splice(0, discardCount);\n }\n\n const nextAction: NextAction = {\n type: \"action\",\n nextLord: shuffledLords[0]!.id,\n nextAction: playerActions.pickDomino,\n };\n\n // Setup Builders Board for QueenDomino mode (including AoG-QD)\n let queendomino = game.queendomino;\n if (\n queendomino &&\n (game.mode.name === \"QueenDomino\" ||\n isAgeOfGiantsQueenDominoMode(game.mode.name))\n ) {\n const buildingShuffle = game.seed\n ? createSeededShuffle(game.seed, \"buildings\")\n : shuffleMethod;\n const board = createBuildersBoard(\n queendomino.buildersBoard.drawPile,\n buildingShuffle,\n );\n queendomino = { ...queendomino, buildersBoard: board };\n }\n\n // Setup Cave Board for Tribe mode\n let origins = game.origins;\n if (origins?.caveBoard && isTribeMode(game.mode.name)) {\n const caveShuffle = game.seed\n ? createSeededShuffle(game.seed, \"cavemen\")\n : shuffleMethod;\n const board = createCaveBoard(origins.caveBoard.drawPile, caveShuffle);\n origins = { ...origins, caveBoard: board };\n }\n\n const newState: GameWithNextAction = {\n ...game,\n lords: shuffledLords,\n nextAction,\n dominoes: dominoesCopy,\n currentDominoes: dominoesDrawn.map((domino, index) => {\n return {\n domino,\n picked: false,\n lordId: null,\n position: index + 1,\n };\n }),\n ...(queendomino !== undefined && { queendomino }),\n ...(origins !== undefined && { origins }),\n };\n\n return ok(newState);\n };\n","import { destroyWithDragon } from \"@core/domain/entities/building.js\";\nimport {\n allLordsHavePlayed,\n nextLordWithAction,\n} from \"@core/domain/entities/lord.js\";\nimport { ErrorCode } from \"@core/domain/errors/domainErrors.js\";\nimport {\n type GameStateResult,\n type GameWithNextAction,\n gameSteps,\n type NextAction,\n} from \"@core/domain/types/game.js\";\nimport { playerActions } from \"@core/domain/types/player.js\";\nimport { err, ok } from \"@utils/result.js\";\n\nexport type UseDragonUseCase = (\n game: GameWithNextAction,\n lordId: string,\n buildingId: number,\n) => GameStateResult;\n\nexport const useDragonUseCase: UseDragonUseCase = (\n game,\n lordId,\n buildingId,\n) => {\n const currentAction = game.nextAction;\n\n if (currentAction.nextLord !== lordId) {\n return err(ErrorCode.NOT_YOUR_TURN);\n }\n\n if (currentAction.nextAction !== playerActions.useDragon) {\n return err(ErrorCode.INVALID_OPTIONAL_ACTION);\n }\n\n if (!game.queendomino) {\n return err(ErrorCode.INVALID_OPTIONAL_ACTION);\n }\n\n if (\n !game.queendomino.dragonAvailable ||\n game.queendomino.dragonUsedThisRound\n ) {\n return err(ErrorCode.DRAGON_UNAVAILABLE);\n }\n\n const currentLord = game.lords.find((l) => l.id === lordId);\n if (!currentLord) return err(ErrorCode.LORD_NOT_FOUND);\n\n const currentPlayer = game.players.find((p) => p.id === currentLord.playerId);\n if (!currentPlayer) return err(ErrorCode.PLAYER_NOT_FOUND);\n\n // Queen holder cannot use dragon\n if (game.queendomino.queenHolderId === currentPlayer.id) {\n return err(ErrorCode.QUEEN_HOLDER_CANNOT_USE_DRAGON);\n }\n\n const result = destroyWithDragon(\n game.queendomino.buildersBoard,\n buildingId,\n currentPlayer,\n );\n\n if (!result) {\n return err(ErrorCode.BUILDING_NOT_FOUND);\n }\n\n const { updatedBoard, updatedPlayer } = result;\n\n const updatedPlayers = game.players.map((p) =>\n p.id === currentPlayer.id ? updatedPlayer : p,\n );\n\n // After dragon, advance to pickDomino (or result)\n const maxTurns = game.rules.basic.maxTurns;\n const isLastTurn = game.turn === maxTurns;\n\n if (isLastTurn && allLordsHavePlayed(game.lords)) {\n return ok({\n ...game,\n players: updatedPlayers,\n queendomino: {\n ...game.queendomino,\n buildersBoard: updatedBoard,\n dragonUsedThisRound: true,\n },\n nextAction: { type: \"step\", step: gameSteps.result },\n });\n }\n\n return ok({\n ...game,\n players: updatedPlayers,\n queendomino: {\n ...game.queendomino,\n buildersBoard: updatedBoard,\n dragonUsedThisRound: true,\n },\n nextAction: <NextAction>nextLordWithAction(game.lords),\n });\n};\n","import { consoleLogger, silentLogger } from \"@adapter/consoleLogger.js\";\nimport jsonBuildings from \"@adapter/jsonBuildings.js\";\nimport jsonCavemen from \"@adapter/jsonCavemen.js\";\nimport jsonDominoes from \"@adapter/jsonDominoes.js\";\nimport jsonModes from \"@adapter/jsonModes.js\";\nimport jsonQuestTiles from \"@adapter/jsonQuestTiles.js\";\nimport jsonRules from \"@adapter/jsonRules.js\";\nimport { shuffleMethod } from \"@adapter/shuffle.js\";\nimport { uuidMethod } from \"@adapter/uuid.js\";\nimport { addExtraRulesHandler } from \"@application/handlers/addExtraRulesHandler.js\";\nimport { addPlayersHandler } from \"@application/handlers/addPlayersHandler.js\";\nimport { calculateScoreHandler } from \"@application/handlers/calculateScoreHandler.js\";\nimport { canPlaceDominoHandler } from \"@application/handlers/canPlaceDominoHandler.js\";\nimport { chooseDominoHandler } from \"@application/handlers/chooseDominoHandler.js\";\nimport { constructBuildingHandler } from \"@application/handlers/constructBuildingHandler.js\";\nimport { createGameHandler } from \"@application/handlers/createGameHandler.js\";\nimport { discardDominoHandler } from \"@application/handlers/discardDominoHandler.js\";\nimport { getDynastyResultHandler } from \"@application/handlers/getDynastyResultHandler.js\";\nimport { getExtraRulesHandler } from \"@application/handlers/getExtraRulesHandler.js\";\nimport { getModesHandler } from \"@application/handlers/getModesHandler.js\";\nimport { getResultHandler } from \"@application/handlers/getResultHandler.js\";\nimport { getValidPlacementsHandler } from \"@application/handlers/getValidPlacementsHandler.js\";\nimport { placeDominoHandler } from \"@application/handlers/placeDominoHandler.js\";\nimport { placeFireTokenHandler } from \"@application/handlers/placeFireTokenHandler.js\";\nimport { placeGiantHandler } from \"@application/handlers/placeGiantHandler.js\";\nimport { placeKnightHandler } from \"@application/handlers/placeKnightHandler.js\";\nimport { recruitCavemanHandler } from \"@application/handlers/recruitCavemanHandler.js\";\nimport { sendGiantHandler } from \"@application/handlers/sendGiantHandler.js\";\nimport {\n deserializeGameHandler,\n serializeGameHandler,\n} from \"@application/handlers/serializeGameHandler.js\";\nimport { skipOptionalActionHandler } from \"@application/handlers/skipOptionalActionHandler.js\";\nimport { startGameHandler } from \"@application/handlers/startGameHandler.js\";\nimport { useDragonHandler } from \"@application/handlers/useDragonHandler.js\";\nimport type { Translator } from \"@core/i18n/translations.js\";\nimport { defaultTranslator } from \"@core/i18n/translations.js\";\nimport type { Logger } from \"@core/portServerside/logger.js\";\nimport type { ShuffleMethod } from \"@core/portServerside/shuffleMethod.js\";\nimport type { UuidMethod } from \"@core/portServerside/uuidMethod.js\";\nimport type { GameEngine } from \"@core/portUserside/engine.js\";\nimport { addExtraRulesUseCase } from \"@core/useCases/addExtraRules.js\";\nimport { addPlayersUseCase } from \"@core/useCases/addPlayers.js\";\nimport { calculateScoreUseCase } from \"@core/useCases/calculateScore.js\";\nimport { chooseDominoUseCase } from \"@core/useCases/chooseDomino.js\";\nimport { constructBuildingUseCase } from \"@core/useCases/constructBuilding.js\";\nimport { createGameUseCase } from \"@core/useCases/createGame.js\";\nimport { discardDominoUseCase } from \"@core/useCases/discardDomino.js\";\nimport type { DebugOptions } from \"@core/useCases/gameDebug.js\";\nimport type { GameEventCallbacks } from \"@core/useCases/gameEvents.js\";\nimport { getDynastyResultUseCase } from \"@core/useCases/getDynastyResult.js\";\nimport { getExtraRulesUseCase } from \"@core/useCases/getExtraRules.js\";\nimport { getModesUseCase } from \"@core/useCases/getModes.js\";\nimport { getResultUseCase } from \"@core/useCases/getResult.js\";\nimport {\n canPlaceDominoUseCase,\n getValidPlacementsUseCase,\n} from \"@core/useCases/getValidPlacements.js\";\nimport { placeDominoUseCase } from \"@core/useCases/placeDomino.js\";\nimport { placeFireTokenUseCase } from \"@core/useCases/placeFireToken.js\";\nimport { placeGiantUseCase } from \"@core/useCases/placeGiant.js\";\nimport { placeKnightUseCase } from \"@core/useCases/placeKnight.js\";\nimport { recruitCavemanUseCase } from \"@core/useCases/recruitCaveman.js\";\nimport { sendGiantUseCase } from \"@core/useCases/sendGiant.js\";\nimport { skipOptionalActionUseCase } from \"@core/useCases/skipOptionalAction.js\";\nimport { startGameUseCase } from \"@core/useCases/startGame.js\";\nimport { useDragonUseCase } from \"@core/useCases/useDragon.js\";\n\n/**\n * Configuration options for the game engine.\n */\nexport type EngineConfig = {\n /** Custom UUID generation method. Defaults to crypto.randomUUID() */\n uuidMethod?: UuidMethod;\n /** Custom shuffle method. Defaults to Fisher-Yates algorithm */\n shuffleMethod?: ShuffleMethod;\n /** Enable console logging. Defaults to false */\n logging?: boolean;\n /** Custom logger instance. When provided, takes precedence over 'logging' option */\n logger?: Logger;\n /** Optional event callbacks for UI/animation integration */\n events?: GameEventCallbacks;\n /** Custom translator for i18n error messages. Defaults to English */\n translator?: Translator;\n /** Enable debug mode with detailed logging. Pass `true` for defaults or a `DebugOptions` object. */\n debug?: boolean | DebugOptions;\n};\n\nexport type ConfiguredHandlers = {\n createGameHandler: GameEngine[\"createGame\"];\n getModesHandler: GameEngine[\"getModes\"];\n getExtraRulesHandler: GameEngine[\"getExtraRules\"];\n addPlayersHandler: GameEngine[\"addPlayers\"];\n addExtraRulesHandler: GameEngine[\"addExtraRules\"];\n startGameHandler: GameEngine[\"startGame\"];\n chooseDominoHandler: GameEngine[\"chooseDomino\"];\n placeDominoHandler: GameEngine[\"placeDomino\"];\n discardDominoHandler: GameEngine[\"discardDomino\"];\n getResultHandler: GameEngine[\"getResults\"];\n calculateScoreHandler: GameEngine[\"calculateScore\"];\n getValidPlacementsHandler: GameEngine[\"getValidPlacements\"];\n canPlaceDominoHandler: GameEngine[\"canPlaceDomino\"];\n serializeGameHandler: GameEngine[\"serialize\"];\n deserializeGameHandler: GameEngine[\"deserialize\"];\n getDynastyResultHandler: GameEngine[\"getDynastyResults\"];\n placeGiantHandler: GameEngine[\"placeGiant\"];\n sendGiantHandler: GameEngine[\"sendGiant\"];\n placeKnightHandler: GameEngine[\"placeKnight\"];\n constructBuildingHandler: GameEngine[\"constructBuilding\"];\n useDragonHandler: GameEngine[\"useDragon\"];\n placeFireTokenHandler: GameEngine[\"placeFireToken\"];\n recruitCavemanHandler: GameEngine[\"recruitCaveman\"];\n skipOptionalActionHandler: GameEngine[\"skipOptionalAction\"];\n};\n\nexport const configureEngine = (\n config: Partial<EngineConfig>,\n): ConfiguredHandlers => {\n const modeRepository = jsonModes();\n const dominoesRepository = jsonDominoes();\n const buildingsRepository = jsonBuildings();\n const cavemenRepository = jsonCavemen();\n const questTilesRepository = jsonQuestTiles();\n const ruleRepository = jsonRules();\n const uuid = config.uuidMethod || uuidMethod;\n const shuffle = config.shuffleMethod || shuffleMethod;\n const translator = config.translator || defaultTranslator;\n\n // Logger priority: custom logger > logging flag > silent\n const logger = config.logger\n ? config.logger\n : config.logging\n ? consoleLogger(true)\n : silentLogger;\n\n return {\n createGameHandler: createGameHandler(\n logger,\n translator,\n createGameUseCase({\n modeRepository,\n dominoesRepository,\n uuidMethod: uuid,\n shuffleMethod: shuffle,\n buildingsRepository,\n cavemenRepository,\n questTilesRepository,\n }),\n ),\n getModesHandler: getModesHandler(\n logger,\n translator,\n getModesUseCase({ modeRepository }),\n ),\n getExtraRulesHandler: getExtraRulesHandler(\n logger,\n translator,\n getExtraRulesUseCase({ ruleRepository }),\n ),\n addPlayersHandler: addPlayersHandler(\n logger,\n translator,\n addPlayersUseCase({\n uuidMethod: uuid,\n shuffleMethod: shuffle,\n ruleRepository,\n }),\n ),\n addExtraRulesHandler: addExtraRulesHandler(\n logger,\n translator,\n addExtraRulesUseCase({\n ruleRepository,\n dominoesRepository,\n shuffleMethod: shuffle,\n }),\n ),\n startGameHandler: startGameHandler(\n logger,\n translator,\n startGameUseCase({ uuidMethod: uuid, shuffleMethod: shuffle }),\n ),\n chooseDominoHandler: chooseDominoHandler(\n logger,\n translator,\n chooseDominoUseCase,\n ),\n placeDominoHandler: placeDominoHandler(\n logger,\n translator,\n placeDominoUseCase,\n ),\n discardDominoHandler: discardDominoHandler(\n logger,\n translator,\n discardDominoUseCase,\n ),\n getResultHandler: getResultHandler(logger, translator, {\n getResultUseCase,\n calculateScoreUseCase,\n }),\n calculateScoreHandler: calculateScoreHandler(\n logger,\n translator,\n calculateScoreUseCase,\n ),\n getValidPlacementsHandler: getValidPlacementsHandler(\n logger,\n translator,\n getValidPlacementsUseCase,\n ),\n canPlaceDominoHandler: canPlaceDominoHandler(\n logger,\n translator,\n canPlaceDominoUseCase,\n ),\n serializeGameHandler: serializeGameHandler(logger, translator),\n deserializeGameHandler: deserializeGameHandler(logger, translator),\n getDynastyResultHandler: getDynastyResultHandler(\n logger,\n translator,\n getDynastyResultUseCase,\n ),\n placeGiantHandler: placeGiantHandler(logger, translator, placeGiantUseCase),\n sendGiantHandler: sendGiantHandler(logger, translator, sendGiantUseCase),\n placeKnightHandler: placeKnightHandler(\n logger,\n translator,\n placeKnightUseCase,\n ),\n constructBuildingHandler: constructBuildingHandler(\n logger,\n translator,\n constructBuildingUseCase,\n ),\n useDragonHandler: useDragonHandler(logger, translator, useDragonUseCase),\n placeFireTokenHandler: placeFireTokenHandler(\n logger,\n translator,\n placeFireTokenUseCase,\n ),\n recruitCavemanHandler: recruitCavemanHandler(\n logger,\n translator,\n recruitCavemanUseCase,\n ),\n skipOptionalActionHandler: skipOptionalActionHandler(\n logger,\n translator,\n skipOptionalActionUseCase,\n ),\n };\n};\n","import { GROUND } from \"@core/domain/types/domino.js\";\nimport type { Game } from \"@core/domain/types/game.js\";\nimport { gameSteps } from \"@core/domain/types/game.js\";\nimport { GRIDSIZE } from \"@core/domain/types/kingdom.js\";\nimport { playerActions } from \"@core/domain/types/player.js\";\nimport type {\n ValidationIssue,\n ValidationSeverity,\n} from \"@core/domain/types/validation.js\";\n\nconst issue = (\n path: string,\n code: string,\n message: string,\n severity: ValidationSeverity = \"error\",\n): ValidationIssue => ({ path, code, message, severity });\n\nconst isNonEmptyString = (value: unknown): value is string =>\n typeof value === \"string\" && value.length > 0;\n\nconst isNonNegativeInteger = (value: unknown): value is number =>\n typeof value === \"number\" && Number.isInteger(value) && value >= 0;\n\nconst isPositiveInteger = (value: unknown): value is number =>\n typeof value === \"number\" && Number.isInteger(value) && value > 0;\n\nconst validGrounds = new Set<string>([...GROUND, \"empty\"]);\nconst validPlayerActions = new Set<string>(Object.values(playerActions));\nconst validGameSteps = new Set<string>(Object.values(gameSteps));\n\n// --- Validation sub-functions ---\n\nconst validateGameStructure = (game: Game): ValidationIssue[] => {\n const issues: ValidationIssue[] = [];\n\n if (!isNonEmptyString(game.id)) {\n issues.push(\n issue(\"id\", \"INVALID_ID\", \"Game id must be a non-empty string\"),\n );\n }\n if (!isNonNegativeInteger(game.turn)) {\n issues.push(\n issue(\"turn\", \"INVALID_TURN\", \"Turn must be a non-negative integer\"),\n );\n }\n if (!Array.isArray(game.dominoes)) {\n issues.push(\n issue(\"dominoes\", \"INVALID_DOMINOES\", \"Dominoes must be an array\"),\n );\n }\n if (!Array.isArray(game.currentDominoes)) {\n issues.push(\n issue(\n \"currentDominoes\",\n \"INVALID_CURRENT_DOMINOES\",\n \"CurrentDominoes must be an array\",\n ),\n );\n }\n if (!Array.isArray(game.players)) {\n issues.push(\n issue(\"players\", \"INVALID_PLAYERS\", \"Players must be an array\"),\n );\n }\n if (!Array.isArray(game.lords)) {\n issues.push(issue(\"lords\", \"INVALID_LORDS\", \"Lords must be an array\"));\n }\n if (!game.rules || typeof game.rules !== \"object\") {\n issues.push(issue(\"rules\", \"INVALID_RULES\", \"Rules must be an object\"));\n } else {\n if (!game.rules.basic || typeof game.rules.basic !== \"object\") {\n issues.push(\n issue(\n \"rules.basic\",\n \"INVALID_BASIC_RULES\",\n \"Rules.basic must be an object\",\n ),\n );\n }\n if (!Array.isArray(game.rules.extra)) {\n issues.push(\n issue(\n \"rules.extra\",\n \"INVALID_EXTRA_RULES\",\n \"Rules.extra must be an array\",\n ),\n );\n }\n }\n if (!game.mode || typeof game.mode !== \"object\") {\n issues.push(issue(\"mode\", \"INVALID_MODE\", \"Mode must be an object\"));\n } else {\n if (!isNonEmptyString(game.mode.name)) {\n issues.push(\n issue(\n \"mode.name\",\n \"INVALID_MODE_NAME\",\n \"Mode name must be a non-empty string\",\n ),\n );\n }\n }\n if (!game.nextAction || typeof game.nextAction !== \"object\") {\n issues.push(\n issue(\n \"nextAction\",\n \"INVALID_NEXT_ACTION\",\n \"NextAction must be an object\",\n ),\n );\n } else if (\n game.nextAction.type !== \"action\" &&\n game.nextAction.type !== \"step\"\n ) {\n issues.push(\n issue(\n \"nextAction.type\",\n \"INVALID_NEXT_ACTION_TYPE\",\n \"NextAction.type must be 'action' or 'step'\",\n ),\n );\n }\n\n return issues;\n};\n\nconst validateTile = (tile: unknown, path: string): ValidationIssue[] => {\n const issues: ValidationIssue[] = [];\n if (!tile || typeof tile !== \"object\") {\n issues.push(\n issue(path, \"INVALID_TILE\", `Tile at ${path} must be an object`),\n );\n return issues;\n }\n const t = tile as Record<string, unknown>;\n if (typeof t.type !== \"string\" || !validGrounds.has(t.type)) {\n issues.push(\n issue(\n `${path}.type`,\n \"INVALID_TILE_TYPE\",\n `Invalid terrain type at ${path}`,\n ),\n );\n }\n if (typeof t.crowns !== \"number\" || t.crowns < 0) {\n issues.push(\n issue(\n `${path}.crowns`,\n \"INVALID_TILE_CROWNS\",\n `Invalid crowns at ${path}`,\n ),\n );\n }\n return issues;\n};\n\nconst validatePlayers = (game: Game): ValidationIssue[] => {\n const issues: ValidationIssue[] = [];\n if (!Array.isArray(game.players)) return issues;\n\n const playerIds = new Set<string>();\n for (let i = 0; i < game.players.length; i++) {\n const player = game.players[i]!;\n const path = `players[${i}]`;\n\n if (!isNonEmptyString(player.id)) {\n issues.push(\n issue(\n `${path}.id`,\n \"INVALID_PLAYER_ID\",\n `Player id must be a non-empty string`,\n ),\n );\n } else if (playerIds.has(player.id)) {\n issues.push(\n issue(\n `${path}.id`,\n \"DUPLICATE_PLAYER_ID\",\n `Duplicate player id: ${player.id}`,\n ),\n );\n } else {\n playerIds.add(player.id);\n }\n\n if (typeof player.name !== \"string\" || player.name.length < 3) {\n issues.push(\n issue(\n `${path}.name`,\n \"INVALID_PLAYER_NAME\",\n `Player name must be at least 3 characters`,\n ),\n );\n }\n\n // Kingdom validation\n if (!Array.isArray(player.kingdom)) {\n issues.push(\n issue(\n `${path}.kingdom`,\n \"INVALID_KINGDOM\",\n `Kingdom must be a 2D array`,\n ),\n );\n continue;\n }\n if (player.kingdom.length !== GRIDSIZE) {\n issues.push(\n issue(\n `${path}.kingdom`,\n \"INVALID_KINGDOM_GRID\",\n `Kingdom must have ${GRIDSIZE} rows, got ${player.kingdom.length}`,\n ),\n );\n continue;\n }\n\n let castleCount = 0;\n for (let y = 0; y < player.kingdom.length; y++) {\n const row = player.kingdom[y]!;\n if (!Array.isArray(row) || row.length !== GRIDSIZE) {\n issues.push(\n issue(\n `${path}.kingdom[${y}]`,\n \"INVALID_KINGDOM_ROW\",\n `Kingdom row ${y} must have ${GRIDSIZE} columns`,\n ),\n );\n continue;\n }\n for (let x = 0; x < row.length; x++) {\n const cell = row[x]!;\n issues.push(...validateTile(cell, `${path}.kingdom[${y}][${x}]`));\n if (\n cell &&\n typeof cell === \"object\" &&\n (cell as Record<string, unknown>).type === \"castle\"\n ) {\n castleCount++;\n }\n }\n }\n if (castleCount === 0) {\n issues.push(\n issue(\n `${path}.kingdom`,\n \"MISSING_CASTLE\",\n `Kingdom must have exactly one castle tile`,\n \"warning\",\n ),\n );\n } else if (castleCount > 1) {\n issues.push(\n issue(\n `${path}.kingdom`,\n \"MULTIPLE_CASTLES\",\n `Kingdom has ${castleCount} castle tiles, expected 1`,\n ),\n );\n }\n }\n\n return issues;\n};\n\nconst validateDominoes = (game: Game): ValidationIssue[] => {\n const issues: ValidationIssue[] = [];\n const allNumbers = new Set<number>();\n\n // Validate draw pile dominoes\n if (Array.isArray(game.dominoes)) {\n for (let i = 0; i < game.dominoes.length; i++) {\n const domino = game.dominoes[i]!;\n const path = `dominoes[${i}]`;\n\n if (!isPositiveInteger(domino.number)) {\n issues.push(\n issue(\n `${path}.number`,\n \"INVALID_DOMINO_NUMBER\",\n `Domino number must be a positive integer`,\n ),\n );\n } else if (allNumbers.has(domino.number)) {\n issues.push(\n issue(\n `${path}.number`,\n \"DUPLICATE_DOMINO_NUMBER\",\n `Duplicate domino number: ${domino.number}`,\n ),\n );\n } else {\n allNumbers.add(domino.number);\n }\n issues.push(...validateTile(domino.left, `${path}.left`));\n issues.push(...validateTile(domino.right, `${path}.right`));\n }\n }\n\n // Validate current (revealed) dominoes\n if (Array.isArray(game.currentDominoes)) {\n for (let i = 0; i < game.currentDominoes.length; i++) {\n const revealed = game.currentDominoes[i]!;\n const path = `currentDominoes[${i}]`;\n\n if (!revealed.domino || typeof revealed.domino !== \"object\") {\n issues.push(\n issue(\n `${path}.domino`,\n \"INVALID_REVEALED_DOMINO\",\n `Revealed domino must be an object`,\n ),\n );\n continue;\n }\n\n const domino = revealed.domino;\n if (!isPositiveInteger(domino.number)) {\n issues.push(\n issue(\n `${path}.domino.number`,\n \"INVALID_DOMINO_NUMBER\",\n `Domino number must be a positive integer`,\n ),\n );\n } else if (allNumbers.has(domino.number)) {\n issues.push(\n issue(\n `${path}.domino.number`,\n \"DUPLICATE_DOMINO_NUMBER\",\n `Duplicate domino number: ${domino.number}`,\n ),\n );\n } else {\n allNumbers.add(domino.number);\n }\n issues.push(...validateTile(domino.left, `${path}.domino.left`));\n issues.push(...validateTile(domino.right, `${path}.domino.right`));\n\n // picked/lordId consistency\n if (revealed.picked && revealed.lordId === null) {\n issues.push(\n issue(\n `${path}`,\n \"PICKED_WITHOUT_LORD\",\n `Domino is marked as picked but has no lordId`,\n ),\n );\n }\n if (!revealed.picked && revealed.lordId !== null) {\n issues.push(\n issue(\n `${path}`,\n \"UNPICKED_WITH_LORD\",\n `Domino is not picked but has a lordId`,\n ),\n );\n }\n }\n }\n\n // Validate dominos picked by lords\n // Note: lord.dominoPicked is a copy of the domino from currentDominoes,\n // so the same number legitimately appears in both places.\n if (Array.isArray(game.lords)) {\n const lordPickedNumbers = new Set<number>();\n for (let i = 0; i < game.lords.length; i++) {\n const lord = game.lords[i]!;\n if (lord.dominoPicked) {\n const path = `lords[${i}].dominoPicked`;\n const domino = lord.dominoPicked;\n if (!isPositiveInteger(domino.number)) {\n issues.push(\n issue(\n `${path}.number`,\n \"INVALID_DOMINO_NUMBER\",\n `Domino number must be a positive integer`,\n ),\n );\n } else if (lordPickedNumbers.has(domino.number)) {\n issues.push(\n issue(\n `${path}.number`,\n \"DUPLICATE_DOMINO_NUMBER\",\n `Duplicate domino number among lords: ${domino.number}`,\n ),\n );\n } else {\n lordPickedNumbers.add(domino.number);\n }\n issues.push(...validateTile(domino.left, `${path}.left`));\n issues.push(...validateTile(domino.right, `${path}.right`));\n }\n }\n }\n\n return issues;\n};\n\nconst validateLords = (game: Game): ValidationIssue[] => {\n const issues: ValidationIssue[] = [];\n if (!Array.isArray(game.lords)) return issues;\n\n const playerIds = new Set<string>(\n Array.isArray(game.players) ? game.players.map((p) => p.id) : [],\n );\n const lordIds = new Set<string>();\n\n for (let i = 0; i < game.lords.length; i++) {\n const lord = game.lords[i]!;\n const path = `lords[${i}]`;\n\n if (!isNonEmptyString(lord.id)) {\n issues.push(\n issue(\n `${path}.id`,\n \"INVALID_LORD_ID\",\n `Lord id must be a non-empty string`,\n ),\n );\n } else if (lordIds.has(lord.id)) {\n issues.push(\n issue(\n `${path}.id`,\n \"DUPLICATE_LORD_ID\",\n `Duplicate lord id: ${lord.id}`,\n ),\n );\n } else {\n lordIds.add(lord.id);\n }\n\n if (!isNonEmptyString(lord.playerId)) {\n issues.push(\n issue(\n `${path}.playerId`,\n \"INVALID_LORD_PLAYER_ID\",\n `Lord playerId must be a non-empty string`,\n ),\n );\n } else if (playerIds.size > 0 && !playerIds.has(lord.playerId)) {\n issues.push(\n issue(\n `${path}.playerId`,\n \"LORD_PLAYER_NOT_FOUND\",\n `Lord references non-existent player: ${lord.playerId}`,\n ),\n );\n }\n\n if (lord.turnEnded && (!lord.hasPick || !lord.hasPlace)) {\n issues.push(\n issue(\n path,\n \"INCONSISTENT_LORD_FLAGS\",\n `Lord has turnEnded=true but hasPick=${lord.hasPick}, hasPlace=${lord.hasPlace}`,\n \"warning\",\n ),\n );\n }\n }\n\n return issues;\n};\n\nconst validateGameFlow = (game: Game): ValidationIssue[] => {\n const issues: ValidationIssue[] = [];\n if (!game.nextAction || typeof game.nextAction !== \"object\") return issues;\n\n const nextAction = game.nextAction;\n\n if (nextAction.type === \"action\") {\n const action = nextAction as {\n type: \"action\";\n nextLord?: unknown;\n nextAction?: unknown;\n };\n\n if (!isNonEmptyString(action.nextLord)) {\n issues.push(\n issue(\n \"nextAction.nextLord\",\n \"INVALID_NEXT_LORD\",\n \"nextLord must be a non-empty string\",\n ),\n );\n } else if (\n Array.isArray(game.lords) &&\n !game.lords.some((l) => l.id === action.nextLord)\n ) {\n issues.push(\n issue(\n \"nextAction.nextLord\",\n \"NEXT_LORD_NOT_FOUND\",\n `nextLord references non-existent lord: ${action.nextLord as string}`,\n ),\n );\n }\n\n if (\n typeof action.nextAction !== \"string\" ||\n !validPlayerActions.has(action.nextAction as string)\n ) {\n issues.push(\n issue(\n \"nextAction.nextAction\",\n \"INVALID_PLAYER_ACTION\",\n `nextAction must be one of: ${[...validPlayerActions].join(\", \")}`,\n ),\n );\n }\n } else if (nextAction.type === \"step\") {\n const step = nextAction as { type: \"step\"; step?: unknown };\n\n if (\n typeof step.step !== \"string\" ||\n !validGameSteps.has(step.step as string)\n ) {\n issues.push(\n issue(\n \"nextAction.step\",\n \"INVALID_GAME_STEP\",\n `step must be one of: ${[...validGameSteps].join(\", \")}`,\n ),\n );\n }\n }\n\n return issues;\n};\n\nconst isSetupPhase = (game: Game): boolean => {\n if (game.nextAction?.type !== \"step\") return false;\n const step = (game.nextAction as { step: string }).step;\n return step === \"addPlayers\" || step === \"options\" || step === \"start\";\n};\n\nconst validateRules = (game: Game): ValidationIssue[] => {\n const issues: ValidationIssue[] = [];\n if (!game.rules || typeof game.rules !== \"object\") return issues;\n\n // During setup phases (before players are added), basic rules may have zero values\n const allowZero = isSetupPhase(game);\n\n const basic = game.rules.basic;\n if (basic && typeof basic === \"object\") {\n const fields = [\n \"lords\",\n \"maxDominoes\",\n \"dominoesPerTurn\",\n \"maxTurns\",\n \"maxKingdomSize\",\n ] as const;\n for (const field of fields) {\n const check = allowZero ? isNonNegativeInteger : isPositiveInteger;\n if (!check(basic[field])) {\n issues.push(\n issue(\n `rules.basic.${field}`,\n \"INVALID_BASIC_RULE_VALUE\",\n `rules.basic.${field} must be a positive integer`,\n ),\n );\n }\n }\n }\n\n if (Array.isArray(game.rules.extra)) {\n for (let i = 0; i < game.rules.extra.length; i++) {\n const rule = game.rules.extra[i]!;\n if (!isNonEmptyString(rule.name)) {\n issues.push(\n issue(\n `rules.extra[${i}].name`,\n \"INVALID_EXTRA_RULE_NAME\",\n `Extra rule name must be a non-empty string`,\n ),\n );\n }\n }\n }\n\n return issues;\n};\n\n/**\n * Validates the integrity of a game state.\n *\n * Use this function after deserializing or restoring a persisted game state\n * to detect corruptions before resuming gameplay.\n *\n * @param game - The game state to validate\n * @returns An array of validation issues. Empty array means the state is valid.\n *\n * @example\n * ```typescript\n * const issues = validateGameState(game);\n * if (issues.length > 0) {\n * console.error(\"Game state is corrupted:\", issues);\n * }\n * ```\n */\nexport const validateGameState = (game: Game): ValidationIssue[] => {\n const issues: ValidationIssue[] = [];\n\n issues.push(...validateGameStructure(game));\n issues.push(...validatePlayers(game));\n issues.push(...validateDominoes(game));\n issues.push(...validateLords(game));\n issues.push(...validateGameFlow(game));\n issues.push(...validateRules(game));\n\n return issues;\n};\n","import type { BotStrategy } from \"./bot.js\";\nimport {\n advancedStrategy,\n expertStrategy,\n greedyStrategy,\n randomStrategy,\n} from \"./bot.js\";\n\n/**\n * Built-in strategy names.\n */\nexport type StrategyName = \"random\" | \"greedy\" | \"advanced\" | \"expert\";\n\n// Use a getter function to avoid circular dependency issues with bot.ts.\n// When biome sorts imports, bot.ts may not be fully initialized when this\n// module-level code runs. Deferring access to the strategies ensures they\n// are resolved at call time, not at module evaluation time.\nconst getDefaultStrategies = (): Record<string, BotStrategy> => ({\n random: randomStrategy,\n greedy: greedyStrategy,\n advanced: advancedStrategy,\n expert: expertStrategy,\n});\n\n/**\n * Resolves a strategy by name. Checks custom strategies first, then defaults.\n * Returns undefined if the name is not found.\n */\nexport const getStrategy = (\n name: string,\n custom?: Record<string, BotStrategy>,\n): BotStrategy | undefined => {\n return custom?.[name] ?? getDefaultStrategies()[name];\n};\n\n/**\n * Returns the list of built-in strategy names.\n */\nexport const getStrategyNames = (): string[] =>\n Object.keys(getDefaultStrategies());\n","import { findCrownsNotCoveredByGiants } from \"@core/domain/entities/giant.js\";\nimport { placeDomino } from \"@core/domain/entities/kingdom.js\";\nimport { isGameWithNextAction } from \"@core/domain/types/game.js\";\nimport type {\n Domino,\n GameState,\n GameWithNextAction,\n Kingdom,\n RevealsDomino,\n} from \"@core/domain/types/index.js\";\nimport type { GameEngine } from \"@core/portUserside/engine.js\";\nimport { isOk } from \"@utils/result.js\";\nimport { getStrategy } from \"./botRegistry.js\";\nimport { calculateScoreUseCase } from \"./calculateScore.js\";\nimport type { ValidPlacement } from \"./getValidPlacements.js\";\nimport { getValidPlacementsUseCase } from \"./getValidPlacements.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────\n\n/**\n * Context provided to a bot strategy when choosing a domino to pick.\n */\nexport type PickContext = {\n game: GameWithNextAction;\n lordId: string;\n availableDominoes: RevealsDomino[];\n};\n\n/**\n * Context provided to a bot strategy when choosing where to place a domino.\n */\nexport type PlaceContext = {\n game: GameWithNextAction;\n lordId: string;\n domino: Domino;\n kingdom: Kingdom;\n validPlacements: ValidPlacement[];\n};\n\n/**\n * A bot strategy that decides which domino to pick and where to place it.\n * Strategies are stateless — all information comes from the context.\n */\nexport type BotStrategy = {\n chooseDomino: (context: PickContext) => number;\n choosePlacement: (context: PlaceContext) => ValidPlacement | null;\n};\n\n// ─── Helpers ─────────────────────────────────────────────────────────\n\nconst scoreKingdom = (kingdom: Kingdom): number => {\n const result = calculateScoreUseCase(kingdom);\n return isOk(result) ? result.value.points : 0;\n};\n\nconst simulatePlacement = (\n kingdom: Kingdom,\n domino: Domino,\n placement: ValidPlacement,\n maxKingdomSize: number,\n): Kingdom | null => {\n const result = placeDomino(\n kingdom,\n placement.position,\n placement.rotation,\n domino,\n maxKingdomSize,\n );\n return isOk(result) ? result.value : null;\n};\n\nconst bestPlacementScore = (\n kingdom: Kingdom,\n domino: Domino,\n placements: ValidPlacement[],\n maxKingdomSize: number,\n): { placement: ValidPlacement; score: number; kingdom: Kingdom } | null => {\n let best: {\n placement: ValidPlacement;\n score: number;\n kingdom: Kingdom;\n } | null = null;\n\n for (const placement of placements) {\n const newKingdom = simulatePlacement(\n kingdom,\n domino,\n placement,\n maxKingdomSize,\n );\n if (!newKingdom) continue;\n const score = scoreKingdom(newKingdom);\n if (!best || score > best.score) {\n best = { placement, score, kingdom: newKingdom };\n }\n }\n\n return best;\n};\n\nconst getMaxKingdomSize = (game: GameWithNextAction): number =>\n game.rules.basic.maxKingdomSize;\n\nconst getLordAndPlayer = (game: GameWithNextAction, lordId: string) => {\n const lord = game.lords.find((l) => l.id === lordId);\n const player = lord\n ? game.players.find((p) => p.id === lord.playerId)\n : undefined;\n return { lord, player };\n};\n\nconst getNextBatchDominoes = (game: GameWithNextAction): Domino[] => {\n const perTurn = game.rules.basic.dominoesPerTurn;\n return [...game.dominoes]\n .slice(0, perTurn)\n .sort((a, b) => a.number - b.number);\n};\n\n// ─── Random Strategy ─────────────────────────────────────────────────\n\n/**\n * Bot strategy that makes random choices.\n * Picks a random available domino and places it at a random valid position.\n */\nexport const randomStrategy: BotStrategy = {\n chooseDomino: (context) => {\n const { availableDominoes } = context;\n const idx = Math.floor(Math.random() * availableDominoes.length);\n return availableDominoes[idx]!.domino.number;\n },\n\n choosePlacement: (context) => {\n const { validPlacements } = context;\n if (validPlacements.length === 0) return null;\n const idx = Math.floor(Math.random() * validPlacements.length);\n return validPlacements[idx]!;\n },\n};\n\n// ─── Greedy Strategy ─────────────────────────────────────────────────\n\n/**\n * Bot strategy that maximizes the immediate score.\n * Evaluates every valid placement and picks the one yielding the highest score.\n * When picking a domino, simulates the best placement for each option.\n */\nexport const greedyStrategy: BotStrategy = {\n chooseDomino: (context) => {\n const { game, lordId, availableDominoes } = context;\n const { player } = getLordAndPlayer(game, lordId);\n if (!player) return availableDominoes[0]!.domino.number;\n\n const maxSize = getMaxKingdomSize(game);\n let bestScore = -1;\n let bestPick = availableDominoes[0]!.domino.number;\n\n for (const rd of availableDominoes) {\n const placements = getValidPlacementsUseCase(\n player.kingdom,\n rd.domino,\n maxSize,\n );\n const result = bestPlacementScore(\n player.kingdom,\n rd.domino,\n placements,\n maxSize,\n );\n const score = result ? result.score : 0;\n if (score > bestScore) {\n bestScore = score;\n bestPick = rd.domino.number;\n }\n }\n\n return bestPick;\n },\n\n choosePlacement: (context) => {\n const { game, domino, kingdom, validPlacements } = context;\n if (validPlacements.length === 0) return null;\n\n const maxSize = getMaxKingdomSize(game);\n const result = bestPlacementScore(\n kingdom,\n domino,\n validPlacements,\n maxSize,\n );\n return result ? result.placement : validPlacements[0]!;\n },\n};\n\n// ─── Advanced Strategy ───────────────────────────────────────────────\n\nconst evaluateWithLookahead = (\n kingdom: Kingdom,\n maxSize: number,\n nextDominoes: Domino[],\n): number => {\n if (nextDominoes.length === 0) return 0;\n\n let bestNextScore = 0;\n for (const nextDomino of nextDominoes) {\n const nextPlacements = getValidPlacementsUseCase(\n kingdom,\n nextDomino,\n maxSize,\n );\n const result = bestPlacementScore(\n kingdom,\n nextDomino,\n nextPlacements,\n maxSize,\n );\n if (result && result.score > bestNextScore) {\n bestNextScore = result.score;\n }\n }\n\n return bestNextScore;\n};\n\n/**\n * Bot strategy with 1-turn lookahead.\n * When making decisions, considers not just the immediate score but also\n * the best possible score achievable in the next turn by peeking at\n * the upcoming domino batch from the draw pile.\n */\nexport const advancedStrategy: BotStrategy = {\n chooseDomino: (context) => {\n const { game, lordId, availableDominoes } = context;\n const { player } = getLordAndPlayer(game, lordId);\n if (!player) return availableDominoes[0]!.domino.number;\n\n const maxSize = getMaxKingdomSize(game);\n const nextBatch = getNextBatchDominoes(game);\n\n let bestCombinedScore = -1;\n let bestPick = availableDominoes[0]!.domino.number;\n\n for (const rd of availableDominoes) {\n const placements = getValidPlacementsUseCase(\n player.kingdom,\n rd.domino,\n maxSize,\n );\n const result = bestPlacementScore(\n player.kingdom,\n rd.domino,\n placements,\n maxSize,\n );\n\n const immediateScore = result\n ? result.score\n : scoreKingdom(player.kingdom);\n const kingdomAfter = result ? result.kingdom : player.kingdom;\n const futureScore = evaluateWithLookahead(\n kingdomAfter,\n maxSize,\n nextBatch,\n );\n const combined = immediateScore + futureScore * 0.8;\n\n if (combined > bestCombinedScore) {\n bestCombinedScore = combined;\n bestPick = rd.domino.number;\n }\n }\n\n return bestPick;\n },\n\n choosePlacement: (context) => {\n const { game, domino, kingdom, validPlacements } = context;\n if (validPlacements.length === 0) return null;\n\n const maxSize = getMaxKingdomSize(game);\n const nextBatch = getNextBatchDominoes(game);\n\n let bestCombinedScore = -1;\n let bestPlacement: ValidPlacement = validPlacements[0]!;\n\n for (const placement of validPlacements) {\n const newKingdom = simulatePlacement(kingdom, domino, placement, maxSize);\n if (!newKingdom) continue;\n\n const immediateScore = scoreKingdom(newKingdom);\n const futureScore = evaluateWithLookahead(newKingdom, maxSize, nextBatch);\n const combined = immediateScore + futureScore * 0.8;\n\n if (combined > bestCombinedScore) {\n bestCombinedScore = combined;\n bestPlacement = placement;\n }\n }\n\n return bestPlacement;\n },\n};\n\n// ─── Expert Strategy ─────────────────────────────────────────────────\n\n/** Maximum placements to evaluate per domino at each depth level (beam width) */\nconst EXPERT_BEAM_WIDTH = 2;\n\n/** Maximum search depth for the expert strategy */\nconst EXPERT_MAX_DEPTH = 2;\n\n/**\n * Ranks placements by immediate score gain (greedy heuristic)\n * and returns only the top N candidates for deeper evaluation.\n */\nconst topPlacements = (\n kingdom: Kingdom,\n domino: Domino,\n placements: ValidPlacement[],\n maxSize: number,\n limit: number,\n): ValidPlacement[] => {\n if (placements.length <= limit) return placements;\n\n const scored = placements\n .map((p) => {\n const k = simulatePlacement(kingdom, domino, p, maxSize);\n return { placement: p, score: k ? scoreKingdom(k) : 0 };\n })\n .sort((a, b) => b.score - a.score);\n\n return scored.slice(0, limit).map((s) => s.placement);\n};\n\nconst expertEvaluate = (\n kingdom: Kingdom,\n remainingDominoes: Domino[],\n dominoesPerTurn: number,\n maxSize: number,\n depth: number,\n): number => {\n if (depth <= 0 || remainingDominoes.length === 0) {\n return scoreKingdom(kingdom);\n }\n\n // Get next batch (sorted by number, as the engine does)\n const batch = [...remainingDominoes]\n .slice(0, dominoesPerTurn)\n .sort((a, b) => a.number - b.number);\n const afterBatch = remainingDominoes.slice(dominoesPerTurn);\n\n let bestScore = scoreKingdom(kingdom);\n\n for (const domino of batch) {\n const allPlacements = getValidPlacementsUseCase(kingdom, domino, maxSize);\n\n if (allPlacements.length === 0) {\n const score = expertEvaluate(\n kingdom,\n afterBatch,\n dominoesPerTurn,\n maxSize,\n depth - 1,\n );\n if (score > bestScore) bestScore = score;\n continue;\n }\n\n // Prune: only evaluate top candidates by greedy score\n const candidates = topPlacements(\n kingdom,\n domino,\n allPlacements,\n maxSize,\n EXPERT_BEAM_WIDTH,\n );\n\n for (const placement of candidates) {\n const newKingdom = simulatePlacement(kingdom, domino, placement, maxSize);\n if (!newKingdom) continue;\n\n const score = expertEvaluate(\n newKingdom,\n afterBatch,\n dominoesPerTurn,\n maxSize,\n depth - 1,\n );\n if (score > bestScore) bestScore = score;\n }\n }\n\n return bestScore;\n};\n\n/**\n * Bot strategy that searches the game tree with beam-search pruning.\n * Explores all remaining turns, but limits the number of placements\n * evaluated per domino to the top candidates (by greedy score).\n * Since kingdoms are independent, this is a solo optimization (no adversarial search needed).\n */\nexport const expertStrategy: BotStrategy = {\n chooseDomino: (context) => {\n const { game, lordId, availableDominoes } = context;\n const { player } = getLordAndPlayer(game, lordId);\n if (!player) return availableDominoes[0]!.domino.number;\n\n const maxSize = getMaxKingdomSize(game);\n const perTurn = game.rules.basic.dominoesPerTurn;\n const turnsLeft = Math.min(\n game.rules.basic.maxTurns - game.turn,\n EXPERT_MAX_DEPTH,\n );\n\n let bestScore = -1;\n let bestPick = availableDominoes[0]!.domino.number;\n\n for (const rd of availableDominoes) {\n const allPlacements = getValidPlacementsUseCase(\n player.kingdom,\n rd.domino,\n maxSize,\n );\n\n if (allPlacements.length === 0) {\n const score = expertEvaluate(\n player.kingdom,\n game.dominoes,\n perTurn,\n maxSize,\n turnsLeft,\n );\n if (score > bestScore) {\n bestScore = score;\n bestPick = rd.domino.number;\n }\n continue;\n }\n\n const candidates = topPlacements(\n player.kingdom,\n rd.domino,\n allPlacements,\n maxSize,\n EXPERT_BEAM_WIDTH,\n );\n\n for (const placement of candidates) {\n const newKingdom = simulatePlacement(\n player.kingdom,\n rd.domino,\n placement,\n maxSize,\n );\n if (!newKingdom) continue;\n\n const score = expertEvaluate(\n newKingdom,\n game.dominoes,\n perTurn,\n maxSize,\n turnsLeft,\n );\n if (score > bestScore) {\n bestScore = score;\n bestPick = rd.domino.number;\n }\n }\n }\n\n return bestPick;\n },\n\n choosePlacement: (context) => {\n const { game, domino, kingdom, validPlacements } = context;\n if (validPlacements.length === 0) return null;\n\n const maxSize = getMaxKingdomSize(game);\n const perTurn = game.rules.basic.dominoesPerTurn;\n const turnsLeft = Math.min(\n game.rules.basic.maxTurns - game.turn,\n EXPERT_MAX_DEPTH,\n );\n\n let bestScore = -1;\n let bestPlacement: ValidPlacement = validPlacements[0]!;\n\n for (const placement of validPlacements) {\n const newKingdom = simulatePlacement(kingdom, domino, placement, maxSize);\n if (!newKingdom) continue;\n\n const score = expertEvaluate(\n newKingdom,\n game.dominoes,\n perTurn,\n maxSize,\n turnsLeft,\n );\n if (score > bestScore) {\n bestScore = score;\n bestPlacement = placement;\n }\n }\n\n return bestPlacement;\n },\n};\n\n// ─── playBotTurn ─────────────────────────────────────────────────────\n\n/**\n * Executes a single bot turn using the given strategy and engine.\n * Reads the current game state to determine the required action,\n * asks the strategy for a decision, and executes it via the engine.\n *\n * @param engine - The game engine instance\n * @param game - Current game state (must require a player action)\n * @param strategy - The bot strategy to use for decisions\n * @returns Updated game state after the bot's action\n */\nexport const playBotTurn = (\n engine: GameEngine,\n game: GameWithNextAction,\n strategy: BotStrategy,\n): GameState => {\n const lordId = game.nextAction.nextLord;\n const action = game.nextAction.nextAction;\n\n if (action === \"pickDomino\") {\n const availableDominoes = game.currentDominoes.filter((d) => !d.picked);\n const dominoPick = strategy.chooseDomino({\n game,\n lordId,\n availableDominoes,\n });\n return engine.chooseDomino({ game, lordId, dominoPick });\n }\n\n if (action === \"placeDomino\") {\n const { lord, player } = getLordAndPlayer(game, lordId);\n if (!lord?.dominoPicked || !player) {\n return engine.discardDomino({ game, lordId });\n }\n\n const domino = lord.dominoPicked;\n const kingdom = player.kingdom;\n const maxSize = getMaxKingdomSize(game);\n const validPlacements = getValidPlacementsUseCase(kingdom, domino, maxSize);\n\n const placement = strategy.choosePlacement({\n game,\n lordId,\n domino,\n kingdom,\n validPlacements,\n });\n\n if (!placement) {\n return engine.discardDomino({ game, lordId });\n }\n\n return engine.placeDomino({\n game,\n lordId,\n position: placement.position,\n rotation: placement.rotation,\n });\n }\n\n // Age of Giants: placeGiant — place on a crown (mandatory, auto-handled)\n if (action === \"placeGiant\") {\n // Find the least valuable crown to cover (one with most crowns in smallest property)\n const player = game.players.find((p) => {\n const lord = game.lords.find((l) => l.id === lordId);\n return lord && p.id === lord.playerId;\n });\n if (player) {\n const availableCrowns = findCrownsNotCoveredByGiants(\n player.kingdom,\n player.giants ?? [],\n );\n if (availableCrowns.length > 0) {\n // Pick first available crown (simple bot behavior)\n return engine.placeGiant({\n game,\n lordId,\n position: availableCrowns[0]!,\n });\n }\n }\n return engine.skipOptionalAction({ game, lordId });\n }\n\n // Optional actions (Queendomino, Origins, AoG sendGiant) - skip them\n if (\n action === \"placeKnight\" ||\n action === \"constructBuilding\" ||\n action === \"useDragon\" ||\n action === \"placeFireToken\" ||\n action === \"recruitCaveman\" ||\n action === \"sendGiant\"\n ) {\n return engine.skipOptionalAction({ game, lordId });\n }\n\n // action === \"pass\"\n return engine.discardDomino({ game, lordId });\n};\n\n// ─── Mixed human/bot helpers ────────────────────────────────────────\n\n/**\n * Checks if the current turn belongs to a bot player.\n */\nexport const isBotTurn = (game: GameWithNextAction): boolean => {\n const lordId = game.nextAction.nextLord;\n const lord = game.lords.find((l) => l.id === lordId);\n const player = lord\n ? game.players.find((p) => p.id === lord.playerId)\n : undefined;\n return !!player?.bot;\n};\n\n/**\n * Plays all consecutive bot turns until a human turn or game end is reached.\n * Resolves each bot's strategy by name from the registry (or custom map).\n * Falls back to randomStrategy if the strategy name is not found.\n *\n * @param engine - The game engine instance\n * @param game - Current game state\n * @param customStrategies - Optional custom strategy map (name → BotStrategy)\n * @returns Updated game state paused at the next human turn or game end\n */\nexport const playBotTurns = (\n engine: GameEngine,\n game: GameState,\n customStrategies?: Record<string, BotStrategy>,\n): GameState => {\n let current = game;\n\n while (isGameWithNextAction(current) && isBotTurn(current)) {\n const lordId = current.nextAction.nextLord;\n const lord = current.lords.find((l) => l.id === lordId);\n const player = lord\n ? current.players.find((p) => p.id === lord.playerId)\n : undefined;\n const strategyName = player?.bot?.strategyName ?? \"random\";\n const strategy =\n getStrategy(strategyName, customStrategies) ?? randomStrategy;\n current = playBotTurn(engine, current, strategy);\n }\n\n return current;\n};\n","import type { PlayerInput } from \"@application/commands/addPlayersCommand.js\";\nimport type {\n GameState,\n GameWithNextAction,\n Position,\n Rotation,\n} from \"@core/domain/types/index.js\";\nimport type { GameEngine } from \"@core/portUserside/engine.js\";\n\n// ─── Types ──────────────────────────────────────────────────────────\n\n/**\n * The types of state-changing actions that can be recorded.\n */\nexport type ActionType =\n | \"createGame\"\n | \"addPlayers\"\n | \"addExtraRules\"\n | \"startGame\"\n | \"chooseDomino\"\n | \"placeDomino\"\n | \"discardDomino\"\n | \"placeGiant\"\n | \"sendGiant\";\n\n/**\n * Payload types for each action, containing only the command parameters\n * (excluding the game state, which is too large to store).\n */\nexport type ActionPayloadMap = {\n createGame: { mode: string; seed?: string };\n addPlayers: { players: PlayerInput[] };\n addExtraRules: { extraRules: string[] };\n startGame: Record<string, never>;\n chooseDomino: { lordId: string; dominoPick: number };\n placeDomino: { lordId: string; position: Position; rotation: Rotation };\n discardDomino: { lordId: string };\n placeGiant: { lordId: string; position: Position };\n sendGiant: {\n lordId: string;\n giantIndex: number;\n targetPlayerId: string;\n targetCrownPosition: Position;\n };\n};\n\n/**\n * A single recorded action in the game log.\n */\nexport type ActionEntry<T extends ActionType = ActionType> = {\n /** Auto-incrementing index (0-based) */\n id: number;\n /** Timestamp when the action was recorded (Date.now()) */\n timestamp: number;\n /** The type of action performed */\n action: T;\n /** Command parameters (excludes game state) */\n payload: ActionPayloadMap[T];\n /** Turn number after the action was applied */\n turn: number;\n};\n\n/**\n * An immutable log of all actions performed during a game.\n * Can be used to replay a game or analyze player decisions.\n *\n * @example\n * ```typescript\n * const { engine, getLog } = wrapWithActionLog(baseEngine);\n * let game = engine.createGame({ mode: 'Classic' });\n * game = engine.addPlayers({ game, players: ['Alice', 'Bob'] });\n * // ... play the game ...\n * const log = getLog();\n * console.log(log.entries); // all actions recorded\n * ```\n */\nexport type GameActionLog = {\n /** The game ID this log belongs to */\n gameId: string;\n /** Immutable array of recorded actions */\n entries: readonly ActionEntry[];\n};\n\n// ─── Construction ───────────────────────────────────────────────────\n\n/**\n * Creates an empty action log for a game.\n */\nexport const createActionLog = (gameId: string): GameActionLog => ({\n gameId,\n entries: [],\n});\n\n/**\n * Appends an action to the log (immutable — returns a new log).\n */\nexport const appendAction = (\n log: GameActionLog,\n entry: Omit<ActionEntry, \"id\" | \"timestamp\">,\n): GameActionLog => ({\n ...log,\n entries: [\n ...log.entries,\n {\n ...entry,\n id: log.entries.length,\n timestamp: Date.now(),\n },\n ],\n});\n\n// ─── Queries ────────────────────────────────────────────────────────\n\n/**\n * Returns all entries in the log.\n */\nexport const getActions = (log: GameActionLog): readonly ActionEntry[] =>\n log.entries;\n\n/**\n * Returns entries filtered by action type.\n */\nexport const getActionsByType = (\n log: GameActionLog,\n type: ActionType,\n): readonly ActionEntry[] => log.entries.filter((e) => e.action === type);\n\n/**\n * Returns entries filtered by turn number.\n */\nexport const getActionsByTurn = (\n log: GameActionLog,\n turn: number,\n): readonly ActionEntry[] => log.entries.filter((e) => e.turn === turn);\n\n// ─── Engine Wrapper ─────────────────────────────────────────────────\n\n/**\n * Wraps a GameEngine to automatically record every state-changing action.\n * Read-only methods are passed through unchanged.\n *\n * @param engine - The base game engine to wrap\n * @returns An object with the wrapped engine and a getLog() accessor\n *\n * @example\n * ```typescript\n * const { engine: logged, getLog } = wrapWithActionLog(baseEngine);\n * let game = logged.createGame({ mode: 'Classic' });\n * // ... play ...\n * const log = getLog(); // retrieve the full action log\n * ```\n */\nexport const wrapWithActionLog = (\n engine: GameEngine,\n): { engine: GameEngine; getLog: () => GameActionLog } => {\n let log = createActionLog(\"\");\n\n const record = <T extends ActionType>(\n action: T,\n payload: ActionPayloadMap[T],\n turn: number,\n ): void => {\n log = appendAction(log, { action, payload, turn });\n };\n\n const wrappedEngine: GameEngine = {\n // Read-only methods — pass through\n getModes: (cmd) => engine.getModes(cmd),\n getExtraRules: (cmd) => engine.getExtraRules(cmd),\n calculateScore: (cmd) => engine.calculateScore(cmd),\n getValidPlacements: (cmd) => engine.getValidPlacements(cmd),\n canPlaceDomino: (cmd) => engine.canPlaceDomino(cmd),\n serialize: (cmd) => engine.serialize(cmd),\n deserialize: (cmd) => engine.deserialize(cmd),\n getResults: (cmd) => engine.getResults(cmd),\n getDynastyResults: (cmd) => engine.getDynastyResults(cmd),\n\n // State-changing methods — record after execution\n createGame: (cmd) => {\n const game = engine.createGame(cmd);\n log = createActionLog(game.id);\n record(\"createGame\", { mode: cmd.mode, seed: cmd.seed }, game.turn);\n return game;\n },\n\n addPlayers: (cmd) => {\n const game = engine.addPlayers(cmd);\n record(\"addPlayers\", { players: cmd.players }, game.turn);\n return game;\n },\n\n addExtraRules: (cmd) => {\n const game = engine.addExtraRules(cmd);\n record(\"addExtraRules\", { extraRules: cmd.extraRules }, game.turn);\n return game;\n },\n\n startGame: (cmd) => {\n const game = engine.startGame(cmd);\n record(\"startGame\", {}, game.turn);\n return game;\n },\n\n chooseDomino: (cmd) => {\n const game = engine.chooseDomino(cmd);\n record(\n \"chooseDomino\",\n { lordId: cmd.lordId, dominoPick: cmd.dominoPick },\n game.turn,\n );\n return game;\n },\n\n placeDomino: (cmd) => {\n const game = engine.placeDomino(cmd);\n record(\n \"placeDomino\",\n {\n lordId: cmd.lordId,\n position: cmd.position,\n rotation: cmd.rotation,\n },\n game.turn,\n );\n return game;\n },\n\n discardDomino: (cmd) => {\n const game = engine.discardDomino(cmd);\n record(\"discardDomino\", { lordId: cmd.lordId }, game.turn);\n return game;\n },\n\n // Queendomino methods — pass through (no action log recording yet)\n placeKnight: (cmd) => engine.placeKnight(cmd),\n constructBuilding: (cmd) => engine.constructBuilding(cmd),\n useDragon: (cmd) => engine.useDragon(cmd),\n skipOptionalAction: (cmd) => engine.skipOptionalAction(cmd),\n\n // Origins methods — pass through (no action log recording yet)\n placeFireToken: (cmd) => engine.placeFireToken(cmd),\n recruitCaveman: (cmd) => engine.recruitCaveman(cmd),\n\n // Age of Giants methods — record after execution\n placeGiant: (cmd) => {\n const game = engine.placeGiant(cmd);\n record(\n \"placeGiant\",\n { lordId: cmd.lordId, position: cmd.position },\n game.turn,\n );\n return game;\n },\n\n sendGiant: (cmd) => {\n const game = engine.sendGiant(cmd);\n record(\n \"sendGiant\",\n {\n lordId: cmd.lordId,\n giantIndex: cmd.giantIndex,\n targetPlayerId: cmd.targetPlayerId,\n targetCrownPosition: cmd.targetCrownPosition,\n },\n game.turn,\n );\n return game;\n },\n };\n\n return {\n engine: wrappedEngine,\n getLog: () => log,\n };\n};\n\n// ─── Replay ─────────────────────────────────────────────────────────\n\n/**\n * Replays all actions from a log on a fresh engine to reconstruct the final game state.\n * The engine should use the same configuration (especially shuffleMethod) as the original game\n * to guarantee deterministic results when a seed is present.\n *\n * @param engine - A game engine instance (should match original config)\n * @param log - The action log to replay\n * @returns The final game state after replaying all actions\n */\nexport const replayActions = (\n engine: GameEngine,\n log: GameActionLog,\n): GameState => {\n if (log.entries.length === 0) {\n throw new Error(\"Cannot replay an empty action log\");\n }\n\n const firstEntry = log.entries[0];\n if (firstEntry?.action !== \"createGame\") {\n throw new Error(\"Action log must start with a createGame action\");\n }\n\n const firstPayload = firstEntry.payload as ActionPayloadMap[\"createGame\"];\n let game: GameState = engine.createGame({\n mode: firstPayload.mode,\n seed: firstPayload.seed,\n });\n\n for (let i = 1; i < log.entries.length; i++) {\n const entry = log.entries[i];\n if (!entry) continue;\n\n switch (entry.action) {\n case \"createGame\": {\n const payload = entry.payload as ActionPayloadMap[\"createGame\"];\n game = engine.createGame({ mode: payload.mode, seed: payload.seed });\n break;\n }\n case \"addPlayers\": {\n const payload = entry.payload as ActionPayloadMap[\"addPlayers\"];\n game = engine.addPlayers({ game, players: payload.players });\n break;\n }\n case \"addExtraRules\": {\n const payload = entry.payload as ActionPayloadMap[\"addExtraRules\"];\n game = engine.addExtraRules({\n game,\n extraRules: payload.extraRules,\n });\n break;\n }\n case \"startGame\": {\n game = engine.startGame({ game });\n break;\n }\n case \"chooseDomino\": {\n const payload = entry.payload as ActionPayloadMap[\"chooseDomino\"];\n game = engine.chooseDomino({\n game,\n lordId: payload.lordId,\n dominoPick: payload.dominoPick,\n });\n break;\n }\n case \"placeDomino\": {\n const payload = entry.payload as ActionPayloadMap[\"placeDomino\"];\n game = engine.placeDomino({\n game,\n lordId: payload.lordId,\n position: payload.position,\n rotation: payload.rotation,\n });\n break;\n }\n case \"discardDomino\": {\n const payload = entry.payload as ActionPayloadMap[\"discardDomino\"];\n game = engine.discardDomino({\n game,\n lordId: payload.lordId,\n });\n break;\n }\n case \"placeGiant\": {\n const payload = entry.payload as ActionPayloadMap[\"placeGiant\"];\n game = engine.placeGiant({\n game: game as GameWithNextAction,\n lordId: payload.lordId,\n position: payload.position,\n });\n break;\n }\n case \"sendGiant\": {\n const payload = entry.payload as ActionPayloadMap[\"sendGiant\"];\n game = engine.sendGiant({\n game: game as GameWithNextAction,\n lordId: payload.lordId,\n giantIndex: payload.giantIndex,\n targetPlayerId: payload.targetPlayerId,\n targetCrownPosition: payload.targetCrownPosition,\n });\n break;\n }\n }\n }\n\n return game;\n};\n","import { RedoError, UndoError } from \"@core/domain/errors/domainErrors.js\";\nimport type { GameState } from \"@core/domain/types/index.js\";\n\n/**\n * Manages a history of game states for undo/redo support.\n * Uses a snapshot-based approach: each state is stored as a full GameState.\n *\n * @example\n * ```typescript\n * let history = createGameHistory(initialGame);\n * const newGame = engine.chooseDomino({ game: history.current, ... });\n * history = pushState(history, newGame);\n * history = undo(history); // back to initialGame\n * history = redo(history); // forward to newGame\n * ```\n */\nexport type GameHistory = {\n /** The current game state */\n current: GameState;\n /** Stack of previous states (most recent last) */\n past: GameState[];\n /** Stack of undone states (most recent last) */\n future: GameState[];\n};\n\n/**\n * Creates a new game history initialized with a game state.\n *\n * @param initialState - The starting game state\n * @returns A new GameHistory with empty past and future\n */\nexport const createGameHistory = (initialState: GameState): GameHistory => ({\n current: initialState,\n past: [],\n future: [],\n});\n\n/**\n * Records a new game state in the history.\n * The current state is pushed to the past stack, and the future stack is cleared\n * (branching from a previous undo point discards the old future).\n *\n * @param history - The current history\n * @param newState - The new game state to record\n * @returns Updated history with the new state as current\n */\nexport const pushState = (\n history: GameHistory,\n newState: GameState,\n): GameHistory => ({\n current: newState,\n past: [...history.past, history.current],\n future: [],\n});\n\n/**\n * Reverts to the previous game state.\n * The current state is moved to the future stack for potential redo.\n *\n * @param history - The current history\n * @returns Updated history with the previous state as current\n * @throws {UndoError} If there is no previous state to revert to\n */\nexport const undo = (history: GameHistory): GameHistory => {\n if (history.past.length === 0) {\n throw new UndoError();\n }\n\n const previous = history.past[history.past.length - 1]!;\n return {\n current: previous,\n past: history.past.slice(0, -1),\n future: [...history.future, history.current],\n };\n};\n\n/**\n * Re-applies a previously undone game state.\n * The current state is moved to the past stack.\n *\n * @param history - The current history\n * @returns Updated history with the next undone state as current\n * @throws {RedoError} If there is no undone state to re-apply\n */\nexport const redo = (history: GameHistory): GameHistory => {\n if (history.future.length === 0) {\n throw new RedoError();\n }\n\n const next = history.future[history.future.length - 1]!;\n return {\n current: next,\n past: [...history.past, history.current],\n future: history.future.slice(0, -1),\n };\n};\n\n/**\n * Checks whether an undo operation is available.\n */\nexport const canUndo = (history: GameHistory): boolean =>\n history.past.length > 0;\n\n/**\n * Checks whether a redo operation is available.\n */\nexport const canRedo = (history: GameHistory): boolean =>\n history.future.length > 0;\n\n/**\n * Clears the undo/redo history, keeping only the current state.\n *\n * @param history - The current history\n * @returns A new history with empty past and future\n */\nexport const clearHistory = (history: GameHistory): GameHistory => ({\n current: history.current,\n past: [],\n future: [],\n});\n\n/**\n * Returns the number of states in the past and future stacks.\n */\nexport const getHistorySize = (\n history: GameHistory,\n): { past: number; future: number } => ({\n past: history.past.length,\n future: history.future.length,\n});\n","import type { GameEngine } from \"@core/portUserside/engine\";\nimport { type DebugOptions, wrapWithDebug } from \"@core/useCases/gameDebug.js\";\nimport { wrapWithEvents } from \"@core/useCases/gameEvents.js\";\nimport { configureEngine, type EngineConfig } from \"./config.js\";\n\n// Commands\nexport * from \"@application/commands/index.js\";\nexport { validateGameState } from \"@core/domain/entities/validateGameState.js\";\n// Domain errors\nexport * from \"@core/domain/errors/domainErrors.js\";\n// Domain types\nexport * from \"@core/domain/types/index.js\";\n// i18n\nexport * from \"@core/i18n/translations.js\";\n// Ports\nexport * from \"@core/portServerside/index.js\";\nexport * from \"@core/portUserside/engine.js\";\n// Bot / AI player\nexport {\n advancedStrategy,\n type BotStrategy,\n expertStrategy,\n greedyStrategy,\n isBotTurn,\n type PickContext,\n type PlaceContext,\n playBotTurn,\n playBotTurns,\n randomStrategy,\n} from \"@core/useCases/bot.js\";\n// Bot strategy registry\nexport {\n getStrategy,\n getStrategyNames,\n type StrategyName,\n} from \"@core/useCases/botRegistry.js\";\nexport type { ConstructBuildingUseCase } from \"@core/useCases/constructBuilding.js\";\n// Action log (game history / replay)\nexport {\n type ActionEntry,\n type ActionPayloadMap,\n type ActionType,\n appendAction,\n createActionLog,\n type GameActionLog,\n getActions,\n getActionsByTurn,\n getActionsByType,\n replayActions,\n wrapWithActionLog,\n} from \"@core/useCases/gameActionLog.js\";\n// Debug mode\nexport {\n type DebugLogEntry,\n type DebugLogger,\n type DebugLogLevel,\n type DebugOptions,\n type GameStateSummary,\n summarizeGameState,\n wrapWithDebug,\n} from \"@core/useCases/gameDebug.js\";\n// Game events\nexport {\n type GameEventCallbacks,\n wrapWithEvents,\n} from \"@core/useCases/gameEvents.js\";\n// History (undo/redo)\nexport {\n canRedo,\n canUndo,\n clearHistory,\n createGameHistory,\n type GameHistory,\n getHistorySize,\n pushState,\n redo,\n undo,\n} from \"@core/useCases/gameHistory.js\";\nexport type { DynastyResult } from \"@core/useCases/getDynastyResult.js\";\n// Use cases (for advanced usage)\nexport type { ValidPlacement } from \"@core/useCases/getValidPlacements.js\";\nexport type { PlaceFireTokenUseCase } from \"@core/useCases/placeFireToken.js\";\nexport type { PlaceGiantUseCase } from \"@core/useCases/placeGiant.js\";\nexport type { PlaceKnightUseCase } from \"@core/useCases/placeKnight.js\";\nexport type { RecruitCavemanUseCase } from \"@core/useCases/recruitCaveman.js\";\nexport type { SendGiantUseCase } from \"@core/useCases/sendGiant.js\";\nexport {\n createSavePoint,\n deserializeGame,\n type GameSavePoint,\n restoreFromSavePoint,\n serializeGame,\n} from \"@core/useCases/serialization.js\";\nexport type { SkipOptionalActionUseCase } from \"@core/useCases/skipOptionalAction.js\";\nexport type { UseDragonUseCase } from \"@core/useCases/useDragon.js\";\n// Configuration\nexport type { EngineConfig };\n\n/**\n * Creates a new Kingdomino game engine instance.\n *\n * @param config - Configuration options for the engine\n * @returns A fully configured GameEngine instance\n *\n * @example\n * ```typescript\n * // Basic usage\n * const engine = createGameEngine({});\n *\n * // With logging\n * const engine = createGameEngine({ logging: true });\n *\n * // With event callbacks\n * const engine = createGameEngine({\n * events: {\n * onDominoPlaced: ({ lordId }) => console.log(`${lordId} placed`),\n * onGameEnd: () => console.log('Game over!'),\n * },\n * });\n * ```\n */\nexport const createGameEngine = (config: Partial<EngineConfig>): GameEngine => {\n const {\n createGameHandler,\n getModesHandler,\n getExtraRulesHandler,\n addPlayersHandler,\n addExtraRulesHandler,\n startGameHandler,\n chooseDominoHandler,\n placeDominoHandler,\n discardDominoHandler,\n getResultHandler,\n calculateScoreHandler,\n getValidPlacementsHandler,\n canPlaceDominoHandler,\n serializeGameHandler,\n deserializeGameHandler,\n getDynastyResultHandler,\n placeGiantHandler,\n sendGiantHandler,\n placeKnightHandler,\n constructBuildingHandler,\n useDragonHandler,\n placeFireTokenHandler,\n recruitCavemanHandler,\n skipOptionalActionHandler,\n } = configureEngine(config);\n\n let engine: GameEngine = {\n getModes: (command) => getModesHandler(command),\n getExtraRules: (command) => getExtraRulesHandler(command),\n createGame: (command) => createGameHandler(command),\n addPlayers: (command) => addPlayersHandler(command),\n addExtraRules: (command) => addExtraRulesHandler(command),\n startGame: (command) => startGameHandler(command),\n chooseDomino: (command) => chooseDominoHandler(command),\n placeDomino: (command) => placeDominoHandler(command),\n discardDomino: (command) => discardDominoHandler(command),\n getResults: (command) => getResultHandler(command),\n calculateScore: (command) => calculateScoreHandler(command),\n getValidPlacements: (command) => getValidPlacementsHandler(command),\n canPlaceDomino: (command) => canPlaceDominoHandler(command),\n serialize: (command) => serializeGameHandler(command),\n deserialize: (command) => deserializeGameHandler(command),\n getDynastyResults: (command) => getDynastyResultHandler(command),\n placeGiant: (command) => placeGiantHandler(command),\n sendGiant: (command) => sendGiantHandler(command),\n placeKnight: (command) => placeKnightHandler(command),\n constructBuilding: (command) => constructBuildingHandler(command),\n useDragon: (command) => useDragonHandler(command),\n placeFireToken: (command) => placeFireTokenHandler(command),\n recruitCaveman: (command) => recruitCavemanHandler(command),\n skipOptionalAction: (command) => skipOptionalActionHandler(command),\n };\n\n if (config.events) {\n engine = wrapWithEvents(engine, config.events);\n }\n\n if (config.debug) {\n const debugOptions: DebugOptions | undefined =\n typeof config.debug === \"object\" ? config.debug : undefined;\n engine = wrapWithDebug(engine, debugOptions);\n }\n\n return engine;\n};\n"],"mappings":";AA+CO,IAAM,YAAY;AAAA;AAAA,EAEvB,YAAY;AAAA;AAAA,EAEZ,SAAS;AAAA;AAAA,EAET,OAAO;AAAA;AAAA,EAEP,QAAQ;AACV;AA8CO,IAAM,uBAAuB,CAClC,SAC+B;AAC/B,SAAO,KAAK,WAAW,SAAS;AAClC;AAOO,IAAM,qBAAqB,CAChC,SAC6B;AAC7B,SAAO,KAAK,WAAW,SAAS;AAClC;;;ACrDO,IAAM,qBAAqB,CAAC,SAAsC;AACvE,QAAM,aAAa,qBAAqB,IAAI,IACxC,UAAU,KAAK,WAAW,UAAU,KACpC,QAAQ,KAAK,WAAW,IAAI;AAEhC,SAAO;AAAA,IACL,QAAQ,KAAK;AAAA,IACb,MAAM,KAAK;AAAA,IACX;AAAA,IACA,cAAc,KAAK,QAAQ;AAAA,IAC3B,mBAAmB,KAAK,SAAS;AAAA,IACjC,sBAAsB,KAAK,gBAAgB;AAAA,IAC3C,YAAY,KAAK,MAAM;AAAA,EACzB;AACF;AAEA,IAAM,qBAAkC;AAAA,EACtC,KAAK,CAAC,UAAyB;AAC7B,UAAM,QAAQ,MAAM,MAAM,YAAY,EAAE,OAAO,CAAC;AAChD,UAAM,OAAO,mBAAmB,MAAM,SAAS,IAAI,KAAK,IAAI,MAAM,MAAM;AAExE,QAAI,MAAM,UAAU,SAAS;AAC3B,cAAQ,MAAM,GAAG,IAAI,aAAa,MAAM,KAAK,EAAE;AAC/C;AAAA,IACF;AAEA,QAAI,MAAM,SAAS;AACjB,YAAM,IAAI,MAAM;AAChB,cAAQ;AAAA,QACN,GAAG,IAAI,WAAW,EAAE,IAAI,SAAS,EAAE,UAAU,YAAY,EAAE,YAAY,aAAa,EAAE,iBAAiB;AAAA,MACzG;AAAA,IACF,OAAO;AACL,cAAQ,IAAI,IAAI;AAAA,IAClB;AAAA,EACF;AACF;AAEA,IAAM,cAAc,CAAC,UAAuC;AAC1D,SACE,OAAO,UAAU,YACjB,UAAU,QACV,QAAQ,SACR,gBAAgB,SAChB,aAAa,SACb,cAAc;AAElB;AAIA,IAAM,mBAAmB,CAAC,QAAyC;AACjE,SACE,OAAO,QAAQ,YACf,QAAQ,QACR,UAAU,OACV,YAAa,IAAwB,IAAI;AAE7C;AAEA,IAAM,gBAAgB,CAAC,QAAsD;AAC3E,MAAI,OAAO,QAAQ,YAAY,QAAQ,KAAM,QAAO;AAEpD,QAAM,SAAS;AACf,QAAM,SAAkC,CAAC;AAEzC,MAAI,UAAU,OAAQ,QAAO,OAAO,OAAO;AAC3C,MAAI,YAAY,OAAQ,QAAO,SAAS,OAAO;AAC/C,MAAI,gBAAgB,OAAQ,QAAO,aAAa,OAAO;AACvD,MAAI,cAAc,OAAQ,QAAO,WAAW,OAAO;AACnD,MAAI,cAAc,OAAQ,QAAO,WAAW,OAAO;AACnD,MAAI,aAAa,OAAQ,QAAO,UAAU,OAAO;AACjD,MAAI,gBAAgB,OAAQ,QAAO,aAAa,OAAO;AAEvD,SAAO,OAAO,KAAK,MAAM,EAAE,SAAS,IAAI,SAAS;AACnD;AAIA,IAAM,aAAa,CACjB,QACA,IACA,QACA,UAC8B;AAC9B,SAAO,CAAC,QAAe;AACrB,UAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AAGzC,UAAM,gBACJ,UAAU,aAAa,iBAAiB,GAAG,IACvC,mBAAmB,IAAI,IAAI,IAC3B;AAEN,UAAM,cAA6B;AAAA,MACjC;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP,SAAS;AAAA,MACT,QAAQ,UAAU,YAAY,cAAc,GAAG,IAAI;AAAA,IACrD;AAEA,WAAO,IAAI,WAAW;AAGtB,UAAM,QAAQ,YAAY,IAAI;AAC9B,QAAI;AACJ,QAAI;AACF,eAAS,GAAG,GAAG;AAAA,IACjB,SAASA,MAAK;AACZ,YAAMC,cAAa,KAAK,OAAO,YAAY,IAAI,IAAI,SAAS,GAAG,IAAI;AACnE,YAAM,aAA4B;AAAA,QAChC,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QAClC;AAAA,QACA,OAAO;AAAA,QACP,SAAS;AAAA,QACT,OAAOD,gBAAe,QAAQA,KAAI,UAAU,OAAOA,IAAG;AAAA,QACtD,YAAAC;AAAA,MACF;AACA,aAAO,IAAI,UAAU;AACrB,YAAMD;AAAA,IACR;AAEA,UAAM,aAAa,KAAK,OAAO,YAAY,IAAI,IAAI,SAAS,GAAG,IAAI;AAGnE,UAAM,eACJ,UAAU,aAAa,YAAY,MAAM,IACrC,mBAAmB,MAAmB,IACtC;AAEN,UAAM,aAA4B;AAAA,MAChC,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC;AAAA,MACA,OAAO;AAAA,MACP,SAAS;AAAA,MACT;AAAA,MACA,WACE,UAAU,aAAa,YAAY,MAAM,IACpC,SACD;AAAA,IACR;AAEA,WAAO,IAAI,UAAU;AAErB,WAAO;AAAA,EACT;AACF;AAkBO,IAAM,gBAAgB,CAC3B,QACA,YACe;AACf,QAAM,SAAS,SAAS,UAAU;AAClC,QAAM,QAAQ,SAAS,SAAS;AAEhC,SAAO;AAAA,IACL,UAAU,WAAW,YAAY,OAAO,UAAU,QAAQ,KAAK;AAAA,IAC/D,eAAe;AAAA,MACb;AAAA,MACA,OAAO;AAAA,MACP;AAAA,MACA;AAAA,IACF;AAAA,IACA,YAAY,WAAW,cAAc,OAAO,YAAY,QAAQ,KAAK;AAAA,IACrE,YAAY,WAAW,cAAc,OAAO,YAAY,QAAQ,KAAK;AAAA,IACrE,eAAe;AAAA,MACb;AAAA,MACA,OAAO;AAAA,MACP;AAAA,MACA;AAAA,IACF;AAAA,IACA,WAAW,WAAW,aAAa,OAAO,WAAW,QAAQ,KAAK;AAAA,IAClE,cAAc;AAAA,MACZ;AAAA,MACA,OAAO;AAAA,MACP;AAAA,MACA;AAAA,IACF;AAAA,IACA,aAAa,WAAW,eAAe,OAAO,aAAa,QAAQ,KAAK;AAAA,IACxE,eAAe;AAAA,MACb;AAAA,MACA,OAAO;AAAA,MACP;AAAA,MACA;AAAA,IACF;AAAA,IACA,YAAY,WAAW,cAAc,OAAO,YAAY,QAAQ,KAAK;AAAA,IACrE,gBAAgB;AAAA,MACd;AAAA,MACA,OAAO;AAAA,MACP;AAAA,MACA;AAAA,IACF;AAAA,IACA,oBAAoB;AAAA,MAClB;AAAA,MACA,OAAO;AAAA,MACP;AAAA,MACA;AAAA,IACF;AAAA,IACA,gBAAgB;AAAA,MACd;AAAA,MACA,OAAO;AAAA,MACP;AAAA,MACA;AAAA,IACF;AAAA,IACA,WAAW,WAAW,aAAa,OAAO,WAAW,QAAQ,KAAK;AAAA,IAClE,aAAa,WAAW,eAAe,OAAO,aAAa,QAAQ,KAAK;AAAA,IACxE,mBAAmB;AAAA,MACjB;AAAA,MACA,OAAO;AAAA,MACP;AAAA,MACA;AAAA,IACF;AAAA,IACA,aAAa,WAAW,eAAe,OAAO,aAAa,QAAQ,KAAK;AAAA,IACxE,mBAAmB;AAAA,MACjB;AAAA,MACA,OAAO;AAAA,MACP;AAAA,MACA;AAAA,IACF;AAAA,IACA,WAAW,WAAW,aAAa,OAAO,WAAW,QAAQ,KAAK;AAAA,IAClE,oBAAoB;AAAA,MAClB;AAAA,MACA,OAAO;AAAA,MACP;AAAA,MACA;AAAA,IACF;AAAA,IACA,gBAAgB;AAAA,MACd;AAAA,MACA,OAAO;AAAA,MACP;AAAA,MACA;AAAA,IACF;AAAA,IACA,gBAAgB;AAAA,MACd;AAAA,MACA,OAAO;AAAA,MACP;AAAA,MACA;AAAA,IACF;AAAA,IACA,YAAY,WAAW,cAAc,OAAO,YAAY,QAAQ,KAAK;AAAA,IACrE,WAAW,WAAW,aAAa,OAAO,WAAW,QAAQ,KAAK;AAAA,EACpE;AACF;;;AC3OA,IAAM,cAAc,CAAC,SACnB,mBAAmB,IAAI,KAAK,KAAK,WAAW,SAAS;AAchD,IAAM,iBAAiB,CAC5B,QACA,eACgB;AAAA;AAAA,EAEhB,UAAU,CAAC,QAAQ,OAAO,SAAS,GAAG;AAAA,EACtC,eAAe,CAAC,QAAQ,OAAO,cAAc,GAAG;AAAA,EAChD,gBAAgB,CAAC,QAAQ,OAAO,eAAe,GAAG;AAAA,EAClD,oBAAoB,CAAC,QAAQ,OAAO,mBAAmB,GAAG;AAAA,EAC1D,gBAAgB,CAAC,QAAQ,OAAO,eAAe,GAAG;AAAA,EAClD,WAAW,CAAC,QAAQ,OAAO,UAAU,GAAG;AAAA,EACxC,aAAa,CAAC,QAAQ,OAAO,YAAY,GAAG;AAAA,EAC5C,YAAY,CAAC,QAAQ,OAAO,WAAW,GAAG;AAAA,EAC1C,mBAAmB,CAAC,QAAQ,OAAO,kBAAkB,GAAG;AAAA;AAAA,EAGxD,YAAY,CAAC,QAAQ;AACnB,UAAM,OAAO,OAAO,WAAW,GAAG;AAClC,cAAU,gBAAgB,EAAE,KAAK,CAAC;AAClC,WAAO;AAAA,EACT;AAAA,EAEA,YAAY,CAAC,QAAQ;AACnB,UAAM,OAAO,OAAO,WAAW,GAAG;AAClC,cAAU,iBAAiB,EAAE,KAAK,CAAC;AACnC,WAAO;AAAA,EACT;AAAA,EAEA,eAAe,CAAC,QAAQ,OAAO,cAAc,GAAG;AAAA,EAEhD,WAAW,CAAC,QAAQ;AAClB,UAAM,OAAO,OAAO,UAAU,GAAG;AACjC,cAAU,gBAAgB,EAAE,KAAK,CAAC;AAClC,cAAU,cAAc,EAAE,MAAM,MAAM,KAAK,KAAK,CAAC;AACjD,WAAO;AAAA,EACT;AAAA,EAEA,cAAc,CAAC,QAAQ;AACrB,UAAM,aAAa,IAAI,KAAK;AAC5B,UAAM,OAAO,OAAO,aAAa,GAAG;AACpC,cAAU,iBAAiB;AAAA,MACzB;AAAA,MACA,QAAQ,IAAI;AAAA,MACZ,cAAc,IAAI;AAAA,IACpB,CAAC;AAGD,QAAI,KAAK,SAAS,YAAY;AAC5B,gBAAU,YAAY,EAAE,MAAM,MAAM,WAAW,CAAC;AAChD,gBAAU,cAAc,EAAE,MAAM,MAAM,KAAK,KAAK,CAAC;AAAA,IACnD;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,aAAa,CAAC,QAAQ;AACpB,UAAM,OAAO,OAAO,YAAY,GAAG;AACnC,cAAU,iBAAiB,EAAE,MAAM,QAAQ,IAAI,OAAO,CAAC;AAEvD,QAAI,YAAY,IAAI,GAAG;AACrB,gBAAU,YAAY,EAAE,KAAK,CAAC;AAAA,IAChC;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,eAAe,CAAC,QAAQ;AACtB,UAAM,OAAO,OAAO,cAAc,GAAG;AACrC,cAAU,oBAAoB,EAAE,MAAM,QAAQ,IAAI,OAAO,CAAC;AAE1D,QAAI,YAAY,IAAI,GAAG;AACrB,gBAAU,YAAY,EAAE,KAAK,CAAC;AAAA,IAChC;AAEA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,aAAa,CAAC,QAAQ;AACpB,UAAM,OAAO,OAAO,YAAY,GAAG;AACnC,cAAU,iBAAiB,EAAE,MAAM,QAAQ,IAAI,OAAO,CAAC;AACvD,WAAO;AAAA,EACT;AAAA,EAEA,mBAAmB,CAAC,QAAQ;AAC1B,UAAM,OAAO,OAAO,kBAAkB,GAAG;AACzC,cAAU,wBAAwB;AAAA,MAChC;AAAA,MACA,QAAQ,IAAI;AAAA,MACZ,YAAY,IAAI;AAAA,IAClB,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,WAAW,CAAC,QAAQ;AAClB,UAAM,OAAO,OAAO,UAAU,GAAG;AACjC,cAAU,eAAe;AAAA,MACvB;AAAA,MACA,QAAQ,IAAI;AAAA,MACZ,YAAY,IAAI;AAAA,IAClB,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,oBAAoB,CAAC,QAAQ,OAAO,mBAAmB,GAAG;AAAA;AAAA,EAG1D,gBAAgB,CAAC,QAAQ;AACvB,UAAM,OAAO,OAAO,eAAe,GAAG;AACtC,cAAU,oBAAoB,EAAE,MAAM,QAAQ,IAAI,OAAO,CAAC;AAC1D,WAAO;AAAA,EACT;AAAA,EAEA,gBAAgB,CAAC,QAAQ;AACvB,UAAM,OAAO,OAAO,eAAe,GAAG;AACtC,cAAU,qBAAqB;AAAA,MAC7B;AAAA,MACA,QAAQ,IAAI;AAAA,MACZ,WAAW,IAAI;AAAA,IACjB,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,YAAY,CAAC,QAAQ;AACnB,UAAM,OAAO,OAAO,WAAW,GAAG;AAClC,cAAU,gBAAgB,EAAE,MAAM,QAAQ,IAAI,OAAO,CAAC;AACtD,WAAO;AAAA,EACT;AAAA,EAEA,WAAW,CAAC,QAAQ;AAClB,UAAM,OAAO,OAAO,UAAU,GAAG;AACjC,cAAU,cAAc;AAAA,MACtB;AAAA,MACA,QAAQ,IAAI;AAAA,MACZ,gBAAgB,IAAI;AAAA,IACtB,CAAC;AACD,WAAO;AAAA,EACT;AACF;;;ACxOO,IAAM,gBAAgB,CAAC,qBAAsC;AAClE,QAAM,gBAAgB,CAAC,OAAe,YAA4B;AAChE,UAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,WAAO,GAAG,SAAS,qBAAqB,KAAK,KAAK,OAAO;AAAA,EAC3D;AAEA,SAAO;AAAA,IACL,MAAM,CAAC,YAAoB;AACzB,UAAI,kBAAkB;AACpB,gBAAQ,IAAI,cAAc,QAAQ,OAAO,CAAC;AAAA,MAC5C;AAAA,IACF;AAAA,IACA,OAAO,CAAC,YAAoB;AAC1B,UAAI,kBAAkB;AACpB,gBAAQ,MAAM,cAAc,SAAS,OAAO,CAAC;AAAA,MAC/C;AAAA,IACF;AAAA,EACF;AACF;AAMO,IAAM,eAAuB;AAAA,EAClC,MAAM,MAAM;AAAA,EAAC;AAAA,EACb,OAAO,MAAM;AAAA,EAAC;AAChB;;;ACnCA;AAAA,EACE,EAAE,IAAM,GAAG,MAAQ,cAAc,MAAQ,GAAG,gBAAkB,EAAE,MAAQ,SAAS,QAAU,EAAE,GAAG,QAAU,GAAG,QAAU,EAAE;AAAA,EACzH,EAAE,IAAM,GAAG,MAAQ,cAAc,MAAQ,GAAG,gBAAkB,EAAE,MAAQ,SAAS,QAAU,EAAE,GAAG,QAAU,GAAG,QAAU,EAAE;AAAA,EACzH,EAAE,IAAM,GAAG,MAAQ,eAAe,MAAQ,GAAG,QAAU,GAAG,QAAU,GAAG,gBAAkB,EAAE,MAAQ,cAAc,SAAW,UAAU,QAAU,EAAE,EAAE;AAAA,EACpJ,EAAE,IAAM,GAAG,MAAQ,oBAAoB,MAAQ,GAAG,gBAAkB,EAAE,MAAQ,SAAS,QAAU,EAAE,GAAG,QAAU,GAAG,QAAU,GAAG,gBAAkB,EAAE,MAAQ,cAAc,SAAW,OAAO,QAAU,EAAE,EAAE;AAAA,EAC1M,EAAE,IAAM,GAAG,MAAQ,oBAAoB,MAAQ,GAAG,gBAAkB,EAAE,MAAQ,SAAS,QAAU,EAAE,GAAG,QAAU,GAAG,QAAU,GAAG,gBAAkB,EAAE,MAAQ,cAAc,SAAW,OAAO,QAAU,EAAE,EAAE;AAAA,EAC1M,EAAE,IAAM,GAAG,MAAQ,oBAAoB,MAAQ,GAAG,QAAU,GAAG,QAAU,GAAG,gBAAkB,EAAE,MAAQ,cAAc,SAAW,SAAS,QAAU,EAAE,EAAE;AAAA,EACxJ,EAAE,IAAM,GAAG,MAAQ,oBAAoB,MAAQ,GAAG,QAAU,GAAG,QAAU,GAAG,gBAAkB,EAAE,MAAQ,YAAY,QAAU,EAAE,EAAE;AAAA,EAClI,EAAE,IAAM,GAAG,MAAQ,gBAAgB,MAAQ,GAAG,QAAU,GAAG,QAAU,GAAG,gBAAkB,EAAE,MAAQ,YAAY,QAAU,EAAE,EAAE;AAAA,EAC9H,EAAE,IAAM,GAAG,MAAQ,cAAc,MAAQ,GAAG,QAAU,GAAG,QAAU,GAAG,gBAAkB,EAAE,MAAQ,eAAe,QAAU,EAAE,EAAE;AAAA,EAC/H,EAAE,IAAM,IAAI,MAAQ,YAAY,MAAQ,GAAG,gBAAkB,EAAE,MAAQ,SAAS,QAAU,EAAE,GAAG,QAAU,GAAG,QAAU,GAAG,gBAAkB,EAAE,MAAQ,QAAQ,QAAU,EAAE,EAAE;AAAA,EAC3K,EAAE,IAAM,IAAI,MAAQ,mBAAmB,MAAQ,GAAG,QAAU,GAAG,QAAU,GAAG,gBAAkB,EAAE,MAAQ,QAAQ,QAAU,EAAE,EAAE;AAAA,EAC9H,EAAE,IAAM,IAAI,MAAQ,mBAAmB,MAAQ,GAAG,QAAU,GAAG,QAAU,GAAG,gBAAkB,EAAE,MAAQ,QAAQ,QAAU,EAAE,EAAE;AAAA,EAC9H,EAAE,IAAM,IAAI,MAAQ,iBAAiB,MAAQ,GAAG,QAAU,GAAG,QAAU,GAAG,gBAAkB,EAAE,MAAQ,QAAQ,QAAU,EAAE,EAAE;AAAA,EAC5H,EAAE,IAAM,IAAI,MAAQ,kBAAkB,MAAQ,GAAG,QAAU,GAAG,QAAU,GAAG,gBAAkB,EAAE,MAAQ,eAAe,QAAU,EAAE,EAAE;AAAA,EACpI,EAAE,IAAM,IAAI,MAAQ,wBAAwB,MAAQ,GAAG,QAAU,GAAG,QAAU,GAAG,gBAAkB,EAAE,MAAQ,QAAQ,QAAU,EAAE,EAAE;AAAA,EACnI,EAAE,IAAM,IAAI,MAAQ,yBAAyB,MAAQ,GAAG,QAAU,GAAG,QAAU,GAAG,gBAAkB,EAAE,MAAQ,YAAY,QAAU,EAAE,EAAE;AAAA,EACxI,EAAE,IAAM,IAAI,MAAQ,wBAAwB,MAAQ,GAAG,gBAAkB,EAAE,MAAQ,SAAS,QAAU,EAAE,GAAG,QAAU,GAAG,QAAU,GAAG,gBAAkB,EAAE,MAAQ,eAAe,QAAU,EAAE,EAAE;AAAA,EAC9L,EAAE,IAAM,IAAI,MAAQ,eAAe,MAAQ,GAAG,QAAU,GAAG,QAAU,GAAG,gBAAkB,EAAE,MAAQ,cAAc,SAAW,OAAO,QAAU,EAAE,EAAE;AACpJ;;;ACTA,IAAM,gBAAgB,MAA2B;AAC/C,QAAM,YAA4B,kBAAc,IAAI,CAAC,MAAM;AACzD,UAAM,OAAqB;AAAA,MACzB,IAAI,EAAE;AAAA,MACN,MAAM,EAAE;AAAA,MACR,MAAM,EAAE;AAAA,MACR,QAAQ,EAAE;AAAA,MACV,QAAQ,EAAE;AAAA,IACZ;AAEA,QAAI,EAAE,gBAAgB;AACpB,WAAK,iBAAiB;AAAA,QACpB,MAAM,EAAE,eAAe;AAAA,QACvB,QAAQ,EAAE,eAAe;AAAA,MAC3B;AAAA,IACF;AAEA,QAAI,oBAAoB,KAAK,EAAE,gBAAgB;AAC7C,WAAK,iBAAiB;AAAA,QACpB,MAAM,EAAE,eAAe;AAAA,QACvB,QAAQ,EAAE,eAAe;AAAA,QACzB,GAAI,aAAa,EAAE,kBAAkB;AAAA,UACnC,SAAS,EAAE,eAAe;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT,CAAC;AAED,SAAO;AAAA,IACL,QAAQ,MAAM;AAAA,EAChB;AACF;AAEA,IAAO,wBAAQ;;;AC7Cf;AAAA,EACE,EAAE,MAAQ,kBAAkB,IAAM,GAAG,YAAc,iBAAiB,gBAAkB,EAAE;AAAA,EACxF,EAAE,MAAQ,kBAAkB,IAAM,GAAG,YAAc,iBAAiB,gBAAkB,EAAE;AAAA,EACxF,EAAE,MAAQ,kBAAkB,IAAM,GAAG,YAAc,aAAa,gBAAkB,EAAE;AAAA,EACpF,EAAE,MAAQ,kBAAkB,IAAM,GAAG,YAAc,aAAa,gBAAkB,EAAE;AAAA,EACpF,EAAE,MAAQ,kBAAkB,IAAM,GAAG,YAAc,kBAAkB,gBAAkB,EAAE;AAAA,EACzF,EAAE,MAAQ,kBAAkB,IAAM,GAAG,YAAc,kBAAkB,gBAAkB,EAAE;AAAA,EACzF,EAAE,MAAQ,kBAAkB,IAAM,GAAG,YAAc,kBAAkB,gBAAkB,EAAE;AAAA,EACzF,EAAE,MAAQ,kBAAkB,IAAM,GAAG,YAAc,kBAAkB,gBAAkB,EAAE;AAAA,EACzF,EAAE,MAAQ,kBAAkB,IAAM,GAAG,YAAc,WAAW,gBAAkB,EAAE;AAAA,EAClF,EAAE,MAAQ,kBAAkB,IAAM,IAAI,YAAc,WAAW,gBAAkB,EAAE;AAAA,EACnF,EAAE,MAAQ,kBAAkB,IAAM,IAAI,YAAc,YAAY,gBAAkB,EAAE;AAAA,EACpF,EAAE,MAAQ,kBAAkB,IAAM,IAAI,YAAc,YAAY,gBAAkB,EAAE;AAAA,EACpF,EAAE,MAAQ,kBAAkB,IAAM,IAAI,YAAc,YAAY,gBAAkB,EAAE;AAAA,EACpF,EAAE,MAAQ,kBAAkB,IAAM,IAAI,YAAc,YAAY,gBAAkB,EAAE;AAAA,EACpF,EAAE,MAAQ,WAAW,IAAM,IAAI,aAAe,SAAS,OAAS,EAAE;AAAA,EAClE,EAAE,MAAQ,WAAW,IAAM,IAAI,aAAe,SAAS,OAAS,EAAE;AAAA,EAClE,EAAE,MAAQ,WAAW,IAAM,IAAI,aAAe,SAAS,OAAS,EAAE;AAAA,EAClE,EAAE,MAAQ,WAAW,IAAM,IAAI,aAAe,SAAS,OAAS,EAAE;AAAA,EAClE,EAAE,MAAQ,WAAW,IAAM,IAAI,aAAe,UAAU,OAAS,EAAE;AAAA,EACnE,EAAE,MAAQ,WAAW,IAAM,IAAI,aAAe,UAAU,OAAS,EAAE;AAAA,EACnE,EAAE,MAAQ,WAAW,IAAM,IAAI,aAAe,UAAU,OAAS,EAAE;AAAA,EACnE,EAAE,MAAQ,WAAW,IAAM,IAAI,aAAe,UAAU,OAAS,EAAE;AACrE;;;ACbA,IAAM,aAAa,CAAC,QAOD;AACjB,MAAI,IAAI,SAAS,kBAAkB;AACjC,WAAO;AAAA,MACL,MAAM;AAAA,MACN,IAAI,IAAI;AAAA,MACR,YAAY,IAAI;AAAA,MAChB,gBAAgB,IAAI;AAAA,IACtB;AAAA,EACF;AACA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,IAAI,IAAI;AAAA,IACR,aAAa,IAAI;AAAA,IACjB,OAAO,IAAI;AAAA,EACb;AACF;AAEA,IAAM,cAAc,MAAyB;AAC3C,QAAM,UAAyB,gBAAY,IAAI,UAAU;AAEzD,SAAO;AAAA,IACL,QAAQ,MAAM,CAAC,GAAG,OAAO;AAAA,EAC3B;AACF;AAEA,IAAO,sBAAQ;;;AC1Cf;AAAA,EACE,SAAW;AAAA,IACT;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA,aAAe;AAAA,IACb;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA,mBAAqB;AAAA,IACnB;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,gBAAkB;AAAA,MACpB;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,gBAAkB;AAAA,MACpB;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,gBAAkB;AAAA,MACpB;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,gBAAkB;AAAA,MACpB;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,gBAAkB;AAAA,MACpB;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,gBAAkB;AAAA,MACpB;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,gBAAkB;AAAA,MACpB;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,gBAAkB;AAAA,MACpB;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,gBAAkB;AAAA,MACpB;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,gBAAkB;AAAA,MACpB;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA,aAAe;AAAA,IACb;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,UAAY;AAAA,MACd;AAAA,MACA,QAAU;AAAA,MACV,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,UAAY;AAAA,MACd;AAAA,MACA,QAAU;AAAA,MACV,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,UAAY;AAAA,MACd;AAAA,MACA,QAAU;AAAA,MACV,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,UAAY;AAAA,MACd;AAAA,MACA,QAAU;AAAA,MACV,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,UAAY;AAAA,MACd;AAAA,MACA,QAAU;AAAA,MACV,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,UAAY;AAAA,MACd;AAAA,MACA,QAAU;AAAA,MACV,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,cAAgB;AAAA,MAClB;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,cAAgB;AAAA,MAClB;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,cAAgB;AAAA,MAClB;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,cAAgB;AAAA,MAClB;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,cAAgB;AAAA,MAClB;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,cAAgB;AAAA,MAClB;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA,2BAA2B;AAAA,IACzB;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,uBAAyB;AAAA,MAC3B;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,UAAY;AAAA,MACd;AAAA,MACA,QAAU;AAAA,MACV,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,UAAY;AAAA,MACd;AAAA,MACA,QAAU;AAAA,MACV,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,UAAY;AAAA,MACd;AAAA,MACA,QAAU;AAAA,MACV,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,UAAY;AAAA,MACd;AAAA,MACA,QAAU;AAAA,MACV,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,UAAY;AAAA,MACd;AAAA,MACA,QAAU;AAAA,MACV,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,UAAY;AAAA,MACd;AAAA,MACA,QAAU;AAAA,MACV,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,cAAgB;AAAA,MAClB;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,cAAgB;AAAA,MAClB;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,cAAgB;AAAA,MAClB;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,cAAgB;AAAA,MAClB;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,cAAgB;AAAA,MAClB;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,QACN,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,cAAgB;AAAA,MAClB;AAAA,MACA,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,QAAU;AAAA,MACZ;AAAA,MACA,QAAU;AAAA,IACZ;AAAA,EACF;AACF;;;ACp7FA,IAAM,UAAU,CAAC,QAOL;AACV,QAAM,OAAa;AAAA,IACjB,MAAM,IAAI;AAAA,IACV,QAAQ,IAAI;AAAA,EACd;AACA,MAAI,IAAI,uBAAuB;AAC7B,SAAK,wBAAwB;AAAA,EAC/B;AACA,MAAI,IAAI,gBAAgB;AACtB,SAAK,iBAAiB,IAAI;AAAA,EAC5B;AACA,MAAI,IAAI,UAAU;AAChB,SAAK,WAAW;AAAA,EAClB;AACA,MAAI,IAAI,cAAc;AACpB,SAAK,eAAe;AAAA,EACtB;AACA,SAAO;AACT;AAGA,IAAM,sBAAsB;AAC5B,IAAM,iBAAiB,CAAC,aAA6B;AACnD,MAAI,SAAS,WAAW,mBAAmB,GAAG;AAC5C,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,IAAM,eAAe,MAA0B;AAC7C,QAAM,WAAqC,CAAC;AAE5C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,gBAAY,GAAG;AACvD,UAAM,kBAA4B,CAAC;AACnC,UAAM,QAAQ,CAAC,WAAW;AACxB,YAAM,IAAY;AAAA,QAChB,MAAM,QAAQ,OAAO,IAAI;AAAA,QACzB,OAAO,QAAQ,OAAO,KAAK;AAAA,QAC3B,QAAQ,OAAO;AAAA,MACjB;AACA,UAAI,YAAY,UAAU,OAAO,OAAO,WAAW,UAAU;AAC3D,UAAE,SAAS,OAAO;AAAA,MACpB;AACA,sBAAgB,KAAK,CAAC;AAAA,IACxB,CAAC;AAED,aAAS,GAAG,IAAI;AAAA,EAClB;AAEA,SAAO;AAAA,IACL,YAAY,CAAC,SAAmB;AAC9B,YAAM,MAAM,eAAe,KAAK,IAAI;AACpC,aAAO,SAAS,GAAG,KAAK,CAAC;AAAA,IAC3B;AAAA,EACF;AACF;AAEA,IAAO,uBAAQ;;;ACrEf;AAAA,EACI;AAAA,IACI,MAAQ;AAAA,IACR,aAAe;AAAA,EACnB;AAAA,EACA;AAAA,IACI,MAAQ;AAAA,IACR,aAAe;AAAA,EACnB;AAAA,EACA;AAAA,IACI,MAAQ;AAAA,IACR,aAAe;AAAA,EACnB;AAAA,EACA;AAAA,IACI,MAAQ;AAAA,IACR,aAAe;AAAA,EACnB;AAAA,EACA;AAAA,IACI,MAAQ;AAAA,IACR,aAAe;AAAA,EACnB;AAAA,EACA;AAAA,IACI,MAAQ;AAAA,IACR,aAAe;AAAA,EACnB;AAAA,EACA;AAAA,IACI,MAAQ;AAAA,IACR,aAAe;AAAA,EACnB;AACJ;;;ACzBA,IAAM,YAAY,MAAsB;AACtC,QAAM,QAAoB,CAAC;AAE3B,gBAAU,QAAQ,CAAC,SAAS;AAC1B,UAAM,KAAK;AAAA,MACT,MAAM,KAAK;AAAA,MACX,aAAa,KAAK;AAAA,IACpB,CAAC;AAAA,EACH,CAAC;AAED,SAAO;AAAA,IACL,eAAe,MAAM;AACnB,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,IAAO,oBAAQ;;;ACrBf;AAAA,EACE;AAAA,IACE,IAAM;AAAA,IACN,MAAQ;AAAA,IACR,MAAQ;AAAA,IACR,aAAe;AAAA,IACf,QAAU;AAAA,IACV,SAAW;AAAA,EACb;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,MAAQ;AAAA,IACR,MAAQ;AAAA,IACR,aAAe;AAAA,IACf,QAAU;AAAA,IACV,SAAW;AAAA,EACb;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,MAAQ;AAAA,IACR,MAAQ;AAAA,IACR,aAAe;AAAA,IACf,QAAU;AAAA,IACV,SAAW;AAAA,EACb;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,MAAQ;AAAA,IACR,MAAQ;AAAA,IACR,aAAe;AAAA,IACf,QAAU;AAAA,IACV,SAAW;AAAA,EACb;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,MAAQ;AAAA,IACR,MAAQ;AAAA,IACR,aAAe;AAAA,IACf,QAAU;AAAA,IACV,SAAW;AAAA,EACb;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,MAAQ;AAAA,IACR,MAAQ;AAAA,IACR,aAAe;AAAA,IACf,QAAU;AAAA,IACV,SAAW;AAAA,EACb;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,MAAQ;AAAA,IACR,MAAQ;AAAA,IACR,aAAe;AAAA,IACf,QAAU;AAAA,IACV,SAAW;AAAA,EACb;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,MAAQ;AAAA,IACR,MAAQ;AAAA,IACR,aAAe;AAAA,IACf,QAAU;AAAA,IACV,SAAW;AAAA,EACb;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,MAAQ;AAAA,IACR,MAAQ;AAAA,IACR,aAAe;AAAA,IACf,QAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,MAAQ;AAAA,IACR,MAAQ;AAAA,IACR,aAAe;AAAA,IACf,QAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,MAAQ;AAAA,IACR,MAAQ;AAAA,IACR,aAAe;AAAA,IACf,QAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,MAAQ;AAAA,IACR,MAAQ;AAAA,IACR,aAAe;AAAA,IACf,QAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,MAAQ;AAAA,IACR,MAAQ;AAAA,IACR,aAAe;AAAA,IACf,QAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,MAAQ;AAAA,IACR,MAAQ;AAAA,IACR,aAAe;AAAA,IACf,QAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,MAAQ;AAAA,IACR,MAAQ;AAAA,IACR,aAAe;AAAA,IACf,QAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,MAAQ;AAAA,IACR,MAAQ;AAAA,IACR,aAAe;AAAA,IACf,QAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAM;AAAA,IACN,MAAQ;AAAA,IACR,MAAQ;AAAA,IACR,aAAe;AAAA,IACf,QAAU;AAAA,EACZ;AACF;;;ACzHA,IAAM,eAAe,CAAC,QAOL;AACf,QAAM,OAAkB;AAAA,IACtB,IAAI,IAAI;AAAA,IACR,MAAM,IAAI;AAAA,IACV,MAAM,IAAI;AAAA,IACV,aAAa,IAAI;AAAA,IACjB,QAAQ,IAAI;AAAA,EACd;AACA,MAAI,IAAI,SAAS;AACf,SAAK,UAAU,IAAI;AAAA,EACrB;AACA,SAAO;AACT;AAEA,IAAM,iBAAiB,MAA4B;AACjD,QAAM,aAA0B,mBAAe,IAAI,YAAY;AAE/D,SAAO;AAAA,IACL,QAAQ,MAAM,CAAC,GAAG,UAAU;AAAA,EAC9B;AACF;AAEA,IAAO,yBAAQ;;;ACpCf;AAAA,EACE,QAAU;AAAA,IACR;AAAA,MACE,cAAgB;AAAA,MAChB,gBAAkB;AAAA,MAClB,aAAe;AAAA,MACf,iBAAmB;AAAA,MACnB,UAAY;AAAA,MACZ,gBAAkB;AAAA,IACpB;AAAA,IACA;AAAA,MACE,cAAgB;AAAA,MAChB,gBAAkB;AAAA,MAClB,aAAe;AAAA,MACf,iBAAmB;AAAA,MACnB,UAAY;AAAA,MACZ,gBAAkB;AAAA,IACpB;AAAA,IACA;AAAA,MACE,cAAgB;AAAA,MAChB,gBAAkB;AAAA,MAClB,aAAe;AAAA,MACf,iBAAmB;AAAA,MACnB,UAAY;AAAA,MACZ,gBAAkB;AAAA,IACpB;AAAA,IACA;AAAA,MACE,cAAgB;AAAA,MAChB,gBAAkB;AAAA,MAClB,aAAe;AAAA,MACf,iBAAmB;AAAA,MACnB,UAAY;AAAA,MACZ,gBAAkB;AAAA,IACpB;AAAA,EACF;AAAA,EACA,KAAO;AAAA,IACL;AAAA,MACE,cAAgB;AAAA,MAChB,gBAAkB;AAAA,MAClB,aAAe;AAAA,MACf,iBAAmB;AAAA,MACnB,UAAY;AAAA,MACZ,gBAAkB;AAAA,MAClB,0BAA4B;AAAA,IAC9B;AAAA,IACA;AAAA,MACE,cAAgB;AAAA,MAChB,gBAAkB;AAAA,MAClB,aAAe;AAAA,MACf,iBAAmB;AAAA,MACnB,UAAY;AAAA,MACZ,gBAAkB;AAAA,MAClB,0BAA4B;AAAA,IAC9B;AAAA,IACA;AAAA,MACE,cAAgB;AAAA,MAChB,gBAAkB;AAAA,MAClB,aAAe;AAAA,MACf,iBAAmB;AAAA,MACnB,UAAY;AAAA,MACZ,gBAAkB;AAAA,MAClB,0BAA4B;AAAA,IAC9B;AAAA,IACA;AAAA,MACE,cAAgB;AAAA,MAChB,gBAAkB;AAAA,MAClB,aAAe;AAAA,MACf,iBAAmB;AAAA,MACnB,UAAY;AAAA,MACZ,gBAAkB;AAAA,MAClB,0BAA4B;AAAA,IAC9B;AAAA,EACF;AAAA,EACA,OAAS;AAAA,IACP;AAAA,MACE,MAAQ;AAAA,MACR,aAAe;AAAA,MACf,MAAQ;AAAA,QACN,EAAE,MAAQ,WAAW,aAAe,2BAA2B;AAAA,QAC/D,EAAE,MAAQ,eAAe,aAAe,iFAAiF;AAAA,MAC3H;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,MACR,aAAe;AAAA,MACf,MAAQ;AAAA,QACN,EAAE,MAAQ,WAAW,aAAe,2BAA2B;AAAA,QAC/D,EAAE,MAAQ,eAAe,aAAe,iFAAiF;AAAA,MAC3H;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,MACR,aAAe;AAAA,MACf,MAAQ;AAAA,QACN,EAAE,MAAQ,WAAW,aAAe,2BAA2B;AAAA,QAC/D,EAAE,MAAQ,eAAe,aAAe,iFAAiF;AAAA,MAC3H;AAAA,MACA,cAAgB;AAAA,IAClB;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,MACR,aAAe;AAAA,MACf,MAAQ;AAAA,QACN,EAAE,MAAQ,WAAW,aAAe,2BAA2B;AAAA,QAC/D,EAAE,MAAQ,eAAe,aAAe,iFAAiF;AAAA,MAC3H;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,MACR,aAAe;AAAA,MACf,MAAQ;AAAA,QACN,EAAE,MAAQ,+BAA+B,aAAe,sCAAsC;AAAA,QAC9F,EAAE,MAAQ,2BAA2B,aAAe,kCAAkC;AAAA,QACtF,EAAE,MAAQ,2BAA2B,aAAe,kCAAkC;AAAA,MACxF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,MACR,aAAe;AAAA,MACf,MAAQ;AAAA,QACN,EAAE,MAAQ,+BAA+B,aAAe,sCAAsC;AAAA,QAC9F,EAAE,MAAQ,2BAA2B,aAAe,kCAAkC;AAAA,QACtF,EAAE,MAAQ,2BAA2B,aAAe,kCAAkC;AAAA,MACxF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,MACR,aAAe;AAAA,MACf,MAAQ;AAAA,QACN,EAAE,MAAQ,+BAA+B,aAAe,sCAAsC;AAAA,QAC9F,EAAE,MAAQ,2BAA2B,aAAe,kCAAkC;AAAA,QACtF,EAAE,MAAQ,2BAA2B,aAAe,kCAAkC;AAAA,MACxF;AAAA,MACA,cAAgB;AAAA,IAClB;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,MACR,aAAe;AAAA,MACf,MAAQ;AAAA,QACN,EAAE,MAAQ,+BAA+B,aAAe,sCAAsC;AAAA,QAC9F,EAAE,MAAQ,2BAA2B,aAAe,kCAAkC;AAAA,QACtF,EAAE,MAAQ,2BAA2B,aAAe,kCAAkC;AAAA,MACxF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,MACR,aAAe;AAAA,MACf,MAAQ;AAAA,QACN,EAAE,MAAQ,eAAe,aAAe,gDAAgD;AAAA,QACxF,EAAE,MAAQ,2BAA2B,aAAe,yCAAyC;AAAA,MAC/F;AAAA,IACF;AAAA,EACF;AACF;;;ACrJA,IAAM,YAAY,MAAsB;AACtC,QAAM,QAAe;AAAA,IACnB,OAAO,CAAC;AAAA,IACR,YAAY,CAAC;AAAA,EACf;AAEA,QAAM,cAAc,cAAU;AAC9B,QAAM,WAAW,cAAU;AAC3B,QAAM,aAAa,cAAU;AAE7B,cAAY,QAAQ,CAAC,SAAS;AAC5B,UAAM,MAAM,KAAK,YAAY,IAAI;AAAA,MAC/B,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK;AAAA,MAClB,iBAAiB,KAAK;AAAA,MACtB,UAAU,KAAK;AAAA,MACf,gBAAgB,KAAK;AAAA,IACvB;AAAA,EACF,CAAC;AAED,MAAI,UAAU;AACZ,UAAM,WAAW,CAAC;AAClB,aAAS,QAAQ,CAAC,SAAS;AACzB,YAAM,SAAU,KAAK,YAAY,IAAI;AAAA,QACnC,OAAO,KAAK;AAAA,QACZ,aAAa,KAAK;AAAA,QAClB,iBAAiB,KAAK;AAAA,QACtB,UAAU,KAAK;AAAA,QACf,gBAAgB,KAAK;AAAA,QACrB,0BAA0B,KAAK;AAAA,MACjC;AAAA,IACF,CAAC;AAAA,EACH;AAEA,aAAW,QAAQ,CAAC,SAAS;AAC3B,UAAM,WAAW,KAAK;AAAA,MACpB,MAAM,KAAK;AAAA,MACX,aAAa,KAAK;AAAA,MAClB,MAAM,KAAK;AAAA,MACX,GAAI,kBAAkB,QAAQ,EAAE,cAAc,KAAK,aAAa;AAAA,IAClE,CAAC;AAAA,EACH,CAAC;AAED,SAAO;AAAA,IACL,QAAQ,MAAM;AACZ,aAAO;AAAA,IACT;AAAA,IACA,aAAa,MAAM;AACjB,aAAO,MAAM;AAAA,IACf;AAAA,EACF;AACF;AAEA,IAAO,oBAAQ;;;ACvDR,IAAM,gBAA+B,CAAI,UAAe;AAC7D,WAAS,IAAI,MAAM,SAAS,GAAG,IAAI,GAAG,KAAK;AACzC,UAAM,IAAI,KAAK,MAAM,KAAK,OAAO,KAAK,IAAI,EAAE;AAC5C,KAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAQ,MAAM,CAAC,CAAM;AAAA,EACtD;AACA,SAAO;AACT;;;ACNO,IAAM,aAAyB,MAAM;AAC1C,SAAO,WAAW,OAAO,WAAW;AACtC;;;ACAO,IAAM,YAAY;AAAA;AAAA,EAEvB,cAAc;AAAA,EACd,uBAAuB;AAAA,EACvB,yBAAyB;AAAA;AAAA,EAGzB,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,gBAAgB;AAAA;AAAA,EAGhB,sBAAsB;AAAA,EACtB,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,wBAAwB;AAAA,EACxB,2BAA2B;AAAA,EAC3B,yBAAyB;AAAA,EACzB,gCAAgC;AAAA;AAAA,EAGhC,eAAe;AAAA,EACf,aAAa;AAAA,EACb,cAAc;AAAA,EACd,uBAAuB;AAAA;AAAA,EAGvB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA;AAAA,EAGlB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,2BAA2B;AAAA,EAC3B,wBAAwB;AAAA,EACxB,wBAAwB;AAAA,EACxB,oBAAoB;AAAA,EACpB,gCAAgC;AAAA,EAChC,oBAAoB;AAAA,EACpB,yBAAyB;AAAA;AAAA,EAGzB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,yBAAyB;AAAA,EACzB,cAAc;AAAA;AAAA,EAGd,uBAAuB;AAAA,EACvB,6BAA6B;AAAA,EAC7B,uBAAuB;AAAA,EACvB,wBAAwB;AAAA,EACxB,wBAAwB;AAAA,EACxB,2BAA2B;AAAA,EAC3B,mBAAmB;AAAA,EACnB,gBAAgB;AAClB;AAmBO,IAAM,oBAAoB,CAC/B,MACA,SACA,aACiB;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AACF;AAKO,IAAM,kBAAN,cAA8B,MAAM;AAAA,EACzB;AAAA,EACA;AAAA,EAEhB,YAAY,OAAoB;AAC9B,UAAM,MAAM,OAAO;AACnB,SAAK,OAAO;AACZ,SAAK,OAAO,MAAM;AAClB,SAAK,UAAU,MAAM;AAAA,EACvB;AACF;AAKO,IAAM,mBAAN,cAA+B,gBAAgB;AAAA,EACpD,YAAY,SAAiB,SAAmC;AAC9D,UAAM;AAAA,MACJ,MAAM,UAAU;AAAA,MAChB;AAAA,MACA;AAAA,IACF,CAAC;AACD,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,qBAAN,cAAiC,gBAAgB;AAAA,EACtD,YACE,SACA,OAAsB,UAAU,uBAChC,SACA;AACA,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,uBAAN,cAAmC,gBAAgB;AAAA,EACxD,YACE,SACA,OAAsB,UAAU,yBAChC,SACA;AACA,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,gBAAN,cAA4B,gBAAgB;AAAA,EACjD,YACE,SACA,OAAsB,UAAU,gBAChC,SACA;AACA,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,kBAAN,cAA8B,gBAAgB;AAAA,EACnD,YACE,SACA,MACA,SACA;AACA,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,YAAN,cAAwB,gBAAgB;AAAA,EAC7C,YAAY,UAAU,oBAAoB,SAAmC;AAC3E,UAAM;AAAA,MACJ,MAAM,UAAU;AAAA,MAChB;AAAA,MACA;AAAA,IACF,CAAC;AACD,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,YAAN,cAAwB,gBAAgB;AAAA,EAC7C,YAAY,UAAU,oBAAoB,SAAmC;AAC3E,UAAM;AAAA,MACJ,MAAM,UAAU;AAAA,MAChB;AAAA,MACA;AAAA,IACF,CAAC;AACD,SAAK,OAAO;AAAA,EACd;AACF;;;ACjNO,IAAM,iBAAiB;AAAA;AAAA,EAE5B,oBAAoB;AAAA,EACpB,6BAA6B;AAAA,EAC7B,+BAA+B;AAAA,EAC/B,sBAAsB;AAAA,EACtB,wBAAwB;AAAA,EACxB,wBAAwB;AAAA,EACxB,sBAAsB;AAAA,EACtB,yBAAyB;AAAA,EACzB,2BAA2B;AAAA,EAC3B,8BAA8B;AAAA,EAC9B,iCAAiC;AAAA,EACjC,+BAA+B;AAAA,EAC/B,sCAAsC;AAAA,EACtC,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,6BAA6B;AAAA,EAC7B,4BAA4B;AAAA,EAC5B,2BAA2B;AAAA,EAC3B,wBAAwB;AAAA,EACxB,wBAAwB;AAAA;AAAA,EAGxB,cAAc;AAAA;AAAA,EAGd,qBAAqB;AAAA,EACrB,cAAc;AAAA;AAAA,EAGd,eAAe;AAAA,EACf,cAAc;AAAA,EACd,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,cAAc;AAAA,EACd,aAAa;AAAA;AAAA,EAGb,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,aAAa;AAAA,EACb,cAAc;AAAA;AAAA,EAGd,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,aAAa;AAAA;AAAA,EAGb,2BAA2B;AAAA,EAC3B,2BAA2B;AAAA,EAC3B,iCAAiC;AAAA,EACjC,8BAA8B;AAAA,EAC9B,8BAA8B;AAAA,EAC9B,0BAA0B;AAAA,EAC1B,sCAAsC;AAAA,EACtC,0BAA0B;AAAA,EAC1B,+BAA+B;AAAA;AAAA,EAG/B,wBAAwB;AAAA,EACxB,uBAAuB;AAAA,EACvB,+BAA+B;AAAA,EAC/B,oBAAoB;AAAA;AAAA,EAGpB,6BAA6B;AAAA,EAC7B,mCAAmC;AAAA,EACnC,6BAA6B;AAAA,EAC7B,8BAA8B;AAAA,EAC9B,8BAA8B;AAAA,EAC9B,iCAAiC;AAAA,EACjC,yBAAyB;AAAA,EACzB,sBAAsB;AACxB;AAQO,IAAM,sBAA0D;AAAA;AAAA,EAErE,CAAC,eAAe,kBAAkB,GAAG;AAAA,EACrC,CAAC,eAAe,2BAA2B,GAAG;AAAA,EAC9C,CAAC,eAAe,6BAA6B,GAAG;AAAA,EAChD,CAAC,eAAe,oBAAoB,GAAG;AAAA,EACvC,CAAC,eAAe,sBAAsB,GAAG;AAAA,EACzC,CAAC,eAAe,sBAAsB,GAAG;AAAA,EACzC,CAAC,eAAe,oBAAoB,GAAG;AAAA,EACvC,CAAC,eAAe,uBAAuB,GAAG;AAAA,EAC1C,CAAC,eAAe,yBAAyB,GAAG;AAAA,EAC5C,CAAC,eAAe,4BAA4B,GAC1C;AAAA,EACF,CAAC,eAAe,+BAA+B,GAC7C;AAAA,EACF,CAAC,eAAe,6BAA6B,GAAG;AAAA,EAChD,CAAC,eAAe,oCAAoC,GAClD;AAAA,EACF,CAAC,eAAe,mBAAmB,GAAG;AAAA,EACtC,CAAC,eAAe,iBAAiB,GAAG;AAAA,EACpC,CAAC,eAAe,kBAAkB,GAAG;AAAA,EACrC,CAAC,eAAe,2BAA2B,GACzC;AAAA,EACF,CAAC,eAAe,0BAA0B,GACxC;AAAA,EACF,CAAC,eAAe,yBAAyB,GACvC;AAAA,EACF,CAAC,eAAe,sBAAsB,GAAG;AAAA,EACzC,CAAC,eAAe,sBAAsB,GAAG;AAAA;AAAA,EAGzC,CAAC,eAAe,YAAY,GAAG;AAAA;AAAA,EAG/B,CAAC,eAAe,mBAAmB,GAAG;AAAA,EACtC,CAAC,eAAe,YAAY,GAAG;AAAA;AAAA,EAG/B,CAAC,eAAe,aAAa,GAAG;AAAA,EAChC,CAAC,eAAe,YAAY,GAAG;AAAA,EAC/B,CAAC,eAAe,aAAa,GAAG;AAAA,EAChC,CAAC,eAAe,UAAU,GAAG;AAAA,EAC7B,CAAC,eAAe,YAAY,GAAG;AAAA,EAC/B,CAAC,eAAe,YAAY,GAAG;AAAA,EAC/B,CAAC,eAAe,WAAW,GAAG;AAAA;AAAA,EAG9B,CAAC,eAAe,iBAAiB,GAAG;AAAA,EACpC,CAAC,eAAe,aAAa,GAAG;AAAA,EAChC,CAAC,eAAe,WAAW,GAAG;AAAA,EAC9B,CAAC,eAAe,YAAY,GAAG;AAAA;AAAA,EAG/B,CAAC,eAAe,kBAAkB,GAAG;AAAA,EACrC,CAAC,eAAe,mBAAmB,GAAG;AAAA,EACtC,CAAC,eAAe,WAAW,GAAG;AAAA;AAAA,EAG9B,CAAC,eAAe,yBAAyB,GAAG;AAAA,EAC5C,CAAC,eAAe,yBAAyB,GACvC;AAAA,EACF,CAAC,eAAe,+BAA+B,GAC7C;AAAA,EACF,CAAC,eAAe,4BAA4B,GAC1C;AAAA,EACF,CAAC,eAAe,4BAA4B,GAC1C;AAAA,EACF,CAAC,eAAe,wBAAwB,GACtC;AAAA,EACF,CAAC,eAAe,oCAAoC,GAClD;AAAA,EACF,CAAC,eAAe,wBAAwB,GACtC;AAAA,EACF,CAAC,eAAe,6BAA6B,GAC3C;AAAA;AAAA,EAGF,CAAC,eAAe,sBAAsB,GAAG;AAAA,EACzC,CAAC,eAAe,qBAAqB,GAAG;AAAA,EACxC,CAAC,eAAe,6BAA6B,GAC3C;AAAA,EACF,CAAC,eAAe,kBAAkB,GAAG;AAAA;AAAA,EAGrC,CAAC,eAAe,2BAA2B,GACzC;AAAA,EACF,CAAC,eAAe,iCAAiC,GAC/C;AAAA,EACF,CAAC,eAAe,2BAA2B,GACzC;AAAA,EACF,CAAC,eAAe,4BAA4B,GAAG;AAAA,EAC/C,CAAC,eAAe,4BAA4B,GAC1C;AAAA,EACF,CAAC,eAAe,+BAA+B,GAC7C;AAAA,EACF,CAAC,eAAe,uBAAuB,GAAG;AAAA,EAC1C,CAAC,eAAe,oBAAoB,GAAG;AACzC;AAMO,IAAM,4BAGT;AAAA,EACF,CAAC,UAAU,YAAY,GAAG,eAAe;AAAA,EACzC,CAAC,UAAU,qBAAqB,GAAG,eAAe;AAAA,EAClD,CAAC,UAAU,uBAAuB,GAChC,eAAe;AAAA,EACjB,CAAC,UAAU,cAAc,GAAG,eAAe;AAAA,EAC3C,CAAC,UAAU,gBAAgB,GAAG,eAAe;AAAA,EAC7C,CAAC,UAAU,gBAAgB,GAAG,eAAe;AAAA,EAC7C,CAAC,UAAU,cAAc,GAAG,eAAe;AAAA,EAC3C,CAAC,UAAU,oBAAoB,GAAG,eAAe;AAAA,EACjD,CAAC,UAAU,mBAAmB,GAAG,eAAe;AAAA,EAChD,CAAC,UAAU,iBAAiB,GAAG,eAAe;AAAA,EAC9C,CAAC,UAAU,mBAAmB,GAAG,eAAe;AAAA,EAChD,CAAC,UAAU,sBAAsB,GAC/B,eAAe;AAAA,EACjB,CAAC,UAAU,yBAAyB,GAClC,eAAe;AAAA,EACjB,CAAC,UAAU,uBAAuB,GAChC,eAAe;AAAA,EACjB,CAAC,UAAU,8BAA8B,GACvC,eAAe;AAAA,EACjB,CAAC,UAAU,aAAa,GAAG,eAAe;AAAA,EAC1C,CAAC,UAAU,WAAW,GAAG,eAAe;AAAA,EACxC,CAAC,UAAU,YAAY,GAAG,eAAe;AAAA,EACzC,CAAC,UAAU,qBAAqB,GAAG,eAAe;AAAA,EAClD,CAAC,UAAU,gBAAgB,GAAG,eAAe;AAAA,EAC7C,CAAC,UAAU,gBAAgB,GAAG,eAAe;AAAA,EAC7C,CAAC,UAAU,mBAAmB,GAAG,eAAe;AAAA,EAChD,CAAC,UAAU,mBAAmB,GAAG,eAAe;AAAA,EAChD,CAAC,UAAU,yBAAyB,GAClC,eAAe;AAAA,EACjB,CAAC,UAAU,sBAAsB,GAC/B,eAAe;AAAA,EACjB,CAAC,UAAU,sBAAsB,GAC/B,eAAe;AAAA,EACjB,CAAC,UAAU,kBAAkB,GAAG,eAAe;AAAA,EAC/C,CAAC,UAAU,8BAA8B,GACvC,eAAe;AAAA,EACjB,CAAC,UAAU,kBAAkB,GAAG,eAAe;AAAA,EAC/C,CAAC,UAAU,uBAAuB,GAChC,eAAe;AAAA,EACjB,CAAC,UAAU,gBAAgB,GAAG,eAAe;AAAA,EAC7C,CAAC,UAAU,eAAe,GAAG,eAAe;AAAA,EAC5C,CAAC,UAAU,uBAAuB,GAChC,eAAe;AAAA,EACjB,CAAC,UAAU,YAAY,GAAG,eAAe;AAAA,EACzC,CAAC,UAAU,qBAAqB,GAAG,eAAe;AAAA,EAClD,CAAC,UAAU,2BAA2B,GACpC,eAAe;AAAA,EACjB,CAAC,UAAU,qBAAqB,GAAG,eAAe;AAAA,EAClD,CAAC,UAAU,sBAAsB,GAC/B,eAAe;AAAA,EACjB,CAAC,UAAU,sBAAsB,GAC/B,eAAe;AAAA,EACjB,CAAC,UAAU,yBAAyB,GAClC,eAAe;AAAA,EACjB,CAAC,UAAU,iBAAiB,GAAG,eAAe;AAAA,EAC9C,CAAC,UAAU,cAAc,GAAG,eAAe;AAC7C;AAMO,IAAM,qBAAqB,CAChC,YACA,MACA,WACW;AACX,QAAM,MAAM,0BAA0B,IAAI;AAC1C,SAAO,WAAW,EAAE,KAAK,MAAM;AACjC;AAsBO,IAAM,mBAAmB,CAC9B,eAA4D,CAAC,MAC9C;AACf,QAAM,qBAAqB,EAAE,GAAG,qBAAqB,GAAG,aAAa;AAErE,SAAO;AAAA,IACL,EACE,KACA,QACQ;AACR,UAAI,OAAO,mBAAmB,GAAG,KAAK;AAGtC,UAAI,QAAQ;AACV,mBAAW,CAAC,UAAU,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACtD,iBAAO,KAAK;AAAA,YACV,IAAI,OAAO,SAAS,QAAQ,UAAU,GAAG;AAAA,YACzC,OAAO,KAAK;AAAA,UACd;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAKO,IAAM,oBAAgC,iBAAiB;;;ACvTvD,IAAM,KAAK,CAAI,WAAqB,EAAE,KAAK,MAAM,MAAM;AACvD,IAAM,MAAM,CAAC,WAAwB,EAAE,KAAK,OAAO,MAAM;AAEzD,IAAM,OAAO,CAAI,WACtB,OAAO,QAAQ;AACV,IAAM,QAAQ,CAAI,WACvB,OAAO,QAAQ;AAEV,IAAM,SAAS,CAAI,WAA2B;AACnD,MAAI,OAAO,QAAQ,OAAO;AACxB,UAAM,IAAI,MAAM,OAAO,KAAK;AAAA,EAC9B;AACA,SAAO,OAAO;AAChB;;;ACNO,IAAM,uBACX,CACE,QACA,YACA,YAEF,CAAC,YAAkC;AACjC,QAAM,EAAE,MAAM,WAAW,IAAI;AAC7B,SAAO,KAAK,+BAA+B,KAAK,EAAE,EAAE;AACpD,SAAO,KAAK,gBAAgB,UAAU,EAAE;AAExC,MAAI,CAAC,mBAAmB,IAAI,GAAG;AAC7B,WAAO;AAAA,MACL,2DAA2D,KAAK,WAAW,IAAI;AAAA,IACjF;AACA,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,UAAU,YAAY;AAAA,MACrD,EAAE,UAAU,QAAQ,QAAQ,KAAK,WAAW,MAAM,QAAQ,KAAK,GAAG;AAAA,IACpE;AAAA,EACF;AAEA,MAAI,KAAK,WAAW,SAAS,WAAW;AACtC,WAAO;AAAA,MACL,4CAA4C,KAAK,WAAW,IAAI;AAAA,IAClE;AACA,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,UAAU,YAAY;AAAA,MACrD,EAAE,UAAU,WAAW,QAAQ,KAAK,WAAW,MAAM,QAAQ,KAAK,GAAG;AAAA,IACvE;AAAA,EACF;AAEA,QAAM,SAAS,QAAQ,MAAM,UAAU;AAEvC,MAAI,MAAM,MAAM,GAAG;AACjB,WAAO,MAAM,6BAA6B,OAAO,KAAK,EAAE;AACxD,UAAM,OAAO,OAAO;AACpB,UAAM,IAAI,mBAAmB,mBAAmB,YAAY,IAAI,GAAG,MAAM;AAAA,MACvE,QAAQ,KAAK;AAAA,MACb,YAAY,QAAQ;AAAA,IACtB,CAAC;AAAA,EACH;AAEA,SAAO,KAAK,8BAA8B,KAAK,EAAE,EAAE;AACnD,SAAO,OAAO;AAChB;;;AC5CK,IAAM,oBACX,CACE,QACA,YACA,YAEF,CAAC,YAA+B;AAC9B,QAAM,EAAE,MAAM,QAAQ,IAAI;AAE1B,SAAO,KAAK,2BAA2B,KAAK,EAAE,EAAE;AAEhD,MAAI,CAAC,mBAAmB,IAAI,GAAG;AAC7B,WAAO;AAAA,MACL,2DAA2D,KAAK,WAAW,IAAI;AAAA,IACjF;AACA,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,UAAU,YAAY;AAAA,MACrD,EAAE,UAAU,QAAQ,QAAQ,KAAK,WAAW,MAAM,QAAQ,KAAK,GAAG;AAAA,IACpE;AAAA,EACF;AAEA,MAAI,KAAK,WAAW,SAAS,cAAc;AACzC,WAAO;AAAA,MACL,+CAA+C,KAAK,WAAW,IAAI;AAAA,IACrE;AACA,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,UAAU,YAAY;AAAA,MACrD;AAAA,QACE,UAAU;AAAA,QACV,QAAQ,KAAK,WAAW;AAAA,QACxB,QAAQ,KAAK;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,QAAQ,MAAM,OAAO;AAEpC,MAAI,MAAM,MAAM,GAAG;AACjB,WAAO,MAAM,yBAAyB,OAAO,KAAK,EAAE;AACpD,UAAM,OAAO,OAAO;AACpB,UAAM,IAAI,mBAAmB,mBAAmB,YAAY,IAAI,GAAG,MAAM;AAAA,MACvE,QAAQ,KAAK;AAAA,MACb,SAAS,QAAQ;AAAA,IACnB,CAAC;AAAA,EACH;AAEA,SAAO,KAAK,0BAA0B,KAAK,EAAE,EAAE;AAC/C,SAAO,OAAO;AAChB;;;AC1DK,IAAM,wBACX,CACE,QACA,aACA,YAEF,CAAC,YAAY;AACX,QAAM,EAAE,QAAQ,IAAI;AACpB,SAAO,KAAK,+BAA+B;AAC3C,QAAM,SAAS,QAAQ,OAAO;AAE9B,MAAI,MAAM,MAAM,GAAG;AACjB,WAAO,MAAM,4BAA4B,OAAO,KAAK,EAAE;AACvD,UAAM,IAAI,MAAM,OAAO,KAAK;AAAA,EAC9B;AAEA,SAAO,KAAK,qBAAqB,OAAO,KAAK,EAAE;AAC/C,SAAO,OAAO;AAChB;;;ACXK,IAAM,wBAAwB,CACnC,QACA,aACA,YAC0B;AAC1B,SAAO,CAAC,YAAY;AAClB,WAAO,KAAK,sBAAsB,QAAQ,OAAO,MAAM,gBAAgB;AACvE,UAAM,WAAW;AAAA,MACf,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AACA,WAAO,KAAK,qBAAqB,QAAQ,EAAE;AAC3C,WAAO;AAAA,EACT;AACF;;;ACZO,IAAM,sBACX,CACE,QACA,YACA,YAEF,CAAC,YAAiC;AAChC,QAAM,EAAE,MAAM,QAAQ,WAAW,IAAI;AACrC,SAAO;AAAA,IACL,oBAAoB,UAAU,cAAc,MAAM,aAAa,KAAK,EAAE;AAAA,EACxE;AAEA,MAAI,CAAC,qBAAqB,IAAI,GAAG;AAC/B,WAAO;AAAA,MACL,6DAA6D,KAAK,WAAW,IAAI;AAAA,IACnF;AACA,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,UAAU,YAAY;AAAA,MACrD,EAAE,UAAU,UAAU,QAAQ,KAAK,WAAW,MAAM,QAAQ,KAAK,GAAG;AAAA,IACtE;AAAA,EACF;AAEA,MAAI,KAAK,WAAW,eAAe,cAAc;AAC/C,WAAO;AAAA,MACL,iDAAiD,KAAK,WAAW,UAAU;AAAA,IAC7E;AACA,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,UAAU,YAAY;AAAA,MACrD;AAAA,QACE,UAAU;AAAA,QACV,QAAQ,KAAK,WAAW;AAAA,QACxB,QAAQ,KAAK;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,QAAQ,MAAM,QAAQ,UAAU;AAE/C,MAAI,MAAM,MAAM,GAAG;AACjB,WAAO,MAAM,0BAA0B,OAAO,KAAK,EAAE;AACrD,UAAM,OAAO,OAAO;AACpB,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,IAAI;AAAA,MACnC;AAAA,MACA;AAAA,QACE,QAAQ,KAAK;AAAA,QACb,QAAQ,QAAQ;AAAA,QAChB,YAAY,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,kBAAkB,UAAU,cAAc,MAAM,aAAa,KAAK,EAAE;AAAA,EACtE;AACA,SAAO,OAAO;AAChB;;;ACzDK,IAAM,2BACX,CACE,QACA,YACA,YAEF,CAAC,YAAsC;AACrC,QAAM,EAAE,MAAM,QAAQ,YAAY,SAAS,IAAI;AAC/C,SAAO;AAAA,IACL,0BAA0B,UAAU,cAAc,MAAM,iBAAiB,KAAK;AAAA,MAC5E;AAAA,IACF,CAAC,aAAa,KAAK,EAAE;AAAA,EACvB;AAEA,MAAI,KAAK,WAAW,eAAe,qBAAqB;AACtD,WAAO;AAAA,MACL,wDAAwD,KAAK,WAAW,UAAU;AAAA,IACpF;AACA,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,UAAU,YAAY;AAAA,MACrD;AAAA,QACE,UAAU;AAAA,QACV,QAAQ,KAAK,WAAW;AAAA,QACxB,QAAQ,KAAK;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,QAAQ,MAAM,QAAQ,YAAY,QAAQ;AAEzD,MAAI,MAAM,MAAM,GAAG;AACjB,WAAO,MAAM,gCAAgC,OAAO,KAAK,EAAE;AAC3D,UAAM,OAAO,OAAO;AACpB,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,IAAI;AAAA,MACnC;AAAA,MACA;AAAA,QACE,QAAQ,KAAK;AAAA,QACb,QAAQ,QAAQ;AAAA,QAChB,YAAY,QAAQ;AAAA,QACpB,UAAU,QAAQ;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,yBAAyB,UAAU,cAAc,MAAM,iBAAiB,KAAK;AAAA,MAC3E;AAAA,IACF,CAAC,aAAa,KAAK,EAAE;AAAA,EACvB;AACA,SAAO,OAAO;AAChB;;;ACvDK,IAAM,oBACX,CACE,QACA,YACA,YAEF,CAAC,YAA+B;AAC9B,SAAO,KAAK,4BAA4B,QAAQ,IAAI,EAAE;AACtD,QAAM,SAAS,QAAQ,QAAQ,MAAM,QAAQ,IAAI;AAEjD,MAAI,MAAM,MAAM,GAAG;AACjB,WAAO,MAAM,wBAAwB,OAAO,KAAK,EAAE;AACnD,UAAM,OAAO,OAAO;AACpB,UAAM,IAAI,mBAAmB,mBAAmB,YAAY,IAAI,GAAG,MAAM;AAAA,MACvE,MAAM,QAAQ;AAAA,IAChB,CAAC;AAAA,EACH;AAEA,SAAO,KAAK,iBAAiB,OAAO,MAAM,EAAE,EAAE;AAC9C,SAAO,OAAO;AAChB;;;ACfK,IAAM,uBACX,CACE,QACA,YACA,YAEF,CAAC,YAAkC;AACjC,QAAM,EAAE,MAAM,OAAO,IAAI;AACzB,SAAO,KAAK,+BAA+B,MAAM,aAAa,KAAK,EAAE,EAAE;AAEvE,MAAI,CAAC,qBAAqB,IAAI,GAAG;AAC/B,WAAO;AAAA,MACL,6DAA6D,KAAK,WAAW,IAAI;AAAA,IACnF;AACA,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,UAAU,YAAY;AAAA,MACrD,EAAE,UAAU,UAAU,QAAQ,KAAK,WAAW,MAAM,QAAQ,KAAK,GAAG;AAAA,IACtE;AAAA,EACF;AAEA,MAAI,KAAK,WAAW,eAAe,eAAe;AAChD,WAAO;AAAA,MACL,kDAAkD,KAAK,WAAW,UAAU;AAAA,IAC9E;AACA,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,UAAU,YAAY;AAAA,MACrD;AAAA,QACE,UAAU;AAAA,QACV,QAAQ,KAAK,WAAW;AAAA,QACxB,QAAQ,KAAK;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,QAAQ,MAAM,MAAM;AAEnC,MAAI,MAAM,MAAM,GAAG;AACjB,WAAO,MAAM,4BAA4B,OAAO,KAAK,EAAE;AACvD,UAAM,OAAO,OAAO;AACpB,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,IAAI;AAAA,MACnC;AAAA,MACA,EAAE,QAAQ,KAAK,IAAI,QAAQ,QAAQ,OAAO;AAAA,IAC5C;AAAA,EACF;AAEA,MAAI,qBAAqB,OAAO,KAAK,GAAG;AACtC,WAAO,KAAK,qBAAqB,MAAM,aAAa,KAAK,EAAE,EAAE;AAC7D,WAAO,OAAO;AAAA,EAChB;AAEA,SAAO,KAAK,qBAAqB,MAAM,aAAa,KAAK,EAAE,EAAE;AAC7D,SAAO,OAAO;AAChB;;;AC5DK,IAAM,0BAA0B,CACrC,QACA,aACA,YAC4B;AAC5B,SAAO,CAAC,YAAY;AAClB,WAAO;AAAA,MACL,mCAAmC,QAAQ,MAAM,MAAM;AAAA,IACzD;AACA,UAAM,UAAU,QAAQ,QAAQ,KAAK;AACrC,WAAO,KAAK,4BAA4B;AACxC,WAAO;AAAA,EACT;AACF;;;ACXO,IAAM,uBACX,CACE,QACA,YACA,YAEF,CAAC,YAAkC;AACjC,QAAM,EAAE,MAAM,QAAQ,IAAI;AAC1B,SAAO;AAAA,IACL,iCAAiC,IAAI,iBAAiB,OAAO;AAAA,EAC/D;AACA,QAAM,SAAS,QAAQ,MAAM,OAAO;AAEpC,MAAI,MAAM,MAAM,GAAG;AACjB,WAAO,MAAM,8BAA8B,OAAO,KAAK,EAAE;AACzD,UAAM,OAAO,OAAO;AACpB,UAAM,IAAI,cAAc,mBAAmB,YAAY,IAAI,GAAG,MAAM;AAAA,MAClE,MAAM,QAAQ;AAAA,IAChB,CAAC;AAAA,EACH;AAEA,SAAO,KAAK,0BAA0B,OAAO,KAAK,EAAE;AACpD,SAAO,OAAO;AAChB;;;ACvBK,IAAM,kBACX,CACE,QACA,YACA,YAEF,CAAC,aAA8B;AAC7B,SAAO,KAAK,eAAe;AAC3B,QAAM,SAAS,QAAQ;AAEvB,MAAI,MAAM,MAAM,GAAG;AACjB,WAAO,MAAM,wBAAwB,OAAO,KAAK,EAAE;AACnD,UAAM,OAAO,OAAO;AACpB,UAAM,IAAI,cAAc,mBAAmB,YAAY,IAAI,GAAG,IAAI;AAAA,EACpE;AAEA,SAAO,KAAK,oBAAoB,OAAO,KAAK,EAAE;AAC9C,SAAO,OAAO;AAChB;;;ACVK,IAAM,mBACX,CACE,QACA,YACA,aAKF,CAAC,YAA8B;AAC7B,QAAM,EAAE,kBAAAE,mBAAkB,uBAAAC,uBAAsB,IAAI;AACpD,QAAM,EAAE,KAAK,IAAI;AACjB,SAAO,KAAK,4BAA4B,KAAK,EAAE,EAAE;AAEjD,MAAI,CAAC,mBAAmB,IAAI,GAAG;AAC7B,WAAO;AAAA,MACL,2DAA2D,KAAK,WAAW,IAAI;AAAA,IACjF;AACA,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,UAAU,YAAY;AAAA,MACrD,EAAE,UAAU,QAAQ,QAAQ,KAAK,WAAW,MAAM,QAAQ,KAAK,GAAG;AAAA,IACpE;AAAA,EACF;AAEA,MAAI,KAAK,WAAW,SAAS,UAAU;AACrC,WAAO;AAAA,MACL,2CAA2C,KAAK,WAAW,IAAI;AAAA,IACjE;AACA,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,UAAU,YAAY;AAAA,MACrD,EAAE,UAAU,UAAU,QAAQ,KAAK,WAAW,MAAM,QAAQ,KAAK,GAAG;AAAA,IACtE;AAAA,EACF;AAEA,QAAM,EAAE,QAAQ,IAAI;AAEpB,QAAM,cAA6B,QAAQ,IAAI,CAAC,WAAW;AACzD,UAAM,EAAE,QAAQ,IAAI;AAEpB,UAAM,iBAAiB,OAAO,QAAQ,IAAI,CAAC,MAAM,EAAE,QAAQ;AAC3D,UAAMC,UAASD,uBAAsB,SAAS,cAAc;AAE5D,QAAI,MAAMC,OAAM,GAAG;AACjB,aAAO,MAAM,iCAAiCA,QAAO,KAAK,EAAE;AAC5D,YAAM,OAAOA,QAAO;AACpB,YAAM,IAAI;AAAA,QACR,mBAAmB,YAAY,IAAI;AAAA,QACnC;AAAA,QACA;AAAA,UACE,QAAQ,KAAK;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,UAAU,OAAO;AAAA,MACjB,YAAY,OAAO;AAAA,MACnB,SAAS;AAAA,QACP,GAAGA,QAAO;AAAA,MACZ;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,SAASF,kBAAiB,MAAM,WAAW;AAEjD,MAAI,MAAM,MAAM,GAAG;AACjB,WAAO,MAAM,yBAAyB,OAAO,KAAK,EAAE;AACpD,UAAM,OAAO,OAAO;AACpB,UAAM,IAAI,cAAc,mBAAmB,YAAY,IAAI,GAAG,MAAM;AAAA,MAClE,QAAQ,KAAK;AAAA,IACf,CAAC;AAAA,EACH;AAEA,SAAO,KAAK,8BAA8B,KAAK,EAAE,EAAE;AACnD,SAAO,OAAO;AAChB;;;AC9EK,IAAM,4BAA4B,CACvC,QACA,aACA,YAC8B;AAC9B,SAAO,CAAC,YAAY;AAClB,WAAO;AAAA,MACL,wCAAwC,QAAQ,OAAO,MAAM;AAAA,IAC/D;AACA,UAAM,aAAa;AAAA,MACjB,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AACA,WAAO,KAAK,SAAS,WAAW,MAAM,mBAAmB;AACzD,WAAO;AAAA,EACT;AACF;;;ACjBO,IAAM,qBACX,CACE,QACA,YACA,YAEF,CAAC,YAAgC;AAC/B,QAAM,EAAE,MAAM,QAAQ,UAAU,SAAS,IAAI;AAC7C,SAAO;AAAA,IACL,mBAAmB,MAAM,iBAAiB,KAAK;AAAA,MAC7C;AAAA,IACF,CAAC,mBAAmB,QAAQ,aAAa,KAAK,EAAE;AAAA,EAClD;AAEA,MAAI,CAAC,qBAAqB,IAAI,GAAG;AAC/B,WAAO;AAAA,MACL,6DAA6D,KAAK,WAAW,IAAI;AAAA,IACnF;AACA,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,UAAU,YAAY;AAAA,MACrD,EAAE,UAAU,UAAU,QAAQ,KAAK,WAAW,MAAM,QAAQ,KAAK,GAAG;AAAA,IACtE;AAAA,EACF;AAEA,MAAI,KAAK,WAAW,eAAe,eAAe;AAChD,WAAO;AAAA,MACL,kDAAkD,KAAK,WAAW,UAAU;AAAA,IAC9E;AACA,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,UAAU,YAAY;AAAA,MACrD;AAAA,QACE,UAAU;AAAA,QACV,QAAQ,KAAK,WAAW;AAAA,QACxB,QAAQ,KAAK;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,QAAQ,MAAM,QAAQ,UAAU,QAAQ;AAEvD,MAAI,MAAM,MAAM,GAAG;AACjB,WAAO,MAAM,yBAAyB,OAAO,KAAK,EAAE;AACpD,UAAM,OAAO,OAAO;AACpB,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,IAAI;AAAA,MACnC;AAAA,MACA;AAAA,QACE,QAAQ,KAAK;AAAA,QACb,QAAQ,QAAQ;AAAA,QAChB,UAAU,QAAQ;AAAA,QAClB,UAAU,QAAQ;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,qBAAqB,OAAO,KAAK,GAAG;AACtC,WAAO;AAAA,MACL,kBAAkB,MAAM,iBAAiB,KAAK;AAAA,QAC5C;AAAA,MACF,CAAC,mBAAmB,QAAQ,aAAa,KAAK,EAAE;AAAA,IAClD;AACA,WAAO,OAAO;AAAA,EAChB;AAEA,SAAO;AAAA,IACL,kBAAkB,MAAM,iBAAiB,KAAK;AAAA,MAC5C;AAAA,IACF,CAAC,mBAAmB,QAAQ,aAAa,KAAK,EAAE;AAAA,EAClD;AACA,SAAO,OAAO;AAChB;;;ACzEK,IAAM,wBACX,CACE,QACA,YACA,YAEF,CAAC,YAAmC;AAClC,QAAM,EAAE,MAAM,QAAQ,SAAS,IAAI;AACnC,SAAO;AAAA,IACL,gCAAgC,MAAM,iBAAiB,KAAK;AAAA,MAC1D;AAAA,IACF,CAAC,aAAa,KAAK,EAAE;AAAA,EACvB;AAEA,MAAI,KAAK,WAAW,eAAe,kBAAkB;AACnD,WAAO;AAAA,MACL,qDAAqD,KAAK,WAAW,UAAU;AAAA,IACjF;AACA,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,UAAU,YAAY;AAAA,MACrD;AAAA,QACE,UAAU;AAAA,QACV,QAAQ,KAAK,WAAW;AAAA,QACxB,QAAQ,KAAK;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,QAAQ,MAAM,QAAQ,QAAQ;AAE7C,MAAI,MAAM,MAAM,GAAG;AACjB,WAAO,MAAM,6BAA6B,OAAO,KAAK,EAAE;AACxD,UAAM,OAAO,OAAO;AACpB,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,IAAI;AAAA,MACnC;AAAA,MACA;AAAA,QACE,QAAQ,KAAK;AAAA,QACb,QAAQ,QAAQ;AAAA,QAChB,UAAU,QAAQ;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,+BAA+B,MAAM,iBAAiB,KAAK;AAAA,MACzD;AAAA,IACF,CAAC,aAAa,KAAK,EAAE;AAAA,EACvB;AACA,SAAO,OAAO;AAChB;;;AClDK,IAAM,oBACX,CACE,QACA,YACA,YAEF,CAAC,YAA+B;AAC9B,QAAM,EAAE,MAAM,QAAQ,SAAS,IAAI;AACnC,SAAO;AAAA,IACL,2BAA2B,MAAM,iBAAiB,KAAK,UAAU,QAAQ,CAAC,aAAa,KAAK,EAAE;AAAA,EAChG;AAEA,MAAI,KAAK,WAAW,eAAe,cAAc;AAC/C,WAAO;AAAA,MACL,iDAAiD,KAAK,WAAW,UAAU;AAAA,IAC7E;AACA,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,UAAU,YAAY;AAAA,MACrD;AAAA,QACE,UAAU;AAAA,QACV,QAAQ,KAAK,WAAW;AAAA,QACxB,QAAQ,KAAK;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,QAAQ,MAAM,QAAQ,QAAQ;AAE7C,MAAI,MAAM,MAAM,GAAG;AACjB,WAAO,MAAM,wBAAwB,OAAO,KAAK,EAAE;AACnD,UAAM,OAAO,OAAO;AACpB,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,IAAI;AAAA,MACnC;AAAA,MACA,EAAE,QAAQ,KAAK,IAAI,QAAQ,SAAS;AAAA,IACtC;AAAA,EACF;AAEA,SAAO,KAAK,0BAA0B,MAAM,aAAa,KAAK,EAAE,EAAE;AAClE,SAAO,OAAO;AAChB;;;ACxCK,IAAM,qBACX,CACE,QACA,YACA,YAEF,CAAC,YAAgC;AAC/B,QAAM,EAAE,MAAM,QAAQ,SAAS,IAAI;AACnC,SAAO;AAAA,IACL,4BAA4B,MAAM,iBAAiB,KAAK;AAAA,MACtD;AAAA,IACF,CAAC,aAAa,KAAK,EAAE;AAAA,EACvB;AAEA,MAAI,KAAK,WAAW,eAAe,eAAe;AAChD,WAAO;AAAA,MACL,kDAAkD,KAAK,WAAW,UAAU;AAAA,IAC9E;AACA,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,UAAU,YAAY;AAAA,MACrD;AAAA,QACE,UAAU;AAAA,QACV,QAAQ,KAAK,WAAW;AAAA,QACxB,QAAQ,KAAK;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,QAAQ,MAAM,QAAQ,QAAQ;AAE7C,MAAI,MAAM,MAAM,GAAG;AACjB,WAAO,MAAM,yBAAyB,OAAO,KAAK,EAAE;AACpD,UAAM,OAAO,OAAO;AACpB,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,IAAI;AAAA,MACnC;AAAA,MACA;AAAA,QACE,QAAQ,KAAK;AAAA,QACb,QAAQ,QAAQ;AAAA,QAChB,UAAU,QAAQ;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,2BAA2B,MAAM,iBAAiB,KAAK;AAAA,MACrD;AAAA,IACF,CAAC,aAAa,KAAK,EAAE;AAAA,EACvB;AACA,SAAO,OAAO;AAChB;;;AClDK,IAAM,wBACX,CACE,QACA,YACA,YAEF,CAAC,YAAmC;AAClC,QAAM,EAAE,MAAM,QAAQ,WAAW,UAAU,kBAAkB,IAAI;AACjE,SAAO;AAAA,IACL,sBAAsB,SAAS,cAAc,MAAM,aAAa,KAAK,EAAE;AAAA,EACzE;AAEA,MAAI,KAAK,WAAW,eAAe,kBAAkB;AACnD,WAAO;AAAA,MACL,qDAAqD,KAAK,WAAW,UAAU;AAAA,IACjF;AACA,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,UAAU,YAAY;AAAA,MACrD;AAAA,QACE,UAAU;AAAA,QACV,QAAQ,KAAK,WAAW;AAAA,QACxB,QAAQ,KAAK;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,MAAM,MAAM,GAAG;AACjB,WAAO,MAAM,6BAA6B,OAAO,KAAK,EAAE;AACxD,UAAM,OAAO,OAAO;AACpB,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,IAAI;AAAA,MACnC;AAAA,MACA;AAAA,QACE,QAAQ,KAAK;AAAA,QACb;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,WAAW,SAAS,wBAAwB,MAAM,aAAa,KAAK,EAAE;AAAA,EACxE;AACA,SAAO,OAAO;AAChB;;;ACrDK,IAAM,mBACX,CACE,QACA,YACA,YAEF,CAAC,YAA8B;AAC7B,QAAM,EAAE,MAAM,QAAQ,YAAY,gBAAgB,oBAAoB,IACpE;AACF,SAAO;AAAA,IACL,2BAA2B,MAAM,eAAe,cAAc,aAAa,KAAK,EAAE;AAAA,EACpF;AAEA,MAAI,KAAK,WAAW,eAAe,aAAa;AAC9C,WAAO;AAAA,MACL,gDAAgD,KAAK,WAAW,UAAU;AAAA,IAC5E;AACA,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,UAAU,YAAY;AAAA,MACrD;AAAA,QACE,UAAU;AAAA,QACV,QAAQ,KAAK,WAAW;AAAA,QACxB,QAAQ,KAAK;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,MAAM,MAAM,GAAG;AACjB,WAAO,MAAM,wBAAwB,OAAO,KAAK,EAAE;AACnD,UAAM,OAAO,OAAO;AACpB,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,IAAI;AAAA,MACnC;AAAA,MACA,EAAE,QAAQ,KAAK,IAAI,QAAQ,gBAAgB,oBAAoB;AAAA,IACjE;AAAA,EACF;AAEA,SAAO;AAAA,IACL,yBAAyB,MAAM,eAAe,cAAc,aAAa,KAAK,EAAE;AAAA,EAClF;AACA,SAAO,OAAO;AAChB;;;AC3DF,IAAM,wBAAwB;AAkBvB,IAAM,gBAAgB,CAAC,SAA4B;AACxD,QAAM,aAA6B;AAAA,IACjC,SAAS;AAAA,IACT,MAAM;AAAA,IACN,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC;AACA,SAAO,KAAK,UAAU,UAAU;AAClC;AASO,IAAM,kBAAkB,CAAC,SAAoC;AAClE,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,IAAI;AAG9B,QAAI,CAAC,OAAO,WAAW,CAAC,OAAO,MAAM;AACnC,aAAO,IAAI,gCAAgC;AAAA,IAC7C;AAGA,QAAI,OAAO,UAAU,uBAAuB;AAC1C,aAAO;AAAA,QACL,sCAAsC,OAAO,OAAO,sBAAsB,qBAAqB;AAAA,MACjG;AAAA,IACF;AAGA,UAAM,OAAO,OAAO;AACpB,QAAI,CAAC,KAAK,MAAM,CAAC,KAAK,WAAW,CAAC,KAAK,SAAS,CAAC,KAAK,YAAY;AAChE,aAAO,IAAI,8BAA8B;AAAA,IAC3C;AAEA,WAAO,GAAG,IAAI;AAAA,EAChB,SAAS,OAAO;AACd,WAAO,IAAI,8BAA+B,MAAgB,OAAO,EAAE;AAAA,EACrE;AACF;AAuBO,IAAM,kBAAkB,CAAC,SAAmC;AACjE,SAAO;AAAA,IACL,YAAY,cAAc,IAAI;AAAA,IAC9B,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC,QAAQ,KAAK;AAAA,IACb,MAAM,KAAK;AAAA,EACb;AACF;AAQO,IAAM,uBAAuB,CAClC,cACsB;AACtB,SAAO,gBAAgB,UAAU,UAAU;AAC7C;;;ACpFO,IAAM,uBAAuB,CAClC,QACA,gBACyB;AACzB,SAAO,CAAC,YAAY;AAClB,WAAO,KAAK,qBAAqB,QAAQ,KAAK,EAAE,EAAE;AAClD,UAAM,aAAa,cAAc,QAAQ,IAAI;AAC7C,WAAO,KAAK,8BAA8B;AAC1C,WAAO;AAAA,EACT;AACF;AAKO,IAAM,yBAAyB,CACpC,QACA,eAC2B;AAC3B,SAAO,CAAC,YAAY;AAClB,WAAO,KAAK,8BAA8B;AAC1C,UAAM,SAAS,gBAAgB,QAAQ,IAAI;AAE3C,QAAI,MAAM,MAAM,GAAG;AACjB,aAAO,MAAM,+BAA+B,OAAO,KAAK,EAAE;AAC1D,YAAM,OAAO,OAAO;AACpB,YAAM,IAAI,mBAAmB,mBAAmB,YAAY,IAAI,GAAG,IAAI;AAAA,IACzE;AAEA,UAAM,OAAO,OAAO,MAAM;AAC1B,WAAO,KAAK,mCAAmC,KAAK,EAAE,EAAE;AACxD,WAAO;AAAA,EACT;AACF;;;ACzCO,IAAM,4BACX,CACE,QACA,YACA,YAEF,CAAC,YAAuC;AACtC,QAAM,EAAE,MAAM,OAAO,IAAI;AACzB,SAAO;AAAA,IACL,sCAAsC,MAAM,aAAa,KAAK,EAAE;AAAA,EAClE;AAEA,QAAM,SAAS,QAAQ,MAAM,MAAM;AAEnC,MAAI,MAAM,MAAM,GAAG;AACjB,WAAO,MAAM,mCAAmC,OAAO,KAAK,EAAE;AAC9D,UAAM,OAAO,OAAO;AACpB,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,IAAI;AAAA,MACnC;AAAA,MACA,EAAE,QAAQ,KAAK,IAAI,QAAQ,QAAQ,OAAO;AAAA,IAC5C;AAAA,EACF;AAEA,SAAO;AAAA,IACL,qCAAqC,MAAM,aAAa,KAAK,EAAE;AAAA,EACjE;AACA,SAAO,OAAO;AAChB;;;ACzBK,IAAM,mBACX,CACE,QACA,YACA,YAEF,CAAC,YAA8B;AAC7B,QAAM,EAAE,KAAK,IAAI;AACjB,SAAO,KAAK,kBAAkB,KAAK,EAAE,EAAE;AAEvC,MAAI,CAAC,mBAAmB,IAAI,GAAG;AAC7B,WAAO;AAAA,MACL,2DAA2D,KAAK,WAAW,IAAI;AAAA,IACjF;AACA,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,UAAU,YAAY;AAAA,MACrD,EAAE,UAAU,QAAQ,QAAQ,KAAK,WAAW,MAAM,QAAQ,KAAK,GAAG;AAAA,IACpE;AAAA,EACF;AAEA,MACE,KAAK,WAAW,SAAS,WACzB,KAAK,WAAW,SAAS,WACzB;AACA,WAAO;AAAA,MACL,0DAA0D,KAAK,WAAW,IAAI;AAAA,IAChF;AACA,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,UAAU,YAAY;AAAA,MACrD;AAAA,QACE,UAAU;AAAA,QACV,QAAQ,KAAK,WAAW;AAAA,QACxB,QAAQ,KAAK;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,QAAQ,IAAI;AAE3B,MAAI,MAAM,MAAM,GAAG;AACjB,WAAO,MAAM,wBAAwB,OAAO,KAAK,EAAE;AACnD,UAAM,OAAO,OAAO;AACpB,UAAM,IAAI,mBAAmB,mBAAmB,YAAY,IAAI,GAAG,MAAM;AAAA,MACvE,QAAQ,KAAK;AAAA,IACf,CAAC;AAAA,EACH;AAEA,SAAO,KAAK,iBAAiB,KAAK,EAAE,EAAE;AACtC,SAAO,OAAO;AAChB;;;ACpDK,IAAM,mBACX,CACE,QACA,YACA,YAEF,CAAC,YAA8B;AAC7B,QAAM,EAAE,MAAM,QAAQ,WAAW,IAAI;AACrC,SAAO;AAAA,IACL,6BAA6B,UAAU,cAAc,MAAM,aAAa,KAAK,EAAE;AAAA,EACjF;AAEA,MAAI,KAAK,WAAW,eAAe,aAAa;AAC9C,WAAO;AAAA,MACL,gDAAgD,KAAK,WAAW,UAAU;AAAA,IAC5E;AACA,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,UAAU,YAAY;AAAA,MACrD;AAAA,QACE,UAAU;AAAA,QACV,QAAQ,KAAK,WAAW;AAAA,QACxB,QAAQ,KAAK;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,QAAQ,MAAM,QAAQ,UAAU;AAE/C,MAAI,MAAM,MAAM,GAAG;AACjB,WAAO,MAAM,uBAAuB,OAAO,KAAK,EAAE;AAClD,UAAM,OAAO,OAAO;AACpB,UAAM,IAAI;AAAA,MACR,mBAAmB,YAAY,IAAI;AAAA,MACnC;AAAA,MACA;AAAA,QACE,QAAQ,KAAK;AAAA,QACb,QAAQ,QAAQ;AAAA,QAChB,YAAY,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,4BAA4B,UAAU,cAAc,MAAM,aAAa,KAAK,EAAE;AAAA,EAChF;AACA,SAAO,OAAO;AAChB;;;AC1DK,IAAM,0BAA0B,CACrC,YACA,MACA,oBACwB;AACxB,QAAM,sBAAsB,WAAW,OAAO,CAAC,SAAS;AACtD,WACE,KAAK,KAAK,OAAO,CAAC,MAAM,EAAE,SAAS,IAAI,EAAE,SAAS,MACjD,CAAC,KAAK,gBAAgB,KAAK,iBAAiB;AAAA,EAEjD,CAAC;AAED,MAAI,oBAAoB,WAAW,GAAG;AACpC,WAAO,IAAI,UAAU,qBAAqB;AAAA,EAC5C;AAEA,SAAO,GAAG,mBAAmB;AAC/B;AAEO,IAAM,cAAc,CACzB,MACA,eACsB;AACtB,QAAM,YAAY,WAAW,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AAExD,MAAI,CAAC,WAAW;AACd,WAAO,IAAI,UAAU,qBAAqB;AAAA,EAC5C;AAEA,SAAO,GAAG,SAAS;AACrB;;;ACdO,IAAM,aAAa;AAAA;AAAA,EAExB,YAAY;AAAA;AAAA,EAEZ,gBAAgB;AAAA;AAAA,EAEhB,SAAS;AAAA;AAAA,EAET,eAAe;AAAA;AAAA,EAEf,YAAY;AAAA;AAAA,EAEZ,aAAa;AAAA;AAAA,EAEb,aAAa;AACf;;;AC/BO,IAAM,SAAS;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACeO,IAAM,WAAW;AAKjB,IAAM,mBAAmB;;;AC7BzB,IAAM,kBAAkB;AAAA,EAC7B,WAAW;AAAA,EACX,OAAO;AAAA,EACP,OAAO;AACT;AA2CO,IAAM,gBAAgB;AAAA,EAC3B,SAAS;AAAA,EACT,MAAM;AAAA,EACN,UAAU;AAAA,EACV,OAAO;AACT;AAiCO,IAAM,sBAAsB;AAAA;AAAA,EAEjC,eAAe;AAAA;AAAA,EAEf,WAAW;AAAA;AAAA,EAEX,gBAAgB;AAAA;AAAA,EAEhB,gBAAgB;AAAA;AAAA,EAEhB,SAAS;AAAA;AAAA,EAET,UAAU;AAAA;AAAA,EAEV,UAAU;AACZ;AAOO,IAAM,eAAe;AAAA,EAC1B,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AACV;AAOO,IAAM,gBAA6C;AAAA,EACxD,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AACV;;;ACpEO,IAAM,gBAAgB;AAAA;AAAA,EAE3B,aAAa;AAAA;AAAA,EAEb,YAAY;AAAA;AAAA,EAEZ,MAAM;AAAA;AAAA,EAEN,aAAa;AAAA;AAAA,EAEb,mBAAmB;AAAA;AAAA,EAEnB,WAAW;AAAA;AAAA,EAEX,oBAAoB;AAAA;AAAA,EAEpB,YAAY;AAAA;AAAA,EAEZ,WAAW;AAAA;AAAA,EAEX,gBAAgB;AAAA;AAAA,EAEhB,gBAAgB;AAClB;;;ACpFA,IAAM,WAAW,CAAC,QAAwB;AACxC,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,YAAQ,IAAI,WAAW,CAAC;AACxB,WAAO,KAAK,KAAK,MAAM,QAAQ;AAAA,EACjC;AACA,SAAO,SAAS;AAClB;AAEA,IAAM,aAAa,CAAC,SAAiC;AACnD,MAAI,QAAQ;AACZ,SAAO,MAAM;AACX,aAAS;AACT,YAAS,QAAQ,aAAc;AAC/B,QAAI,IAAI,KAAK,KAAK,QAAS,UAAU,IAAK,IAAI,KAAK;AACnD,QAAK,IAAI,KAAK,KAAK,IAAK,MAAM,GAAI,KAAK,CAAC,IAAK;AAC7C,aAAS,IAAK,MAAM,QAAS,KAAK;AAAA,EACpC;AACF;AAEO,IAAM,sBAAsB,CACjC,MACA,SACkB;AAClB,QAAM,cAAc,SAAS,GAAG,IAAI,IAAI,IAAI,EAAE;AAC9C,QAAM,SAAS,WAAW,WAAW;AAErC,SAAO,CAAI,UAAoB;AAC7B,UAAM,SAAS,CAAC,GAAG,KAAK;AACxB,aAAS,IAAI,OAAO,SAAS,GAAG,IAAI,GAAG,KAAK;AAC1C,YAAM,IAAI,KAAK,MAAM,OAAO,KAAK,IAAI,EAAE;AACvC,OAAC,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAQ,OAAO,CAAC,CAAM;AAAA,IAC1D;AACA,WAAO;AAAA,EACT;AACF;;;ACnBO,IAAM,uBACX,CAAC,SAKD,CAAC,MAAM,UAAU;AACf,QAAM,EAAE,gBAAgB,oBAAoB,eAAAG,eAAc,IAAI;AAC9D,QAAM,sBAAsB,eAAe,YAAY;AAEvD,QAAM,gBAA6B,CAAC;AAEpC,aAAW,QAAQ,OAAO;AACxB,UAAM,SAAS,YAAY,MAAM,mBAAmB;AAEpD,QAAI,MAAM,MAAM,GAAG;AACjB,aAAO;AAAA,IACT;AAEA,kBAAc,KAAK,OAAO,KAAK;AAAA,EACjC;AAGA,MAAI,eAAe,KAAK,MAAM;AAC9B,MAAI,kBAAkB,KAAK;AAC3B,QAAM,gBAAgB,cAAc;AAAA,IAClC,CAAC,MAAM,EAAE,SAAS;AAAA,EACpB;AACA,MAAI,eAAe;AACjB,mBAAe;AAAA,MACb,GAAG;AAAA,MACH,aAAa;AAAA,MACb,UAAU;AAAA,MACV,gBAAgB;AAAA,IAClB;AAEA,UAAM,cAAc,mBAAmB,WAAW,KAAK,IAAI;AAC3D,QAAI,aAAa;AACf,YAAM,UAAU,KAAK,OACjB,oBAAoB,KAAK,MAAM,aAAa,IAC5CA;AACJ,wBAAkB,QAAQ,WAAW;AAAA,IACvC;AAAA,EACF;AAEA,QAAM,eAAe;AAAA,IACnB,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAEA,QAAM,OAAiB;AAAA,IACrB,MAAM;AAAA,IACN,MAAM,UAAU;AAAA,EAClB;AAEA,QAAM,cAAgC;AAAA,IACpC,GAAG;AAAA,IACH,UAAU;AAAA,IACV,OAAO;AAAA,IACP,YAAY;AAAA,EACd;AAEA,SAAO,GAAG,WAAW;AACvB;;;AC/EF,IAAM,kBAAkB;AAKjB,IAAM,oBAAoB,CAAC,aAChC,SAAS,WAAW,eAAe;AAK9B,IAAM,+BAA+B,CAAC,aAC3C,aAAa;AAMR,IAAM,gBAAgB,CAAC,YAC3B,OAAO,KAAK,YAAY,WAAW,OAAO,MAAM,YAAY;AAMxD,IAAM,oBAAoB,CAAC,YAC/B,OAAO,KAAK,gBAAgB,WAAW,OAAO,MAAM,gBAAgB;;;ACzBhE,IAAM,iBAAiB;AAGvB,IAAM,cAAc;AAIpB,IAAM,WAAW,CAAC,QAAgB,YAA4B;AAAA,EACnE,GAAG;AAAA,EACH,QAAQ,OAAO,SAAS,KAAK;AAC/B;AAEO,IAAM,cAAc,CAAC,QAAgB,YAA4B;AAAA,EACtE,GAAG;AAAA,EACH,QAAQ,OAAO,SAAS,KAAK;AAC/B;AAEO,IAAM,YAAY,CAAC,QAAgB,UACvC,OAAO,SAAS,MAAM;AAElB,IAAM,YAAY,CAAC,QAAgB,YAA4B;AAAA,EACpE,GAAG;AAAA,EACH,SAAS,OAAO,UAAU,KAAK;AACjC;AAEO,IAAM,gBAAgB,CAAC,WAA2B,OAAO,UAAU;;;ACnB1E,IAAM,WAAW,CAAC,WAAsC;AACtD,SAAO,OAAO,SAAS,MAAgB;AACzC;AAEO,IAAM,aAAa,CACxB,QACA,SAAgB,MACK;AACrB,MAAI,SAAS,MAAM,GAAG;AACpB,WAAO,EAAE,MAAM,QAAQ,OAAO;AAAA,EAChC;AACA,SAAO,EAAE,MAAM,QAAQ,QAAQ,EAAE;AACnC;;;ACPO,IAAM,qBAAqB,MAAe;AAC/C,QAAM,YAAY,WAAW,OAAO;AACpC,SAAO,MAAM;AAAA,IAAK,EAAE,QAAQ,SAAS;AAAA,IAAG,MACtC,MAAM,KAAK,EAAE,QAAQ,SAAS,GAAG,MAAM,SAAS;AAAA,EAClD;AACF;AAEO,IAAM,cAAc,CAAC,YAA8B;AACxD,QAAM,SAAS,WAAW,QAAQ;AAClC,QAAM,aAAa,gBAAgB,OAAO;AAC1C,aAAW,CAAC,EAAG,CAAC,IAAI;AACpB,SAAO;AACT;AAEO,IAAM,YAAY,CACvB,SACA,UACA,SACY;AACZ,QAAM,aAAa,gBAAgB,OAAO;AAC1C,aAAW,SAAS,CAAC,EAAG,SAAS,CAAC,IAAI;AACtC,SAAO;AACT;AAEO,IAAM,UAAU,CACrB,SACA,aAC6B;AAC7B,QAAM,OAAO,QAAQ,SAAS,CAAC,IAAI,SAAS,CAAC;AAC7C,MAAI,CAAC,MAAM;AACT,WAAO,IAAI,UAAU,uBAAuB;AAAA,EAC9C;AACA,SAAO,GAAG,IAAI;AAChB;AAEO,IAAM,0BAA0B,CACrC,UACA,UACA,WAC6E;AAC7E,MAAI;AAIJ,MAAI;AAKJ,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,kBAAY;AAAA,QACV,MAAM,OAAO;AAAA,QACb,UAAU;AAAA,UACR,GAAG,SAAS;AAAA,UACZ,GAAG,SAAS;AAAA,QACd;AAAA,MACF;AACA,mBAAa;AAAA,QACX,MAAM,OAAO;AAAA,QACb,UAAU;AAAA,UACR,GAAG,SAAS,IAAI;AAAA,UAChB,GAAG,SAAS;AAAA,QACd;AAAA,MACF;AACA;AAAA,IACF,KAAK;AACH,kBAAY;AAAA,QACV,MAAM,OAAO;AAAA,QACb,UAAU;AAAA,UACR,GAAG,SAAS;AAAA,UACZ,GAAG,SAAS;AAAA,QACd;AAAA,MACF;AACA,mBAAa;AAAA,QACX,MAAM,OAAO;AAAA,QACb,UAAU;AAAA,UACR,GAAG,SAAS;AAAA,UACZ,GAAG,SAAS,IAAI;AAAA,QAClB;AAAA,MACF;AACA;AAAA,IACF,KAAK;AACH,kBAAY;AAAA,QACV,MAAM,OAAO;AAAA,QACb,UAAU;AAAA,UACR,GAAG,SAAS;AAAA,UACZ,GAAG,SAAS;AAAA,QACd;AAAA,MACF;AACA,mBAAa;AAAA,QACX,MAAM,OAAO;AAAA,QACb,UAAU;AAAA,UACR,GAAG,SAAS,IAAI;AAAA,UAChB,GAAG,SAAS;AAAA,QACd;AAAA,MACF;AACA;AAAA,IACF,KAAK;AACH,kBAAY;AAAA,QACV,MAAM,OAAO;AAAA,QACb,UAAU;AAAA,UACR,GAAG,SAAS;AAAA,UACZ,GAAG,SAAS;AAAA,QACd;AAAA,MACF;AACA,mBAAa;AAAA,QACX,MAAM,OAAO;AAAA,QACb,UAAU;AAAA,UACR,GAAG,SAAS;AAAA,UACZ,GAAG,SAAS,IAAI;AAAA,QAClB;AAAA,MACF;AACA;AAAA,EACJ;AAEA,SAAO,CAAC,WAAW,UAAU;AAC/B;AAEO,IAAM,cAAc,CACzB,SACA,UACA,UACA,QACA,iBAAyB,qBACL;AACpB,QAAM,CAAC,WAAW,UAAU,IAAI;AAAA,IAC9B;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,oBAAoB;AAAA,IACxB;AAAA,IACA,UAAU;AAAA,IACV,WAAW;AAAA,EACb;AACA,MAAI,MAAM,iBAAiB,GAAG;AAC5B,WAAO;AAAA,EACT;AAEA,MACE;AAAA,IACE;AAAA,IACA,UAAU;AAAA,IACV,WAAW;AAAA,IACX;AAAA,EACF,GACA;AACA,WAAO,IAAI,UAAU,8BAA8B;AAAA,EACrD;AAEA,QAAM,gBAAgB,WAAW,SAAS,WAAW,UAAU;AAE/D,MAAI,cAAc,WAAW,GAAG;AAC9B,WAAO,IAAI,UAAU,sBAAsB;AAAA,EAC7C;AAEA,MAAI,CAAC,iBAAiB,aAAa,GAAG;AACpC,WAAO,IAAI,UAAU,yBAAyB;AAAA,EAChD;AAEA,SAAO,GAAG,WAAW,SAAS,CAAC,WAAW,UAAU,CAAC,CAAC;AACxD;AAEA,IAAM,aAAa,CACjB,SACA,UACG;AACH,MAAI,aAAa,gBAAgB,OAAO;AACxC,aAAW,EAAE,MAAM,SAAS,KAAK,OAAO;AACtC,iBAAa,UAAU,YAAY,UAAU,IAAI;AAAA,EACnD;AACA,SAAO;AACT;AAEA,IAAM,cAAc,CAClB,SACA,eACA,mBACoB;AACpB,QAAM,YAAY,QAAQ,SAAS,aAAa;AAChD,QAAM,aAAa,QAAQ,SAAS,cAAc;AAElD,MAAI,MAAM,SAAS,GAAG;AACpB,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,UAAU,GAAG;AACrB,WAAO;AAAA,EACT;AAEA,MAAI,UAAU,MAAM,SAAS,WAAW,WAAW,MAAM,SAAS,SAAS;AACzE,WAAO,IAAI,UAAU,mBAAmB;AAAA,EAC1C;AAEA,SAAO,GAAG,IAAI;AAChB;AAIA,IAAM,aAAa,CACjB,SACA,WACA,eACmB;AACnB,QAAM,UAAU;AAAA,IACd,EAAE,GAAG,IAAI,GAAG,EAAE;AAAA,IACd,EAAE,GAAG,GAAG,GAAG,EAAE;AAAA,IACb,EAAE,GAAG,GAAG,GAAG,GAAG;AAAA,IACd,EAAE,GAAG,GAAG,GAAG,EAAE;AAAA,EACf;AAEA,QAAM,gBAAgB,CAAC,GAAW,MAC/B,MAAM,UAAU,SAAS,KAAK,MAAM,UAAU,SAAS,KACvD,MAAM,WAAW,SAAS,KAAK,MAAM,WAAW,SAAS;AAE5D,QAAM,QAAwB,CAAC;AAE/B,aAAW,OAAO,CAAC,WAAW,UAAU,GAAG;AACzC,eAAW,UAAU,SAAS;AAC5B,YAAM,KAAK,IAAI,SAAS,IAAI,OAAO;AACnC,YAAM,KAAK,IAAI,SAAS,IAAI,OAAO;AACnC,UAAI,cAAc,IAAI,EAAE,EAAG;AAC3B,YAAM,OAAO,QAAQ,SAAS,EAAE,GAAG,IAAI,GAAG,GAAG,CAAC;AAC9C,UAAI,KAAK,IAAI,KAAK,KAAK,MAAM,SAAS,SAAS;AAC7C,cAAM,KAAK,EAAE,UAAU,KAAK,OAAO,KAAK,IAAI,KAAK,CAAC;AAAA,MACpD;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,IAAM,mBAAmB,CAAC,UAAmC;AAC3D,SAAO,MAAM;AAAA,IACX,CAAC,EAAE,UAAU,IAAI,MACf,SAAS,SAAS,YAAY,SAAS,SAAS,IAAI;AAAA,EACxD;AACF;AAEO,IAAM,wBAAwB,CAAC,YAA8B;AAElE,MAAI;AACJ,MAAI;AAEJ,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,IAAI,QAAQ,CAAC,EAAG,UAAU,CAAC,SAAS,KAAK,SAAS,QAAQ;AAChE,QAAI,MAAM,IAAI;AACZ,gBAAU;AACV,gBAAU;AACV;AAAA,IACF;AAAA,EACF;AAEA,MAAI,YAAY,UAAa,YAAY,QAAW;AAClD,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,eAAe,OAAO;AACnC,MAAI,CAAC,KAAM,QAAO;AAGlB,QAAM,WAAW,KAAK,OAAO,KAAK,QAAQ;AAC1C,QAAM,WAAW,KAAK,OAAO,KAAK,QAAQ;AAE1C,SAAO,YAAY,WAAW,YAAY;AAC5C;AAEO,IAAM,iBAAiB,CAC5B,YACsE;AACtE,MAAI,OAAO;AACX,MAAI,OAAO;AACX,MAAI,OAAO;AACX,MAAI,OAAO;AAEX,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,aAAS,IAAI,GAAG,IAAI,QAAQ,CAAC,EAAG,QAAQ,KAAK;AAC3C,UAAI,QAAQ,CAAC,EAAG,CAAC,EAAG,SAAS,SAAS;AACpC,YAAI,IAAI,KAAM,QAAO;AACrB,YAAI,IAAI,KAAM,QAAO;AACrB,YAAI,IAAI,KAAM,QAAO;AACrB,YAAI,IAAI,KAAM,QAAO;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,SAAS,SAAU,QAAO;AAC9B,SAAO,EAAE,MAAM,MAAM,MAAM,KAAK;AAClC;AAEA,IAAM,iBAAiB,CACrB,SACA,eACA,gBACA,UAAkB,qBACN;AACZ,QAAM,OAAO,eAAe,OAAO;AAEnC,MAAI,OAAO,MAAM,QAAQ;AACzB,MAAI,OAAO,MAAM,QAAQ;AACzB,MAAI,OAAO,MAAM,QAAQ;AACzB,MAAI,OAAO,MAAM,QAAQ;AAEzB,aAAW,OAAO,CAAC,eAAe,cAAc,GAAG;AACjD,QAAI,IAAI,IAAI,KAAM,QAAO,IAAI;AAC7B,QAAI,IAAI,IAAI,KAAM,QAAO,IAAI;AAC7B,QAAI,IAAI,IAAI,KAAM,QAAO,IAAI;AAC7B,QAAI,IAAI,IAAI,KAAM,QAAO,IAAI;AAAA,EAC/B;AAEA,SAAO,OAAO,OAAO,IAAI,WAAW,OAAO,OAAO,IAAI;AACxD;AAEO,IAAM,gBAAgB,CAAC,YAA6B;AACzD,QAAM,aAAa,QAAQ,KAAK,EAAE,OAAO,CAAC,SAAS,KAAK,SAAS,OAAO;AAExE,UAAQ,WAAW,SAAS,KAAK;AACnC;AAEA,IAAM,kBAAkB,CAAC,YAA8B;AACrD,SAAO,QAAQ,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,UAAU,EAAE,GAAG,KAAK,EAAE,CAAC;AAChE;;;AC/UA,IAAMC,uBAAsB;AAKrB,IAAM,gBAAgB,CAAC,aAC5B,SAAS,WAAWA,oBAAmB;AAMlC,IAAM,oBAAoB,CAC/B,aAC+B;AAC/B,MAAI,CAAC,cAAc,QAAQ,EAAG,QAAO;AACrC,SAAO,SAAS,MAAMA,qBAAoB,MAAM;AAClD;AAKO,IAAM,iBAAiB,CAAC,aAA8B;AAC3D,QAAM,MAAM,kBAAkB,QAAQ;AACtC,SAAO,QAAQ,WAAW,QAAQ;AACpC;AAKO,IAAM,cAAc,CAAC,aAA8B;AACxD,SAAO,kBAAkB,QAAQ,MAAM;AACzC;AAKO,IAAM,cAAc,CAAC,aAA8B;AACxD,SAAO,kBAAkB,QAAQ,MAAM;AACzC;;;ACpCA,IAAM,uBAAuB;AAEtB,IAAM,iBAAiB,CAAC,SAAiC;AAC9D,MAAI,CAAC,QAAQ,KAAK,KAAK,EAAE,SAAS,sBAAsB;AACtD,WAAO,IAAI,UAAU,mBAAmB;AAAA,EAC1C;AAEA,SAAO,GAAG,IAAI;AAChB;AAEO,IAAM,eAAe,CAC1B,YACA,IACA,SACA,QACmB;AACnB,QAAM,OAAO,eAAe,UAAU;AAEtC,MAAI,MAAM,IAAI,GAAG;AACf,WAAO;AAAA,EACT;AAEA,SAAO,GAAG;AAAA,IACR,MAAM,KAAK;AAAA,IACX;AAAA,IACA;AAAA,IACA,GAAI,OAAO,EAAE,IAAI;AAAA,EACnB,CAAC;AACH;;;ACAA,IAAM,uBAAuB,CAC3B,UACqD;AACrD,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,EAAE,MAAM,MAAM;AAAA,EACvB;AACA,SAAO,EAAE,MAAM,MAAM,MAAM,KAAK,MAAM,IAAI;AAC5C;AAEO,IAAM,oBACX,CAAC,SAKD,CAAC,MAAM,YAAY;AACjB,QAAM,EAAE,YAAAC,aAAY,eAAAC,gBAAe,eAAe,IAAI;AAEtD,QAAM,QAAQ,kBAAkB,KAAK,KAAK,IAAI;AAC9C,QAAM,aAAa,QAAQ,IAAI;AAC/B,QAAM,aAAa,QAAQ,IAAI;AAE/B,MACE,CAAC,WACD,QAAQ,SAAS,cACjB,QAAQ,SAAS,YACjB;AACA,WAAO,IAAI,UAAU,oBAAoB;AAAA,EAC3C;AAEA,QAAM,aAAsB,CAAC;AAE7B,aAAW,UAAU,SAAS;AAC5B,UAAM,EAAE,MAAM,IAAI,IAAI,qBAAqB,MAAM;AACjD,QAAI,UAAU,mBAAmB;AACjC,cAAU,YAAY,OAAO;AAC7B,UAAM,KAAKD,YAAW;AACtB,UAAM,YAAY,aAAa,MAAM,IAAI,SAAS,GAAG;AAErD,QAAI,MAAM,SAAS,GAAG;AACpB,aAAO;AAAA,IACT;AAGA,QAAI,KAAK,KAAK,SAAS,eAAe;AACpC,gBAAU,MAAM,QAAQ;AACxB,gBAAU,MAAM,SAAS;AACzB,gBAAU,MAAM,UAAU,CAAC;AAC3B,gBAAU,MAAM,YAAY,CAAC;AAAA,IAC/B;AAGA,QAAI,OAAO;AACT,gBAAU,MAAM,SAAS,CAAC;AAE1B,UAAI,6BAA6B,KAAK,KAAK,IAAI,GAAG;AAChD,kBAAU,MAAM,QAAQ;AACxB,kBAAU,MAAM,SAAS;AACzB,kBAAU,MAAM,UAAU,CAAC;AAC3B,kBAAU,MAAM,YAAY,CAAC;AAAA,MAC/B;AAAA,IACF;AAGA,QAAI,cAAc,KAAK,KAAK,IAAI,GAAG;AACjC,gBAAU,MAAM,aAAa,CAAC;AAC9B,UAAI,eAAe,KAAK,KAAK,IAAI,GAAG;AAClC,kBAAU,MAAM,YAAY,CAAC;AAAA,MAC/B;AACA,UAAI,YAAY,KAAK,KAAK,IAAI,GAAG;AAC/B,kBAAU,MAAM,UAAU,CAAC;AAAA,MAC7B;AAAA,IACF;AAEA,eAAW,KAAK,UAAU,KAAK;AAAA,EACjC;AAGA,QAAM,QAAQ,eAAe,OAAO;AACpC,QAAM,aACJ,SAAS,MAAM,WACX,MAAM,SAAS,WAAW,MAAM,IAChC,MAAM,MAAM,WAAW,MAAM;AAEnC,MAAI,CAAC,YAAY;AACf,WAAO,IAAI,UAAU,qBAAqB;AAAA,EAC5C;AAGA,QAAM,WAAW,KAAK;AACtB,QAAM,EAAE,YAAY,IAAI;AACxB,QAAM,UAAU,KAAK,OACjB,oBAAoB,KAAK,MAAM,UAAU,IACzCC;AACJ,QAAM,mBAAmB,QAAQ,QAAQ;AACzC,QAAM,kBAAkB,iBAAiB,MAAM,GAAG,WAAW;AAC7D,QAAM,OAAiB;AAAA,IACrB,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAEA,QAAM,cAAgC;AAAA,IACpC,GAAG;AAAA,IACH,SAAS;AAAA,IACT,UAAU;AAAA,IACV,OAAO;AAAA,MACL,GAAG,KAAK;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA,YAAY;AAAA,EACd;AAEA,SAAO,GAAG,WAAW;AACvB;;;ACrIK,IAAM,wBAA+C,CAC1D,SACA,mBACG;AACH,QAAM,OAAO,QAAQ;AACrB,QAAM,OAAO,QAAQ,CAAC,EAAG;AACzB,QAAM,UAAuB,QAAQ,IAAI,CAAC,QAAQ,IAAI,IAAI,MAAM,KAAK,CAAC;AACtE,QAAM,aAAyB,CAAC;AAGhC,QAAM,WAAW,oBAAI,IAAY;AACjC,MAAI,gBAAgB;AAClB,eAAW,OAAO,gBAAgB;AAChC,eAAS,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE;AAAA,IAClC;AAAA,EACF;AAEA,QAAM,aAAa;AAAA,IACjB,CAAC,IAAI,CAAC;AAAA,IACN,CAAC,GAAG,CAAC;AAAA,IACL,CAAC,GAAG,EAAE;AAAA,IACN,CAAC,GAAG,CAAC;AAAA,EACP;AAEA,WAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,YAAM,OAAO,QAAQ,CAAC,EAAG,CAAC;AAC1B,UAAI,QAAQ,CAAC,EAAG,CAAC,KAAK,KAAK,SAAS,WAAW,KAAK,SAAS,UAAU;AACrE;AAAA,MACF;AAGA,YAAM,OAAO,KAAK;AAClB,UAAI,OAAO;AACX,UAAI,SAAS;AACb,YAAM,QAA4B,CAAC,CAAC,GAAG,CAAC,CAAC;AACzC,cAAQ,CAAC,EAAG,CAAC,IAAI;AAEjB,aAAO,MAAM,SAAS,GAAG;AACvB,cAAM,CAAC,IAAI,EAAE,IAAI,MAAM,IAAI;AAC3B,cAAM,UAAU,QAAQ,EAAE,EAAG,EAAE;AAC/B;AAGA,YAAI,aAAa,QAAQ;AACzB,YAAI,SAAS,IAAI,GAAG,EAAE,IAAI,EAAE,EAAE,GAAG;AAC/B,uBAAa,KAAK,IAAI,GAAG,aAAa,CAAC;AAAA,QACzC;AACA,kBAAU;AAEV,mBAAW,CAAC,IAAI,EAAE,KAAK,YAAY;AACjC,gBAAM,KAAK,KAAM;AACjB,gBAAM,KAAK,KAAM;AACjB,cACE,MAAM,KACN,MAAM,KACN,KAAK,QACL,KAAK,QACL,CAAC,QAAQ,EAAE,EAAG,EAAE,KAChB,QAAQ,EAAE,EAAG,EAAE,EAAG,SAAS,MAC3B;AACA,oBAAQ,EAAE,EAAG,EAAE,IAAI;AACnB,kBAAM,KAAK,CAAC,IAAI,EAAE,CAAC;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAEA,iBAAW,KAAK,EAAE,MAAM,OAAO,CAAC;AAAA,IAClC;AAAA,EACF;AAEA,MAAI,WAAW,WAAW,GAAG;AAC3B,WAAO,GAAG;AAAA,MACR,QAAQ;AAAA,MACR,mBAAmB;AAAA,MACnB,aAAa;AAAA,IACf,CAAC;AAAA,EACH;AAEA,MAAI,SAAS;AACb,MAAI,oBAAoB;AACxB,MAAI,cAAc;AAElB,aAAW,YAAY,YAAY;AACjC,cAAU,SAAS,OAAO,SAAS;AACnC,QAAI,SAAS,OAAO,mBAAmB;AACrC,0BAAoB,SAAS;AAAA,IAC/B;AACA,mBAAe,SAAS;AAAA,EAC1B;AAEA,SAAO,GAAG;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACH;;;ACtGO,IAAM,aAAa,CAAC,IAAY,aAA2B;AAChE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AACF;AAEA,IAAM,UAAU,CAAC,SAAwB,KAAK;AAC9C,IAAM,WAAW,CAAC,SAAwB,KAAK;AAC/C,IAAM,eAAe,CAAC,SAAwB,KAAK;AAE5C,IAAM,UAAU,CAAC,SAAwB;AAC9C,SAAO,CAAC,QAAQ,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,aAAa,IAAI;AAChE;AAEO,IAAM,UAAU,CAAC,SAAwB;AAC9C,SAAO,CAAC,QAAQ,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,aAAa,IAAI;AAC/D;AAEO,IAAM,mCAAmC,CAC9C,SACwD;AACxD,SACE,CAAC,QAAQ,IAAI,KACb,CAAC,SAAS,IAAI,KACd,CAAC,aAAa,IAAI,KAClB,KAAK,iBAAiB;AAE1B;AAEO,IAAM,kBAAkB,CAAC,UAA0B;AACxD,SAAO,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM;AAC/B,YAAQ,EAAE,cAAc,UAAU,MAAM,EAAE,cAAc,UAAU;AAAA,EACpE,CAAC;AACH;AAEO,IAAM,oBAAoB,CAAC,UAA0B;AAC1D,SAAO,MAAM,IAAI,CAAC,UAAU;AAAA,IAC1B,GAAG;AAAA,IACH,WAAW;AAAA,IACX,SAAS;AAAA,IACT,UAAU;AAAA,EACZ,EAAE;AACJ;AAEO,IAAM,qBAAqB,CAAC,UAA8B;AAC/D,QAAM,WAAW,aAAa,KAAK;AAEnC,SAAO;AAAA,IACL,MAAM;AAAA,IACN,UAAU,SAAS;AAAA,IACnB,YAAY,SAAS,QAAQ,IACzB,cAAc,aACd,cAAc;AAAA,EACpB;AACF;AAEA,IAAM,eAAe,CAAC,UAAwB;AAC5C,QAAM,OAAO,MAAM,KAAK,CAACC,UAAS,CAAC,aAAaA,KAAI,CAAC;AACrD,MAAI,CAAC,MAAM;AACT,WAAO,MAAM,CAAC;AAAA,EAChB;AACA,SAAO;AACT;AAEO,IAAM,qBAAqB,CAAC,UAA2B;AAC5D,SAAO,MAAM,MAAM,CAAC,SAAS,KAAK,SAAS;AAC7C;AAQA,IAAM,8BAA+C;AAAA,EACnD,cAAc;AAAA,EACd,cAAc;AAAA,EACd,cAAc;AAAA,EACd,cAAc;AAChB;AAEO,IAAM,wBAAwB,CACnC,kBACkB;AAClB,QAAM,QAAQ,4BAA4B,QAAQ,aAAa;AAC/D,MAAI,UAAU,MAAM,SAAS,4BAA4B,SAAS,GAAG;AACnE,WAAO,cAAc;AAAA,EACvB;AACA,SAAO,4BAA4B,QAAQ,CAAC;AAC9C;AASA,IAAM,yBAA0C;AAAA,EAC9C,cAAc;AAAA;AAAA,EACd,cAAc;AAAA,EACd,cAAc;AAAA,EACd,cAAc;AAAA,EACd,cAAc;AAChB;AAOO,IAAM,wBAAwB,CACnC,eACA,kBACkB;AAClB,MAAI,CAAC,eAAe;AAElB,WAAO,cAAc;AAAA,EACvB;AAGA,QAAM,WAAW;AAEjB,QAAM,mBACJ,kBAAkB,cAAc,YAC5B,cAAc,aACd;AAEN,QAAM,QAAQ,SAAS,QAAQ,gBAAgB;AAC/C,MAAI,UAAU,MAAM,SAAS,SAAS,SAAS,GAAG;AAChD,WAAO,cAAc;AAAA,EACvB;AACA,SAAO,SAAS,QAAQ,CAAC;AAC3B;AAQA,IAAM,6BAA8C;AAAA,EAClD,cAAc;AAAA,EACd,cAAc;AAChB;AAQA,IAAM,yBAA0C;AAAA,EAC9C,cAAc;AAAA,EACd,cAAc;AAAA,EACd,cAAc;AAChB;AAOO,IAAM,oBAAoB,CAC/B,eACA,YACkB;AAClB,QAAM,WAAW,UACb,yBACA;AACJ,QAAM,QAAQ,SAAS,QAAQ,aAAa;AAC5C,MAAI,UAAU,MAAM,SAAS,SAAS,SAAS,GAAG;AAEhD,WAAO,cAAc;AAAA,EACvB;AACA,SAAO,SAAS,QAAQ,CAAC;AAC3B;;;ACxKO,IAAM,sBAA2C,CACtD,MACA,QACA,eACG;AACH,QAAM,cAAc,KAAK,MAAM;AAAA,IAC7B,CAAC,SAAS,KAAK,OAAO,KAAK,WAAW;AAAA,EACxC;AAEA,MAAI,CAAC,aAAa;AAChB,WAAO,IAAI,UAAU,cAAc;AAAA,EACrC;AAEA,MAAI,YAAY,OAAO,QAAQ;AAC7B,WAAO,IAAI,UAAU,aAAa;AAAA,EACpC;AAEA,MAAI,CAAC,QAAQ,WAAW,GAAG;AACzB,WAAO,IAAI,UAAU,WAAW;AAAA,EAClC;AAGA,QAAM,iBAAiB,KAAK,gBAAgB;AAAA,IAC1C,CAAC,WAAW,OAAO,OAAO,WAAW;AAAA,EACvC;AAEA,MAAI,CAAC,gBAAgB;AACnB,WAAO,IAAI,UAAU,gBAAgB;AAAA,EACvC;AAEA,MAAI,eAAe,QAAQ;AACzB,WAAO,IAAI,UAAU,qBAAqB;AAAA,EAC5C;AAGA,QAAM,yBAAyB,KAAK,gBAAgB;AAAA,IAAI,CAAC,WACvD,OAAO,OAAO,WAAW,aACrB,EAAE,GAAG,QAAQ,QAAQ,MAAM,QAAQ,YAAY,GAAG,IAClD;AAAA,EACN;AAEA,QAAM,UAAU,YAAY,KAAK,KAAK,IAAI;AAG1C,QAAM,eAAe,KAAK,MAAM;AAAA,IAAI,CAAC,SACnC,KAAK,OAAO,YAAY,KACpB;AAAA,MACE,GAAG;AAAA,MACH,SAAS;AAAA,MACT,WAAW;AAAA,MACX,cAAc,eAAe;AAAA,IAC/B,IACA;AAAA,EACN;AAEA,QAAM,YAAY,mBAAmB,YAAY;AAEjD,MAAI,WAAW;AAEb,UAAM,QAAQ,kBAAkB,gBAAgB,YAAY,CAAC;AAC7D,UAAM,cAAc,KAAK,OAAO;AAChC,UAAM,eAAe,CAAC,GAAG,KAAK,QAAQ;AACtC,UAAM,gBAAgB,aAAa;AAAA,MACjC;AAAA,MACA,KAAK,MAAM,MAAM;AAAA,IACnB;AACA,kBAAc,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM;AAGhD,UAAM,eAAe,KAAK,MAAM,MAAM,4BAA4B;AAClE,QAAI,eAAe,GAAG;AACpB,oBAAc,OAAO,GAAG,YAAY;AAAA,IACtC;AAEA,UAAM,qBAAqB,cAAc,IAAI,CAAC,QAAQ,WAAW;AAAA,MAC/D;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,UAAU,QAAQ;AAAA,IACpB,EAAE;AAEF,QAAI,SAAS;AAEX,aAAO,GAAG;AAAA,QACR,GAAG;AAAA,QACH,iBAAiB;AAAA,QACjB,UAAU;AAAA,QACV;AAAA,QACA,MAAM;AAAA,QACN,YAAY;AAAA,UACV,MAAM;AAAA,UACN,UAAU,YAAY;AAAA,UACtB,YAAY,cAAc;AAAA,QAC5B;AAAA,MACF,CAAC;AAAA,IACH;AAEA,UAAMC,QAAO,mBAAmB,KAAK;AACrC,WAAO,GAAG;AAAA,MACR,GAAG;AAAA,MACH,iBAAiB;AAAA,MACjB,UAAU;AAAA,MACV;AAAA,MACA,MAAM;AAAA,MACN,YAAYA;AAAA,IACd,CAAC;AAAA,EACH;AAEA,MAAI,SAAS;AAEX,WAAO,GAAG;AAAA,MACR,GAAG;AAAA,MACH,iBAAiB;AAAA,MACjB,OAAO;AAAA,MACP,YAAY;AAAA,QACV,MAAM;AAAA,QACN,UAAU,YAAY;AAAA,QACtB,YAAY,cAAc;AAAA,MAC5B;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,OAAO,mBAAmB,YAAY;AAE5C,SAAO,GAAG;AAAA,IACR,GAAG;AAAA,IACH,iBAAiB;AAAA,IACjB,OAAO;AAAA,IACP,YAAY;AAAA,EACd,CAAC;AACH;;;AC1IA,IAAM,cAAc;AAEb,IAAM,sBAAsB,CACjC,OACA,YACkB;AAClB,QAAM,WAAW,QAAQ,CAAC,GAAG,KAAK,CAAC;AACnC,QAAM,QAAQ,SAAS,MAAM,GAAG,WAAW;AAC3C,QAAM,WAAW,SAAS,MAAM,WAAW;AAE3C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAeO,IAAM,sBAAsB,CACjC,OACA,eACyD;AACzD,WAAS,IAAI,GAAG,IAAI,MAAM,MAAM,QAAQ,KAAK;AAC3C,UAAM,OAAO,MAAM,MAAM,CAAC;AAC1B,QAAI,QAAQ,KAAK,OAAO,YAAY;AAClC,aAAO,EAAE,UAAU,MAAM,WAAW,EAAE;AAAA,IACxC;AAAA,EACF;AACA,SAAO;AACT;AAEO,IAAM,0BAA0B,CACrC,OACA,cACkB;AAClB,QAAM,WAAW,CAAC,GAAG,MAAM,KAAK;AAChC,WAAS,SAAS,IAAI;AACtB,SAAO,EAAE,GAAG,OAAO,OAAO,SAAS;AACrC;AAEO,IAAM,mBAAmB,CAC9B,OACA,QACA,eAKU;AACV,QAAM,QAAQ,oBAAoB,OAAO,UAAU;AACnD,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,EAAE,UAAU,UAAU,IAAI;AAChC,MAAI,CAAC,UAAU,QAAQ,SAAS,IAAI,EAAG,QAAO;AAE9C,MAAI,gBAAgB,YAAY,QAAQ,SAAS,IAAI;AAGrD,MAAI,SAAS,gBAAgB;AAC3B,YAAQ,SAAS,eAAe,MAAM;AAAA,MACpC,KAAK;AACH,wBAAgB,SAAS,eAAe,SAAS,eAAe,MAAM;AACtE;AAAA,MACF,KAAK;AACH,wBAAgB;AAAA,UACd;AAAA,UACA,SAAS,eAAe;AAAA,QAC1B;AACA;AAAA,IACJ;AAAA,EACF;AAGA,MAAI,SAAS,SAAS,GAAG;AACvB,oBAAgB,UAAU,eAAe,SAAS,MAAM;AAAA,EAC1D;AAEA,QAAM,eAAe,wBAAwB,OAAO,SAAS;AAE7D,SAAO,EAAE,cAAc,eAAe,SAAS;AACjD;AA4BO,IAAM,8BAA8B,CACzC,SACA,iBACA,aACY;AACZ,QAAM,OAAO,QAAQ,SAAS,CAAC,IAAI,SAAS,CAAC;AAC7C,MAAI,CAAC,QAAQ,KAAK,SAAS,WAAW,KAAK,SAAS,SAAU,QAAO;AACrE,MAAI,EAAE,2BAA2B,SAAS,CAAC,KAAK;AAC9C,WAAO;AAET,QAAM,WAAW,gBAAgB;AAAA,IAC/B,CAAC,MAAM,EAAE,SAAS,MAAM,SAAS,KAAK,EAAE,SAAS,MAAM,SAAS;AAAA,EAClE;AACA,SAAO,CAAC;AACV;AAEO,IAAM,yBAAyB,CACpC,SACA,UACA,aACY;AAEZ,QAAM,aAAa,QAAQ,IAAI,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC;AAChD,QAAM,OAAO,WAAW,SAAS,CAAC,EAAG,SAAS,CAAC;AAE/C,MAAI,KAAK,SAAS,WAAW,KAAK,SAAS,UAAU;AACnD,eAAW,SAAS,CAAC,EAAG,SAAS,CAAC,IAAI;AAAA,MACpC,GAAG;AAAA,MACH,QAAQ,KAAK,SAAS,SAAS;AAAA,IACjC;AAAA,EACF;AAEA,SAAO;AACT;AAEO,IAAM,oBAAoB,CAC/B,OACA,YACA,WAIU;AACV,QAAM,QAAQ,oBAAoB,OAAO,UAAU;AACnD,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,EAAE,UAAU,UAAU,IAAI;AAChC,MAAI,CAAC,UAAU,QAAQ,SAAS,IAAI,EAAG,QAAO;AAE9C,QAAM,gBAAgB,YAAY,QAAQ,SAAS,IAAI;AACvD,QAAM,eAAe,wBAAwB,OAAO,SAAS;AAE7D,SAAO,EAAE,cAAc,cAAc;AACvC;;;AC9KO,IAAM,uBAAuB,CAClC,SACA,oBACkB;AAClB,MAAI,YAAY;AAChB,MAAI,WAA0B;AAC9B,MAAI,SAAS;AAEb,aAAW,UAAU,SAAS;AAC5B,UAAM,SAAS,cAAc,MAAM;AACnC,QAAI,SAAS,WAAW;AACtB,kBAAY;AACZ,iBAAW,OAAO;AAClB,eAAS;AAAA,IACX,WAAW,WAAW,aAAa,SAAS,KAAK,aAAa,MAAM;AAClE,eAAS;AAAA,IACX;AAAA,EACF;AAEA,MAAI,UAAU,cAAc,GAAG;AAC7B,WAAO;AAAA,EACT;AAEA,SAAO;AACT;;;ACTO,IAAM,2BAAqD,CAChE,MACA,QACA,YACA,aACG;AACH,QAAM,gBAAgB,KAAK;AAE3B,MAAI,cAAc,aAAa,QAAQ;AACrC,WAAO,IAAI,UAAU,aAAa;AAAA,EACpC;AAEA,MAAI,cAAc,eAAe,cAAc,mBAAmB;AAChE,WAAO,IAAI,UAAU,uBAAuB;AAAA,EAC9C;AAEA,MAAI,CAAC,KAAK,aAAa;AACrB,WAAO,IAAI,UAAU,uBAAuB;AAAA,EAC9C;AAEA,QAAM,cAAc,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM;AAC1D,MAAI,CAAC,YAAa,QAAO,IAAI,UAAU,cAAc;AAErD,QAAM,gBAAgB,KAAK,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,YAAY,QAAQ;AAC5E,MAAI,CAAC,cAAe,QAAO,IAAI,UAAU,gBAAgB;AAGzD,MACE,CAAC;AAAA,IACC,cAAc;AAAA,IACd,cAAc,aAAa,CAAC;AAAA,IAC5B;AAAA,EACF,GACA;AACA,WAAO,IAAI,UAAU,sBAAsB;AAAA,EAC7C;AAGA,QAAM,iBAAiB;AAAA,IACrB,KAAK,YAAY;AAAA,IACjB;AAAA,IACA;AAAA,EACF;AAEA,MAAI,CAAC,gBAAgB;AACnB,WAAO,IAAI,UAAU,sBAAsB;AAAA,EAC7C;AAEA,QAAM,EAAE,cAAc,eAAe,SAAS,IAAI;AAGlD,QAAM,iBAAiB;AAAA,IACrB,cAAc;AAAA,IACd;AAAA,IACA;AAAA,EACF;AAEA,QAAM,iBAAiC,EAAE,UAAU,SAAS;AAC5D,QAAM,cAAc;AAAA,IAClB,GAAG;AAAA,IACH,SAAS;AAAA,IACT,WAAW,CAAC,GAAI,cAAc,aAAa,CAAC,GAAI,cAAc;AAAA,EAChE;AAEA,QAAM,iBAAiB,KAAK,QAAQ;AAAA,IAAI,CAAC,MACvC,EAAE,OAAO,cAAc,KAAK,cAAc;AAAA,EAC5C;AAGA,QAAM,iBAAiB;AAAA,IACrB;AAAA,IACA,KAAK,YAAY;AAAA,EACnB;AAEA,QAAM,aAAa,sBAAsB,cAAc,iBAAiB;AAExE,SAAO,GAAG;AAAA,IACR,GAAG;AAAA,IACH,SAAS;AAAA,IACT,aAAa;AAAA,MACX,GAAG,KAAK;AAAA,MACR,eAAe;AAAA,MACf,eAAe;AAAA,IACjB;AAAA,IACA,YAAY;AAAA,MACV,MAAM;AAAA,MACN,UAAU;AAAA,MACV;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;ACpGO,IAAM,sBAAsB,OAAsB;AAAA,EACvD,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AACV;AAMO,IAAM,gBAAgB,CAC3B,MACA,YAC6D;AAC7D,MAAI,YAAY,KAAK,KAAK,OAAO,GAAG;AAClC,WAAO,GAAG,EAAE,OAAO,GAAG,aAAa,EAAE,GAAG,MAAM,MAAM,KAAK,OAAO,EAAE,EAAE,CAAC;AAAA,EACvE;AACA,MAAI,YAAY,KAAK,KAAK,OAAO,GAAG;AAClC,WAAO,GAAG,EAAE,OAAO,GAAG,aAAa,EAAE,GAAG,MAAM,MAAM,KAAK,OAAO,EAAE,EAAE,CAAC;AAAA,EACvE;AACA,MAAI,YAAY,KAAK,KAAK,SAAS,GAAG;AACpC,WAAO,GAAG,EAAE,OAAO,GAAG,aAAa,EAAE,GAAG,MAAM,QAAQ,KAAK,SAAS,EAAE,EAAE,CAAC;AAAA,EAC3E;AACA,SAAO,IAAI,UAAU,qBAAqB;AAC5C;AAkBA,IAAM,wBAAwB,CAC5B,MACA,OACA,aACe;AACf,MAAI,UAAU,EAAG,QAAO,CAAC,IAAI;AAG7B,MAAI,UAAU,oBAAI,IAAY;AAC9B,UAAQ,IAAI,GAAG,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE;AAEjC,WAAS,OAAO,GAAG,OAAO,OAAO,QAAQ;AACvC,UAAM,OAAO,oBAAI,IAAY;AAC7B,eAAW,OAAO,SAAS;AACzB,YAAM,CAAC,IAAI,EAAE,IAAI,IAAI,MAAM,GAAG,EAAE,IAAI,MAAM;AAC1C,eAAS,KAAK,IAAI,MAAM,GAAG,MAAM;AAC/B,iBAAS,KAAK,IAAI,MAAM,GAAG,MAAM;AAC/B,cAAI,OAAO,KAAK,OAAO,EAAG;AAC1B,gBAAM,KAAK,KAAK;AAChB,gBAAM,KAAK,KAAK;AAChB,cAAI,MAAM,KAAK,KAAK,YAAY,MAAM,KAAK,KAAK,UAAU;AACxD,iBAAK,IAAI,GAAG,EAAE,IAAI,EAAE,EAAE;AAAA,UACxB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,cAAU;AAAA,EACZ;AAEA,SAAO,CAAC,GAAG,OAAO,EAAE,IAAI,CAAC,QAAQ;AAC/B,UAAM,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,GAAG,EAAE,IAAI,MAAM;AACxC,WAAO,EAAE,GAAG,EAAE;AAAA,EAChB,CAAC;AACH;AAaO,IAAM,6BAA6B,CACxC,SACA,iBACA,OACA,uBACe;AACf,QAAM,WAAW,QAAQ;AACzB,QAAM,YAAY,sBAAsB,iBAAiB,OAAO,QAAQ;AAExE,QAAM,qBAAqB,IAAI;AAAA,IAC7B,mBAAmB,IAAI,CAAC,OAAO,GAAG,GAAG,SAAS,CAAC,IAAI,GAAG,SAAS,CAAC,EAAE;AAAA,EACpE;AAEA,SAAO,UAAU,OAAO,CAAC,QAAQ;AAC/B,UAAM,OAAO,QAAQ,IAAI,CAAC,IAAI,IAAI,CAAC;AACnC,QAAI,CAAC,KAAM,QAAO;AAClB,QAAI,KAAK,SAAS,QAAS,QAAO;AAClC,QAAI,KAAK,SAAS,UAAW,QAAO;AACpC,QAAI,KAAK,SAAS,SAAU,QAAO;AACnC,QAAI,KAAK,SAAS,EAAG,QAAO;AAC5B,QAAI,mBAAmB,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAG,QAAO;AACxD,WAAO;AAAA,EACT,CAAC;AACH;AAKO,IAAM,2BAA2B,CACtC,SACA,UACA,iBACA,OACA,uBACY;AACZ,QAAM,iBAAiB;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,SAAO,eAAe,KAAK,CAAC,MAAM,EAAE,MAAM,SAAS,KAAK,EAAE,MAAM,SAAS,CAAC;AAC5E;;;AC1IA,IAAM,qBAAqB;AAKpB,IAAM,kBAAkB,MAAc;AAMtC,IAAM,oBAAoB,CAAC,SAAiC;AACjE,MAAI,QAAQ,GAAG;AACb,WAAO,IAAI,UAAU,gBAAgB;AAAA,EACvC;AACA,SAAO,GAAG,OAAO,CAAC;AACpB;AAKO,IAAM,sBAAsB,CAAC,YAAiC;AACnE,QAAM,SAAqB,CAAC;AAC5B,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,MAAM,QAAQ,CAAC;AACrB,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,YAAM,OAAO,IAAI,CAAC;AAClB,UAAI,KAAK,SAAS,WAAW,KAAK,SAAS,YAAY,KAAK,SAAS,GAAG;AACtE,eAAO,KAAK,EAAE,GAAG,EAAE,CAAC;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAKO,IAAM,+BAA+B,CAC1C,SACA,WACe;AACf,QAAM,YAAY,oBAAoB,OAAO;AAC7C,SAAO,UAAU;AAAA,IACf,CAAC,UACC,CAAC,OAAO,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM,MAAM,KAAK,EAAE,SAAS,MAAM,MAAM,CAAC;AAAA,EAC5E;AACF;AAKO,IAAM,iBAAiB,CAAC,YAC5B,OAAO,QAAQ,UAAU,KAAK;AAM1B,IAAM,oBAAoB,CAC/B,QACA,aACmB;AACnB,QAAM,UAAU,OAAO;AACvB,QAAM,OAAO,QAAQ,SAAS,CAAC,IAAI,SAAS,CAAC;AAE7C,MAAI,CAAC,QAAQ,KAAK,SAAS,WAAW,KAAK,SAAS,UAAU;AAC5D,WAAO,IAAI,UAAU,uBAAuB;AAAA,EAC9C;AAEA,MAAI,KAAK,UAAU,GAAG;AACpB,WAAO,IAAI,UAAU,uBAAuB;AAAA,EAC9C;AAEA,QAAM,SAAS,OAAO,UAAU,CAAC;AAGjC,QAAM,iBAAiB,OAAO;AAAA,IAC5B,CAAC,MAAM,EAAE,SAAS,MAAM,SAAS,KAAK,EAAE,SAAS,MAAM,SAAS;AAAA,EAClE;AACA,MAAI,gBAAgB;AAClB,WAAO,IAAI,UAAU,uBAAuB;AAAA,EAC9C;AAEA,QAAM,WAAwB,EAAE,SAAS;AACzC,SAAO,GAAG;AAAA,IACR,GAAG;AAAA,IACH,QAAQ,CAAC,GAAG,QAAQ,QAAQ;AAAA,EAC9B,CAAC;AACH;AAMO,IAAM,sBAAsB,CACjC,cACA,cACA,YACA,wBAC+C;AAC/C,QAAM,eAAe,aAAa,UAAU,CAAC;AAE7C,MAAI,aAAa,KAAK,cAAc,aAAa,QAAQ;AACvD,WAAO,IAAI,UAAU,eAAe;AAAA,EACtC;AAGA,QAAM,aACJ,aAAa,QAAQ,oBAAoB,CAAC,IAAI,oBAAoB,CAAC;AACrE,MACE,CAAC,cACD,WAAW,SAAS,WACpB,WAAW,SAAS,YACpB,WAAW,UAAU,GACrB;AACA,WAAO,IAAI,UAAU,uBAAuB;AAAA,EAC9C;AAGA,QAAM,eAAe,aAAa,UAAU,CAAC;AAC7C,QAAM,iBAAiB,aAAa;AAAA,IAClC,CAAC,MACC,EAAE,SAAS,MAAM,oBAAoB,KACrC,EAAE,SAAS,MAAM,oBAAoB;AAAA,EACzC;AACA,MAAI,gBAAgB;AAClB,WAAO,IAAI,UAAU,uBAAuB;AAAA,EAC9C;AAGA,QAAM,sBAAsB,aAAa,OAAO,CAAC,GAAG,MAAM,MAAM,UAAU;AAG1E,QAAM,WAAwB,EAAE,UAAU,oBAAoB;AAE9D,SAAO,GAAG;AAAA,IACR,QAAQ,EAAE,GAAG,cAAc,QAAQ,oBAAoB;AAAA,IACvD,QAAQ,EAAE,GAAG,cAAc,QAAQ,CAAC,GAAG,cAAc,QAAQ,EAAE;AAAA,EACjE,CAAC;AACH;;;AC3HO,IAAM,SAAS,CAAC,YAQC;AACtB,QAAM,EAAE,IAAI,MAAM,UAAU,MAAM,WAAW,SAAS,WAAW,IAAI;AAErE,MAAI;AACJ,OACG,KAAK,SAAS,iBAAiB,KAAK,SAAS,8BAC9C,WACA;AACA,kBAAc;AAAA,MACZ,eAAe;AAAA,QACb,OAAO,CAAC;AAAA,QACR,UAAU;AAAA,MACZ;AAAA,MACA,eAAe;AAAA,MACf,iBAAiB;AAAA,MACjB,qBAAqB;AAAA,IACvB;AAAA,EACF;AAEA,MAAI;AACJ,MAAI,cAAc,KAAK,IAAI,GAAG;AAC5B,UAAM,UAAU,kBAAkB,KAAK,IAAI;AAC3C,cAAU;AAAA,MACR;AAAA,MACA,eAAe,oBAAoB;AAAA,MACnC,GAAI,YAAY,KAAK,IAAI,KAAK;AAAA,QAC5B,QAAQ;AAAA,UACN,SAAS;AAAA,UACT,MAAM;AAAA,UACN,UAAU;AAAA,UACV,OAAO;AAAA,QACT;AAAA,MACF;AAAA,MACA,GAAI,YAAY,KAAK,IAAI,KACvB,WAAW;AAAA,QACT,WAAW;AAAA,UACT,SAAS,CAAC;AAAA,UACV,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACJ;AAAA,EACF;AAEA,MAAI;AACJ,MAAI,kBAAkB,KAAK,IAAI,KAAK,YAAY;AAC9C,kBAAc;AAAA,MACZ,WAAW,gBAAgB;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,iBAAiB,CAAC;AAAA,IAClB,SAAS,CAAC;AAAA,IACV,OAAO,CAAC;AAAA,IACR,MAAM;AAAA,IACN,YAAY;AAAA,MACV,MAAM;AAAA,MACN,MAAM,UAAU;AAAA,IAClB;AAAA,IACA,OAAO;AAAA,MACL,OAAO;AAAA,QACL,OAAO;AAAA,QACP,aAAa;AAAA,QACb,iBAAiB;AAAA,QACjB,UAAU;AAAA,QACV,gBAAgB;AAAA,MAClB;AAAA,MACA,OAAO,CAAC;AAAA,IACV;AAAA,IACA;AAAA,IACA,GAAI,SAAS,UAAa,EAAE,KAAK;AAAA,IACjC,GAAI,gBAAgB,UAAa,EAAE,YAAY;AAAA,IAC/C,GAAI,YAAY,UAAa,EAAE,QAAQ;AAAA,IACvC,GAAI,gBAAgB,UAAa,EAAE,YAAY;AAAA,EACjD;AACF;;;ACzGA,IAAM,WAAW,CACf,MACA,kBACyB;AACzB,SAAO,cAAc,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AAClD;AAEO,IAAM,aAAa,CACxB,MACA,kBACqB;AACrB,QAAM,YAAY,SAAS,MAAM,aAAa;AAC9C,MAAI,WAAW;AACb,WAAO,GAAG,SAAS;AAAA,EACrB;AAEA,SAAO,IAAI,UAAU,cAAc;AACrC;;;ACMO,IAAM,oBACX,CAAC,SASD,CAAC,MAAM,SAAS;AACd,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,YAAAC;AAAA,IACA,eAAAC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AACJ,QAAM,KAAKD,YAAW;AACtB,QAAM,WAAW,QAAQA,YAAW;AACpC,QAAM,gBAAgB,eAAe,cAAc;AACnD,QAAM,UAAU,WAAW,MAAM,aAAa;AAE9C,MAAI,MAAM,OAAO,GAAG;AAClB,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,mBAAmB,WAAW,QAAQ,KAAK;AAE5D,MAAI,CAAC,YAAY,SAAS,WAAW,GAAG;AACtC,WAAO,IAAI,UAAU,gBAAgB;AAAA,EACvC;AAEA,QAAM,gBACJ,QAAQ,MAAM,SAAS,iBACvB,6BAA6B,QAAQ,MAAM,IAAI;AACjD,MAAI;AAEJ,MAAI,iBAAiB,qBAAqB;AACxC,gBAAY,oBAAoB,OAAO;AAAA,EACzC;AAEA,MAAI;AACJ,MAAI,YAAY,QAAQ,MAAM,IAAI,KAAK,mBAAmB;AACxD,cAAU,kBAAkB,OAAO;AAAA,EACrC;AAEA,MAAI;AACJ,MAAI,kBAAkB,QAAQ,MAAM,IAAI,KAAK,sBAAsB;AACjE,UAAM,YAAY,qBAAqB,OAAO;AAE9C,UAAM,eAAe,WACjB,oBAAoB,UAAU,QAAQ,IACtCC;AACJ,UAAM,iBAAiB,aAAa,SAAS;AAC7C,iBAAa,eAAe,MAAM,GAAG,CAAC;AAAA,EACxC;AAEA,QAAM,UAAU;AAAA,IACd;AAAA,IACA,MAAM,QAAQ;AAAA,IACd;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,UAAU,OAAO,OAAO;AAE9B,SAAO,GAAG,OAAO;AACnB;;;ACnEK,IAAM,4BAAuD,CAClE,SACA,QACA,iBAAiB,qBACd;AACH,QAAM,kBAAoC,CAAC;AAC3C,QAAM,YAAwB,CAAC,GAAG,IAAI,KAAK,GAAG;AAG9C,WAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AACjC,aAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AACjC,YAAM,WAAqB,EAAE,GAAG,EAAE;AAGlC,iBAAW,YAAY,WAAW;AAChC,cAAM,SAAS;AAAA,UACb;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AACA,YAAI,KAAK,MAAM,GAAG;AAChB,0BAAgB,KAAK,EAAE,UAAU,SAAS,CAAC;AAAA,QAC7C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAUO,IAAM,wBAAwB,CACnC,SACA,QACA,iBAAyB,qBACb;AACZ,QAAM,YAAwB,CAAC,GAAG,IAAI,KAAK,GAAG;AAG9C,WAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AACjC,aAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AACjC,YAAM,WAAqB,EAAE,GAAG,EAAE;AAGlC,iBAAW,YAAY,WAAW;AAChC,cAAM,SAAS;AAAA,UACb;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AACA,YAAI,KAAK,MAAM,GAAG;AAChB,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;AChFO,IAAM,uBAA6C,CAAC,MAAM,WAAW;AAC1E,QAAM,aAAa,KAAK;AAExB,QAAM,cAAc,KAAK,MAAM;AAAA,IAC7B,CAAC,SAAS,KAAK,OAAO,WAAW;AAAA,EACnC;AAEA,MAAI,CAAC,aAAa;AAChB,WAAO,IAAI,UAAU,cAAc;AAAA,EACrC;AAEA,MAAI,YAAY,OAAO,QAAQ;AAC7B,WAAO,IAAI,UAAU,aAAa;AAAA,EACpC;AAEA,MAAI,CAAC,QAAQ,WAAW,GAAG;AACzB,WAAO,IAAI,UAAU,YAAY;AAAA,EACnC;AAEA,MAAI,YAAY,cAAc;AAC5B,UAAM,gBAAgB,KAAK,QAAQ;AAAA,MACjC,CAAC,WAAW,OAAO,OAAO,YAAY;AAAA,IACxC;AAEA,QACE,iBACA;AAAA,MACE,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,KAAK,MAAM,MAAM;AAAA,IACnB,GACA;AACA,aAAO,IAAI,UAAU,YAAY;AAAA,IACnC;AAAA,EACF;AAEA,QAAM,WAAW,KAAK,MAAM,MAAM;AAClC,QAAM,cAAc,KAAK;AACzB,QAAM,aAAa,gBAAgB;AAEnC,QAAM,cAAc,KAAK,MAAM,IAAI,CAAC,SAAS;AAC3C,QAAI,KAAK,OAAO,YAAY,IAAI;AAC9B,UAAI,YAAY;AACd,eAAO;AAAA,UACL,GAAG;AAAA,UACH,WAAW;AAAA,UACX,UAAU;AAAA,QACZ;AAAA,MACF;AAEA,aAAO;AAAA,QACL,GAAG;AAAA,QACH,UAAU;AAAA,MACZ;AAAA,IACF;AACA,WAAO;AAAA,EACT,CAAC;AAED,MAAI;AAEJ,QAAM,aAAuB;AAAA,IAC3B,MAAM;AAAA,IACN,MAAM,UAAU;AAAA,EAClB;AAEA,MAAI,cAAc,mBAAmB,WAAW,GAAG;AACjD,kBAAc;AAAA,MACZ,GAAG;AAAA,MACH,OAAO;AAAA,MACP,YAAY;AAAA,IACd;AAAA,EACF,OAAO;AACL,kBAAc;AAAA,MACZ,GAAG;AAAA,MACH,OAAO;AAAA,MACP,YAAwB,mBAAmB,WAAW;AAAA,IACxD;AAAA,EACF;AAEA,SAAO,GAAG,WAAW;AACvB;;;ACxFO,IAAM,0BAAmD,CAAC,UAAU;AAEzE,QAAM,YAAY,oBAAI,IAAgD;AAEtE,aAAW,QAAQ,OAAO;AACxB,eAAW,UAAU,KAAK,QAAQ;AAChC,YAAM,WAAW,UAAU,IAAI,OAAO,QAAQ;AAC9C,UAAI,UAAU;AACZ,iBAAS,OAAO,KAAK,OAAO,QAAQ,MAAM;AAAA,MAC5C,OAAO;AACL,kBAAU,IAAI,OAAO,UAAU;AAAA,UAC7B,MAAM,OAAO;AAAA,UACb,QAAQ,CAAC,OAAO,QAAQ,MAAM;AAAA,QAChC,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAGA,QAAM,UAA6C,CAAC;AACpD,aAAW,CAAC,UAAU,IAAI,KAAK,WAAW;AACxC,YAAQ,KAAK;AAAA,MACX;AAAA,MACA,YAAY,KAAK;AAAA,MACjB,aAAa,KAAK,OAAO,OAAO,CAAC,KAAK,MAAM,MAAM,GAAG,CAAC;AAAA,MACtD,aAAa,KAAK;AAAA,IACpB,CAAC;AAAA,EACH;AAEA,UAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,EAAE,WAAW;AAGpD,QAAM,eAAgC,CAAC;AACvC,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,UAAU,QAAQ,CAAC;AACzB,UAAM,WAAW,IAAI,IAAI,aAAa,IAAI,CAAC,IAAK;AAChD,UAAM,WACJ,YAAY,QAAQ,gBAAgB,SAAS,cACzC,SAAS,WACT,IAAI;AACV,iBAAa,KAAK,EAAE,GAAG,SAAS,SAAS,CAAC;AAAA,EAC5C;AAEA,SAAO;AACT;;;AC9CO,IAAM,uBACX,CAAC,SACD,CAAC,MAAwB,YAAyC;AAChE,QAAM,EAAE,eAAe,IAAI;AAE3B,QAAM,gBAAgB,eAAe,YAAY;AAEjD,MAAI,CAAC,eAAe;AAClB,WAAO,IAAI,UAAU,qBAAqB;AAAA,EAC5C;AAEA,SAAO,wBAAwB,eAAe,MAAM,OAAO;AAC7D;;;AClBK,IAAM,kBACX,CAAC,SACD,MAA0B;AACxB,QAAM,EAAE,eAAe,IAAI;AAC3B,SAAO,GAAG,eAAe,cAAc,CAAC;AAC1C;;;ACAF,IAAM,qBAAqB;AAQpB,IAAM,kBAAkB,CAC7B,OACA,YACc;AACd,QAAM,WAAW,QAAQ,KAAK;AAC9B,SAAO;AAAA,IACL,SAAS,SAAS,MAAM,GAAG,kBAAkB;AAAA,IAC7C,UAAU,SAAS,MAAM,kBAAkB;AAAA,EAC7C;AACF;AAKO,IAAM,yBAAyB,CACpC,OACA,cACkE;AAClE,QAAM,QAAQ,MAAM,QAAQ,UAAU,CAAC,MAAM,EAAE,OAAO,SAAS;AAC/D,MAAI,UAAU,GAAI,QAAO;AAEzB,QAAM,UAAU,MAAM,QAAQ,KAAK;AACnC,QAAM,aAAa,CAAC,GAAG,MAAM,OAAO;AACpC,aAAW,OAAO,OAAO,CAAC;AAG1B,QAAM,cAAc,CAAC,GAAG,MAAM,QAAQ;AACtC,MAAI,YAAY,SAAS,GAAG;AAC1B,eAAW,KAAK,YAAY,MAAM,CAAE;AAAA,EACtC;AAEA,SAAO;AAAA,IACL;AAAA,IACA,cAAc,EAAE,SAAS,YAAY,UAAU,YAAY;AAAA,EAC7D;AACF;AAKO,IAAM,0BAA0B,CACrC,OACA,cACkE;AAClE,QAAM,QAAQ,MAAM,SAAS,UAAU,CAAC,MAAM,EAAE,OAAO,SAAS;AAChE,MAAI,UAAU,GAAI,QAAO;AAEzB,QAAM,UAAU,MAAM,SAAS,KAAK;AACpC,QAAM,cAAc,CAAC,GAAG,MAAM,QAAQ;AACtC,cAAY,OAAO,OAAO,CAAC;AAE3B,SAAO;AAAA,IACL;AAAA,IACA,cAAc,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,GAAG,UAAU,YAAY;AAAA,EACrE;AACF;AAQO,IAAM,yBAAyB,CACpC,SACA,UACA,YACA,WACA,YACY;AACZ,QAAM,OAAO,QAAQ,SAAS,CAAC,IAAI,SAAS,CAAC;AAC7C,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI,KAAK,SAAS,WAAW,KAAK,SAAS,SAAU,QAAO;AAG5D,MAAI,KAAK,SAAS,EAAG,QAAO;AAG5B,MACE,WAAW;AAAA,IACT,CAAC,OAAO,GAAG,SAAS,MAAM,SAAS,KAAK,GAAG,SAAS,MAAM,SAAS;AAAA,EACrE;AAEA,WAAO;AAGT,MACE,UAAU;AAAA,IACR,CAAC,MAAM,EAAE,SAAS,MAAM,SAAS,KAAK,EAAE,SAAS,MAAM,SAAS;AAAA,EAClE;AAEA,WAAO;AAGT,MACE,QAAQ;AAAA,IACN,CAAC,MAAM,EAAE,SAAS,MAAM,SAAS,KAAK,EAAE,SAAS,MAAM,SAAS;AAAA,EAClE;AAEA,WAAO;AAET,SAAO;AACT;AAOA,IAAM,mBAAmB;AAAA,EACvB,CAAC,IAAI,EAAE;AAAA,EACP,CAAC,IAAI,CAAC;AAAA,EACN,CAAC,IAAI,CAAC;AAAA,EACN,CAAC,GAAG,EAAE;AAAA,EACN,CAAC,GAAG,CAAC;AAAA,EACL,CAAC,GAAG,EAAE;AAAA,EACN,CAAC,GAAG,CAAC;AAAA,EACL,CAAC,GAAG,CAAC;AACP;AAKO,IAAM,+BAA+B,CAC1C,SACA,SACA,WACA,eACW;AACX,MAAI,QAAQ,QAAQ,SAAS,iBAAkB,QAAO;AAEtD,QAAM,EAAE,YAAY,eAAe,IAAI,QAAQ;AAC/C,QAAM,EAAE,GAAG,EAAE,IAAI,QAAQ;AACzB,MAAI,UAAU;AAEd,aAAW,CAAC,IAAI,EAAE,KAAK,kBAAkB;AACvC,UAAM,KAAK,IAAK;AAChB,UAAM,KAAK,IAAK;AAEhB,YAAQ,YAAY;AAAA,MAClB,KAAK;AACH,YACE,UAAU;AAAA,UACR,CAAC,MACC,EAAE,SAAS,MAAM,MACjB,EAAE,SAAS,MAAM,MACjB,EAAE,SAAS;AAAA,QACf;AAEA;AACF;AAAA,MACF,KAAK;AACH,YACE,UAAU;AAAA,UACR,CAAC,MACC,EAAE,SAAS,MAAM,MAAM,EAAE,SAAS,MAAM,MAAM,EAAE,SAAS;AAAA,QAC7D;AAEA;AACF;AAAA,MACF,KAAK;AACH,YACE,UAAU;AAAA,UACR,CAAC,MACC,EAAE,SAAS,MAAM,MACjB,EAAE,SAAS,MAAM,MACjB,EAAE,SAAS;AAAA,QACf;AAEA;AACF;AAAA,MACF,KAAK;AACH,YACE,UAAU;AAAA,UACR,CAAC,MACC,EAAE,SAAS,MAAM,MAAM,EAAE,SAAS,MAAM,MAAM,EAAE,SAAS;AAAA,QAC7D;AAEA;AACF;AAAA,MACF,KAAK,WAAW;AAEd,cAAM,gBAAgB,oBAAI,IAAkB;AAC5C,mBAAW,KAAK,WAAW;AACzB,cAAI,EAAE,SAAS,MAAM,MAAM,EAAE,SAAS,MAAM,IAAI;AAC9C,0BAAc,IAAI,EAAE,IAAI;AAAA,UAC1B;AAAA,QACF;AACA,mBAAW,cAAc;AACzB;AAAA,MACF;AAAA,MACA,KAAK;AAEH,YAAI,UAAU,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM,MAAM,EAAE,SAAS,MAAM,EAAE;AAClE;AACF;AAAA,MACF,KAAK,YAAY;AAEf,cAAM,OAAO,QAAQ,EAAE,IAAI,EAAE;AAC7B,YAAI,QAAQ,KAAK,SAAS,SAAS;AACjC,qBAAW,KAAK;AAAA,QAClB;AACA,YACE,WAAW,KAAK,CAAC,OAAO,GAAG,SAAS,MAAM,MAAM,GAAG,SAAS,MAAM,EAAE,GACpE;AACA,gBAAM,QAAQ,WAAW;AAAA,YACvB,CAAC,OAAO,GAAG,SAAS,MAAM,MAAM,GAAG,SAAS,MAAM;AAAA,UACpD;AACA,cAAI,MAAO,YAAW,MAAM;AAAA,QAC9B;AACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,UAAU;AACnB;AAOO,IAAM,6BAA6B,CACxC,YACW;AACX,QAAM,WAAW,QAAQ,OAAO,CAAC,MAAM,EAAE,QAAQ,SAAS,SAAS;AACnE,MAAI,SAAS,WAAW,EAAG,QAAO;AAElC,QAAM,UAAU,oBAAI,IAAY;AAChC,MAAI,aAAa;AAEjB,QAAM,aAAa;AAAA,IACjB,CAAC,IAAI,CAAC;AAAA,IACN,CAAC,GAAG,CAAC;AAAA,IACL,CAAC,GAAG,EAAE;AAAA,IACN,CAAC,GAAG,CAAC;AAAA,EACP;AAEA,aAAW,WAAW,UAAU;AAC9B,UAAM,MAAM,GAAG,QAAQ,SAAS,CAAC,IAAI,QAAQ,SAAS,CAAC;AACvD,QAAI,QAAQ,IAAI,GAAG,EAAG;AAGtB,QAAI,YAAY;AAChB,QAAI,aAAa;AACjB,UAAM,QAAyB,CAAC,OAAO;AACvC,YAAQ,IAAI,GAAG;AAEf,WAAO,MAAM,SAAS,GAAG;AACvB,YAAM,UAAU,MAAM,IAAI;AAC1B;AACA,UAAI,QAAQ,QAAQ,SAAS,WAAW;AACtC,sBAAc,QAAQ,QAAQ;AAAA,MAChC;AAEA,iBAAW,CAAC,IAAI,EAAE,KAAK,YAAY;AACjC,cAAM,KAAK,QAAQ,SAAS,IAAK;AACjC,cAAM,KAAK,QAAQ,SAAS,IAAK;AACjC,cAAM,OAAO,GAAG,EAAE,IAAI,EAAE;AAExB,YAAI,CAAC,QAAQ,IAAI,IAAI,GAAG;AACtB,gBAAM,WAAW,SAAS;AAAA,YACxB,CAAC,MAAM,EAAE,SAAS,MAAM,MAAM,EAAE,SAAS,MAAM;AAAA,UACjD;AACA,cAAI,UAAU;AACZ,oBAAQ,IAAI,IAAI;AAChB,kBAAM,KAAK,QAAQ;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,kBAAc,YAAY;AAAA,EAC5B;AAEA,SAAO;AACT;AAKO,IAAM,6BAA6B,CACxC,SACA,SACA,WACA,eACW;AACX,MAAI,aAAa;AAGjB,aAAW,WAAW,SAAS;AAC7B,QAAI,QAAQ,QAAQ,SAAS,kBAAkB;AAC7C,oBAAc;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,gBAAc,2BAA2B,OAAO;AAEhD,SAAO;AACT;;;ACxTO,IAAM,4BAA4B,CACvC,SACA,qBACW;AACX,MAAI,iBAAiB,WAAW,EAAG,QAAO;AAE1C,QAAM,OAAO,QAAQ;AACrB,QAAM,OAAO,QAAQ,CAAC,EAAG;AACzB,QAAM,UAAuB,QAAQ,IAAI,CAAC,QAAQ,IAAI,IAAI,MAAM,KAAK,CAAC;AAEtE,QAAM,aAAa;AAAA,IACjB,CAAC,IAAI,CAAC;AAAA,IACN,CAAC,GAAG,CAAC;AAAA,IACL,CAAC,GAAG,EAAE;AAAA,IACN,CAAC,GAAG,CAAC;AAAA,EACP;AAGA,QAAM,WAAW,oBAAI,IAAoB;AACzC,aAAW,SAAS,kBAAkB;AACpC,UAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,MAAM,SAAS,CAAC;AACnD,aAAS,IAAI,MAAM,SAAS,IAAI,GAAG,KAAK,KAAK,MAAM,KAAK;AAAA,EAC1D;AAEA,MAAI,aAAa;AAEjB,WAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,YAAM,OAAO,QAAQ,CAAC,EAAG,CAAC;AAC1B,UACE,QAAQ,CAAC,EAAG,CAAC,KACb,KAAK,SAAS,WACd,KAAK,SAAS,YACd,KAAK,SAAS,WACd;AACA;AAAA,MACF;AAGA,YAAM,OAAO,KAAK;AAClB,UAAI,OAAO;AACX,UAAI,iBAAiB;AACrB,YAAM,QAA4B,CAAC,CAAC,GAAG,CAAC,CAAC;AACzC,cAAQ,CAAC,EAAG,CAAC,IAAI;AAEjB,aAAO,MAAM,SAAS,GAAG;AACvB,cAAM,CAAC,IAAI,EAAE,IAAI,MAAM,IAAI;AAC3B;AAGA,cAAM,MAAM,GAAG,EAAE,IAAI,EAAE;AACvB,YAAI,SAAS,IAAI,GAAG,GAAG;AACrB,4BAAkB,SAAS,IAAI,GAAG;AAAA,QACpC;AAEA,mBAAW,CAAC,IAAI,EAAE,KAAK,YAAY;AACjC,gBAAM,KAAK,KAAM;AACjB,gBAAM,KAAK,KAAM;AACjB,cACE,MAAM,KACN,MAAM,KACN,KAAK,QACL,KAAK,QACL,CAAC,QAAQ,EAAE,EAAG,EAAE,KAChB,QAAQ,EAAE,EAAG,EAAE,EAAG,SAAS,MAC3B;AACA,oBAAQ,EAAE,EAAG,EAAE,IAAI;AACnB,kBAAM,KAAK,CAAC,IAAI,EAAE,CAAC;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAGA,oBAAc,OAAO;AAAA,IACvB;AAAA,EACF;AAEA,SAAO;AACT;;;AClFA,IAAM,qBAAqB,CACzB,YACyC;AACzC,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,MAAM,QAAQ,CAAC;AACrB,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,UAAI,IAAI,CAAC,EAAG,SAAS,UAAU;AAC7B,eAAO,EAAE,GAAG,EAAE;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAKA,IAAMC,kBAAiB,CACrB,YAC2E;AAC3E,MAAI,OAAO,OAAO;AAClB,MAAI,OAAO,OAAO;AAClB,MAAI,OAAO;AACX,MAAI,OAAO;AAEX,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,MAAM,QAAQ,CAAC;AACrB,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,UAAI,IAAI,CAAC,EAAG,SAAS,SAAS;AAC5B,eAAO,KAAK,IAAI,MAAM,CAAC;AACvB,eAAO,KAAK,IAAI,MAAM,CAAC;AACvB,eAAO,KAAK,IAAI,MAAM,CAAC;AACvB,eAAO,KAAK,IAAI,MAAM,CAAC;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,SAAS,GAAI,QAAO;AACxB,SAAO,EAAE,MAAM,MAAM,MAAM,KAAK;AAClC;AAKO,IAAM,2BAA2B,CACtC,SACA,SACA,mBACW;AACX,QAAM,SAAS,mBAAmB,OAAO;AACzC,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,aAAa;AAAA,IACjB,CAAC,IAAI,EAAE;AAAA,IACP,CAAC,IAAI,CAAC;AAAA,IACN,CAAC,IAAI,CAAC;AAAA,IACN,CAAC,GAAG,EAAE;AAAA,IACN,CAAC,GAAG,CAAC;AAAA,IACL,CAAC,GAAG,EAAE;AAAA,IACN,CAAC,GAAG,CAAC;AAAA,IACL,CAAC,GAAG,CAAC;AAAA,EACP;AAEA,MAAI,QAAQ;AACZ,aAAW,CAAC,IAAI,EAAE,KAAK,YAAY;AACjC,UAAM,KAAK,OAAO,IAAK;AACvB,UAAM,KAAK,OAAO,IAAK;AACvB,UAAM,OAAO,QAAQ,EAAE,IAAI,EAAE;AAC7B,QAAI,QAAQ,KAAK,SAAS,SAAS;AACjC;AAAA,IACF;AAAA,EACF;AAEA,SAAO,QAAQ;AACjB;AAKO,IAAM,+BAA+B,CAC1C,SACA,SACA,mBACW;AACX,QAAM,MAAMA,gBAAe,OAAO;AAClC,MAAI,CAAC,IAAK,QAAO;AAEjB,QAAM,UAAU;AAAA,IACd,EAAE,GAAG,IAAI,MAAM,GAAG,IAAI,KAAK;AAAA,IAC3B,EAAE,GAAG,IAAI,MAAM,GAAG,IAAI,KAAK;AAAA,IAC3B,EAAE,GAAG,IAAI,MAAM,GAAG,IAAI,KAAK;AAAA,IAC3B,EAAE,GAAG,IAAI,MAAM,GAAG,IAAI,KAAK;AAAA,EAC7B;AAEA,MAAI,QAAQ;AACZ,aAAW,UAAU,SAAS;AAC5B,UAAM,OAAO,QAAQ,OAAO,CAAC,IAAI,OAAO,CAAC;AACzC,QAAI,QAAQ,KAAK,SAAS,SAAS;AACjC;AAAA,IACF;AAAA,EACF;AAEA,SAAO,QAAQ;AACjB;AAKO,IAAM,2BAA2B,CACtC,SACA,WACW;AACX,QAAM,SAAS,mBAAmB,OAAO;AACzC,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,MAAMA,gBAAe,OAAO;AAClC,MAAI,CAAC,IAAK,QAAO;AAEjB,QAAM,WACH,OAAO,MAAM,IAAI,QAAQ,OAAO,MAAM,IAAI,QAC1C,OAAO,MAAM,IAAI,QAAQ,OAAO,MAAM,IAAI,QAC1C,OAAO,MAAM,IAAI,QAAQ,OAAO,MAAM,IAAI,QAC1C,OAAO,MAAM,IAAI,QAAQ,OAAO,MAAM,IAAI;AAE7C,SAAO,WAAW,SAAS;AAC7B;AAMO,IAAM,4BAA4B,CACvC,SACA,QACA,WACW;AACX,QAAM,OAAO,QAAQ;AACrB,QAAM,OAAO,QAAQ,CAAC,EAAG;AAGzB,QAAM,WAAwB,MAAM;AAAA,IAAK,EAAE,QAAQ,KAAK;AAAA,IAAG,MACzD,MAAM,KAAK,EAAE,QAAQ,KAAK,GAAG,MAAM,KAAK;AAAA,EAC1C;AAEA,WAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,YAAM,OAAO,QAAQ,CAAC,EAAG,CAAC;AAC1B,UAAI,KAAK,SAAS,WAAW,KAAK,SAAS,YAAY,KAAK,SAAS,GAAG;AACtE,cAAM,iBAAiB,OAAO;AAAA,UAC5B,CAAC,MAAM,EAAE,SAAS,MAAM,KAAK,EAAE,SAAS,MAAM;AAAA,QAChD;AACA,YAAI,CAAC,gBAAgB;AACnB,mBAAS,CAAC,EAAG,CAAC,IAAI;AAAA,QACpB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,aAAa;AAGjB,QAAM,aAAa;AAAA,IACjB,EAAE,IAAI,GAAG,IAAI,EAAE;AAAA;AAAA,IACf,EAAE,IAAI,GAAG,IAAI,EAAE;AAAA;AAAA,IACf,EAAE,IAAI,GAAG,IAAI,EAAE;AAAA;AAAA,IACf,EAAE,IAAI,GAAG,IAAI,GAAG;AAAA;AAAA,EAClB;AAEA,aAAW,EAAE,IAAI,GAAG,KAAK,YAAY;AAEnC,UAAM,UAAuB,MAAM;AAAA,MAAK,EAAE,QAAQ,KAAK;AAAA,MAAG,MACxD,MAAM,KAAK,EAAE,QAAQ,KAAK,GAAG,MAAM,KAAK;AAAA,IAC1C;AAEA,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,eAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,YAAI,QAAQ,CAAC,EAAG,CAAC,KAAK,CAAC,SAAS,CAAC,EAAG,CAAC,EAAG;AAGxC,YAAI,SAAS;AACb,YAAI,KAAK;AACT,YAAI,KAAK;AACT,eACE,MAAM,KACN,KAAK,QACL,MAAM,KACN,KAAK,QACL,SAAS,EAAE,EAAG,EAAE,GAChB;AACA,kBAAQ,EAAE,EAAG,EAAE,IAAI;AACnB;AACA,gBAAM;AACN,gBAAM;AAAA,QACR;AAEA,YAAI,UAAU,GAAG;AACf;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,aAAa;AACtB;AAKO,IAAM,4BAA4B,CACvC,SACA,WACW;AACX,QAAM,mBAA6B,CAAC,SAAS,UAAU,OAAO,OAAO;AACrE,QAAM,OAAO,QAAQ;AACrB,QAAM,OAAO,QAAQ,CAAC,EAAG;AACzB,QAAM,UAAuB,MAAM;AAAA,IAAK,EAAE,QAAQ,KAAK;AAAA,IAAG,MACxD,MAAM,KAAK,EAAE,QAAQ,KAAK,GAAG,MAAM,KAAK;AAAA,EAC1C;AAEA,QAAM,aAAa;AAAA,IACjB,CAAC,IAAI,CAAC;AAAA,IACN,CAAC,GAAG,CAAC;AAAA,IACL,CAAC,GAAG,EAAE;AAAA,IACN,CAAC,GAAG,CAAC;AAAA,EACP;AAEA,MAAI,uBAAuB;AAE3B,WAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,YAAM,OAAO,QAAQ,CAAC,EAAG,CAAC;AAC1B,UAAI,QAAQ,CAAC,EAAG,CAAC,KAAK,CAAC,iBAAiB,SAAS,KAAK,IAAc;AAClE;AACF,UAAI,KAAK,SAAS,WAAW,KAAK,SAAS,SAAU;AAGrD,YAAM,OAAO,KAAK;AAClB,UAAI,OAAO;AACX,UAAI,cAAc;AAClB,YAAM,QAA4B,CAAC,CAAC,GAAG,CAAC,CAAC;AACzC,cAAQ,CAAC,EAAG,CAAC,IAAI;AAEjB,aAAO,MAAM,SAAS,GAAG;AACvB,cAAM,CAAC,IAAI,EAAE,IAAI,MAAM,IAAI;AAC3B,cAAM,UAAU,QAAQ,EAAE,EAAG,EAAE;AAC/B;AACA,YAAI,QAAQ,SAAS,EAAG,eAAc;AAEtC,mBAAW,CAAC,IAAI,EAAE,KAAK,YAAY;AACjC,gBAAM,KAAK,KAAM;AACjB,gBAAM,KAAK,KAAM;AACjB,cACE,MAAM,KACN,MAAM,KACN,KAAK,QACL,KAAK,QACL,CAAC,QAAQ,EAAE,EAAG,EAAE,KAChB,QAAQ,EAAE,EAAG,EAAE,EAAG,SAAS,MAC3B;AACA,oBAAQ,EAAE,EAAG,EAAE,IAAI;AACnB,kBAAM,KAAK,CAAC,IAAI,EAAE,CAAC;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAEA,UAAI,QAAQ,KAAK,CAAC,aAAa;AAC7B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,uBAAuB;AAChC;AAKO,IAAM,sBAAsB,CACjC,OACA,SACA,QACA,aACA,gBACW;AACX,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK,WAAW;AACd,aAAO,yBAAyB,SAAS,MAAM,SAAU,MAAM,MAAM;AAAA,IAEvE,KAAK,WAAW;AACd,aAAO;AAAA,QACL;AAAA,QACA,MAAM;AAAA,QACN,MAAM;AAAA,MACR;AAAA,IAEF,KAAK,WAAW,SAAS;AACvB,YAAM,gBAAgB,cAAc,OAAO;AAC3C,YAAM,oBAAoB,cAAc;AACxC,aAAO,kBAAkB,oBAAoB,MAAM,SAAS;AAAA,IAC9D;AAAA,IAEA,KAAK,WAAW;AACd,aAAO,sBAAsB,OAAO,IAAI,MAAM,SAAS;AAAA,IAEzD,KAAK,WAAW;AACd,aAAO,yBAAyB,SAAS,MAAM,MAAM;AAAA,IAEvD,KAAK,WAAW;AACd,aAAO,0BAA0B,SAAS,QAAQ,MAAM,MAAM;AAAA,IAEhE,KAAK,WAAW;AACd,aAAO,0BAA0B,SAAS,MAAM,MAAM;AAAA,IAExD;AACE,aAAO;AAAA,EACX;AACF;;;AC7TO,IAAM,oBAAoB,CAAC,YAAyC;AACzE,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAcO,IAAM,wBAAwB,CACnC,MACA,aACoB;AACpB,QAAM,eAAe,kBAAkB,KAAK,IAAI;AAChD,MAAI,iBAAiB,QAAQ,KAAK,SAAS,EAAG,QAAO;AACrD,SAAO,EAAE,MAAM,cAAc,SAAS;AACxC;AAuCO,IAAM,oBAAoB,CAC/B,WACA,WACA,2BACY;AACZ,QAAM,UAAU,UAAU;AAAA,IAAI,CAAC,QAC7B,UAAU,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM,IAAI,KAAK,EAAE,SAAS,MAAM,IAAI,CAAC;AAAA,EACxE;AAGA,MAAI,QAAQ,KAAK,CAAC,MAAM,MAAM,MAAS,EAAG,QAAO;AAGjD,QAAM,QAAQ,IAAI,IAAI,QAAQ,IAAI,CAAC,MAAM,EAAG,IAAI,CAAC;AACjD,SAAO,MAAM,QAAQ;AACvB;AAKO,IAAM,iBAAiB,CAC5B,WACA,cACe;AACf,QAAM,SAAS,IAAI,IAAI,UAAU,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;AAC5D,SAAO,UAAU;AAAA,IACf,CAAC,MAAM,CAAC,OAAO,IAAI,GAAG,EAAE,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE;AAAA,EACtD;AACF;;;ACrGO,IAAM,gBAA8C;AAAA,EACzD,SAAS;AAAA,EACT,MAAM;AAAA,EACN,UAAU;AAAA,EACV,OAAO;AACT;AAEA,IAAM,iBAAiC,CAAC,WAAW,QAAQ,YAAY,OAAO;AA2DvE,IAAM,sBAAsB,CACjC,QACA,eACW;AACX,MAAI,QAAQ;AAGZ,QAAM,YAAY,OAAO,aAAa,CAAC;AACvC,WAAS,UAAU;AAGnB,aAAW,gBAAgB,gBAAgB;AACzC,QAAI,WAAW,YAAY,MAAM,OAAO,IAAI;AAC1C,eAAS,cAAc,YAAY;AAAA,IACrC;AAAA,EACF;AAEA,SAAO;AACT;;;ACjEO,IAAM,mBAAqC,CAAC,MAAM,gBAAgB;AACvE,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,EAAE,OAAO,MAAM,IAAI;AAEzB,QAAM,mBAAmB,YAAY,IAAI,CAAC,UAAuB;AAC/D,QAAI,aAAa,MAAM,QAAQ;AAE/B,UAAM,SAAS,KAAK,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,QAAQ;AAC/D,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,IACT;AAEA,UAAM,EAAE,QAAQ,IAAI;AAGpB,QACE,cAAc,KAAK,KAAK,IAAI,KAC5B,OAAO,cACP,OAAO,WAAW,SAAS,GAC3B;AACA,oBAAc,0BAA0B,SAAS,OAAO,UAAU;AAAA,IACpE;AAGA,QAAI,YAAY,KAAK,KAAK,IAAI,KAAK,KAAK,SAAS,QAAQ;AACvD,oBAAc,oBAAoB,QAAQ,KAAK,QAAQ,MAAM;AAAA,IAC/D;AAGA,QACE,YAAY,KAAK,KAAK,IAAI,KAC1B,OAAO,WACP,OAAO,QAAQ,SAAS,GACxB;AACA,oBAAc;AAAA,QACZ,OAAO;AAAA,QACP;AAAA,QACA,OAAO,aAAa,CAAC;AAAA,QACrB,OAAO,cAAc,CAAC;AAAA,MACxB;AAAA,IACF;AAGA,QAAI,kBAAkB,KAAK,KAAK,IAAI,KAAK,KAAK,aAAa,YAAY;AACrE,YAAM,SAAS,OAAO,UAAU,CAAC;AACjC,iBAAW,SAAS,KAAK,YAAY,YAAY;AAC/C,sBAAc;AAAA,UACZ;AAAA,UACA;AAAA,UACA;AAAA,UACA,MAAM;AAAA,UACN,KAAK,QAAQ;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAEA,QAAI,MAAM,SAAS,GAAG;AACpB,YAAM,QAAQ,CAAC,cAAc;AAE3B,YACE,UAAU,SAAS,wBACnB,UAAU,SAAS,kBACnB;AACA,gBAAM,mBAAmB,sBAAsB,OAAO;AACtD,cAAI,kBAAkB;AACpB,0BAAc;AAAA,UAChB;AAAA,QACF;AAGA,YAAI,UAAU,SAAS,aAAa,UAAU,SAAS,gBAAgB;AACrE,gBAAM,gBAAgB,cAAc,OAAO;AAC3C,gBAAM,cAAc,MAAM;AAC1B,gBAAM,eAAe,KAAK,QAAQ;AAClC,gBAAM,oBAAoB,cAAc;AACxC,cAAI,kBAAkB,mBAAmB;AACvC,0BAAc;AAAA,UAChB;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL,GAAG;AAAA,MACH,SAAS;AAAA,QACP,GAAG,MAAM;AAAA,QACT,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF,CAAC;AAGD,mBAAiB,KAAK,CAAC,GAAG,MAAM;AAC9B,QAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,QAAQ;AACzC,aAAO,EAAE,QAAQ,SAAS,EAAE,QAAQ;AAAA,IACtC;AACA,WAAO,EAAE,QAAQ,oBAAoB,EAAE,QAAQ;AAAA,EACjD,CAAC;AAED,QAAM,SAAwB,CAAC;AAE/B,MAAI,QAAQ;AACZ,SAAO,KAAK;AAAA,IACV,UAAU,iBAAiB,CAAC,EAAG;AAAA,IAC/B,YAAY,iBAAiB,CAAC,EAAG;AAAA,IACjC,SAAS,iBAAiB,CAAC,EAAG;AAAA,IAC9B,UAAU;AAAA,EACZ,CAAC;AAED,WAAS,IAAI,GAAG,IAAI,iBAAiB,QAAQ,KAAK;AAChD,UAAM,eAAe,iBAAiB,CAAC;AACvC,UAAM,gBAAgB,iBAAiB,IAAI,CAAC;AAC5C,QACE,iBACA,gBACA,aAAa,QAAQ,WAAW,cAAc,QAAQ,UACtD,aAAa,QAAQ,sBACnB,cAAc,QAAQ,mBACxB;AACA,cAAQ;AAAA,IACV;AAEA,QAAI,OAAO;AACT,aAAO,KAAK;AAAA,QACV,GAAG;AAAA,QACH,UAAU,OAAO,IAAI,CAAC,EAAG;AAAA,MAC3B,CAAC;AAAA,IACH,OAAO;AACL,aAAO,KAAK;AAAA,QACV,GAAG;AAAA,QACH,UAAU,IAAI;AAAA,MAChB,CAAC;AAAA,IACH;AAEA,YAAQ;AAAA,EACV;AAEA,SAAO,GAAG;AAAA,IACR,GAAG;AAAA,IACH;AAAA,EACF,CAAC;AACH;;;ACnHA,IAAM,sBAAsB,CAC1B,MACA,UACA,aAC+D;AAC/D,QAAM,OAAO,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK,WAAW,QAAQ;AACrE,MAAI,CAAC,MAAM,aAAc,QAAO;AAEhC,QAAM,CAAC,OAAO,MAAM,IAAI;AAAA,IACtB;AAAA,IACA;AAAA,IACA,KAAK;AAAA,EACP;AAEA,aAAW,UAAU,CAAC,OAAO,MAAM,GAAG;AACpC,QACE,OAAO,KAAK,SAAS,aACrB,OAAO,KAAK,kBACZ,OAAO,KAAK,iBAAiB,GAC7B;AACA,aAAO;AAAA,QACL,SAAS,OAAO,KAAK;AAAA,QACrB,iBAAiB,OAAO;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEO,IAAM,qBAAyC,CACpD,MACA,QACA,UACA,aACG;AACH,QAAM,aAAa,KAAK;AAExB,QAAM,cAAc,KAAK,MAAM;AAAA,IAC7B,CAAC,SAAS,KAAK,OAAO,WAAW;AAAA,EACnC;AAEA,MAAI,CAAC,aAAa;AAChB,WAAO,IAAI,UAAU,cAAc;AAAA,EACrC;AAEA,MAAI,YAAY,OAAO,QAAQ;AAC7B,WAAO,IAAI,UAAU,aAAa;AAAA,EACpC;AAEA,MAAI,CAAC,iCAAiC,WAAW,GAAG;AAClD,WAAO,IAAI,UAAU,YAAY;AAAA,EACnC;AAEA,QAAM,SAAS,YAAY;AAE3B,QAAM,gBAAgB,KAAK,QAAQ;AAAA,IACjC,CAAC,WAAW,OAAO,OAAO,YAAY;AAAA,EACxC;AAEA,MAAI,CAAC,eAAe;AAClB,WAAO,IAAI,UAAU,gBAAgB;AAAA,EACvC;AAEA,QAAM,iBAAiB;AAAA,IACrB,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA,KAAK,MAAM,MAAM;AAAA,EACnB;AAEA,MAAI,MAAM,cAAc,GAAG;AACzB,WAAO;AAAA,EACT;AAGA,QAAM,eAA2B,CAAC;AAClC,MAAI,eAAe,KAAK,KAAK,IAAI,GAAG;AAClC,UAAM,CAAC,OAAO,MAAM,IAAI,wBAAwB,UAAU,UAAU,MAAM;AAC1E,eAAW,UAAU,CAAC,OAAO,MAAM,GAAG;AACpC,YAAM,WAAW,sBAAsB,OAAO,MAAM,OAAO,QAAQ;AACnE,UAAI,UAAU;AACZ,qBAAa,KAAK,QAAQ;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAEA,QAAM,iBAAiB,KAAK,QAAQ,IAAI,CAAC,WAAW;AAClD,QAAI,OAAO,OAAO,cAAc,IAAI;AAClC,YAAM,UAAU,EAAE,GAAG,QAAQ,SAAS,eAAe,MAAM;AAC3D,UAAI,aAAa,SAAS,KAAK,QAAQ,WAAW;AAChD,gBAAQ,YAAY,CAAC,GAAG,QAAQ,WAAW,GAAG,YAAY;AAAA,MAC5D;AACA,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,CAAC;AAED,QAAM,WAAW,KAAK,MAAM,MAAM;AAClC,QAAM,cAAc,KAAK;AACzB,QAAM,aAAa,gBAAgB;AAEnC,QAAM,eAAe,KAAK,MAAM,IAAI,CAAC,SAAS;AAC5C,QAAI,KAAK,OAAO,YAAY,IAAI;AAC9B,UAAI,YAAY;AACd,eAAO;AAAA,UACL,GAAG;AAAA,UACH,WAAW;AAAA,UACX,UAAU;AAAA,QACZ;AAAA,MACF;AACA,aAAO;AAAA,QACL,GAAG;AAAA,QACH,UAAU;AAAA,MACZ;AAAA,IACF;AACA,WAAO;AAAA,EACT,CAAC;AAED,MAAI;AAEJ,QAAM,aAAuB;AAAA,IAC3B,MAAM;AAAA,IACN,MAAM,UAAU;AAAA,EAClB;AAEA,QAAM,gBAAgB,KAAK,KAAK,SAAS;AACzC,QAAM,YAAY,cAAc,KAAK,KAAK,IAAI;AAC9C,QAAM,QAAQ,kBAAkB,KAAK,KAAK,IAAI;AAC9C,QAAM,UAAU,6BAA6B,KAAK,KAAK,IAAI;AAE3D,MACE,cACA,mBAAmB,YAAY,KAC/B,CAAC,iBACD,CAAC,aACD,CAAC,OACD;AACA,kBAAc;AAAA,MACZ,GAAG;AAAA,MACH,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,SAAS;AAAA,IACX;AAAA,EACF,WAAW,iBAAiB,CAAC,YAAY;AAEvC,kBAAc;AAAA,MACZ,GAAG;AAAA,MACH,OAAO;AAAA,MACP,YAAY;AAAA,QACV,MAAM;AAAA,QACN,UAAU,YAAY;AAAA,QACtB,YAAY,cAAc;AAAA,MAC5B;AAAA,MACA,SAAS;AAAA,IACX;AAAA,EACF,WAAW,iBAAiB,YAAY;AAEtC,UAAM,oBAAgC;AAAA,MACpC,MAAM;AAAA,MACN,UAAU,YAAY;AAAA,MACtB,YAAY,cAAc;AAAA,IAC5B;AACA,kBAAc;AAAA,MACZ,GAAG;AAAA,MACH,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,SAAS;AAAA,IACX;AAAA,EACF,WAAW,WAAW;AAEpB,UAAM,UAAU,oBAAoB,MAAM,UAAU,QAAQ;AAC5D,QAAI,iBAAiB,KAAK;AAE1B,QAAI,WAAW,gBAAgB;AAC7B,YAAM,cAAc;AAAA,QAClB,eAAe;AAAA,QACf,QAAQ;AAAA,MACV;AACA,UAAI,KAAK,WAAW,GAAG;AAErB,cAAM,mBAAqC;AAAA,UACzC,OAAO,YAAY,MAAM;AAAA,UACzB,iBAAiB,QAAQ;AAAA,QAC3B;AACA,yBAAiB;AAAA,UACf,GAAG;AAAA,UACH,eAAe,YAAY,MAAM;AAAA,UACjC;AAAA,QACF;AAGA,sBAAc;AAAA,UACZ,GAAG;AAAA,UACH,OAAO;AAAA,UACP,SAAS;AAAA,UACT,SAAS;AAAA,UACT,YAAY;AAAA,YACV,MAAM;AAAA,YACN,UAAU,YAAY;AAAA,YACtB,YAAY,cAAc;AAAA,UAC5B;AAAA,QACF;AAAA,MACF,OAAO;AAEL,YAAI,cAAc,mBAAmB,YAAY,GAAG;AAClD,wBAAc;AAAA,YACZ,GAAG;AAAA,YACH,OAAO;AAAA,YACP,YAAY;AAAA,YACZ,SAAS;AAAA,YACT,SAAS;AAAA,UACX;AAAA,QACF,WAAW,YAAY;AACrB,wBAAc;AAAA,YACZ,GAAG;AAAA,YACH,OAAO;AAAA,YACP,YAAY;AAAA,YACZ,SAAS;AAAA,YACT,SAAS;AAAA,UACX;AAAA,QACF,OAAO;AACL,wBAAc;AAAA,YACZ,GAAG;AAAA,YACH,OAAO;AAAA,YACP,YAAY,mBAAmB,YAAY;AAAA,YAC3C,SAAS;AAAA,YACT,SAAS;AAAA,UACX;AAAA,QACF;AAAA,MACF;AAAA,IACF,OAAO;AAEL,UAAI,cAAc,mBAAmB,YAAY,GAAG;AAClD,sBAAc;AAAA,UACZ,GAAG;AAAA,UACH,OAAO;AAAA,UACP,YAAY;AAAA,UACZ,SAAS;AAAA,QACX;AAAA,MACF,WAAW,YAAY;AACrB,sBAAc;AAAA,UACZ,GAAG;AAAA,UACH,OAAO;AAAA,UACP,YAAY;AAAA,UACZ,SAAS;AAAA,QACX;AAAA,MACF,OAAO;AACL,sBAAc;AAAA,UACZ,GAAG;AAAA,UACH,OAAO;AAAA,UACP,YAAY,mBAAmB,YAAY;AAAA,UAC3C,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF,WAAW,OAAO;AAEhB,UAAMC,iBAAgB,eAAe;AAAA,MACnC,CAAC,MAAM,EAAE,OAAO,YAAY;AAAA,IAC9B;AACA,UAAM,UAAU,cAAc,MAAM;AACpC,UAAM,cAAc,kBAAkB,MAAM;AAE5C,QAAI,YAAkC;AAEtC,QAAI,SAAS;AAGX,YAAM,qBACJA,kBACA;AAAA,QACEA,eAAc;AAAA,QACdA,eAAc,UAAU,CAAC;AAAA,MAC3B,EAAE,SAAS;AACb,YAAM,iBAAiB,KAAK,aAAa,aAAa,KAAK;AAE3D,UAAI,sBAAsB,eAAe;AACvC,oBAAY,cAAc;AAAA,MAC5B;AAAA,IACF,WAAW,aAAa;AAGtB,UAAIA,kBAAiB,eAAeA,cAAa,GAAG;AAClD,oBAAY,cAAc;AAAA,MAC5B;AAAA,IACF;AAEA,QAAI,WAAW;AACb,oBAAc;AAAA,QACZ,GAAG;AAAA,QACH,OAAO;AAAA,QACP,SAAS;AAAA,QACT,YAAY;AAAA,UACV,MAAM;AAAA,UACN,UAAU,YAAY;AAAA,UACtB,YAAY;AAAA,QACd;AAAA,MACF;AAAA,IACF,WAAW,SAAS;AAElB,oBAAc;AAAA,QACZ,GAAG;AAAA,QACH,OAAO;AAAA,QACP,SAAS;AAAA,QACT,YAAY;AAAA,UACV,MAAM;AAAA,UACN,UAAU,YAAY;AAAA,UACtB,YAAY,cAAc;AAAA,QAC5B;AAAA,MACF;AAAA,IACF,WAAW,cAAc,mBAAmB,YAAY,GAAG;AACzD,oBAAc;AAAA,QACZ,GAAG;AAAA,QACH,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,SAAS;AAAA,MACX;AAAA,IACF,OAAO;AACL,oBAAc;AAAA,QACZ,GAAG;AAAA,QACH,OAAO;AAAA,QACP,YAAY,mBAAmB,YAAY;AAAA,QAC3C,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF,OAAO;AACL,kBAAc;AAAA,MACZ,GAAG;AAAA,MACH,OAAO;AAAA,MACP,YAAY,mBAAmB,YAAY;AAAA,MAC3C,SAAS;AAAA,IACX;AAAA,EACF;AAEA,SAAO,GAAG,WAAW;AACvB;;;AC9WO,IAAM,wBAA+C,CAC1D,MACA,QACA,aACG;AACH,QAAM,cAAc,KAAK,MAAM;AAAA,IAC7B,CAAC,SAAS,KAAK,OAAO,KAAK,WAAW;AAAA,EACxC;AAEA,MAAI,CAAC,aAAa;AAChB,WAAO,IAAI,UAAU,cAAc;AAAA,EACrC;AAEA,MAAI,YAAY,OAAO,QAAQ;AAC7B,WAAO,IAAI,UAAU,aAAa;AAAA,EACpC;AAEA,MAAI,CAAC,KAAK,SAAS,kBAAkB;AACnC,WAAO,IAAI,UAAU,qBAAqB;AAAA,EAC5C;AAEA,QAAM,EAAE,OAAO,gBAAgB,IAAI,KAAK,QAAQ;AAEhD,QAAM,gBAAgB,KAAK,QAAQ;AAAA,IACjC,CAAC,WAAW,OAAO,OAAO,YAAY;AAAA,EACxC;AAEA,MAAI,CAAC,eAAe;AAClB,WAAO,IAAI,UAAU,gBAAgB;AAAA,EACvC;AAEA,QAAM,iBAAiB,cAAc,cAAc,CAAC;AAEpD,MACE,CAAC;AAAA,IACC,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GACA;AACA,WAAO,IAAI,UAAU,2BAA2B;AAAA,EAClD;AAGA,QAAM,WAA4B,EAAE,OAAO,SAAS;AACpD,QAAM,oBAAoB,CAAC,GAAG,gBAAgB,QAAQ;AAGtD,MAAI,mBAAmB,cAAc;AACrC,MAAI,kBAAkB;AACpB,uBAAmB,iBAAiB;AAAA,MAClC,CAAC,MAAM,EAAE,EAAE,SAAS,MAAM,SAAS,KAAK,EAAE,SAAS,MAAM,SAAS;AAAA,IACpE;AAAA,EACF;AAGA,MAAI,iBAAiB,cAAc;AACnC,MAAI,gBAAgB;AAClB,qBAAiB,eAAe;AAAA,MAC9B,CAAC,MAAM,EAAE,EAAE,SAAS,MAAM,SAAS,KAAK,EAAE,SAAS,MAAM,SAAS;AAAA,IACpE;AAAA,EACF;AAEA,QAAM,iBAAiB,KAAK,QAAQ,IAAI,CAAC,WAAW;AAClD,QAAI,OAAO,OAAO,cAAc,IAAI;AAClC,aAAO;AAAA,QACL,GAAG;AAAA,QACH,YAAY;AAAA,QACZ,GAAI,qBAAqB,UAAa,EAAE,WAAW,iBAAiB;AAAA,QACpE,GAAI,mBAAmB,UAAa,EAAE,SAAS,eAAe;AAAA,MAChE;AAAA,IACF;AACA,WAAO;AAAA,EACT,CAAC;AAGD,QAAM,iBAAiB;AAAA,IACrB,GAAG,KAAK;AAAA,IACR,kBAAkB;AAAA,EACpB;AAGA,QAAM,aAAa,KAAK,SAAS,KAAK,MAAM,MAAM;AAElD,MAAI;AAEJ,MAAI,cAAc,mBAAmB,KAAK,KAAK,GAAG;AAChD,qBAAiB;AAAA,MACf,GAAG;AAAA,MACH,SAAS;AAAA,MACT,SAAS;AAAA,MACT,YAAY,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO;AAAA,IACrD;AAAA,EACF,WAAW,YAAY;AACrB,qBAAiB;AAAA,MACf,GAAG;AAAA,MACH,SAAS;AAAA,MACT,SAAS;AAAA,MACT,YAAY,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO;AAAA,IACrD;AAAA,EACF,OAAO;AACL,qBAAiB;AAAA,MACf,GAAG;AAAA,MACH,SAAS;AAAA,MACT,SAAS;AAAA,MACT,YAAY,mBAAmB,KAAK,KAAK;AAAA,IAC3C;AAAA,EACF;AAEA,SAAO,GAAG,cAAc;AAC1B;;;AC5GO,IAAM,oBAAuC,CAClD,MACA,QACA,aACG;AACH,QAAM,gBAAgB,KAAK;AAE3B,MAAI,cAAc,eAAe,cAAc,YAAY;AACzD,WAAO,IAAI,UAAU,uBAAuB;AAAA,EAC9C;AAEA,MAAI,cAAc,aAAa,QAAQ;AACrC,WAAO,IAAI,UAAU,aAAa;AAAA,EACpC;AAEA,MAAI,CAAC,KAAK,aAAa;AACrB,WAAO,IAAI,UAAU,YAAY;AAAA,EACnC;AAGA,QAAM,aAAa,kBAAkB,KAAK,YAAY,SAAS;AAC/D,MAAI,MAAM,UAAU,GAAG;AACrB,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM;AAC1D,MAAI,CAAC,aAAa;AAChB,WAAO,IAAI,UAAU,cAAc;AAAA,EACrC;AAEA,QAAM,gBAAgB,KAAK,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,YAAY,QAAQ;AAC5E,MAAI,CAAC,eAAe;AAClB,WAAO,IAAI,UAAU,gBAAgB;AAAA,EACvC;AAGA,QAAM,cAAc,kBAAkB,eAAe,QAAQ;AAC7D,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,EACT;AAEA,QAAM,iBAAiB,KAAK,QAAQ;AAAA,IAAI,CAAC,MACvC,EAAE,OAAO,cAAc,KAAK,YAAY,QAAQ;AAAA,EAClD;AAEA,QAAM,aAAa;AAAA,IACjB,GAAG,KAAK;AAAA,IACR,WAAW,WAAW;AAAA,EACxB;AAGA,QAAM,UAAU,6BAA6B,KAAK,KAAK,IAAI;AAC3D,QAAM,aAAa,sBAAsB,cAAc,YAAY,OAAO;AAE1E,MAAI,eAAe,cAAc,YAAY;AAE3C,UAAM,aAAa,KAAK,SAAS,KAAK,MAAM,MAAM;AAClD,QAAI,cAAc,mBAAmB,KAAK,KAAK,GAAG;AAChD,aAAO,GAAG;AAAA,QACR,GAAG;AAAA,QACH,SAAS;AAAA,QACT,aAAa;AAAA,QACb,YAAY,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO;AAAA,MACrD,CAAC;AAAA,IACH;AACA,WAAO,GAAG;AAAA,MACR,GAAG;AAAA,MACH,SAAS;AAAA,MACT,aAAa;AAAA,MACb,YAAY,mBAAmB,KAAK,KAAK;AAAA,IAC3C,CAAC;AAAA,EACH;AAGA,SAAO,GAAG;AAAA,IACR,GAAG;AAAA,IACH,SAAS;AAAA,IACT,aAAa;AAAA,IACb,YAAY;AAAA,MACV,MAAM;AAAA,MACN,UAAU;AAAA,MACV;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;ACvGO,IAAM,sCAAsC,CACjD,SACA,aACW;AACX,QAAM,OAAO,QAAQ;AACrB,QAAM,OAAO,QAAQ,CAAC,GAAG,UAAU;AACnC,QAAM,YAAY,QAAQ,SAAS,CAAC,IAAI,SAAS,CAAC;AAElD,MAAI,CAAC,aAAa,UAAU,SAAS,WAAW,UAAU,SAAS,UAAU;AAC3E,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,UAAU;AAC9B,QAAM,UAAuB,QAAQ,IAAI,CAAC,QAAQ,IAAI,IAAI,MAAM,KAAK,CAAC;AACtE,QAAM,QAA4B,CAAC,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;AAC3D,UAAQ,SAAS,CAAC,EAAG,SAAS,CAAC,IAAI;AACnC,MAAI,QAAQ;AAEZ,QAAM,aAAa;AAAA,IACjB,CAAC,IAAI,CAAC;AAAA,IACN,CAAC,GAAG,CAAC;AAAA,IACL,CAAC,GAAG,EAAE;AAAA,IACN,CAAC,GAAG,CAAC;AAAA,EACP;AAEA,SAAO,MAAM,SAAS,GAAG;AACvB,UAAM,CAAC,IAAI,EAAE,IAAI,MAAM,IAAI;AAC3B,UAAM,OAAO,QAAQ,EAAE,EAAG,EAAE;AAE5B,QACE,KAAK,SAAS,WACd,KAAK,SAAS,YACd,2BAA2B,QAC3B,KAAK,uBACL;AACA;AAAA,IACF;AAEA,eAAW,CAAC,IAAI,EAAE,KAAK,YAAY;AACjC,YAAM,KAAK,KAAM;AACjB,YAAM,KAAK,KAAM;AACjB,UACE,MAAM,KACN,MAAM,KACN,KAAK,QACL,KAAK,QACL,CAAC,QAAQ,EAAE,EAAG,EAAE,KAChB,QAAQ,EAAE,EAAG,EAAE,EAAG,SAAS,aAC3B;AACA,gBAAQ,EAAE,EAAG,EAAE,IAAI;AACnB,cAAM,KAAK,CAAC,IAAI,EAAE,CAAC;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAKA,IAAM,sBAAsB,CAC1B,SACA,aACkB;AAClB,QAAM,OAAO,QAAQ,SAAS,CAAC,IAAI,SAAS,CAAC;AAC7C,MAAI,CAAC,QAAQ,KAAK,SAAS,WAAW,KAAK,SAAS,SAAU,QAAO;AACrE,SAAO,KAAK;AACd;AAKA,IAAM,qBAAqB,CACzB,SACA,UACA,YACY;AACZ,QAAM,UAAU,oBAAoB,SAAS,QAAQ;AACrD,MAAI,CAAC,QAAS,QAAO;AAGrB,QAAM,OAAO,QAAQ;AACrB,QAAM,OAAO,QAAQ,CAAC,GAAG,UAAU;AACnC,QAAM,UAAuB,QAAQ,IAAI,CAAC,QAAQ,IAAI,IAAI,MAAM,KAAK,CAAC;AACtE,QAAM,QAA4B,CAAC,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;AAC3D,UAAQ,SAAS,CAAC,EAAG,SAAS,CAAC,IAAI;AACnC,QAAM,qBAAqB,oBAAI,IAAY;AAE3C,QAAM,aAAa;AAAA,IACjB,CAAC,IAAI,CAAC;AAAA,IACN,CAAC,GAAG,CAAC;AAAA,IACL,CAAC,GAAG,EAAE;AAAA,IACN,CAAC,GAAG,CAAC;AAAA,EACP;AAEA,SAAO,MAAM,SAAS,GAAG;AACvB,UAAM,CAAC,IAAI,EAAE,IAAI,MAAM,IAAI;AAC3B,uBAAmB,IAAI,GAAG,EAAE,IAAI,EAAE,EAAE;AAEpC,eAAW,CAAC,IAAI,EAAE,KAAK,YAAY;AACjC,YAAM,KAAK,KAAM;AACjB,YAAM,KAAK,KAAM;AACjB,UACE,MAAM,KACN,MAAM,KACN,KAAK,QACL,KAAK,QACL,CAAC,QAAQ,EAAE,EAAG,EAAE,KAChB,QAAQ,EAAE,EAAG,EAAE,EAAG,SAAS,SAC3B;AACA,gBAAQ,EAAE,EAAG,EAAE,IAAI;AACnB,cAAM,KAAK,CAAC,IAAI,EAAE,CAAC;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAEA,SAAO,QAAQ;AAAA,IAAK,CAAC,MACnB,mBAAmB,IAAI,GAAG,EAAE,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE;AAAA,EAC1D;AACF;AAEO,IAAM,iBAAiB,CAC5B,QACA,SACA,aACY;AACZ,QAAM,UAAU,OAAO,WAAW,CAAC;AACnC,MAAI,QAAQ,UAAU,YAAa,QAAO;AAE1C,QAAM,OAAO,QAAQ,SAAS,CAAC,IAAI,SAAS,CAAC;AAC7C,MAAI,CAAC,QAAQ,KAAK,SAAS,WAAW,KAAK,SAAS,SAAU,QAAO;AAErE,MAAI,mBAAmB,SAAS,UAAU,OAAO,EAAG,QAAO;AAE3D,SAAO;AACT;AAEO,IAAM,cAAc,CACzB,QACA,SACA,aACW;AACX,QAAM,SAAiB,EAAE,UAAU,OAAO,IAAI,SAAS;AACvD,QAAM,UAAU,CAAC,GAAI,OAAO,WAAW,CAAC,GAAI,MAAM;AAClD,QAAM,YAAY,oCAAoC,SAAS,QAAQ;AACvE,QAAM,gBAAgB,SAAS,EAAE,GAAG,QAAQ,QAAQ,GAAG,SAAS;AAEhE,SAAO;AACT;;;AC5IO,IAAM,qBAAyC,CACpD,MACA,QACA,aACG;AACH,QAAM,gBAAgB,KAAK;AAE3B,MAAI,cAAc,aAAa,QAAQ;AACrC,WAAO,IAAI,UAAU,aAAa;AAAA,EACpC;AAEA,MAAI,cAAc,eAAe,cAAc,aAAa;AAC1D,WAAO,IAAI,UAAU,uBAAuB;AAAA,EAC9C;AAEA,QAAM,cAAc,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM;AAC1D,MAAI,CAAC,YAAa,QAAO,IAAI,UAAU,cAAc;AAErD,QAAM,gBAAgB,KAAK,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,YAAY,QAAQ;AAC5E,MAAI,CAAC,cAAe,QAAO,IAAI,UAAU,gBAAgB;AAEzD,MAAI,CAAC,eAAe,eAAe,cAAc,SAAS,QAAQ,GAAG;AACnE,WAAO,IAAI,UAAU,mBAAmB;AAAA,EAC1C;AAEA,QAAM,gBAAgB;AAAA,IACpB;AAAA,IACA,cAAc;AAAA,IACd;AAAA,EACF;AAEA,QAAM,iBAAiB,KAAK,QAAQ;AAAA,IAAI,CAAC,MACvC,EAAE,OAAO,cAAc,KAAK,gBAAgB;AAAA,EAC9C;AAEA,QAAM,aAAa,sBAAsB,cAAc,WAAW;AAElE,SAAO,GAAG;AAAA,IACR,GAAG;AAAA,IACH,SAAS;AAAA,IACT,YAAY;AAAA,MACV,MAAM;AAAA,MACN,UAAU;AAAA,MACV;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;AC/BO,IAAM,wBAA+C,CAC1D,MACA,QACA,WACA,UACA,sBACG;AACH,QAAM,cAAc,KAAK,MAAM;AAAA,IAC7B,CAAC,SAAS,KAAK,OAAO,KAAK,WAAW;AAAA,EACxC;AAEA,MAAI,CAAC,aAAa;AAChB,WAAO,IAAI,UAAU,cAAc;AAAA,EACrC;AAEA,MAAI,YAAY,OAAO,QAAQ;AAC7B,WAAO,IAAI,UAAU,aAAa;AAAA,EACpC;AAEA,MAAI,CAAC,KAAK,SAAS,WAAW;AAC5B,WAAO,IAAI,UAAU,cAAc;AAAA,EACrC;AAEA,QAAM,gBAAgB,KAAK,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,YAAY,QAAQ;AAE5E,MAAI,CAAC,eAAe;AAClB,WAAO,IAAI,UAAU,gBAAgB;AAAA,EACvC;AAEA,QAAM,YAAY,cAAc,aAAa,CAAC;AAC9C,QAAM,aAAa,cAAc,cAAc,CAAC;AAChD,QAAM,UAAU,cAAc,WAAW,CAAC;AAG1C,QAAM,gBAAgB,KAAK,QAAQ,UAAU,QAAQ;AAAA,IACnD,CAAC,MAAM,EAAE,OAAO;AAAA,EAClB;AACA,QAAM,iBAAiB,KAAK,QAAQ,UAAU,SAAS;AAAA,IACrD,CAAC,MAAM,EAAE,OAAO;AAAA,EAClB;AAEA,MAAI,CAAC,iBAAiB,CAAC,gBAAgB;AACrC,WAAO,IAAI,UAAU,iBAAiB;AAAA,EACxC;AAEA,QAAM,yBAAyB,gBAAgB,IAAI;AACnD,QAAM,wBAAwB,gBAAgB,IAAI;AAElD,MAAI,kBAAkB,WAAW,uBAAuB;AACtD,WAAO,IAAI,UAAU,sBAAsB;AAAA,EAC7C;AAEA,MACE,CAAC,kBAAkB,WAAW,mBAAmB,sBAAsB,GACvE;AACA,WAAO,IAAI,UAAU,sBAAsB;AAAA,EAC7C;AAGA,MACE,CAAC;AAAA,IACC,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GACA;AACA,WAAO,IAAI,UAAU,yBAAyB;AAAA,EAChD;AAGA,MAAI;AACJ,MAAI,eAAe;AACjB,oBAAgB,uBAAuB,KAAK,QAAQ,WAAW,SAAS;AAAA,EAC1E,OAAO;AACL,oBAAgB,wBAAwB,KAAK,QAAQ,WAAW,SAAS;AAAA,EAC3E;AAEA,MAAI,CAAC,eAAe;AAClB,WAAO,IAAI,UAAU,iBAAiB;AAAA,EACxC;AAGA,QAAM,mBAAmB,eAAe,WAAW,iBAAiB;AAGpE,QAAM,iBAAiB;AAAA,IACrB,GAAG;AAAA,IACH,EAAE,SAAS,cAAc,SAAS,SAAS;AAAA,EAC7C;AAEA,QAAM,iBAAiB,KAAK,QAAQ,IAAI,CAAC,WAAW;AAClD,QAAI,OAAO,OAAO,cAAc,IAAI;AAClC,aAAO;AAAA,QACL,GAAG;AAAA,QACH,WAAW;AAAA,QACX,SAAS;AAAA,MACX;AAAA,IACF;AACA,WAAO;AAAA,EACT,CAAC;AAED,QAAM,iBAAiB;AAAA,IACrB,GAAG,KAAK;AAAA,IACR,WAAW,cAAc;AAAA,EAC3B;AAGA,QAAM,eAAe,KAAK,MAAM,IAAI,CAAC,SAAS;AAC5C,QAAI,KAAK,OAAO,YAAY,IAAI;AAC9B,aAAO,EAAE,GAAG,MAAM,WAAW,KAAK;AAAA,IACpC;AACA,WAAO;AAAA,EACT,CAAC;AAED,QAAM,aAAa,KAAK,SAAS,KAAK,MAAM,MAAM;AAElD,MAAI;AAEJ,MAAI,cAAc,mBAAmB,YAAY,GAAG;AAClD,qBAAiB;AAAA,MACf,GAAG;AAAA,MACH,SAAS;AAAA,MACT,OAAO;AAAA,MACP,SAAS;AAAA,MACT,YAAY,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO;AAAA,IACrD;AAAA,EACF,OAAO;AACL,qBAAiB;AAAA,MACf,GAAG;AAAA,MACH,SAAS;AAAA,MACT,OAAO;AAAA,MACP,SAAS;AAAA,MACT,YAAY,mBAAmB,YAAY;AAAA,IAC7C;AAAA,EACF;AAEA,SAAO,GAAG,cAAc;AAC1B;;;ACjJO,IAAM,mBAAqC,CAChD,MACA,QACA,YACA,gBACA,wBACG;AACH,QAAM,gBAAgB,KAAK;AAE3B,MAAI,cAAc,eAAe,cAAc,WAAW;AACxD,WAAO,IAAI,UAAU,uBAAuB;AAAA,EAC9C;AAEA,MAAI,cAAc,aAAa,QAAQ;AACrC,WAAO,IAAI,UAAU,aAAa;AAAA,EACpC;AAEA,MAAI,CAAC,KAAK,aAAa;AACrB,WAAO,IAAI,UAAU,YAAY;AAAA,EACnC;AAEA,QAAM,cAAc,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM;AAC1D,MAAI,CAAC,aAAa;AAChB,WAAO,IAAI,UAAU,cAAc;AAAA,EACrC;AAEA,QAAM,eAAe,KAAK,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,YAAY,QAAQ;AAC3E,MAAI,CAAC,cAAc;AACjB,WAAO,IAAI,UAAU,gBAAgB;AAAA,EACvC;AAEA,QAAM,eAAe,KAAK,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,cAAc;AACrE,MAAI,CAAC,cAAc;AACjB,WAAO,IAAI,UAAU,gBAAgB;AAAA,EACvC;AAEA,MAAI,aAAa,OAAO,aAAa,IAAI;AACvC,WAAO,IAAI,UAAU,uBAAuB;AAAA,EAC9C;AAEA,QAAM,SAAS;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,MAAM,MAAM,GAAG;AACjB,WAAO;AAAA,EACT;AAEA,QAAM,iBAAiB,KAAK,QAAQ,IAAI,CAAC,MAAM;AAC7C,QAAI,EAAE,OAAO,OAAO,MAAM,OAAO,GAAI,QAAO,OAAO,MAAM;AACzD,QAAI,EAAE,OAAO,OAAO,MAAM,OAAO,GAAI,QAAO,OAAO,MAAM;AACzD,WAAO;AAAA,EACT,CAAC;AAGD,QAAM,UAAU,6BAA6B,KAAK,KAAK,IAAI;AAC3D,QAAM,aAAa,sBAAsB,cAAc,WAAW,OAAO;AAEzE,MAAI,eAAe,cAAc,YAAY;AAC3C,UAAM,aAAa,KAAK,SAAS,KAAK,MAAM,MAAM;AAClD,QAAI,cAAc,mBAAmB,KAAK,KAAK,GAAG;AAChD,aAAO,GAAG;AAAA,QACR,GAAG;AAAA,QACH,SAAS;AAAA,QACT,YAAY,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO;AAAA,MACrD,CAAC;AAAA,IACH;AACA,WAAO,GAAG;AAAA,MACR,GAAG;AAAA,MACH,SAAS;AAAA,MACT,YAAY,mBAAmB,KAAK,KAAK;AAAA,IAC3C,CAAC;AAAA,EACH;AAEA,SAAO,GAAG;AAAA,IACR,GAAG;AAAA,IACH,SAAS;AAAA,IACT,YAAY;AAAA,MACV,MAAM;AAAA,MACN,UAAU;AAAA,MACV;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;ACvFO,IAAM,4BAAuD,CAClE,MACA,WACG;AACH,QAAM,gBAAgB,KAAK;AAE3B,MAAI,cAAc,aAAa,QAAQ;AACrC,WAAO,IAAI,UAAU,aAAa;AAAA,EACpC;AAEA,QAAM,SAAS,cAAc;AAG7B,QAAM,wBACJ,WAAW,cAAc,eACzB,WAAW,cAAc,qBACzB,WAAW,cAAc;AAG3B,QAAM,oBACJ,WAAW,cAAc,kBACzB,WAAW,cAAc;AAG3B,QAAM,gBACJ,WAAW,cAAc,aAAa,WAAW,cAAc;AAEjE,MAAI,CAAC,yBAAyB,CAAC,qBAAqB,CAAC,eAAe;AAClE,WAAO,IAAI,UAAU,uBAAuB;AAAA,EAC9C;AAEA,MAAI,eAAe;AACjB,WAAO,cAAc,MAAM,QAAQ,MAAM;AAAA,EAC3C;AAEA,MAAI,mBAAmB;AACrB,WAAO,kBAAkB,MAAM,QAAQ,MAAM;AAAA,EAC/C;AAGA,QAAM,aAAa,sBAAsB,MAAM;AAE/C,MAAI,eAAe,cAAc,YAAY;AAC3C,WAAO,0BAA0B,IAAI;AAAA,EACvC;AAEA,SAAO,GAAG;AAAA,IACR,GAAG;AAAA,IACH,YAAY;AAAA,MACV,MAAM;AAAA,MACN,UAAU;AAAA,MACV;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEA,IAAM,oBAAoB,CACxB,MACA,QACA,WACoB;AAEpB,MAAI,iBAAiB,KAAK;AAC1B,MACE,WAAW,cAAc,kBACzB,gBAAgB,kBAChB;AACA,qBAAiB;AAAA,MACf,GAAG;AAAA,MACH,kBAAkB;AAAA,IACpB;AAAA,EACF;AAEA,QAAM,QAAQ,YAAY,KAAK,KAAK,IAAI;AACxC,QAAM,aAAa;AAAA,IACjB;AAAA,IACA;AAAA,EACF;AAEA,QAAM,cAAc;AAAA,IAClB,GAAG;AAAA,IACH,GAAI,mBAAmB,UAAa,EAAE,SAAS,eAAe;AAAA,EAChE;AAGA,MAAI,eAAe,cAAc,YAAY;AAC3C,WAAO,0BAA0B,WAAW;AAAA,EAC9C;AAIA,MAAI,WAAW,cAAc,gBAAgB;AAC3C,WAAO,0BAA0B,WAAW;AAAA,EAC9C;AAEA,SAAO,GAAG;AAAA,IACR,GAAG;AAAA,IACH,YAAY;AAAA,MACV,MAAM;AAAA,MACN,UAAU;AAAA,MACV;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEA,IAAM,gBAAgB,CACpB,MACA,QACA,WACoB;AACpB,QAAM,UAAU,6BAA6B,KAAK,KAAK,IAAI;AAC3D,QAAM,aAAa;AAAA,IACjB;AAAA,IACA;AAAA,EACF;AAEA,MAAI,eAAe,cAAc,YAAY;AAC3C,WAAO,0BAA0B,IAAI;AAAA,EACvC;AAGA,SAAO,GAAG;AAAA,IACR,GAAG;AAAA,IACH,YAAY;AAAA,MACV,MAAM;AAAA,MACN,UAAU;AAAA,MACV;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEA,IAAM,4BAA4B,CAChC,SACoB;AACpB,QAAM,WAAW,KAAK,MAAM,MAAM;AAClC,QAAM,aAAa,KAAK,SAAS;AAEjC,MAAI,cAAc,mBAAmB,KAAK,KAAK,GAAG;AAChD,WAAO,GAAG;AAAA,MACR,GAAG;AAAA,MACH,YAAY,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO;AAAA,IACrD,CAAC;AAAA,EACH;AAEA,SAAO,GAAG;AAAA,IACR,GAAG;AAAA,IACH,YAAY,mBAAmB,KAAK,KAAK;AAAA,EAC3C,CAAC;AACH;;;ACvJO,IAAM,mBACX,CAAC,SAID,CAAC,SAAS;AACR,QAAM,EAAE,YAAAC,aAAY,eAAAC,eAAc,IAAI;AACtC,QAAM;AAAA,IACJ,OAAO;AAAA,MACL,OAAO,EAAE,OAAO,UAAU,gBAAgB;AAAA,IAC5C;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,kBAAkB,QAAQ;AAEhC,QAAM,WAAmB,CAAC;AAE1B,WAAS,IAAI,GAAG,IAAI,iBAAiB,KAAK;AACxC,aAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AACjC,YAAM,OAAO,WAAWD,YAAW,GAAG,QAAQ,CAAC,EAAG,EAAE;AACpD,eAAS,KAAK,IAAI;AAAA,IACpB;AAAA,EACF;AAEA,QAAM,UAAU,KAAK,OACjB,oBAAoB,KAAK,MAAM,OAAO,IACtCC;AACJ,QAAM,gBAAgB,QAAQ,QAAQ;AACtC,QAAM,eAAe,CAAC,GAAG,QAAQ;AACjC,QAAM,gBAAgB,aAAa,OAAO,GAAG,eAAe;AAC5D,gBAAc,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM;AAGhD,QAAM,eAAe,KAAK,MAAM,MAAM,4BAA4B;AAClE,MAAI,eAAe,GAAG;AACpB,kBAAc,OAAO,GAAG,YAAY;AAAA,EACtC;AAEA,QAAM,aAAyB;AAAA,IAC7B,MAAM;AAAA,IACN,UAAU,cAAc,CAAC,EAAG;AAAA,IAC5B,YAAY,cAAc;AAAA,EAC5B;AAGA,MAAI,cAAc,KAAK;AACvB,MACE,gBACC,KAAK,KAAK,SAAS,iBAClB,6BAA6B,KAAK,KAAK,IAAI,IAC7C;AACA,UAAM,kBAAkB,KAAK,OACzB,oBAAoB,KAAK,MAAM,WAAW,IAC1CA;AACJ,UAAM,QAAQ;AAAA,MACZ,YAAY,cAAc;AAAA,MAC1B;AAAA,IACF;AACA,kBAAc,EAAE,GAAG,aAAa,eAAe,MAAM;AAAA,EACvD;AAGA,MAAI,UAAU,KAAK;AACnB,MAAI,SAAS,aAAa,YAAY,KAAK,KAAK,IAAI,GAAG;AACrD,UAAM,cAAc,KAAK,OACrB,oBAAoB,KAAK,MAAM,SAAS,IACxCA;AACJ,UAAM,QAAQ,gBAAgB,QAAQ,UAAU,UAAU,WAAW;AACrE,cAAU,EAAE,GAAG,SAAS,WAAW,MAAM;AAAA,EAC3C;AAEA,QAAM,WAA+B;AAAA,IACnC,GAAG;AAAA,IACH,OAAO;AAAA,IACP;AAAA,IACA,UAAU;AAAA,IACV,iBAAiB,cAAc,IAAI,CAAC,QAAQ,UAAU;AACpD,aAAO;AAAA,QACL;AAAA,QACA,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,UAAU,QAAQ;AAAA,MACpB;AAAA,IACF,CAAC;AAAA,IACD,GAAI,gBAAgB,UAAa,EAAE,YAAY;AAAA,IAC/C,GAAI,YAAY,UAAa,EAAE,QAAQ;AAAA,EACzC;AAEA,SAAO,GAAG,QAAQ;AACpB;;;AC3FK,IAAM,mBAAqC,CAChD,MACA,QACA,eACG;AACH,QAAM,gBAAgB,KAAK;AAE3B,MAAI,cAAc,aAAa,QAAQ;AACrC,WAAO,IAAI,UAAU,aAAa;AAAA,EACpC;AAEA,MAAI,cAAc,eAAe,cAAc,WAAW;AACxD,WAAO,IAAI,UAAU,uBAAuB;AAAA,EAC9C;AAEA,MAAI,CAAC,KAAK,aAAa;AACrB,WAAO,IAAI,UAAU,uBAAuB;AAAA,EAC9C;AAEA,MACE,CAAC,KAAK,YAAY,mBAClB,KAAK,YAAY,qBACjB;AACA,WAAO,IAAI,UAAU,kBAAkB;AAAA,EACzC;AAEA,QAAM,cAAc,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM;AAC1D,MAAI,CAAC,YAAa,QAAO,IAAI,UAAU,cAAc;AAErD,QAAM,gBAAgB,KAAK,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,YAAY,QAAQ;AAC5E,MAAI,CAAC,cAAe,QAAO,IAAI,UAAU,gBAAgB;AAGzD,MAAI,KAAK,YAAY,kBAAkB,cAAc,IAAI;AACvD,WAAO,IAAI,UAAU,8BAA8B;AAAA,EACrD;AAEA,QAAM,SAAS;AAAA,IACb,KAAK,YAAY;AAAA,IACjB;AAAA,IACA;AAAA,EACF;AAEA,MAAI,CAAC,QAAQ;AACX,WAAO,IAAI,UAAU,kBAAkB;AAAA,EACzC;AAEA,QAAM,EAAE,cAAc,cAAc,IAAI;AAExC,QAAM,iBAAiB,KAAK,QAAQ;AAAA,IAAI,CAAC,MACvC,EAAE,OAAO,cAAc,KAAK,gBAAgB;AAAA,EAC9C;AAGA,QAAM,WAAW,KAAK,MAAM,MAAM;AAClC,QAAM,aAAa,KAAK,SAAS;AAEjC,MAAI,cAAc,mBAAmB,KAAK,KAAK,GAAG;AAChD,WAAO,GAAG;AAAA,MACR,GAAG;AAAA,MACH,SAAS;AAAA,MACT,aAAa;AAAA,QACX,GAAG,KAAK;AAAA,QACR,eAAe;AAAA,QACf,qBAAqB;AAAA,MACvB;AAAA,MACA,YAAY,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO;AAAA,IACrD,CAAC;AAAA,EACH;AAEA,SAAO,GAAG;AAAA,IACR,GAAG;AAAA,IACH,SAAS;AAAA,IACT,aAAa;AAAA,MACX,GAAG,KAAK;AAAA,MACR,eAAe;AAAA,MACf,qBAAqB;AAAA,IACvB;AAAA,IACA,YAAwB,mBAAmB,KAAK,KAAK;AAAA,EACvD,CAAC;AACH;;;ACcO,IAAM,kBAAkB,CAC7B,WACuB;AACvB,QAAM,iBAAiB,kBAAU;AACjC,QAAM,qBAAqB,qBAAa;AACxC,QAAM,sBAAsB,sBAAc;AAC1C,QAAM,oBAAoB,oBAAY;AACtC,QAAM,uBAAuB,uBAAe;AAC5C,QAAM,iBAAiB,kBAAU;AACjC,QAAM,OAAO,OAAO,cAAc;AAClC,QAAM,UAAU,OAAO,iBAAiB;AACxC,QAAM,aAAa,OAAO,cAAc;AAGxC,QAAM,SAAS,OAAO,SAClB,OAAO,SACP,OAAO,UACL,cAAc,IAAI,IAClB;AAEN,SAAO;AAAA,IACL,mBAAmB;AAAA,MACjB;AAAA,MACA;AAAA,MACA,kBAAkB;AAAA,QAChB;AAAA,QACA;AAAA,QACA,YAAY;AAAA,QACZ,eAAe;AAAA,QACf;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,iBAAiB;AAAA,MACf;AAAA,MACA;AAAA,MACA,gBAAgB,EAAE,eAAe,CAAC;AAAA,IACpC;AAAA,IACA,sBAAsB;AAAA,MACpB;AAAA,MACA;AAAA,MACA,qBAAqB,EAAE,eAAe,CAAC;AAAA,IACzC;AAAA,IACA,mBAAmB;AAAA,MACjB;AAAA,MACA;AAAA,MACA,kBAAkB;AAAA,QAChB,YAAY;AAAA,QACZ,eAAe;AAAA,QACf;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,sBAAsB;AAAA,MACpB;AAAA,MACA;AAAA,MACA,qBAAqB;AAAA,QACnB;AAAA,QACA;AAAA,QACA,eAAe;AAAA,MACjB,CAAC;AAAA,IACH;AAAA,IACA,kBAAkB;AAAA,MAChB;AAAA,MACA;AAAA,MACA,iBAAiB,EAAE,YAAY,MAAM,eAAe,QAAQ,CAAC;AAAA,IAC/D;AAAA,IACA,qBAAqB;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,oBAAoB;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,sBAAsB;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,kBAAkB,iBAAiB,QAAQ,YAAY;AAAA,MACrD;AAAA,MACA;AAAA,IACF,CAAC;AAAA,IACD,uBAAuB;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,2BAA2B;AAAA,MACzB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,uBAAuB;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,sBAAsB,qBAAqB,QAAQ,UAAU;AAAA,IAC7D,wBAAwB,uBAAuB,QAAQ,UAAU;AAAA,IACjE,yBAAyB;AAAA,MACvB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,mBAAmB,kBAAkB,QAAQ,YAAY,iBAAiB;AAAA,IAC1E,kBAAkB,iBAAiB,QAAQ,YAAY,gBAAgB;AAAA,IACvE,oBAAoB;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,0BAA0B;AAAA,MACxB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,kBAAkB,iBAAiB,QAAQ,YAAY,gBAAgB;AAAA,IACvE,uBAAuB;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,uBAAuB;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,2BAA2B;AAAA,MACzB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;;;AClPA,IAAM,QAAQ,CACZ,MACA,MACA,SACA,WAA+B,aACV,EAAE,MAAM,MAAM,SAAS,SAAS;AAEvD,IAAM,mBAAmB,CAAC,UACxB,OAAO,UAAU,YAAY,MAAM,SAAS;AAE9C,IAAM,uBAAuB,CAAC,UAC5B,OAAO,UAAU,YAAY,OAAO,UAAU,KAAK,KAAK,SAAS;AAEnE,IAAM,oBAAoB,CAAC,UACzB,OAAO,UAAU,YAAY,OAAO,UAAU,KAAK,KAAK,QAAQ;AAElE,IAAM,eAAe,oBAAI,IAAY,CAAC,GAAG,QAAQ,OAAO,CAAC;AACzD,IAAM,qBAAqB,IAAI,IAAY,OAAO,OAAO,aAAa,CAAC;AACvE,IAAM,iBAAiB,IAAI,IAAY,OAAO,OAAO,SAAS,CAAC;AAI/D,IAAM,wBAAwB,CAAC,SAAkC;AAC/D,QAAM,SAA4B,CAAC;AAEnC,MAAI,CAAC,iBAAiB,KAAK,EAAE,GAAG;AAC9B,WAAO;AAAA,MACL,MAAM,MAAM,cAAc,oCAAoC;AAAA,IAChE;AAAA,EACF;AACA,MAAI,CAAC,qBAAqB,KAAK,IAAI,GAAG;AACpC,WAAO;AAAA,MACL,MAAM,QAAQ,gBAAgB,qCAAqC;AAAA,IACrE;AAAA,EACF;AACA,MAAI,CAAC,MAAM,QAAQ,KAAK,QAAQ,GAAG;AACjC,WAAO;AAAA,MACL,MAAM,YAAY,oBAAoB,2BAA2B;AAAA,IACnE;AAAA,EACF;AACA,MAAI,CAAC,MAAM,QAAQ,KAAK,eAAe,GAAG;AACxC,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,MAAI,CAAC,MAAM,QAAQ,KAAK,OAAO,GAAG;AAChC,WAAO;AAAA,MACL,MAAM,WAAW,mBAAmB,0BAA0B;AAAA,IAChE;AAAA,EACF;AACA,MAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,GAAG;AAC9B,WAAO,KAAK,MAAM,SAAS,iBAAiB,wBAAwB,CAAC;AAAA,EACvE;AACA,MAAI,CAAC,KAAK,SAAS,OAAO,KAAK,UAAU,UAAU;AACjD,WAAO,KAAK,MAAM,SAAS,iBAAiB,yBAAyB,CAAC;AAAA,EACxE,OAAO;AACL,QAAI,CAAC,KAAK,MAAM,SAAS,OAAO,KAAK,MAAM,UAAU,UAAU;AAC7D,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,QAAI,CAAC,MAAM,QAAQ,KAAK,MAAM,KAAK,GAAG;AACpC,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,MAAI,CAAC,KAAK,QAAQ,OAAO,KAAK,SAAS,UAAU;AAC/C,WAAO,KAAK,MAAM,QAAQ,gBAAgB,wBAAwB,CAAC;AAAA,EACrE,OAAO;AACL,QAAI,CAAC,iBAAiB,KAAK,KAAK,IAAI,GAAG;AACrC,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,MAAI,CAAC,KAAK,cAAc,OAAO,KAAK,eAAe,UAAU;AAC3D,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF,WACE,KAAK,WAAW,SAAS,YACzB,KAAK,WAAW,SAAS,QACzB;AACA,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,IAAM,eAAe,CAAC,MAAe,SAAoC;AACvE,QAAM,SAA4B,CAAC;AACnC,MAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;AACrC,WAAO;AAAA,MACL,MAAM,MAAM,gBAAgB,WAAW,IAAI,oBAAoB;AAAA,IACjE;AACA,WAAO;AAAA,EACT;AACA,QAAM,IAAI;AACV,MAAI,OAAO,EAAE,SAAS,YAAY,CAAC,aAAa,IAAI,EAAE,IAAI,GAAG;AAC3D,WAAO;AAAA,MACL;AAAA,QACE,GAAG,IAAI;AAAA,QACP;AAAA,QACA,2BAA2B,IAAI;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AACA,MAAI,OAAO,EAAE,WAAW,YAAY,EAAE,SAAS,GAAG;AAChD,WAAO;AAAA,MACL;AAAA,QACE,GAAG,IAAI;AAAA,QACP;AAAA,QACA,qBAAqB,IAAI;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,IAAM,kBAAkB,CAAC,SAAkC;AACzD,QAAM,SAA4B,CAAC;AACnC,MAAI,CAAC,MAAM,QAAQ,KAAK,OAAO,EAAG,QAAO;AAEzC,QAAM,YAAY,oBAAI,IAAY;AAClC,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,QAAQ,KAAK;AAC5C,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,UAAM,OAAO,WAAW,CAAC;AAEzB,QAAI,CAAC,iBAAiB,OAAO,EAAE,GAAG;AAChC,aAAO;AAAA,QACL;AAAA,UACE,GAAG,IAAI;AAAA,UACP;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF,WAAW,UAAU,IAAI,OAAO,EAAE,GAAG;AACnC,aAAO;AAAA,QACL;AAAA,UACE,GAAG,IAAI;AAAA,UACP;AAAA,UACA,wBAAwB,OAAO,EAAE;AAAA,QACnC;AAAA,MACF;AAAA,IACF,OAAO;AACL,gBAAU,IAAI,OAAO,EAAE;AAAA,IACzB;AAEA,QAAI,OAAO,OAAO,SAAS,YAAY,OAAO,KAAK,SAAS,GAAG;AAC7D,aAAO;AAAA,QACL;AAAA,UACE,GAAG,IAAI;AAAA,UACP;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,QAAI,CAAC,MAAM,QAAQ,OAAO,OAAO,GAAG;AAClC,aAAO;AAAA,QACL;AAAA,UACE,GAAG,IAAI;AAAA,UACP;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA;AAAA,IACF;AACA,QAAI,OAAO,QAAQ,WAAW,UAAU;AACtC,aAAO;AAAA,QACL;AAAA,UACE,GAAG,IAAI;AAAA,UACP;AAAA,UACA,qBAAqB,QAAQ,cAAc,OAAO,QAAQ,MAAM;AAAA,QAClE;AAAA,MACF;AACA;AAAA,IACF;AAEA,QAAI,cAAc;AAClB,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,QAAQ,KAAK;AAC9C,YAAM,MAAM,OAAO,QAAQ,CAAC;AAC5B,UAAI,CAAC,MAAM,QAAQ,GAAG,KAAK,IAAI,WAAW,UAAU;AAClD,eAAO;AAAA,UACL;AAAA,YACE,GAAG,IAAI,YAAY,CAAC;AAAA,YACpB;AAAA,YACA,eAAe,CAAC,cAAc,QAAQ;AAAA,UACxC;AAAA,QACF;AACA;AAAA,MACF;AACA,eAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,cAAM,OAAO,IAAI,CAAC;AAClB,eAAO,KAAK,GAAG,aAAa,MAAM,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC;AAChE,YACE,QACA,OAAO,SAAS,YACf,KAAiC,SAAS,UAC3C;AACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,QAAI,gBAAgB,GAAG;AACrB,aAAO;AAAA,QACL;AAAA,UACE,GAAG,IAAI;AAAA,UACP;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF,WAAW,cAAc,GAAG;AAC1B,aAAO;AAAA,QACL;AAAA,UACE,GAAG,IAAI;AAAA,UACP;AAAA,UACA,eAAe,WAAW;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,IAAM,mBAAmB,CAAC,SAAkC;AAC1D,QAAM,SAA4B,CAAC;AACnC,QAAM,aAAa,oBAAI,IAAY;AAGnC,MAAI,MAAM,QAAQ,KAAK,QAAQ,GAAG;AAChC,aAAS,IAAI,GAAG,IAAI,KAAK,SAAS,QAAQ,KAAK;AAC7C,YAAM,SAAS,KAAK,SAAS,CAAC;AAC9B,YAAM,OAAO,YAAY,CAAC;AAE1B,UAAI,CAAC,kBAAkB,OAAO,MAAM,GAAG;AACrC,eAAO;AAAA,UACL;AAAA,YACE,GAAG,IAAI;AAAA,YACP;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF,WAAW,WAAW,IAAI,OAAO,MAAM,GAAG;AACxC,eAAO;AAAA,UACL;AAAA,YACE,GAAG,IAAI;AAAA,YACP;AAAA,YACA,4BAA4B,OAAO,MAAM;AAAA,UAC3C;AAAA,QACF;AAAA,MACF,OAAO;AACL,mBAAW,IAAI,OAAO,MAAM;AAAA,MAC9B;AACA,aAAO,KAAK,GAAG,aAAa,OAAO,MAAM,GAAG,IAAI,OAAO,CAAC;AACxD,aAAO,KAAK,GAAG,aAAa,OAAO,OAAO,GAAG,IAAI,QAAQ,CAAC;AAAA,IAC5D;AAAA,EACF;AAGA,MAAI,MAAM,QAAQ,KAAK,eAAe,GAAG;AACvC,aAAS,IAAI,GAAG,IAAI,KAAK,gBAAgB,QAAQ,KAAK;AACpD,YAAM,WAAW,KAAK,gBAAgB,CAAC;AACvC,YAAM,OAAO,mBAAmB,CAAC;AAEjC,UAAI,CAAC,SAAS,UAAU,OAAO,SAAS,WAAW,UAAU;AAC3D,eAAO;AAAA,UACL;AAAA,YACE,GAAG,IAAI;AAAA,YACP;AAAA,YACA;AAAA,UACF;AAAA,QACF;AACA;AAAA,MACF;AAEA,YAAM,SAAS,SAAS;AACxB,UAAI,CAAC,kBAAkB,OAAO,MAAM,GAAG;AACrC,eAAO;AAAA,UACL;AAAA,YACE,GAAG,IAAI;AAAA,YACP;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF,WAAW,WAAW,IAAI,OAAO,MAAM,GAAG;AACxC,eAAO;AAAA,UACL;AAAA,YACE,GAAG,IAAI;AAAA,YACP;AAAA,YACA,4BAA4B,OAAO,MAAM;AAAA,UAC3C;AAAA,QACF;AAAA,MACF,OAAO;AACL,mBAAW,IAAI,OAAO,MAAM;AAAA,MAC9B;AACA,aAAO,KAAK,GAAG,aAAa,OAAO,MAAM,GAAG,IAAI,cAAc,CAAC;AAC/D,aAAO,KAAK,GAAG,aAAa,OAAO,OAAO,GAAG,IAAI,eAAe,CAAC;AAGjE,UAAI,SAAS,UAAU,SAAS,WAAW,MAAM;AAC/C,eAAO;AAAA,UACL;AAAA,YACE,GAAG,IAAI;AAAA,YACP;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,UAAI,CAAC,SAAS,UAAU,SAAS,WAAW,MAAM;AAChD,eAAO;AAAA,UACL;AAAA,YACE,GAAG,IAAI;AAAA,YACP;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAKA,MAAI,MAAM,QAAQ,KAAK,KAAK,GAAG;AAC7B,UAAM,oBAAoB,oBAAI,IAAY;AAC1C,aAAS,IAAI,GAAG,IAAI,KAAK,MAAM,QAAQ,KAAK;AAC1C,YAAM,OAAO,KAAK,MAAM,CAAC;AACzB,UAAI,KAAK,cAAc;AACrB,cAAM,OAAO,SAAS,CAAC;AACvB,cAAM,SAAS,KAAK;AACpB,YAAI,CAAC,kBAAkB,OAAO,MAAM,GAAG;AACrC,iBAAO;AAAA,YACL;AAAA,cACE,GAAG,IAAI;AAAA,cACP;AAAA,cACA;AAAA,YACF;AAAA,UACF;AAAA,QACF,WAAW,kBAAkB,IAAI,OAAO,MAAM,GAAG;AAC/C,iBAAO;AAAA,YACL;AAAA,cACE,GAAG,IAAI;AAAA,cACP;AAAA,cACA,wCAAwC,OAAO,MAAM;AAAA,YACvD;AAAA,UACF;AAAA,QACF,OAAO;AACL,4BAAkB,IAAI,OAAO,MAAM;AAAA,QACrC;AACA,eAAO,KAAK,GAAG,aAAa,OAAO,MAAM,GAAG,IAAI,OAAO,CAAC;AACxD,eAAO,KAAK,GAAG,aAAa,OAAO,OAAO,GAAG,IAAI,QAAQ,CAAC;AAAA,MAC5D;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,IAAM,gBAAgB,CAAC,SAAkC;AACvD,QAAM,SAA4B,CAAC;AACnC,MAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,EAAG,QAAO;AAEvC,QAAM,YAAY,IAAI;AAAA,IACpB,MAAM,QAAQ,KAAK,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC;AAAA,EACjE;AACA,QAAM,UAAU,oBAAI,IAAY;AAEhC,WAAS,IAAI,GAAG,IAAI,KAAK,MAAM,QAAQ,KAAK;AAC1C,UAAM,OAAO,KAAK,MAAM,CAAC;AACzB,UAAM,OAAO,SAAS,CAAC;AAEvB,QAAI,CAAC,iBAAiB,KAAK,EAAE,GAAG;AAC9B,aAAO;AAAA,QACL;AAAA,UACE,GAAG,IAAI;AAAA,UACP;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF,WAAW,QAAQ,IAAI,KAAK,EAAE,GAAG;AAC/B,aAAO;AAAA,QACL;AAAA,UACE,GAAG,IAAI;AAAA,UACP;AAAA,UACA,sBAAsB,KAAK,EAAE;AAAA,QAC/B;AAAA,MACF;AAAA,IACF,OAAO;AACL,cAAQ,IAAI,KAAK,EAAE;AAAA,IACrB;AAEA,QAAI,CAAC,iBAAiB,KAAK,QAAQ,GAAG;AACpC,aAAO;AAAA,QACL;AAAA,UACE,GAAG,IAAI;AAAA,UACP;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF,WAAW,UAAU,OAAO,KAAK,CAAC,UAAU,IAAI,KAAK,QAAQ,GAAG;AAC9D,aAAO;AAAA,QACL;AAAA,UACE,GAAG,IAAI;AAAA,UACP;AAAA,UACA,wCAAwC,KAAK,QAAQ;AAAA,QACvD;AAAA,MACF;AAAA,IACF;AAEA,QAAI,KAAK,cAAc,CAAC,KAAK,WAAW,CAAC,KAAK,WAAW;AACvD,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA;AAAA,UACA,uCAAuC,KAAK,OAAO,cAAc,KAAK,QAAQ;AAAA,UAC9E;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,IAAM,mBAAmB,CAAC,SAAkC;AAC1D,QAAM,SAA4B,CAAC;AACnC,MAAI,CAAC,KAAK,cAAc,OAAO,KAAK,eAAe,SAAU,QAAO;AAEpE,QAAM,aAAa,KAAK;AAExB,MAAI,WAAW,SAAS,UAAU;AAChC,UAAM,SAAS;AAMf,QAAI,CAAC,iBAAiB,OAAO,QAAQ,GAAG;AACtC,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF,WACE,MAAM,QAAQ,KAAK,KAAK,KACxB,CAAC,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,OAAO,QAAQ,GAChD;AACA,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA;AAAA,UACA,0CAA0C,OAAO,QAAkB;AAAA,QACrE;AAAA,MACF;AAAA,IACF;AAEA,QACE,OAAO,OAAO,eAAe,YAC7B,CAAC,mBAAmB,IAAI,OAAO,UAAoB,GACnD;AACA,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA;AAAA,UACA,8BAA8B,CAAC,GAAG,kBAAkB,EAAE,KAAK,IAAI,CAAC;AAAA,QAClE;AAAA,MACF;AAAA,IACF;AAAA,EACF,WAAW,WAAW,SAAS,QAAQ;AACrC,UAAM,OAAO;AAEb,QACE,OAAO,KAAK,SAAS,YACrB,CAAC,eAAe,IAAI,KAAK,IAAc,GACvC;AACA,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA;AAAA,UACA,wBAAwB,CAAC,GAAG,cAAc,EAAE,KAAK,IAAI,CAAC;AAAA,QACxD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,IAAM,eAAe,CAAC,SAAwB;AAC5C,MAAI,KAAK,YAAY,SAAS,OAAQ,QAAO;AAC7C,QAAM,OAAQ,KAAK,WAAgC;AACnD,SAAO,SAAS,gBAAgB,SAAS,aAAa,SAAS;AACjE;AAEA,IAAM,gBAAgB,CAAC,SAAkC;AACvD,QAAM,SAA4B,CAAC;AACnC,MAAI,CAAC,KAAK,SAAS,OAAO,KAAK,UAAU,SAAU,QAAO;AAG1D,QAAM,YAAY,aAAa,IAAI;AAEnC,QAAM,QAAQ,KAAK,MAAM;AACzB,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,UAAM,SAAS;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,eAAW,SAAS,QAAQ;AAC1B,YAAM,QAAQ,YAAY,uBAAuB;AACjD,UAAI,CAAC,MAAM,MAAM,KAAK,CAAC,GAAG;AACxB,eAAO;AAAA,UACL;AAAA,YACE,eAAe,KAAK;AAAA,YACpB;AAAA,YACA,eAAe,KAAK;AAAA,UACtB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,MAAM,QAAQ,KAAK,MAAM,KAAK,GAAG;AACnC,aAAS,IAAI,GAAG,IAAI,KAAK,MAAM,MAAM,QAAQ,KAAK;AAChD,YAAM,OAAO,KAAK,MAAM,MAAM,CAAC;AAC/B,UAAI,CAAC,iBAAiB,KAAK,IAAI,GAAG;AAChC,eAAO;AAAA,UACL;AAAA,YACE,eAAe,CAAC;AAAA,YAChB;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAmBO,IAAM,oBAAoB,CAAC,SAAkC;AAClE,QAAM,SAA4B,CAAC;AAEnC,SAAO,KAAK,GAAG,sBAAsB,IAAI,CAAC;AAC1C,SAAO,KAAK,GAAG,gBAAgB,IAAI,CAAC;AACpC,SAAO,KAAK,GAAG,iBAAiB,IAAI,CAAC;AACrC,SAAO,KAAK,GAAG,cAAc,IAAI,CAAC;AAClC,SAAO,KAAK,GAAG,iBAAiB,IAAI,CAAC;AACrC,SAAO,KAAK,GAAG,cAAc,IAAI,CAAC;AAElC,SAAO;AACT;;;ACplBA,IAAM,uBAAuB,OAAoC;AAAA,EAC/D,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,QAAQ;AACV;AAMO,IAAM,cAAc,CACzB,MACA,WAC4B;AAC5B,SAAO,SAAS,IAAI,KAAK,qBAAqB,EAAE,IAAI;AACtD;AAKO,IAAM,mBAAmB,MAC9B,OAAO,KAAK,qBAAqB,CAAC;;;ACWpC,IAAM,eAAe,CAAC,YAA6B;AACjD,QAAM,SAAS,sBAAsB,OAAO;AAC5C,SAAO,KAAK,MAAM,IAAI,OAAO,MAAM,SAAS;AAC9C;AAEA,IAAM,oBAAoB,CACxB,SACA,QACA,WACA,mBACmB;AACnB,QAAM,SAAS;AAAA,IACb;AAAA,IACA,UAAU;AAAA,IACV,UAAU;AAAA,IACV;AAAA,IACA;AAAA,EACF;AACA,SAAO,KAAK,MAAM,IAAI,OAAO,QAAQ;AACvC;AAEA,IAAM,qBAAqB,CACzB,SACA,QACA,YACA,mBAC0E;AAC1E,MAAI,OAIO;AAEX,aAAW,aAAa,YAAY;AAClC,UAAM,aAAa;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,QAAI,CAAC,WAAY;AACjB,UAAM,QAAQ,aAAa,UAAU;AACrC,QAAI,CAAC,QAAQ,QAAQ,KAAK,OAAO;AAC/B,aAAO,EAAE,WAAW,OAAO,SAAS,WAAW;AAAA,IACjD;AAAA,EACF;AAEA,SAAO;AACT;AAEA,IAAM,oBAAoB,CAAC,SACzB,KAAK,MAAM,MAAM;AAEnB,IAAM,mBAAmB,CAAC,MAA0B,WAAmB;AACrE,QAAM,OAAO,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM;AACnD,QAAM,SAAS,OACX,KAAK,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK,QAAQ,IAC/C;AACJ,SAAO,EAAE,MAAM,OAAO;AACxB;AAEA,IAAM,uBAAuB,CAAC,SAAuC;AACnE,QAAM,UAAU,KAAK,MAAM,MAAM;AACjC,SAAO,CAAC,GAAG,KAAK,QAAQ,EACrB,MAAM,GAAG,OAAO,EAChB,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM;AACvC;AAQO,IAAM,iBAA8B;AAAA,EACzC,cAAc,CAAC,YAAY;AACzB,UAAM,EAAE,kBAAkB,IAAI;AAC9B,UAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,kBAAkB,MAAM;AAC/D,WAAO,kBAAkB,GAAG,EAAG,OAAO;AAAA,EACxC;AAAA,EAEA,iBAAiB,CAAC,YAAY;AAC5B,UAAM,EAAE,gBAAgB,IAAI;AAC5B,QAAI,gBAAgB,WAAW,EAAG,QAAO;AACzC,UAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,gBAAgB,MAAM;AAC7D,WAAO,gBAAgB,GAAG;AAAA,EAC5B;AACF;AASO,IAAM,iBAA8B;AAAA,EACzC,cAAc,CAAC,YAAY;AACzB,UAAM,EAAE,MAAM,QAAQ,kBAAkB,IAAI;AAC5C,UAAM,EAAE,OAAO,IAAI,iBAAiB,MAAM,MAAM;AAChD,QAAI,CAAC,OAAQ,QAAO,kBAAkB,CAAC,EAAG,OAAO;AAEjD,UAAM,UAAU,kBAAkB,IAAI;AACtC,QAAI,YAAY;AAChB,QAAI,WAAW,kBAAkB,CAAC,EAAG,OAAO;AAE5C,eAAW,MAAM,mBAAmB;AAClC,YAAM,aAAa;AAAA,QACjB,OAAO;AAAA,QACP,GAAG;AAAA,QACH;AAAA,MACF;AACA,YAAM,SAAS;AAAA,QACb,OAAO;AAAA,QACP,GAAG;AAAA,QACH;AAAA,QACA;AAAA,MACF;AACA,YAAM,QAAQ,SAAS,OAAO,QAAQ;AACtC,UAAI,QAAQ,WAAW;AACrB,oBAAY;AACZ,mBAAW,GAAG,OAAO;AAAA,MACvB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,iBAAiB,CAAC,YAAY;AAC5B,UAAM,EAAE,MAAM,QAAQ,SAAS,gBAAgB,IAAI;AACnD,QAAI,gBAAgB,WAAW,EAAG,QAAO;AAEzC,UAAM,UAAU,kBAAkB,IAAI;AACtC,UAAM,SAAS;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,WAAO,SAAS,OAAO,YAAY,gBAAgB,CAAC;AAAA,EACtD;AACF;AAIA,IAAM,wBAAwB,CAC5B,SACA,SACA,iBACW;AACX,MAAI,aAAa,WAAW,EAAG,QAAO;AAEtC,MAAI,gBAAgB;AACpB,aAAW,cAAc,cAAc;AACrC,UAAM,iBAAiB;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,SAAS;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,QAAI,UAAU,OAAO,QAAQ,eAAe;AAC1C,sBAAgB,OAAO;AAAA,IACzB;AAAA,EACF;AAEA,SAAO;AACT;AAQO,IAAM,mBAAgC;AAAA,EAC3C,cAAc,CAAC,YAAY;AACzB,UAAM,EAAE,MAAM,QAAQ,kBAAkB,IAAI;AAC5C,UAAM,EAAE,OAAO,IAAI,iBAAiB,MAAM,MAAM;AAChD,QAAI,CAAC,OAAQ,QAAO,kBAAkB,CAAC,EAAG,OAAO;AAEjD,UAAM,UAAU,kBAAkB,IAAI;AACtC,UAAM,YAAY,qBAAqB,IAAI;AAE3C,QAAI,oBAAoB;AACxB,QAAI,WAAW,kBAAkB,CAAC,EAAG,OAAO;AAE5C,eAAW,MAAM,mBAAmB;AAClC,YAAM,aAAa;AAAA,QACjB,OAAO;AAAA,QACP,GAAG;AAAA,QACH;AAAA,MACF;AACA,YAAM,SAAS;AAAA,QACb,OAAO;AAAA,QACP,GAAG;AAAA,QACH;AAAA,QACA;AAAA,MACF;AAEA,YAAM,iBAAiB,SACnB,OAAO,QACP,aAAa,OAAO,OAAO;AAC/B,YAAM,eAAe,SAAS,OAAO,UAAU,OAAO;AACtD,YAAM,cAAc;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,YAAM,WAAW,iBAAiB,cAAc;AAEhD,UAAI,WAAW,mBAAmB;AAChC,4BAAoB;AACpB,mBAAW,GAAG,OAAO;AAAA,MACvB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,iBAAiB,CAAC,YAAY;AAC5B,UAAM,EAAE,MAAM,QAAQ,SAAS,gBAAgB,IAAI;AACnD,QAAI,gBAAgB,WAAW,EAAG,QAAO;AAEzC,UAAM,UAAU,kBAAkB,IAAI;AACtC,UAAM,YAAY,qBAAqB,IAAI;AAE3C,QAAI,oBAAoB;AACxB,QAAI,gBAAgC,gBAAgB,CAAC;AAErD,eAAW,aAAa,iBAAiB;AACvC,YAAM,aAAa,kBAAkB,SAAS,QAAQ,WAAW,OAAO;AACxE,UAAI,CAAC,WAAY;AAEjB,YAAM,iBAAiB,aAAa,UAAU;AAC9C,YAAM,cAAc,sBAAsB,YAAY,SAAS,SAAS;AACxE,YAAM,WAAW,iBAAiB,cAAc;AAEhD,UAAI,WAAW,mBAAmB;AAChC,4BAAoB;AACpB,wBAAgB;AAAA,MAClB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;AAKA,IAAM,oBAAoB;AAG1B,IAAM,mBAAmB;AAMzB,IAAM,gBAAgB,CACpB,SACA,QACA,YACA,SACA,UACqB;AACrB,MAAI,WAAW,UAAU,MAAO,QAAO;AAEvC,QAAM,SAAS,WACZ,IAAI,CAAC,MAAM;AACV,UAAM,IAAI,kBAAkB,SAAS,QAAQ,GAAG,OAAO;AACvD,WAAO,EAAE,WAAW,GAAG,OAAO,IAAI,aAAa,CAAC,IAAI,EAAE;AAAA,EACxD,CAAC,EACA,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAEnC,SAAO,OAAO,MAAM,GAAG,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,SAAS;AACtD;AAEA,IAAM,iBAAiB,CACrB,SACA,mBACA,iBACA,SACA,UACW;AACX,MAAI,SAAS,KAAK,kBAAkB,WAAW,GAAG;AAChD,WAAO,aAAa,OAAO;AAAA,EAC7B;AAGA,QAAM,QAAQ,CAAC,GAAG,iBAAiB,EAChC,MAAM,GAAG,eAAe,EACxB,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM;AACrC,QAAM,aAAa,kBAAkB,MAAM,eAAe;AAE1D,MAAI,YAAY,aAAa,OAAO;AAEpC,aAAW,UAAU,OAAO;AAC1B,UAAM,gBAAgB,0BAA0B,SAAS,QAAQ,OAAO;AAExE,QAAI,cAAc,WAAW,GAAG;AAC9B,YAAM,QAAQ;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,MACV;AACA,UAAI,QAAQ,UAAW,aAAY;AACnC;AAAA,IACF;AAGA,UAAM,aAAa;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,eAAW,aAAa,YAAY;AAClC,YAAM,aAAa,kBAAkB,SAAS,QAAQ,WAAW,OAAO;AACxE,UAAI,CAAC,WAAY;AAEjB,YAAM,QAAQ;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,MACV;AACA,UAAI,QAAQ,UAAW,aAAY;AAAA,IACrC;AAAA,EACF;AAEA,SAAO;AACT;AAQO,IAAM,iBAA8B;AAAA,EACzC,cAAc,CAAC,YAAY;AACzB,UAAM,EAAE,MAAM,QAAQ,kBAAkB,IAAI;AAC5C,UAAM,EAAE,OAAO,IAAI,iBAAiB,MAAM,MAAM;AAChD,QAAI,CAAC,OAAQ,QAAO,kBAAkB,CAAC,EAAG,OAAO;AAEjD,UAAM,UAAU,kBAAkB,IAAI;AACtC,UAAM,UAAU,KAAK,MAAM,MAAM;AACjC,UAAM,YAAY,KAAK;AAAA,MACrB,KAAK,MAAM,MAAM,WAAW,KAAK;AAAA,MACjC;AAAA,IACF;AAEA,QAAI,YAAY;AAChB,QAAI,WAAW,kBAAkB,CAAC,EAAG,OAAO;AAE5C,eAAW,MAAM,mBAAmB;AAClC,YAAM,gBAAgB;AAAA,QACpB,OAAO;AAAA,QACP,GAAG;AAAA,QACH;AAAA,MACF;AAEA,UAAI,cAAc,WAAW,GAAG;AAC9B,cAAM,QAAQ;AAAA,UACZ,OAAO;AAAA,UACP,KAAK;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,QACF;AACA,YAAI,QAAQ,WAAW;AACrB,sBAAY;AACZ,qBAAW,GAAG,OAAO;AAAA,QACvB;AACA;AAAA,MACF;AAEA,YAAM,aAAa;AAAA,QACjB,OAAO;AAAA,QACP,GAAG;AAAA,QACH;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,iBAAW,aAAa,YAAY;AAClC,cAAM,aAAa;AAAA,UACjB,OAAO;AAAA,UACP,GAAG;AAAA,UACH;AAAA,UACA;AAAA,QACF;AACA,YAAI,CAAC,WAAY;AAEjB,cAAM,QAAQ;AAAA,UACZ;AAAA,UACA,KAAK;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,QACF;AACA,YAAI,QAAQ,WAAW;AACrB,sBAAY;AACZ,qBAAW,GAAG,OAAO;AAAA,QACvB;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,iBAAiB,CAAC,YAAY;AAC5B,UAAM,EAAE,MAAM,QAAQ,SAAS,gBAAgB,IAAI;AACnD,QAAI,gBAAgB,WAAW,EAAG,QAAO;AAEzC,UAAM,UAAU,kBAAkB,IAAI;AACtC,UAAM,UAAU,KAAK,MAAM,MAAM;AACjC,UAAM,YAAY,KAAK;AAAA,MACrB,KAAK,MAAM,MAAM,WAAW,KAAK;AAAA,MACjC;AAAA,IACF;AAEA,QAAI,YAAY;AAChB,QAAI,gBAAgC,gBAAgB,CAAC;AAErD,eAAW,aAAa,iBAAiB;AACvC,YAAM,aAAa,kBAAkB,SAAS,QAAQ,WAAW,OAAO;AACxE,UAAI,CAAC,WAAY;AAEjB,YAAM,QAAQ;AAAA,QACZ;AAAA,QACA,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,UAAI,QAAQ,WAAW;AACrB,oBAAY;AACZ,wBAAgB;AAAA,MAClB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;AAcO,IAAM,cAAc,CACzB,QACA,MACA,aACc;AACd,QAAM,SAAS,KAAK,WAAW;AAC/B,QAAM,SAAS,KAAK,WAAW;AAE/B,MAAI,WAAW,cAAc;AAC3B,UAAM,oBAAoB,KAAK,gBAAgB,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM;AACtE,UAAM,aAAa,SAAS,aAAa;AAAA,MACvC;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,WAAO,OAAO,aAAa,EAAE,MAAM,QAAQ,WAAW,CAAC;AAAA,EACzD;AAEA,MAAI,WAAW,eAAe;AAC5B,UAAM,EAAE,MAAM,OAAO,IAAI,iBAAiB,MAAM,MAAM;AACtD,QAAI,CAAC,MAAM,gBAAgB,CAAC,QAAQ;AAClC,aAAO,OAAO,cAAc,EAAE,MAAM,OAAO,CAAC;AAAA,IAC9C;AAEA,UAAM,SAAS,KAAK;AACpB,UAAM,UAAU,OAAO;AACvB,UAAM,UAAU,kBAAkB,IAAI;AACtC,UAAM,kBAAkB,0BAA0B,SAAS,QAAQ,OAAO;AAE1E,UAAM,YAAY,SAAS,gBAAgB;AAAA,MACzC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,QAAI,CAAC,WAAW;AACd,aAAO,OAAO,cAAc,EAAE,MAAM,OAAO,CAAC;AAAA,IAC9C;AAEA,WAAO,OAAO,YAAY;AAAA,MACxB;AAAA,MACA;AAAA,MACA,UAAU,UAAU;AAAA,MACpB,UAAU,UAAU;AAAA,IACtB,CAAC;AAAA,EACH;AAGA,MAAI,WAAW,cAAc;AAE3B,UAAM,SAAS,KAAK,QAAQ,KAAK,CAAC,MAAM;AACtC,YAAM,OAAO,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM;AACnD,aAAO,QAAQ,EAAE,OAAO,KAAK;AAAA,IAC/B,CAAC;AACD,QAAI,QAAQ;AACV,YAAM,kBAAkB;AAAA,QACtB,OAAO;AAAA,QACP,OAAO,UAAU,CAAC;AAAA,MACpB;AACA,UAAI,gBAAgB,SAAS,GAAG;AAE9B,eAAO,OAAO,WAAW;AAAA,UACvB;AAAA,UACA;AAAA,UACA,UAAU,gBAAgB,CAAC;AAAA,QAC7B,CAAC;AAAA,MACH;AAAA,IACF;AACA,WAAO,OAAO,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAAA,EACnD;AAGA,MACE,WAAW,iBACX,WAAW,uBACX,WAAW,eACX,WAAW,oBACX,WAAW,oBACX,WAAW,aACX;AACA,WAAO,OAAO,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAAA,EACnD;AAGA,SAAO,OAAO,cAAc,EAAE,MAAM,OAAO,CAAC;AAC9C;AAOO,IAAM,YAAY,CAAC,SAAsC;AAC9D,QAAM,SAAS,KAAK,WAAW;AAC/B,QAAM,OAAO,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM;AACnD,QAAM,SAAS,OACX,KAAK,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK,QAAQ,IAC/C;AACJ,SAAO,CAAC,CAAC,QAAQ;AACnB;AAYO,IAAM,eAAe,CAC1B,QACA,MACA,qBACc;AACd,MAAI,UAAU;AAEd,SAAO,qBAAqB,OAAO,KAAK,UAAU,OAAO,GAAG;AAC1D,UAAM,SAAS,QAAQ,WAAW;AAClC,UAAM,OAAO,QAAQ,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM;AACtD,UAAM,SAAS,OACX,QAAQ,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK,QAAQ,IAClD;AACJ,UAAM,eAAe,QAAQ,KAAK,gBAAgB;AAClD,UAAM,WACJ,YAAY,cAAc,gBAAgB,KAAK;AACjD,cAAU,YAAY,QAAQ,SAAS,QAAQ;AAAA,EACjD;AAEA,SAAO;AACT;;;ACpjBO,IAAM,kBAAkB,CAAC,YAAmC;AAAA,EACjE;AAAA,EACA,SAAS,CAAC;AACZ;AAKO,IAAM,eAAe,CAC1B,KACA,WACmB;AAAA,EACnB,GAAG;AAAA,EACH,SAAS;AAAA,IACP,GAAG,IAAI;AAAA,IACP;AAAA,MACE,GAAG;AAAA,MACH,IAAI,IAAI,QAAQ;AAAA,MAChB,WAAW,KAAK,IAAI;AAAA,IACtB;AAAA,EACF;AACF;AAOO,IAAM,aAAa,CAAC,QACzB,IAAI;AAKC,IAAM,mBAAmB,CAC9B,KACA,SAC2B,IAAI,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,IAAI;AAKjE,IAAM,mBAAmB,CAC9B,KACA,SAC2B,IAAI,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,IAAI;AAmB/D,IAAM,oBAAoB,CAC/B,WACwD;AACxD,MAAI,MAAM,gBAAgB,EAAE;AAE5B,QAAM,SAAS,CACb,QACA,SACA,SACS;AACT,UAAM,aAAa,KAAK,EAAE,QAAQ,SAAS,KAAK,CAAC;AAAA,EACnD;AAEA,QAAM,gBAA4B;AAAA;AAAA,IAEhC,UAAU,CAAC,QAAQ,OAAO,SAAS,GAAG;AAAA,IACtC,eAAe,CAAC,QAAQ,OAAO,cAAc,GAAG;AAAA,IAChD,gBAAgB,CAAC,QAAQ,OAAO,eAAe,GAAG;AAAA,IAClD,oBAAoB,CAAC,QAAQ,OAAO,mBAAmB,GAAG;AAAA,IAC1D,gBAAgB,CAAC,QAAQ,OAAO,eAAe,GAAG;AAAA,IAClD,WAAW,CAAC,QAAQ,OAAO,UAAU,GAAG;AAAA,IACxC,aAAa,CAAC,QAAQ,OAAO,YAAY,GAAG;AAAA,IAC5C,YAAY,CAAC,QAAQ,OAAO,WAAW,GAAG;AAAA,IAC1C,mBAAmB,CAAC,QAAQ,OAAO,kBAAkB,GAAG;AAAA;AAAA,IAGxD,YAAY,CAAC,QAAQ;AACnB,YAAM,OAAO,OAAO,WAAW,GAAG;AAClC,YAAM,gBAAgB,KAAK,EAAE;AAC7B,aAAO,cAAc,EAAE,MAAM,IAAI,MAAM,MAAM,IAAI,KAAK,GAAG,KAAK,IAAI;AAClE,aAAO;AAAA,IACT;AAAA,IAEA,YAAY,CAAC,QAAQ;AACnB,YAAM,OAAO,OAAO,WAAW,GAAG;AAClC,aAAO,cAAc,EAAE,SAAS,IAAI,QAAQ,GAAG,KAAK,IAAI;AACxD,aAAO;AAAA,IACT;AAAA,IAEA,eAAe,CAAC,QAAQ;AACtB,YAAM,OAAO,OAAO,cAAc,GAAG;AACrC,aAAO,iBAAiB,EAAE,YAAY,IAAI,WAAW,GAAG,KAAK,IAAI;AACjE,aAAO;AAAA,IACT;AAAA,IAEA,WAAW,CAAC,QAAQ;AAClB,YAAM,OAAO,OAAO,UAAU,GAAG;AACjC,aAAO,aAAa,CAAC,GAAG,KAAK,IAAI;AACjC,aAAO;AAAA,IACT;AAAA,IAEA,cAAc,CAAC,QAAQ;AACrB,YAAM,OAAO,OAAO,aAAa,GAAG;AACpC;AAAA,QACE;AAAA,QACA,EAAE,QAAQ,IAAI,QAAQ,YAAY,IAAI,WAAW;AAAA,QACjD,KAAK;AAAA,MACP;AACA,aAAO;AAAA,IACT;AAAA,IAEA,aAAa,CAAC,QAAQ;AACpB,YAAM,OAAO,OAAO,YAAY,GAAG;AACnC;AAAA,QACE;AAAA,QACA;AAAA,UACE,QAAQ,IAAI;AAAA,UACZ,UAAU,IAAI;AAAA,UACd,UAAU,IAAI;AAAA,QAChB;AAAA,QACA,KAAK;AAAA,MACP;AACA,aAAO;AAAA,IACT;AAAA,IAEA,eAAe,CAAC,QAAQ;AACtB,YAAM,OAAO,OAAO,cAAc,GAAG;AACrC,aAAO,iBAAiB,EAAE,QAAQ,IAAI,OAAO,GAAG,KAAK,IAAI;AACzD,aAAO;AAAA,IACT;AAAA;AAAA,IAGA,aAAa,CAAC,QAAQ,OAAO,YAAY,GAAG;AAAA,IAC5C,mBAAmB,CAAC,QAAQ,OAAO,kBAAkB,GAAG;AAAA,IACxD,WAAW,CAAC,QAAQ,OAAO,UAAU,GAAG;AAAA,IACxC,oBAAoB,CAAC,QAAQ,OAAO,mBAAmB,GAAG;AAAA;AAAA,IAG1D,gBAAgB,CAAC,QAAQ,OAAO,eAAe,GAAG;AAAA,IAClD,gBAAgB,CAAC,QAAQ,OAAO,eAAe,GAAG;AAAA;AAAA,IAGlD,YAAY,CAAC,QAAQ;AACnB,YAAM,OAAO,OAAO,WAAW,GAAG;AAClC;AAAA,QACE;AAAA,QACA,EAAE,QAAQ,IAAI,QAAQ,UAAU,IAAI,SAAS;AAAA,QAC7C,KAAK;AAAA,MACP;AACA,aAAO;AAAA,IACT;AAAA,IAEA,WAAW,CAAC,QAAQ;AAClB,YAAM,OAAO,OAAO,UAAU,GAAG;AACjC;AAAA,QACE;AAAA,QACA;AAAA,UACE,QAAQ,IAAI;AAAA,UACZ,YAAY,IAAI;AAAA,UAChB,gBAAgB,IAAI;AAAA,UACpB,qBAAqB,IAAI;AAAA,QAC3B;AAAA,QACA,KAAK;AAAA,MACP;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,QAAQ,MAAM;AAAA,EAChB;AACF;AAaO,IAAM,gBAAgB,CAC3B,QACA,QACc;AACd,MAAI,IAAI,QAAQ,WAAW,GAAG;AAC5B,UAAM,IAAI,MAAM,mCAAmC;AAAA,EACrD;AAEA,QAAM,aAAa,IAAI,QAAQ,CAAC;AAChC,MAAI,YAAY,WAAW,cAAc;AACvC,UAAM,IAAI,MAAM,gDAAgD;AAAA,EAClE;AAEA,QAAM,eAAe,WAAW;AAChC,MAAI,OAAkB,OAAO,WAAW;AAAA,IACtC,MAAM,aAAa;AAAA,IACnB,MAAM,aAAa;AAAA,EACrB,CAAC;AAED,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,QAAQ,KAAK;AAC3C,UAAM,QAAQ,IAAI,QAAQ,CAAC;AAC3B,QAAI,CAAC,MAAO;AAEZ,YAAQ,MAAM,QAAQ;AAAA,MACpB,KAAK,cAAc;AACjB,cAAM,UAAU,MAAM;AACtB,eAAO,OAAO,WAAW,EAAE,MAAM,QAAQ,MAAM,MAAM,QAAQ,KAAK,CAAC;AACnE;AAAA,MACF;AAAA,MACA,KAAK,cAAc;AACjB,cAAM,UAAU,MAAM;AACtB,eAAO,OAAO,WAAW,EAAE,MAAM,SAAS,QAAQ,QAAQ,CAAC;AAC3D;AAAA,MACF;AAAA,MACA,KAAK,iBAAiB;AACpB,cAAM,UAAU,MAAM;AACtB,eAAO,OAAO,cAAc;AAAA,UAC1B;AAAA,UACA,YAAY,QAAQ;AAAA,QACtB,CAAC;AACD;AAAA,MACF;AAAA,MACA,KAAK,aAAa;AAChB,eAAO,OAAO,UAAU,EAAE,KAAK,CAAC;AAChC;AAAA,MACF;AAAA,MACA,KAAK,gBAAgB;AACnB,cAAM,UAAU,MAAM;AACtB,eAAO,OAAO,aAAa;AAAA,UACzB;AAAA,UACA,QAAQ,QAAQ;AAAA,UAChB,YAAY,QAAQ;AAAA,QACtB,CAAC;AACD;AAAA,MACF;AAAA,MACA,KAAK,eAAe;AAClB,cAAM,UAAU,MAAM;AACtB,eAAO,OAAO,YAAY;AAAA,UACxB;AAAA,UACA,QAAQ,QAAQ;AAAA,UAChB,UAAU,QAAQ;AAAA,UAClB,UAAU,QAAQ;AAAA,QACpB,CAAC;AACD;AAAA,MACF;AAAA,MACA,KAAK,iBAAiB;AACpB,cAAM,UAAU,MAAM;AACtB,eAAO,OAAO,cAAc;AAAA,UAC1B;AAAA,UACA,QAAQ,QAAQ;AAAA,QAClB,CAAC;AACD;AAAA,MACF;AAAA,MACA,KAAK,cAAc;AACjB,cAAM,UAAU,MAAM;AACtB,eAAO,OAAO,WAAW;AAAA,UACvB;AAAA,UACA,QAAQ,QAAQ;AAAA,UAChB,UAAU,QAAQ;AAAA,QACpB,CAAC;AACD;AAAA,MACF;AAAA,MACA,KAAK,aAAa;AAChB,cAAM,UAAU,MAAM;AACtB,eAAO,OAAO,UAAU;AAAA,UACtB;AAAA,UACA,QAAQ,QAAQ;AAAA,UAChB,YAAY,QAAQ;AAAA,UACpB,gBAAgB,QAAQ;AAAA,UACxB,qBAAqB,QAAQ;AAAA,QAC/B,CAAC;AACD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;ACjWO,IAAM,oBAAoB,CAAC,kBAA0C;AAAA,EAC1E,SAAS;AAAA,EACT,MAAM,CAAC;AAAA,EACP,QAAQ,CAAC;AACX;AAWO,IAAM,YAAY,CACvB,SACA,cACiB;AAAA,EACjB,SAAS;AAAA,EACT,MAAM,CAAC,GAAG,QAAQ,MAAM,QAAQ,OAAO;AAAA,EACvC,QAAQ,CAAC;AACX;AAUO,IAAM,OAAO,CAAC,YAAsC;AACzD,MAAI,QAAQ,KAAK,WAAW,GAAG;AAC7B,UAAM,IAAI,UAAU;AAAA,EACtB;AAEA,QAAM,WAAW,QAAQ,KAAK,QAAQ,KAAK,SAAS,CAAC;AACrD,SAAO;AAAA,IACL,SAAS;AAAA,IACT,MAAM,QAAQ,KAAK,MAAM,GAAG,EAAE;AAAA,IAC9B,QAAQ,CAAC,GAAG,QAAQ,QAAQ,QAAQ,OAAO;AAAA,EAC7C;AACF;AAUO,IAAM,OAAO,CAAC,YAAsC;AACzD,MAAI,QAAQ,OAAO,WAAW,GAAG;AAC/B,UAAM,IAAI,UAAU;AAAA,EACtB;AAEA,QAAM,OAAO,QAAQ,OAAO,QAAQ,OAAO,SAAS,CAAC;AACrD,SAAO;AAAA,IACL,SAAS;AAAA,IACT,MAAM,CAAC,GAAG,QAAQ,MAAM,QAAQ,OAAO;AAAA,IACvC,QAAQ,QAAQ,OAAO,MAAM,GAAG,EAAE;AAAA,EACpC;AACF;AAKO,IAAM,UAAU,CAAC,YACtB,QAAQ,KAAK,SAAS;AAKjB,IAAM,UAAU,CAAC,YACtB,QAAQ,OAAO,SAAS;AAQnB,IAAM,eAAe,CAAC,aAAuC;AAAA,EAClE,SAAS,QAAQ;AAAA,EACjB,MAAM,CAAC;AAAA,EACP,QAAQ,CAAC;AACX;AAKO,IAAM,iBAAiB,CAC5B,aACsC;AAAA,EACtC,MAAM,QAAQ,KAAK;AAAA,EACnB,QAAQ,QAAQ,OAAO;AACzB;;;ACRO,IAAM,mBAAmB,CAAC,WAA8C;AAC7E,QAAM;AAAA,IACJ,mBAAAC;AAAA,IACA,iBAAAC;AAAA,IACA,sBAAAC;AAAA,IACA,mBAAAC;AAAA,IACA,sBAAAC;AAAA,IACA,kBAAAC;AAAA,IACA,qBAAAC;AAAA,IACA,oBAAAC;AAAA,IACA,sBAAAC;AAAA,IACA,kBAAAC;AAAA,IACA,uBAAAC;AAAA,IACA,2BAAAC;AAAA,IACA,uBAAAC;AAAA,IACA,sBAAAC;AAAA,IACA,wBAAAC;AAAA,IACA,yBAAAC;AAAA,IACA,mBAAAC;AAAA,IACA,kBAAAC;AAAA,IACA,oBAAAC;AAAA,IACA,0BAAAC;AAAA,IACA,kBAAAC;AAAA,IACA,uBAAAC;AAAA,IACA,uBAAAC;AAAA,IACA,2BAAAC;AAAA,EACF,IAAI,gBAAgB,MAAM;AAE1B,MAAI,SAAqB;AAAA,IACvB,UAAU,CAAC,YAAYtB,iBAAgB,OAAO;AAAA,IAC9C,eAAe,CAAC,YAAYC,sBAAqB,OAAO;AAAA,IACxD,YAAY,CAAC,YAAYF,mBAAkB,OAAO;AAAA,IAClD,YAAY,CAAC,YAAYG,mBAAkB,OAAO;AAAA,IAClD,eAAe,CAAC,YAAYC,sBAAqB,OAAO;AAAA,IACxD,WAAW,CAAC,YAAYC,kBAAiB,OAAO;AAAA,IAChD,cAAc,CAAC,YAAYC,qBAAoB,OAAO;AAAA,IACtD,aAAa,CAAC,YAAYC,oBAAmB,OAAO;AAAA,IACpD,eAAe,CAAC,YAAYC,sBAAqB,OAAO;AAAA,IACxD,YAAY,CAAC,YAAYC,kBAAiB,OAAO;AAAA,IACjD,gBAAgB,CAAC,YAAYC,uBAAsB,OAAO;AAAA,IAC1D,oBAAoB,CAAC,YAAYC,2BAA0B,OAAO;AAAA,IAClE,gBAAgB,CAAC,YAAYC,uBAAsB,OAAO;AAAA,IAC1D,WAAW,CAAC,YAAYC,sBAAqB,OAAO;AAAA,IACpD,aAAa,CAAC,YAAYC,wBAAuB,OAAO;AAAA,IACxD,mBAAmB,CAAC,YAAYC,yBAAwB,OAAO;AAAA,IAC/D,YAAY,CAAC,YAAYC,mBAAkB,OAAO;AAAA,IAClD,WAAW,CAAC,YAAYC,kBAAiB,OAAO;AAAA,IAChD,aAAa,CAAC,YAAYC,oBAAmB,OAAO;AAAA,IACpD,mBAAmB,CAAC,YAAYC,0BAAyB,OAAO;AAAA,IAChE,WAAW,CAAC,YAAYC,kBAAiB,OAAO;AAAA,IAChD,gBAAgB,CAAC,YAAYC,uBAAsB,OAAO;AAAA,IAC1D,gBAAgB,CAAC,YAAYC,uBAAsB,OAAO;AAAA,IAC1D,oBAAoB,CAAC,YAAYC,2BAA0B,OAAO;AAAA,EACpE;AAEA,MAAI,OAAO,QAAQ;AACjB,aAAS,eAAe,QAAQ,OAAO,MAAM;AAAA,EAC/C;AAEA,MAAI,OAAO,OAAO;AAChB,UAAM,eACJ,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ;AACpD,aAAS,cAAc,QAAQ,YAAY;AAAA,EAC7C;AAEA,SAAO;AACT;","names":["err","durationMs","getResultUseCase","calculateScoreUseCase","result","shuffleMethod","ORIGINS_MODE_PREFIX","uuidMethod","shuffleMethod","lord","next","uuidMethod","shuffleMethod","getBoundingBox","currentPlayer","uuidMethod","shuffleMethod","createGameHandler","getModesHandler","getExtraRulesHandler","addPlayersHandler","addExtraRulesHandler","startGameHandler","chooseDominoHandler","placeDominoHandler","discardDominoHandler","getResultHandler","calculateScoreHandler","getValidPlacementsHandler","canPlaceDominoHandler","serializeGameHandler","deserializeGameHandler","getDynastyResultHandler","placeGiantHandler","sendGiantHandler","placeKnightHandler","constructBuildingHandler","useDragonHandler","placeFireTokenHandler","recruitCavemanHandler","skipOptionalActionHandler"]}