@vue-skuilder/courseware 0.1.40 → 0.2.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/chess-BVYo88i5.cjs +1 -0
- package/dist/{chess-BsgVZARV.cjs → chess-BWes0jGA.cjs} +2 -2
- package/dist/{chess-BsgVZARV.cjs.map → chess-BWes0jGA.cjs.map} +1 -1
- package/dist/{chess-BbHATAzk.js → chess-E2uOAyQS.js} +10 -8
- package/dist/{chess-BbHATAzk.js.map → chess-E2uOAyQS.js.map} +1 -1
- package/dist/{chess-X1bmWmh3.js → chess-Lfm7Fsvs.js} +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.mjs +2 -2
- package/package.json +5 -5
- package/dist/chess-C_2RQEuq.cjs +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chess-BbHATAzk.js","names":["swapColor"],"sources":["../src/chess/chessground/types.ts","../src/chess/chessground/util.ts","../src/chess/chessground/premove.ts","../src/chess/chessground/board.ts","../src/chess/chessground/fen.ts","../src/chess/chessground/config.ts","../src/chess/chessground/anim.ts","../src/chess/chessground/draw.ts","../src/chess/chessground/drag.ts","../src/chess/chessground/explosion.ts","../src/chess/chessground/api.ts","../src/chess/chessground/state.ts","../src/chess/chessground/svg.ts","../src/chess/chessground/wrap.ts","../src/chess/chessground/drop.ts","../src/chess/chessground/events.ts","../src/chess/chessground/render.ts","../src/chess/chessground/sync.ts","../src/chess/chessground/autoPieces.ts","../src/chess/chessground/chessground.ts","../../../node_modules/chess.js/dist/esm/chess.js","../src/chess/composables/useChessgroundBounds.ts","../src/chess/questions/puzzle/puzzle.vue","../src/chess/questions/puzzle/puzzle.vue","../src/chess/questions/puzzle/index.ts","../src/chess/index.ts"],"sourcesContent":["export type Color = (typeof colors)[number];\nexport type Role = 'king' | 'queen' | 'rook' | 'bishop' | 'knight' | 'pawn';\nexport type File = (typeof files)[number];\nexport type Rank = (typeof ranks)[number];\nexport type Key = 'a0' | 'a1' | 'a2' | 'a3' | 'a4' | 'a5' | 'a6' | 'a7' | 'a8' |\n 'b1' | 'b2' | 'b3' | 'b4' | 'b5' | 'b6' | 'b7' | 'b8' |\n 'c1' | 'c2' | 'c3' | 'c4' | 'c5' | 'c6' | 'c7' | 'c8' |\n 'd1' | 'd2' | 'd3' | 'd4' | 'd5' | 'd6' | 'd7' | 'd8' |\n 'e1' | 'e2' | 'e3' | 'e4' | 'e5' | 'e6' | 'e7' | 'e8' |\n 'f1' | 'f2' | 'f3' | 'f4' | 'f5' | 'f6' | 'f7' | 'f8' |\n 'g1' | 'g2' | 'g3' | 'g4' | 'g5' | 'g6' | 'g7' | 'g8' |\n 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'h7' | 'h8';\nexport type FEN = string;\nexport type Pos = [number, number];\nexport interface Piece {\n role: Role;\n color: Color;\n promoted?: boolean;\n}\nexport interface Drop {\n role: Role;\n key: Key;\n}\nexport type Pieces = Map<Key, Piece>;\nexport type PiecesDiff = Map<Key, Piece | undefined>;\n\nexport type KeyPair = [Key, Key];\n\nexport type NumberPair = [number, number];\n\nexport type NumberQuad = [number, number, number, number];\n\nexport interface Rect {\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\nexport type Dests = Map<Key, Key[]>;\n\nexport interface Elements {\n board: HTMLElement;\n wrap: HTMLElement;\n container: HTMLElement;\n ghost?: HTMLElement;\n svg?: SVGElement;\n customSvg?: SVGElement;\n autoPieces?: HTMLElement;\n}\nexport interface Dom {\n elements: Elements;\n bounds: Memo<DOMRectReadOnly>;\n redraw: () => void;\n redrawNow: (skipSvg?: boolean) => void;\n unbind?: Unbind;\n destroyed?: boolean;\n}\nexport interface Exploding {\n stage: number;\n keys: readonly Key[];\n}\n\nexport interface MoveMetadata {\n premove: boolean;\n ctrlKey?: boolean;\n holdTime?: number;\n captured?: Piece;\n predrop?: boolean;\n}\nexport interface SetPremoveMetadata {\n ctrlKey?: boolean;\n}\n\nexport type MouchEvent = Event & Partial<MouseEvent & TouchEvent>;\n\nexport interface KeyedNode extends HTMLElement {\n cgKey: Key;\n}\nexport interface PieceNode extends KeyedNode {\n tagName: 'PIECE';\n cgPiece: string;\n cgAnimating?: boolean;\n cgFading?: boolean;\n cgDragging?: boolean;\n cgScale?: number;\n}\nexport interface SquareNode extends KeyedNode {\n tagName: 'SQUARE';\n}\n\nexport interface Memo<A> {\n (): A;\n clear: () => void;\n}\n\nexport interface Timer {\n start: () => void;\n cancel: () => void;\n stop: () => number;\n}\n\nexport type Redraw = () => void;\nexport type Unbind = () => void;\nexport type Milliseconds = number;\nexport type KHz = number;\n\nexport const colors = ['cg-white', 'cg-black'] as const;\nexport const files = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] as const;\nexport const ranks = ['1', '2', '3', '4', '5', '6', '7', '8'] as const;\n\nexport type RanksPosition = 'left' | 'right';\n\nexport type BrushColor = 'green' | 'red' | 'blue' | 'yellow';\n\nexport type SquareClasses = Map<Key, string>;\n","import * as cg from './types';\n\nexport const invRanks: readonly cg.Rank[] = [...cg.ranks].reverse();\n\nexport const allKeys: readonly cg.Key[] = Array.prototype.concat(\n ...cg.files.map(c => cg.ranks.map(r => c + r)),\n);\n\nexport const pos2key = (pos: cg.Pos): cg.Key => allKeys[8 * pos[0] + pos[1]];\n\nexport const key2pos = (k: cg.Key): cg.Pos => [k.charCodeAt(0) - 97, k.charCodeAt(1) - 49];\n\nexport const uciToMove = (uci: string | undefined): cg.Key[] | undefined => {\n if (!uci) return undefined;\n if (uci[1] === '@') return [uci.slice(2, 4) as cg.Key];\n return [uci.slice(0, 2), uci.slice(2, 4)] as cg.Key[];\n};\n\nexport const allPos: readonly cg.Pos[] = allKeys.map(key2pos);\n\nexport function memo<A>(f: () => A): cg.Memo<A> {\n let v: A | undefined;\n const ret = (): A => {\n if (v === undefined) v = f();\n return v;\n };\n ret.clear = () => {\n v = undefined;\n };\n return ret;\n}\n\nexport const timer = (): cg.Timer => {\n let startAt: number | undefined;\n return {\n start() {\n startAt = performance.now();\n },\n cancel() {\n startAt = undefined;\n },\n stop() {\n if (!startAt) return 0;\n const time = performance.now() - startAt;\n startAt = undefined;\n return time;\n },\n };\n};\n\nexport const opposite = (c: cg.Color): cg.Color => (c === 'cg-white' ? 'cg-black' : 'cg-white');\n\nexport const distanceSq = (pos1: cg.Pos, pos2: cg.Pos): number => {\n const dx = pos1[0] - pos2[0],\n dy = pos1[1] - pos2[1];\n return dx * dx + dy * dy;\n};\n\nexport const samePiece = (p1: cg.Piece, p2: cg.Piece): boolean =>\n p1.role === p2.role && p1.color === p2.color;\n\nexport const posToTranslate =\n (bounds: DOMRectReadOnly): ((pos: cg.Pos, asWhite: boolean) => cg.NumberPair) =>\n (pos, asWhite) => [\n ((asWhite ? pos[0] : 7 - pos[0]) * bounds.width) / 8,\n ((asWhite ? 7 - pos[1] : pos[1]) * bounds.height) / 8,\n ];\n\nexport const translate = (el: HTMLElement, pos: cg.NumberPair): void => {\n el.style.transform = `translate(${pos[0]}px,${pos[1]}px)`;\n};\n\nexport const translateAndScale = (el: HTMLElement, pos: cg.NumberPair, scale = 1): void => {\n el.style.transform = `translate(${pos[0]}px,${pos[1]}px) scale(${scale})`;\n};\n\nexport const setVisible = (el: HTMLElement, v: boolean): void => {\n el.style.visibility = v ? 'visible' : 'hidden';\n};\n\nexport const eventPosition = (e: cg.MouchEvent): cg.NumberPair | undefined => {\n if (e.clientX || e.clientX === 0) return [e.clientX, e.clientY!];\n if (e.targetTouches?.[0]) return [e.targetTouches[0].clientX, e.targetTouches[0].clientY];\n return; // touchend has no position!\n};\n\nexport const isRightButton = (e: cg.MouchEvent): boolean => e.button === 2;\n\nexport const createEl = (tagName: string, className?: string): HTMLElement => {\n const el = document.createElement(tagName);\n if (className) el.className = className;\n return el;\n};\n\nexport function computeSquareCenter(key: cg.Key, asWhite: boolean, bounds: DOMRectReadOnly): cg.NumberPair {\n const pos = key2pos(key);\n if (!asWhite) {\n pos[0] = 7 - pos[0];\n pos[1] = 7 - pos[1];\n }\n return [\n bounds.left + (bounds.width * pos[0]) / 8 + bounds.width / 16,\n bounds.top + (bounds.height * (7 - pos[1])) / 8 + bounds.height / 16,\n ];\n}\n","import * as util from './util';\nimport * as cg from './types';\n\ntype Mobility = (x1: number, y1: number, x2: number, y2: number) => boolean;\n\nconst diff = (a: number, b: number): number => Math.abs(a - b);\n\nconst pawn =\n (color: cg.Color): Mobility =>\n (x1, y1, x2, y2) =>\n diff(x1, x2) < 2 &&\n (color === 'cg-white'\n ? // allow 2 squares from first two ranks, for horde\n y2 === y1 + 1 || (y1 <= 1 && y2 === y1 + 2 && x1 === x2)\n : y2 === y1 - 1 || (y1 >= 6 && y2 === y1 - 2 && x1 === x2));\n\nexport const knight: Mobility = (x1, y1, x2, y2) => {\n const xd = diff(x1, x2);\n const yd = diff(y1, y2);\n return (xd === 1 && yd === 2) || (xd === 2 && yd === 1);\n};\n\nconst bishop: Mobility = (x1, y1, x2, y2) => {\n return diff(x1, x2) === diff(y1, y2);\n};\n\nconst rook: Mobility = (x1, y1, x2, y2) => {\n return x1 === x2 || y1 === y2;\n};\n\nexport const queen: Mobility = (x1, y1, x2, y2) => {\n return bishop(x1, y1, x2, y2) || rook(x1, y1, x2, y2);\n};\n\nconst king =\n (color: cg.Color, rookFiles: number[], canCastle: boolean): Mobility =>\n (x1, y1, x2, y2) =>\n (diff(x1, x2) < 2 && diff(y1, y2) < 2) ||\n (canCastle &&\n y1 === y2 &&\n y1 === (color === 'cg-white' ? 0 : 7) &&\n ((x1 === 4 && ((x2 === 2 && rookFiles.includes(0)) || (x2 === 6 && rookFiles.includes(7)))) ||\n rookFiles.includes(x2)));\n\nfunction rookFilesOf(pieces: cg.Pieces, color: cg.Color) {\n const backrank = color === 'cg-white' ? '1' : '8';\n const files = [];\n for (const [key, piece] of pieces) {\n if (key[1] === backrank && piece.color === color && piece.role === 'rook') {\n files.push(util.key2pos(key)[0]);\n }\n }\n return files;\n}\n\nexport function premove(pieces: cg.Pieces, key: cg.Key, canCastle: boolean): cg.Key[] {\n const piece = pieces.get(key);\n if (!piece) return [];\n const pos = util.key2pos(key),\n r = piece.role,\n mobility: Mobility =\n r === 'pawn'\n ? pawn(piece.color)\n : r === 'knight'\n ? knight\n : r === 'bishop'\n ? bishop\n : r === 'rook'\n ? rook\n : r === 'queen'\n ? queen\n : king(piece.color, rookFilesOf(pieces, piece.color), canCastle);\n return util.allPos\n .filter(pos2 => (pos[0] !== pos2[0] || pos[1] !== pos2[1]) && mobility(pos[0], pos[1], pos2[0], pos2[1]))\n .map(util.pos2key);\n}\n","import { HeadlessState } from './state';\nimport { pos2key, key2pos, opposite, distanceSq, allPos, computeSquareCenter } from './util';\nimport { premove, queen, knight } from './premove';\nimport * as cg from './types';\n\nexport function callUserFunction<T extends (...args: any[]) => void>(\n f: T | undefined,\n ...args: Parameters<T>\n): void {\n if (f) setTimeout(() => f(...args), 1);\n}\n\nexport function toggleOrientation(state: HeadlessState): void {\n state.orientation = opposite(state.orientation);\n state.animation.current = state.draggable.current = state.selected = undefined;\n}\n\nexport function reset(state: HeadlessState): void {\n state.lastMove = undefined;\n unselect(state);\n unsetPremove(state);\n unsetPredrop(state);\n}\n\nexport function setPieces(state: HeadlessState, pieces: cg.PiecesDiff): void {\n for (const [key, piece] of pieces) {\n if (piece) state.pieces.set(key, piece);\n else state.pieces.delete(key);\n }\n}\n\nexport function setCheck(state: HeadlessState, color: cg.Color | boolean): void {\n state.check = undefined;\n if (color === true) color = state.turnColor;\n if (color)\n for (const [k, p] of state.pieces) {\n if (p.role === 'king' && p.color === color) {\n state.check = k;\n }\n }\n}\n\nfunction setPremove(state: HeadlessState, orig: cg.Key, dest: cg.Key, meta: cg.SetPremoveMetadata): void {\n unsetPredrop(state);\n state.premovable.current = [orig, dest];\n callUserFunction(state.premovable.events.set, orig, dest, meta);\n}\n\nexport function unsetPremove(state: HeadlessState): void {\n if (state.premovable.current) {\n state.premovable.current = undefined;\n callUserFunction(state.premovable.events.unset);\n }\n}\n\nfunction setPredrop(state: HeadlessState, role: cg.Role, key: cg.Key): void {\n unsetPremove(state);\n state.predroppable.current = { role, key };\n callUserFunction(state.predroppable.events.set, role, key);\n}\n\nexport function unsetPredrop(state: HeadlessState): void {\n const pd = state.predroppable;\n if (pd.current) {\n pd.current = undefined;\n callUserFunction(pd.events.unset);\n }\n}\n\nfunction tryAutoCastle(state: HeadlessState, orig: cg.Key, dest: cg.Key): boolean {\n if (!state.autoCastle) return false;\n\n const king = state.pieces.get(orig);\n if (!king || king.role !== 'king') return false;\n\n const origPos = key2pos(orig);\n const destPos = key2pos(dest);\n if ((origPos[1] !== 0 && origPos[1] !== 7) || origPos[1] !== destPos[1]) return false;\n if (origPos[0] === 4 && !state.pieces.has(dest)) {\n if (destPos[0] === 6) dest = pos2key([7, destPos[1]]);\n else if (destPos[0] === 2) dest = pos2key([0, destPos[1]]);\n }\n const rook = state.pieces.get(dest);\n if (!rook || rook.color !== king.color || rook.role !== 'rook') return false;\n\n state.pieces.delete(orig);\n state.pieces.delete(dest);\n\n if (origPos[0] < destPos[0]) {\n state.pieces.set(pos2key([6, destPos[1]]), king);\n state.pieces.set(pos2key([5, destPos[1]]), rook);\n } else {\n state.pieces.set(pos2key([2, destPos[1]]), king);\n state.pieces.set(pos2key([3, destPos[1]]), rook);\n }\n return true;\n}\n\nexport function baseMove(state: HeadlessState, orig: cg.Key, dest: cg.Key): cg.Piece | boolean {\n const origPiece = state.pieces.get(orig),\n destPiece = state.pieces.get(dest);\n if (orig === dest || !origPiece) return false;\n const captured = destPiece && destPiece.color !== origPiece.color ? destPiece : undefined;\n if (dest === state.selected) unselect(state);\n callUserFunction(state.events.move, orig, dest, captured);\n if (!tryAutoCastle(state, orig, dest)) {\n state.pieces.set(dest, origPiece);\n state.pieces.delete(orig);\n }\n state.lastMove = [orig, dest];\n state.check = undefined;\n callUserFunction(state.events.change);\n return captured || true;\n}\n\nexport function baseNewPiece(state: HeadlessState, piece: cg.Piece, key: cg.Key, force?: boolean): boolean {\n if (state.pieces.has(key)) {\n if (force) state.pieces.delete(key);\n else return false;\n }\n callUserFunction(state.events.dropNewPiece, piece, key);\n state.pieces.set(key, piece);\n state.lastMove = [key];\n state.check = undefined;\n callUserFunction(state.events.change);\n state.movable.dests = undefined;\n state.turnColor = opposite(state.turnColor);\n return true;\n}\n\nfunction baseUserMove(state: HeadlessState, orig: cg.Key, dest: cg.Key): cg.Piece | boolean {\n const result = baseMove(state, orig, dest);\n if (result) {\n state.movable.dests = undefined;\n state.turnColor = opposite(state.turnColor);\n state.animation.current = undefined;\n }\n return result;\n}\n\nexport function userMove(state: HeadlessState, orig: cg.Key, dest: cg.Key): boolean {\n if (canMove(state, orig, dest)) {\n const result = baseUserMove(state, orig, dest);\n if (result) {\n const holdTime = state.hold.stop();\n unselect(state);\n const metadata: cg.MoveMetadata = {\n premove: false,\n ctrlKey: state.stats.ctrlKey,\n holdTime,\n };\n if (result !== true) metadata.captured = result;\n callUserFunction(state.movable.events.after, orig, dest, metadata);\n return true;\n }\n } else if (canPremove(state, orig, dest)) {\n setPremove(state, orig, dest, {\n ctrlKey: state.stats.ctrlKey,\n });\n unselect(state);\n return true;\n }\n unselect(state);\n return false;\n}\n\nexport function dropNewPiece(state: HeadlessState, orig: cg.Key, dest: cg.Key, force?: boolean): void {\n const piece = state.pieces.get(orig);\n if (piece && (canDrop(state, orig, dest) || force)) {\n state.pieces.delete(orig);\n baseNewPiece(state, piece, dest, force);\n callUserFunction(state.movable.events.afterNewPiece, piece.role, dest, {\n premove: false,\n predrop: false,\n });\n } else if (piece && canPredrop(state, orig, dest)) {\n setPredrop(state, piece.role, dest);\n } else {\n unsetPremove(state);\n unsetPredrop(state);\n }\n state.pieces.delete(orig);\n unselect(state);\n}\n\nexport function selectSquare(state: HeadlessState, key: cg.Key, force?: boolean): void {\n callUserFunction(state.events.select, key);\n if (state.selected) {\n if (state.selected === key && !state.draggable.enabled) {\n unselect(state);\n state.hold.cancel();\n return;\n } else if ((state.selectable.enabled || force) && state.selected !== key) {\n if (userMove(state, state.selected, key)) {\n state.stats.dragged = false;\n return;\n }\n }\n }\n if (\n (state.selectable.enabled || state.draggable.enabled) &&\n (isMovable(state, key) || isPremovable(state, key))\n ) {\n setSelected(state, key);\n state.hold.start();\n }\n}\n\nexport function setSelected(state: HeadlessState, key: cg.Key): void {\n state.selected = key;\n if (isPremovable(state, key)) {\n // calculate chess premoves if custom premoves are not passed\n if (!state.premovable.customDests) {\n state.premovable.dests = premove(state.pieces, key, state.premovable.castle);\n }\n } else state.premovable.dests = undefined;\n}\n\nexport function unselect(state: HeadlessState): void {\n state.selected = undefined;\n state.premovable.dests = undefined;\n state.hold.cancel();\n}\n\nfunction isMovable(state: HeadlessState, orig: cg.Key): boolean {\n const piece = state.pieces.get(orig);\n return (\n !!piece &&\n (state.movable.color === 'both' ||\n (state.movable.color === piece.color && state.turnColor === piece.color))\n );\n}\n\nexport const canMove = (state: HeadlessState, orig: cg.Key, dest: cg.Key): boolean =>\n orig !== dest &&\n isMovable(state, orig) &&\n (state.movable.free || !!state.movable.dests?.get(orig)?.includes(dest));\n\nfunction canDrop(state: HeadlessState, orig: cg.Key, dest: cg.Key): boolean {\n const piece = state.pieces.get(orig);\n return (\n !!piece &&\n (orig === dest || !state.pieces.has(dest)) &&\n (state.movable.color === 'both' ||\n (state.movable.color === piece.color && state.turnColor === piece.color))\n );\n}\n\nfunction isPremovable(state: HeadlessState, orig: cg.Key): boolean {\n const piece = state.pieces.get(orig);\n return (\n !!piece &&\n state.premovable.enabled &&\n state.movable.color === piece.color &&\n state.turnColor !== piece.color\n );\n}\n\nfunction canPremove(state: HeadlessState, orig: cg.Key, dest: cg.Key): boolean {\n const validPremoves: cg.Key[] =\n state.premovable.customDests?.get(orig) ?? premove(state.pieces, orig, state.premovable.castle);\n return orig !== dest && isPremovable(state, orig) && validPremoves.includes(dest);\n}\n\nfunction canPredrop(state: HeadlessState, orig: cg.Key, dest: cg.Key): boolean {\n const piece = state.pieces.get(orig);\n const destPiece = state.pieces.get(dest);\n return (\n !!piece &&\n (!destPiece || destPiece.color !== state.movable.color) &&\n state.predroppable.enabled &&\n (piece.role !== 'pawn' || (dest[1] !== '1' && dest[1] !== '8')) &&\n state.movable.color === piece.color &&\n state.turnColor !== piece.color\n );\n}\n\nexport function isDraggable(state: HeadlessState, orig: cg.Key): boolean {\n const piece = state.pieces.get(orig);\n return (\n !!piece &&\n state.draggable.enabled &&\n (state.movable.color === 'both' ||\n (state.movable.color === piece.color && (state.turnColor === piece.color || state.premovable.enabled)))\n );\n}\n\nexport function playPremove(state: HeadlessState): boolean {\n const move = state.premovable.current;\n if (!move) return false;\n const orig = move[0],\n dest = move[1];\n let success = false;\n if (canMove(state, orig, dest)) {\n const result = baseUserMove(state, orig, dest);\n if (result) {\n const metadata: cg.MoveMetadata = { premove: true };\n if (result !== true) metadata.captured = result;\n callUserFunction(state.movable.events.after, orig, dest, metadata);\n success = true;\n }\n }\n unsetPremove(state);\n return success;\n}\n\nexport function playPredrop(state: HeadlessState, validate: (drop: cg.Drop) => boolean): boolean {\n const drop = state.predroppable.current;\n let success = false;\n if (!drop) return false;\n if (validate(drop)) {\n const piece = {\n role: drop.role,\n color: state.movable.color,\n } as cg.Piece;\n if (baseNewPiece(state, piece, drop.key)) {\n callUserFunction(state.movable.events.afterNewPiece, drop.role, drop.key, {\n premove: false,\n predrop: true,\n });\n success = true;\n }\n }\n unsetPredrop(state);\n return success;\n}\n\nexport function cancelMove(state: HeadlessState): void {\n unsetPremove(state);\n unsetPredrop(state);\n unselect(state);\n}\n\nexport function stop(state: HeadlessState): void {\n state.movable.color = state.movable.dests = state.animation.current = undefined;\n cancelMove(state);\n}\n\nexport function getKeyAtDomPos(\n pos: cg.NumberPair,\n asWhite: boolean,\n bounds: DOMRectReadOnly,\n): cg.Key | undefined {\n let file = Math.floor((8 * (pos[0] - bounds.left)) / bounds.width);\n if (!asWhite) file = 7 - file;\n let rank = 7 - Math.floor((8 * (pos[1] - bounds.top)) / bounds.height);\n if (!asWhite) rank = 7 - rank;\n return file >= 0 && file < 8 && rank >= 0 && rank < 8 ? pos2key([file, rank]) : undefined;\n}\n\nexport function getSnappedKeyAtDomPos(\n orig: cg.Key,\n pos: cg.NumberPair,\n asWhite: boolean,\n bounds: DOMRectReadOnly,\n): cg.Key | undefined {\n const origPos = key2pos(orig);\n const validSnapPos = allPos.filter(\n pos2 =>\n queen(origPos[0], origPos[1], pos2[0], pos2[1]) || knight(origPos[0], origPos[1], pos2[0], pos2[1]),\n );\n const validSnapCenters = validSnapPos.map(pos2 => computeSquareCenter(pos2key(pos2), asWhite, bounds));\n const validSnapDistances = validSnapCenters.map(pos2 => distanceSq(pos, pos2));\n const [, closestSnapIndex] = validSnapDistances.reduce(\n (a, b, index) => (a[0] < b ? a : [b, index]),\n [validSnapDistances[0], 0],\n );\n return pos2key(validSnapPos[closestSnapIndex]);\n}\n\nexport const whitePov = (s: HeadlessState): boolean => s.orientation === 'cg-white';\n","import { pos2key, invRanks } from './util';\nimport * as cg from './types';\n\nexport const initial: cg.FEN = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR';\n\nconst roles: { [letter: string]: cg.Role } = {\n p: 'pawn',\n r: 'rook',\n n: 'knight',\n b: 'bishop',\n q: 'queen',\n k: 'king',\n};\n\nconst letters = {\n pawn: 'p',\n rook: 'r',\n knight: 'n',\n bishop: 'b',\n queen: 'q',\n king: 'k',\n};\n\nexport function read(fen: cg.FEN): cg.Pieces {\n if (fen === 'start') fen = initial;\n const pieces: cg.Pieces = new Map();\n let row = 7,\n col = 0;\n for (const c of fen) {\n switch (c) {\n case ' ':\n case '[':\n return pieces;\n case '/':\n --row;\n if (row < 0) return pieces;\n col = 0;\n break;\n case '~': {\n const piece = pieces.get(pos2key([col - 1, row]));\n if (piece) piece.promoted = true;\n break;\n }\n default: {\n const nb = c.charCodeAt(0);\n if (nb < 57) col += nb - 48;\n else {\n const role = c.toLowerCase();\n pieces.set(pos2key([col, row]), {\n role: roles[role],\n color: c === role ? 'cg-black' : 'cg-white',\n });\n ++col;\n }\n }\n }\n }\n return pieces;\n}\n\nexport function write(pieces: cg.Pieces): cg.FEN {\n return invRanks\n .map(y =>\n cg.files\n .map(x => {\n const piece = pieces.get((x + y) as cg.Key);\n if (piece) {\n let p = letters[piece.role];\n if (piece.color === 'cg-white') p = p.toUpperCase();\n if (piece.promoted) p += '~';\n return p;\n } else return '1';\n })\n .join(''),\n )\n .join('/')\n .replace(/1{2,}/g, s => s.length.toString());\n}\n","import { HeadlessState } from './state';\nimport { setCheck, setSelected } from './board';\nimport { read as fenRead } from './fen';\nimport { DrawShape, DrawBrushes } from './draw';\nimport * as cg from './types';\n\nexport interface Config {\n fen?: cg.FEN; // chess position in Forsyth notation\n orientation?: cg.Color; // board orientation. white | black\n turnColor?: cg.Color; // turn to play. white | black\n check?: cg.Color | boolean; // true for current color, false to unset\n lastMove?: cg.Key[]; // squares part of the last move [\"c3\", \"c4\"]\n selected?: cg.Key; // square currently selected \"a1\"\n coordinates?: boolean; // include coords attributes\n coordinatesOnSquares?: boolean; // include coords attributes on every square\n autoCastle?: boolean; // immediately complete the castle by moving the rook after king move\n viewOnly?: boolean; // don't bind events: the user will never be able to move pieces around\n disableContextMenu?: boolean; // because who needs a context menu on a chessboard\n addPieceZIndex?: boolean; // adds z-index values to pieces (for 3D)\n addDimensionsCssVarsTo?: HTMLElement; // add ---cg-width and ---cg-height CSS vars containing the board's dimensions to this element\n blockTouchScroll?: boolean; // block scrolling via touch dragging on the board, e.g. for coordinate training\n // pieceKey: boolean; // add a data-key attribute to piece elements\n trustAllEvents?: boolean; // disable checking for human only input (e.isTrusted)\n highlight?: {\n lastMove?: boolean; // add last-move class to squares\n check?: boolean; // add check class to squares\n custom?: cg.SquareClasses; // add custom classes to custom squares\n };\n animation?: {\n enabled?: boolean;\n duration?: number;\n };\n movable?: {\n free?: boolean; // all moves are valid - board editor\n color?: cg.Color | 'both'; // color that can move. white | black | both | undefined\n dests?: cg.Dests; // valid moves. {\"a2\" [\"a3\" \"a4\"] \"b1\" [\"a3\" \"c3\"]}\n showDests?: boolean; // whether to add the move-dest class on squares\n events?: {\n after?: (orig: cg.Key, dest: cg.Key, metadata: cg.MoveMetadata) => void; // called after the move has been played\n afterNewPiece?: (role: cg.Role, key: cg.Key, metadata: cg.MoveMetadata) => void; // called after a new piece is dropped on the board\n };\n rookCastle?: boolean; // castle by moving the king to the rook\n };\n premovable?: {\n enabled?: boolean; // allow premoves for color that can not move\n showDests?: boolean; // whether to add the premove-dest class on squares\n castle?: boolean; // whether to allow king castle premoves\n dests?: cg.Key[]; // premove destinations for the current selection\n customDests?: cg.Dests; // use custom valid premoves. {\"a2\" [\"a3\" \"a4\"] \"b1\" [\"a3\" \"c3\"]}\n events?: {\n set?: (orig: cg.Key, dest: cg.Key, metadata?: cg.SetPremoveMetadata) => void; // called after the premove has been set\n unset?: () => void; // called after the premove has been unset\n };\n };\n predroppable?: {\n enabled?: boolean; // allow predrops for color that can not move\n events?: {\n set?: (role: cg.Role, key: cg.Key) => void; // called after the predrop has been set\n unset?: () => void; // called after the predrop has been unset\n };\n };\n draggable?: {\n enabled?: boolean; // allow moves & premoves to use drag'n drop\n distance?: number; // minimum distance to initiate a drag; in pixels\n autoDistance?: boolean; // lets chessground set distance to zero when user drags pieces\n showGhost?: boolean; // show ghost of piece being dragged\n deleteOnDropOff?: boolean; // delete a piece when it is dropped off the board\n };\n selectable?: {\n // disable to enforce dragging over click-click move\n enabled?: boolean;\n };\n events?: {\n change?: () => void; // called after the situation changes on the board\n // called after a piece has been moved.\n // capturedPiece is undefined or like {color: 'cg-white'; 'role': 'queen'}\n move?: (orig: cg.Key, dest: cg.Key, capturedPiece?: cg.Piece) => void;\n dropNewPiece?: (piece: cg.Piece, key: cg.Key) => void;\n select?: (key: cg.Key) => void; // called when a square is selected\n insert?: (elements: cg.Elements) => void; // when the board DOM has been (re)inserted\n };\n drawable?: {\n enabled?: boolean; // can draw\n visible?: boolean; // can view\n defaultSnapToValidMove?: boolean;\n // false to keep the drawing if a movable piece is clicked.\n // Clicking an empty square or immovable piece will clear the drawing regardless.\n eraseOnClick?: boolean;\n shapes?: DrawShape[];\n autoShapes?: DrawShape[];\n brushes?: DrawBrushes;\n onChange?: (shapes: DrawShape[]) => void; // called after drawable shapes change\n };\n}\n\nexport function applyAnimation(state: HeadlessState, config: Config): void {\n if (config.animation) {\n deepMerge(state.animation, config.animation);\n // no need for such short animations\n if ((state.animation.duration || 0) < 70) state.animation.enabled = false;\n }\n}\n\nexport function configure(state: HeadlessState, config: Config): void {\n // don't merge destinations and autoShapes. Just override.\n if (config.movable?.dests) state.movable.dests = undefined;\n if (config.drawable?.autoShapes) state.drawable.autoShapes = [];\n\n deepMerge(state, config);\n\n // if a fen was provided, replace the pieces\n if (config.fen) {\n state.pieces = fenRead(config.fen);\n state.drawable.shapes = config.drawable?.shapes || [];\n }\n\n // apply config values that could be undefined yet meaningful\n if ('check' in config) setCheck(state, config.check || false);\n if ('lastMove' in config && !config.lastMove) state.lastMove = undefined;\n // in case of ZH drop last move, there's a single square.\n // if the previous last move had two squares,\n // the merge algorithm will incorrectly keep the second square.\n else if (config.lastMove) state.lastMove = config.lastMove;\n\n // fix move/premove dests\n if (state.selected) setSelected(state, state.selected);\n\n applyAnimation(state, config);\n\n if (!state.movable.rookCastle && state.movable.dests) {\n const rank = state.movable.color === 'cg-white' ? '1' : '8',\n kingStartPos = ('e' + rank) as cg.Key,\n dests = state.movable.dests.get(kingStartPos),\n king = state.pieces.get(kingStartPos);\n if (!dests || !king || king.role !== 'king') return;\n state.movable.dests.set(\n kingStartPos,\n dests.filter(\n d =>\n !(d === 'a' + rank && dests.includes(('c' + rank) as cg.Key)) &&\n !(d === 'h' + rank && dests.includes(('g' + rank) as cg.Key)),\n ),\n );\n }\n}\n\nfunction deepMerge(base: any, extend: any): void {\n for (const key in extend) {\n if (Object.prototype.hasOwnProperty.call(extend, key)) {\n if (\n Object.prototype.hasOwnProperty.call(base, key) &&\n isPlainObject(base[key]) &&\n isPlainObject(extend[key])\n )\n deepMerge(base[key], extend[key]);\n else base[key] = extend[key];\n }\n }\n}\n\nfunction isPlainObject(o: unknown): boolean {\n if (typeof o !== 'object' || o === null) return false;\n const proto = Object.getPrototypeOf(o);\n return proto === Object.prototype || proto === null;\n}\n","import { State } from './state';\nimport * as util from './util';\nimport * as cg from './types';\n\nexport type Mutation<A> = (state: State) => A;\n\n// 0,1 animation goal\n// 2,3 animation current status\nexport type AnimVector = cg.NumberQuad;\n\nexport type AnimVectors = Map<cg.Key, AnimVector>;\n\nexport type AnimFadings = Map<cg.Key, cg.Piece>;\n\nexport interface AnimPlan {\n anims: AnimVectors;\n fadings: AnimFadings;\n}\n\nexport interface AnimCurrent {\n start: DOMHighResTimeStamp;\n frequency: cg.KHz;\n plan: AnimPlan;\n}\n\nexport const anim = <A>(mutation: Mutation<A>, state: State): A =>\n state.animation.enabled ? animate(mutation, state) : render(mutation, state);\n\nexport function render<A>(mutation: Mutation<A>, state: State): A {\n const result = mutation(state);\n state.dom.redraw();\n return result;\n}\n\ninterface AnimPiece {\n key: cg.Key;\n pos: cg.Pos;\n piece: cg.Piece;\n}\ntype AnimPieces = Map<cg.Key, AnimPiece>;\n\nconst makePiece = (key: cg.Key, piece: cg.Piece): AnimPiece => ({\n key: key,\n pos: util.key2pos(key),\n piece: piece,\n});\n\nconst closer = (piece: AnimPiece, pieces: AnimPiece[]): AnimPiece | undefined =>\n pieces.sort((p1, p2) => util.distanceSq(piece.pos, p1.pos) - util.distanceSq(piece.pos, p2.pos))[0];\n\nfunction computePlan(prevPieces: cg.Pieces, current: State): AnimPlan {\n const anims: AnimVectors = new Map(),\n animedOrigs: cg.Key[] = [],\n fadings: AnimFadings = new Map(),\n missings: AnimPiece[] = [],\n news: AnimPiece[] = [],\n prePieces: AnimPieces = new Map();\n let curP: cg.Piece | undefined, preP: AnimPiece | undefined, vector: cg.NumberPair;\n for (const [k, p] of prevPieces) {\n prePieces.set(k, makePiece(k, p));\n }\n for (const key of util.allKeys) {\n curP = current.pieces.get(key);\n preP = prePieces.get(key);\n if (curP) {\n if (preP) {\n if (!util.samePiece(curP, preP.piece)) {\n missings.push(preP);\n news.push(makePiece(key, curP));\n }\n } else news.push(makePiece(key, curP));\n } else if (preP) missings.push(preP);\n }\n for (const newP of news) {\n preP = closer(\n newP,\n missings.filter(p => util.samePiece(newP.piece, p.piece)),\n );\n if (preP) {\n vector = [preP.pos[0] - newP.pos[0], preP.pos[1] - newP.pos[1]];\n anims.set(newP.key, vector.concat(vector) as AnimVector);\n animedOrigs.push(preP.key);\n }\n }\n for (const p of missings) {\n if (!animedOrigs.includes(p.key)) fadings.set(p.key, p.piece);\n }\n\n return {\n anims: anims,\n fadings: fadings,\n };\n}\n\nfunction step(state: State, now: DOMHighResTimeStamp): void {\n const cur = state.animation.current;\n if (cur === undefined) {\n // animation was canceled :(\n if (!state.dom.destroyed) state.dom.redrawNow();\n return;\n }\n const rest = 1 - (now - cur.start) * cur.frequency;\n if (rest <= 0) {\n state.animation.current = undefined;\n state.dom.redrawNow();\n } else {\n const ease = easing(rest);\n for (const cfg of cur.plan.anims.values()) {\n cfg[2] = cfg[0] * ease;\n cfg[3] = cfg[1] * ease;\n }\n state.dom.redrawNow(true); // optimisation: don't render SVG changes during animations\n requestAnimationFrame((now = performance.now()) => step(state, now));\n }\n}\n\nfunction animate<A>(mutation: Mutation<A>, state: State): A {\n // clone state before mutating it\n const prevPieces: cg.Pieces = new Map(state.pieces);\n\n const result = mutation(state);\n const plan = computePlan(prevPieces, state);\n if (plan.anims.size || plan.fadings.size) {\n const alreadyRunning = state.animation.current && state.animation.current.start;\n state.animation.current = {\n start: performance.now(),\n frequency: 1 / state.animation.duration,\n plan: plan,\n };\n if (!alreadyRunning) step(state, performance.now());\n } else {\n // don't animate, just render right away\n state.dom.redraw();\n }\n return result;\n}\n\n// https://gist.github.com/gre/1650294\nconst easing = (t: number): number => (t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1);\n","import { State } from './state';\nimport { unselect, cancelMove, getKeyAtDomPos, getSnappedKeyAtDomPos, whitePov } from './board';\nimport { eventPosition, isRightButton } from './util';\nimport * as cg from './types';\n\nexport interface DrawShape {\n orig: cg.Key;\n dest?: cg.Key;\n brush?: string; // if no brush, no shape. label moved to top right of square\n modifiers?: DrawModifiers;\n piece?: DrawShapePiece;\n customSvg?: { html: string; center?: 'orig' | 'dest' | 'label' }; // 100 x 100 viewbox cenetered at [50,50]\n label?: { text: string; fill?: string }; // fill is in '#rrggbb' format\n}\n\nexport interface DrawModifiers {\n lineWidth?: number;\n hilite?: boolean;\n}\n\nexport interface DrawShapePiece {\n role: cg.Role;\n color: cg.Color;\n scale?: number;\n}\n\nexport interface DrawBrush {\n key: string;\n color: string;\n opacity: number;\n lineWidth: number;\n}\n\nexport interface DrawBrushes {\n green: DrawBrush;\n red: DrawBrush;\n blue: DrawBrush;\n yellow: DrawBrush;\n [color: string]: DrawBrush;\n}\n\nexport interface Drawable {\n enabled: boolean; // can draw\n visible: boolean; // can view\n defaultSnapToValidMove: boolean;\n eraseOnClick: boolean;\n onChange?: (shapes: DrawShape[]) => void;\n shapes: DrawShape[]; // user shapes\n autoShapes: DrawShape[]; // computer shapes\n current?: DrawCurrent;\n brushes: DrawBrushes;\n prevSvgHash: string;\n}\n\nexport interface DrawCurrent {\n orig: cg.Key; // orig key of drawing\n dest?: cg.Key; // shape dest, or undefined for circle\n mouseSq?: cg.Key; // square being moused over\n pos: cg.NumberPair; // relative current position\n brush: cg.BrushColor; // brush name for shape\n snapToValidMove: boolean; // whether to snap to valid piece moves\n}\n\nconst brushes: cg.BrushColor[] = ['green', 'red', 'blue', 'yellow'];\n\nexport function start(state: State, e: cg.MouchEvent): void {\n // support one finger touch only\n if (e.touches && e.touches.length > 1) return;\n e.stopPropagation();\n e.preventDefault();\n if (e.ctrlKey) unselect(state);\n else cancelMove(state);\n const pos = eventPosition(e)!,\n orig = getKeyAtDomPos(pos, whitePov(state), state.dom.bounds());\n if (!orig) return;\n state.drawable.current = {\n orig,\n pos,\n brush: eventBrush(e),\n snapToValidMove: state.drawable.defaultSnapToValidMove,\n };\n\n processDraw(state);\n}\n\nexport function processDraw(state: State): void {\n requestAnimationFrame(() => {\n const cur = state.drawable.current;\n if (cur) {\n const keyAtDomPos = getKeyAtDomPos(cur.pos, whitePov(state), state.dom.bounds());\n if (!keyAtDomPos) {\n cur.snapToValidMove = false;\n }\n const mouseSq = cur.snapToValidMove\n ? getSnappedKeyAtDomPos(cur.orig, cur.pos, whitePov(state), state.dom.bounds())\n : keyAtDomPos;\n if (mouseSq !== cur.mouseSq) {\n cur.mouseSq = mouseSq;\n cur.dest = mouseSq !== cur.orig ? mouseSq : undefined;\n state.dom.redrawNow();\n }\n processDraw(state);\n }\n });\n}\n\nexport function move(state: State, e: cg.MouchEvent): void {\n if (state.drawable.current) state.drawable.current.pos = eventPosition(e)!;\n}\n\nexport function end(state: State): void {\n const cur = state.drawable.current;\n if (cur) {\n if (cur.mouseSq) addShape(state.drawable, cur);\n cancel(state);\n }\n}\n\nexport function cancel(state: State): void {\n if (state.drawable.current) {\n state.drawable.current = undefined;\n state.dom.redraw();\n }\n}\n\nexport function clear(state: State): void {\n if (state.drawable.shapes.length) {\n state.drawable.shapes = [];\n state.dom.redraw();\n onChange(state.drawable);\n }\n}\n\nfunction eventBrush(e: cg.MouchEvent): cg.BrushColor {\n const modA = (e.shiftKey || e.ctrlKey) && isRightButton(e);\n const modB = e.altKey || e.metaKey || e.getModifierState?.('AltGraph');\n return brushes[(modA ? 1 : 0) + (modB ? 2 : 0)];\n}\n\nfunction addShape(drawable: Drawable, cur: DrawCurrent): void {\n const sameShape = (s: DrawShape) => s.orig === cur.orig && s.dest === cur.dest;\n const similar = drawable.shapes.find(sameShape);\n if (similar) drawable.shapes = drawable.shapes.filter(s => !sameShape(s));\n if (!similar || similar.brush !== cur.brush)\n drawable.shapes.push({\n orig: cur.orig,\n dest: cur.dest,\n brush: cur.brush,\n });\n onChange(drawable);\n}\n\nfunction onChange(drawable: Drawable): void {\n if (drawable.onChange) drawable.onChange(drawable.shapes);\n}\n","import { State } from './state';\nimport * as board from './board';\nimport * as util from './util';\nimport { clear as drawClear } from './draw';\nimport * as cg from './types';\nimport { anim } from './anim';\n\nexport interface DragCurrent {\n orig: cg.Key; // orig key of dragging piece\n piece: cg.Piece;\n origPos: cg.NumberPair; // first event position\n pos: cg.NumberPair; // latest event position\n started: boolean; // whether the drag has started; as per the distance setting\n element: cg.PieceNode | (() => cg.PieceNode | undefined);\n newPiece?: boolean; // it it a new piece from outside the board\n force?: boolean; // can the new piece replace an existing one (editor)\n previouslySelected?: cg.Key;\n originTarget: EventTarget | null;\n keyHasChanged: boolean; // whether the drag has left the orig key\n}\n\nexport function start(s: State, e: cg.MouchEvent): void {\n if (!(s.trustAllEvents || e.isTrusted)) return; // only trust when trustAllEvents is enabled\n if (e.buttons !== undefined && e.buttons > 1) return; // only touch or left click\n if (e.touches && e.touches.length > 1) return; // support one finger touch only\n const bounds = s.dom.bounds(),\n position = util.eventPosition(e)!,\n orig = board.getKeyAtDomPos(position, board.whitePov(s), bounds);\n if (!orig) return;\n const piece = s.pieces.get(orig);\n const previouslySelected = s.selected;\n if (\n !previouslySelected &&\n s.drawable.enabled &&\n (s.drawable.eraseOnClick || !piece || piece.color !== s.turnColor)\n )\n drawClear(s);\n // Prevent touch scroll and create no corresponding mouse event, if there\n // is an intent to interact with the board.\n if (\n e.cancelable !== false &&\n (!e.touches || s.blockTouchScroll || piece || previouslySelected || pieceCloseTo(s, position))\n )\n e.preventDefault();\n else if (e.touches) return; // Handle only corresponding mouse event https://github.com/lichess-org/chessground/pull/268\n\n const hadPremove = !!s.premovable.current;\n const hadPredrop = !!s.predroppable.current;\n s.stats.ctrlKey = e.ctrlKey;\n if (s.selected && board.canMove(s, s.selected, orig)) {\n anim(state => board.selectSquare(state, orig), s);\n } else {\n board.selectSquare(s, orig);\n }\n const stillSelected = s.selected === orig;\n const element = pieceElementByKey(s, orig);\n if (piece && element && stillSelected && board.isDraggable(s, orig)) {\n s.draggable.current = {\n orig,\n piece,\n origPos: position,\n pos: position,\n started: s.draggable.autoDistance && s.stats.dragged,\n element,\n previouslySelected,\n originTarget: e.target,\n keyHasChanged: false,\n };\n element.cgDragging = true;\n element.classList.add('dragging');\n // place ghost\n const ghost = s.dom.elements.ghost;\n if (ghost) {\n ghost.className = `ghost ${piece.color} ${piece.role}`;\n util.translate(ghost, util.posToTranslate(bounds)(util.key2pos(orig), board.whitePov(s)));\n util.setVisible(ghost, true);\n }\n processDrag(s);\n } else {\n if (hadPremove) board.unsetPremove(s);\n if (hadPredrop) board.unsetPredrop(s);\n }\n s.dom.redraw();\n}\n\nfunction pieceCloseTo(s: State, pos: cg.NumberPair): boolean {\n const asWhite = board.whitePov(s),\n bounds = s.dom.bounds(),\n radiusSq = Math.pow(bounds.width / 8, 2);\n for (const key of s.pieces.keys()) {\n const center = util.computeSquareCenter(key, asWhite, bounds);\n if (util.distanceSq(center, pos) <= radiusSq) return true;\n }\n return false;\n}\n\nexport function dragNewPiece(s: State, piece: cg.Piece, e: cg.MouchEvent, force?: boolean): void {\n const key: cg.Key = 'a0';\n s.pieces.set(key, piece);\n s.dom.redraw();\n\n const position = util.eventPosition(e)!;\n\n s.draggable.current = {\n orig: key,\n piece,\n origPos: position,\n pos: position,\n started: true,\n element: () => pieceElementByKey(s, key),\n originTarget: e.target,\n newPiece: true,\n force: !!force,\n keyHasChanged: false,\n };\n processDrag(s);\n}\n\nfunction processDrag(s: State): void {\n requestAnimationFrame(() => {\n const cur = s.draggable.current;\n if (!cur) return;\n // cancel animations while dragging\n if (s.animation.current?.plan.anims.has(cur.orig)) s.animation.current = undefined;\n // if moving piece is gone, cancel\n const origPiece = s.pieces.get(cur.orig);\n if (!origPiece || !util.samePiece(origPiece, cur.piece)) cancel(s);\n else {\n if (!cur.started && util.distanceSq(cur.pos, cur.origPos) >= Math.pow(s.draggable.distance, 2))\n cur.started = true;\n if (cur.started) {\n // support lazy elements\n if (typeof cur.element === 'function') {\n const found = cur.element();\n if (!found) return;\n found.cgDragging = true;\n found.classList.add('dragging');\n cur.element = found;\n }\n\n const bounds = s.dom.bounds();\n util.translate(cur.element, [\n cur.pos[0] - bounds.left - bounds.width / 16,\n cur.pos[1] - bounds.top - bounds.height / 16,\n ]);\n\n cur.keyHasChanged = cur.keyHasChanged || cur.orig !== board.getKeyAtDomPos(cur.pos, board.whitePov(s), bounds);\n }\n }\n processDrag(s);\n });\n}\n\nexport function move(s: State, e: cg.MouchEvent): void {\n // support one finger touch only\n if (s.draggable.current && (!e.touches || e.touches.length < 2)) {\n s.draggable.current.pos = util.eventPosition(e)!;\n }\n}\n\nexport function end(s: State, e: cg.MouchEvent): void {\n const cur = s.draggable.current;\n if (!cur) return;\n // create no corresponding mouse event\n if (e.type === 'touchend' && e.cancelable !== false) e.preventDefault();\n // comparing with the origin target is an easy way to test that the end event\n // has the same touch origin\n if (e.type === 'touchend' && cur.originTarget !== e.target && !cur.newPiece) {\n s.draggable.current = undefined;\n return;\n }\n board.unsetPremove(s);\n board.unsetPredrop(s);\n // touchend has no position; so use the last touchmove position instead\n const eventPos = util.eventPosition(e) || cur.pos;\n const dest = board.getKeyAtDomPos(eventPos, board.whitePov(s), s.dom.bounds());\n if (dest && cur.started && cur.orig !== dest) {\n if (cur.newPiece) board.dropNewPiece(s, cur.orig, dest, cur.force);\n else {\n s.stats.ctrlKey = e.ctrlKey;\n if (board.userMove(s, cur.orig, dest)) s.stats.dragged = true;\n }\n } else if (cur.newPiece) {\n s.pieces.delete(cur.orig);\n } else if (s.draggable.deleteOnDropOff && !dest) {\n s.pieces.delete(cur.orig);\n board.callUserFunction(s.events.change);\n }\n if ((cur.orig === cur.previouslySelected || cur.keyHasChanged) && (cur.orig === dest || !dest))\n board.unselect(s);\n else if (!s.selectable.enabled) board.unselect(s);\n\n removeDragElements(s);\n\n s.draggable.current = undefined;\n s.dom.redraw();\n}\n\nexport function cancel(s: State): void {\n const cur = s.draggable.current;\n if (cur) {\n if (cur.newPiece) s.pieces.delete(cur.orig);\n s.draggable.current = undefined;\n board.unselect(s);\n removeDragElements(s);\n s.dom.redraw();\n }\n}\n\nfunction removeDragElements(s: State): void {\n const e = s.dom.elements;\n if (e.ghost) util.setVisible(e.ghost, false);\n}\n\nfunction pieceElementByKey(s: State, key: cg.Key): cg.PieceNode | undefined {\n let el = s.dom.elements.board.firstChild;\n while (el) {\n if ((el as cg.KeyedNode).cgKey === key && (el as cg.KeyedNode).tagName === 'PIECE')\n return el as cg.PieceNode;\n el = el.nextSibling;\n }\n return;\n}\n","import { State } from './state';\nimport { Key } from './types';\n\nexport function explosion(state: State, keys: Key[]): void {\n state.exploding = { stage: 1, keys };\n state.dom.redraw();\n setTimeout(() => {\n setStage(state, 2);\n setTimeout(() => setStage(state, undefined), 120);\n }, 120);\n}\n\nfunction setStage(state: State, stage: number | undefined): void {\n if (state.exploding) {\n if (stage) state.exploding.stage = stage;\n else state.exploding = undefined;\n state.dom.redraw();\n }\n}\n","import { State } from './state';\nimport * as board from './board';\nimport { write as fenWrite } from './fen';\nimport { Config, configure, applyAnimation } from './config';\nimport { anim, render } from './anim';\nimport { cancel as dragCancel, dragNewPiece } from './drag';\nimport { DrawShape } from './draw';\nimport { explosion } from './explosion';\nimport * as cg from './types';\n\nexport interface Api {\n // reconfigure the instance. Accepts all config options, except for viewOnly & drawable.visible.\n // board will be animated accordingly, if animations are enabled.\n set(config: Config): void;\n\n // read chessground state; write at your own risks.\n state: State;\n\n // get the position as a FEN string (only contains pieces, no flags)\n // e.g. rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR\n getFen(): cg.FEN;\n\n // change the view angle\n toggleOrientation(): void;\n\n // perform a move programmatically\n move(orig: cg.Key, dest: cg.Key): void;\n\n // add and/or remove arbitrary pieces on the board\n setPieces(pieces: cg.PiecesDiff): void;\n\n // click a square programmatically\n selectSquare(key: cg.Key | null, force?: boolean): void;\n\n // put a new piece on the board\n newPiece(piece: cg.Piece, key: cg.Key): void;\n\n // play the current premove, if any; returns true if premove was played\n playPremove(): boolean;\n\n // cancel the current premove, if any\n cancelPremove(): void;\n\n // play the current predrop, if any; returns true if premove was played\n playPredrop(validate: (drop: cg.Drop) => boolean): boolean;\n\n // cancel the current predrop, if any\n cancelPredrop(): void;\n\n // cancel the current move being made\n cancelMove(): void;\n\n // cancel current move and prevent further ones\n stop(): void;\n\n // make squares explode (atomic chess)\n explode(keys: cg.Key[]): void;\n\n // programmatically draw user shapes\n setShapes(shapes: DrawShape[]): void;\n\n // programmatically draw auto shapes\n setAutoShapes(shapes: DrawShape[]): void;\n\n // square name at this DOM position (like \"e4\")\n getKeyAtDomPos(pos: cg.NumberPair): cg.Key | undefined;\n\n // only useful when CSS changes the board width/height ratio (for 3D)\n redrawAll: cg.Redraw;\n\n // for crazyhouse and board editors\n dragNewPiece(piece: cg.Piece, event: cg.MouchEvent, force?: boolean): void;\n\n // unbinds all events\n // (important for document-wide events like scroll and mousemove)\n destroy: cg.Unbind;\n}\n\n// see API types and documentations in dts/api.d.ts\nexport function start(state: State, redrawAll: cg.Redraw): Api {\n function toggleOrientation(): void {\n board.toggleOrientation(state);\n redrawAll();\n }\n\n return {\n set(config): void {\n if (config.orientation && config.orientation !== state.orientation) toggleOrientation();\n applyAnimation(state, config);\n (config.fen ? anim : render)(state => configure(state, config), state);\n },\n\n state,\n\n getFen: () => fenWrite(state.pieces),\n\n toggleOrientation,\n\n setPieces(pieces): void {\n anim(state => board.setPieces(state, pieces), state);\n },\n\n selectSquare(key, force): void {\n if (key) anim(state => board.selectSquare(state, key, force), state);\n else if (state.selected) {\n board.unselect(state);\n state.dom.redraw();\n }\n },\n\n move(orig, dest): void {\n anim(state => board.baseMove(state, orig, dest), state);\n },\n\n newPiece(piece, key): void {\n anim(state => board.baseNewPiece(state, piece, key), state);\n },\n\n playPremove(): boolean {\n if (state.premovable.current) {\n if (anim(board.playPremove, state)) return true;\n // if the premove couldn't be played, redraw to clear it up\n state.dom.redraw();\n }\n return false;\n },\n\n playPredrop(validate): boolean {\n if (state.predroppable.current) {\n const result = board.playPredrop(state, validate);\n state.dom.redraw();\n return result;\n }\n return false;\n },\n\n cancelPremove(): void {\n render(board.unsetPremove, state);\n },\n\n cancelPredrop(): void {\n render(board.unsetPredrop, state);\n },\n\n cancelMove(): void {\n render(state => {\n board.cancelMove(state);\n dragCancel(state);\n }, state);\n },\n\n stop(): void {\n render(state => {\n board.stop(state);\n dragCancel(state);\n }, state);\n },\n\n explode(keys: cg.Key[]): void {\n explosion(state, keys);\n },\n\n setAutoShapes(shapes: DrawShape[]): void {\n render(state => (state.drawable.autoShapes = shapes), state);\n },\n\n setShapes(shapes: DrawShape[]): void {\n render(state => (state.drawable.shapes = shapes), state);\n },\n\n getKeyAtDomPos(pos): cg.Key | undefined {\n return board.getKeyAtDomPos(pos, board.whitePov(state), state.dom.bounds());\n },\n\n redrawAll,\n\n dragNewPiece(piece, event, force): void {\n dragNewPiece(state, piece, event, force);\n },\n\n destroy(): void {\n board.stop(state);\n state.dom.unbind?.();\n state.dom.destroyed = true;\n },\n };\n}\n","import * as fen from './fen';\nimport { AnimCurrent } from './anim';\nimport { DragCurrent } from './drag';\nimport { Drawable } from './draw';\nimport { timer } from './util';\nimport * as cg from './types';\n\nexport interface HeadlessState {\n pieces: cg.Pieces;\n orientation: cg.Color; // board orientation. white | black\n turnColor: cg.Color; // turn to play. white | black\n check?: cg.Key; // square currently in check \"a2\"\n lastMove?: cg.Key[]; // squares part of the last move [\"c3\"; \"c4\"]\n selected?: cg.Key; // square currently selected \"a1\"\n coordinates: boolean; // include coords attributes\n coordinatesOnSquares: boolean; // include coords attributes on every square\n ranksPosition: cg.RanksPosition; // position ranks on either side. left | right\n autoCastle: boolean; // immediately complete the castle by moving the rook after king move\n viewOnly: boolean; // don't bind events: the user will never be able to move pieces around\n disableContextMenu: boolean; // because who needs a context menu on a chessboard\n addPieceZIndex: boolean; // adds z-index values to pieces (for 3D)\n addDimensionsCssVarsTo?: HTMLElement; // add ---cg-width and ---cg-height CSS vars containing the board's dimensions to this element\n blockTouchScroll: boolean; // block scrolling via touch dragging on the board, e.g. for coordinate training\n pieceKey: boolean; // add a data-key attribute to piece elements\n trustAllEvents?: boolean; // disable checking for human only input (e.isTrusted)\n highlight: {\n lastMove: boolean; // add last-move class to squares\n check: boolean; // add check class to squares\n custom?: cg.SquareClasses; // add custom classes to custom squares\n };\n animation: {\n enabled: boolean;\n duration: number;\n current?: AnimCurrent;\n };\n movable: {\n free: boolean; // all moves are valid - board editor\n color?: cg.Color | 'both'; // color that can move. white | black | both\n dests?: cg.Dests; // valid moves. {\"a2\" [\"a3\" \"a4\"] \"b1\" [\"a3\" \"c3\"]}\n showDests: boolean; // whether to add the move-dest class on squares\n events: {\n after?: (orig: cg.Key, dest: cg.Key, metadata: cg.MoveMetadata) => void; // called after the move has been played\n afterNewPiece?: (role: cg.Role, key: cg.Key, metadata: cg.MoveMetadata) => void; // called after a new piece is dropped on the board\n };\n rookCastle: boolean; // castle by moving the king to the rook\n };\n premovable: {\n enabled: boolean; // allow premoves for color that can not move\n showDests: boolean; // whether to add the premove-dest class on squares\n castle: boolean; // whether to allow king castle premoves\n dests?: cg.Key[]; // premove destinations for the current selection\n customDests?: cg.Dests; // use custom valid premoves. {\"a2\" [\"a3\" \"a4\"] \"b1\" [\"a3\" \"c3\"]}\n current?: cg.KeyPair; // keys of the current saved premove [\"e2\" \"e4\"]\n events: {\n set?: (orig: cg.Key, dest: cg.Key, metadata?: cg.SetPremoveMetadata) => void; // called after the premove has been set\n unset?: () => void; // called after the premove has been unset\n };\n };\n predroppable: {\n enabled: boolean; // allow predrops for color that can not move\n current?: {\n // current saved predrop {role: 'knight'; key: 'e4'}\n role: cg.Role;\n key: cg.Key;\n };\n events: {\n set?: (role: cg.Role, key: cg.Key) => void; // called after the predrop has been set\n unset?: () => void; // called after the predrop has been unset\n };\n };\n draggable: {\n enabled: boolean; // allow moves & premoves to use drag'n drop\n distance: number; // minimum distance to initiate a drag; in pixels\n autoDistance: boolean; // lets chessground set distance to zero when user drags pieces\n showGhost: boolean; // show ghost of piece being dragged\n deleteOnDropOff: boolean; // delete a piece when it is dropped off the board\n current?: DragCurrent;\n };\n dropmode: {\n active: boolean;\n piece?: cg.Piece;\n };\n selectable: {\n // disable to enforce dragging over click-click move\n enabled: boolean;\n };\n stats: {\n // was last piece dragged or clicked?\n // needs default to false for touch\n dragged: boolean;\n ctrlKey?: boolean;\n };\n events: {\n change?: () => void; // called after the situation changes on the board\n // called after a piece has been moved.\n // capturedPiece is undefined or like {color: 'cg-white'; 'role': 'queen'}\n move?: (orig: cg.Key, dest: cg.Key, capturedPiece?: cg.Piece) => void;\n dropNewPiece?: (piece: cg.Piece, key: cg.Key) => void;\n select?: (key: cg.Key) => void; // called when a square is selected\n insert?: (elements: cg.Elements) => void; // when the board DOM has been (re)inserted\n };\n drawable: Drawable;\n exploding?: cg.Exploding;\n hold: cg.Timer;\n}\n\nexport interface State extends HeadlessState {\n dom: cg.Dom;\n}\n\nexport function defaults(): HeadlessState {\n return {\n pieces: fen.read(fen.initial),\n orientation: 'cg-white',\n turnColor: 'cg-white',\n coordinates: true,\n coordinatesOnSquares: false,\n ranksPosition: 'right',\n autoCastle: true,\n viewOnly: false,\n disableContextMenu: false,\n addPieceZIndex: false,\n blockTouchScroll: false,\n pieceKey: false,\n trustAllEvents: false,\n highlight: {\n lastMove: true,\n check: true,\n },\n animation: {\n enabled: true,\n duration: 200,\n },\n movable: {\n free: true,\n color: 'both',\n showDests: true,\n events: {},\n rookCastle: true,\n },\n premovable: {\n enabled: true,\n showDests: true,\n castle: true,\n events: {},\n },\n predroppable: {\n enabled: false,\n events: {},\n },\n draggable: {\n enabled: true,\n distance: 3,\n autoDistance: true,\n showGhost: true,\n deleteOnDropOff: false,\n },\n dropmode: {\n active: false,\n },\n selectable: {\n enabled: true,\n },\n stats: {\n // on touchscreen, default to \"tap-tap\" moves\n // instead of drag\n dragged: !('ontouchstart' in window),\n },\n events: {},\n drawable: {\n enabled: true, // can draw\n visible: true, // can view\n defaultSnapToValidMove: true,\n eraseOnClick: true,\n shapes: [],\n autoShapes: [],\n brushes: {\n green: { key: 'g', color: '#15781B', opacity: 1, lineWidth: 10 },\n red: { key: 'r', color: '#882020', opacity: 1, lineWidth: 10 },\n blue: { key: 'b', color: '#003088', opacity: 1, lineWidth: 10 },\n yellow: { key: 'y', color: '#e68f00', opacity: 1, lineWidth: 10 },\n paleBlue: { key: 'pb', color: '#003088', opacity: 0.4, lineWidth: 15 },\n paleGreen: { key: 'pg', color: '#15781B', opacity: 0.4, lineWidth: 15 },\n paleRed: { key: 'pr', color: '#882020', opacity: 0.4, lineWidth: 15 },\n paleGrey: {\n key: 'pgr',\n color: '#4a4a4a',\n opacity: 0.35,\n lineWidth: 15,\n },\n purple: { key: 'purple', color: '#68217a', opacity: 0.65, lineWidth: 10 },\n pink: { key: 'pink', color: '#ee2080', opacity: 0.5, lineWidth: 10 },\n white: { key: 'white', color: 'white', opacity: 1, lineWidth: 10 },\n },\n prevSvgHash: '',\n },\n hold: timer(),\n };\n}\n","import { State } from './state';\nimport { key2pos } from './util';\nimport { Drawable, DrawShape, DrawShapePiece, DrawBrush, DrawBrushes, DrawModifiers } from './draw';\nimport { SyncableShape, Hash } from './sync';\nimport * as cg from './types';\n\ntype CustomBrushes = Map<string, DrawBrush>; // by hash\ntype Svg = { el: SVGElement; isCustom?: boolean };\ntype AngleSlots = Set<number>; // arrow angle slots for label positioning\ntype ArrowDests = Map<cg.Key | undefined, AngleSlots>; // angle slots per dest\n\nconst hilites: { [name: string]: DrawBrush } = {\n hilitePrimary: { key: 'hilitePrimary', color: '#3291ff', opacity: 1, lineWidth: 1 },\n hiliteWhite: { key: 'hiliteWhite', color: '#ffffff', opacity: 1, lineWidth: 1 },\n};\n\nexport { createElement, setAttributes };\n\nexport function createDefs(): Element {\n const defs = createElement('defs');\n const filter = setAttributes(createElement('filter'), { id: 'cg-filter-blur' });\n filter.appendChild(setAttributes(createElement('feGaussianBlur'), { stdDeviation: '0.019' }));\n defs.appendChild(filter);\n return defs;\n}\n\nexport function renderSvg(state: State, shapesEl: SVGElement, customsEl: SVGElement): void {\n const d = state.drawable,\n curD = d.current,\n cur = curD && curD.mouseSq ? (curD as DrawShape) : undefined,\n dests: ArrowDests = new Map(),\n bounds = state.dom.bounds(),\n nonPieceAutoShapes = d.autoShapes.filter(autoShape => !autoShape.piece);\n\n for (const s of d.shapes.concat(nonPieceAutoShapes).concat(cur ? [cur] : [])) {\n if (!s.dest) continue;\n const sources = dests.get(s.dest) ?? new Set(),\n from = pos2user(orient(key2pos(s.orig), state.orientation), bounds),\n to = pos2user(orient(key2pos(s.dest), state.orientation), bounds);\n sources.add(moveAngle(from, to));\n dests.set(s.dest, sources);\n }\n const shapes: SyncableShape[] = d.shapes.concat(nonPieceAutoShapes).map((s: DrawShape) => {\n return {\n shape: s,\n current: false,\n hash: shapeHash(s, isShort(s.dest, dests), false, bounds),\n };\n });\n if (cur)\n shapes.push({\n shape: cur,\n current: true,\n hash: shapeHash(cur, isShort(cur.dest, dests), true, bounds),\n });\n\n const fullHash = shapes.map(sc => sc.hash).join(';');\n if (fullHash === state.drawable.prevSvgHash) return;\n state.drawable.prevSvgHash = fullHash;\n\n /*\n -- DOM hierarchy --\n <svg class=\"cg-shapes\"> (<= svg)\n <defs>\n ...(for brushes)...\n </defs>\n <g>\n ...(for arrows and circles)...\n </g>\n </svg>\n <svg class=\"cg-custom-svgs\"> (<= customSvg)\n <g>\n ...(for custom svgs)...\n </g>\n </svg>\n */\n\n const defsEl = shapesEl.querySelector('defs') as SVGElement;\n\n syncDefs(d, shapes, defsEl);\n syncShapes(shapes, shapesEl.querySelector('g')!, customsEl.querySelector('g')!, s =>\n renderShape(state, s, d.brushes, dests, bounds),\n );\n}\n\n// append only. Don't try to update/remove.\nfunction syncDefs(d: Drawable, shapes: SyncableShape[], defsEl: SVGElement) {\n const brushes: CustomBrushes = new Map();\n let brush: DrawBrush;\n for (const s of shapes.filter(s => s.shape.dest && s.shape.brush)) {\n brush = makeCustomBrush(d.brushes[s.shape.brush!], s.shape.modifiers);\n if (s.shape.modifiers?.hilite) brushes.set(hilite(brush).key, hilite(brush));\n brushes.set(brush.key, brush);\n }\n const keysInDom = new Set();\n let el: SVGElement | undefined = defsEl.firstElementChild as SVGElement;\n while (el) {\n keysInDom.add(el.getAttribute('cgKey'));\n el = el.nextElementSibling as SVGElement | undefined;\n }\n for (const [key, brush] of brushes.entries()) {\n if (!keysInDom.has(key)) defsEl.appendChild(renderMarker(brush));\n }\n}\n\nfunction syncShapes(\n syncables: SyncableShape[],\n shapes: Element,\n customs: Element,\n renderShape: (shape: SyncableShape) => Svg[],\n): void {\n const hashesInDom = new Map();\n\n for (const sc of syncables) hashesInDom.set(sc.hash, false);\n for (const root of [shapes, customs]) {\n const toRemove: SVGElement[] = [];\n let el: SVGElement | undefined = root.firstElementChild as SVGElement,\n elHash: Hash | null;\n while (el) {\n elHash = el.getAttribute('cgHash') as Hash;\n if (hashesInDom.has(elHash)) hashesInDom.set(elHash, true);\n else toRemove.push(el);\n el = el.nextElementSibling as SVGElement | undefined;\n }\n for (const el of toRemove) root.removeChild(el);\n }\n // insert shapes that are not yet in dom\n for (const sc of syncables.filter(s => !hashesInDom.get(s.hash))) {\n for (const svg of renderShape(sc)) {\n if (svg.isCustom) customs.appendChild(svg.el);\n else shapes.appendChild(svg.el);\n }\n }\n}\n\nfunction shapeHash(\n { orig, dest, brush, piece, modifiers, customSvg, label }: DrawShape,\n shorten: boolean,\n current: boolean,\n bounds: DOMRectReadOnly,\n): Hash {\n // a shape and an overlay svg share a lifetime and have the same cgHash attribute\n return [\n bounds.width,\n bounds.height,\n current,\n orig,\n dest,\n brush,\n shorten && '-',\n piece && pieceHash(piece),\n modifiers && modifiersHash(modifiers),\n customSvg && `custom-${textHash(customSvg.html)},${customSvg.center?.[0] ?? 'o'}`,\n label && `label-${textHash(label.text)}`,\n ]\n .filter(x => x)\n .join(',');\n}\n\nfunction pieceHash(piece: DrawShapePiece): Hash {\n return [piece.color, piece.role, piece.scale].filter(x => x).join(',');\n}\n\nfunction modifiersHash(m: DrawModifiers): Hash {\n return [m.lineWidth, m.hilite && '*'].filter(x => x).join(',');\n}\n\nfunction textHash(s: string): Hash {\n // Rolling hash with base 31 (cf. https://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript)\n let h = 0;\n for (let i = 0; i < s.length; i++) {\n h = ((h << 5) - h + s.charCodeAt(i)) >>> 0;\n }\n return h.toString();\n}\n\nfunction renderShape(\n state: State,\n { shape, current, hash }: SyncableShape,\n brushes: DrawBrushes,\n dests: ArrowDests,\n bounds: DOMRectReadOnly,\n): Svg[] {\n const from = pos2user(orient(key2pos(shape.orig), state.orientation), bounds),\n to = shape.dest ? pos2user(orient(key2pos(shape.dest), state.orientation), bounds) : from,\n brush = shape.brush && makeCustomBrush(brushes[shape.brush], shape.modifiers),\n slots = dests.get(shape.dest),\n svgs: Svg[] = [];\n\n if (brush) {\n const el = setAttributes(createElement('g'), { cgHash: hash });\n svgs.push({ el });\n\n if (from[0] !== to[0] || from[1] !== to[1])\n el.appendChild(renderArrow(shape, brush, from, to, current, isShort(shape.dest, dests)));\n else el.appendChild(renderCircle(brushes[shape.brush!], from, current, bounds));\n }\n if (shape.label) {\n const label = shape.label;\n if (!label.fill) {\n if (shape.brush && brushes[shape.brush]) {\n label.fill = brushes[shape.brush].color;\n }\n }\n const corner = shape.brush ? undefined : 'tr';\n svgs.push({ el: renderLabel(label, hash, from, to, slots, corner), isCustom: true });\n }\n if (shape.customSvg) {\n const on = shape.customSvg.center ?? 'orig';\n const [x, y] =\n on === 'label' ? labelCoords(from, to, slots).map(c => c - 0.5) : on === 'dest' ? to : from;\n const el = setAttributes(createElement('g'), { transform: `translate(${x},${y})`, cgHash: hash });\n el.innerHTML = `<svg width=\"1\" height=\"1\" viewBox=\"0 0 100 100\">${shape.customSvg.html}</svg>`;\n svgs.push({ el, isCustom: true });\n }\n return svgs;\n}\n\nfunction renderCircle(\n brush: DrawBrush,\n at: cg.NumberPair,\n current: boolean,\n bounds: DOMRectReadOnly,\n): SVGElement {\n const widths = circleWidth(),\n radius = (bounds.width + bounds.height) / (4 * Math.max(bounds.width, bounds.height));\n return setAttributes(createElement('circle'), {\n stroke: brush.color,\n 'stroke-width': widths[current ? 0 : 1],\n fill: 'none',\n opacity: opacity(brush, current),\n cx: at[0],\n cy: at[1],\n r: radius - widths[1] / 2,\n });\n}\n\nfunction hilite(brush: DrawBrush): DrawBrush {\n return ['#ffffff', '#fff', 'white'].includes(brush.color)\n ? hilites['hilitePrimary']\n : hilites['hiliteWhite'];\n}\n\nfunction renderArrow(\n s: DrawShape,\n brush: DrawBrush,\n from: cg.NumberPair,\n to: cg.NumberPair,\n current: boolean,\n shorten: boolean,\n): SVGElement {\n function renderLine(isHilite: boolean) {\n const m = arrowMargin(shorten && !current),\n dx = to[0] - from[0],\n dy = to[1] - from[1],\n angle = Math.atan2(dy, dx),\n xo = Math.cos(angle) * m,\n yo = Math.sin(angle) * m;\n return setAttributes(createElement('line'), {\n stroke: isHilite ? hilite(brush).color : brush.color,\n 'stroke-width': lineWidth(brush, current) + (isHilite ? 0.04 : 0),\n 'stroke-linecap': 'round',\n 'marker-end': `url(#arrowhead-${isHilite ? hilite(brush).key : brush.key})`,\n opacity: s.modifiers?.hilite ? 1 : opacity(brush, current),\n x1: from[0],\n y1: from[1],\n x2: to[0] - xo,\n y2: to[1] - yo,\n });\n }\n if (!s.modifiers?.hilite) return renderLine(false);\n\n const g = createElement('g');\n const blurred = setAttributes(createElement('g'), { filter: 'url(#cg-filter-blur)' });\n blurred.appendChild(filterBox(from, to));\n blurred.appendChild(renderLine(true));\n g.appendChild(blurred);\n g.appendChild(renderLine(false));\n return g;\n}\n\nfunction renderMarker(brush: DrawBrush): SVGElement {\n const marker = setAttributes(createElement('marker'), {\n id: 'arrowhead-' + brush.key,\n orient: 'auto',\n overflow: 'visible',\n markerWidth: 4,\n markerHeight: 4,\n refX: brush.key.startsWith('hilite') ? 1.86 : 2.05,\n refY: 2,\n });\n marker.appendChild(\n setAttributes(createElement('path'), {\n d: 'M0,0 V4 L3,2 Z',\n fill: brush.color,\n }),\n );\n marker.setAttribute('cgKey', brush.key);\n return marker;\n}\n\nfunction renderLabel(\n label: { text: string; fill?: string },\n hash: string,\n from: cg.NumberPair,\n to: cg.NumberPair,\n slots?: AngleSlots,\n corner?: 'tr',\n): SVGElement {\n const labelSize = 0.4,\n fontSize = labelSize * 0.75 ** label.text.length,\n at = labelCoords(from, to, slots),\n cornerOff = corner === 'tr' ? 0.4 : 0,\n g = setAttributes(createElement('g'), {\n transform: `translate(${at[0] + cornerOff},${at[1] - cornerOff})`,\n cgHash: hash,\n });\n g.appendChild(\n setAttributes(createElement('circle'), {\n r: labelSize / 2,\n 'fill-opacity': corner ? 1.0 : 0.8,\n 'stroke-opacity': corner ? 1.0 : 0.7,\n 'stroke-width': 0.03,\n fill: label.fill ?? '#666',\n stroke: 'white',\n }),\n );\n const labelEl = setAttributes(createElement('text'), {\n 'font-size': fontSize,\n 'font-family': 'Noto Sans',\n 'text-anchor': 'middle',\n fill: 'white',\n y: 0.13 * 0.75 ** label.text.length,\n });\n labelEl.innerHTML = label.text;\n g.appendChild(labelEl);\n return g;\n}\n\nfunction orient(pos: cg.Pos, color: cg.Color): cg.Pos {\n return color === 'cg-white' ? pos : [7 - pos[0], 7 - pos[1]];\n}\n\nfunction isShort(dest: cg.Key | undefined, dests: ArrowDests) {\n return true === (dest && dests.has(dest) && dests.get(dest)!.size > 1);\n}\n\nfunction createElement(tagName: string): SVGElement {\n return document.createElementNS('http://www.w3.org/2000/svg', tagName);\n}\n\nfunction setAttributes(el: SVGElement, attrs: { [key: string]: any }): SVGElement {\n for (const key in attrs) {\n if (Object.prototype.hasOwnProperty.call(attrs, key)) el.setAttribute(key, attrs[key]);\n }\n return el;\n}\n\nfunction makeCustomBrush(base: DrawBrush, modifiers: DrawModifiers | undefined): DrawBrush {\n return !modifiers\n ? base\n : {\n color: base.color,\n opacity: Math.round(base.opacity * 10) / 10,\n lineWidth: Math.round(modifiers.lineWidth || base.lineWidth),\n key: [base.key, modifiers.lineWidth].filter(x => x).join(''),\n };\n}\n\nfunction circleWidth(): [number, number] {\n return [3 / 64, 4 / 64];\n}\n\nfunction lineWidth(brush: DrawBrush, current: boolean): number {\n return ((brush.lineWidth || 10) * (current ? 0.85 : 1)) / 64;\n}\n\nfunction opacity(brush: DrawBrush, current: boolean): number {\n return (brush.opacity || 1) * (current ? 0.9 : 1);\n}\n\nfunction arrowMargin(shorten: boolean): number {\n return (shorten ? 20 : 10) / 64;\n}\n\nfunction pos2user(pos: cg.Pos, bounds: DOMRectReadOnly): cg.NumberPair {\n const xScale = Math.min(1, bounds.width / bounds.height);\n const yScale = Math.min(1, bounds.height / bounds.width);\n return [(pos[0] - 3.5) * xScale, (3.5 - pos[1]) * yScale];\n}\n\nfunction filterBox(from: cg.NumberPair, to: cg.NumberPair): SVGElement {\n // lines/arrows are considered to be one dimensional for the purposes of SVG filters,\n // so we add a transparent bounding box to ensure they apply to the 2nd dimension\n const box = {\n from: [Math.floor(Math.min(from[0], to[0])), Math.floor(Math.min(from[1], to[1]))],\n to: [Math.ceil(Math.max(from[0], to[0])), Math.ceil(Math.max(from[1], to[1]))],\n };\n return setAttributes(createElement('rect'), {\n x: box.from[0],\n y: box.from[1],\n width: box.to[0] - box.from[0],\n height: box.to[1] - box.from[1],\n fill: 'none',\n stroke: 'none',\n });\n}\n\nfunction moveAngle(from: cg.NumberPair, to: cg.NumberPair, asSlot = true) {\n const angle = Math.atan2(to[1] - from[1], to[0] - from[0]) + Math.PI;\n return asSlot ? (Math.round((angle * 8) / Math.PI) + 16) % 16 : angle;\n}\n\nfunction dist(from: cg.NumberPair, to: cg.NumberPair): number {\n return Math.sqrt([from[0] - to[0], from[1] - to[1]].reduce((acc, x) => acc + x * x, 0));\n}\n\n/*\n try to place label at the junction of the destination shaft and arrowhead. if there's more than\n 1 arrow pointing to a square, the arrow shortens by 10 / 64 units so the label must move as well. \n \n if the angle between two incoming arrows is pi / 8, such as when an adjacent knight and bishop\n attack the same square, the knight's label is slid further down the shaft by an amount equal to\n our label size to avoid collision\n*/\n\nfunction labelCoords(from: cg.NumberPair, to: cg.NumberPair, slots?: AngleSlots): cg.NumberPair {\n let mag = dist(from, to);\n //if (mag === 0) return [from[0], from[1]];\n const angle = moveAngle(from, to, false);\n if (slots) {\n mag -= 33 / 64; // reduce by arrowhead length\n if (slots.size > 1) {\n mag -= 10 / 64; // reduce by shortening factor\n const slot = moveAngle(from, to);\n if (slots.has((slot + 1) % 16) || slots.has((slot + 15) % 16)) {\n if (slot & 1) mag -= 0.4;\n // and by label size for the knight if another arrow is within pi / 8.\n }\n }\n }\n return [from[0] - Math.cos(angle) * mag, from[1] - Math.sin(angle) * mag].map(\n c => c + 0.5,\n ) as cg.NumberPair;\n}\n","import { HeadlessState } from './state';\nimport { setVisible, createEl } from './util';\nimport { colors, files, ranks, Elements } from './types';\nimport { createElement as createSVG, setAttributes, createDefs } from './svg';\n\nexport function renderWrap(element: HTMLElement, s: HeadlessState): Elements {\n // .cg-wrap (element passed to Chessground)\n // cg-container\n // cg-board\n // svg.cg-shapes\n // defs\n // g\n // svg.cg-custom-svgs\n // g\n // cg-auto-pieces\n // coords.ranks\n // coords.files\n // piece.ghost\n\n element.innerHTML = '';\n\n // ensure the cg-wrap class is set\n // so bounds calculation can use the CSS width/height values\n // add that class yourself to the element before calling chessground\n // for a slight performance improvement! (avoids recomputing style)\n element.classList.add('cg-wrap');\n\n for (const c of colors) element.classList.toggle('orientation-' + c, s.orientation === c);\n element.classList.toggle('manipulable', !s.viewOnly);\n\n const container = createEl('cg-container');\n element.appendChild(container);\n\n const board = createEl('cg-board');\n container.appendChild(board);\n\n let svg: SVGElement | undefined;\n let customSvg: SVGElement | undefined;\n let autoPieces: HTMLElement | undefined;\n\n if (s.drawable.visible) {\n svg = setAttributes(createSVG('svg'), {\n class: 'cg-shapes',\n viewBox: '-4 -4 8 8',\n preserveAspectRatio: 'xMidYMid slice',\n });\n svg.appendChild(createDefs());\n svg.appendChild(createSVG('g'));\n\n customSvg = setAttributes(createSVG('svg'), {\n class: 'cg-custom-svgs',\n viewBox: '-3.5 -3.5 8 8',\n preserveAspectRatio: 'xMidYMid slice',\n });\n customSvg.appendChild(createSVG('g'));\n\n autoPieces = createEl('cg-auto-pieces');\n\n container.appendChild(svg);\n container.appendChild(customSvg);\n container.appendChild(autoPieces);\n }\n\n if (s.coordinates) {\n const orientClass = s.orientation === 'cg-black' ? ' black' : '';\n const ranksPositionClass = s.ranksPosition === 'left' ? ' left' : '';\n\n if (s.coordinatesOnSquares) {\n const rankN: (i: number) => number = s.orientation === 'cg-white' ? i => i + 1 : i => 8 - i;\n files.forEach((f, i) =>\n container.appendChild(\n renderCoords(\n ranks.map(r => f + r),\n 'squares rank' + rankN(i) + orientClass + ranksPositionClass,\n ),\n ),\n );\n } else {\n container.appendChild(renderCoords(ranks, 'ranks' + orientClass + ranksPositionClass));\n container.appendChild(renderCoords(files, 'files' + orientClass));\n }\n }\n\n let ghost: HTMLElement | undefined;\n if (s.draggable.enabled && s.draggable.showGhost) {\n ghost = createEl('piece', 'ghost');\n setVisible(ghost, false);\n container.appendChild(ghost);\n }\n\n return {\n board,\n container,\n wrap: element,\n ghost,\n svg,\n customSvg,\n autoPieces,\n };\n}\n\nfunction renderCoords(elems: readonly string[], className: string): HTMLElement {\n const el = createEl('coords', className);\n let f: HTMLElement;\n for (const elem of elems) {\n f = createEl('coord');\n f.textContent = elem;\n el.appendChild(f);\n }\n return el;\n}\n","import { State } from './state';\nimport * as cg from './types';\nimport * as board from './board';\nimport * as util from './util';\nimport { cancel as dragCancel } from './drag';\n\nexport function setDropMode(s: State, piece?: cg.Piece): void {\n s.dropmode = {\n active: true,\n piece,\n };\n dragCancel(s);\n}\n\nexport function cancelDropMode(s: State): void {\n s.dropmode = {\n active: false,\n };\n}\n\nexport function drop(s: State, e: cg.MouchEvent): void {\n if (!s.dropmode.active) return;\n\n board.unsetPremove(s);\n board.unsetPredrop(s);\n\n const piece = s.dropmode.piece;\n\n if (piece) {\n s.pieces.set('a0', piece);\n const position = util.eventPosition(e);\n const dest = position && board.getKeyAtDomPos(position, board.whitePov(s), s.dom.bounds());\n if (dest) board.dropNewPiece(s, 'a0', dest);\n }\n s.dom.redraw();\n}\n","import { State } from './state';\nimport * as drag from './drag';\nimport * as draw from './draw';\nimport { drop } from './drop';\nimport { isRightButton } from './util';\nimport * as cg from './types';\n\ntype MouchBind = (e: cg.MouchEvent) => void;\ntype StateMouchBind = (d: State, e: cg.MouchEvent) => void;\n\nexport function bindBoard(s: State): void {\n const boardEl = s.dom.elements.board;\n\n // if ('ResizeObserver' in window) new ResizeObserver(onResize).observe(s.dom.elements.wrap);\n\n if (s.disableContextMenu || s.drawable.enabled) {\n boardEl.addEventListener('contextmenu', (e) => e.preventDefault());\n }\n\n if (s.viewOnly) return;\n\n // Cannot be passive, because we prevent touch scrolling and dragging of\n // selected elements.\n const onStart = startDragOrDraw(s);\n boardEl.addEventListener('touchstart', onStart as EventListener, {\n passive: false,\n });\n boardEl.addEventListener('mousedown', onStart as EventListener, {\n passive: false,\n });\n}\n\n// returns the unbind function\nexport function bindDocument(s: State, onResize: () => void): cg.Unbind {\n const unbinds: cg.Unbind[] = [];\n\n // Old versions of Edge and Safari do not support ResizeObserver. Send\n // chessground.resize if a user action has changed the bounds of the board.\n if (!('ResizeObserver' in window))\n unbinds.push(unbindable(document.body, 'chessground.resize', onResize));\n\n if (!s.viewOnly) {\n const onmove = dragOrDraw(s, drag.move, draw.move);\n const onend = dragOrDraw(s, drag.end, draw.end);\n\n for (const ev of ['touchmove', 'mousemove'])\n unbinds.push(unbindable(document, ev, onmove as EventListener));\n for (const ev of ['touchend', 'mouseup'])\n unbinds.push(unbindable(document, ev, onend as EventListener));\n\n const onScroll = () => s.dom.bounds.clear();\n unbinds.push(unbindable(document, 'scroll', onScroll, { capture: true, passive: true }));\n unbinds.push(unbindable(window, 'resize', onScroll, { passive: true }));\n }\n\n return () => unbinds.forEach((f) => f());\n}\n\nfunction unbindable(\n el: EventTarget,\n eventName: string,\n callback: EventListener,\n options?: AddEventListenerOptions\n): cg.Unbind {\n el.addEventListener(eventName, callback, options);\n return () => el.removeEventListener(eventName, callback, options);\n}\n\nconst startDragOrDraw =\n (s: State): MouchBind =>\n (e) => {\n if (s.draggable.current) drag.cancel(s);\n else if (s.drawable.current) draw.cancel(s);\n else if (e.shiftKey || isRightButton(e)) {\n if (s.drawable.enabled) draw.start(s, e);\n } else if (!s.viewOnly) {\n if (s.dropmode.active) drop(s, e);\n else drag.start(s, e);\n }\n };\n\nconst dragOrDraw =\n (s: State, withDrag: StateMouchBind, withDraw: StateMouchBind): MouchBind =>\n (e) => {\n if (s.drawable.current) {\n if (s.drawable.enabled) withDraw(s, e);\n } else if (!s.viewOnly) withDrag(s, e);\n };\n","import { State } from './state';\nimport { key2pos, createEl, posToTranslate as posToTranslateFromBounds, translate } from './util';\nimport { whitePov } from './board';\nimport { AnimCurrent, AnimVectors, AnimVector, AnimFadings } from './anim';\nimport { DragCurrent } from './drag';\nimport * as cg from './types';\n\ntype PieceName = string; // `$color $role`\n\n// ported from https://github.com/lichess-org/lichobile/blob/master/src/chessground/render.ts\n// in case of bugs, blame @veloce\nexport function render(s: State): void {\n const asWhite: boolean = whitePov(s),\n posToTranslate = posToTranslateFromBounds(s.dom.bounds()),\n boardEl: HTMLElement = s.dom.elements.board,\n pieces: cg.Pieces = s.pieces,\n curAnim: AnimCurrent | undefined = s.animation.current,\n anims: AnimVectors = curAnim ? curAnim.plan.anims : new Map(),\n fadings: AnimFadings = curAnim ? curAnim.plan.fadings : new Map(),\n curDrag: DragCurrent | undefined = s.draggable.current,\n squares: cg.SquareClasses = computeSquareClasses(s),\n samePieces: Set<cg.Key> = new Set(),\n sameSquares: Set<cg.Key> = new Set(),\n movedPieces: Map<PieceName, cg.PieceNode[]> = new Map(),\n movedSquares: Map<string, cg.SquareNode[]> = new Map(); // by class name\n let k: cg.Key,\n el: cg.PieceNode | cg.SquareNode | undefined,\n pieceAtKey: cg.Piece | undefined,\n elPieceName: PieceName,\n anim: AnimVector | undefined,\n fading: cg.Piece | undefined,\n pMvdset: cg.PieceNode[] | undefined,\n pMvd: cg.PieceNode | undefined,\n sMvdset: cg.SquareNode[] | undefined,\n sMvd: cg.SquareNode | undefined;\n\n // walk over all board dom elements, apply animations and flag moved pieces\n el = boardEl.firstChild as cg.PieceNode | cg.SquareNode | undefined;\n while (el) {\n k = el.cgKey;\n if (isPieceNode(el)) {\n pieceAtKey = pieces.get(k);\n anim = anims.get(k);\n fading = fadings.get(k);\n elPieceName = el.cgPiece;\n // if piece not being dragged anymore, remove dragging style\n if (el.cgDragging && (!curDrag || curDrag.orig !== k)) {\n el.classList.remove('dragging');\n translate(el, posToTranslate(key2pos(k), asWhite));\n el.cgDragging = false;\n }\n // remove fading class if it still remains\n if (!fading && el.cgFading) {\n el.cgFading = false;\n el.classList.remove('fading');\n }\n // there is now a piece at this dom key\n if (pieceAtKey) {\n // continue animation if already animating and same piece\n // (otherwise it could animate a captured piece)\n if (anim && el.cgAnimating && elPieceName === pieceNameOf(pieceAtKey)) {\n const pos = key2pos(k);\n pos[0] += anim[2];\n pos[1] += anim[3];\n el.classList.add('anim');\n translate(el, posToTranslate(pos, asWhite));\n } else if (el.cgAnimating) {\n el.cgAnimating = false;\n el.classList.remove('anim');\n translate(el, posToTranslate(key2pos(k), asWhite));\n if (s.addPieceZIndex) el.style.zIndex = posZIndex(key2pos(k), asWhite);\n }\n // same piece: flag as same\n if (elPieceName === pieceNameOf(pieceAtKey) && (!fading || !el.cgFading)) {\n samePieces.add(k);\n }\n // different piece: flag as moved unless it is a fading piece\n else {\n if (fading && elPieceName === pieceNameOf(fading)) {\n el.classList.add('fading');\n el.cgFading = true;\n } else {\n appendValue(movedPieces, elPieceName, el);\n }\n }\n }\n // no piece: flag as moved\n else {\n appendValue(movedPieces, elPieceName, el);\n }\n } else if (isSquareNode(el)) {\n const cn = el.className;\n if (squares.get(k) === cn) sameSquares.add(k);\n else appendValue(movedSquares, cn, el);\n }\n el = el.nextSibling as cg.PieceNode | cg.SquareNode | undefined;\n }\n\n // walk over all squares in current set, apply dom changes to moved squares\n // or append new squares\n for (const [sk, className] of squares) {\n if (!sameSquares.has(sk)) {\n sMvdset = movedSquares.get(className);\n sMvd = sMvdset && sMvdset.pop();\n const translation = posToTranslate(key2pos(sk), asWhite);\n if (sMvd) {\n sMvd.cgKey = sk;\n translate(sMvd, translation);\n } else {\n const squareNode = createEl('square', className) as cg.SquareNode;\n squareNode.cgKey = sk;\n translate(squareNode, translation);\n boardEl.insertBefore(squareNode, boardEl.firstChild);\n }\n }\n }\n\n // walk over all pieces in current set, apply dom changes to moved pieces\n // or append new pieces\n for (const [k, p] of pieces) {\n anim = anims.get(k);\n if (!samePieces.has(k)) {\n pMvdset = movedPieces.get(pieceNameOf(p));\n pMvd = pMvdset && pMvdset.pop();\n // a same piece was moved\n if (pMvd) {\n // apply dom changes\n pMvd.cgKey = k;\n if (pMvd.cgFading) {\n pMvd.classList.remove('fading');\n pMvd.cgFading = false;\n }\n const pos = key2pos(k);\n if (s.addPieceZIndex) pMvd.style.zIndex = posZIndex(pos, asWhite);\n if (anim) {\n pMvd.cgAnimating = true;\n pMvd.classList.add('anim');\n pos[0] += anim[2];\n pos[1] += anim[3];\n }\n translate(pMvd, posToTranslate(pos, asWhite));\n }\n // no piece in moved obj: insert the new piece\n // assumes the new piece is not being dragged\n else {\n const pieceName = pieceNameOf(p),\n pieceNode = createEl('piece', pieceName) as cg.PieceNode,\n pos = key2pos(k);\n\n pieceNode.cgPiece = pieceName;\n pieceNode.cgKey = k;\n if (anim) {\n pieceNode.cgAnimating = true;\n pos[0] += anim[2];\n pos[1] += anim[3];\n }\n translate(pieceNode, posToTranslate(pos, asWhite));\n\n if (s.addPieceZIndex) pieceNode.style.zIndex = posZIndex(pos, asWhite);\n\n boardEl.appendChild(pieceNode);\n }\n }\n }\n\n // remove any element that remains in the moved sets\n for (const nodes of movedPieces.values()) removeNodes(s, nodes);\n for (const nodes of movedSquares.values()) removeNodes(s, nodes);\n}\n\nexport function renderResized(s: State): void {\n const asWhite: boolean = whitePov(s),\n posToTranslate = posToTranslateFromBounds(s.dom.bounds());\n let el = s.dom.elements.board.firstChild as cg.PieceNode | cg.SquareNode | undefined;\n while (el) {\n if ((isPieceNode(el) && !el.cgAnimating) || isSquareNode(el)) {\n translate(el, posToTranslate(key2pos(el.cgKey), asWhite));\n }\n el = el.nextSibling as cg.PieceNode | cg.SquareNode | undefined;\n }\n}\n\nexport function updateBounds(s: State): void {\n const bounds = s.dom.elements.wrap.getBoundingClientRect();\n const container = s.dom.elements.container;\n const ratio = bounds.height / bounds.width;\n const width = (Math.floor((bounds.width * window.devicePixelRatio) / 8) * 8) / window.devicePixelRatio;\n const height = width * ratio;\n container.style.width = width + 'px';\n container.style.height = height + 'px';\n s.dom.bounds.clear();\n\n s.addDimensionsCssVarsTo?.style.setProperty('---cg-width', width + 'px');\n s.addDimensionsCssVarsTo?.style.setProperty('---cg-height', height + 'px');\n}\n\nconst isPieceNode = (el: cg.PieceNode | cg.SquareNode): el is cg.PieceNode => el.tagName === 'PIECE';\nconst isSquareNode = (el: cg.PieceNode | cg.SquareNode): el is cg.SquareNode => el.tagName === 'SQUARE';\n\nfunction removeNodes(s: State, nodes: HTMLElement[]): void {\n for (const node of nodes) s.dom.elements.board.removeChild(node);\n}\n\nfunction posZIndex(pos: cg.Pos, asWhite: boolean): string {\n const minZ = 3;\n const rank = pos[1];\n const z = asWhite ? minZ + 7 - rank : minZ + rank;\n\n return `${z}`;\n}\n\nconst pieceNameOf = (piece: cg.Piece): string => `${piece.color} ${piece.role}`;\n\nfunction computeSquareClasses(s: State): cg.SquareClasses {\n const squares: cg.SquareClasses = new Map();\n if (s.lastMove && s.highlight.lastMove)\n for (const k of s.lastMove) {\n addSquare(squares, k, 'last-move');\n }\n if (s.check && s.highlight.check) addSquare(squares, s.check, 'check');\n if (s.selected) {\n addSquare(squares, s.selected, 'selected');\n if (s.movable.showDests) {\n const dests = s.movable.dests?.get(s.selected);\n if (dests)\n for (const k of dests) {\n addSquare(squares, k, 'move-dest' + (s.pieces.has(k) ? ' oc' : ''));\n }\n const pDests = s.premovable.customDests?.get(s.selected) ?? s.premovable.dests;\n if (pDests)\n for (const k of pDests) {\n addSquare(squares, k, 'premove-dest' + (s.pieces.has(k) ? ' oc' : ''));\n }\n }\n }\n const premove = s.premovable.current;\n if (premove) for (const k of premove) addSquare(squares, k, 'current-premove');\n else if (s.predroppable.current) addSquare(squares, s.predroppable.current.key, 'current-premove');\n\n const o = s.exploding;\n if (o) for (const k of o.keys) addSquare(squares, k, 'exploding' + o.stage);\n\n if (s.highlight.custom) {\n s.highlight.custom.forEach((v: string, k: cg.Key) => {\n addSquare(squares, k, v);\n });\n }\n\n return squares;\n}\n\nfunction addSquare(squares: cg.SquareClasses, key: cg.Key, klass: string): void {\n const classes = squares.get(key);\n if (classes) squares.set(key, `${classes} ${klass}`);\n else squares.set(key, klass);\n}\n\nfunction appendValue<K, V>(map: Map<K, V[]>, key: K, value: V): void {\n const arr = map.get(key);\n if (arr) arr.push(value);\n else map.set(key, [value]);\n}\n","import { DrawShape } from './draw';\n\nexport interface SyncableShape {\n shape: DrawShape;\n current: boolean;\n hash: Hash;\n}\n\nexport type Hash = string;\n\n// append and remove only. No updates.\nexport function syncShapes(\n shapes: SyncableShape[],\n root: HTMLElement | SVGElement,\n renderShape: (shape: SyncableShape) => HTMLElement | SVGElement,\n): void {\n const hashesInDom = new Map(), // by hash\n toRemove: SVGElement[] = [];\n for (const sc of shapes) hashesInDom.set(sc.hash, false);\n let el: SVGElement | undefined = root.firstElementChild as SVGElement,\n elHash: Hash | null;\n while (el) {\n elHash = el.getAttribute('cgHash') as Hash;\n // found a shape element that's here to stay\n if (hashesInDom.has(elHash)) hashesInDom.set(elHash, true);\n // or remove it\n else toRemove.push(el);\n el = el.nextElementSibling as SVGElement | undefined;\n }\n // remove old shapes\n for (const el of toRemove) root.removeChild(el);\n // insert shapes that are not yet in dom\n for (const sc of shapes) {\n if (!hashesInDom.get(sc.hash)) root.appendChild(renderShape(sc));\n }\n}\n","import { State } from './state';\nimport { key2pos, createEl, posToTranslate as posToTranslateFromBounds, translateAndScale } from './util';\nimport { whitePov } from './board';\nimport * as cg from './types';\nimport { DrawShape } from './draw';\nimport { SyncableShape, Hash, syncShapes } from './sync';\n\nexport function render(state: State, autoPieceEl: HTMLElement): void {\n const autoPieces = state.drawable.autoShapes.filter(autoShape => autoShape.piece);\n const autoPieceShapes: SyncableShape[] = autoPieces.map((s: DrawShape) => {\n return {\n shape: s,\n hash: hash(s),\n current: false,\n };\n });\n\n syncShapes(autoPieceShapes, autoPieceEl, shape => renderShape(state, shape, state.dom.bounds()));\n}\n\nexport function renderResized(state: State): void {\n const asWhite: boolean = whitePov(state),\n posToTranslate = posToTranslateFromBounds(state.dom.bounds());\n let el = state.dom.elements.autoPieces?.firstChild as cg.PieceNode | undefined;\n while (el) {\n translateAndScale(el, posToTranslate(key2pos(el.cgKey), asWhite), el.cgScale);\n el = el.nextSibling as cg.PieceNode | undefined;\n }\n}\n\nfunction renderShape(state: State, { shape, hash }: SyncableShape, bounds: DOMRectReadOnly): cg.PieceNode {\n const orig = shape.orig;\n const role = shape.piece?.role;\n const color = shape.piece?.color;\n const scale = shape.piece?.scale;\n\n const pieceEl = createEl('piece', `${role} ${color}`) as cg.PieceNode;\n pieceEl.setAttribute('cgHash', hash);\n pieceEl.cgKey = orig;\n pieceEl.cgScale = scale;\n translateAndScale(pieceEl, posToTranslateFromBounds(bounds)(key2pos(orig), whitePov(state)), scale);\n\n return pieceEl;\n}\n\nconst hash = (autoPiece: DrawShape): Hash =>\n [autoPiece.orig, autoPiece.piece?.role, autoPiece.piece?.color, autoPiece.piece?.scale].join(',');\n","import { Api, start } from './api';\nimport { Config, configure } from './config';\nimport { HeadlessState, State, defaults } from './state';\n\nimport { renderWrap } from './wrap';\nimport * as events from './events';\nimport { render, renderResized, updateBounds } from './render';\nimport * as autoPieces from './autoPieces';\nimport * as svg from './svg';\nimport * as util from './util';\n\nexport function initModule({ el, config }: { el: HTMLElement; config?: Config }): Api {\n return Chessground(el, config);\n}\n\nexport function Chessground(element: HTMLElement, config?: Config): Api {\n const maybeState: State | HeadlessState = defaults();\n\n configure(maybeState, config || {});\n\n function redrawAll(): State {\n const prevUnbind = 'dom' in maybeState ? maybeState.dom.unbind : undefined;\n // compute bounds from existing board element if possible\n // this allows non-square boards from CSS to be handled (for 3D)\n const elements = renderWrap(element, maybeState),\n bounds = util.memo(() => elements.board.getBoundingClientRect()),\n redrawNow = (skipSvg?: boolean): void => {\n render(state);\n if (elements.autoPieces) autoPieces.render(state, elements.autoPieces);\n if (!skipSvg && elements.svg) svg.renderSvg(state, elements.svg, elements.customSvg!);\n },\n onResize = (): void => {\n updateBounds(state);\n renderResized(state);\n if (elements.autoPieces) autoPieces.renderResized(state);\n };\n const state = maybeState as State;\n state.dom = {\n elements,\n bounds,\n redraw: debounceRedraw(redrawNow),\n redrawNow,\n unbind: prevUnbind,\n };\n state.drawable.prevSvgHash = '';\n updateBounds(state);\n redrawNow(false);\n events.bindBoard(state);\n if (!prevUnbind) state.dom.unbind = events.bindDocument(state, onResize);\n state.events.insert?.(elements);\n return state;\n }\n\n return start(redrawAll(), redrawAll);\n}\n\nfunction debounceRedraw(redrawNow: (skipSvg?: boolean) => void): () => void {\n let redrawing = false;\n return () => {\n if (redrawing) return;\n redrawing = true;\n requestAnimationFrame(() => {\n redrawNow();\n redrawing = false;\n });\n };\n}\n","/**\n * @license\n * Copyright (c) 2025, Jeff Hlywa (jhlywa@gmail.com)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n * this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the documentation\n * and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n * POSSIBILITY OF SUCH DAMAGE.\n */\nexport const WHITE = 'w';\nexport const BLACK = 'b';\nexport const PAWN = 'p';\nexport const KNIGHT = 'n';\nexport const BISHOP = 'b';\nexport const ROOK = 'r';\nexport const QUEEN = 'q';\nexport const KING = 'k';\nexport const DEFAULT_POSITION = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1';\nexport class Move {\n color;\n from;\n to;\n piece;\n captured;\n promotion;\n /**\n * @deprecated This field is deprecated and will be removed in version 2.0.0.\n * Please use move descriptor functions instead: `isCapture`, `isPromotion`,\n * `isEnPassant`, `isKingsideCastle`, `isQueensideCastle`, `isCastle`, and\n * `isBigPawn`\n */\n flags;\n san;\n lan;\n before;\n after;\n constructor(chess, internal) {\n const { color, piece, from, to, flags, captured, promotion } = internal;\n const fromAlgebraic = algebraic(from);\n const toAlgebraic = algebraic(to);\n this.color = color;\n this.piece = piece;\n this.from = fromAlgebraic;\n this.to = toAlgebraic;\n /*\n * HACK: The chess['_method']() calls below invoke private methods in the\n * Chess class to generate SAN and FEN. It's a bit of a hack, but makes the\n * code cleaner elsewhere.\n */\n this.san = chess['_moveToSan'](internal, chess['_moves']({ legal: true }));\n this.lan = fromAlgebraic + toAlgebraic;\n this.before = chess.fen();\n // Generate the FEN for the 'after' key\n chess['_makeMove'](internal);\n this.after = chess.fen();\n chess['_undoMove']();\n // Build the text representation of the move flags\n this.flags = '';\n for (const flag in BITS) {\n if (BITS[flag] & flags) {\n this.flags += FLAGS[flag];\n }\n }\n if (captured) {\n this.captured = captured;\n }\n if (promotion) {\n this.promotion = promotion;\n this.lan += promotion;\n }\n }\n isCapture() {\n return this.flags.indexOf(FLAGS['CAPTURE']) > -1;\n }\n isPromotion() {\n return this.flags.indexOf(FLAGS['PROMOTION']) > -1;\n }\n isEnPassant() {\n return this.flags.indexOf(FLAGS['EP_CAPTURE']) > -1;\n }\n isKingsideCastle() {\n return this.flags.indexOf(FLAGS['KSIDE_CASTLE']) > -1;\n }\n isQueensideCastle() {\n return this.flags.indexOf(FLAGS['QSIDE_CASTLE']) > -1;\n }\n isBigPawn() {\n return this.flags.indexOf(FLAGS['BIG_PAWN']) > -1;\n }\n}\nconst EMPTY = -1;\nconst FLAGS = {\n NORMAL: 'n',\n CAPTURE: 'c',\n BIG_PAWN: 'b',\n EP_CAPTURE: 'e',\n PROMOTION: 'p',\n KSIDE_CASTLE: 'k',\n QSIDE_CASTLE: 'q',\n};\n// prettier-ignore\nexport const SQUARES = [\n 'a8', 'b8', 'c8', 'd8', 'e8', 'f8', 'g8', 'h8',\n 'a7', 'b7', 'c7', 'd7', 'e7', 'f7', 'g7', 'h7',\n 'a6', 'b6', 'c6', 'd6', 'e6', 'f6', 'g6', 'h6',\n 'a5', 'b5', 'c5', 'd5', 'e5', 'f5', 'g5', 'h5',\n 'a4', 'b4', 'c4', 'd4', 'e4', 'f4', 'g4', 'h4',\n 'a3', 'b3', 'c3', 'd3', 'e3', 'f3', 'g3', 'h3',\n 'a2', 'b2', 'c2', 'd2', 'e2', 'f2', 'g2', 'h2',\n 'a1', 'b1', 'c1', 'd1', 'e1', 'f1', 'g1', 'h1'\n];\nconst BITS = {\n NORMAL: 1,\n CAPTURE: 2,\n BIG_PAWN: 4,\n EP_CAPTURE: 8,\n PROMOTION: 16,\n KSIDE_CASTLE: 32,\n QSIDE_CASTLE: 64,\n};\n/*\n * NOTES ABOUT 0x88 MOVE GENERATION ALGORITHM\n * ----------------------------------------------------------------------------\n * From https://github.com/jhlywa/chess.js/issues/230\n *\n * A lot of people are confused when they first see the internal representation\n * of chess.js. It uses the 0x88 Move Generation Algorithm which internally\n * stores the board as an 8x16 array. This is purely for efficiency but has a\n * couple of interesting benefits:\n *\n * 1. 0x88 offers a very inexpensive \"off the board\" check. Bitwise AND (&) any\n * square with 0x88, if the result is non-zero then the square is off the\n * board. For example, assuming a knight square A8 (0 in 0x88 notation),\n * there are 8 possible directions in which the knight can move. These\n * directions are relative to the 8x16 board and are stored in the\n * PIECE_OFFSETS map. One possible move is A8 - 18 (up one square, and two\n * squares to the left - which is off the board). 0 - 18 = -18 & 0x88 = 0x88\n * (because of two-complement representation of -18). The non-zero result\n * means the square is off the board and the move is illegal. Take the\n * opposite move (from A8 to C7), 0 + 18 = 18 & 0x88 = 0. A result of zero\n * means the square is on the board.\n *\n * 2. The relative distance (or difference) between two squares on a 8x16 board\n * is unique and can be used to inexpensively determine if a piece on a\n * square can attack any other arbitrary square. For example, let's see if a\n * pawn on E7 can attack E2. The difference between E7 (20) - E2 (100) is\n * -80. We add 119 to make the ATTACKS array index non-negative (because the\n * worst case difference is A8 - H1 = -119). The ATTACKS array contains a\n * bitmask of pieces that can attack from that distance and direction.\n * ATTACKS[-80 + 119=39] gives us 24 or 0b11000 in binary. Look at the\n * PIECE_MASKS map to determine the mask for a given piece type. In our pawn\n * example, we would check to see if 24 & 0x1 is non-zero, which it is\n * not. So, naturally, a pawn on E7 can't attack a piece on E2. However, a\n * rook can since 24 & 0x8 is non-zero. The only thing left to check is that\n * there are no blocking pieces between E7 and E2. That's where the RAYS\n * array comes in. It provides an offset (in this case 16) to add to E7 (20)\n * to check for blocking pieces. E7 (20) + 16 = E6 (36) + 16 = E5 (52) etc.\n */\n// prettier-ignore\n// eslint-disable-next-line\nconst Ox88 = {\n a8: 0, b8: 1, c8: 2, d8: 3, e8: 4, f8: 5, g8: 6, h8: 7,\n a7: 16, b7: 17, c7: 18, d7: 19, e7: 20, f7: 21, g7: 22, h7: 23,\n a6: 32, b6: 33, c6: 34, d6: 35, e6: 36, f6: 37, g6: 38, h6: 39,\n a5: 48, b5: 49, c5: 50, d5: 51, e5: 52, f5: 53, g5: 54, h5: 55,\n a4: 64, b4: 65, c4: 66, d4: 67, e4: 68, f4: 69, g4: 70, h4: 71,\n a3: 80, b3: 81, c3: 82, d3: 83, e3: 84, f3: 85, g3: 86, h3: 87,\n a2: 96, b2: 97, c2: 98, d2: 99, e2: 100, f2: 101, g2: 102, h2: 103,\n a1: 112, b1: 113, c1: 114, d1: 115, e1: 116, f1: 117, g1: 118, h1: 119\n};\nconst PAWN_OFFSETS = {\n b: [16, 32, 17, 15],\n w: [-16, -32, -17, -15],\n};\nconst PIECE_OFFSETS = {\n n: [-18, -33, -31, -14, 18, 33, 31, 14],\n b: [-17, -15, 17, 15],\n r: [-16, 1, 16, -1],\n q: [-17, -16, -15, 1, 17, 16, 15, -1],\n k: [-17, -16, -15, 1, 17, 16, 15, -1],\n};\n// prettier-ignore\nconst ATTACKS = [\n 20, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 20, 0,\n 0, 20, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 20, 0, 0,\n 0, 0, 20, 0, 0, 0, 0, 24, 0, 0, 0, 0, 20, 0, 0, 0,\n 0, 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, 20, 0, 0, 0, 0,\n 0, 0, 0, 0, 20, 0, 0, 24, 0, 0, 20, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 20, 2, 24, 2, 20, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 2, 53, 56, 53, 2, 0, 0, 0, 0, 0, 0,\n 24, 24, 24, 24, 24, 24, 56, 0, 56, 24, 24, 24, 24, 24, 24, 0,\n 0, 0, 0, 0, 0, 2, 53, 56, 53, 2, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 20, 2, 24, 2, 20, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 20, 0, 0, 24, 0, 0, 20, 0, 0, 0, 0, 0,\n 0, 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, 20, 0, 0, 0, 0,\n 0, 0, 20, 0, 0, 0, 0, 24, 0, 0, 0, 0, 20, 0, 0, 0,\n 0, 20, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 20, 0, 0,\n 20, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 20\n];\n// prettier-ignore\nconst RAYS = [\n 17, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 15, 0,\n 0, 17, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 15, 0, 0,\n 0, 0, 17, 0, 0, 0, 0, 16, 0, 0, 0, 0, 15, 0, 0, 0,\n 0, 0, 0, 17, 0, 0, 0, 16, 0, 0, 0, 15, 0, 0, 0, 0,\n 0, 0, 0, 0, 17, 0, 0, 16, 0, 0, 15, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 17, 0, 16, 0, 15, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 17, 16, 15, 0, 0, 0, 0, 0, 0, 0,\n 1, 1, 1, 1, 1, 1, 1, 0, -1, -1, -1, -1, -1, -1, -1, 0,\n 0, 0, 0, 0, 0, 0, -15, -16, -17, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, -15, 0, -16, 0, -17, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, -15, 0, 0, -16, 0, 0, -17, 0, 0, 0, 0, 0,\n 0, 0, 0, -15, 0, 0, 0, -16, 0, 0, 0, -17, 0, 0, 0, 0,\n 0, 0, -15, 0, 0, 0, 0, -16, 0, 0, 0, 0, -17, 0, 0, 0,\n 0, -15, 0, 0, 0, 0, 0, -16, 0, 0, 0, 0, 0, -17, 0, 0,\n -15, 0, 0, 0, 0, 0, 0, -16, 0, 0, 0, 0, 0, 0, -17\n];\nconst PIECE_MASKS = { p: 0x1, n: 0x2, b: 0x4, r: 0x8, q: 0x10, k: 0x20 };\nconst SYMBOLS = 'pnbrqkPNBRQK';\nconst PROMOTIONS = [KNIGHT, BISHOP, ROOK, QUEEN];\nconst RANK_1 = 7;\nconst RANK_2 = 6;\n/*\n * const RANK_3 = 5\n * const RANK_4 = 4\n * const RANK_5 = 3\n * const RANK_6 = 2\n */\nconst RANK_7 = 1;\nconst RANK_8 = 0;\nconst SIDES = {\n [KING]: BITS.KSIDE_CASTLE,\n [QUEEN]: BITS.QSIDE_CASTLE,\n};\nconst ROOKS = {\n w: [\n { square: Ox88.a1, flag: BITS.QSIDE_CASTLE },\n { square: Ox88.h1, flag: BITS.KSIDE_CASTLE },\n ],\n b: [\n { square: Ox88.a8, flag: BITS.QSIDE_CASTLE },\n { square: Ox88.h8, flag: BITS.KSIDE_CASTLE },\n ],\n};\nconst SECOND_RANK = { b: RANK_7, w: RANK_2 };\nconst TERMINATION_MARKERS = ['1-0', '0-1', '1/2-1/2', '*'];\n// Extracts the zero-based rank of an 0x88 square.\nfunction rank(square) {\n return square >> 4;\n}\n// Extracts the zero-based file of an 0x88 square.\nfunction file(square) {\n return square & 0xf;\n}\nfunction isDigit(c) {\n return '0123456789'.indexOf(c) !== -1;\n}\n// Converts a 0x88 square to algebraic notation.\nfunction algebraic(square) {\n const f = file(square);\n const r = rank(square);\n return ('abcdefgh'.substring(f, f + 1) +\n '87654321'.substring(r, r + 1));\n}\nfunction swapColor(color) {\n return color === WHITE ? BLACK : WHITE;\n}\nexport function validateFen(fen) {\n // 1st criterion: 6 space-seperated fields?\n const tokens = fen.split(/\\s+/);\n if (tokens.length !== 6) {\n return {\n ok: false,\n error: 'Invalid FEN: must contain six space-delimited fields',\n };\n }\n // 2nd criterion: move number field is a integer value > 0?\n const moveNumber = parseInt(tokens[5], 10);\n if (isNaN(moveNumber) || moveNumber <= 0) {\n return {\n ok: false,\n error: 'Invalid FEN: move number must be a positive integer',\n };\n }\n // 3rd criterion: half move counter is an integer >= 0?\n const halfMoves = parseInt(tokens[4], 10);\n if (isNaN(halfMoves) || halfMoves < 0) {\n return {\n ok: false,\n error: 'Invalid FEN: half move counter number must be a non-negative integer',\n };\n }\n // 4th criterion: 4th field is a valid e.p.-string?\n if (!/^(-|[abcdefgh][36])$/.test(tokens[3])) {\n return { ok: false, error: 'Invalid FEN: en-passant square is invalid' };\n }\n // 5th criterion: 3th field is a valid castle-string?\n if (/[^kKqQ-]/.test(tokens[2])) {\n return { ok: false, error: 'Invalid FEN: castling availability is invalid' };\n }\n // 6th criterion: 2nd field is \"w\" (white) or \"b\" (black)?\n if (!/^(w|b)$/.test(tokens[1])) {\n return { ok: false, error: 'Invalid FEN: side-to-move is invalid' };\n }\n // 7th criterion: 1st field contains 8 rows?\n const rows = tokens[0].split('/');\n if (rows.length !== 8) {\n return {\n ok: false,\n error: \"Invalid FEN: piece data does not contain 8 '/'-delimited rows\",\n };\n }\n // 8th criterion: every row is valid?\n for (let i = 0; i < rows.length; i++) {\n // check for right sum of fields AND not two numbers in succession\n let sumFields = 0;\n let previousWasNumber = false;\n for (let k = 0; k < rows[i].length; k++) {\n if (isDigit(rows[i][k])) {\n if (previousWasNumber) {\n return {\n ok: false,\n error: 'Invalid FEN: piece data is invalid (consecutive number)',\n };\n }\n sumFields += parseInt(rows[i][k], 10);\n previousWasNumber = true;\n }\n else {\n if (!/^[prnbqkPRNBQK]$/.test(rows[i][k])) {\n return {\n ok: false,\n error: 'Invalid FEN: piece data is invalid (invalid piece)',\n };\n }\n sumFields += 1;\n previousWasNumber = false;\n }\n }\n if (sumFields !== 8) {\n return {\n ok: false,\n error: 'Invalid FEN: piece data is invalid (too many squares in rank)',\n };\n }\n }\n // 9th criterion: is en-passant square legal?\n if ((tokens[3][1] == '3' && tokens[1] == 'w') ||\n (tokens[3][1] == '6' && tokens[1] == 'b')) {\n return { ok: false, error: 'Invalid FEN: illegal en-passant square' };\n }\n // 10th criterion: does chess position contain exact two kings?\n const kings = [\n { color: 'white', regex: /K/g },\n { color: 'black', regex: /k/g },\n ];\n for (const { color, regex } of kings) {\n if (!regex.test(tokens[0])) {\n return { ok: false, error: `Invalid FEN: missing ${color} king` };\n }\n if ((tokens[0].match(regex) || []).length > 1) {\n return { ok: false, error: `Invalid FEN: too many ${color} kings` };\n }\n }\n // 11th criterion: are any pawns on the first or eighth rows?\n if (Array.from(rows[0] + rows[7]).some((char) => char.toUpperCase() === 'P')) {\n return {\n ok: false,\n error: 'Invalid FEN: some pawns are on the edge rows',\n };\n }\n return { ok: true };\n}\n// this function is used to uniquely identify ambiguous moves\nfunction getDisambiguator(move, moves) {\n const from = move.from;\n const to = move.to;\n const piece = move.piece;\n let ambiguities = 0;\n let sameRank = 0;\n let sameFile = 0;\n for (let i = 0, len = moves.length; i < len; i++) {\n const ambigFrom = moves[i].from;\n const ambigTo = moves[i].to;\n const ambigPiece = moves[i].piece;\n /*\n * if a move of the same piece type ends on the same to square, we'll need\n * to add a disambiguator to the algebraic notation\n */\n if (piece === ambigPiece && from !== ambigFrom && to === ambigTo) {\n ambiguities++;\n if (rank(from) === rank(ambigFrom)) {\n sameRank++;\n }\n if (file(from) === file(ambigFrom)) {\n sameFile++;\n }\n }\n }\n if (ambiguities > 0) {\n if (sameRank > 0 && sameFile > 0) {\n /*\n * if there exists a similar moving piece on the same rank and file as\n * the move in question, use the square as the disambiguator\n */\n return algebraic(from);\n }\n else if (sameFile > 0) {\n /*\n * if the moving piece rests on the same file, use the rank symbol as the\n * disambiguator\n */\n return algebraic(from).charAt(1);\n }\n else {\n // else use the file symbol\n return algebraic(from).charAt(0);\n }\n }\n return '';\n}\nfunction addMove(moves, color, from, to, piece, captured = undefined, flags = BITS.NORMAL) {\n const r = rank(to);\n if (piece === PAWN && (r === RANK_1 || r === RANK_8)) {\n for (let i = 0; i < PROMOTIONS.length; i++) {\n const promotion = PROMOTIONS[i];\n moves.push({\n color,\n from,\n to,\n piece,\n captured,\n promotion,\n flags: flags | BITS.PROMOTION,\n });\n }\n }\n else {\n moves.push({\n color,\n from,\n to,\n piece,\n captured,\n flags,\n });\n }\n}\nfunction inferPieceType(san) {\n let pieceType = san.charAt(0);\n if (pieceType >= 'a' && pieceType <= 'h') {\n const matches = san.match(/[a-h]\\d.*[a-h]\\d/);\n if (matches) {\n return undefined;\n }\n return PAWN;\n }\n pieceType = pieceType.toLowerCase();\n if (pieceType === 'o') {\n return KING;\n }\n return pieceType;\n}\n// parses all of the decorators out of a SAN string\nfunction strippedSan(move) {\n return move.replace(/=/, '').replace(/[+#]?[?!]*$/, '');\n}\nfunction trimFen(fen) {\n /*\n * remove last two fields in FEN string as they're not needed when checking\n * for repetition\n */\n return fen.split(' ').slice(0, 4).join(' ');\n}\nexport class Chess {\n _board = new Array(128);\n _turn = WHITE;\n _header = {};\n _kings = { w: EMPTY, b: EMPTY };\n _epSquare = -1;\n _halfMoves = 0;\n _moveNumber = 0;\n _history = [];\n _comments = {};\n _castling = { w: 0, b: 0 };\n // tracks number of times a position has been seen for repetition checking\n _positionCount = {};\n constructor(fen = DEFAULT_POSITION, { skipValidation = false } = {}) {\n this.load(fen, { skipValidation });\n }\n clear({ preserveHeaders = false } = {}) {\n this._board = new Array(128);\n this._kings = { w: EMPTY, b: EMPTY };\n this._turn = WHITE;\n this._castling = { w: 0, b: 0 };\n this._epSquare = EMPTY;\n this._halfMoves = 0;\n this._moveNumber = 1;\n this._history = [];\n this._comments = {};\n this._header = preserveHeaders ? this._header : {};\n this._positionCount = {};\n /*\n * Delete the SetUp and FEN headers (if preserved), the board is empty and\n * these headers don't make sense in this state. They'll get added later\n * via .load() or .put()\n */\n delete this._header['SetUp'];\n delete this._header['FEN'];\n }\n load(fen, { skipValidation = false, preserveHeaders = false } = {}) {\n let tokens = fen.split(/\\s+/);\n // append commonly omitted fen tokens\n if (tokens.length >= 2 && tokens.length < 6) {\n const adjustments = ['-', '-', '0', '1'];\n fen = tokens.concat(adjustments.slice(-(6 - tokens.length))).join(' ');\n }\n tokens = fen.split(/\\s+/);\n if (!skipValidation) {\n const { ok, error } = validateFen(fen);\n if (!ok) {\n throw new Error(error);\n }\n }\n const position = tokens[0];\n let square = 0;\n this.clear({ preserveHeaders });\n for (let i = 0; i < position.length; i++) {\n const piece = position.charAt(i);\n if (piece === '/') {\n square += 8;\n }\n else if (isDigit(piece)) {\n square += parseInt(piece, 10);\n }\n else {\n const color = piece < 'a' ? WHITE : BLACK;\n this._put({ type: piece.toLowerCase(), color }, algebraic(square));\n square++;\n }\n }\n this._turn = tokens[1];\n if (tokens[2].indexOf('K') > -1) {\n this._castling.w |= BITS.KSIDE_CASTLE;\n }\n if (tokens[2].indexOf('Q') > -1) {\n this._castling.w |= BITS.QSIDE_CASTLE;\n }\n if (tokens[2].indexOf('k') > -1) {\n this._castling.b |= BITS.KSIDE_CASTLE;\n }\n if (tokens[2].indexOf('q') > -1) {\n this._castling.b |= BITS.QSIDE_CASTLE;\n }\n this._epSquare = tokens[3] === '-' ? EMPTY : Ox88[tokens[3]];\n this._halfMoves = parseInt(tokens[4], 10);\n this._moveNumber = parseInt(tokens[5], 10);\n this._updateSetup(fen);\n this._incPositionCount(fen);\n }\n fen() {\n let empty = 0;\n let fen = '';\n for (let i = Ox88.a8; i <= Ox88.h1; i++) {\n if (this._board[i]) {\n if (empty > 0) {\n fen += empty;\n empty = 0;\n }\n const { color, type: piece } = this._board[i];\n fen += color === WHITE ? piece.toUpperCase() : piece.toLowerCase();\n }\n else {\n empty++;\n }\n if ((i + 1) & 0x88) {\n if (empty > 0) {\n fen += empty;\n }\n if (i !== Ox88.h1) {\n fen += '/';\n }\n empty = 0;\n i += 8;\n }\n }\n let castling = '';\n if (this._castling[WHITE] & BITS.KSIDE_CASTLE) {\n castling += 'K';\n }\n if (this._castling[WHITE] & BITS.QSIDE_CASTLE) {\n castling += 'Q';\n }\n if (this._castling[BLACK] & BITS.KSIDE_CASTLE) {\n castling += 'k';\n }\n if (this._castling[BLACK] & BITS.QSIDE_CASTLE) {\n castling += 'q';\n }\n // do we have an empty castling flag?\n castling = castling || '-';\n let epSquare = '-';\n /*\n * only print the ep square if en passant is a valid move (pawn is present\n * and ep capture is not pinned)\n */\n if (this._epSquare !== EMPTY) {\n const bigPawnSquare = this._epSquare + (this._turn === WHITE ? 16 : -16);\n const squares = [bigPawnSquare + 1, bigPawnSquare - 1];\n for (const square of squares) {\n // is the square off the board?\n if (square & 0x88) {\n continue;\n }\n const color = this._turn;\n // is there a pawn that can capture the epSquare?\n if (this._board[square]?.color === color &&\n this._board[square]?.type === PAWN) {\n // if the pawn makes an ep capture, does it leave it's king in check?\n this._makeMove({\n color,\n from: square,\n to: this._epSquare,\n piece: PAWN,\n captured: PAWN,\n flags: BITS.EP_CAPTURE,\n });\n const isLegal = !this._isKingAttacked(color);\n this._undoMove();\n // if ep is legal, break and set the ep square in the FEN output\n if (isLegal) {\n epSquare = algebraic(this._epSquare);\n break;\n }\n }\n }\n }\n return [\n fen,\n this._turn,\n castling,\n epSquare,\n this._halfMoves,\n this._moveNumber,\n ].join(' ');\n }\n /*\n * Called when the initial board setup is changed with put() or remove().\n * modifies the SetUp and FEN properties of the header object. If the FEN\n * is equal to the default position, the SetUp and FEN are deleted the setup\n * is only updated if history.length is zero, ie moves haven't been made.\n */\n _updateSetup(fen) {\n if (this._history.length > 0)\n return;\n if (fen !== DEFAULT_POSITION) {\n this._header['SetUp'] = '1';\n this._header['FEN'] = fen;\n }\n else {\n delete this._header['SetUp'];\n delete this._header['FEN'];\n }\n }\n reset() {\n this.load(DEFAULT_POSITION);\n }\n get(square) {\n return this._board[Ox88[square]];\n }\n put({ type, color }, square) {\n if (this._put({ type, color }, square)) {\n this._updateCastlingRights();\n this._updateEnPassantSquare();\n this._updateSetup(this.fen());\n return true;\n }\n return false;\n }\n _put({ type, color }, square) {\n // check for piece\n if (SYMBOLS.indexOf(type.toLowerCase()) === -1) {\n return false;\n }\n // check for valid square\n if (!(square in Ox88)) {\n return false;\n }\n const sq = Ox88[square];\n // don't let the user place more than one king\n if (type == KING &&\n !(this._kings[color] == EMPTY || this._kings[color] == sq)) {\n return false;\n }\n const currentPieceOnSquare = this._board[sq];\n // if one of the kings will be replaced by the piece from args, set the `_kings` respective entry to `EMPTY`\n if (currentPieceOnSquare && currentPieceOnSquare.type === KING) {\n this._kings[currentPieceOnSquare.color] = EMPTY;\n }\n this._board[sq] = { type: type, color: color };\n if (type === KING) {\n this._kings[color] = sq;\n }\n return true;\n }\n remove(square) {\n const piece = this.get(square);\n delete this._board[Ox88[square]];\n if (piece && piece.type === KING) {\n this._kings[piece.color] = EMPTY;\n }\n this._updateCastlingRights();\n this._updateEnPassantSquare();\n this._updateSetup(this.fen());\n return piece;\n }\n _updateCastlingRights() {\n const whiteKingInPlace = this._board[Ox88.e1]?.type === KING &&\n this._board[Ox88.e1]?.color === WHITE;\n const blackKingInPlace = this._board[Ox88.e8]?.type === KING &&\n this._board[Ox88.e8]?.color === BLACK;\n if (!whiteKingInPlace ||\n this._board[Ox88.a1]?.type !== ROOK ||\n this._board[Ox88.a1]?.color !== WHITE) {\n this._castling.w &= ~BITS.QSIDE_CASTLE;\n }\n if (!whiteKingInPlace ||\n this._board[Ox88.h1]?.type !== ROOK ||\n this._board[Ox88.h1]?.color !== WHITE) {\n this._castling.w &= ~BITS.KSIDE_CASTLE;\n }\n if (!blackKingInPlace ||\n this._board[Ox88.a8]?.type !== ROOK ||\n this._board[Ox88.a8]?.color !== BLACK) {\n this._castling.b &= ~BITS.QSIDE_CASTLE;\n }\n if (!blackKingInPlace ||\n this._board[Ox88.h8]?.type !== ROOK ||\n this._board[Ox88.h8]?.color !== BLACK) {\n this._castling.b &= ~BITS.KSIDE_CASTLE;\n }\n }\n _updateEnPassantSquare() {\n if (this._epSquare === EMPTY) {\n return;\n }\n const startSquare = this._epSquare + (this._turn === WHITE ? -16 : 16);\n const currentSquare = this._epSquare + (this._turn === WHITE ? 16 : -16);\n const attackers = [currentSquare + 1, currentSquare - 1];\n if (this._board[startSquare] !== null ||\n this._board[this._epSquare] !== null ||\n this._board[currentSquare]?.color !== swapColor(this._turn) ||\n this._board[currentSquare]?.type !== PAWN) {\n this._epSquare = EMPTY;\n return;\n }\n const canCapture = (square) => !(square & 0x88) &&\n this._board[square]?.color === this._turn &&\n this._board[square]?.type === PAWN;\n if (!attackers.some(canCapture)) {\n this._epSquare = EMPTY;\n }\n }\n _attacked(color, square, verbose) {\n const attackers = [];\n for (let i = Ox88.a8; i <= Ox88.h1; i++) {\n // did we run off the end of the board\n if (i & 0x88) {\n i += 7;\n continue;\n }\n // if empty square or wrong color\n if (this._board[i] === undefined || this._board[i].color !== color) {\n continue;\n }\n const piece = this._board[i];\n const difference = i - square;\n // skip - to/from square are the same\n if (difference === 0) {\n continue;\n }\n const index = difference + 119;\n if (ATTACKS[index] & PIECE_MASKS[piece.type]) {\n if (piece.type === PAWN) {\n if ((difference > 0 && piece.color === WHITE) ||\n (difference <= 0 && piece.color === BLACK)) {\n if (!verbose) {\n return true;\n }\n else {\n attackers.push(algebraic(i));\n }\n }\n continue;\n }\n // if the piece is a knight or a king\n if (piece.type === 'n' || piece.type === 'k') {\n if (!verbose) {\n return true;\n }\n else {\n attackers.push(algebraic(i));\n continue;\n }\n }\n const offset = RAYS[index];\n let j = i + offset;\n let blocked = false;\n while (j !== square) {\n if (this._board[j] != null) {\n blocked = true;\n break;\n }\n j += offset;\n }\n if (!blocked) {\n if (!verbose) {\n return true;\n }\n else {\n attackers.push(algebraic(i));\n continue;\n }\n }\n }\n }\n if (verbose) {\n return attackers;\n }\n else {\n return false;\n }\n }\n attackers(square, attackedBy) {\n if (!attackedBy) {\n return this._attacked(this._turn, Ox88[square], true);\n }\n else {\n return this._attacked(attackedBy, Ox88[square], true);\n }\n }\n _isKingAttacked(color) {\n const square = this._kings[color];\n return square === -1 ? false : this._attacked(swapColor(color), square);\n }\n isAttacked(square, attackedBy) {\n return this._attacked(attackedBy, Ox88[square]);\n }\n isCheck() {\n return this._isKingAttacked(this._turn);\n }\n inCheck() {\n return this.isCheck();\n }\n isCheckmate() {\n return this.isCheck() && this._moves().length === 0;\n }\n isStalemate() {\n return !this.isCheck() && this._moves().length === 0;\n }\n isInsufficientMaterial() {\n /*\n * k.b. vs k.b. (of opposite colors) with mate in 1:\n * 8/8/8/8/1b6/8/B1k5/K7 b - - 0 1\n *\n * k.b. vs k.n. with mate in 1:\n * 8/8/8/8/1n6/8/B7/K1k5 b - - 2 1\n */\n const pieces = {\n b: 0,\n n: 0,\n r: 0,\n q: 0,\n k: 0,\n p: 0,\n };\n const bishops = [];\n let numPieces = 0;\n let squareColor = 0;\n for (let i = Ox88.a8; i <= Ox88.h1; i++) {\n squareColor = (squareColor + 1) % 2;\n if (i & 0x88) {\n i += 7;\n continue;\n }\n const piece = this._board[i];\n if (piece) {\n pieces[piece.type] = piece.type in pieces ? pieces[piece.type] + 1 : 1;\n if (piece.type === BISHOP) {\n bishops.push(squareColor);\n }\n numPieces++;\n }\n }\n // k vs. k\n if (numPieces === 2) {\n return true;\n }\n else if (\n // k vs. kn .... or .... k vs. kb\n numPieces === 3 &&\n (pieces[BISHOP] === 1 || pieces[KNIGHT] === 1)) {\n return true;\n }\n else if (numPieces === pieces[BISHOP] + 2) {\n // kb vs. kb where any number of bishops are all on the same color\n let sum = 0;\n const len = bishops.length;\n for (let i = 0; i < len; i++) {\n sum += bishops[i];\n }\n if (sum === 0 || sum === len) {\n return true;\n }\n }\n return false;\n }\n isThreefoldRepetition() {\n return this._getPositionCount(this.fen()) >= 3;\n }\n isDrawByFiftyMoves() {\n return this._halfMoves >= 100; // 50 moves per side = 100 half moves\n }\n isDraw() {\n return (this.isDrawByFiftyMoves() ||\n this.isStalemate() ||\n this.isInsufficientMaterial() ||\n this.isThreefoldRepetition());\n }\n isGameOver() {\n return this.isCheckmate() || this.isStalemate() || this.isDraw();\n }\n moves({ verbose = false, square = undefined, piece = undefined, } = {}) {\n const moves = this._moves({ square, piece });\n if (verbose) {\n return moves.map((move) => new Move(this, move));\n }\n else {\n return moves.map((move) => this._moveToSan(move, moves));\n }\n }\n _moves({ legal = true, piece = undefined, square = undefined, } = {}) {\n const forSquare = square ? square.toLowerCase() : undefined;\n const forPiece = piece?.toLowerCase();\n const moves = [];\n const us = this._turn;\n const them = swapColor(us);\n let firstSquare = Ox88.a8;\n let lastSquare = Ox88.h1;\n let singleSquare = false;\n // are we generating moves for a single square?\n if (forSquare) {\n // illegal square, return empty moves\n if (!(forSquare in Ox88)) {\n return [];\n }\n else {\n firstSquare = lastSquare = Ox88[forSquare];\n singleSquare = true;\n }\n }\n for (let from = firstSquare; from <= lastSquare; from++) {\n // did we run off the end of the board\n if (from & 0x88) {\n from += 7;\n continue;\n }\n // empty square or opponent, skip\n if (!this._board[from] || this._board[from].color === them) {\n continue;\n }\n const { type } = this._board[from];\n let to;\n if (type === PAWN) {\n if (forPiece && forPiece !== type)\n continue;\n // single square, non-capturing\n to = from + PAWN_OFFSETS[us][0];\n if (!this._board[to]) {\n addMove(moves, us, from, to, PAWN);\n // double square\n to = from + PAWN_OFFSETS[us][1];\n if (SECOND_RANK[us] === rank(from) && !this._board[to]) {\n addMove(moves, us, from, to, PAWN, undefined, BITS.BIG_PAWN);\n }\n }\n // pawn captures\n for (let j = 2; j < 4; j++) {\n to = from + PAWN_OFFSETS[us][j];\n if (to & 0x88)\n continue;\n if (this._board[to]?.color === them) {\n addMove(moves, us, from, to, PAWN, this._board[to].type, BITS.CAPTURE);\n }\n else if (to === this._epSquare) {\n addMove(moves, us, from, to, PAWN, PAWN, BITS.EP_CAPTURE);\n }\n }\n }\n else {\n if (forPiece && forPiece !== type)\n continue;\n for (let j = 0, len = PIECE_OFFSETS[type].length; j < len; j++) {\n const offset = PIECE_OFFSETS[type][j];\n to = from;\n while (true) {\n to += offset;\n if (to & 0x88)\n break;\n if (!this._board[to]) {\n addMove(moves, us, from, to, type);\n }\n else {\n // own color, stop loop\n if (this._board[to].color === us)\n break;\n addMove(moves, us, from, to, type, this._board[to].type, BITS.CAPTURE);\n break;\n }\n /* break, if knight or king */\n if (type === KNIGHT || type === KING)\n break;\n }\n }\n }\n }\n /*\n * check for castling if we're:\n * a) generating all moves, or\n * b) doing single square move generation on the king's square\n */\n if (forPiece === undefined || forPiece === KING) {\n if (!singleSquare || lastSquare === this._kings[us]) {\n // king-side castling\n if (this._castling[us] & BITS.KSIDE_CASTLE) {\n const castlingFrom = this._kings[us];\n const castlingTo = castlingFrom + 2;\n if (!this._board[castlingFrom + 1] &&\n !this._board[castlingTo] &&\n !this._attacked(them, this._kings[us]) &&\n !this._attacked(them, castlingFrom + 1) &&\n !this._attacked(them, castlingTo)) {\n addMove(moves, us, this._kings[us], castlingTo, KING, undefined, BITS.KSIDE_CASTLE);\n }\n }\n // queen-side castling\n if (this._castling[us] & BITS.QSIDE_CASTLE) {\n const castlingFrom = this._kings[us];\n const castlingTo = castlingFrom - 2;\n if (!this._board[castlingFrom - 1] &&\n !this._board[castlingFrom - 2] &&\n !this._board[castlingFrom - 3] &&\n !this._attacked(them, this._kings[us]) &&\n !this._attacked(them, castlingFrom - 1) &&\n !this._attacked(them, castlingTo)) {\n addMove(moves, us, this._kings[us], castlingTo, KING, undefined, BITS.QSIDE_CASTLE);\n }\n }\n }\n }\n /*\n * return all pseudo-legal moves (this includes moves that allow the king\n * to be captured)\n */\n if (!legal || this._kings[us] === -1) {\n return moves;\n }\n // filter out illegal moves\n const legalMoves = [];\n for (let i = 0, len = moves.length; i < len; i++) {\n this._makeMove(moves[i]);\n if (!this._isKingAttacked(us)) {\n legalMoves.push(moves[i]);\n }\n this._undoMove();\n }\n return legalMoves;\n }\n move(move, { strict = false } = {}) {\n /*\n * The move function can be called with in the following parameters:\n *\n * .move('Nxb7') <- argument is a case-sensitive SAN string\n *\n * .move({ from: 'h7', <- argument is a move object\n * to :'h8',\n * promotion: 'q' })\n *\n *\n * An optional strict argument may be supplied to tell chess.js to\n * strictly follow the SAN specification.\n */\n let moveObj = null;\n if (typeof move === 'string') {\n moveObj = this._moveFromSan(move, strict);\n }\n else if (typeof move === 'object') {\n const moves = this._moves();\n // convert the pretty move object to an ugly move object\n for (let i = 0, len = moves.length; i < len; i++) {\n if (move.from === algebraic(moves[i].from) &&\n move.to === algebraic(moves[i].to) &&\n (!('promotion' in moves[i]) || move.promotion === moves[i].promotion)) {\n moveObj = moves[i];\n break;\n }\n }\n }\n // failed to find move\n if (!moveObj) {\n if (typeof move === 'string') {\n throw new Error(`Invalid move: ${move}`);\n }\n else {\n throw new Error(`Invalid move: ${JSON.stringify(move)}`);\n }\n }\n /*\n * need to make a copy of move because we can't generate SAN after the move\n * is made\n */\n const prettyMove = new Move(this, moveObj);\n this._makeMove(moveObj);\n this._incPositionCount(prettyMove.after);\n return prettyMove;\n }\n _push(move) {\n this._history.push({\n move,\n kings: { b: this._kings.b, w: this._kings.w },\n turn: this._turn,\n castling: { b: this._castling.b, w: this._castling.w },\n epSquare: this._epSquare,\n halfMoves: this._halfMoves,\n moveNumber: this._moveNumber,\n });\n }\n _makeMove(move) {\n const us = this._turn;\n const them = swapColor(us);\n this._push(move);\n this._board[move.to] = this._board[move.from];\n delete this._board[move.from];\n // if ep capture, remove the captured pawn\n if (move.flags & BITS.EP_CAPTURE) {\n if (this._turn === BLACK) {\n delete this._board[move.to - 16];\n }\n else {\n delete this._board[move.to + 16];\n }\n }\n // if pawn promotion, replace with new piece\n if (move.promotion) {\n this._board[move.to] = { type: move.promotion, color: us };\n }\n // if we moved the king\n if (this._board[move.to].type === KING) {\n this._kings[us] = move.to;\n // if we castled, move the rook next to the king\n if (move.flags & BITS.KSIDE_CASTLE) {\n const castlingTo = move.to - 1;\n const castlingFrom = move.to + 1;\n this._board[castlingTo] = this._board[castlingFrom];\n delete this._board[castlingFrom];\n }\n else if (move.flags & BITS.QSIDE_CASTLE) {\n const castlingTo = move.to + 1;\n const castlingFrom = move.to - 2;\n this._board[castlingTo] = this._board[castlingFrom];\n delete this._board[castlingFrom];\n }\n // turn off castling\n this._castling[us] = 0;\n }\n // turn off castling if we move a rook\n if (this._castling[us]) {\n for (let i = 0, len = ROOKS[us].length; i < len; i++) {\n if (move.from === ROOKS[us][i].square &&\n this._castling[us] & ROOKS[us][i].flag) {\n this._castling[us] ^= ROOKS[us][i].flag;\n break;\n }\n }\n }\n // turn off castling if we capture a rook\n if (this._castling[them]) {\n for (let i = 0, len = ROOKS[them].length; i < len; i++) {\n if (move.to === ROOKS[them][i].square &&\n this._castling[them] & ROOKS[them][i].flag) {\n this._castling[them] ^= ROOKS[them][i].flag;\n break;\n }\n }\n }\n // if big pawn move, update the en passant square\n if (move.flags & BITS.BIG_PAWN) {\n if (us === BLACK) {\n this._epSquare = move.to - 16;\n }\n else {\n this._epSquare = move.to + 16;\n }\n }\n else {\n this._epSquare = EMPTY;\n }\n // reset the 50 move counter if a pawn is moved or a piece is captured\n if (move.piece === PAWN) {\n this._halfMoves = 0;\n }\n else if (move.flags & (BITS.CAPTURE | BITS.EP_CAPTURE)) {\n this._halfMoves = 0;\n }\n else {\n this._halfMoves++;\n }\n if (us === BLACK) {\n this._moveNumber++;\n }\n this._turn = them;\n }\n undo() {\n const move = this._undoMove();\n if (move) {\n const prettyMove = new Move(this, move);\n this._decPositionCount(prettyMove.after);\n return prettyMove;\n }\n return null;\n }\n _undoMove() {\n const old = this._history.pop();\n if (old === undefined) {\n return null;\n }\n const move = old.move;\n this._kings = old.kings;\n this._turn = old.turn;\n this._castling = old.castling;\n this._epSquare = old.epSquare;\n this._halfMoves = old.halfMoves;\n this._moveNumber = old.moveNumber;\n const us = this._turn;\n const them = swapColor(us);\n this._board[move.from] = this._board[move.to];\n this._board[move.from].type = move.piece; // to undo any promotions\n delete this._board[move.to];\n if (move.captured) {\n if (move.flags & BITS.EP_CAPTURE) {\n // en passant capture\n let index;\n if (us === BLACK) {\n index = move.to - 16;\n }\n else {\n index = move.to + 16;\n }\n this._board[index] = { type: PAWN, color: them };\n }\n else {\n // regular capture\n this._board[move.to] = { type: move.captured, color: them };\n }\n }\n if (move.flags & (BITS.KSIDE_CASTLE | BITS.QSIDE_CASTLE)) {\n let castlingTo, castlingFrom;\n if (move.flags & BITS.KSIDE_CASTLE) {\n castlingTo = move.to + 1;\n castlingFrom = move.to - 1;\n }\n else {\n castlingTo = move.to - 2;\n castlingFrom = move.to + 1;\n }\n this._board[castlingTo] = this._board[castlingFrom];\n delete this._board[castlingFrom];\n }\n return move;\n }\n pgn({ newline = '\\n', maxWidth = 0, } = {}) {\n /*\n * using the specification from http://www.chessclub.com/help/PGN-spec\n * example for html usage: .pgn({ max_width: 72, newline_char: \"<br />\" })\n */\n const result = [];\n let headerExists = false;\n /* add the PGN header information */\n for (const i in this._header) {\n /*\n * TODO: order of enumerated properties in header object is not\n * guaranteed, see ECMA-262 spec (section 12.6.4)\n */\n result.push('[' + i + ' \"' + this._header[i] + '\"]' + newline);\n headerExists = true;\n }\n if (headerExists && this._history.length) {\n result.push(newline);\n }\n const appendComment = (moveString) => {\n const comment = this._comments[this.fen()];\n if (typeof comment !== 'undefined') {\n const delimiter = moveString.length > 0 ? ' ' : '';\n moveString = `${moveString}${delimiter}{${comment}}`;\n }\n return moveString;\n };\n // pop all of history onto reversed_history\n const reversedHistory = [];\n while (this._history.length > 0) {\n reversedHistory.push(this._undoMove());\n }\n const moves = [];\n let moveString = '';\n // special case of a commented starting position with no moves\n if (reversedHistory.length === 0) {\n moves.push(appendComment(''));\n }\n // build the list of moves. a move_string looks like: \"3. e3 e6\"\n while (reversedHistory.length > 0) {\n moveString = appendComment(moveString);\n const move = reversedHistory.pop();\n // make TypeScript stop complaining about move being undefined\n if (!move) {\n break;\n }\n // if the position started with black to move, start PGN with #. ...\n if (!this._history.length && move.color === 'b') {\n const prefix = `${this._moveNumber}. ...`;\n // is there a comment preceding the first move?\n moveString = moveString ? `${moveString} ${prefix}` : prefix;\n }\n else if (move.color === 'w') {\n // store the previous generated move_string if we have one\n if (moveString.length) {\n moves.push(moveString);\n }\n moveString = this._moveNumber + '.';\n }\n moveString =\n moveString + ' ' + this._moveToSan(move, this._moves({ legal: true }));\n this._makeMove(move);\n }\n // are there any other leftover moves?\n if (moveString.length) {\n moves.push(appendComment(moveString));\n }\n // is there a result?\n if (typeof this._header.Result !== 'undefined') {\n moves.push(this._header.Result);\n }\n /*\n * history should be back to what it was before we started generating PGN,\n * so join together moves\n */\n if (maxWidth === 0) {\n return result.join('') + moves.join(' ');\n }\n // TODO (jah): huh?\n const strip = function () {\n if (result.length > 0 && result[result.length - 1] === ' ') {\n result.pop();\n return true;\n }\n return false;\n };\n // NB: this does not preserve comment whitespace.\n const wrapComment = function (width, move) {\n for (const token of move.split(' ')) {\n if (!token) {\n continue;\n }\n if (width + token.length > maxWidth) {\n while (strip()) {\n width--;\n }\n result.push(newline);\n width = 0;\n }\n result.push(token);\n width += token.length;\n result.push(' ');\n width++;\n }\n if (strip()) {\n width--;\n }\n return width;\n };\n // wrap the PGN output at max_width\n let currentWidth = 0;\n for (let i = 0; i < moves.length; i++) {\n if (currentWidth + moves[i].length > maxWidth) {\n if (moves[i].includes('{')) {\n currentWidth = wrapComment(currentWidth, moves[i]);\n continue;\n }\n }\n // if the current move will push past max_width\n if (currentWidth + moves[i].length > maxWidth && i !== 0) {\n // don't end the line with whitespace\n if (result[result.length - 1] === ' ') {\n result.pop();\n }\n result.push(newline);\n currentWidth = 0;\n }\n else if (i !== 0) {\n result.push(' ');\n currentWidth++;\n }\n result.push(moves[i]);\n currentWidth += moves[i].length;\n }\n return result.join('');\n }\n /*\n * @deprecated Use `setHeader` and `getHeaders` instead.\n */\n header(...args) {\n for (let i = 0; i < args.length; i += 2) {\n if (typeof args[i] === 'string' && typeof args[i + 1] === 'string') {\n this._header[args[i]] = args[i + 1];\n }\n }\n return this._header;\n }\n setHeader(key, value) {\n this._header[key] = value;\n return this._header;\n }\n removeHeader(key) {\n if (key in this._header) {\n delete this._header[key];\n return true;\n }\n return false;\n }\n getHeaders() {\n return this._header;\n }\n loadPgn(pgn, { strict = false, newlineChar = '\\r?\\n', } = {}) {\n function mask(str) {\n return str.replace(/\\\\/g, '\\\\');\n }\n function parsePgnHeader(header) {\n const headerObj = {};\n const headers = header.split(new RegExp(mask(newlineChar)));\n let key = '';\n let value = '';\n for (let i = 0; i < headers.length; i++) {\n const regex = /^\\s*\\[\\s*([A-Za-z]+)\\s*\"(.*)\"\\s*\\]\\s*$/;\n key = headers[i].replace(regex, '$1');\n value = headers[i].replace(regex, '$2');\n if (key.trim().length > 0) {\n headerObj[key] = value;\n }\n }\n return headerObj;\n }\n // strip whitespace from head/tail of PGN block\n pgn = pgn.trim();\n /*\n * RegExp to split header. Takes advantage of the fact that header and movetext\n * will always have a blank line between them (ie, two newline_char's). Handles\n * case where movetext is empty by matching newlineChar until end of string is\n * matched - effectively trimming from the end extra newlineChar.\n *\n * With default newline_char, will equal:\n * /^(\\[((?:\\r?\\n)|.)*\\])((?:\\s*\\r?\\n){2}|(?:\\s*\\r?\\n)*$)/\n */\n const headerRegex = new RegExp('^(\\\\[((?:' +\n mask(newlineChar) +\n ')|.)*\\\\])' +\n '((?:\\\\s*' +\n mask(newlineChar) +\n '){2}|(?:\\\\s*' +\n mask(newlineChar) +\n ')*$)');\n // If no header given, begin with moves.\n const headerRegexResults = headerRegex.exec(pgn);\n const headerString = headerRegexResults\n ? headerRegexResults.length >= 2\n ? headerRegexResults[1]\n : ''\n : '';\n // Put the board in the starting position\n this.reset();\n // parse PGN header\n const headers = parsePgnHeader(headerString);\n let fen = '';\n for (const key in headers) {\n // check to see user is including fen (possibly with wrong tag case)\n if (key.toLowerCase() === 'fen') {\n fen = headers[key];\n }\n this.header(key, headers[key]);\n }\n /*\n * the permissive parser should attempt to load a fen tag, even if it's the\n * wrong case and doesn't include a corresponding [SetUp \"1\"] tag\n */\n if (!strict) {\n if (fen) {\n this.load(fen, { preserveHeaders: true });\n }\n }\n else {\n /*\n * strict parser - load the starting position indicated by [Setup '1']\n * and [FEN position]\n */\n if (headers['SetUp'] === '1') {\n if (!('FEN' in headers)) {\n throw new Error('Invalid PGN: FEN tag must be supplied with SetUp tag');\n }\n // don't clear the headers when loading\n this.load(headers['FEN'], { preserveHeaders: true });\n }\n }\n /*\n * NB: the regexes below that delete move numbers, recursive annotations,\n * and numeric annotation glyphs may also match text in comments. To\n * prevent this, we transform comments by hex-encoding them in place and\n * decoding them again after the other tokens have been deleted.\n *\n * While the spec states that PGN files should be ASCII encoded, we use\n * {en,de}codeURIComponent here to support arbitrary UTF8 as a convenience\n * for modern users\n */\n function toHex(s) {\n return Array.from(s)\n .map(function (c) {\n /*\n * encodeURI doesn't transform most ASCII characters, so we handle\n * these ourselves\n */\n return c.charCodeAt(0) < 128\n ? c.charCodeAt(0).toString(16)\n : encodeURIComponent(c).replace(/%/g, '').toLowerCase();\n })\n .join('');\n }\n function fromHex(s) {\n return s.length == 0\n ? ''\n : decodeURIComponent('%' + (s.match(/.{1,2}/g) || []).join('%'));\n }\n const encodeComment = function (s) {\n s = s.replace(new RegExp(mask(newlineChar), 'g'), ' ');\n return `{${toHex(s.slice(1, s.length - 1))}}`;\n };\n const decodeComment = function (s) {\n if (s.startsWith('{') && s.endsWith('}')) {\n return fromHex(s.slice(1, s.length - 1));\n }\n };\n // delete header to get the moves\n let ms = pgn\n .replace(headerString, '')\n .replace(\n // encode comments so they don't get deleted below\n new RegExp(`({[^}]*})+?|;([^${mask(newlineChar)}]*)`, 'g'), function (_match, bracket, semicolon) {\n return bracket !== undefined\n ? encodeComment(bracket)\n : ' ' + encodeComment(`{${semicolon.slice(1)}}`);\n })\n .replace(new RegExp(mask(newlineChar), 'g'), ' ');\n // delete recursive annotation variations\n const ravRegex = /(\\([^()]+\\))+?/g;\n while (ravRegex.test(ms)) {\n ms = ms.replace(ravRegex, '');\n }\n // delete move numbers\n ms = ms.replace(/\\d+\\.(\\.\\.)?/g, '');\n // delete ... indicating black to move\n ms = ms.replace(/\\.\\.\\./g, '');\n /* delete numeric annotation glyphs */\n ms = ms.replace(/\\$\\d+/g, '');\n // trim and get array of moves\n let moves = ms.trim().split(new RegExp(/\\s+/));\n // delete empty entries\n moves = moves.filter((move) => move !== '');\n let result = '';\n for (let halfMove = 0; halfMove < moves.length; halfMove++) {\n const comment = decodeComment(moves[halfMove]);\n if (comment !== undefined) {\n this._comments[this.fen()] = comment;\n continue;\n }\n const move = this._moveFromSan(moves[halfMove], strict);\n // invalid move\n if (move == null) {\n // was the move an end of game marker\n if (TERMINATION_MARKERS.indexOf(moves[halfMove]) > -1) {\n result = moves[halfMove];\n }\n else {\n throw new Error(`Invalid move in PGN: ${moves[halfMove]}`);\n }\n }\n else {\n // reset the end of game marker if making a valid move\n result = '';\n this._makeMove(move);\n this._incPositionCount(this.fen());\n }\n }\n /*\n * Per section 8.2.6 of the PGN spec, the Result tag pair must match match\n * the termination marker. Only do this when headers are present, but the\n * result tag is missing\n */\n if (result && Object.keys(this._header).length && !this._header['Result']) {\n this.header('Result', result);\n }\n }\n /*\n * Convert a move from 0x88 coordinates to Standard Algebraic Notation\n * (SAN)\n *\n * @param {boolean} strict Use the strict SAN parser. It will throw errors\n * on overly disambiguated moves (see below):\n *\n * r1bqkbnr/ppp2ppp/2n5/1B1pP3/4P3/8/PPPP2PP/RNBQK1NR b KQkq - 2 4\n * 4. ... Nge7 is overly disambiguated because the knight on c6 is pinned\n * 4. ... Ne7 is technically the valid SAN\n */\n _moveToSan(move, moves) {\n let output = '';\n if (move.flags & BITS.KSIDE_CASTLE) {\n output = 'O-O';\n }\n else if (move.flags & BITS.QSIDE_CASTLE) {\n output = 'O-O-O';\n }\n else {\n if (move.piece !== PAWN) {\n const disambiguator = getDisambiguator(move, moves);\n output += move.piece.toUpperCase() + disambiguator;\n }\n if (move.flags & (BITS.CAPTURE | BITS.EP_CAPTURE)) {\n if (move.piece === PAWN) {\n output += algebraic(move.from)[0];\n }\n output += 'x';\n }\n output += algebraic(move.to);\n if (move.promotion) {\n output += '=' + move.promotion.toUpperCase();\n }\n }\n this._makeMove(move);\n if (this.isCheck()) {\n if (this.isCheckmate()) {\n output += '#';\n }\n else {\n output += '+';\n }\n }\n this._undoMove();\n return output;\n }\n // convert a move from Standard Algebraic Notation (SAN) to 0x88 coordinates\n _moveFromSan(move, strict = false) {\n // strip off any move decorations: e.g Nf3+?! becomes Nf3\n const cleanMove = strippedSan(move);\n let pieceType = inferPieceType(cleanMove);\n let moves = this._moves({ legal: true, piece: pieceType });\n // strict parser\n for (let i = 0, len = moves.length; i < len; i++) {\n if (cleanMove === strippedSan(this._moveToSan(moves[i], moves))) {\n return moves[i];\n }\n }\n // the strict parser failed\n if (strict) {\n return null;\n }\n let piece = undefined;\n let matches = undefined;\n let from = undefined;\n let to = undefined;\n let promotion = undefined;\n /*\n * The default permissive (non-strict) parser allows the user to parse\n * non-standard chess notations. This parser is only run after the strict\n * Standard Algebraic Notation (SAN) parser has failed.\n *\n * When running the permissive parser, we'll run a regex to grab the piece, the\n * to/from square, and an optional promotion piece. This regex will\n * parse common non-standard notation like: Pe2-e4, Rc1c4, Qf3xf7,\n * f7f8q, b1c3\n *\n * NOTE: Some positions and moves may be ambiguous when using the permissive\n * parser. For example, in this position: 6k1/8/8/B7/8/8/8/BN4K1 w - - 0 1,\n * the move b1c3 may be interpreted as Nc3 or B1c3 (a disambiguated bishop\n * move). In these cases, the permissive parser will default to the most\n * basic interpretation (which is b1c3 parsing to Nc3).\n */\n let overlyDisambiguated = false;\n matches = cleanMove.match(/([pnbrqkPNBRQK])?([a-h][1-8])x?-?([a-h][1-8])([qrbnQRBN])?/);\n if (matches) {\n piece = matches[1];\n from = matches[2];\n to = matches[3];\n promotion = matches[4];\n if (from.length == 1) {\n overlyDisambiguated = true;\n }\n }\n else {\n /*\n * The [a-h]?[1-8]? portion of the regex below handles moves that may be\n * overly disambiguated (e.g. Nge7 is unnecessary and non-standard when\n * there is one legal knight move to e7). In this case, the value of\n * 'from' variable will be a rank or file, not a square.\n */\n matches = cleanMove.match(/([pnbrqkPNBRQK])?([a-h]?[1-8]?)x?-?([a-h][1-8])([qrbnQRBN])?/);\n if (matches) {\n piece = matches[1];\n from = matches[2];\n to = matches[3];\n promotion = matches[4];\n if (from.length == 1) {\n overlyDisambiguated = true;\n }\n }\n }\n pieceType = inferPieceType(cleanMove);\n moves = this._moves({\n legal: true,\n piece: piece ? piece : pieceType,\n });\n if (!to) {\n return null;\n }\n for (let i = 0, len = moves.length; i < len; i++) {\n if (!from) {\n // if there is no from square, it could be just 'x' missing from a capture\n if (cleanMove ===\n strippedSan(this._moveToSan(moves[i], moves)).replace('x', '')) {\n return moves[i];\n }\n // hand-compare move properties with the results from our permissive regex\n }\n else if ((!piece || piece.toLowerCase() == moves[i].piece) &&\n Ox88[from] == moves[i].from &&\n Ox88[to] == moves[i].to &&\n (!promotion || promotion.toLowerCase() == moves[i].promotion)) {\n return moves[i];\n }\n else if (overlyDisambiguated) {\n /*\n * SPECIAL CASE: we parsed a move string that may have an unneeded\n * rank/file disambiguator (e.g. Nge7). The 'from' variable will\n */\n const square = algebraic(moves[i].from);\n if ((!piece || piece.toLowerCase() == moves[i].piece) &&\n Ox88[to] == moves[i].to &&\n (from == square[0] || from == square[1]) &&\n (!promotion || promotion.toLowerCase() == moves[i].promotion)) {\n return moves[i];\n }\n }\n }\n return null;\n }\n ascii() {\n let s = ' +------------------------+\\n';\n for (let i = Ox88.a8; i <= Ox88.h1; i++) {\n // display the rank\n if (file(i) === 0) {\n s += ' ' + '87654321'[rank(i)] + ' |';\n }\n if (this._board[i]) {\n const piece = this._board[i].type;\n const color = this._board[i].color;\n const symbol = color === WHITE ? piece.toUpperCase() : piece.toLowerCase();\n s += ' ' + symbol + ' ';\n }\n else {\n s += ' . ';\n }\n if ((i + 1) & 0x88) {\n s += '|\\n';\n i += 8;\n }\n }\n s += ' +------------------------+\\n';\n s += ' a b c d e f g h';\n return s;\n }\n perft(depth) {\n const moves = this._moves({ legal: false });\n let nodes = 0;\n const color = this._turn;\n for (let i = 0, len = moves.length; i < len; i++) {\n this._makeMove(moves[i]);\n if (!this._isKingAttacked(color)) {\n if (depth - 1 > 0) {\n nodes += this.perft(depth - 1);\n }\n else {\n nodes++;\n }\n }\n this._undoMove();\n }\n return nodes;\n }\n turn() {\n return this._turn;\n }\n board() {\n const output = [];\n let row = [];\n for (let i = Ox88.a8; i <= Ox88.h1; i++) {\n if (this._board[i] == null) {\n row.push(null);\n }\n else {\n row.push({\n square: algebraic(i),\n type: this._board[i].type,\n color: this._board[i].color,\n });\n }\n if ((i + 1) & 0x88) {\n output.push(row);\n row = [];\n i += 8;\n }\n }\n return output;\n }\n squareColor(square) {\n if (square in Ox88) {\n const sq = Ox88[square];\n return (rank(sq) + file(sq)) % 2 === 0 ? 'light' : 'dark';\n }\n return null;\n }\n history({ verbose = false } = {}) {\n const reversedHistory = [];\n const moveHistory = [];\n while (this._history.length > 0) {\n reversedHistory.push(this._undoMove());\n }\n while (true) {\n const move = reversedHistory.pop();\n if (!move) {\n break;\n }\n if (verbose) {\n moveHistory.push(new Move(this, move));\n }\n else {\n moveHistory.push(this._moveToSan(move, this._moves()));\n }\n this._makeMove(move);\n }\n return moveHistory;\n }\n /*\n * Keeps track of position occurrence counts for the purpose of repetition\n * checking. All three methods (`_inc`, `_dec`, and `_get`) trim the\n * irrelevent information from the fen, initialising new positions, and\n * removing old positions from the record if their counts are reduced to 0.\n */\n _getPositionCount(fen) {\n const trimmedFen = trimFen(fen);\n return this._positionCount[trimmedFen] || 0;\n }\n _incPositionCount(fen) {\n const trimmedFen = trimFen(fen);\n if (this._positionCount[trimmedFen] === undefined) {\n this._positionCount[trimmedFen] = 0;\n }\n this._positionCount[trimmedFen] += 1;\n }\n _decPositionCount(fen) {\n const trimmedFen = trimFen(fen);\n if (this._positionCount[trimmedFen] === 1) {\n delete this._positionCount[trimmedFen];\n }\n else {\n this._positionCount[trimmedFen] -= 1;\n }\n }\n _pruneComments() {\n const reversedHistory = [];\n const currentComments = {};\n const copyComment = (fen) => {\n if (fen in this._comments) {\n currentComments[fen] = this._comments[fen];\n }\n };\n while (this._history.length > 0) {\n reversedHistory.push(this._undoMove());\n }\n copyComment(this.fen());\n while (true) {\n const move = reversedHistory.pop();\n if (!move) {\n break;\n }\n this._makeMove(move);\n copyComment(this.fen());\n }\n this._comments = currentComments;\n }\n getComment() {\n return this._comments[this.fen()];\n }\n setComment(comment) {\n this._comments[this.fen()] = comment.replace('{', '[').replace('}', ']');\n }\n /**\n * @deprecated Renamed to `removeComment` for consistency\n */\n deleteComment() {\n return this.removeComment();\n }\n removeComment() {\n const comment = this._comments[this.fen()];\n delete this._comments[this.fen()];\n return comment;\n }\n getComments() {\n this._pruneComments();\n return Object.keys(this._comments).map((fen) => {\n return { fen: fen, comment: this._comments[fen] };\n });\n }\n /**\n * @deprecated Renamed to `removeComments` for consistency\n */\n deleteComments() {\n return this.removeComments();\n }\n removeComments() {\n this._pruneComments();\n return Object.keys(this._comments).map((fen) => {\n const comment = this._comments[fen];\n delete this._comments[fen];\n return { fen: fen, comment: comment };\n });\n }\n setCastlingRights(color, rights) {\n for (const side of [KING, QUEEN]) {\n if (rights[side] !== undefined) {\n if (rights[side]) {\n this._castling[color] |= SIDES[side];\n }\n else {\n this._castling[color] &= ~SIDES[side];\n }\n }\n }\n this._updateCastlingRights();\n const result = this.getCastlingRights(color);\n return ((rights[KING] === undefined || rights[KING] === result[KING]) &&\n (rights[QUEEN] === undefined || rights[QUEEN] === result[QUEEN]));\n }\n getCastlingRights(color) {\n return {\n [KING]: (this._castling[color] & SIDES[KING]) !== 0,\n [QUEEN]: (this._castling[color] & SIDES[QUEEN]) !== 0,\n };\n }\n moveNumber() {\n return this._moveNumber;\n }\n}\n//# sourceMappingURL=chess.js.map","import { onUnmounted, Ref, watch } from 'vue';\nimport type { Api as CgAPI } from '../chessground/api';\n\n/**\n * Keep Chessground's cached board bounds in sync with the actual DOM.\n *\n * Chessground caches `getBoundingClientRect()` on the board element at\n * mount/redraw and uses it to translate pointer coordinates to squares.\n * If the surrounding layout shifts the board after mount — for example,\n * a flex-centered transition container in StudySession, font-load\n * reflow, or a parent that toggles visibility — the cached rect goes\n * stale and clicks land on the wrong squares.\n *\n * This composable:\n * 1. Forces a `redrawAll()` on the next animation frame after the\n * Chessground API becomes available, catching the initial mount\n * race against parent layout settling.\n * 2. Observes the board element with a ResizeObserver and triggers\n * `redrawAll()` on any subsequent size change.\n *\n * Pass a ref to the board element and a ref to the Chessground API.\n * Cleanup is handled via `onUnmounted`.\n */\nexport function useChessgroundBounds(\n boardEl: Ref<HTMLElement | null | undefined>,\n api: Ref<CgAPI | undefined>\n): void {\n let ro: ResizeObserver | null = null;\n\n const stop = watch(\n () => api.value,\n (cg) => {\n if (!cg || !boardEl.value) return;\n\n // Initial post-mount sync: parent flex/transition layout may\n // settle one frame after Chessground reads its bounding rect.\n requestAnimationFrame(() => cg.redrawAll());\n\n ro = new ResizeObserver(() => cg.redrawAll());\n ro.observe(boardEl.value);\n\n stop();\n },\n { immediate: true }\n );\n\n onUnmounted(() => {\n ro?.disconnect();\n ro = null;\n });\n}\n","<template>\n <!-- Template remains largely the same -->\n <div data-viewable=\"PuzzleView\">\n <p class=\"text-h5\">\n Make the best move for {{ playerColor === 'cg-white' ? 'White ♖♘♗♕♔♗♘♖' : 'Black ♜♞♝♚♛♝♞♜' }}:\n </p>\n <div class=\"puzzle-board-wrapper\">\n <div class=\"puzzle-ranks-labels\">\n <div v-for=\"rank in 8\" :key=\"rank\">{{ playerColor === 'cg-white' ? 9 - rank : rank }}</div>\n </div>\n <div class=\"puzzle-board-and-files\">\n <div id=\"cg\" ref=\"boardElement\"></div>\n <div class=\"puzzle-files-labels\">\n <div v-for=\"file in files\" :key=\"file\">{{ file }}</div>\n </div>\n </div>\n </div>\n <div v-if=\"showPromotionDialog\" class=\"puzzle-promotion-dialog\">\n <button v-for=\"piece in promotionPieces\" :key=\"piece.value\" @click=\"handlePromotion(piece.value)\">\n {{ playerColor === 'cg-white' ? piece.whiteSymbol : piece.blackSymbol }}\n {{ piece.name }}\n </button>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, ref, computed, onMounted, onUnmounted, PropType } from 'vue';\nimport { Chessground } from '../../chessground/chessground';\nimport { Key } from '../../chessground/types';\nimport { Api as cgAPI } from '../../chessground/api';\nimport { useViewable, useQuestionView } from '@vue-skuilder/common-ui';\nimport { ChessPuzzle } from './index';\nimport { Chess, SQUARES } from 'chess.js';\nimport { ViewData } from '@vue-skuilder/common';\nimport { useChessgroundBounds } from '../../composables/useChessgroundBounds';\n\n// Types and interfaces\ntype PromotionPiece = 'q' | 'r' | 'b' | 'n';\ntype Color = 'cg-white' | 'cg-black';\n\ninterface UciMove {\n from: string;\n to: string;\n promotion?: PromotionPiece;\n}\n\n// Helper functions (moved outside component)\nconst parseUciMove = (moveString: string): UciMove => {\n if (moveString.length < 4 || moveString.length > 5) {\n throw new Error(`Invalid UCI move format: ${moveString}`);\n }\n\n return {\n from: moveString.substring(0, 2),\n to: moveString.substring(2, 4),\n promotion: moveString.length === 5 ? (moveString[4] as PromotionPiece) : undefined,\n };\n};\n\nconst toDests = (chess: Chess) => {\n const dests = new Map();\n SQUARES.forEach((s) => {\n const ms = chess.moves({ square: s, verbose: true });\n if (ms.length)\n dests.set(\n s,\n ms.map((m) => m.to)\n );\n });\n return dests;\n};\n\nconst swapColor = (color: Color): Color => (color === 'cg-white' ? 'cg-black' : 'cg-white');\n\nconst toColor = (chess: Chess): Color => (chess.turn() === 'w' ? 'cg-white' : 'cg-black');\n\n// Chess puzzle component\nexport default defineComponent({\n name: 'PuzzleView',\n\n props: {\n data: {\n type: Array as PropType<ViewData[]>,\n required: true,\n },\n modifyDifficulty: {\n type: Number,\n required: false,\n default: 0,\n },\n },\n\n setup(props, { emit }) {\n // Initialize base utilities\n const viewableUtils = useViewable(props, emit, 'PuzzleView');\n const questionUtils = useQuestionView<ChessPuzzle>(viewableUtils);\n\n // State\n const boardElement = ref<HTMLElement | null>(null);\n const chessEngine = ref<Chess>();\n const chessBoard = ref<cgAPI>();\n const playerColor = ref<Color>('cg-white');\n const showPromotionDialog = ref(false);\n const promotionMove = ref<{ from: string; to: string } | null>(null);\n\n const ANIM_DELAY = 300;\n\n // Keep Chessground's cached board bounds in sync with the DOM —\n // StudySession's flex-centered transition container can shift the\n // board after Chessground reads its rect at mount, which leaves\n // click hitboxes offset from the rendered squares until a resize.\n useChessgroundBounds(boardElement, chessBoard);\n\n const promotionPieces = [\n { value: 'q', name: 'Queen', whiteSymbol: '♕', blackSymbol: '♛' },\n { value: 'r', name: 'Rook', whiteSymbol: '♖', blackSymbol: '♜' },\n { value: 'b', name: 'Bishop', whiteSymbol: '♗', blackSymbol: '♝' },\n { value: 'n', name: 'Knight', whiteSymbol: '♘', blackSymbol: '♞' },\n ];\n\n // Computed\n const files = computed(() => {\n const filesList = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];\n return playerColor.value === 'cg-white' ? filesList : filesList.reverse();\n });\n\n // Methods\n const isPromotionPiece = (p?: string): p is PromotionPiece => {\n if (!p) return false;\n return ['q', 'r', 'b', 'n'].includes(p);\n };\n\n const isUnfinishedPromotion = (from: string, to: string, promotionPiece?: PromotionPiece) => {\n if (isPromotionPiece(promotionPiece)) return false;\n // [ ] typing\n // @ts-expect-error - `from` is well-formed\n const piece = chessEngine.value?.get(from);\n return piece?.type === 'p' && (to[1] === '8' || to[1] === '1');\n };\n\n const updateChessground = () => {\n if (!chessEngine.value || !chessBoard.value) return;\n\n chessBoard.value.set({\n fen: chessEngine.value.fen(),\n turnColor: toColor(chessEngine.value),\n movable: {\n color: toColor(chessEngine.value),\n dests: toDests(chessEngine.value),\n },\n });\n };\n\n const handlePromotion = (promotionPiece: PromotionPiece | string) => {\n if (promotionPiece !== 'q' && promotionPiece !== 'r' && promotionPiece !== 'b' && promotionPiece !== 'n') {\n viewableUtils.logger.error(`Invalid promotion piece: ${promotionPiece}`);\n return;\n }\n if (!promotionMove.value) return;\n\n viewableUtils.logger.log(`promoting to ${promotionPiece}`);\n showPromotionDialog.value = false;\n checkMove(promotionMove.value.from, promotionMove.value.to, promotionPiece);\n };\n\n const checkMove = (orig: string, dest: string, promotionPiece?: PromotionPiece) => {\n if (!questionUtils.question.value?.moves.length) {\n throw new Error('No moves');\n }\n\n if (isUnfinishedPromotion(orig, dest, promotionPiece)) {\n promotionMove.value = { from: orig, to: dest };\n showPromotionDialog.value = true;\n return;\n }\n\n const expectedMove = questionUtils.question.value.moves[0];\n const moveMade = isPromotionPiece(promotionPiece) ? `${orig}${dest}${promotionPiece}` : `${orig}${dest}`;\n\n if (expectedMove === moveMade) {\n chessEngine.value?.move({\n from: orig,\n to: dest,\n promotion: isPromotionPiece(promotionPiece) ? promotionPiece : undefined,\n });\n updateChessground();\n\n questionUtils.question.value.moves.shift();\n\n if (questionUtils.question.value.moves.length === 0) {\n questionUtils.submitAnswer('');\n } else {\n window.setTimeout(() => {\n if (!questionUtils.question.value) return;\n\n const nextMove = questionUtils.question.value.moves.shift()!;\n const move = parseUciMove(nextMove);\n chessEngine.value?.move(move);\n updateChessground();\n }, ANIM_DELAY);\n }\n } else {\n // Handle incorrect move\n chessEngine.value?.move({ from: orig, to: dest, promotion: promotionPiece });\n if (chessEngine.value?.isCheckmate()) {\n questionUtils.submitAnswer(ChessPuzzle.CHECKMATE);\n } else {\n chessEngine.value?.undo();\n }\n\n questionUtils.submitAnswer(orig + dest + promotionPiece);\n updateChessground();\n }\n };\n\n // Initialization\n onMounted(() => {\n if (!boardElement.value) return;\n\n questionUtils.question.value = new ChessPuzzle(props.data);\n chessEngine.value = new Chess(questionUtils.question.value.fen);\n playerColor.value = swapColor(toColor(chessEngine.value));\n\n chessBoard.value = Chessground(boardElement.value, {\n movable: {\n free: false,\n showDests: true,\n dests: toDests(chessEngine.value),\n events: {\n // [ ] typing\n // @ts-expect-error - `orig` and `dest` are well-formed\n after: checkMove,\n },\n },\n draggable: {\n showGhost: true,\n },\n fen: chessEngine.value.fen(),\n orientation: playerColor.value,\n coordinates: false,\n animation: {\n duration: ANIM_DELAY,\n enabled: true,\n },\n });\n\n // Make first move\n const firstMove = questionUtils.question.value.moves.shift()!;\n chessBoard.value.move(firstMove.substring(0, 2) as Key, firstMove.substring(2) as Key);\n chessEngine.value.move({\n from: firstMove.substring(0, 2),\n to: firstMove.substring(2),\n });\n updateChessground();\n });\n\n onUnmounted(() => {\n chessBoard.value?.destroy();\n chessEngine.value = undefined;\n });\n\n return {\n boardElement,\n playerColor,\n files,\n showPromotionDialog,\n promotionPieces,\n handlePromotion,\n ...viewableUtils,\n ...questionUtils,\n };\n },\n});\n</script>\n\n<style>\n@import '../../chessground/css/chessground.base.css';\n@import '../../chessground/css/chessground.brown.css';\n@import '../../chessground/css/chessground.cburnett.css';\n\n.puzzle-promotion-dialog {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n background: rgba(255, 255, 255, 0.95);\n padding: 15px;\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);\n z-index: 1000;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.puzzle-promotion-dialog button {\n padding: 10px 20px;\n font-size: 16px;\n border: none;\n background: #f0f0f0;\n border-radius: 4px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n width: 150px;\n}\n\n.puzzle-promotion-dialog button:hover {\n background: #e0e0e0;\n}\n\n/* Optional: Add piece symbols next to text */\n.puzzle-promotion-dialog button::before {\n content: attr(data-piece);\n font-size: 24px;\n}\n\n.puzzle-board-wrapper {\n display: flex;\n align-items: center;\n width: 440px;\n}\n\n.puzzle-ranks-labels {\n display: flex;\n flex-direction: column;\n justify-content: center;\n /* width: 0px; */\n height: 400px;\n margin-right: 10px;\n}\n\n.puzzle-ranks-labels.reversed {\n flex-direction: column-reverse;\n}\n\n.puzzle-ranks-labels div {\n height: 50px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.puzzle-board-and-files {\n display: flex;\n flex-direction: column;\n}\n\n.puzzle-files-labels {\n display: flex;\n justify-content: center;\n height: 20px;\n}\n\n.puzzle-files-labels.reversed {\n flex-direction: row-reverse;\n}\n\n.puzzle-files-labels div {\n width: 50px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n#cg {\n width: 400px;\n height: 400px;\n}\n</style>\n","<template>\n <!-- Template remains largely the same -->\n <div data-viewable=\"PuzzleView\">\n <p class=\"text-h5\">\n Make the best move for {{ playerColor === 'cg-white' ? 'White ♖♘♗♕♔♗♘♖' : 'Black ♜♞♝♚♛♝♞♜' }}:\n </p>\n <div class=\"puzzle-board-wrapper\">\n <div class=\"puzzle-ranks-labels\">\n <div v-for=\"rank in 8\" :key=\"rank\">{{ playerColor === 'cg-white' ? 9 - rank : rank }}</div>\n </div>\n <div class=\"puzzle-board-and-files\">\n <div id=\"cg\" ref=\"boardElement\"></div>\n <div class=\"puzzle-files-labels\">\n <div v-for=\"file in files\" :key=\"file\">{{ file }}</div>\n </div>\n </div>\n </div>\n <div v-if=\"showPromotionDialog\" class=\"puzzle-promotion-dialog\">\n <button v-for=\"piece in promotionPieces\" :key=\"piece.value\" @click=\"handlePromotion(piece.value)\">\n {{ playerColor === 'cg-white' ? piece.whiteSymbol : piece.blackSymbol }}\n {{ piece.name }}\n </button>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, ref, computed, onMounted, onUnmounted, PropType } from 'vue';\nimport { Chessground } from '../../chessground/chessground';\nimport { Key } from '../../chessground/types';\nimport { Api as cgAPI } from '../../chessground/api';\nimport { useViewable, useQuestionView } from '@vue-skuilder/common-ui';\nimport { ChessPuzzle } from './index';\nimport { Chess, SQUARES } from 'chess.js';\nimport { ViewData } from '@vue-skuilder/common';\nimport { useChessgroundBounds } from '../../composables/useChessgroundBounds';\n\n// Types and interfaces\ntype PromotionPiece = 'q' | 'r' | 'b' | 'n';\ntype Color = 'cg-white' | 'cg-black';\n\ninterface UciMove {\n from: string;\n to: string;\n promotion?: PromotionPiece;\n}\n\n// Helper functions (moved outside component)\nconst parseUciMove = (moveString: string): UciMove => {\n if (moveString.length < 4 || moveString.length > 5) {\n throw new Error(`Invalid UCI move format: ${moveString}`);\n }\n\n return {\n from: moveString.substring(0, 2),\n to: moveString.substring(2, 4),\n promotion: moveString.length === 5 ? (moveString[4] as PromotionPiece) : undefined,\n };\n};\n\nconst toDests = (chess: Chess) => {\n const dests = new Map();\n SQUARES.forEach((s) => {\n const ms = chess.moves({ square: s, verbose: true });\n if (ms.length)\n dests.set(\n s,\n ms.map((m) => m.to)\n );\n });\n return dests;\n};\n\nconst swapColor = (color: Color): Color => (color === 'cg-white' ? 'cg-black' : 'cg-white');\n\nconst toColor = (chess: Chess): Color => (chess.turn() === 'w' ? 'cg-white' : 'cg-black');\n\n// Chess puzzle component\nexport default defineComponent({\n name: 'PuzzleView',\n\n props: {\n data: {\n type: Array as PropType<ViewData[]>,\n required: true,\n },\n modifyDifficulty: {\n type: Number,\n required: false,\n default: 0,\n },\n },\n\n setup(props, { emit }) {\n // Initialize base utilities\n const viewableUtils = useViewable(props, emit, 'PuzzleView');\n const questionUtils = useQuestionView<ChessPuzzle>(viewableUtils);\n\n // State\n const boardElement = ref<HTMLElement | null>(null);\n const chessEngine = ref<Chess>();\n const chessBoard = ref<cgAPI>();\n const playerColor = ref<Color>('cg-white');\n const showPromotionDialog = ref(false);\n const promotionMove = ref<{ from: string; to: string } | null>(null);\n\n const ANIM_DELAY = 300;\n\n // Keep Chessground's cached board bounds in sync with the DOM —\n // StudySession's flex-centered transition container can shift the\n // board after Chessground reads its rect at mount, which leaves\n // click hitboxes offset from the rendered squares until a resize.\n useChessgroundBounds(boardElement, chessBoard);\n\n const promotionPieces = [\n { value: 'q', name: 'Queen', whiteSymbol: '♕', blackSymbol: '♛' },\n { value: 'r', name: 'Rook', whiteSymbol: '♖', blackSymbol: '♜' },\n { value: 'b', name: 'Bishop', whiteSymbol: '♗', blackSymbol: '♝' },\n { value: 'n', name: 'Knight', whiteSymbol: '♘', blackSymbol: '♞' },\n ];\n\n // Computed\n const files = computed(() => {\n const filesList = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];\n return playerColor.value === 'cg-white' ? filesList : filesList.reverse();\n });\n\n // Methods\n const isPromotionPiece = (p?: string): p is PromotionPiece => {\n if (!p) return false;\n return ['q', 'r', 'b', 'n'].includes(p);\n };\n\n const isUnfinishedPromotion = (from: string, to: string, promotionPiece?: PromotionPiece) => {\n if (isPromotionPiece(promotionPiece)) return false;\n // [ ] typing\n // @ts-expect-error - `from` is well-formed\n const piece = chessEngine.value?.get(from);\n return piece?.type === 'p' && (to[1] === '8' || to[1] === '1');\n };\n\n const updateChessground = () => {\n if (!chessEngine.value || !chessBoard.value) return;\n\n chessBoard.value.set({\n fen: chessEngine.value.fen(),\n turnColor: toColor(chessEngine.value),\n movable: {\n color: toColor(chessEngine.value),\n dests: toDests(chessEngine.value),\n },\n });\n };\n\n const handlePromotion = (promotionPiece: PromotionPiece | string) => {\n if (promotionPiece !== 'q' && promotionPiece !== 'r' && promotionPiece !== 'b' && promotionPiece !== 'n') {\n viewableUtils.logger.error(`Invalid promotion piece: ${promotionPiece}`);\n return;\n }\n if (!promotionMove.value) return;\n\n viewableUtils.logger.log(`promoting to ${promotionPiece}`);\n showPromotionDialog.value = false;\n checkMove(promotionMove.value.from, promotionMove.value.to, promotionPiece);\n };\n\n const checkMove = (orig: string, dest: string, promotionPiece?: PromotionPiece) => {\n if (!questionUtils.question.value?.moves.length) {\n throw new Error('No moves');\n }\n\n if (isUnfinishedPromotion(orig, dest, promotionPiece)) {\n promotionMove.value = { from: orig, to: dest };\n showPromotionDialog.value = true;\n return;\n }\n\n const expectedMove = questionUtils.question.value.moves[0];\n const moveMade = isPromotionPiece(promotionPiece) ? `${orig}${dest}${promotionPiece}` : `${orig}${dest}`;\n\n if (expectedMove === moveMade) {\n chessEngine.value?.move({\n from: orig,\n to: dest,\n promotion: isPromotionPiece(promotionPiece) ? promotionPiece : undefined,\n });\n updateChessground();\n\n questionUtils.question.value.moves.shift();\n\n if (questionUtils.question.value.moves.length === 0) {\n questionUtils.submitAnswer('');\n } else {\n window.setTimeout(() => {\n if (!questionUtils.question.value) return;\n\n const nextMove = questionUtils.question.value.moves.shift()!;\n const move = parseUciMove(nextMove);\n chessEngine.value?.move(move);\n updateChessground();\n }, ANIM_DELAY);\n }\n } else {\n // Handle incorrect move\n chessEngine.value?.move({ from: orig, to: dest, promotion: promotionPiece });\n if (chessEngine.value?.isCheckmate()) {\n questionUtils.submitAnswer(ChessPuzzle.CHECKMATE);\n } else {\n chessEngine.value?.undo();\n }\n\n questionUtils.submitAnswer(orig + dest + promotionPiece);\n updateChessground();\n }\n };\n\n // Initialization\n onMounted(() => {\n if (!boardElement.value) return;\n\n questionUtils.question.value = new ChessPuzzle(props.data);\n chessEngine.value = new Chess(questionUtils.question.value.fen);\n playerColor.value = swapColor(toColor(chessEngine.value));\n\n chessBoard.value = Chessground(boardElement.value, {\n movable: {\n free: false,\n showDests: true,\n dests: toDests(chessEngine.value),\n events: {\n // [ ] typing\n // @ts-expect-error - `orig` and `dest` are well-formed\n after: checkMove,\n },\n },\n draggable: {\n showGhost: true,\n },\n fen: chessEngine.value.fen(),\n orientation: playerColor.value,\n coordinates: false,\n animation: {\n duration: ANIM_DELAY,\n enabled: true,\n },\n });\n\n // Make first move\n const firstMove = questionUtils.question.value.moves.shift()!;\n chessBoard.value.move(firstMove.substring(0, 2) as Key, firstMove.substring(2) as Key);\n chessEngine.value.move({\n from: firstMove.substring(0, 2),\n to: firstMove.substring(2),\n });\n updateChessground();\n });\n\n onUnmounted(() => {\n chessBoard.value?.destroy();\n chessEngine.value = undefined;\n });\n\n return {\n boardElement,\n playerColor,\n files,\n showPromotionDialog,\n promotionPieces,\n handlePromotion,\n ...viewableUtils,\n ...questionUtils,\n };\n },\n});\n</script>\n\n<style>\n@import '../../chessground/css/chessground.base.css';\n@import '../../chessground/css/chessground.brown.css';\n@import '../../chessground/css/chessground.cburnett.css';\n\n.puzzle-promotion-dialog {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n background: rgba(255, 255, 255, 0.95);\n padding: 15px;\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);\n z-index: 1000;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.puzzle-promotion-dialog button {\n padding: 10px 20px;\n font-size: 16px;\n border: none;\n background: #f0f0f0;\n border-radius: 4px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n width: 150px;\n}\n\n.puzzle-promotion-dialog button:hover {\n background: #e0e0e0;\n}\n\n/* Optional: Add piece symbols next to text */\n.puzzle-promotion-dialog button::before {\n content: attr(data-piece);\n font-size: 24px;\n}\n\n.puzzle-board-wrapper {\n display: flex;\n align-items: center;\n width: 440px;\n}\n\n.puzzle-ranks-labels {\n display: flex;\n flex-direction: column;\n justify-content: center;\n /* width: 0px; */\n height: 400px;\n margin-right: 10px;\n}\n\n.puzzle-ranks-labels.reversed {\n flex-direction: column-reverse;\n}\n\n.puzzle-ranks-labels div {\n height: 50px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.puzzle-board-and-files {\n display: flex;\n flex-direction: column;\n}\n\n.puzzle-files-labels {\n display: flex;\n justify-content: center;\n height: 20px;\n}\n\n.puzzle-files-labels.reversed {\n flex-direction: row-reverse;\n}\n\n.puzzle-files-labels div {\n width: 50px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n#cg {\n width: 400px;\n height: 400px;\n}\n</style>\n","import { Question, ViewComponent } from '@vue-skuilder/common-ui';\nimport {\n Answer,\n DataShape,\n ViewData,\n DataShapeName,\n Status,\n FieldType,\n} from '@vue-skuilder/common';\nimport PuzzleView from './puzzle.vue';\nimport { Key as cgKey } from '../../chessground/types';\n\nexport class ChessPuzzle extends Question {\n public static dataShapes: DataShape[] = [\n {\n name: DataShapeName.CHESS_puzzle,\n fields: [\n {\n name: 'puzzleData', // see https://database.lichess.org/#puzzles\n type: FieldType.CHESS_PUZZLE,\n validator: {\n instructions: 'insert a valid fen string',\n test: function (s: string) {\n console.log(`running puzzle validator on ${s}`);\n\n if (!s) {\n return {\n status: Status.error,\n msg: 'no defined input',\n };\n }\n\n const split = s.split(',');\n if (split.length != 10) {\n return {\n status: Status.error,\n msg: 'puzzleData must have 8 comma-separated fields',\n };\n } else {\n return {\n status: Status.ok,\n msg: '',\n };\n }\n },\n },\n tagger: () => {\n // [ ] not actually used\n return ['test'];\n },\n },\n ],\n },\n ];\n public static views: ViewComponent[] = [PuzzleView];\n public static acceptsUserData: boolean = true;\n\n public static readonly CHECKMATE = 'CHECKMATE';\n\n public fen: string;\n id: string;\n moves: string[];\n rating: number;\n themes: string[];\n\n constructor(data: ViewData[]) {\n super(data);\n\n const [id, fen, movesStr, rating, , , , themes] = (data[0].puzzleData as string).split(',');\n this.id = id;\n this.fen = fen;\n this.moves = movesStr.split(' ');\n this.rating = parseInt(rating, 10);\n this.themes = themes.split(' ');\n // this.fen = data[0].fen as string;\n }\n\n public checkMove = (orig: cgKey, dest: cgKey) => {\n alert('checkMove');\n console.log('checkMove', orig, dest);\n console.log('this.moves[0]', this.moves[0]);\n\n if (this.moves[0] === dest) {\n return true;\n } else {\n return false;\n }\n };\n\n evaluate(a: Answer, t: number) {\n return {\n isCorrect: this.isCorrect(a),\n performance: this.displayedSkill(a, t),\n };\n }\n displayedSkill(a: Answer, t: number) {\n if (this.isCorrect(a)) {\n if (t < 5000) {\n return 1;\n } else {\n // scale from 1 at t=5s to 0,5 at t>=15s\n return 1 - Math.min(1, (t - 5000) / 10000);\n }\n }\n\n return 0;\n }\n dataShapes() {\n return ChessPuzzle.dataShapes;\n }\n\n views(): Array<ViewComponent> {\n return ChessPuzzle.views;\n }\n\n isCorrect(a: Answer) {\n // player actions have exhausted the move tree\n const sequenceComplete = this.moves.length === 0;\n\n return a === ChessPuzzle.CHECKMATE || sequenceComplete;\n }\n}\n","import { CourseWare } from '../CourseWare';\nimport { ChessPuzzle } from './questions/puzzle';\n\nconst chess: CourseWare = new CourseWare('chess', [ChessPuzzle]);\n\nexport default chess;\n"],"x_google_ignoreList":[20],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"chess-E2uOAyQS.js","names":["swapColor"],"sources":["../src/chess/chessground/types.ts","../src/chess/chessground/util.ts","../src/chess/chessground/premove.ts","../src/chess/chessground/board.ts","../src/chess/chessground/fen.ts","../src/chess/chessground/config.ts","../src/chess/chessground/anim.ts","../src/chess/chessground/draw.ts","../src/chess/chessground/drag.ts","../src/chess/chessground/explosion.ts","../src/chess/chessground/api.ts","../src/chess/chessground/state.ts","../src/chess/chessground/svg.ts","../src/chess/chessground/wrap.ts","../src/chess/chessground/drop.ts","../src/chess/chessground/events.ts","../src/chess/chessground/render.ts","../src/chess/chessground/sync.ts","../src/chess/chessground/autoPieces.ts","../src/chess/chessground/chessground.ts","../../../node_modules/chess.js/dist/esm/chess.js","../src/chess/composables/useChessgroundBounds.ts","../src/chess/questions/puzzle/puzzle.vue","../src/chess/questions/puzzle/puzzle.vue","../src/chess/questions/puzzle/index.ts","../src/chess/index.ts"],"sourcesContent":["export type Color = (typeof colors)[number];\nexport type Role = 'king' | 'queen' | 'rook' | 'bishop' | 'knight' | 'pawn';\nexport type File = (typeof files)[number];\nexport type Rank = (typeof ranks)[number];\nexport type Key = 'a0' | 'a1' | 'a2' | 'a3' | 'a4' | 'a5' | 'a6' | 'a7' | 'a8' |\n 'b1' | 'b2' | 'b3' | 'b4' | 'b5' | 'b6' | 'b7' | 'b8' |\n 'c1' | 'c2' | 'c3' | 'c4' | 'c5' | 'c6' | 'c7' | 'c8' |\n 'd1' | 'd2' | 'd3' | 'd4' | 'd5' | 'd6' | 'd7' | 'd8' |\n 'e1' | 'e2' | 'e3' | 'e4' | 'e5' | 'e6' | 'e7' | 'e8' |\n 'f1' | 'f2' | 'f3' | 'f4' | 'f5' | 'f6' | 'f7' | 'f8' |\n 'g1' | 'g2' | 'g3' | 'g4' | 'g5' | 'g6' | 'g7' | 'g8' |\n 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'h7' | 'h8';\nexport type FEN = string;\nexport type Pos = [number, number];\nexport interface Piece {\n role: Role;\n color: Color;\n promoted?: boolean;\n}\nexport interface Drop {\n role: Role;\n key: Key;\n}\nexport type Pieces = Map<Key, Piece>;\nexport type PiecesDiff = Map<Key, Piece | undefined>;\n\nexport type KeyPair = [Key, Key];\n\nexport type NumberPair = [number, number];\n\nexport type NumberQuad = [number, number, number, number];\n\nexport interface Rect {\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\nexport type Dests = Map<Key, Key[]>;\n\nexport interface Elements {\n board: HTMLElement;\n wrap: HTMLElement;\n container: HTMLElement;\n ghost?: HTMLElement;\n svg?: SVGElement;\n customSvg?: SVGElement;\n autoPieces?: HTMLElement;\n}\nexport interface Dom {\n elements: Elements;\n bounds: Memo<DOMRectReadOnly>;\n redraw: () => void;\n redrawNow: (skipSvg?: boolean) => void;\n unbind?: Unbind;\n destroyed?: boolean;\n}\nexport interface Exploding {\n stage: number;\n keys: readonly Key[];\n}\n\nexport interface MoveMetadata {\n premove: boolean;\n ctrlKey?: boolean;\n holdTime?: number;\n captured?: Piece;\n predrop?: boolean;\n}\nexport interface SetPremoveMetadata {\n ctrlKey?: boolean;\n}\n\nexport type MouchEvent = Event & Partial<MouseEvent & TouchEvent>;\n\nexport interface KeyedNode extends HTMLElement {\n cgKey: Key;\n}\nexport interface PieceNode extends KeyedNode {\n tagName: 'PIECE';\n cgPiece: string;\n cgAnimating?: boolean;\n cgFading?: boolean;\n cgDragging?: boolean;\n cgScale?: number;\n}\nexport interface SquareNode extends KeyedNode {\n tagName: 'SQUARE';\n}\n\nexport interface Memo<A> {\n (): A;\n clear: () => void;\n}\n\nexport interface Timer {\n start: () => void;\n cancel: () => void;\n stop: () => number;\n}\n\nexport type Redraw = () => void;\nexport type Unbind = () => void;\nexport type Milliseconds = number;\nexport type KHz = number;\n\nexport const colors = ['cg-white', 'cg-black'] as const;\nexport const files = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] as const;\nexport const ranks = ['1', '2', '3', '4', '5', '6', '7', '8'] as const;\n\nexport type RanksPosition = 'left' | 'right';\n\nexport type BrushColor = 'green' | 'red' | 'blue' | 'yellow';\n\nexport type SquareClasses = Map<Key, string>;\n","import * as cg from './types';\n\nexport const invRanks: readonly cg.Rank[] = [...cg.ranks].reverse();\n\nexport const allKeys: readonly cg.Key[] = Array.prototype.concat(\n ...cg.files.map(c => cg.ranks.map(r => c + r)),\n);\n\nexport const pos2key = (pos: cg.Pos): cg.Key => allKeys[8 * pos[0] + pos[1]];\n\nexport const key2pos = (k: cg.Key): cg.Pos => [k.charCodeAt(0) - 97, k.charCodeAt(1) - 49];\n\nexport const uciToMove = (uci: string | undefined): cg.Key[] | undefined => {\n if (!uci) return undefined;\n if (uci[1] === '@') return [uci.slice(2, 4) as cg.Key];\n return [uci.slice(0, 2), uci.slice(2, 4)] as cg.Key[];\n};\n\nexport const allPos: readonly cg.Pos[] = allKeys.map(key2pos);\n\nexport function memo<A>(f: () => A): cg.Memo<A> {\n let v: A | undefined;\n const ret = (): A => {\n if (v === undefined) v = f();\n return v;\n };\n ret.clear = () => {\n v = undefined;\n };\n return ret;\n}\n\nexport const timer = (): cg.Timer => {\n let startAt: number | undefined;\n return {\n start() {\n startAt = performance.now();\n },\n cancel() {\n startAt = undefined;\n },\n stop() {\n if (!startAt) return 0;\n const time = performance.now() - startAt;\n startAt = undefined;\n return time;\n },\n };\n};\n\nexport const opposite = (c: cg.Color): cg.Color => (c === 'cg-white' ? 'cg-black' : 'cg-white');\n\nexport const distanceSq = (pos1: cg.Pos, pos2: cg.Pos): number => {\n const dx = pos1[0] - pos2[0],\n dy = pos1[1] - pos2[1];\n return dx * dx + dy * dy;\n};\n\nexport const samePiece = (p1: cg.Piece, p2: cg.Piece): boolean =>\n p1.role === p2.role && p1.color === p2.color;\n\nexport const posToTranslate =\n (bounds: DOMRectReadOnly): ((pos: cg.Pos, asWhite: boolean) => cg.NumberPair) =>\n (pos, asWhite) => [\n ((asWhite ? pos[0] : 7 - pos[0]) * bounds.width) / 8,\n ((asWhite ? 7 - pos[1] : pos[1]) * bounds.height) / 8,\n ];\n\nexport const translate = (el: HTMLElement, pos: cg.NumberPair): void => {\n el.style.transform = `translate(${pos[0]}px,${pos[1]}px)`;\n};\n\nexport const translateAndScale = (el: HTMLElement, pos: cg.NumberPair, scale = 1): void => {\n el.style.transform = `translate(${pos[0]}px,${pos[1]}px) scale(${scale})`;\n};\n\nexport const setVisible = (el: HTMLElement, v: boolean): void => {\n el.style.visibility = v ? 'visible' : 'hidden';\n};\n\nexport const eventPosition = (e: cg.MouchEvent): cg.NumberPair | undefined => {\n if (e.clientX || e.clientX === 0) return [e.clientX, e.clientY!];\n if (e.targetTouches?.[0]) return [e.targetTouches[0].clientX, e.targetTouches[0].clientY];\n return; // touchend has no position!\n};\n\nexport const isRightButton = (e: cg.MouchEvent): boolean => e.button === 2;\n\nexport const createEl = (tagName: string, className?: string): HTMLElement => {\n const el = document.createElement(tagName);\n if (className) el.className = className;\n return el;\n};\n\nexport function computeSquareCenter(key: cg.Key, asWhite: boolean, bounds: DOMRectReadOnly): cg.NumberPair {\n const pos = key2pos(key);\n if (!asWhite) {\n pos[0] = 7 - pos[0];\n pos[1] = 7 - pos[1];\n }\n return [\n bounds.left + (bounds.width * pos[0]) / 8 + bounds.width / 16,\n bounds.top + (bounds.height * (7 - pos[1])) / 8 + bounds.height / 16,\n ];\n}\n","import * as util from './util';\nimport * as cg from './types';\n\ntype Mobility = (x1: number, y1: number, x2: number, y2: number) => boolean;\n\nconst diff = (a: number, b: number): number => Math.abs(a - b);\n\nconst pawn =\n (color: cg.Color): Mobility =>\n (x1, y1, x2, y2) =>\n diff(x1, x2) < 2 &&\n (color === 'cg-white'\n ? // allow 2 squares from first two ranks, for horde\n y2 === y1 + 1 || (y1 <= 1 && y2 === y1 + 2 && x1 === x2)\n : y2 === y1 - 1 || (y1 >= 6 && y2 === y1 - 2 && x1 === x2));\n\nexport const knight: Mobility = (x1, y1, x2, y2) => {\n const xd = diff(x1, x2);\n const yd = diff(y1, y2);\n return (xd === 1 && yd === 2) || (xd === 2 && yd === 1);\n};\n\nconst bishop: Mobility = (x1, y1, x2, y2) => {\n return diff(x1, x2) === diff(y1, y2);\n};\n\nconst rook: Mobility = (x1, y1, x2, y2) => {\n return x1 === x2 || y1 === y2;\n};\n\nexport const queen: Mobility = (x1, y1, x2, y2) => {\n return bishop(x1, y1, x2, y2) || rook(x1, y1, x2, y2);\n};\n\nconst king =\n (color: cg.Color, rookFiles: number[], canCastle: boolean): Mobility =>\n (x1, y1, x2, y2) =>\n (diff(x1, x2) < 2 && diff(y1, y2) < 2) ||\n (canCastle &&\n y1 === y2 &&\n y1 === (color === 'cg-white' ? 0 : 7) &&\n ((x1 === 4 && ((x2 === 2 && rookFiles.includes(0)) || (x2 === 6 && rookFiles.includes(7)))) ||\n rookFiles.includes(x2)));\n\nfunction rookFilesOf(pieces: cg.Pieces, color: cg.Color) {\n const backrank = color === 'cg-white' ? '1' : '8';\n const files = [];\n for (const [key, piece] of pieces) {\n if (key[1] === backrank && piece.color === color && piece.role === 'rook') {\n files.push(util.key2pos(key)[0]);\n }\n }\n return files;\n}\n\nexport function premove(pieces: cg.Pieces, key: cg.Key, canCastle: boolean): cg.Key[] {\n const piece = pieces.get(key);\n if (!piece) return [];\n const pos = util.key2pos(key),\n r = piece.role,\n mobility: Mobility =\n r === 'pawn'\n ? pawn(piece.color)\n : r === 'knight'\n ? knight\n : r === 'bishop'\n ? bishop\n : r === 'rook'\n ? rook\n : r === 'queen'\n ? queen\n : king(piece.color, rookFilesOf(pieces, piece.color), canCastle);\n return util.allPos\n .filter(pos2 => (pos[0] !== pos2[0] || pos[1] !== pos2[1]) && mobility(pos[0], pos[1], pos2[0], pos2[1]))\n .map(util.pos2key);\n}\n","import { HeadlessState } from './state';\nimport { pos2key, key2pos, opposite, distanceSq, allPos, computeSquareCenter } from './util';\nimport { premove, queen, knight } from './premove';\nimport * as cg from './types';\n\nexport function callUserFunction<T extends (...args: any[]) => void>(\n f: T | undefined,\n ...args: Parameters<T>\n): void {\n if (f) setTimeout(() => f(...args), 1);\n}\n\nexport function toggleOrientation(state: HeadlessState): void {\n state.orientation = opposite(state.orientation);\n state.animation.current = state.draggable.current = state.selected = undefined;\n}\n\nexport function reset(state: HeadlessState): void {\n state.lastMove = undefined;\n unselect(state);\n unsetPremove(state);\n unsetPredrop(state);\n}\n\nexport function setPieces(state: HeadlessState, pieces: cg.PiecesDiff): void {\n for (const [key, piece] of pieces) {\n if (piece) state.pieces.set(key, piece);\n else state.pieces.delete(key);\n }\n}\n\nexport function setCheck(state: HeadlessState, color: cg.Color | boolean): void {\n state.check = undefined;\n if (color === true) color = state.turnColor;\n if (color)\n for (const [k, p] of state.pieces) {\n if (p.role === 'king' && p.color === color) {\n state.check = k;\n }\n }\n}\n\nfunction setPremove(state: HeadlessState, orig: cg.Key, dest: cg.Key, meta: cg.SetPremoveMetadata): void {\n unsetPredrop(state);\n state.premovable.current = [orig, dest];\n callUserFunction(state.premovable.events.set, orig, dest, meta);\n}\n\nexport function unsetPremove(state: HeadlessState): void {\n if (state.premovable.current) {\n state.premovable.current = undefined;\n callUserFunction(state.premovable.events.unset);\n }\n}\n\nfunction setPredrop(state: HeadlessState, role: cg.Role, key: cg.Key): void {\n unsetPremove(state);\n state.predroppable.current = { role, key };\n callUserFunction(state.predroppable.events.set, role, key);\n}\n\nexport function unsetPredrop(state: HeadlessState): void {\n const pd = state.predroppable;\n if (pd.current) {\n pd.current = undefined;\n callUserFunction(pd.events.unset);\n }\n}\n\nfunction tryAutoCastle(state: HeadlessState, orig: cg.Key, dest: cg.Key): boolean {\n if (!state.autoCastle) return false;\n\n const king = state.pieces.get(orig);\n if (!king || king.role !== 'king') return false;\n\n const origPos = key2pos(orig);\n const destPos = key2pos(dest);\n if ((origPos[1] !== 0 && origPos[1] !== 7) || origPos[1] !== destPos[1]) return false;\n if (origPos[0] === 4 && !state.pieces.has(dest)) {\n if (destPos[0] === 6) dest = pos2key([7, destPos[1]]);\n else if (destPos[0] === 2) dest = pos2key([0, destPos[1]]);\n }\n const rook = state.pieces.get(dest);\n if (!rook || rook.color !== king.color || rook.role !== 'rook') return false;\n\n state.pieces.delete(orig);\n state.pieces.delete(dest);\n\n if (origPos[0] < destPos[0]) {\n state.pieces.set(pos2key([6, destPos[1]]), king);\n state.pieces.set(pos2key([5, destPos[1]]), rook);\n } else {\n state.pieces.set(pos2key([2, destPos[1]]), king);\n state.pieces.set(pos2key([3, destPos[1]]), rook);\n }\n return true;\n}\n\nexport function baseMove(state: HeadlessState, orig: cg.Key, dest: cg.Key): cg.Piece | boolean {\n const origPiece = state.pieces.get(orig),\n destPiece = state.pieces.get(dest);\n if (orig === dest || !origPiece) return false;\n const captured = destPiece && destPiece.color !== origPiece.color ? destPiece : undefined;\n if (dest === state.selected) unselect(state);\n callUserFunction(state.events.move, orig, dest, captured);\n if (!tryAutoCastle(state, orig, dest)) {\n state.pieces.set(dest, origPiece);\n state.pieces.delete(orig);\n }\n state.lastMove = [orig, dest];\n state.check = undefined;\n callUserFunction(state.events.change);\n return captured || true;\n}\n\nexport function baseNewPiece(state: HeadlessState, piece: cg.Piece, key: cg.Key, force?: boolean): boolean {\n if (state.pieces.has(key)) {\n if (force) state.pieces.delete(key);\n else return false;\n }\n callUserFunction(state.events.dropNewPiece, piece, key);\n state.pieces.set(key, piece);\n state.lastMove = [key];\n state.check = undefined;\n callUserFunction(state.events.change);\n state.movable.dests = undefined;\n state.turnColor = opposite(state.turnColor);\n return true;\n}\n\nfunction baseUserMove(state: HeadlessState, orig: cg.Key, dest: cg.Key): cg.Piece | boolean {\n const result = baseMove(state, orig, dest);\n if (result) {\n state.movable.dests = undefined;\n state.turnColor = opposite(state.turnColor);\n state.animation.current = undefined;\n }\n return result;\n}\n\nexport function userMove(state: HeadlessState, orig: cg.Key, dest: cg.Key): boolean {\n if (canMove(state, orig, dest)) {\n const result = baseUserMove(state, orig, dest);\n if (result) {\n const holdTime = state.hold.stop();\n unselect(state);\n const metadata: cg.MoveMetadata = {\n premove: false,\n ctrlKey: state.stats.ctrlKey,\n holdTime,\n };\n if (result !== true) metadata.captured = result;\n callUserFunction(state.movable.events.after, orig, dest, metadata);\n return true;\n }\n } else if (canPremove(state, orig, dest)) {\n setPremove(state, orig, dest, {\n ctrlKey: state.stats.ctrlKey,\n });\n unselect(state);\n return true;\n }\n unselect(state);\n return false;\n}\n\nexport function dropNewPiece(state: HeadlessState, orig: cg.Key, dest: cg.Key, force?: boolean): void {\n const piece = state.pieces.get(orig);\n if (piece && (canDrop(state, orig, dest) || force)) {\n state.pieces.delete(orig);\n baseNewPiece(state, piece, dest, force);\n callUserFunction(state.movable.events.afterNewPiece, piece.role, dest, {\n premove: false,\n predrop: false,\n });\n } else if (piece && canPredrop(state, orig, dest)) {\n setPredrop(state, piece.role, dest);\n } else {\n unsetPremove(state);\n unsetPredrop(state);\n }\n state.pieces.delete(orig);\n unselect(state);\n}\n\nexport function selectSquare(state: HeadlessState, key: cg.Key, force?: boolean): void {\n callUserFunction(state.events.select, key);\n if (state.selected) {\n if (state.selected === key && !state.draggable.enabled) {\n unselect(state);\n state.hold.cancel();\n return;\n } else if ((state.selectable.enabled || force) && state.selected !== key) {\n if (userMove(state, state.selected, key)) {\n state.stats.dragged = false;\n return;\n }\n }\n }\n if (\n (state.selectable.enabled || state.draggable.enabled) &&\n (isMovable(state, key) || isPremovable(state, key))\n ) {\n setSelected(state, key);\n state.hold.start();\n }\n}\n\nexport function setSelected(state: HeadlessState, key: cg.Key): void {\n state.selected = key;\n if (isPremovable(state, key)) {\n // calculate chess premoves if custom premoves are not passed\n if (!state.premovable.customDests) {\n state.premovable.dests = premove(state.pieces, key, state.premovable.castle);\n }\n } else state.premovable.dests = undefined;\n}\n\nexport function unselect(state: HeadlessState): void {\n state.selected = undefined;\n state.premovable.dests = undefined;\n state.hold.cancel();\n}\n\nfunction isMovable(state: HeadlessState, orig: cg.Key): boolean {\n const piece = state.pieces.get(orig);\n return (\n !!piece &&\n (state.movable.color === 'both' ||\n (state.movable.color === piece.color && state.turnColor === piece.color))\n );\n}\n\nexport const canMove = (state: HeadlessState, orig: cg.Key, dest: cg.Key): boolean =>\n orig !== dest &&\n isMovable(state, orig) &&\n (state.movable.free || !!state.movable.dests?.get(orig)?.includes(dest));\n\nfunction canDrop(state: HeadlessState, orig: cg.Key, dest: cg.Key): boolean {\n const piece = state.pieces.get(orig);\n return (\n !!piece &&\n (orig === dest || !state.pieces.has(dest)) &&\n (state.movable.color === 'both' ||\n (state.movable.color === piece.color && state.turnColor === piece.color))\n );\n}\n\nfunction isPremovable(state: HeadlessState, orig: cg.Key): boolean {\n const piece = state.pieces.get(orig);\n return (\n !!piece &&\n state.premovable.enabled &&\n state.movable.color === piece.color &&\n state.turnColor !== piece.color\n );\n}\n\nfunction canPremove(state: HeadlessState, orig: cg.Key, dest: cg.Key): boolean {\n const validPremoves: cg.Key[] =\n state.premovable.customDests?.get(orig) ?? premove(state.pieces, orig, state.premovable.castle);\n return orig !== dest && isPremovable(state, orig) && validPremoves.includes(dest);\n}\n\nfunction canPredrop(state: HeadlessState, orig: cg.Key, dest: cg.Key): boolean {\n const piece = state.pieces.get(orig);\n const destPiece = state.pieces.get(dest);\n return (\n !!piece &&\n (!destPiece || destPiece.color !== state.movable.color) &&\n state.predroppable.enabled &&\n (piece.role !== 'pawn' || (dest[1] !== '1' && dest[1] !== '8')) &&\n state.movable.color === piece.color &&\n state.turnColor !== piece.color\n );\n}\n\nexport function isDraggable(state: HeadlessState, orig: cg.Key): boolean {\n const piece = state.pieces.get(orig);\n return (\n !!piece &&\n state.draggable.enabled &&\n (state.movable.color === 'both' ||\n (state.movable.color === piece.color && (state.turnColor === piece.color || state.premovable.enabled)))\n );\n}\n\nexport function playPremove(state: HeadlessState): boolean {\n const move = state.premovable.current;\n if (!move) return false;\n const orig = move[0],\n dest = move[1];\n let success = false;\n if (canMove(state, orig, dest)) {\n const result = baseUserMove(state, orig, dest);\n if (result) {\n const metadata: cg.MoveMetadata = { premove: true };\n if (result !== true) metadata.captured = result;\n callUserFunction(state.movable.events.after, orig, dest, metadata);\n success = true;\n }\n }\n unsetPremove(state);\n return success;\n}\n\nexport function playPredrop(state: HeadlessState, validate: (drop: cg.Drop) => boolean): boolean {\n const drop = state.predroppable.current;\n let success = false;\n if (!drop) return false;\n if (validate(drop)) {\n const piece = {\n role: drop.role,\n color: state.movable.color,\n } as cg.Piece;\n if (baseNewPiece(state, piece, drop.key)) {\n callUserFunction(state.movable.events.afterNewPiece, drop.role, drop.key, {\n premove: false,\n predrop: true,\n });\n success = true;\n }\n }\n unsetPredrop(state);\n return success;\n}\n\nexport function cancelMove(state: HeadlessState): void {\n unsetPremove(state);\n unsetPredrop(state);\n unselect(state);\n}\n\nexport function stop(state: HeadlessState): void {\n state.movable.color = state.movable.dests = state.animation.current = undefined;\n cancelMove(state);\n}\n\nexport function getKeyAtDomPos(\n pos: cg.NumberPair,\n asWhite: boolean,\n bounds: DOMRectReadOnly,\n): cg.Key | undefined {\n let file = Math.floor((8 * (pos[0] - bounds.left)) / bounds.width);\n if (!asWhite) file = 7 - file;\n let rank = 7 - Math.floor((8 * (pos[1] - bounds.top)) / bounds.height);\n if (!asWhite) rank = 7 - rank;\n return file >= 0 && file < 8 && rank >= 0 && rank < 8 ? pos2key([file, rank]) : undefined;\n}\n\nexport function getSnappedKeyAtDomPos(\n orig: cg.Key,\n pos: cg.NumberPair,\n asWhite: boolean,\n bounds: DOMRectReadOnly,\n): cg.Key | undefined {\n const origPos = key2pos(orig);\n const validSnapPos = allPos.filter(\n pos2 =>\n queen(origPos[0], origPos[1], pos2[0], pos2[1]) || knight(origPos[0], origPos[1], pos2[0], pos2[1]),\n );\n const validSnapCenters = validSnapPos.map(pos2 => computeSquareCenter(pos2key(pos2), asWhite, bounds));\n const validSnapDistances = validSnapCenters.map(pos2 => distanceSq(pos, pos2));\n const [, closestSnapIndex] = validSnapDistances.reduce(\n (a, b, index) => (a[0] < b ? a : [b, index]),\n [validSnapDistances[0], 0],\n );\n return pos2key(validSnapPos[closestSnapIndex]);\n}\n\nexport const whitePov = (s: HeadlessState): boolean => s.orientation === 'cg-white';\n","import { pos2key, invRanks } from './util';\nimport * as cg from './types';\n\nexport const initial: cg.FEN = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR';\n\nconst roles: { [letter: string]: cg.Role } = {\n p: 'pawn',\n r: 'rook',\n n: 'knight',\n b: 'bishop',\n q: 'queen',\n k: 'king',\n};\n\nconst letters = {\n pawn: 'p',\n rook: 'r',\n knight: 'n',\n bishop: 'b',\n queen: 'q',\n king: 'k',\n};\n\nexport function read(fen: cg.FEN): cg.Pieces {\n if (fen === 'start') fen = initial;\n const pieces: cg.Pieces = new Map();\n let row = 7,\n col = 0;\n for (const c of fen) {\n switch (c) {\n case ' ':\n case '[':\n return pieces;\n case '/':\n --row;\n if (row < 0) return pieces;\n col = 0;\n break;\n case '~': {\n const piece = pieces.get(pos2key([col - 1, row]));\n if (piece) piece.promoted = true;\n break;\n }\n default: {\n const nb = c.charCodeAt(0);\n if (nb < 57) col += nb - 48;\n else {\n const role = c.toLowerCase();\n pieces.set(pos2key([col, row]), {\n role: roles[role],\n color: c === role ? 'cg-black' : 'cg-white',\n });\n ++col;\n }\n }\n }\n }\n return pieces;\n}\n\nexport function write(pieces: cg.Pieces): cg.FEN {\n return invRanks\n .map(y =>\n cg.files\n .map(x => {\n const piece = pieces.get((x + y) as cg.Key);\n if (piece) {\n let p = letters[piece.role];\n if (piece.color === 'cg-white') p = p.toUpperCase();\n if (piece.promoted) p += '~';\n return p;\n } else return '1';\n })\n .join(''),\n )\n .join('/')\n .replace(/1{2,}/g, s => s.length.toString());\n}\n","import { HeadlessState } from './state';\nimport { setCheck, setSelected } from './board';\nimport { read as fenRead } from './fen';\nimport { DrawShape, DrawBrushes } from './draw';\nimport * as cg from './types';\n\nexport interface Config {\n fen?: cg.FEN; // chess position in Forsyth notation\n orientation?: cg.Color; // board orientation. white | black\n turnColor?: cg.Color; // turn to play. white | black\n check?: cg.Color | boolean; // true for current color, false to unset\n lastMove?: cg.Key[]; // squares part of the last move [\"c3\", \"c4\"]\n selected?: cg.Key; // square currently selected \"a1\"\n coordinates?: boolean; // include coords attributes\n coordinatesOnSquares?: boolean; // include coords attributes on every square\n autoCastle?: boolean; // immediately complete the castle by moving the rook after king move\n viewOnly?: boolean; // don't bind events: the user will never be able to move pieces around\n disableContextMenu?: boolean; // because who needs a context menu on a chessboard\n addPieceZIndex?: boolean; // adds z-index values to pieces (for 3D)\n addDimensionsCssVarsTo?: HTMLElement; // add ---cg-width and ---cg-height CSS vars containing the board's dimensions to this element\n blockTouchScroll?: boolean; // block scrolling via touch dragging on the board, e.g. for coordinate training\n // pieceKey: boolean; // add a data-key attribute to piece elements\n trustAllEvents?: boolean; // disable checking for human only input (e.isTrusted)\n highlight?: {\n lastMove?: boolean; // add last-move class to squares\n check?: boolean; // add check class to squares\n custom?: cg.SquareClasses; // add custom classes to custom squares\n };\n animation?: {\n enabled?: boolean;\n duration?: number;\n };\n movable?: {\n free?: boolean; // all moves are valid - board editor\n color?: cg.Color | 'both'; // color that can move. white | black | both | undefined\n dests?: cg.Dests; // valid moves. {\"a2\" [\"a3\" \"a4\"] \"b1\" [\"a3\" \"c3\"]}\n showDests?: boolean; // whether to add the move-dest class on squares\n events?: {\n after?: (orig: cg.Key, dest: cg.Key, metadata: cg.MoveMetadata) => void; // called after the move has been played\n afterNewPiece?: (role: cg.Role, key: cg.Key, metadata: cg.MoveMetadata) => void; // called after a new piece is dropped on the board\n };\n rookCastle?: boolean; // castle by moving the king to the rook\n };\n premovable?: {\n enabled?: boolean; // allow premoves for color that can not move\n showDests?: boolean; // whether to add the premove-dest class on squares\n castle?: boolean; // whether to allow king castle premoves\n dests?: cg.Key[]; // premove destinations for the current selection\n customDests?: cg.Dests; // use custom valid premoves. {\"a2\" [\"a3\" \"a4\"] \"b1\" [\"a3\" \"c3\"]}\n events?: {\n set?: (orig: cg.Key, dest: cg.Key, metadata?: cg.SetPremoveMetadata) => void; // called after the premove has been set\n unset?: () => void; // called after the premove has been unset\n };\n };\n predroppable?: {\n enabled?: boolean; // allow predrops for color that can not move\n events?: {\n set?: (role: cg.Role, key: cg.Key) => void; // called after the predrop has been set\n unset?: () => void; // called after the predrop has been unset\n };\n };\n draggable?: {\n enabled?: boolean; // allow moves & premoves to use drag'n drop\n distance?: number; // minimum distance to initiate a drag; in pixels\n autoDistance?: boolean; // lets chessground set distance to zero when user drags pieces\n showGhost?: boolean; // show ghost of piece being dragged\n deleteOnDropOff?: boolean; // delete a piece when it is dropped off the board\n };\n selectable?: {\n // disable to enforce dragging over click-click move\n enabled?: boolean;\n };\n events?: {\n change?: () => void; // called after the situation changes on the board\n // called after a piece has been moved.\n // capturedPiece is undefined or like {color: 'cg-white'; 'role': 'queen'}\n move?: (orig: cg.Key, dest: cg.Key, capturedPiece?: cg.Piece) => void;\n dropNewPiece?: (piece: cg.Piece, key: cg.Key) => void;\n select?: (key: cg.Key) => void; // called when a square is selected\n insert?: (elements: cg.Elements) => void; // when the board DOM has been (re)inserted\n };\n drawable?: {\n enabled?: boolean; // can draw\n visible?: boolean; // can view\n defaultSnapToValidMove?: boolean;\n // false to keep the drawing if a movable piece is clicked.\n // Clicking an empty square or immovable piece will clear the drawing regardless.\n eraseOnClick?: boolean;\n shapes?: DrawShape[];\n autoShapes?: DrawShape[];\n brushes?: DrawBrushes;\n onChange?: (shapes: DrawShape[]) => void; // called after drawable shapes change\n };\n}\n\nexport function applyAnimation(state: HeadlessState, config: Config): void {\n if (config.animation) {\n deepMerge(state.animation, config.animation);\n // no need for such short animations\n if ((state.animation.duration || 0) < 70) state.animation.enabled = false;\n }\n}\n\nexport function configure(state: HeadlessState, config: Config): void {\n // don't merge destinations and autoShapes. Just override.\n if (config.movable?.dests) state.movable.dests = undefined;\n if (config.drawable?.autoShapes) state.drawable.autoShapes = [];\n\n deepMerge(state, config);\n\n // if a fen was provided, replace the pieces\n if (config.fen) {\n state.pieces = fenRead(config.fen);\n state.drawable.shapes = config.drawable?.shapes || [];\n }\n\n // apply config values that could be undefined yet meaningful\n if ('check' in config) setCheck(state, config.check || false);\n if ('lastMove' in config && !config.lastMove) state.lastMove = undefined;\n // in case of ZH drop last move, there's a single square.\n // if the previous last move had two squares,\n // the merge algorithm will incorrectly keep the second square.\n else if (config.lastMove) state.lastMove = config.lastMove;\n\n // fix move/premove dests\n if (state.selected) setSelected(state, state.selected);\n\n applyAnimation(state, config);\n\n if (!state.movable.rookCastle && state.movable.dests) {\n const rank = state.movable.color === 'cg-white' ? '1' : '8',\n kingStartPos = ('e' + rank) as cg.Key,\n dests = state.movable.dests.get(kingStartPos),\n king = state.pieces.get(kingStartPos);\n if (!dests || !king || king.role !== 'king') return;\n state.movable.dests.set(\n kingStartPos,\n dests.filter(\n d =>\n !(d === 'a' + rank && dests.includes(('c' + rank) as cg.Key)) &&\n !(d === 'h' + rank && dests.includes(('g' + rank) as cg.Key)),\n ),\n );\n }\n}\n\nfunction deepMerge(base: any, extend: any): void {\n for (const key in extend) {\n if (Object.prototype.hasOwnProperty.call(extend, key)) {\n if (\n Object.prototype.hasOwnProperty.call(base, key) &&\n isPlainObject(base[key]) &&\n isPlainObject(extend[key])\n )\n deepMerge(base[key], extend[key]);\n else base[key] = extend[key];\n }\n }\n}\n\nfunction isPlainObject(o: unknown): boolean {\n if (typeof o !== 'object' || o === null) return false;\n const proto = Object.getPrototypeOf(o);\n return proto === Object.prototype || proto === null;\n}\n","import { State } from './state';\nimport * as util from './util';\nimport * as cg from './types';\n\nexport type Mutation<A> = (state: State) => A;\n\n// 0,1 animation goal\n// 2,3 animation current status\nexport type AnimVector = cg.NumberQuad;\n\nexport type AnimVectors = Map<cg.Key, AnimVector>;\n\nexport type AnimFadings = Map<cg.Key, cg.Piece>;\n\nexport interface AnimPlan {\n anims: AnimVectors;\n fadings: AnimFadings;\n}\n\nexport interface AnimCurrent {\n start: DOMHighResTimeStamp;\n frequency: cg.KHz;\n plan: AnimPlan;\n}\n\nexport const anim = <A>(mutation: Mutation<A>, state: State): A =>\n state.animation.enabled ? animate(mutation, state) : render(mutation, state);\n\nexport function render<A>(mutation: Mutation<A>, state: State): A {\n const result = mutation(state);\n state.dom.redraw();\n return result;\n}\n\ninterface AnimPiece {\n key: cg.Key;\n pos: cg.Pos;\n piece: cg.Piece;\n}\ntype AnimPieces = Map<cg.Key, AnimPiece>;\n\nconst makePiece = (key: cg.Key, piece: cg.Piece): AnimPiece => ({\n key: key,\n pos: util.key2pos(key),\n piece: piece,\n});\n\nconst closer = (piece: AnimPiece, pieces: AnimPiece[]): AnimPiece | undefined =>\n pieces.sort((p1, p2) => util.distanceSq(piece.pos, p1.pos) - util.distanceSq(piece.pos, p2.pos))[0];\n\nfunction computePlan(prevPieces: cg.Pieces, current: State): AnimPlan {\n const anims: AnimVectors = new Map(),\n animedOrigs: cg.Key[] = [],\n fadings: AnimFadings = new Map(),\n missings: AnimPiece[] = [],\n news: AnimPiece[] = [],\n prePieces: AnimPieces = new Map();\n let curP: cg.Piece | undefined, preP: AnimPiece | undefined, vector: cg.NumberPair;\n for (const [k, p] of prevPieces) {\n prePieces.set(k, makePiece(k, p));\n }\n for (const key of util.allKeys) {\n curP = current.pieces.get(key);\n preP = prePieces.get(key);\n if (curP) {\n if (preP) {\n if (!util.samePiece(curP, preP.piece)) {\n missings.push(preP);\n news.push(makePiece(key, curP));\n }\n } else news.push(makePiece(key, curP));\n } else if (preP) missings.push(preP);\n }\n for (const newP of news) {\n preP = closer(\n newP,\n missings.filter(p => util.samePiece(newP.piece, p.piece)),\n );\n if (preP) {\n vector = [preP.pos[0] - newP.pos[0], preP.pos[1] - newP.pos[1]];\n anims.set(newP.key, vector.concat(vector) as AnimVector);\n animedOrigs.push(preP.key);\n }\n }\n for (const p of missings) {\n if (!animedOrigs.includes(p.key)) fadings.set(p.key, p.piece);\n }\n\n return {\n anims: anims,\n fadings: fadings,\n };\n}\n\nfunction step(state: State, now: DOMHighResTimeStamp): void {\n const cur = state.animation.current;\n if (cur === undefined) {\n // animation was canceled :(\n if (!state.dom.destroyed) state.dom.redrawNow();\n return;\n }\n const rest = 1 - (now - cur.start) * cur.frequency;\n if (rest <= 0) {\n state.animation.current = undefined;\n state.dom.redrawNow();\n } else {\n const ease = easing(rest);\n for (const cfg of cur.plan.anims.values()) {\n cfg[2] = cfg[0] * ease;\n cfg[3] = cfg[1] * ease;\n }\n state.dom.redrawNow(true); // optimisation: don't render SVG changes during animations\n requestAnimationFrame((now = performance.now()) => step(state, now));\n }\n}\n\nfunction animate<A>(mutation: Mutation<A>, state: State): A {\n // clone state before mutating it\n const prevPieces: cg.Pieces = new Map(state.pieces);\n\n const result = mutation(state);\n const plan = computePlan(prevPieces, state);\n if (plan.anims.size || plan.fadings.size) {\n const alreadyRunning = state.animation.current && state.animation.current.start;\n state.animation.current = {\n start: performance.now(),\n frequency: 1 / state.animation.duration,\n plan: plan,\n };\n if (!alreadyRunning) step(state, performance.now());\n } else {\n // don't animate, just render right away\n state.dom.redraw();\n }\n return result;\n}\n\n// https://gist.github.com/gre/1650294\nconst easing = (t: number): number => (t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1);\n","import { State } from './state';\nimport { unselect, cancelMove, getKeyAtDomPos, getSnappedKeyAtDomPos, whitePov } from './board';\nimport { eventPosition, isRightButton } from './util';\nimport * as cg from './types';\n\nexport interface DrawShape {\n orig: cg.Key;\n dest?: cg.Key;\n brush?: string; // if no brush, no shape. label moved to top right of square\n modifiers?: DrawModifiers;\n piece?: DrawShapePiece;\n customSvg?: { html: string; center?: 'orig' | 'dest' | 'label' }; // 100 x 100 viewbox cenetered at [50,50]\n label?: { text: string; fill?: string }; // fill is in '#rrggbb' format\n}\n\nexport interface DrawModifiers {\n lineWidth?: number;\n hilite?: boolean;\n}\n\nexport interface DrawShapePiece {\n role: cg.Role;\n color: cg.Color;\n scale?: number;\n}\n\nexport interface DrawBrush {\n key: string;\n color: string;\n opacity: number;\n lineWidth: number;\n}\n\nexport interface DrawBrushes {\n green: DrawBrush;\n red: DrawBrush;\n blue: DrawBrush;\n yellow: DrawBrush;\n [color: string]: DrawBrush;\n}\n\nexport interface Drawable {\n enabled: boolean; // can draw\n visible: boolean; // can view\n defaultSnapToValidMove: boolean;\n eraseOnClick: boolean;\n onChange?: (shapes: DrawShape[]) => void;\n shapes: DrawShape[]; // user shapes\n autoShapes: DrawShape[]; // computer shapes\n current?: DrawCurrent;\n brushes: DrawBrushes;\n prevSvgHash: string;\n}\n\nexport interface DrawCurrent {\n orig: cg.Key; // orig key of drawing\n dest?: cg.Key; // shape dest, or undefined for circle\n mouseSq?: cg.Key; // square being moused over\n pos: cg.NumberPair; // relative current position\n brush: cg.BrushColor; // brush name for shape\n snapToValidMove: boolean; // whether to snap to valid piece moves\n}\n\nconst brushes: cg.BrushColor[] = ['green', 'red', 'blue', 'yellow'];\n\nexport function start(state: State, e: cg.MouchEvent): void {\n // support one finger touch only\n if (e.touches && e.touches.length > 1) return;\n e.stopPropagation();\n e.preventDefault();\n if (e.ctrlKey) unselect(state);\n else cancelMove(state);\n const pos = eventPosition(e)!,\n orig = getKeyAtDomPos(pos, whitePov(state), state.dom.bounds());\n if (!orig) return;\n state.drawable.current = {\n orig,\n pos,\n brush: eventBrush(e),\n snapToValidMove: state.drawable.defaultSnapToValidMove,\n };\n\n processDraw(state);\n}\n\nexport function processDraw(state: State): void {\n requestAnimationFrame(() => {\n const cur = state.drawable.current;\n if (cur) {\n const keyAtDomPos = getKeyAtDomPos(cur.pos, whitePov(state), state.dom.bounds());\n if (!keyAtDomPos) {\n cur.snapToValidMove = false;\n }\n const mouseSq = cur.snapToValidMove\n ? getSnappedKeyAtDomPos(cur.orig, cur.pos, whitePov(state), state.dom.bounds())\n : keyAtDomPos;\n if (mouseSq !== cur.mouseSq) {\n cur.mouseSq = mouseSq;\n cur.dest = mouseSq !== cur.orig ? mouseSq : undefined;\n state.dom.redrawNow();\n }\n processDraw(state);\n }\n });\n}\n\nexport function move(state: State, e: cg.MouchEvent): void {\n if (state.drawable.current) state.drawable.current.pos = eventPosition(e)!;\n}\n\nexport function end(state: State): void {\n const cur = state.drawable.current;\n if (cur) {\n if (cur.mouseSq) addShape(state.drawable, cur);\n cancel(state);\n }\n}\n\nexport function cancel(state: State): void {\n if (state.drawable.current) {\n state.drawable.current = undefined;\n state.dom.redraw();\n }\n}\n\nexport function clear(state: State): void {\n if (state.drawable.shapes.length) {\n state.drawable.shapes = [];\n state.dom.redraw();\n onChange(state.drawable);\n }\n}\n\nfunction eventBrush(e: cg.MouchEvent): cg.BrushColor {\n const modA = (e.shiftKey || e.ctrlKey) && isRightButton(e);\n const modB = e.altKey || e.metaKey || e.getModifierState?.('AltGraph');\n return brushes[(modA ? 1 : 0) + (modB ? 2 : 0)];\n}\n\nfunction addShape(drawable: Drawable, cur: DrawCurrent): void {\n const sameShape = (s: DrawShape) => s.orig === cur.orig && s.dest === cur.dest;\n const similar = drawable.shapes.find(sameShape);\n if (similar) drawable.shapes = drawable.shapes.filter(s => !sameShape(s));\n if (!similar || similar.brush !== cur.brush)\n drawable.shapes.push({\n orig: cur.orig,\n dest: cur.dest,\n brush: cur.brush,\n });\n onChange(drawable);\n}\n\nfunction onChange(drawable: Drawable): void {\n if (drawable.onChange) drawable.onChange(drawable.shapes);\n}\n","import { State } from './state';\nimport * as board from './board';\nimport * as util from './util';\nimport { clear as drawClear } from './draw';\nimport * as cg from './types';\nimport { anim } from './anim';\n\nexport interface DragCurrent {\n orig: cg.Key; // orig key of dragging piece\n piece: cg.Piece;\n origPos: cg.NumberPair; // first event position\n pos: cg.NumberPair; // latest event position\n started: boolean; // whether the drag has started; as per the distance setting\n element: cg.PieceNode | (() => cg.PieceNode | undefined);\n newPiece?: boolean; // it it a new piece from outside the board\n force?: boolean; // can the new piece replace an existing one (editor)\n previouslySelected?: cg.Key;\n originTarget: EventTarget | null;\n keyHasChanged: boolean; // whether the drag has left the orig key\n}\n\nexport function start(s: State, e: cg.MouchEvent): void {\n if (!(s.trustAllEvents || e.isTrusted)) return; // only trust when trustAllEvents is enabled\n if (e.buttons !== undefined && e.buttons > 1) return; // only touch or left click\n if (e.touches && e.touches.length > 1) return; // support one finger touch only\n const bounds = s.dom.bounds(),\n position = util.eventPosition(e)!,\n orig = board.getKeyAtDomPos(position, board.whitePov(s), bounds);\n if (!orig) return;\n const piece = s.pieces.get(orig);\n const previouslySelected = s.selected;\n if (\n !previouslySelected &&\n s.drawable.enabled &&\n (s.drawable.eraseOnClick || !piece || piece.color !== s.turnColor)\n )\n drawClear(s);\n // Prevent touch scroll and create no corresponding mouse event, if there\n // is an intent to interact with the board.\n if (\n e.cancelable !== false &&\n (!e.touches || s.blockTouchScroll || piece || previouslySelected || pieceCloseTo(s, position))\n )\n e.preventDefault();\n else if (e.touches) return; // Handle only corresponding mouse event https://github.com/lichess-org/chessground/pull/268\n\n const hadPremove = !!s.premovable.current;\n const hadPredrop = !!s.predroppable.current;\n s.stats.ctrlKey = e.ctrlKey;\n if (s.selected && board.canMove(s, s.selected, orig)) {\n anim(state => board.selectSquare(state, orig), s);\n } else {\n board.selectSquare(s, orig);\n }\n const stillSelected = s.selected === orig;\n const element = pieceElementByKey(s, orig);\n if (piece && element && stillSelected && board.isDraggable(s, orig)) {\n s.draggable.current = {\n orig,\n piece,\n origPos: position,\n pos: position,\n started: s.draggable.autoDistance && s.stats.dragged,\n element,\n previouslySelected,\n originTarget: e.target,\n keyHasChanged: false,\n };\n element.cgDragging = true;\n element.classList.add('dragging');\n // place ghost\n const ghost = s.dom.elements.ghost;\n if (ghost) {\n ghost.className = `ghost ${piece.color} ${piece.role}`;\n util.translate(ghost, util.posToTranslate(bounds)(util.key2pos(orig), board.whitePov(s)));\n util.setVisible(ghost, true);\n }\n processDrag(s);\n } else {\n if (hadPremove) board.unsetPremove(s);\n if (hadPredrop) board.unsetPredrop(s);\n }\n s.dom.redraw();\n}\n\nfunction pieceCloseTo(s: State, pos: cg.NumberPair): boolean {\n const asWhite = board.whitePov(s),\n bounds = s.dom.bounds(),\n radiusSq = Math.pow(bounds.width / 8, 2);\n for (const key of s.pieces.keys()) {\n const center = util.computeSquareCenter(key, asWhite, bounds);\n if (util.distanceSq(center, pos) <= radiusSq) return true;\n }\n return false;\n}\n\nexport function dragNewPiece(s: State, piece: cg.Piece, e: cg.MouchEvent, force?: boolean): void {\n const key: cg.Key = 'a0';\n s.pieces.set(key, piece);\n s.dom.redraw();\n\n const position = util.eventPosition(e)!;\n\n s.draggable.current = {\n orig: key,\n piece,\n origPos: position,\n pos: position,\n started: true,\n element: () => pieceElementByKey(s, key),\n originTarget: e.target,\n newPiece: true,\n force: !!force,\n keyHasChanged: false,\n };\n processDrag(s);\n}\n\nfunction processDrag(s: State): void {\n requestAnimationFrame(() => {\n const cur = s.draggable.current;\n if (!cur) return;\n // cancel animations while dragging\n if (s.animation.current?.plan.anims.has(cur.orig)) s.animation.current = undefined;\n // if moving piece is gone, cancel\n const origPiece = s.pieces.get(cur.orig);\n if (!origPiece || !util.samePiece(origPiece, cur.piece)) cancel(s);\n else {\n if (!cur.started && util.distanceSq(cur.pos, cur.origPos) >= Math.pow(s.draggable.distance, 2))\n cur.started = true;\n if (cur.started) {\n // support lazy elements\n if (typeof cur.element === 'function') {\n const found = cur.element();\n if (!found) return;\n found.cgDragging = true;\n found.classList.add('dragging');\n cur.element = found;\n }\n\n const bounds = s.dom.bounds();\n util.translate(cur.element, [\n cur.pos[0] - bounds.left - bounds.width / 16,\n cur.pos[1] - bounds.top - bounds.height / 16,\n ]);\n\n cur.keyHasChanged = cur.keyHasChanged || cur.orig !== board.getKeyAtDomPos(cur.pos, board.whitePov(s), bounds);\n }\n }\n processDrag(s);\n });\n}\n\nexport function move(s: State, e: cg.MouchEvent): void {\n // support one finger touch only\n if (s.draggable.current && (!e.touches || e.touches.length < 2)) {\n s.draggable.current.pos = util.eventPosition(e)!;\n }\n}\n\nexport function end(s: State, e: cg.MouchEvent): void {\n const cur = s.draggable.current;\n if (!cur) return;\n // create no corresponding mouse event\n if (e.type === 'touchend' && e.cancelable !== false) e.preventDefault();\n // comparing with the origin target is an easy way to test that the end event\n // has the same touch origin\n if (e.type === 'touchend' && cur.originTarget !== e.target && !cur.newPiece) {\n s.draggable.current = undefined;\n return;\n }\n board.unsetPremove(s);\n board.unsetPredrop(s);\n // touchend has no position; so use the last touchmove position instead\n const eventPos = util.eventPosition(e) || cur.pos;\n const dest = board.getKeyAtDomPos(eventPos, board.whitePov(s), s.dom.bounds());\n if (dest && cur.started && cur.orig !== dest) {\n if (cur.newPiece) board.dropNewPiece(s, cur.orig, dest, cur.force);\n else {\n s.stats.ctrlKey = e.ctrlKey;\n if (board.userMove(s, cur.orig, dest)) s.stats.dragged = true;\n }\n } else if (cur.newPiece) {\n s.pieces.delete(cur.orig);\n } else if (s.draggable.deleteOnDropOff && !dest) {\n s.pieces.delete(cur.orig);\n board.callUserFunction(s.events.change);\n }\n if ((cur.orig === cur.previouslySelected || cur.keyHasChanged) && (cur.orig === dest || !dest))\n board.unselect(s);\n else if (!s.selectable.enabled) board.unselect(s);\n\n removeDragElements(s);\n\n s.draggable.current = undefined;\n s.dom.redraw();\n}\n\nexport function cancel(s: State): void {\n const cur = s.draggable.current;\n if (cur) {\n if (cur.newPiece) s.pieces.delete(cur.orig);\n s.draggable.current = undefined;\n board.unselect(s);\n removeDragElements(s);\n s.dom.redraw();\n }\n}\n\nfunction removeDragElements(s: State): void {\n const e = s.dom.elements;\n if (e.ghost) util.setVisible(e.ghost, false);\n}\n\nfunction pieceElementByKey(s: State, key: cg.Key): cg.PieceNode | undefined {\n let el = s.dom.elements.board.firstChild;\n while (el) {\n if ((el as cg.KeyedNode).cgKey === key && (el as cg.KeyedNode).tagName === 'PIECE')\n return el as cg.PieceNode;\n el = el.nextSibling;\n }\n return;\n}\n","import { State } from './state';\nimport { Key } from './types';\n\nexport function explosion(state: State, keys: Key[]): void {\n state.exploding = { stage: 1, keys };\n state.dom.redraw();\n setTimeout(() => {\n setStage(state, 2);\n setTimeout(() => setStage(state, undefined), 120);\n }, 120);\n}\n\nfunction setStage(state: State, stage: number | undefined): void {\n if (state.exploding) {\n if (stage) state.exploding.stage = stage;\n else state.exploding = undefined;\n state.dom.redraw();\n }\n}\n","import { State } from './state';\nimport * as board from './board';\nimport { write as fenWrite } from './fen';\nimport { Config, configure, applyAnimation } from './config';\nimport { anim, render } from './anim';\nimport { cancel as dragCancel, dragNewPiece } from './drag';\nimport { DrawShape } from './draw';\nimport { explosion } from './explosion';\nimport * as cg from './types';\n\nexport interface Api {\n // reconfigure the instance. Accepts all config options, except for viewOnly & drawable.visible.\n // board will be animated accordingly, if animations are enabled.\n set(config: Config): void;\n\n // read chessground state; write at your own risks.\n state: State;\n\n // get the position as a FEN string (only contains pieces, no flags)\n // e.g. rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR\n getFen(): cg.FEN;\n\n // change the view angle\n toggleOrientation(): void;\n\n // perform a move programmatically\n move(orig: cg.Key, dest: cg.Key): void;\n\n // add and/or remove arbitrary pieces on the board\n setPieces(pieces: cg.PiecesDiff): void;\n\n // click a square programmatically\n selectSquare(key: cg.Key | null, force?: boolean): void;\n\n // put a new piece on the board\n newPiece(piece: cg.Piece, key: cg.Key): void;\n\n // play the current premove, if any; returns true if premove was played\n playPremove(): boolean;\n\n // cancel the current premove, if any\n cancelPremove(): void;\n\n // play the current predrop, if any; returns true if premove was played\n playPredrop(validate: (drop: cg.Drop) => boolean): boolean;\n\n // cancel the current predrop, if any\n cancelPredrop(): void;\n\n // cancel the current move being made\n cancelMove(): void;\n\n // cancel current move and prevent further ones\n stop(): void;\n\n // make squares explode (atomic chess)\n explode(keys: cg.Key[]): void;\n\n // programmatically draw user shapes\n setShapes(shapes: DrawShape[]): void;\n\n // programmatically draw auto shapes\n setAutoShapes(shapes: DrawShape[]): void;\n\n // square name at this DOM position (like \"e4\")\n getKeyAtDomPos(pos: cg.NumberPair): cg.Key | undefined;\n\n // only useful when CSS changes the board width/height ratio (for 3D)\n redrawAll: cg.Redraw;\n\n // for crazyhouse and board editors\n dragNewPiece(piece: cg.Piece, event: cg.MouchEvent, force?: boolean): void;\n\n // unbinds all events\n // (important for document-wide events like scroll and mousemove)\n destroy: cg.Unbind;\n}\n\n// see API types and documentations in dts/api.d.ts\nexport function start(state: State, redrawAll: cg.Redraw): Api {\n function toggleOrientation(): void {\n board.toggleOrientation(state);\n redrawAll();\n }\n\n return {\n set(config): void {\n if (config.orientation && config.orientation !== state.orientation) toggleOrientation();\n applyAnimation(state, config);\n (config.fen ? anim : render)(state => configure(state, config), state);\n },\n\n state,\n\n getFen: () => fenWrite(state.pieces),\n\n toggleOrientation,\n\n setPieces(pieces): void {\n anim(state => board.setPieces(state, pieces), state);\n },\n\n selectSquare(key, force): void {\n if (key) anim(state => board.selectSquare(state, key, force), state);\n else if (state.selected) {\n board.unselect(state);\n state.dom.redraw();\n }\n },\n\n move(orig, dest): void {\n anim(state => board.baseMove(state, orig, dest), state);\n },\n\n newPiece(piece, key): void {\n anim(state => board.baseNewPiece(state, piece, key), state);\n },\n\n playPremove(): boolean {\n if (state.premovable.current) {\n if (anim(board.playPremove, state)) return true;\n // if the premove couldn't be played, redraw to clear it up\n state.dom.redraw();\n }\n return false;\n },\n\n playPredrop(validate): boolean {\n if (state.predroppable.current) {\n const result = board.playPredrop(state, validate);\n state.dom.redraw();\n return result;\n }\n return false;\n },\n\n cancelPremove(): void {\n render(board.unsetPremove, state);\n },\n\n cancelPredrop(): void {\n render(board.unsetPredrop, state);\n },\n\n cancelMove(): void {\n render(state => {\n board.cancelMove(state);\n dragCancel(state);\n }, state);\n },\n\n stop(): void {\n render(state => {\n board.stop(state);\n dragCancel(state);\n }, state);\n },\n\n explode(keys: cg.Key[]): void {\n explosion(state, keys);\n },\n\n setAutoShapes(shapes: DrawShape[]): void {\n render(state => (state.drawable.autoShapes = shapes), state);\n },\n\n setShapes(shapes: DrawShape[]): void {\n render(state => (state.drawable.shapes = shapes), state);\n },\n\n getKeyAtDomPos(pos): cg.Key | undefined {\n return board.getKeyAtDomPos(pos, board.whitePov(state), state.dom.bounds());\n },\n\n redrawAll,\n\n dragNewPiece(piece, event, force): void {\n dragNewPiece(state, piece, event, force);\n },\n\n destroy(): void {\n board.stop(state);\n state.dom.unbind?.();\n state.dom.destroyed = true;\n },\n };\n}\n","import * as fen from './fen';\nimport { AnimCurrent } from './anim';\nimport { DragCurrent } from './drag';\nimport { Drawable } from './draw';\nimport { timer } from './util';\nimport * as cg from './types';\n\nexport interface HeadlessState {\n pieces: cg.Pieces;\n orientation: cg.Color; // board orientation. white | black\n turnColor: cg.Color; // turn to play. white | black\n check?: cg.Key; // square currently in check \"a2\"\n lastMove?: cg.Key[]; // squares part of the last move [\"c3\"; \"c4\"]\n selected?: cg.Key; // square currently selected \"a1\"\n coordinates: boolean; // include coords attributes\n coordinatesOnSquares: boolean; // include coords attributes on every square\n ranksPosition: cg.RanksPosition; // position ranks on either side. left | right\n autoCastle: boolean; // immediately complete the castle by moving the rook after king move\n viewOnly: boolean; // don't bind events: the user will never be able to move pieces around\n disableContextMenu: boolean; // because who needs a context menu on a chessboard\n addPieceZIndex: boolean; // adds z-index values to pieces (for 3D)\n addDimensionsCssVarsTo?: HTMLElement; // add ---cg-width and ---cg-height CSS vars containing the board's dimensions to this element\n blockTouchScroll: boolean; // block scrolling via touch dragging on the board, e.g. for coordinate training\n pieceKey: boolean; // add a data-key attribute to piece elements\n trustAllEvents?: boolean; // disable checking for human only input (e.isTrusted)\n highlight: {\n lastMove: boolean; // add last-move class to squares\n check: boolean; // add check class to squares\n custom?: cg.SquareClasses; // add custom classes to custom squares\n };\n animation: {\n enabled: boolean;\n duration: number;\n current?: AnimCurrent;\n };\n movable: {\n free: boolean; // all moves are valid - board editor\n color?: cg.Color | 'both'; // color that can move. white | black | both\n dests?: cg.Dests; // valid moves. {\"a2\" [\"a3\" \"a4\"] \"b1\" [\"a3\" \"c3\"]}\n showDests: boolean; // whether to add the move-dest class on squares\n events: {\n after?: (orig: cg.Key, dest: cg.Key, metadata: cg.MoveMetadata) => void; // called after the move has been played\n afterNewPiece?: (role: cg.Role, key: cg.Key, metadata: cg.MoveMetadata) => void; // called after a new piece is dropped on the board\n };\n rookCastle: boolean; // castle by moving the king to the rook\n };\n premovable: {\n enabled: boolean; // allow premoves for color that can not move\n showDests: boolean; // whether to add the premove-dest class on squares\n castle: boolean; // whether to allow king castle premoves\n dests?: cg.Key[]; // premove destinations for the current selection\n customDests?: cg.Dests; // use custom valid premoves. {\"a2\" [\"a3\" \"a4\"] \"b1\" [\"a3\" \"c3\"]}\n current?: cg.KeyPair; // keys of the current saved premove [\"e2\" \"e4\"]\n events: {\n set?: (orig: cg.Key, dest: cg.Key, metadata?: cg.SetPremoveMetadata) => void; // called after the premove has been set\n unset?: () => void; // called after the premove has been unset\n };\n };\n predroppable: {\n enabled: boolean; // allow predrops for color that can not move\n current?: {\n // current saved predrop {role: 'knight'; key: 'e4'}\n role: cg.Role;\n key: cg.Key;\n };\n events: {\n set?: (role: cg.Role, key: cg.Key) => void; // called after the predrop has been set\n unset?: () => void; // called after the predrop has been unset\n };\n };\n draggable: {\n enabled: boolean; // allow moves & premoves to use drag'n drop\n distance: number; // minimum distance to initiate a drag; in pixels\n autoDistance: boolean; // lets chessground set distance to zero when user drags pieces\n showGhost: boolean; // show ghost of piece being dragged\n deleteOnDropOff: boolean; // delete a piece when it is dropped off the board\n current?: DragCurrent;\n };\n dropmode: {\n active: boolean;\n piece?: cg.Piece;\n };\n selectable: {\n // disable to enforce dragging over click-click move\n enabled: boolean;\n };\n stats: {\n // was last piece dragged or clicked?\n // needs default to false for touch\n dragged: boolean;\n ctrlKey?: boolean;\n };\n events: {\n change?: () => void; // called after the situation changes on the board\n // called after a piece has been moved.\n // capturedPiece is undefined or like {color: 'cg-white'; 'role': 'queen'}\n move?: (orig: cg.Key, dest: cg.Key, capturedPiece?: cg.Piece) => void;\n dropNewPiece?: (piece: cg.Piece, key: cg.Key) => void;\n select?: (key: cg.Key) => void; // called when a square is selected\n insert?: (elements: cg.Elements) => void; // when the board DOM has been (re)inserted\n };\n drawable: Drawable;\n exploding?: cg.Exploding;\n hold: cg.Timer;\n}\n\nexport interface State extends HeadlessState {\n dom: cg.Dom;\n}\n\nexport function defaults(): HeadlessState {\n return {\n pieces: fen.read(fen.initial),\n orientation: 'cg-white',\n turnColor: 'cg-white',\n coordinates: true,\n coordinatesOnSquares: false,\n ranksPosition: 'right',\n autoCastle: true,\n viewOnly: false,\n disableContextMenu: false,\n addPieceZIndex: false,\n blockTouchScroll: false,\n pieceKey: false,\n trustAllEvents: false,\n highlight: {\n lastMove: true,\n check: true,\n },\n animation: {\n enabled: true,\n duration: 200,\n },\n movable: {\n free: true,\n color: 'both',\n showDests: true,\n events: {},\n rookCastle: true,\n },\n premovable: {\n enabled: true,\n showDests: true,\n castle: true,\n events: {},\n },\n predroppable: {\n enabled: false,\n events: {},\n },\n draggable: {\n enabled: true,\n distance: 3,\n autoDistance: true,\n showGhost: true,\n deleteOnDropOff: false,\n },\n dropmode: {\n active: false,\n },\n selectable: {\n enabled: true,\n },\n stats: {\n // on touchscreen, default to \"tap-tap\" moves\n // instead of drag\n dragged: !('ontouchstart' in window),\n },\n events: {},\n drawable: {\n enabled: true, // can draw\n visible: true, // can view\n defaultSnapToValidMove: true,\n eraseOnClick: true,\n shapes: [],\n autoShapes: [],\n brushes: {\n green: { key: 'g', color: '#15781B', opacity: 1, lineWidth: 10 },\n red: { key: 'r', color: '#882020', opacity: 1, lineWidth: 10 },\n blue: { key: 'b', color: '#003088', opacity: 1, lineWidth: 10 },\n yellow: { key: 'y', color: '#e68f00', opacity: 1, lineWidth: 10 },\n paleBlue: { key: 'pb', color: '#003088', opacity: 0.4, lineWidth: 15 },\n paleGreen: { key: 'pg', color: '#15781B', opacity: 0.4, lineWidth: 15 },\n paleRed: { key: 'pr', color: '#882020', opacity: 0.4, lineWidth: 15 },\n paleGrey: {\n key: 'pgr',\n color: '#4a4a4a',\n opacity: 0.35,\n lineWidth: 15,\n },\n purple: { key: 'purple', color: '#68217a', opacity: 0.65, lineWidth: 10 },\n pink: { key: 'pink', color: '#ee2080', opacity: 0.5, lineWidth: 10 },\n white: { key: 'white', color: 'white', opacity: 1, lineWidth: 10 },\n },\n prevSvgHash: '',\n },\n hold: timer(),\n };\n}\n","import { State } from './state';\nimport { key2pos } from './util';\nimport { Drawable, DrawShape, DrawShapePiece, DrawBrush, DrawBrushes, DrawModifiers } from './draw';\nimport { SyncableShape, Hash } from './sync';\nimport * as cg from './types';\n\ntype CustomBrushes = Map<string, DrawBrush>; // by hash\ntype Svg = { el: SVGElement; isCustom?: boolean };\ntype AngleSlots = Set<number>; // arrow angle slots for label positioning\ntype ArrowDests = Map<cg.Key | undefined, AngleSlots>; // angle slots per dest\n\nconst hilites: { [name: string]: DrawBrush } = {\n hilitePrimary: { key: 'hilitePrimary', color: '#3291ff', opacity: 1, lineWidth: 1 },\n hiliteWhite: { key: 'hiliteWhite', color: '#ffffff', opacity: 1, lineWidth: 1 },\n};\n\nexport { createElement, setAttributes };\n\nexport function createDefs(): Element {\n const defs = createElement('defs');\n const filter = setAttributes(createElement('filter'), { id: 'cg-filter-blur' });\n filter.appendChild(setAttributes(createElement('feGaussianBlur'), { stdDeviation: '0.019' }));\n defs.appendChild(filter);\n return defs;\n}\n\nexport function renderSvg(state: State, shapesEl: SVGElement, customsEl: SVGElement): void {\n const d = state.drawable,\n curD = d.current,\n cur = curD && curD.mouseSq ? (curD as DrawShape) : undefined,\n dests: ArrowDests = new Map(),\n bounds = state.dom.bounds(),\n nonPieceAutoShapes = d.autoShapes.filter(autoShape => !autoShape.piece);\n\n for (const s of d.shapes.concat(nonPieceAutoShapes).concat(cur ? [cur] : [])) {\n if (!s.dest) continue;\n const sources = dests.get(s.dest) ?? new Set(),\n from = pos2user(orient(key2pos(s.orig), state.orientation), bounds),\n to = pos2user(orient(key2pos(s.dest), state.orientation), bounds);\n sources.add(moveAngle(from, to));\n dests.set(s.dest, sources);\n }\n const shapes: SyncableShape[] = d.shapes.concat(nonPieceAutoShapes).map((s: DrawShape) => {\n return {\n shape: s,\n current: false,\n hash: shapeHash(s, isShort(s.dest, dests), false, bounds),\n };\n });\n if (cur)\n shapes.push({\n shape: cur,\n current: true,\n hash: shapeHash(cur, isShort(cur.dest, dests), true, bounds),\n });\n\n const fullHash = shapes.map(sc => sc.hash).join(';');\n if (fullHash === state.drawable.prevSvgHash) return;\n state.drawable.prevSvgHash = fullHash;\n\n /*\n -- DOM hierarchy --\n <svg class=\"cg-shapes\"> (<= svg)\n <defs>\n ...(for brushes)...\n </defs>\n <g>\n ...(for arrows and circles)...\n </g>\n </svg>\n <svg class=\"cg-custom-svgs\"> (<= customSvg)\n <g>\n ...(for custom svgs)...\n </g>\n </svg>\n */\n\n const defsEl = shapesEl.querySelector('defs') as SVGElement;\n\n syncDefs(d, shapes, defsEl);\n syncShapes(shapes, shapesEl.querySelector('g')!, customsEl.querySelector('g')!, s =>\n renderShape(state, s, d.brushes, dests, bounds),\n );\n}\n\n// append only. Don't try to update/remove.\nfunction syncDefs(d: Drawable, shapes: SyncableShape[], defsEl: SVGElement) {\n const brushes: CustomBrushes = new Map();\n let brush: DrawBrush;\n for (const s of shapes.filter(s => s.shape.dest && s.shape.brush)) {\n brush = makeCustomBrush(d.brushes[s.shape.brush!], s.shape.modifiers);\n if (s.shape.modifiers?.hilite) brushes.set(hilite(brush).key, hilite(brush));\n brushes.set(brush.key, brush);\n }\n const keysInDom = new Set();\n let el: SVGElement | undefined = defsEl.firstElementChild as SVGElement;\n while (el) {\n keysInDom.add(el.getAttribute('cgKey'));\n el = el.nextElementSibling as SVGElement | undefined;\n }\n for (const [key, brush] of brushes.entries()) {\n if (!keysInDom.has(key)) defsEl.appendChild(renderMarker(brush));\n }\n}\n\nfunction syncShapes(\n syncables: SyncableShape[],\n shapes: Element,\n customs: Element,\n renderShape: (shape: SyncableShape) => Svg[],\n): void {\n const hashesInDom = new Map();\n\n for (const sc of syncables) hashesInDom.set(sc.hash, false);\n for (const root of [shapes, customs]) {\n const toRemove: SVGElement[] = [];\n let el: SVGElement | undefined = root.firstElementChild as SVGElement,\n elHash: Hash | null;\n while (el) {\n elHash = el.getAttribute('cgHash') as Hash;\n if (hashesInDom.has(elHash)) hashesInDom.set(elHash, true);\n else toRemove.push(el);\n el = el.nextElementSibling as SVGElement | undefined;\n }\n for (const el of toRemove) root.removeChild(el);\n }\n // insert shapes that are not yet in dom\n for (const sc of syncables.filter(s => !hashesInDom.get(s.hash))) {\n for (const svg of renderShape(sc)) {\n if (svg.isCustom) customs.appendChild(svg.el);\n else shapes.appendChild(svg.el);\n }\n }\n}\n\nfunction shapeHash(\n { orig, dest, brush, piece, modifiers, customSvg, label }: DrawShape,\n shorten: boolean,\n current: boolean,\n bounds: DOMRectReadOnly,\n): Hash {\n // a shape and an overlay svg share a lifetime and have the same cgHash attribute\n return [\n bounds.width,\n bounds.height,\n current,\n orig,\n dest,\n brush,\n shorten && '-',\n piece && pieceHash(piece),\n modifiers && modifiersHash(modifiers),\n customSvg && `custom-${textHash(customSvg.html)},${customSvg.center?.[0] ?? 'o'}`,\n label && `label-${textHash(label.text)}`,\n ]\n .filter(x => x)\n .join(',');\n}\n\nfunction pieceHash(piece: DrawShapePiece): Hash {\n return [piece.color, piece.role, piece.scale].filter(x => x).join(',');\n}\n\nfunction modifiersHash(m: DrawModifiers): Hash {\n return [m.lineWidth, m.hilite && '*'].filter(x => x).join(',');\n}\n\nfunction textHash(s: string): Hash {\n // Rolling hash with base 31 (cf. https://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript)\n let h = 0;\n for (let i = 0; i < s.length; i++) {\n h = ((h << 5) - h + s.charCodeAt(i)) >>> 0;\n }\n return h.toString();\n}\n\nfunction renderShape(\n state: State,\n { shape, current, hash }: SyncableShape,\n brushes: DrawBrushes,\n dests: ArrowDests,\n bounds: DOMRectReadOnly,\n): Svg[] {\n const from = pos2user(orient(key2pos(shape.orig), state.orientation), bounds),\n to = shape.dest ? pos2user(orient(key2pos(shape.dest), state.orientation), bounds) : from,\n brush = shape.brush && makeCustomBrush(brushes[shape.brush], shape.modifiers),\n slots = dests.get(shape.dest),\n svgs: Svg[] = [];\n\n if (brush) {\n const el = setAttributes(createElement('g'), { cgHash: hash });\n svgs.push({ el });\n\n if (from[0] !== to[0] || from[1] !== to[1])\n el.appendChild(renderArrow(shape, brush, from, to, current, isShort(shape.dest, dests)));\n else el.appendChild(renderCircle(brushes[shape.brush!], from, current, bounds));\n }\n if (shape.label) {\n const label = shape.label;\n if (!label.fill) {\n if (shape.brush && brushes[shape.brush]) {\n label.fill = brushes[shape.brush].color;\n }\n }\n const corner = shape.brush ? undefined : 'tr';\n svgs.push({ el: renderLabel(label, hash, from, to, slots, corner), isCustom: true });\n }\n if (shape.customSvg) {\n const on = shape.customSvg.center ?? 'orig';\n const [x, y] =\n on === 'label' ? labelCoords(from, to, slots).map(c => c - 0.5) : on === 'dest' ? to : from;\n const el = setAttributes(createElement('g'), { transform: `translate(${x},${y})`, cgHash: hash });\n el.innerHTML = `<svg width=\"1\" height=\"1\" viewBox=\"0 0 100 100\">${shape.customSvg.html}</svg>`;\n svgs.push({ el, isCustom: true });\n }\n return svgs;\n}\n\nfunction renderCircle(\n brush: DrawBrush,\n at: cg.NumberPair,\n current: boolean,\n bounds: DOMRectReadOnly,\n): SVGElement {\n const widths = circleWidth(),\n radius = (bounds.width + bounds.height) / (4 * Math.max(bounds.width, bounds.height));\n return setAttributes(createElement('circle'), {\n stroke: brush.color,\n 'stroke-width': widths[current ? 0 : 1],\n fill: 'none',\n opacity: opacity(brush, current),\n cx: at[0],\n cy: at[1],\n r: radius - widths[1] / 2,\n });\n}\n\nfunction hilite(brush: DrawBrush): DrawBrush {\n return ['#ffffff', '#fff', 'white'].includes(brush.color)\n ? hilites['hilitePrimary']\n : hilites['hiliteWhite'];\n}\n\nfunction renderArrow(\n s: DrawShape,\n brush: DrawBrush,\n from: cg.NumberPair,\n to: cg.NumberPair,\n current: boolean,\n shorten: boolean,\n): SVGElement {\n function renderLine(isHilite: boolean) {\n const m = arrowMargin(shorten && !current),\n dx = to[0] - from[0],\n dy = to[1] - from[1],\n angle = Math.atan2(dy, dx),\n xo = Math.cos(angle) * m,\n yo = Math.sin(angle) * m;\n return setAttributes(createElement('line'), {\n stroke: isHilite ? hilite(brush).color : brush.color,\n 'stroke-width': lineWidth(brush, current) + (isHilite ? 0.04 : 0),\n 'stroke-linecap': 'round',\n 'marker-end': `url(#arrowhead-${isHilite ? hilite(brush).key : brush.key})`,\n opacity: s.modifiers?.hilite ? 1 : opacity(brush, current),\n x1: from[0],\n y1: from[1],\n x2: to[0] - xo,\n y2: to[1] - yo,\n });\n }\n if (!s.modifiers?.hilite) return renderLine(false);\n\n const g = createElement('g');\n const blurred = setAttributes(createElement('g'), { filter: 'url(#cg-filter-blur)' });\n blurred.appendChild(filterBox(from, to));\n blurred.appendChild(renderLine(true));\n g.appendChild(blurred);\n g.appendChild(renderLine(false));\n return g;\n}\n\nfunction renderMarker(brush: DrawBrush): SVGElement {\n const marker = setAttributes(createElement('marker'), {\n id: 'arrowhead-' + brush.key,\n orient: 'auto',\n overflow: 'visible',\n markerWidth: 4,\n markerHeight: 4,\n refX: brush.key.startsWith('hilite') ? 1.86 : 2.05,\n refY: 2,\n });\n marker.appendChild(\n setAttributes(createElement('path'), {\n d: 'M0,0 V4 L3,2 Z',\n fill: brush.color,\n }),\n );\n marker.setAttribute('cgKey', brush.key);\n return marker;\n}\n\nfunction renderLabel(\n label: { text: string; fill?: string },\n hash: string,\n from: cg.NumberPair,\n to: cg.NumberPair,\n slots?: AngleSlots,\n corner?: 'tr',\n): SVGElement {\n const labelSize = 0.4,\n fontSize = labelSize * 0.75 ** label.text.length,\n at = labelCoords(from, to, slots),\n cornerOff = corner === 'tr' ? 0.4 : 0,\n g = setAttributes(createElement('g'), {\n transform: `translate(${at[0] + cornerOff},${at[1] - cornerOff})`,\n cgHash: hash,\n });\n g.appendChild(\n setAttributes(createElement('circle'), {\n r: labelSize / 2,\n 'fill-opacity': corner ? 1.0 : 0.8,\n 'stroke-opacity': corner ? 1.0 : 0.7,\n 'stroke-width': 0.03,\n fill: label.fill ?? '#666',\n stroke: 'white',\n }),\n );\n const labelEl = setAttributes(createElement('text'), {\n 'font-size': fontSize,\n 'font-family': 'Noto Sans',\n 'text-anchor': 'middle',\n fill: 'white',\n y: 0.13 * 0.75 ** label.text.length,\n });\n labelEl.innerHTML = label.text;\n g.appendChild(labelEl);\n return g;\n}\n\nfunction orient(pos: cg.Pos, color: cg.Color): cg.Pos {\n return color === 'cg-white' ? pos : [7 - pos[0], 7 - pos[1]];\n}\n\nfunction isShort(dest: cg.Key | undefined, dests: ArrowDests) {\n return true === (dest && dests.has(dest) && dests.get(dest)!.size > 1);\n}\n\nfunction createElement(tagName: string): SVGElement {\n return document.createElementNS('http://www.w3.org/2000/svg', tagName);\n}\n\nfunction setAttributes(el: SVGElement, attrs: { [key: string]: any }): SVGElement {\n for (const key in attrs) {\n if (Object.prototype.hasOwnProperty.call(attrs, key)) el.setAttribute(key, attrs[key]);\n }\n return el;\n}\n\nfunction makeCustomBrush(base: DrawBrush, modifiers: DrawModifiers | undefined): DrawBrush {\n return !modifiers\n ? base\n : {\n color: base.color,\n opacity: Math.round(base.opacity * 10) / 10,\n lineWidth: Math.round(modifiers.lineWidth || base.lineWidth),\n key: [base.key, modifiers.lineWidth].filter(x => x).join(''),\n };\n}\n\nfunction circleWidth(): [number, number] {\n return [3 / 64, 4 / 64];\n}\n\nfunction lineWidth(brush: DrawBrush, current: boolean): number {\n return ((brush.lineWidth || 10) * (current ? 0.85 : 1)) / 64;\n}\n\nfunction opacity(brush: DrawBrush, current: boolean): number {\n return (brush.opacity || 1) * (current ? 0.9 : 1);\n}\n\nfunction arrowMargin(shorten: boolean): number {\n return (shorten ? 20 : 10) / 64;\n}\n\nfunction pos2user(pos: cg.Pos, bounds: DOMRectReadOnly): cg.NumberPair {\n const xScale = Math.min(1, bounds.width / bounds.height);\n const yScale = Math.min(1, bounds.height / bounds.width);\n return [(pos[0] - 3.5) * xScale, (3.5 - pos[1]) * yScale];\n}\n\nfunction filterBox(from: cg.NumberPair, to: cg.NumberPair): SVGElement {\n // lines/arrows are considered to be one dimensional for the purposes of SVG filters,\n // so we add a transparent bounding box to ensure they apply to the 2nd dimension\n const box = {\n from: [Math.floor(Math.min(from[0], to[0])), Math.floor(Math.min(from[1], to[1]))],\n to: [Math.ceil(Math.max(from[0], to[0])), Math.ceil(Math.max(from[1], to[1]))],\n };\n return setAttributes(createElement('rect'), {\n x: box.from[0],\n y: box.from[1],\n width: box.to[0] - box.from[0],\n height: box.to[1] - box.from[1],\n fill: 'none',\n stroke: 'none',\n });\n}\n\nfunction moveAngle(from: cg.NumberPair, to: cg.NumberPair, asSlot = true) {\n const angle = Math.atan2(to[1] - from[1], to[0] - from[0]) + Math.PI;\n return asSlot ? (Math.round((angle * 8) / Math.PI) + 16) % 16 : angle;\n}\n\nfunction dist(from: cg.NumberPair, to: cg.NumberPair): number {\n return Math.sqrt([from[0] - to[0], from[1] - to[1]].reduce((acc, x) => acc + x * x, 0));\n}\n\n/*\n try to place label at the junction of the destination shaft and arrowhead. if there's more than\n 1 arrow pointing to a square, the arrow shortens by 10 / 64 units so the label must move as well. \n \n if the angle between two incoming arrows is pi / 8, such as when an adjacent knight and bishop\n attack the same square, the knight's label is slid further down the shaft by an amount equal to\n our label size to avoid collision\n*/\n\nfunction labelCoords(from: cg.NumberPair, to: cg.NumberPair, slots?: AngleSlots): cg.NumberPair {\n let mag = dist(from, to);\n //if (mag === 0) return [from[0], from[1]];\n const angle = moveAngle(from, to, false);\n if (slots) {\n mag -= 33 / 64; // reduce by arrowhead length\n if (slots.size > 1) {\n mag -= 10 / 64; // reduce by shortening factor\n const slot = moveAngle(from, to);\n if (slots.has((slot + 1) % 16) || slots.has((slot + 15) % 16)) {\n if (slot & 1) mag -= 0.4;\n // and by label size for the knight if another arrow is within pi / 8.\n }\n }\n }\n return [from[0] - Math.cos(angle) * mag, from[1] - Math.sin(angle) * mag].map(\n c => c + 0.5,\n ) as cg.NumberPair;\n}\n","import { HeadlessState } from './state';\nimport { setVisible, createEl } from './util';\nimport { colors, files, ranks, Elements } from './types';\nimport { createElement as createSVG, setAttributes, createDefs } from './svg';\n\nexport function renderWrap(element: HTMLElement, s: HeadlessState): Elements {\n // .cg-wrap (element passed to Chessground)\n // cg-container\n // cg-board\n // svg.cg-shapes\n // defs\n // g\n // svg.cg-custom-svgs\n // g\n // cg-auto-pieces\n // coords.ranks\n // coords.files\n // piece.ghost\n\n element.innerHTML = '';\n\n // ensure the cg-wrap class is set\n // so bounds calculation can use the CSS width/height values\n // add that class yourself to the element before calling chessground\n // for a slight performance improvement! (avoids recomputing style)\n element.classList.add('cg-wrap');\n\n for (const c of colors) element.classList.toggle('orientation-' + c, s.orientation === c);\n element.classList.toggle('manipulable', !s.viewOnly);\n\n const container = createEl('cg-container');\n element.appendChild(container);\n\n const board = createEl('cg-board');\n container.appendChild(board);\n\n let svg: SVGElement | undefined;\n let customSvg: SVGElement | undefined;\n let autoPieces: HTMLElement | undefined;\n\n if (s.drawable.visible) {\n svg = setAttributes(createSVG('svg'), {\n class: 'cg-shapes',\n viewBox: '-4 -4 8 8',\n preserveAspectRatio: 'xMidYMid slice',\n });\n svg.appendChild(createDefs());\n svg.appendChild(createSVG('g'));\n\n customSvg = setAttributes(createSVG('svg'), {\n class: 'cg-custom-svgs',\n viewBox: '-3.5 -3.5 8 8',\n preserveAspectRatio: 'xMidYMid slice',\n });\n customSvg.appendChild(createSVG('g'));\n\n autoPieces = createEl('cg-auto-pieces');\n\n container.appendChild(svg);\n container.appendChild(customSvg);\n container.appendChild(autoPieces);\n }\n\n if (s.coordinates) {\n const orientClass = s.orientation === 'cg-black' ? ' black' : '';\n const ranksPositionClass = s.ranksPosition === 'left' ? ' left' : '';\n\n if (s.coordinatesOnSquares) {\n const rankN: (i: number) => number = s.orientation === 'cg-white' ? i => i + 1 : i => 8 - i;\n files.forEach((f, i) =>\n container.appendChild(\n renderCoords(\n ranks.map(r => f + r),\n 'squares rank' + rankN(i) + orientClass + ranksPositionClass,\n ),\n ),\n );\n } else {\n container.appendChild(renderCoords(ranks, 'ranks' + orientClass + ranksPositionClass));\n container.appendChild(renderCoords(files, 'files' + orientClass));\n }\n }\n\n let ghost: HTMLElement | undefined;\n if (s.draggable.enabled && s.draggable.showGhost) {\n ghost = createEl('piece', 'ghost');\n setVisible(ghost, false);\n container.appendChild(ghost);\n }\n\n return {\n board,\n container,\n wrap: element,\n ghost,\n svg,\n customSvg,\n autoPieces,\n };\n}\n\nfunction renderCoords(elems: readonly string[], className: string): HTMLElement {\n const el = createEl('coords', className);\n let f: HTMLElement;\n for (const elem of elems) {\n f = createEl('coord');\n f.textContent = elem;\n el.appendChild(f);\n }\n return el;\n}\n","import { State } from './state';\nimport * as cg from './types';\nimport * as board from './board';\nimport * as util from './util';\nimport { cancel as dragCancel } from './drag';\n\nexport function setDropMode(s: State, piece?: cg.Piece): void {\n s.dropmode = {\n active: true,\n piece,\n };\n dragCancel(s);\n}\n\nexport function cancelDropMode(s: State): void {\n s.dropmode = {\n active: false,\n };\n}\n\nexport function drop(s: State, e: cg.MouchEvent): void {\n if (!s.dropmode.active) return;\n\n board.unsetPremove(s);\n board.unsetPredrop(s);\n\n const piece = s.dropmode.piece;\n\n if (piece) {\n s.pieces.set('a0', piece);\n const position = util.eventPosition(e);\n const dest = position && board.getKeyAtDomPos(position, board.whitePov(s), s.dom.bounds());\n if (dest) board.dropNewPiece(s, 'a0', dest);\n }\n s.dom.redraw();\n}\n","import { State } from './state';\nimport * as drag from './drag';\nimport * as draw from './draw';\nimport { drop } from './drop';\nimport { isRightButton } from './util';\nimport * as cg from './types';\n\ntype MouchBind = (e: cg.MouchEvent) => void;\ntype StateMouchBind = (d: State, e: cg.MouchEvent) => void;\n\nexport function bindBoard(s: State): void {\n const boardEl = s.dom.elements.board;\n\n // if ('ResizeObserver' in window) new ResizeObserver(onResize).observe(s.dom.elements.wrap);\n\n if (s.disableContextMenu || s.drawable.enabled) {\n boardEl.addEventListener('contextmenu', (e) => e.preventDefault());\n }\n\n if (s.viewOnly) return;\n\n // Cannot be passive, because we prevent touch scrolling and dragging of\n // selected elements.\n const onStart = startDragOrDraw(s);\n boardEl.addEventListener('touchstart', onStart as EventListener, {\n passive: false,\n });\n boardEl.addEventListener('mousedown', onStart as EventListener, {\n passive: false,\n });\n}\n\n// returns the unbind function\nexport function bindDocument(s: State, onResize: () => void): cg.Unbind {\n const unbinds: cg.Unbind[] = [];\n\n // Old versions of Edge and Safari do not support ResizeObserver. Send\n // chessground.resize if a user action has changed the bounds of the board.\n if (!('ResizeObserver' in window))\n unbinds.push(unbindable(document.body, 'chessground.resize', onResize));\n\n if (!s.viewOnly) {\n const onmove = dragOrDraw(s, drag.move, draw.move);\n const onend = dragOrDraw(s, drag.end, draw.end);\n\n for (const ev of ['touchmove', 'mousemove'])\n unbinds.push(unbindable(document, ev, onmove as EventListener));\n for (const ev of ['touchend', 'mouseup'])\n unbinds.push(unbindable(document, ev, onend as EventListener));\n\n const onScroll = () => s.dom.bounds.clear();\n unbinds.push(unbindable(document, 'scroll', onScroll, { capture: true, passive: true }));\n unbinds.push(unbindable(window, 'resize', onScroll, { passive: true }));\n }\n\n return () => unbinds.forEach((f) => f());\n}\n\nfunction unbindable(\n el: EventTarget,\n eventName: string,\n callback: EventListener,\n options?: AddEventListenerOptions\n): cg.Unbind {\n el.addEventListener(eventName, callback, options);\n return () => el.removeEventListener(eventName, callback, options);\n}\n\nconst startDragOrDraw =\n (s: State): MouchBind =>\n (e) => {\n if (s.draggable.current) drag.cancel(s);\n else if (s.drawable.current) draw.cancel(s);\n else if (e.shiftKey || isRightButton(e)) {\n if (s.drawable.enabled) draw.start(s, e);\n } else if (!s.viewOnly) {\n if (s.dropmode.active) drop(s, e);\n else drag.start(s, e);\n }\n };\n\nconst dragOrDraw =\n (s: State, withDrag: StateMouchBind, withDraw: StateMouchBind): MouchBind =>\n (e) => {\n if (s.drawable.current) {\n if (s.drawable.enabled) withDraw(s, e);\n } else if (!s.viewOnly) withDrag(s, e);\n };\n","import { State } from './state';\nimport { key2pos, createEl, posToTranslate as posToTranslateFromBounds, translate } from './util';\nimport { whitePov } from './board';\nimport { AnimCurrent, AnimVectors, AnimVector, AnimFadings } from './anim';\nimport { DragCurrent } from './drag';\nimport * as cg from './types';\n\ntype PieceName = string; // `$color $role`\n\n// ported from https://github.com/lichess-org/lichobile/blob/master/src/chessground/render.ts\n// in case of bugs, blame @veloce\nexport function render(s: State): void {\n const asWhite: boolean = whitePov(s),\n posToTranslate = posToTranslateFromBounds(s.dom.bounds()),\n boardEl: HTMLElement = s.dom.elements.board,\n pieces: cg.Pieces = s.pieces,\n curAnim: AnimCurrent | undefined = s.animation.current,\n anims: AnimVectors = curAnim ? curAnim.plan.anims : new Map(),\n fadings: AnimFadings = curAnim ? curAnim.plan.fadings : new Map(),\n curDrag: DragCurrent | undefined = s.draggable.current,\n squares: cg.SquareClasses = computeSquareClasses(s),\n samePieces: Set<cg.Key> = new Set(),\n sameSquares: Set<cg.Key> = new Set(),\n movedPieces: Map<PieceName, cg.PieceNode[]> = new Map(),\n movedSquares: Map<string, cg.SquareNode[]> = new Map(); // by class name\n let k: cg.Key,\n el: cg.PieceNode | cg.SquareNode | undefined,\n pieceAtKey: cg.Piece | undefined,\n elPieceName: PieceName,\n anim: AnimVector | undefined,\n fading: cg.Piece | undefined,\n pMvdset: cg.PieceNode[] | undefined,\n pMvd: cg.PieceNode | undefined,\n sMvdset: cg.SquareNode[] | undefined,\n sMvd: cg.SquareNode | undefined;\n\n // walk over all board dom elements, apply animations and flag moved pieces\n el = boardEl.firstChild as cg.PieceNode | cg.SquareNode | undefined;\n while (el) {\n k = el.cgKey;\n if (isPieceNode(el)) {\n pieceAtKey = pieces.get(k);\n anim = anims.get(k);\n fading = fadings.get(k);\n elPieceName = el.cgPiece;\n // if piece not being dragged anymore, remove dragging style\n if (el.cgDragging && (!curDrag || curDrag.orig !== k)) {\n el.classList.remove('dragging');\n translate(el, posToTranslate(key2pos(k), asWhite));\n el.cgDragging = false;\n }\n // remove fading class if it still remains\n if (!fading && el.cgFading) {\n el.cgFading = false;\n el.classList.remove('fading');\n }\n // there is now a piece at this dom key\n if (pieceAtKey) {\n // continue animation if already animating and same piece\n // (otherwise it could animate a captured piece)\n if (anim && el.cgAnimating && elPieceName === pieceNameOf(pieceAtKey)) {\n const pos = key2pos(k);\n pos[0] += anim[2];\n pos[1] += anim[3];\n el.classList.add('anim');\n translate(el, posToTranslate(pos, asWhite));\n } else if (el.cgAnimating) {\n el.cgAnimating = false;\n el.classList.remove('anim');\n translate(el, posToTranslate(key2pos(k), asWhite));\n if (s.addPieceZIndex) el.style.zIndex = posZIndex(key2pos(k), asWhite);\n }\n // same piece: flag as same\n if (elPieceName === pieceNameOf(pieceAtKey) && (!fading || !el.cgFading)) {\n samePieces.add(k);\n }\n // different piece: flag as moved unless it is a fading piece\n else {\n if (fading && elPieceName === pieceNameOf(fading)) {\n el.classList.add('fading');\n el.cgFading = true;\n } else {\n appendValue(movedPieces, elPieceName, el);\n }\n }\n }\n // no piece: flag as moved\n else {\n appendValue(movedPieces, elPieceName, el);\n }\n } else if (isSquareNode(el)) {\n const cn = el.className;\n if (squares.get(k) === cn) sameSquares.add(k);\n else appendValue(movedSquares, cn, el);\n }\n el = el.nextSibling as cg.PieceNode | cg.SquareNode | undefined;\n }\n\n // walk over all squares in current set, apply dom changes to moved squares\n // or append new squares\n for (const [sk, className] of squares) {\n if (!sameSquares.has(sk)) {\n sMvdset = movedSquares.get(className);\n sMvd = sMvdset && sMvdset.pop();\n const translation = posToTranslate(key2pos(sk), asWhite);\n if (sMvd) {\n sMvd.cgKey = sk;\n translate(sMvd, translation);\n } else {\n const squareNode = createEl('square', className) as cg.SquareNode;\n squareNode.cgKey = sk;\n translate(squareNode, translation);\n boardEl.insertBefore(squareNode, boardEl.firstChild);\n }\n }\n }\n\n // walk over all pieces in current set, apply dom changes to moved pieces\n // or append new pieces\n for (const [k, p] of pieces) {\n anim = anims.get(k);\n if (!samePieces.has(k)) {\n pMvdset = movedPieces.get(pieceNameOf(p));\n pMvd = pMvdset && pMvdset.pop();\n // a same piece was moved\n if (pMvd) {\n // apply dom changes\n pMvd.cgKey = k;\n if (pMvd.cgFading) {\n pMvd.classList.remove('fading');\n pMvd.cgFading = false;\n }\n const pos = key2pos(k);\n if (s.addPieceZIndex) pMvd.style.zIndex = posZIndex(pos, asWhite);\n if (anim) {\n pMvd.cgAnimating = true;\n pMvd.classList.add('anim');\n pos[0] += anim[2];\n pos[1] += anim[3];\n }\n translate(pMvd, posToTranslate(pos, asWhite));\n }\n // no piece in moved obj: insert the new piece\n // assumes the new piece is not being dragged\n else {\n const pieceName = pieceNameOf(p),\n pieceNode = createEl('piece', pieceName) as cg.PieceNode,\n pos = key2pos(k);\n\n pieceNode.cgPiece = pieceName;\n pieceNode.cgKey = k;\n if (anim) {\n pieceNode.cgAnimating = true;\n pos[0] += anim[2];\n pos[1] += anim[3];\n }\n translate(pieceNode, posToTranslate(pos, asWhite));\n\n if (s.addPieceZIndex) pieceNode.style.zIndex = posZIndex(pos, asWhite);\n\n boardEl.appendChild(pieceNode);\n }\n }\n }\n\n // remove any element that remains in the moved sets\n for (const nodes of movedPieces.values()) removeNodes(s, nodes);\n for (const nodes of movedSquares.values()) removeNodes(s, nodes);\n}\n\nexport function renderResized(s: State): void {\n const asWhite: boolean = whitePov(s),\n posToTranslate = posToTranslateFromBounds(s.dom.bounds());\n let el = s.dom.elements.board.firstChild as cg.PieceNode | cg.SquareNode | undefined;\n while (el) {\n if ((isPieceNode(el) && !el.cgAnimating) || isSquareNode(el)) {\n translate(el, posToTranslate(key2pos(el.cgKey), asWhite));\n }\n el = el.nextSibling as cg.PieceNode | cg.SquareNode | undefined;\n }\n}\n\nexport function updateBounds(s: State): void {\n const bounds = s.dom.elements.wrap.getBoundingClientRect();\n const container = s.dom.elements.container;\n const ratio = bounds.height / bounds.width;\n const width = (Math.floor((bounds.width * window.devicePixelRatio) / 8) * 8) / window.devicePixelRatio;\n const height = width * ratio;\n container.style.width = width + 'px';\n container.style.height = height + 'px';\n s.dom.bounds.clear();\n\n s.addDimensionsCssVarsTo?.style.setProperty('---cg-width', width + 'px');\n s.addDimensionsCssVarsTo?.style.setProperty('---cg-height', height + 'px');\n}\n\nconst isPieceNode = (el: cg.PieceNode | cg.SquareNode): el is cg.PieceNode => el.tagName === 'PIECE';\nconst isSquareNode = (el: cg.PieceNode | cg.SquareNode): el is cg.SquareNode => el.tagName === 'SQUARE';\n\nfunction removeNodes(s: State, nodes: HTMLElement[]): void {\n for (const node of nodes) s.dom.elements.board.removeChild(node);\n}\n\nfunction posZIndex(pos: cg.Pos, asWhite: boolean): string {\n const minZ = 3;\n const rank = pos[1];\n const z = asWhite ? minZ + 7 - rank : minZ + rank;\n\n return `${z}`;\n}\n\nconst pieceNameOf = (piece: cg.Piece): string => `${piece.color} ${piece.role}`;\n\nfunction computeSquareClasses(s: State): cg.SquareClasses {\n const squares: cg.SquareClasses = new Map();\n if (s.lastMove && s.highlight.lastMove)\n for (const k of s.lastMove) {\n addSquare(squares, k, 'last-move');\n }\n if (s.check && s.highlight.check) addSquare(squares, s.check, 'check');\n if (s.selected) {\n addSquare(squares, s.selected, 'selected');\n if (s.movable.showDests) {\n const dests = s.movable.dests?.get(s.selected);\n if (dests)\n for (const k of dests) {\n addSquare(squares, k, 'move-dest' + (s.pieces.has(k) ? ' oc' : ''));\n }\n const pDests = s.premovable.customDests?.get(s.selected) ?? s.premovable.dests;\n if (pDests)\n for (const k of pDests) {\n addSquare(squares, k, 'premove-dest' + (s.pieces.has(k) ? ' oc' : ''));\n }\n }\n }\n const premove = s.premovable.current;\n if (premove) for (const k of premove) addSquare(squares, k, 'current-premove');\n else if (s.predroppable.current) addSquare(squares, s.predroppable.current.key, 'current-premove');\n\n const o = s.exploding;\n if (o) for (const k of o.keys) addSquare(squares, k, 'exploding' + o.stage);\n\n if (s.highlight.custom) {\n s.highlight.custom.forEach((v: string, k: cg.Key) => {\n addSquare(squares, k, v);\n });\n }\n\n return squares;\n}\n\nfunction addSquare(squares: cg.SquareClasses, key: cg.Key, klass: string): void {\n const classes = squares.get(key);\n if (classes) squares.set(key, `${classes} ${klass}`);\n else squares.set(key, klass);\n}\n\nfunction appendValue<K, V>(map: Map<K, V[]>, key: K, value: V): void {\n const arr = map.get(key);\n if (arr) arr.push(value);\n else map.set(key, [value]);\n}\n","import { DrawShape } from './draw';\n\nexport interface SyncableShape {\n shape: DrawShape;\n current: boolean;\n hash: Hash;\n}\n\nexport type Hash = string;\n\n// append and remove only. No updates.\nexport function syncShapes(\n shapes: SyncableShape[],\n root: HTMLElement | SVGElement,\n renderShape: (shape: SyncableShape) => HTMLElement | SVGElement,\n): void {\n const hashesInDom = new Map(), // by hash\n toRemove: SVGElement[] = [];\n for (const sc of shapes) hashesInDom.set(sc.hash, false);\n let el: SVGElement | undefined = root.firstElementChild as SVGElement,\n elHash: Hash | null;\n while (el) {\n elHash = el.getAttribute('cgHash') as Hash;\n // found a shape element that's here to stay\n if (hashesInDom.has(elHash)) hashesInDom.set(elHash, true);\n // or remove it\n else toRemove.push(el);\n el = el.nextElementSibling as SVGElement | undefined;\n }\n // remove old shapes\n for (const el of toRemove) root.removeChild(el);\n // insert shapes that are not yet in dom\n for (const sc of shapes) {\n if (!hashesInDom.get(sc.hash)) root.appendChild(renderShape(sc));\n }\n}\n","import { State } from './state';\nimport { key2pos, createEl, posToTranslate as posToTranslateFromBounds, translateAndScale } from './util';\nimport { whitePov } from './board';\nimport * as cg from './types';\nimport { DrawShape } from './draw';\nimport { SyncableShape, Hash, syncShapes } from './sync';\n\nexport function render(state: State, autoPieceEl: HTMLElement): void {\n const autoPieces = state.drawable.autoShapes.filter(autoShape => autoShape.piece);\n const autoPieceShapes: SyncableShape[] = autoPieces.map((s: DrawShape) => {\n return {\n shape: s,\n hash: hash(s),\n current: false,\n };\n });\n\n syncShapes(autoPieceShapes, autoPieceEl, shape => renderShape(state, shape, state.dom.bounds()));\n}\n\nexport function renderResized(state: State): void {\n const asWhite: boolean = whitePov(state),\n posToTranslate = posToTranslateFromBounds(state.dom.bounds());\n let el = state.dom.elements.autoPieces?.firstChild as cg.PieceNode | undefined;\n while (el) {\n translateAndScale(el, posToTranslate(key2pos(el.cgKey), asWhite), el.cgScale);\n el = el.nextSibling as cg.PieceNode | undefined;\n }\n}\n\nfunction renderShape(state: State, { shape, hash }: SyncableShape, bounds: DOMRectReadOnly): cg.PieceNode {\n const orig = shape.orig;\n const role = shape.piece?.role;\n const color = shape.piece?.color;\n const scale = shape.piece?.scale;\n\n const pieceEl = createEl('piece', `${role} ${color}`) as cg.PieceNode;\n pieceEl.setAttribute('cgHash', hash);\n pieceEl.cgKey = orig;\n pieceEl.cgScale = scale;\n translateAndScale(pieceEl, posToTranslateFromBounds(bounds)(key2pos(orig), whitePov(state)), scale);\n\n return pieceEl;\n}\n\nconst hash = (autoPiece: DrawShape): Hash =>\n [autoPiece.orig, autoPiece.piece?.role, autoPiece.piece?.color, autoPiece.piece?.scale].join(',');\n","import { Api, start } from './api';\nimport { Config, configure } from './config';\nimport { HeadlessState, State, defaults } from './state';\n\nimport { renderWrap } from './wrap';\nimport * as events from './events';\nimport { render, renderResized, updateBounds } from './render';\nimport * as autoPieces from './autoPieces';\nimport * as svg from './svg';\nimport * as util from './util';\n\nexport function initModule({ el, config }: { el: HTMLElement; config?: Config }): Api {\n return Chessground(el, config);\n}\n\nexport function Chessground(element: HTMLElement, config?: Config): Api {\n const maybeState: State | HeadlessState = defaults();\n\n configure(maybeState, config || {});\n\n function redrawAll(): State {\n const prevUnbind = 'dom' in maybeState ? maybeState.dom.unbind : undefined;\n // compute bounds from existing board element if possible\n // this allows non-square boards from CSS to be handled (for 3D)\n const elements = renderWrap(element, maybeState),\n bounds = util.memo(() => elements.board.getBoundingClientRect()),\n redrawNow = (skipSvg?: boolean): void => {\n render(state);\n if (elements.autoPieces) autoPieces.render(state, elements.autoPieces);\n if (!skipSvg && elements.svg) svg.renderSvg(state, elements.svg, elements.customSvg!);\n },\n onResize = (): void => {\n updateBounds(state);\n renderResized(state);\n if (elements.autoPieces) autoPieces.renderResized(state);\n };\n const state = maybeState as State;\n state.dom = {\n elements,\n bounds,\n redraw: debounceRedraw(redrawNow),\n redrawNow,\n unbind: prevUnbind,\n };\n state.drawable.prevSvgHash = '';\n updateBounds(state);\n redrawNow(false);\n events.bindBoard(state);\n if (!prevUnbind) state.dom.unbind = events.bindDocument(state, onResize);\n state.events.insert?.(elements);\n return state;\n }\n\n return start(redrawAll(), redrawAll);\n}\n\nfunction debounceRedraw(redrawNow: (skipSvg?: boolean) => void): () => void {\n let redrawing = false;\n return () => {\n if (redrawing) return;\n redrawing = true;\n requestAnimationFrame(() => {\n redrawNow();\n redrawing = false;\n });\n };\n}\n","/**\n * @license\n * Copyright (c) 2025, Jeff Hlywa (jhlywa@gmail.com)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n * this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the documentation\n * and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n * POSSIBILITY OF SUCH DAMAGE.\n */\nexport const WHITE = 'w';\nexport const BLACK = 'b';\nexport const PAWN = 'p';\nexport const KNIGHT = 'n';\nexport const BISHOP = 'b';\nexport const ROOK = 'r';\nexport const QUEEN = 'q';\nexport const KING = 'k';\nexport const DEFAULT_POSITION = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1';\nexport class Move {\n color;\n from;\n to;\n piece;\n captured;\n promotion;\n /**\n * @deprecated This field is deprecated and will be removed in version 2.0.0.\n * Please use move descriptor functions instead: `isCapture`, `isPromotion`,\n * `isEnPassant`, `isKingsideCastle`, `isQueensideCastle`, `isCastle`, and\n * `isBigPawn`\n */\n flags;\n san;\n lan;\n before;\n after;\n constructor(chess, internal) {\n const { color, piece, from, to, flags, captured, promotion } = internal;\n const fromAlgebraic = algebraic(from);\n const toAlgebraic = algebraic(to);\n this.color = color;\n this.piece = piece;\n this.from = fromAlgebraic;\n this.to = toAlgebraic;\n /*\n * HACK: The chess['_method']() calls below invoke private methods in the\n * Chess class to generate SAN and FEN. It's a bit of a hack, but makes the\n * code cleaner elsewhere.\n */\n this.san = chess['_moveToSan'](internal, chess['_moves']({ legal: true }));\n this.lan = fromAlgebraic + toAlgebraic;\n this.before = chess.fen();\n // Generate the FEN for the 'after' key\n chess['_makeMove'](internal);\n this.after = chess.fen();\n chess['_undoMove']();\n // Build the text representation of the move flags\n this.flags = '';\n for (const flag in BITS) {\n if (BITS[flag] & flags) {\n this.flags += FLAGS[flag];\n }\n }\n if (captured) {\n this.captured = captured;\n }\n if (promotion) {\n this.promotion = promotion;\n this.lan += promotion;\n }\n }\n isCapture() {\n return this.flags.indexOf(FLAGS['CAPTURE']) > -1;\n }\n isPromotion() {\n return this.flags.indexOf(FLAGS['PROMOTION']) > -1;\n }\n isEnPassant() {\n return this.flags.indexOf(FLAGS['EP_CAPTURE']) > -1;\n }\n isKingsideCastle() {\n return this.flags.indexOf(FLAGS['KSIDE_CASTLE']) > -1;\n }\n isQueensideCastle() {\n return this.flags.indexOf(FLAGS['QSIDE_CASTLE']) > -1;\n }\n isBigPawn() {\n return this.flags.indexOf(FLAGS['BIG_PAWN']) > -1;\n }\n}\nconst EMPTY = -1;\nconst FLAGS = {\n NORMAL: 'n',\n CAPTURE: 'c',\n BIG_PAWN: 'b',\n EP_CAPTURE: 'e',\n PROMOTION: 'p',\n KSIDE_CASTLE: 'k',\n QSIDE_CASTLE: 'q',\n};\n// prettier-ignore\nexport const SQUARES = [\n 'a8', 'b8', 'c8', 'd8', 'e8', 'f8', 'g8', 'h8',\n 'a7', 'b7', 'c7', 'd7', 'e7', 'f7', 'g7', 'h7',\n 'a6', 'b6', 'c6', 'd6', 'e6', 'f6', 'g6', 'h6',\n 'a5', 'b5', 'c5', 'd5', 'e5', 'f5', 'g5', 'h5',\n 'a4', 'b4', 'c4', 'd4', 'e4', 'f4', 'g4', 'h4',\n 'a3', 'b3', 'c3', 'd3', 'e3', 'f3', 'g3', 'h3',\n 'a2', 'b2', 'c2', 'd2', 'e2', 'f2', 'g2', 'h2',\n 'a1', 'b1', 'c1', 'd1', 'e1', 'f1', 'g1', 'h1'\n];\nconst BITS = {\n NORMAL: 1,\n CAPTURE: 2,\n BIG_PAWN: 4,\n EP_CAPTURE: 8,\n PROMOTION: 16,\n KSIDE_CASTLE: 32,\n QSIDE_CASTLE: 64,\n};\n/*\n * NOTES ABOUT 0x88 MOVE GENERATION ALGORITHM\n * ----------------------------------------------------------------------------\n * From https://github.com/jhlywa/chess.js/issues/230\n *\n * A lot of people are confused when they first see the internal representation\n * of chess.js. It uses the 0x88 Move Generation Algorithm which internally\n * stores the board as an 8x16 array. This is purely for efficiency but has a\n * couple of interesting benefits:\n *\n * 1. 0x88 offers a very inexpensive \"off the board\" check. Bitwise AND (&) any\n * square with 0x88, if the result is non-zero then the square is off the\n * board. For example, assuming a knight square A8 (0 in 0x88 notation),\n * there are 8 possible directions in which the knight can move. These\n * directions are relative to the 8x16 board and are stored in the\n * PIECE_OFFSETS map. One possible move is A8 - 18 (up one square, and two\n * squares to the left - which is off the board). 0 - 18 = -18 & 0x88 = 0x88\n * (because of two-complement representation of -18). The non-zero result\n * means the square is off the board and the move is illegal. Take the\n * opposite move (from A8 to C7), 0 + 18 = 18 & 0x88 = 0. A result of zero\n * means the square is on the board.\n *\n * 2. The relative distance (or difference) between two squares on a 8x16 board\n * is unique and can be used to inexpensively determine if a piece on a\n * square can attack any other arbitrary square. For example, let's see if a\n * pawn on E7 can attack E2. The difference between E7 (20) - E2 (100) is\n * -80. We add 119 to make the ATTACKS array index non-negative (because the\n * worst case difference is A8 - H1 = -119). The ATTACKS array contains a\n * bitmask of pieces that can attack from that distance and direction.\n * ATTACKS[-80 + 119=39] gives us 24 or 0b11000 in binary. Look at the\n * PIECE_MASKS map to determine the mask for a given piece type. In our pawn\n * example, we would check to see if 24 & 0x1 is non-zero, which it is\n * not. So, naturally, a pawn on E7 can't attack a piece on E2. However, a\n * rook can since 24 & 0x8 is non-zero. The only thing left to check is that\n * there are no blocking pieces between E7 and E2. That's where the RAYS\n * array comes in. It provides an offset (in this case 16) to add to E7 (20)\n * to check for blocking pieces. E7 (20) + 16 = E6 (36) + 16 = E5 (52) etc.\n */\n// prettier-ignore\n// eslint-disable-next-line\nconst Ox88 = {\n a8: 0, b8: 1, c8: 2, d8: 3, e8: 4, f8: 5, g8: 6, h8: 7,\n a7: 16, b7: 17, c7: 18, d7: 19, e7: 20, f7: 21, g7: 22, h7: 23,\n a6: 32, b6: 33, c6: 34, d6: 35, e6: 36, f6: 37, g6: 38, h6: 39,\n a5: 48, b5: 49, c5: 50, d5: 51, e5: 52, f5: 53, g5: 54, h5: 55,\n a4: 64, b4: 65, c4: 66, d4: 67, e4: 68, f4: 69, g4: 70, h4: 71,\n a3: 80, b3: 81, c3: 82, d3: 83, e3: 84, f3: 85, g3: 86, h3: 87,\n a2: 96, b2: 97, c2: 98, d2: 99, e2: 100, f2: 101, g2: 102, h2: 103,\n a1: 112, b1: 113, c1: 114, d1: 115, e1: 116, f1: 117, g1: 118, h1: 119\n};\nconst PAWN_OFFSETS = {\n b: [16, 32, 17, 15],\n w: [-16, -32, -17, -15],\n};\nconst PIECE_OFFSETS = {\n n: [-18, -33, -31, -14, 18, 33, 31, 14],\n b: [-17, -15, 17, 15],\n r: [-16, 1, 16, -1],\n q: [-17, -16, -15, 1, 17, 16, 15, -1],\n k: [-17, -16, -15, 1, 17, 16, 15, -1],\n};\n// prettier-ignore\nconst ATTACKS = [\n 20, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 20, 0,\n 0, 20, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 20, 0, 0,\n 0, 0, 20, 0, 0, 0, 0, 24, 0, 0, 0, 0, 20, 0, 0, 0,\n 0, 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, 20, 0, 0, 0, 0,\n 0, 0, 0, 0, 20, 0, 0, 24, 0, 0, 20, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 20, 2, 24, 2, 20, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 2, 53, 56, 53, 2, 0, 0, 0, 0, 0, 0,\n 24, 24, 24, 24, 24, 24, 56, 0, 56, 24, 24, 24, 24, 24, 24, 0,\n 0, 0, 0, 0, 0, 2, 53, 56, 53, 2, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 20, 2, 24, 2, 20, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 20, 0, 0, 24, 0, 0, 20, 0, 0, 0, 0, 0,\n 0, 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, 20, 0, 0, 0, 0,\n 0, 0, 20, 0, 0, 0, 0, 24, 0, 0, 0, 0, 20, 0, 0, 0,\n 0, 20, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 20, 0, 0,\n 20, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 20\n];\n// prettier-ignore\nconst RAYS = [\n 17, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 15, 0,\n 0, 17, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 15, 0, 0,\n 0, 0, 17, 0, 0, 0, 0, 16, 0, 0, 0, 0, 15, 0, 0, 0,\n 0, 0, 0, 17, 0, 0, 0, 16, 0, 0, 0, 15, 0, 0, 0, 0,\n 0, 0, 0, 0, 17, 0, 0, 16, 0, 0, 15, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 17, 0, 16, 0, 15, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 17, 16, 15, 0, 0, 0, 0, 0, 0, 0,\n 1, 1, 1, 1, 1, 1, 1, 0, -1, -1, -1, -1, -1, -1, -1, 0,\n 0, 0, 0, 0, 0, 0, -15, -16, -17, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, -15, 0, -16, 0, -17, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, -15, 0, 0, -16, 0, 0, -17, 0, 0, 0, 0, 0,\n 0, 0, 0, -15, 0, 0, 0, -16, 0, 0, 0, -17, 0, 0, 0, 0,\n 0, 0, -15, 0, 0, 0, 0, -16, 0, 0, 0, 0, -17, 0, 0, 0,\n 0, -15, 0, 0, 0, 0, 0, -16, 0, 0, 0, 0, 0, -17, 0, 0,\n -15, 0, 0, 0, 0, 0, 0, -16, 0, 0, 0, 0, 0, 0, -17\n];\nconst PIECE_MASKS = { p: 0x1, n: 0x2, b: 0x4, r: 0x8, q: 0x10, k: 0x20 };\nconst SYMBOLS = 'pnbrqkPNBRQK';\nconst PROMOTIONS = [KNIGHT, BISHOP, ROOK, QUEEN];\nconst RANK_1 = 7;\nconst RANK_2 = 6;\n/*\n * const RANK_3 = 5\n * const RANK_4 = 4\n * const RANK_5 = 3\n * const RANK_6 = 2\n */\nconst RANK_7 = 1;\nconst RANK_8 = 0;\nconst SIDES = {\n [KING]: BITS.KSIDE_CASTLE,\n [QUEEN]: BITS.QSIDE_CASTLE,\n};\nconst ROOKS = {\n w: [\n { square: Ox88.a1, flag: BITS.QSIDE_CASTLE },\n { square: Ox88.h1, flag: BITS.KSIDE_CASTLE },\n ],\n b: [\n { square: Ox88.a8, flag: BITS.QSIDE_CASTLE },\n { square: Ox88.h8, flag: BITS.KSIDE_CASTLE },\n ],\n};\nconst SECOND_RANK = { b: RANK_7, w: RANK_2 };\nconst TERMINATION_MARKERS = ['1-0', '0-1', '1/2-1/2', '*'];\n// Extracts the zero-based rank of an 0x88 square.\nfunction rank(square) {\n return square >> 4;\n}\n// Extracts the zero-based file of an 0x88 square.\nfunction file(square) {\n return square & 0xf;\n}\nfunction isDigit(c) {\n return '0123456789'.indexOf(c) !== -1;\n}\n// Converts a 0x88 square to algebraic notation.\nfunction algebraic(square) {\n const f = file(square);\n const r = rank(square);\n return ('abcdefgh'.substring(f, f + 1) +\n '87654321'.substring(r, r + 1));\n}\nfunction swapColor(color) {\n return color === WHITE ? BLACK : WHITE;\n}\nexport function validateFen(fen) {\n // 1st criterion: 6 space-seperated fields?\n const tokens = fen.split(/\\s+/);\n if (tokens.length !== 6) {\n return {\n ok: false,\n error: 'Invalid FEN: must contain six space-delimited fields',\n };\n }\n // 2nd criterion: move number field is a integer value > 0?\n const moveNumber = parseInt(tokens[5], 10);\n if (isNaN(moveNumber) || moveNumber <= 0) {\n return {\n ok: false,\n error: 'Invalid FEN: move number must be a positive integer',\n };\n }\n // 3rd criterion: half move counter is an integer >= 0?\n const halfMoves = parseInt(tokens[4], 10);\n if (isNaN(halfMoves) || halfMoves < 0) {\n return {\n ok: false,\n error: 'Invalid FEN: half move counter number must be a non-negative integer',\n };\n }\n // 4th criterion: 4th field is a valid e.p.-string?\n if (!/^(-|[abcdefgh][36])$/.test(tokens[3])) {\n return { ok: false, error: 'Invalid FEN: en-passant square is invalid' };\n }\n // 5th criterion: 3th field is a valid castle-string?\n if (/[^kKqQ-]/.test(tokens[2])) {\n return { ok: false, error: 'Invalid FEN: castling availability is invalid' };\n }\n // 6th criterion: 2nd field is \"w\" (white) or \"b\" (black)?\n if (!/^(w|b)$/.test(tokens[1])) {\n return { ok: false, error: 'Invalid FEN: side-to-move is invalid' };\n }\n // 7th criterion: 1st field contains 8 rows?\n const rows = tokens[0].split('/');\n if (rows.length !== 8) {\n return {\n ok: false,\n error: \"Invalid FEN: piece data does not contain 8 '/'-delimited rows\",\n };\n }\n // 8th criterion: every row is valid?\n for (let i = 0; i < rows.length; i++) {\n // check for right sum of fields AND not two numbers in succession\n let sumFields = 0;\n let previousWasNumber = false;\n for (let k = 0; k < rows[i].length; k++) {\n if (isDigit(rows[i][k])) {\n if (previousWasNumber) {\n return {\n ok: false,\n error: 'Invalid FEN: piece data is invalid (consecutive number)',\n };\n }\n sumFields += parseInt(rows[i][k], 10);\n previousWasNumber = true;\n }\n else {\n if (!/^[prnbqkPRNBQK]$/.test(rows[i][k])) {\n return {\n ok: false,\n error: 'Invalid FEN: piece data is invalid (invalid piece)',\n };\n }\n sumFields += 1;\n previousWasNumber = false;\n }\n }\n if (sumFields !== 8) {\n return {\n ok: false,\n error: 'Invalid FEN: piece data is invalid (too many squares in rank)',\n };\n }\n }\n // 9th criterion: is en-passant square legal?\n if ((tokens[3][1] == '3' && tokens[1] == 'w') ||\n (tokens[3][1] == '6' && tokens[1] == 'b')) {\n return { ok: false, error: 'Invalid FEN: illegal en-passant square' };\n }\n // 10th criterion: does chess position contain exact two kings?\n const kings = [\n { color: 'white', regex: /K/g },\n { color: 'black', regex: /k/g },\n ];\n for (const { color, regex } of kings) {\n if (!regex.test(tokens[0])) {\n return { ok: false, error: `Invalid FEN: missing ${color} king` };\n }\n if ((tokens[0].match(regex) || []).length > 1) {\n return { ok: false, error: `Invalid FEN: too many ${color} kings` };\n }\n }\n // 11th criterion: are any pawns on the first or eighth rows?\n if (Array.from(rows[0] + rows[7]).some((char) => char.toUpperCase() === 'P')) {\n return {\n ok: false,\n error: 'Invalid FEN: some pawns are on the edge rows',\n };\n }\n return { ok: true };\n}\n// this function is used to uniquely identify ambiguous moves\nfunction getDisambiguator(move, moves) {\n const from = move.from;\n const to = move.to;\n const piece = move.piece;\n let ambiguities = 0;\n let sameRank = 0;\n let sameFile = 0;\n for (let i = 0, len = moves.length; i < len; i++) {\n const ambigFrom = moves[i].from;\n const ambigTo = moves[i].to;\n const ambigPiece = moves[i].piece;\n /*\n * if a move of the same piece type ends on the same to square, we'll need\n * to add a disambiguator to the algebraic notation\n */\n if (piece === ambigPiece && from !== ambigFrom && to === ambigTo) {\n ambiguities++;\n if (rank(from) === rank(ambigFrom)) {\n sameRank++;\n }\n if (file(from) === file(ambigFrom)) {\n sameFile++;\n }\n }\n }\n if (ambiguities > 0) {\n if (sameRank > 0 && sameFile > 0) {\n /*\n * if there exists a similar moving piece on the same rank and file as\n * the move in question, use the square as the disambiguator\n */\n return algebraic(from);\n }\n else if (sameFile > 0) {\n /*\n * if the moving piece rests on the same file, use the rank symbol as the\n * disambiguator\n */\n return algebraic(from).charAt(1);\n }\n else {\n // else use the file symbol\n return algebraic(from).charAt(0);\n }\n }\n return '';\n}\nfunction addMove(moves, color, from, to, piece, captured = undefined, flags = BITS.NORMAL) {\n const r = rank(to);\n if (piece === PAWN && (r === RANK_1 || r === RANK_8)) {\n for (let i = 0; i < PROMOTIONS.length; i++) {\n const promotion = PROMOTIONS[i];\n moves.push({\n color,\n from,\n to,\n piece,\n captured,\n promotion,\n flags: flags | BITS.PROMOTION,\n });\n }\n }\n else {\n moves.push({\n color,\n from,\n to,\n piece,\n captured,\n flags,\n });\n }\n}\nfunction inferPieceType(san) {\n let pieceType = san.charAt(0);\n if (pieceType >= 'a' && pieceType <= 'h') {\n const matches = san.match(/[a-h]\\d.*[a-h]\\d/);\n if (matches) {\n return undefined;\n }\n return PAWN;\n }\n pieceType = pieceType.toLowerCase();\n if (pieceType === 'o') {\n return KING;\n }\n return pieceType;\n}\n// parses all of the decorators out of a SAN string\nfunction strippedSan(move) {\n return move.replace(/=/, '').replace(/[+#]?[?!]*$/, '');\n}\nfunction trimFen(fen) {\n /*\n * remove last two fields in FEN string as they're not needed when checking\n * for repetition\n */\n return fen.split(' ').slice(0, 4).join(' ');\n}\nexport class Chess {\n _board = new Array(128);\n _turn = WHITE;\n _header = {};\n _kings = { w: EMPTY, b: EMPTY };\n _epSquare = -1;\n _halfMoves = 0;\n _moveNumber = 0;\n _history = [];\n _comments = {};\n _castling = { w: 0, b: 0 };\n // tracks number of times a position has been seen for repetition checking\n _positionCount = {};\n constructor(fen = DEFAULT_POSITION, { skipValidation = false } = {}) {\n this.load(fen, { skipValidation });\n }\n clear({ preserveHeaders = false } = {}) {\n this._board = new Array(128);\n this._kings = { w: EMPTY, b: EMPTY };\n this._turn = WHITE;\n this._castling = { w: 0, b: 0 };\n this._epSquare = EMPTY;\n this._halfMoves = 0;\n this._moveNumber = 1;\n this._history = [];\n this._comments = {};\n this._header = preserveHeaders ? this._header : {};\n this._positionCount = {};\n /*\n * Delete the SetUp and FEN headers (if preserved), the board is empty and\n * these headers don't make sense in this state. They'll get added later\n * via .load() or .put()\n */\n delete this._header['SetUp'];\n delete this._header['FEN'];\n }\n load(fen, { skipValidation = false, preserveHeaders = false } = {}) {\n let tokens = fen.split(/\\s+/);\n // append commonly omitted fen tokens\n if (tokens.length >= 2 && tokens.length < 6) {\n const adjustments = ['-', '-', '0', '1'];\n fen = tokens.concat(adjustments.slice(-(6 - tokens.length))).join(' ');\n }\n tokens = fen.split(/\\s+/);\n if (!skipValidation) {\n const { ok, error } = validateFen(fen);\n if (!ok) {\n throw new Error(error);\n }\n }\n const position = tokens[0];\n let square = 0;\n this.clear({ preserveHeaders });\n for (let i = 0; i < position.length; i++) {\n const piece = position.charAt(i);\n if (piece === '/') {\n square += 8;\n }\n else if (isDigit(piece)) {\n square += parseInt(piece, 10);\n }\n else {\n const color = piece < 'a' ? WHITE : BLACK;\n this._put({ type: piece.toLowerCase(), color }, algebraic(square));\n square++;\n }\n }\n this._turn = tokens[1];\n if (tokens[2].indexOf('K') > -1) {\n this._castling.w |= BITS.KSIDE_CASTLE;\n }\n if (tokens[2].indexOf('Q') > -1) {\n this._castling.w |= BITS.QSIDE_CASTLE;\n }\n if (tokens[2].indexOf('k') > -1) {\n this._castling.b |= BITS.KSIDE_CASTLE;\n }\n if (tokens[2].indexOf('q') > -1) {\n this._castling.b |= BITS.QSIDE_CASTLE;\n }\n this._epSquare = tokens[3] === '-' ? EMPTY : Ox88[tokens[3]];\n this._halfMoves = parseInt(tokens[4], 10);\n this._moveNumber = parseInt(tokens[5], 10);\n this._updateSetup(fen);\n this._incPositionCount(fen);\n }\n fen() {\n let empty = 0;\n let fen = '';\n for (let i = Ox88.a8; i <= Ox88.h1; i++) {\n if (this._board[i]) {\n if (empty > 0) {\n fen += empty;\n empty = 0;\n }\n const { color, type: piece } = this._board[i];\n fen += color === WHITE ? piece.toUpperCase() : piece.toLowerCase();\n }\n else {\n empty++;\n }\n if ((i + 1) & 0x88) {\n if (empty > 0) {\n fen += empty;\n }\n if (i !== Ox88.h1) {\n fen += '/';\n }\n empty = 0;\n i += 8;\n }\n }\n let castling = '';\n if (this._castling[WHITE] & BITS.KSIDE_CASTLE) {\n castling += 'K';\n }\n if (this._castling[WHITE] & BITS.QSIDE_CASTLE) {\n castling += 'Q';\n }\n if (this._castling[BLACK] & BITS.KSIDE_CASTLE) {\n castling += 'k';\n }\n if (this._castling[BLACK] & BITS.QSIDE_CASTLE) {\n castling += 'q';\n }\n // do we have an empty castling flag?\n castling = castling || '-';\n let epSquare = '-';\n /*\n * only print the ep square if en passant is a valid move (pawn is present\n * and ep capture is not pinned)\n */\n if (this._epSquare !== EMPTY) {\n const bigPawnSquare = this._epSquare + (this._turn === WHITE ? 16 : -16);\n const squares = [bigPawnSquare + 1, bigPawnSquare - 1];\n for (const square of squares) {\n // is the square off the board?\n if (square & 0x88) {\n continue;\n }\n const color = this._turn;\n // is there a pawn that can capture the epSquare?\n if (this._board[square]?.color === color &&\n this._board[square]?.type === PAWN) {\n // if the pawn makes an ep capture, does it leave it's king in check?\n this._makeMove({\n color,\n from: square,\n to: this._epSquare,\n piece: PAWN,\n captured: PAWN,\n flags: BITS.EP_CAPTURE,\n });\n const isLegal = !this._isKingAttacked(color);\n this._undoMove();\n // if ep is legal, break and set the ep square in the FEN output\n if (isLegal) {\n epSquare = algebraic(this._epSquare);\n break;\n }\n }\n }\n }\n return [\n fen,\n this._turn,\n castling,\n epSquare,\n this._halfMoves,\n this._moveNumber,\n ].join(' ');\n }\n /*\n * Called when the initial board setup is changed with put() or remove().\n * modifies the SetUp and FEN properties of the header object. If the FEN\n * is equal to the default position, the SetUp and FEN are deleted the setup\n * is only updated if history.length is zero, ie moves haven't been made.\n */\n _updateSetup(fen) {\n if (this._history.length > 0)\n return;\n if (fen !== DEFAULT_POSITION) {\n this._header['SetUp'] = '1';\n this._header['FEN'] = fen;\n }\n else {\n delete this._header['SetUp'];\n delete this._header['FEN'];\n }\n }\n reset() {\n this.load(DEFAULT_POSITION);\n }\n get(square) {\n return this._board[Ox88[square]];\n }\n put({ type, color }, square) {\n if (this._put({ type, color }, square)) {\n this._updateCastlingRights();\n this._updateEnPassantSquare();\n this._updateSetup(this.fen());\n return true;\n }\n return false;\n }\n _put({ type, color }, square) {\n // check for piece\n if (SYMBOLS.indexOf(type.toLowerCase()) === -1) {\n return false;\n }\n // check for valid square\n if (!(square in Ox88)) {\n return false;\n }\n const sq = Ox88[square];\n // don't let the user place more than one king\n if (type == KING &&\n !(this._kings[color] == EMPTY || this._kings[color] == sq)) {\n return false;\n }\n const currentPieceOnSquare = this._board[sq];\n // if one of the kings will be replaced by the piece from args, set the `_kings` respective entry to `EMPTY`\n if (currentPieceOnSquare && currentPieceOnSquare.type === KING) {\n this._kings[currentPieceOnSquare.color] = EMPTY;\n }\n this._board[sq] = { type: type, color: color };\n if (type === KING) {\n this._kings[color] = sq;\n }\n return true;\n }\n remove(square) {\n const piece = this.get(square);\n delete this._board[Ox88[square]];\n if (piece && piece.type === KING) {\n this._kings[piece.color] = EMPTY;\n }\n this._updateCastlingRights();\n this._updateEnPassantSquare();\n this._updateSetup(this.fen());\n return piece;\n }\n _updateCastlingRights() {\n const whiteKingInPlace = this._board[Ox88.e1]?.type === KING &&\n this._board[Ox88.e1]?.color === WHITE;\n const blackKingInPlace = this._board[Ox88.e8]?.type === KING &&\n this._board[Ox88.e8]?.color === BLACK;\n if (!whiteKingInPlace ||\n this._board[Ox88.a1]?.type !== ROOK ||\n this._board[Ox88.a1]?.color !== WHITE) {\n this._castling.w &= ~BITS.QSIDE_CASTLE;\n }\n if (!whiteKingInPlace ||\n this._board[Ox88.h1]?.type !== ROOK ||\n this._board[Ox88.h1]?.color !== WHITE) {\n this._castling.w &= ~BITS.KSIDE_CASTLE;\n }\n if (!blackKingInPlace ||\n this._board[Ox88.a8]?.type !== ROOK ||\n this._board[Ox88.a8]?.color !== BLACK) {\n this._castling.b &= ~BITS.QSIDE_CASTLE;\n }\n if (!blackKingInPlace ||\n this._board[Ox88.h8]?.type !== ROOK ||\n this._board[Ox88.h8]?.color !== BLACK) {\n this._castling.b &= ~BITS.KSIDE_CASTLE;\n }\n }\n _updateEnPassantSquare() {\n if (this._epSquare === EMPTY) {\n return;\n }\n const startSquare = this._epSquare + (this._turn === WHITE ? -16 : 16);\n const currentSquare = this._epSquare + (this._turn === WHITE ? 16 : -16);\n const attackers = [currentSquare + 1, currentSquare - 1];\n if (this._board[startSquare] !== null ||\n this._board[this._epSquare] !== null ||\n this._board[currentSquare]?.color !== swapColor(this._turn) ||\n this._board[currentSquare]?.type !== PAWN) {\n this._epSquare = EMPTY;\n return;\n }\n const canCapture = (square) => !(square & 0x88) &&\n this._board[square]?.color === this._turn &&\n this._board[square]?.type === PAWN;\n if (!attackers.some(canCapture)) {\n this._epSquare = EMPTY;\n }\n }\n _attacked(color, square, verbose) {\n const attackers = [];\n for (let i = Ox88.a8; i <= Ox88.h1; i++) {\n // did we run off the end of the board\n if (i & 0x88) {\n i += 7;\n continue;\n }\n // if empty square or wrong color\n if (this._board[i] === undefined || this._board[i].color !== color) {\n continue;\n }\n const piece = this._board[i];\n const difference = i - square;\n // skip - to/from square are the same\n if (difference === 0) {\n continue;\n }\n const index = difference + 119;\n if (ATTACKS[index] & PIECE_MASKS[piece.type]) {\n if (piece.type === PAWN) {\n if ((difference > 0 && piece.color === WHITE) ||\n (difference <= 0 && piece.color === BLACK)) {\n if (!verbose) {\n return true;\n }\n else {\n attackers.push(algebraic(i));\n }\n }\n continue;\n }\n // if the piece is a knight or a king\n if (piece.type === 'n' || piece.type === 'k') {\n if (!verbose) {\n return true;\n }\n else {\n attackers.push(algebraic(i));\n continue;\n }\n }\n const offset = RAYS[index];\n let j = i + offset;\n let blocked = false;\n while (j !== square) {\n if (this._board[j] != null) {\n blocked = true;\n break;\n }\n j += offset;\n }\n if (!blocked) {\n if (!verbose) {\n return true;\n }\n else {\n attackers.push(algebraic(i));\n continue;\n }\n }\n }\n }\n if (verbose) {\n return attackers;\n }\n else {\n return false;\n }\n }\n attackers(square, attackedBy) {\n if (!attackedBy) {\n return this._attacked(this._turn, Ox88[square], true);\n }\n else {\n return this._attacked(attackedBy, Ox88[square], true);\n }\n }\n _isKingAttacked(color) {\n const square = this._kings[color];\n return square === -1 ? false : this._attacked(swapColor(color), square);\n }\n isAttacked(square, attackedBy) {\n return this._attacked(attackedBy, Ox88[square]);\n }\n isCheck() {\n return this._isKingAttacked(this._turn);\n }\n inCheck() {\n return this.isCheck();\n }\n isCheckmate() {\n return this.isCheck() && this._moves().length === 0;\n }\n isStalemate() {\n return !this.isCheck() && this._moves().length === 0;\n }\n isInsufficientMaterial() {\n /*\n * k.b. vs k.b. (of opposite colors) with mate in 1:\n * 8/8/8/8/1b6/8/B1k5/K7 b - - 0 1\n *\n * k.b. vs k.n. with mate in 1:\n * 8/8/8/8/1n6/8/B7/K1k5 b - - 2 1\n */\n const pieces = {\n b: 0,\n n: 0,\n r: 0,\n q: 0,\n k: 0,\n p: 0,\n };\n const bishops = [];\n let numPieces = 0;\n let squareColor = 0;\n for (let i = Ox88.a8; i <= Ox88.h1; i++) {\n squareColor = (squareColor + 1) % 2;\n if (i & 0x88) {\n i += 7;\n continue;\n }\n const piece = this._board[i];\n if (piece) {\n pieces[piece.type] = piece.type in pieces ? pieces[piece.type] + 1 : 1;\n if (piece.type === BISHOP) {\n bishops.push(squareColor);\n }\n numPieces++;\n }\n }\n // k vs. k\n if (numPieces === 2) {\n return true;\n }\n else if (\n // k vs. kn .... or .... k vs. kb\n numPieces === 3 &&\n (pieces[BISHOP] === 1 || pieces[KNIGHT] === 1)) {\n return true;\n }\n else if (numPieces === pieces[BISHOP] + 2) {\n // kb vs. kb where any number of bishops are all on the same color\n let sum = 0;\n const len = bishops.length;\n for (let i = 0; i < len; i++) {\n sum += bishops[i];\n }\n if (sum === 0 || sum === len) {\n return true;\n }\n }\n return false;\n }\n isThreefoldRepetition() {\n return this._getPositionCount(this.fen()) >= 3;\n }\n isDrawByFiftyMoves() {\n return this._halfMoves >= 100; // 50 moves per side = 100 half moves\n }\n isDraw() {\n return (this.isDrawByFiftyMoves() ||\n this.isStalemate() ||\n this.isInsufficientMaterial() ||\n this.isThreefoldRepetition());\n }\n isGameOver() {\n return this.isCheckmate() || this.isStalemate() || this.isDraw();\n }\n moves({ verbose = false, square = undefined, piece = undefined, } = {}) {\n const moves = this._moves({ square, piece });\n if (verbose) {\n return moves.map((move) => new Move(this, move));\n }\n else {\n return moves.map((move) => this._moveToSan(move, moves));\n }\n }\n _moves({ legal = true, piece = undefined, square = undefined, } = {}) {\n const forSquare = square ? square.toLowerCase() : undefined;\n const forPiece = piece?.toLowerCase();\n const moves = [];\n const us = this._turn;\n const them = swapColor(us);\n let firstSquare = Ox88.a8;\n let lastSquare = Ox88.h1;\n let singleSquare = false;\n // are we generating moves for a single square?\n if (forSquare) {\n // illegal square, return empty moves\n if (!(forSquare in Ox88)) {\n return [];\n }\n else {\n firstSquare = lastSquare = Ox88[forSquare];\n singleSquare = true;\n }\n }\n for (let from = firstSquare; from <= lastSquare; from++) {\n // did we run off the end of the board\n if (from & 0x88) {\n from += 7;\n continue;\n }\n // empty square or opponent, skip\n if (!this._board[from] || this._board[from].color === them) {\n continue;\n }\n const { type } = this._board[from];\n let to;\n if (type === PAWN) {\n if (forPiece && forPiece !== type)\n continue;\n // single square, non-capturing\n to = from + PAWN_OFFSETS[us][0];\n if (!this._board[to]) {\n addMove(moves, us, from, to, PAWN);\n // double square\n to = from + PAWN_OFFSETS[us][1];\n if (SECOND_RANK[us] === rank(from) && !this._board[to]) {\n addMove(moves, us, from, to, PAWN, undefined, BITS.BIG_PAWN);\n }\n }\n // pawn captures\n for (let j = 2; j < 4; j++) {\n to = from + PAWN_OFFSETS[us][j];\n if (to & 0x88)\n continue;\n if (this._board[to]?.color === them) {\n addMove(moves, us, from, to, PAWN, this._board[to].type, BITS.CAPTURE);\n }\n else if (to === this._epSquare) {\n addMove(moves, us, from, to, PAWN, PAWN, BITS.EP_CAPTURE);\n }\n }\n }\n else {\n if (forPiece && forPiece !== type)\n continue;\n for (let j = 0, len = PIECE_OFFSETS[type].length; j < len; j++) {\n const offset = PIECE_OFFSETS[type][j];\n to = from;\n while (true) {\n to += offset;\n if (to & 0x88)\n break;\n if (!this._board[to]) {\n addMove(moves, us, from, to, type);\n }\n else {\n // own color, stop loop\n if (this._board[to].color === us)\n break;\n addMove(moves, us, from, to, type, this._board[to].type, BITS.CAPTURE);\n break;\n }\n /* break, if knight or king */\n if (type === KNIGHT || type === KING)\n break;\n }\n }\n }\n }\n /*\n * check for castling if we're:\n * a) generating all moves, or\n * b) doing single square move generation on the king's square\n */\n if (forPiece === undefined || forPiece === KING) {\n if (!singleSquare || lastSquare === this._kings[us]) {\n // king-side castling\n if (this._castling[us] & BITS.KSIDE_CASTLE) {\n const castlingFrom = this._kings[us];\n const castlingTo = castlingFrom + 2;\n if (!this._board[castlingFrom + 1] &&\n !this._board[castlingTo] &&\n !this._attacked(them, this._kings[us]) &&\n !this._attacked(them, castlingFrom + 1) &&\n !this._attacked(them, castlingTo)) {\n addMove(moves, us, this._kings[us], castlingTo, KING, undefined, BITS.KSIDE_CASTLE);\n }\n }\n // queen-side castling\n if (this._castling[us] & BITS.QSIDE_CASTLE) {\n const castlingFrom = this._kings[us];\n const castlingTo = castlingFrom - 2;\n if (!this._board[castlingFrom - 1] &&\n !this._board[castlingFrom - 2] &&\n !this._board[castlingFrom - 3] &&\n !this._attacked(them, this._kings[us]) &&\n !this._attacked(them, castlingFrom - 1) &&\n !this._attacked(them, castlingTo)) {\n addMove(moves, us, this._kings[us], castlingTo, KING, undefined, BITS.QSIDE_CASTLE);\n }\n }\n }\n }\n /*\n * return all pseudo-legal moves (this includes moves that allow the king\n * to be captured)\n */\n if (!legal || this._kings[us] === -1) {\n return moves;\n }\n // filter out illegal moves\n const legalMoves = [];\n for (let i = 0, len = moves.length; i < len; i++) {\n this._makeMove(moves[i]);\n if (!this._isKingAttacked(us)) {\n legalMoves.push(moves[i]);\n }\n this._undoMove();\n }\n return legalMoves;\n }\n move(move, { strict = false } = {}) {\n /*\n * The move function can be called with in the following parameters:\n *\n * .move('Nxb7') <- argument is a case-sensitive SAN string\n *\n * .move({ from: 'h7', <- argument is a move object\n * to :'h8',\n * promotion: 'q' })\n *\n *\n * An optional strict argument may be supplied to tell chess.js to\n * strictly follow the SAN specification.\n */\n let moveObj = null;\n if (typeof move === 'string') {\n moveObj = this._moveFromSan(move, strict);\n }\n else if (typeof move === 'object') {\n const moves = this._moves();\n // convert the pretty move object to an ugly move object\n for (let i = 0, len = moves.length; i < len; i++) {\n if (move.from === algebraic(moves[i].from) &&\n move.to === algebraic(moves[i].to) &&\n (!('promotion' in moves[i]) || move.promotion === moves[i].promotion)) {\n moveObj = moves[i];\n break;\n }\n }\n }\n // failed to find move\n if (!moveObj) {\n if (typeof move === 'string') {\n throw new Error(`Invalid move: ${move}`);\n }\n else {\n throw new Error(`Invalid move: ${JSON.stringify(move)}`);\n }\n }\n /*\n * need to make a copy of move because we can't generate SAN after the move\n * is made\n */\n const prettyMove = new Move(this, moveObj);\n this._makeMove(moveObj);\n this._incPositionCount(prettyMove.after);\n return prettyMove;\n }\n _push(move) {\n this._history.push({\n move,\n kings: { b: this._kings.b, w: this._kings.w },\n turn: this._turn,\n castling: { b: this._castling.b, w: this._castling.w },\n epSquare: this._epSquare,\n halfMoves: this._halfMoves,\n moveNumber: this._moveNumber,\n });\n }\n _makeMove(move) {\n const us = this._turn;\n const them = swapColor(us);\n this._push(move);\n this._board[move.to] = this._board[move.from];\n delete this._board[move.from];\n // if ep capture, remove the captured pawn\n if (move.flags & BITS.EP_CAPTURE) {\n if (this._turn === BLACK) {\n delete this._board[move.to - 16];\n }\n else {\n delete this._board[move.to + 16];\n }\n }\n // if pawn promotion, replace with new piece\n if (move.promotion) {\n this._board[move.to] = { type: move.promotion, color: us };\n }\n // if we moved the king\n if (this._board[move.to].type === KING) {\n this._kings[us] = move.to;\n // if we castled, move the rook next to the king\n if (move.flags & BITS.KSIDE_CASTLE) {\n const castlingTo = move.to - 1;\n const castlingFrom = move.to + 1;\n this._board[castlingTo] = this._board[castlingFrom];\n delete this._board[castlingFrom];\n }\n else if (move.flags & BITS.QSIDE_CASTLE) {\n const castlingTo = move.to + 1;\n const castlingFrom = move.to - 2;\n this._board[castlingTo] = this._board[castlingFrom];\n delete this._board[castlingFrom];\n }\n // turn off castling\n this._castling[us] = 0;\n }\n // turn off castling if we move a rook\n if (this._castling[us]) {\n for (let i = 0, len = ROOKS[us].length; i < len; i++) {\n if (move.from === ROOKS[us][i].square &&\n this._castling[us] & ROOKS[us][i].flag) {\n this._castling[us] ^= ROOKS[us][i].flag;\n break;\n }\n }\n }\n // turn off castling if we capture a rook\n if (this._castling[them]) {\n for (let i = 0, len = ROOKS[them].length; i < len; i++) {\n if (move.to === ROOKS[them][i].square &&\n this._castling[them] & ROOKS[them][i].flag) {\n this._castling[them] ^= ROOKS[them][i].flag;\n break;\n }\n }\n }\n // if big pawn move, update the en passant square\n if (move.flags & BITS.BIG_PAWN) {\n if (us === BLACK) {\n this._epSquare = move.to - 16;\n }\n else {\n this._epSquare = move.to + 16;\n }\n }\n else {\n this._epSquare = EMPTY;\n }\n // reset the 50 move counter if a pawn is moved or a piece is captured\n if (move.piece === PAWN) {\n this._halfMoves = 0;\n }\n else if (move.flags & (BITS.CAPTURE | BITS.EP_CAPTURE)) {\n this._halfMoves = 0;\n }\n else {\n this._halfMoves++;\n }\n if (us === BLACK) {\n this._moveNumber++;\n }\n this._turn = them;\n }\n undo() {\n const move = this._undoMove();\n if (move) {\n const prettyMove = new Move(this, move);\n this._decPositionCount(prettyMove.after);\n return prettyMove;\n }\n return null;\n }\n _undoMove() {\n const old = this._history.pop();\n if (old === undefined) {\n return null;\n }\n const move = old.move;\n this._kings = old.kings;\n this._turn = old.turn;\n this._castling = old.castling;\n this._epSquare = old.epSquare;\n this._halfMoves = old.halfMoves;\n this._moveNumber = old.moveNumber;\n const us = this._turn;\n const them = swapColor(us);\n this._board[move.from] = this._board[move.to];\n this._board[move.from].type = move.piece; // to undo any promotions\n delete this._board[move.to];\n if (move.captured) {\n if (move.flags & BITS.EP_CAPTURE) {\n // en passant capture\n let index;\n if (us === BLACK) {\n index = move.to - 16;\n }\n else {\n index = move.to + 16;\n }\n this._board[index] = { type: PAWN, color: them };\n }\n else {\n // regular capture\n this._board[move.to] = { type: move.captured, color: them };\n }\n }\n if (move.flags & (BITS.KSIDE_CASTLE | BITS.QSIDE_CASTLE)) {\n let castlingTo, castlingFrom;\n if (move.flags & BITS.KSIDE_CASTLE) {\n castlingTo = move.to + 1;\n castlingFrom = move.to - 1;\n }\n else {\n castlingTo = move.to - 2;\n castlingFrom = move.to + 1;\n }\n this._board[castlingTo] = this._board[castlingFrom];\n delete this._board[castlingFrom];\n }\n return move;\n }\n pgn({ newline = '\\n', maxWidth = 0, } = {}) {\n /*\n * using the specification from http://www.chessclub.com/help/PGN-spec\n * example for html usage: .pgn({ max_width: 72, newline_char: \"<br />\" })\n */\n const result = [];\n let headerExists = false;\n /* add the PGN header information */\n for (const i in this._header) {\n /*\n * TODO: order of enumerated properties in header object is not\n * guaranteed, see ECMA-262 spec (section 12.6.4)\n */\n result.push('[' + i + ' \"' + this._header[i] + '\"]' + newline);\n headerExists = true;\n }\n if (headerExists && this._history.length) {\n result.push(newline);\n }\n const appendComment = (moveString) => {\n const comment = this._comments[this.fen()];\n if (typeof comment !== 'undefined') {\n const delimiter = moveString.length > 0 ? ' ' : '';\n moveString = `${moveString}${delimiter}{${comment}}`;\n }\n return moveString;\n };\n // pop all of history onto reversed_history\n const reversedHistory = [];\n while (this._history.length > 0) {\n reversedHistory.push(this._undoMove());\n }\n const moves = [];\n let moveString = '';\n // special case of a commented starting position with no moves\n if (reversedHistory.length === 0) {\n moves.push(appendComment(''));\n }\n // build the list of moves. a move_string looks like: \"3. e3 e6\"\n while (reversedHistory.length > 0) {\n moveString = appendComment(moveString);\n const move = reversedHistory.pop();\n // make TypeScript stop complaining about move being undefined\n if (!move) {\n break;\n }\n // if the position started with black to move, start PGN with #. ...\n if (!this._history.length && move.color === 'b') {\n const prefix = `${this._moveNumber}. ...`;\n // is there a comment preceding the first move?\n moveString = moveString ? `${moveString} ${prefix}` : prefix;\n }\n else if (move.color === 'w') {\n // store the previous generated move_string if we have one\n if (moveString.length) {\n moves.push(moveString);\n }\n moveString = this._moveNumber + '.';\n }\n moveString =\n moveString + ' ' + this._moveToSan(move, this._moves({ legal: true }));\n this._makeMove(move);\n }\n // are there any other leftover moves?\n if (moveString.length) {\n moves.push(appendComment(moveString));\n }\n // is there a result?\n if (typeof this._header.Result !== 'undefined') {\n moves.push(this._header.Result);\n }\n /*\n * history should be back to what it was before we started generating PGN,\n * so join together moves\n */\n if (maxWidth === 0) {\n return result.join('') + moves.join(' ');\n }\n // TODO (jah): huh?\n const strip = function () {\n if (result.length > 0 && result[result.length - 1] === ' ') {\n result.pop();\n return true;\n }\n return false;\n };\n // NB: this does not preserve comment whitespace.\n const wrapComment = function (width, move) {\n for (const token of move.split(' ')) {\n if (!token) {\n continue;\n }\n if (width + token.length > maxWidth) {\n while (strip()) {\n width--;\n }\n result.push(newline);\n width = 0;\n }\n result.push(token);\n width += token.length;\n result.push(' ');\n width++;\n }\n if (strip()) {\n width--;\n }\n return width;\n };\n // wrap the PGN output at max_width\n let currentWidth = 0;\n for (let i = 0; i < moves.length; i++) {\n if (currentWidth + moves[i].length > maxWidth) {\n if (moves[i].includes('{')) {\n currentWidth = wrapComment(currentWidth, moves[i]);\n continue;\n }\n }\n // if the current move will push past max_width\n if (currentWidth + moves[i].length > maxWidth && i !== 0) {\n // don't end the line with whitespace\n if (result[result.length - 1] === ' ') {\n result.pop();\n }\n result.push(newline);\n currentWidth = 0;\n }\n else if (i !== 0) {\n result.push(' ');\n currentWidth++;\n }\n result.push(moves[i]);\n currentWidth += moves[i].length;\n }\n return result.join('');\n }\n /*\n * @deprecated Use `setHeader` and `getHeaders` instead.\n */\n header(...args) {\n for (let i = 0; i < args.length; i += 2) {\n if (typeof args[i] === 'string' && typeof args[i + 1] === 'string') {\n this._header[args[i]] = args[i + 1];\n }\n }\n return this._header;\n }\n setHeader(key, value) {\n this._header[key] = value;\n return this._header;\n }\n removeHeader(key) {\n if (key in this._header) {\n delete this._header[key];\n return true;\n }\n return false;\n }\n getHeaders() {\n return this._header;\n }\n loadPgn(pgn, { strict = false, newlineChar = '\\r?\\n', } = {}) {\n function mask(str) {\n return str.replace(/\\\\/g, '\\\\');\n }\n function parsePgnHeader(header) {\n const headerObj = {};\n const headers = header.split(new RegExp(mask(newlineChar)));\n let key = '';\n let value = '';\n for (let i = 0; i < headers.length; i++) {\n const regex = /^\\s*\\[\\s*([A-Za-z]+)\\s*\"(.*)\"\\s*\\]\\s*$/;\n key = headers[i].replace(regex, '$1');\n value = headers[i].replace(regex, '$2');\n if (key.trim().length > 0) {\n headerObj[key] = value;\n }\n }\n return headerObj;\n }\n // strip whitespace from head/tail of PGN block\n pgn = pgn.trim();\n /*\n * RegExp to split header. Takes advantage of the fact that header and movetext\n * will always have a blank line between them (ie, two newline_char's). Handles\n * case where movetext is empty by matching newlineChar until end of string is\n * matched - effectively trimming from the end extra newlineChar.\n *\n * With default newline_char, will equal:\n * /^(\\[((?:\\r?\\n)|.)*\\])((?:\\s*\\r?\\n){2}|(?:\\s*\\r?\\n)*$)/\n */\n const headerRegex = new RegExp('^(\\\\[((?:' +\n mask(newlineChar) +\n ')|.)*\\\\])' +\n '((?:\\\\s*' +\n mask(newlineChar) +\n '){2}|(?:\\\\s*' +\n mask(newlineChar) +\n ')*$)');\n // If no header given, begin with moves.\n const headerRegexResults = headerRegex.exec(pgn);\n const headerString = headerRegexResults\n ? headerRegexResults.length >= 2\n ? headerRegexResults[1]\n : ''\n : '';\n // Put the board in the starting position\n this.reset();\n // parse PGN header\n const headers = parsePgnHeader(headerString);\n let fen = '';\n for (const key in headers) {\n // check to see user is including fen (possibly with wrong tag case)\n if (key.toLowerCase() === 'fen') {\n fen = headers[key];\n }\n this.header(key, headers[key]);\n }\n /*\n * the permissive parser should attempt to load a fen tag, even if it's the\n * wrong case and doesn't include a corresponding [SetUp \"1\"] tag\n */\n if (!strict) {\n if (fen) {\n this.load(fen, { preserveHeaders: true });\n }\n }\n else {\n /*\n * strict parser - load the starting position indicated by [Setup '1']\n * and [FEN position]\n */\n if (headers['SetUp'] === '1') {\n if (!('FEN' in headers)) {\n throw new Error('Invalid PGN: FEN tag must be supplied with SetUp tag');\n }\n // don't clear the headers when loading\n this.load(headers['FEN'], { preserveHeaders: true });\n }\n }\n /*\n * NB: the regexes below that delete move numbers, recursive annotations,\n * and numeric annotation glyphs may also match text in comments. To\n * prevent this, we transform comments by hex-encoding them in place and\n * decoding them again after the other tokens have been deleted.\n *\n * While the spec states that PGN files should be ASCII encoded, we use\n * {en,de}codeURIComponent here to support arbitrary UTF8 as a convenience\n * for modern users\n */\n function toHex(s) {\n return Array.from(s)\n .map(function (c) {\n /*\n * encodeURI doesn't transform most ASCII characters, so we handle\n * these ourselves\n */\n return c.charCodeAt(0) < 128\n ? c.charCodeAt(0).toString(16)\n : encodeURIComponent(c).replace(/%/g, '').toLowerCase();\n })\n .join('');\n }\n function fromHex(s) {\n return s.length == 0\n ? ''\n : decodeURIComponent('%' + (s.match(/.{1,2}/g) || []).join('%'));\n }\n const encodeComment = function (s) {\n s = s.replace(new RegExp(mask(newlineChar), 'g'), ' ');\n return `{${toHex(s.slice(1, s.length - 1))}}`;\n };\n const decodeComment = function (s) {\n if (s.startsWith('{') && s.endsWith('}')) {\n return fromHex(s.slice(1, s.length - 1));\n }\n };\n // delete header to get the moves\n let ms = pgn\n .replace(headerString, '')\n .replace(\n // encode comments so they don't get deleted below\n new RegExp(`({[^}]*})+?|;([^${mask(newlineChar)}]*)`, 'g'), function (_match, bracket, semicolon) {\n return bracket !== undefined\n ? encodeComment(bracket)\n : ' ' + encodeComment(`{${semicolon.slice(1)}}`);\n })\n .replace(new RegExp(mask(newlineChar), 'g'), ' ');\n // delete recursive annotation variations\n const ravRegex = /(\\([^()]+\\))+?/g;\n while (ravRegex.test(ms)) {\n ms = ms.replace(ravRegex, '');\n }\n // delete move numbers\n ms = ms.replace(/\\d+\\.(\\.\\.)?/g, '');\n // delete ... indicating black to move\n ms = ms.replace(/\\.\\.\\./g, '');\n /* delete numeric annotation glyphs */\n ms = ms.replace(/\\$\\d+/g, '');\n // trim and get array of moves\n let moves = ms.trim().split(new RegExp(/\\s+/));\n // delete empty entries\n moves = moves.filter((move) => move !== '');\n let result = '';\n for (let halfMove = 0; halfMove < moves.length; halfMove++) {\n const comment = decodeComment(moves[halfMove]);\n if (comment !== undefined) {\n this._comments[this.fen()] = comment;\n continue;\n }\n const move = this._moveFromSan(moves[halfMove], strict);\n // invalid move\n if (move == null) {\n // was the move an end of game marker\n if (TERMINATION_MARKERS.indexOf(moves[halfMove]) > -1) {\n result = moves[halfMove];\n }\n else {\n throw new Error(`Invalid move in PGN: ${moves[halfMove]}`);\n }\n }\n else {\n // reset the end of game marker if making a valid move\n result = '';\n this._makeMove(move);\n this._incPositionCount(this.fen());\n }\n }\n /*\n * Per section 8.2.6 of the PGN spec, the Result tag pair must match match\n * the termination marker. Only do this when headers are present, but the\n * result tag is missing\n */\n if (result && Object.keys(this._header).length && !this._header['Result']) {\n this.header('Result', result);\n }\n }\n /*\n * Convert a move from 0x88 coordinates to Standard Algebraic Notation\n * (SAN)\n *\n * @param {boolean} strict Use the strict SAN parser. It will throw errors\n * on overly disambiguated moves (see below):\n *\n * r1bqkbnr/ppp2ppp/2n5/1B1pP3/4P3/8/PPPP2PP/RNBQK1NR b KQkq - 2 4\n * 4. ... Nge7 is overly disambiguated because the knight on c6 is pinned\n * 4. ... Ne7 is technically the valid SAN\n */\n _moveToSan(move, moves) {\n let output = '';\n if (move.flags & BITS.KSIDE_CASTLE) {\n output = 'O-O';\n }\n else if (move.flags & BITS.QSIDE_CASTLE) {\n output = 'O-O-O';\n }\n else {\n if (move.piece !== PAWN) {\n const disambiguator = getDisambiguator(move, moves);\n output += move.piece.toUpperCase() + disambiguator;\n }\n if (move.flags & (BITS.CAPTURE | BITS.EP_CAPTURE)) {\n if (move.piece === PAWN) {\n output += algebraic(move.from)[0];\n }\n output += 'x';\n }\n output += algebraic(move.to);\n if (move.promotion) {\n output += '=' + move.promotion.toUpperCase();\n }\n }\n this._makeMove(move);\n if (this.isCheck()) {\n if (this.isCheckmate()) {\n output += '#';\n }\n else {\n output += '+';\n }\n }\n this._undoMove();\n return output;\n }\n // convert a move from Standard Algebraic Notation (SAN) to 0x88 coordinates\n _moveFromSan(move, strict = false) {\n // strip off any move decorations: e.g Nf3+?! becomes Nf3\n const cleanMove = strippedSan(move);\n let pieceType = inferPieceType(cleanMove);\n let moves = this._moves({ legal: true, piece: pieceType });\n // strict parser\n for (let i = 0, len = moves.length; i < len; i++) {\n if (cleanMove === strippedSan(this._moveToSan(moves[i], moves))) {\n return moves[i];\n }\n }\n // the strict parser failed\n if (strict) {\n return null;\n }\n let piece = undefined;\n let matches = undefined;\n let from = undefined;\n let to = undefined;\n let promotion = undefined;\n /*\n * The default permissive (non-strict) parser allows the user to parse\n * non-standard chess notations. This parser is only run after the strict\n * Standard Algebraic Notation (SAN) parser has failed.\n *\n * When running the permissive parser, we'll run a regex to grab the piece, the\n * to/from square, and an optional promotion piece. This regex will\n * parse common non-standard notation like: Pe2-e4, Rc1c4, Qf3xf7,\n * f7f8q, b1c3\n *\n * NOTE: Some positions and moves may be ambiguous when using the permissive\n * parser. For example, in this position: 6k1/8/8/B7/8/8/8/BN4K1 w - - 0 1,\n * the move b1c3 may be interpreted as Nc3 or B1c3 (a disambiguated bishop\n * move). In these cases, the permissive parser will default to the most\n * basic interpretation (which is b1c3 parsing to Nc3).\n */\n let overlyDisambiguated = false;\n matches = cleanMove.match(/([pnbrqkPNBRQK])?([a-h][1-8])x?-?([a-h][1-8])([qrbnQRBN])?/);\n if (matches) {\n piece = matches[1];\n from = matches[2];\n to = matches[3];\n promotion = matches[4];\n if (from.length == 1) {\n overlyDisambiguated = true;\n }\n }\n else {\n /*\n * The [a-h]?[1-8]? portion of the regex below handles moves that may be\n * overly disambiguated (e.g. Nge7 is unnecessary and non-standard when\n * there is one legal knight move to e7). In this case, the value of\n * 'from' variable will be a rank or file, not a square.\n */\n matches = cleanMove.match(/([pnbrqkPNBRQK])?([a-h]?[1-8]?)x?-?([a-h][1-8])([qrbnQRBN])?/);\n if (matches) {\n piece = matches[1];\n from = matches[2];\n to = matches[3];\n promotion = matches[4];\n if (from.length == 1) {\n overlyDisambiguated = true;\n }\n }\n }\n pieceType = inferPieceType(cleanMove);\n moves = this._moves({\n legal: true,\n piece: piece ? piece : pieceType,\n });\n if (!to) {\n return null;\n }\n for (let i = 0, len = moves.length; i < len; i++) {\n if (!from) {\n // if there is no from square, it could be just 'x' missing from a capture\n if (cleanMove ===\n strippedSan(this._moveToSan(moves[i], moves)).replace('x', '')) {\n return moves[i];\n }\n // hand-compare move properties with the results from our permissive regex\n }\n else if ((!piece || piece.toLowerCase() == moves[i].piece) &&\n Ox88[from] == moves[i].from &&\n Ox88[to] == moves[i].to &&\n (!promotion || promotion.toLowerCase() == moves[i].promotion)) {\n return moves[i];\n }\n else if (overlyDisambiguated) {\n /*\n * SPECIAL CASE: we parsed a move string that may have an unneeded\n * rank/file disambiguator (e.g. Nge7). The 'from' variable will\n */\n const square = algebraic(moves[i].from);\n if ((!piece || piece.toLowerCase() == moves[i].piece) &&\n Ox88[to] == moves[i].to &&\n (from == square[0] || from == square[1]) &&\n (!promotion || promotion.toLowerCase() == moves[i].promotion)) {\n return moves[i];\n }\n }\n }\n return null;\n }\n ascii() {\n let s = ' +------------------------+\\n';\n for (let i = Ox88.a8; i <= Ox88.h1; i++) {\n // display the rank\n if (file(i) === 0) {\n s += ' ' + '87654321'[rank(i)] + ' |';\n }\n if (this._board[i]) {\n const piece = this._board[i].type;\n const color = this._board[i].color;\n const symbol = color === WHITE ? piece.toUpperCase() : piece.toLowerCase();\n s += ' ' + symbol + ' ';\n }\n else {\n s += ' . ';\n }\n if ((i + 1) & 0x88) {\n s += '|\\n';\n i += 8;\n }\n }\n s += ' +------------------------+\\n';\n s += ' a b c d e f g h';\n return s;\n }\n perft(depth) {\n const moves = this._moves({ legal: false });\n let nodes = 0;\n const color = this._turn;\n for (let i = 0, len = moves.length; i < len; i++) {\n this._makeMove(moves[i]);\n if (!this._isKingAttacked(color)) {\n if (depth - 1 > 0) {\n nodes += this.perft(depth - 1);\n }\n else {\n nodes++;\n }\n }\n this._undoMove();\n }\n return nodes;\n }\n turn() {\n return this._turn;\n }\n board() {\n const output = [];\n let row = [];\n for (let i = Ox88.a8; i <= Ox88.h1; i++) {\n if (this._board[i] == null) {\n row.push(null);\n }\n else {\n row.push({\n square: algebraic(i),\n type: this._board[i].type,\n color: this._board[i].color,\n });\n }\n if ((i + 1) & 0x88) {\n output.push(row);\n row = [];\n i += 8;\n }\n }\n return output;\n }\n squareColor(square) {\n if (square in Ox88) {\n const sq = Ox88[square];\n return (rank(sq) + file(sq)) % 2 === 0 ? 'light' : 'dark';\n }\n return null;\n }\n history({ verbose = false } = {}) {\n const reversedHistory = [];\n const moveHistory = [];\n while (this._history.length > 0) {\n reversedHistory.push(this._undoMove());\n }\n while (true) {\n const move = reversedHistory.pop();\n if (!move) {\n break;\n }\n if (verbose) {\n moveHistory.push(new Move(this, move));\n }\n else {\n moveHistory.push(this._moveToSan(move, this._moves()));\n }\n this._makeMove(move);\n }\n return moveHistory;\n }\n /*\n * Keeps track of position occurrence counts for the purpose of repetition\n * checking. All three methods (`_inc`, `_dec`, and `_get`) trim the\n * irrelevent information from the fen, initialising new positions, and\n * removing old positions from the record if their counts are reduced to 0.\n */\n _getPositionCount(fen) {\n const trimmedFen = trimFen(fen);\n return this._positionCount[trimmedFen] || 0;\n }\n _incPositionCount(fen) {\n const trimmedFen = trimFen(fen);\n if (this._positionCount[trimmedFen] === undefined) {\n this._positionCount[trimmedFen] = 0;\n }\n this._positionCount[trimmedFen] += 1;\n }\n _decPositionCount(fen) {\n const trimmedFen = trimFen(fen);\n if (this._positionCount[trimmedFen] === 1) {\n delete this._positionCount[trimmedFen];\n }\n else {\n this._positionCount[trimmedFen] -= 1;\n }\n }\n _pruneComments() {\n const reversedHistory = [];\n const currentComments = {};\n const copyComment = (fen) => {\n if (fen in this._comments) {\n currentComments[fen] = this._comments[fen];\n }\n };\n while (this._history.length > 0) {\n reversedHistory.push(this._undoMove());\n }\n copyComment(this.fen());\n while (true) {\n const move = reversedHistory.pop();\n if (!move) {\n break;\n }\n this._makeMove(move);\n copyComment(this.fen());\n }\n this._comments = currentComments;\n }\n getComment() {\n return this._comments[this.fen()];\n }\n setComment(comment) {\n this._comments[this.fen()] = comment.replace('{', '[').replace('}', ']');\n }\n /**\n * @deprecated Renamed to `removeComment` for consistency\n */\n deleteComment() {\n return this.removeComment();\n }\n removeComment() {\n const comment = this._comments[this.fen()];\n delete this._comments[this.fen()];\n return comment;\n }\n getComments() {\n this._pruneComments();\n return Object.keys(this._comments).map((fen) => {\n return { fen: fen, comment: this._comments[fen] };\n });\n }\n /**\n * @deprecated Renamed to `removeComments` for consistency\n */\n deleteComments() {\n return this.removeComments();\n }\n removeComments() {\n this._pruneComments();\n return Object.keys(this._comments).map((fen) => {\n const comment = this._comments[fen];\n delete this._comments[fen];\n return { fen: fen, comment: comment };\n });\n }\n setCastlingRights(color, rights) {\n for (const side of [KING, QUEEN]) {\n if (rights[side] !== undefined) {\n if (rights[side]) {\n this._castling[color] |= SIDES[side];\n }\n else {\n this._castling[color] &= ~SIDES[side];\n }\n }\n }\n this._updateCastlingRights();\n const result = this.getCastlingRights(color);\n return ((rights[KING] === undefined || rights[KING] === result[KING]) &&\n (rights[QUEEN] === undefined || rights[QUEEN] === result[QUEEN]));\n }\n getCastlingRights(color) {\n return {\n [KING]: (this._castling[color] & SIDES[KING]) !== 0,\n [QUEEN]: (this._castling[color] & SIDES[QUEEN]) !== 0,\n };\n }\n moveNumber() {\n return this._moveNumber;\n }\n}\n//# sourceMappingURL=chess.js.map","import { onUnmounted, Ref, watch } from 'vue';\nimport type { Api as CgAPI } from '../chessground/api';\n\n/**\n * Keep Chessground's cached board bounds in sync with the actual DOM.\n *\n * Chessground caches `getBoundingClientRect()` on the board element at\n * mount/redraw and uses it to translate pointer coordinates to squares.\n * If the surrounding layout shifts the board after mount — for example,\n * a flex-centered transition container in StudySession, font-load\n * reflow, or a parent that toggles visibility — the cached rect goes\n * stale and clicks land on the wrong squares.\n *\n * This composable:\n * 1. Forces a `redrawAll()` on the next animation frame after the\n * Chessground API becomes available, catching the initial mount\n * race against parent layout settling.\n * 2. Observes the board element with a ResizeObserver and triggers\n * `redrawAll()` on any subsequent size change.\n *\n * Pass a ref to the board element and a ref to the Chessground API.\n * Cleanup is handled via `onUnmounted`.\n */\nexport function useChessgroundBounds(\n boardEl: Ref<HTMLElement | null | undefined>,\n api: Ref<CgAPI | undefined>\n): void {\n let ro: ResizeObserver | null = null;\n\n const stop = watch(\n () => api.value,\n (cg) => {\n if (!cg || !boardEl.value) return;\n\n // Initial post-mount sync: parent flex/transition layout may\n // settle one frame after Chessground reads its bounding rect.\n requestAnimationFrame(() => cg.redrawAll());\n\n ro = new ResizeObserver(() => cg.redrawAll());\n ro.observe(boardEl.value);\n\n stop();\n },\n { immediate: true }\n );\n\n onUnmounted(() => {\n ro?.disconnect();\n ro = null;\n });\n}\n","<template>\n <!-- Template remains largely the same -->\n <div data-viewable=\"PuzzleView\">\n <p class=\"text-h5\">\n Make the best move for {{ playerColor === 'cg-white' ? 'White ♖♘♗♕♔♗♘♖' : 'Black ♜♞♝♚♛♝♞♜' }}:\n </p>\n <div class=\"puzzle-board-wrapper\">\n <div class=\"puzzle-ranks-labels\">\n <div v-for=\"rank in 8\" :key=\"rank\">{{ playerColor === 'cg-white' ? 9 - rank : rank }}</div>\n </div>\n <div class=\"puzzle-board-and-files\">\n <div id=\"cg\" ref=\"boardElement\"></div>\n <div class=\"puzzle-files-labels\">\n <div v-for=\"file in files\" :key=\"file\">{{ file }}</div>\n </div>\n </div>\n </div>\n <div v-if=\"showPromotionDialog\" class=\"puzzle-promotion-dialog\">\n <button v-for=\"piece in promotionPieces\" :key=\"piece.value\" @click=\"handlePromotion(piece.value)\">\n {{ playerColor === 'cg-white' ? piece.whiteSymbol : piece.blackSymbol }}\n {{ piece.name }}\n </button>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, ref, computed, onMounted, onUnmounted, PropType } from 'vue';\nimport { Chessground } from '../../chessground/chessground';\nimport { Key } from '../../chessground/types';\nimport { Api as cgAPI } from '../../chessground/api';\nimport { useViewable, useQuestionView } from '@vue-skuilder/common-ui';\nimport { ChessPuzzle } from './index';\nimport { Chess, SQUARES } from 'chess.js';\nimport { ViewData } from '@vue-skuilder/common';\nimport { useChessgroundBounds } from '../../composables/useChessgroundBounds';\n\n// Types and interfaces\ntype PromotionPiece = 'q' | 'r' | 'b' | 'n';\ntype Color = 'cg-white' | 'cg-black';\n\ninterface UciMove {\n from: string;\n to: string;\n promotion?: PromotionPiece;\n}\n\n// Helper functions (moved outside component)\nconst parseUciMove = (moveString: string): UciMove => {\n if (moveString.length < 4 || moveString.length > 5) {\n throw new Error(`Invalid UCI move format: ${moveString}`);\n }\n\n return {\n from: moveString.substring(0, 2),\n to: moveString.substring(2, 4),\n promotion: moveString.length === 5 ? (moveString[4] as PromotionPiece) : undefined,\n };\n};\n\nconst toDests = (chess: Chess) => {\n const dests = new Map();\n SQUARES.forEach((s) => {\n const ms = chess.moves({ square: s, verbose: true });\n if (ms.length)\n dests.set(\n s,\n ms.map((m) => m.to)\n );\n });\n return dests;\n};\n\nconst swapColor = (color: Color): Color => (color === 'cg-white' ? 'cg-black' : 'cg-white');\n\nconst toColor = (chess: Chess): Color => (chess.turn() === 'w' ? 'cg-white' : 'cg-black');\n\n// Chess puzzle component\nexport default defineComponent({\n name: 'PuzzleView',\n\n props: {\n data: {\n type: Array as PropType<ViewData[]>,\n required: true,\n },\n modifyDifficulty: {\n type: Number,\n required: false,\n default: 0,\n },\n },\n\n setup(props, { emit }) {\n // Initialize base utilities\n const viewableUtils = useViewable(props, emit, 'PuzzleView');\n const questionUtils = useQuestionView<ChessPuzzle>(viewableUtils);\n\n // State\n const boardElement = ref<HTMLElement | null>(null);\n const chessEngine = ref<Chess>();\n const chessBoard = ref<cgAPI>();\n const playerColor = ref<Color>('cg-white');\n const showPromotionDialog = ref(false);\n const promotionMove = ref<{ from: string; to: string } | null>(null);\n\n const ANIM_DELAY = 300;\n\n // Keep Chessground's cached board bounds in sync with the DOM —\n // StudySession's flex-centered transition container can shift the\n // board after Chessground reads its rect at mount, which leaves\n // click hitboxes offset from the rendered squares until a resize.\n useChessgroundBounds(boardElement, chessBoard);\n\n const promotionPieces = [\n { value: 'q', name: 'Queen', whiteSymbol: '♕', blackSymbol: '♛' },\n { value: 'r', name: 'Rook', whiteSymbol: '♖', blackSymbol: '♜' },\n { value: 'b', name: 'Bishop', whiteSymbol: '♗', blackSymbol: '♝' },\n { value: 'n', name: 'Knight', whiteSymbol: '♘', blackSymbol: '♞' },\n ];\n\n // Computed\n const files = computed(() => {\n const filesList = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];\n return playerColor.value === 'cg-white' ? filesList : filesList.reverse();\n });\n\n // Methods\n const isPromotionPiece = (p?: string): p is PromotionPiece => {\n if (!p) return false;\n return ['q', 'r', 'b', 'n'].includes(p);\n };\n\n const isUnfinishedPromotion = (from: string, to: string, promotionPiece?: PromotionPiece) => {\n if (isPromotionPiece(promotionPiece)) return false;\n // [ ] typing\n // @ts-expect-error - `from` is well-formed\n const piece = chessEngine.value?.get(from);\n return piece?.type === 'p' && (to[1] === '8' || to[1] === '1');\n };\n\n const updateChessground = () => {\n if (!chessEngine.value || !chessBoard.value) return;\n\n chessBoard.value.set({\n fen: chessEngine.value.fen(),\n turnColor: toColor(chessEngine.value),\n movable: {\n color: toColor(chessEngine.value),\n dests: toDests(chessEngine.value),\n },\n });\n };\n\n const handlePromotion = (promotionPiece: PromotionPiece | string) => {\n if (promotionPiece !== 'q' && promotionPiece !== 'r' && promotionPiece !== 'b' && promotionPiece !== 'n') {\n viewableUtils.logger.error(`Invalid promotion piece: ${promotionPiece}`);\n return;\n }\n if (!promotionMove.value) return;\n\n viewableUtils.logger.log(`promoting to ${promotionPiece}`);\n showPromotionDialog.value = false;\n checkMove(promotionMove.value.from, promotionMove.value.to, promotionPiece);\n };\n\n const checkMove = (orig: string, dest: string, promotionPiece?: PromotionPiece) => {\n if (!questionUtils.question.value?.moves.length) {\n throw new Error('No moves');\n }\n\n if (isUnfinishedPromotion(orig, dest, promotionPiece)) {\n promotionMove.value = { from: orig, to: dest };\n showPromotionDialog.value = true;\n return;\n }\n\n const expectedMove = questionUtils.question.value.moves[0];\n const moveMade = isPromotionPiece(promotionPiece) ? `${orig}${dest}${promotionPiece}` : `${orig}${dest}`;\n\n if (expectedMove === moveMade) {\n chessEngine.value?.move({\n from: orig,\n to: dest,\n promotion: isPromotionPiece(promotionPiece) ? promotionPiece : undefined,\n });\n updateChessground();\n\n questionUtils.question.value.moves.shift();\n\n if (questionUtils.question.value.moves.length === 0) {\n questionUtils.submitAnswer('');\n } else {\n window.setTimeout(() => {\n if (!questionUtils.question.value) return;\n\n const nextMove = questionUtils.question.value.moves.shift()!;\n const move = parseUciMove(nextMove);\n chessEngine.value?.move(move);\n updateChessground();\n }, ANIM_DELAY);\n }\n } else {\n // Handle incorrect move\n chessEngine.value?.move({ from: orig, to: dest, promotion: promotionPiece });\n if (chessEngine.value?.isCheckmate()) {\n questionUtils.submitAnswer(ChessPuzzle.CHECKMATE);\n } else {\n chessEngine.value?.undo();\n }\n\n questionUtils.submitAnswer(orig + dest + promotionPiece);\n updateChessground();\n }\n };\n\n // Initialization\n onMounted(() => {\n if (!boardElement.value) return;\n\n questionUtils.question.value = new ChessPuzzle(props.data);\n chessEngine.value = new Chess(questionUtils.question.value.fen);\n playerColor.value = swapColor(toColor(chessEngine.value));\n\n chessBoard.value = Chessground(boardElement.value, {\n movable: {\n free: false,\n showDests: true,\n dests: toDests(chessEngine.value),\n events: {\n // [ ] typing\n // @ts-expect-error - `orig` and `dest` are well-formed\n after: checkMove,\n },\n },\n draggable: {\n showGhost: true,\n },\n fen: chessEngine.value.fen(),\n orientation: playerColor.value,\n coordinates: false,\n animation: {\n duration: ANIM_DELAY,\n enabled: true,\n },\n });\n\n // Make first move\n const firstMove = questionUtils.question.value.moves.shift()!;\n chessBoard.value.move(firstMove.substring(0, 2) as Key, firstMove.substring(2) as Key);\n chessEngine.value.move({\n from: firstMove.substring(0, 2),\n to: firstMove.substring(2),\n });\n updateChessground();\n });\n\n onUnmounted(() => {\n chessBoard.value?.destroy();\n chessEngine.value = undefined;\n });\n\n return {\n boardElement,\n playerColor,\n files,\n showPromotionDialog,\n promotionPieces,\n handlePromotion,\n ...viewableUtils,\n ...questionUtils,\n };\n },\n});\n</script>\n\n<style>\n@import '../../chessground/css/chessground.base.css';\n@import '../../chessground/css/chessground.brown.css';\n@import '../../chessground/css/chessground.cburnett.css';\n\n.puzzle-promotion-dialog {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n background: rgba(255, 255, 255, 0.95);\n padding: 15px;\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);\n z-index: 1000;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.puzzle-promotion-dialog button {\n padding: 10px 20px;\n font-size: 16px;\n border: none;\n background: #f0f0f0;\n border-radius: 4px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n width: 150px;\n}\n\n.puzzle-promotion-dialog button:hover {\n background: #e0e0e0;\n}\n\n/* Optional: Add piece symbols next to text */\n.puzzle-promotion-dialog button::before {\n content: attr(data-piece);\n font-size: 24px;\n}\n\n.puzzle-board-wrapper {\n display: flex;\n align-items: center;\n width: 440px;\n}\n\n.puzzle-ranks-labels {\n display: flex;\n flex-direction: column;\n justify-content: center;\n /* width: 0px; */\n height: 400px;\n margin-right: 10px;\n}\n\n.puzzle-ranks-labels.reversed {\n flex-direction: column-reverse;\n}\n\n.puzzle-ranks-labels div {\n height: 50px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.puzzle-board-and-files {\n display: flex;\n flex-direction: column;\n}\n\n.puzzle-files-labels {\n display: flex;\n justify-content: center;\n height: 20px;\n}\n\n.puzzle-files-labels.reversed {\n flex-direction: row-reverse;\n}\n\n.puzzle-files-labels div {\n width: 50px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n#cg {\n width: 400px;\n height: 400px;\n}\n</style>\n","<template>\n <!-- Template remains largely the same -->\n <div data-viewable=\"PuzzleView\">\n <p class=\"text-h5\">\n Make the best move for {{ playerColor === 'cg-white' ? 'White ♖♘♗♕♔♗♘♖' : 'Black ♜♞♝♚♛♝♞♜' }}:\n </p>\n <div class=\"puzzle-board-wrapper\">\n <div class=\"puzzle-ranks-labels\">\n <div v-for=\"rank in 8\" :key=\"rank\">{{ playerColor === 'cg-white' ? 9 - rank : rank }}</div>\n </div>\n <div class=\"puzzle-board-and-files\">\n <div id=\"cg\" ref=\"boardElement\"></div>\n <div class=\"puzzle-files-labels\">\n <div v-for=\"file in files\" :key=\"file\">{{ file }}</div>\n </div>\n </div>\n </div>\n <div v-if=\"showPromotionDialog\" class=\"puzzle-promotion-dialog\">\n <button v-for=\"piece in promotionPieces\" :key=\"piece.value\" @click=\"handlePromotion(piece.value)\">\n {{ playerColor === 'cg-white' ? piece.whiteSymbol : piece.blackSymbol }}\n {{ piece.name }}\n </button>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, ref, computed, onMounted, onUnmounted, PropType } from 'vue';\nimport { Chessground } from '../../chessground/chessground';\nimport { Key } from '../../chessground/types';\nimport { Api as cgAPI } from '../../chessground/api';\nimport { useViewable, useQuestionView } from '@vue-skuilder/common-ui';\nimport { ChessPuzzle } from './index';\nimport { Chess, SQUARES } from 'chess.js';\nimport { ViewData } from '@vue-skuilder/common';\nimport { useChessgroundBounds } from '../../composables/useChessgroundBounds';\n\n// Types and interfaces\ntype PromotionPiece = 'q' | 'r' | 'b' | 'n';\ntype Color = 'cg-white' | 'cg-black';\n\ninterface UciMove {\n from: string;\n to: string;\n promotion?: PromotionPiece;\n}\n\n// Helper functions (moved outside component)\nconst parseUciMove = (moveString: string): UciMove => {\n if (moveString.length < 4 || moveString.length > 5) {\n throw new Error(`Invalid UCI move format: ${moveString}`);\n }\n\n return {\n from: moveString.substring(0, 2),\n to: moveString.substring(2, 4),\n promotion: moveString.length === 5 ? (moveString[4] as PromotionPiece) : undefined,\n };\n};\n\nconst toDests = (chess: Chess) => {\n const dests = new Map();\n SQUARES.forEach((s) => {\n const ms = chess.moves({ square: s, verbose: true });\n if (ms.length)\n dests.set(\n s,\n ms.map((m) => m.to)\n );\n });\n return dests;\n};\n\nconst swapColor = (color: Color): Color => (color === 'cg-white' ? 'cg-black' : 'cg-white');\n\nconst toColor = (chess: Chess): Color => (chess.turn() === 'w' ? 'cg-white' : 'cg-black');\n\n// Chess puzzle component\nexport default defineComponent({\n name: 'PuzzleView',\n\n props: {\n data: {\n type: Array as PropType<ViewData[]>,\n required: true,\n },\n modifyDifficulty: {\n type: Number,\n required: false,\n default: 0,\n },\n },\n\n setup(props, { emit }) {\n // Initialize base utilities\n const viewableUtils = useViewable(props, emit, 'PuzzleView');\n const questionUtils = useQuestionView<ChessPuzzle>(viewableUtils);\n\n // State\n const boardElement = ref<HTMLElement | null>(null);\n const chessEngine = ref<Chess>();\n const chessBoard = ref<cgAPI>();\n const playerColor = ref<Color>('cg-white');\n const showPromotionDialog = ref(false);\n const promotionMove = ref<{ from: string; to: string } | null>(null);\n\n const ANIM_DELAY = 300;\n\n // Keep Chessground's cached board bounds in sync with the DOM —\n // StudySession's flex-centered transition container can shift the\n // board after Chessground reads its rect at mount, which leaves\n // click hitboxes offset from the rendered squares until a resize.\n useChessgroundBounds(boardElement, chessBoard);\n\n const promotionPieces = [\n { value: 'q', name: 'Queen', whiteSymbol: '♕', blackSymbol: '♛' },\n { value: 'r', name: 'Rook', whiteSymbol: '♖', blackSymbol: '♜' },\n { value: 'b', name: 'Bishop', whiteSymbol: '♗', blackSymbol: '♝' },\n { value: 'n', name: 'Knight', whiteSymbol: '♘', blackSymbol: '♞' },\n ];\n\n // Computed\n const files = computed(() => {\n const filesList = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];\n return playerColor.value === 'cg-white' ? filesList : filesList.reverse();\n });\n\n // Methods\n const isPromotionPiece = (p?: string): p is PromotionPiece => {\n if (!p) return false;\n return ['q', 'r', 'b', 'n'].includes(p);\n };\n\n const isUnfinishedPromotion = (from: string, to: string, promotionPiece?: PromotionPiece) => {\n if (isPromotionPiece(promotionPiece)) return false;\n // [ ] typing\n // @ts-expect-error - `from` is well-formed\n const piece = chessEngine.value?.get(from);\n return piece?.type === 'p' && (to[1] === '8' || to[1] === '1');\n };\n\n const updateChessground = () => {\n if (!chessEngine.value || !chessBoard.value) return;\n\n chessBoard.value.set({\n fen: chessEngine.value.fen(),\n turnColor: toColor(chessEngine.value),\n movable: {\n color: toColor(chessEngine.value),\n dests: toDests(chessEngine.value),\n },\n });\n };\n\n const handlePromotion = (promotionPiece: PromotionPiece | string) => {\n if (promotionPiece !== 'q' && promotionPiece !== 'r' && promotionPiece !== 'b' && promotionPiece !== 'n') {\n viewableUtils.logger.error(`Invalid promotion piece: ${promotionPiece}`);\n return;\n }\n if (!promotionMove.value) return;\n\n viewableUtils.logger.log(`promoting to ${promotionPiece}`);\n showPromotionDialog.value = false;\n checkMove(promotionMove.value.from, promotionMove.value.to, promotionPiece);\n };\n\n const checkMove = (orig: string, dest: string, promotionPiece?: PromotionPiece) => {\n if (!questionUtils.question.value?.moves.length) {\n throw new Error('No moves');\n }\n\n if (isUnfinishedPromotion(orig, dest, promotionPiece)) {\n promotionMove.value = { from: orig, to: dest };\n showPromotionDialog.value = true;\n return;\n }\n\n const expectedMove = questionUtils.question.value.moves[0];\n const moveMade = isPromotionPiece(promotionPiece) ? `${orig}${dest}${promotionPiece}` : `${orig}${dest}`;\n\n if (expectedMove === moveMade) {\n chessEngine.value?.move({\n from: orig,\n to: dest,\n promotion: isPromotionPiece(promotionPiece) ? promotionPiece : undefined,\n });\n updateChessground();\n\n questionUtils.question.value.moves.shift();\n\n if (questionUtils.question.value.moves.length === 0) {\n questionUtils.submitAnswer('');\n } else {\n window.setTimeout(() => {\n if (!questionUtils.question.value) return;\n\n const nextMove = questionUtils.question.value.moves.shift()!;\n const move = parseUciMove(nextMove);\n chessEngine.value?.move(move);\n updateChessground();\n }, ANIM_DELAY);\n }\n } else {\n // Handle incorrect move\n chessEngine.value?.move({ from: orig, to: dest, promotion: promotionPiece });\n if (chessEngine.value?.isCheckmate()) {\n questionUtils.submitAnswer(ChessPuzzle.CHECKMATE);\n } else {\n chessEngine.value?.undo();\n }\n\n questionUtils.submitAnswer(orig + dest + promotionPiece);\n updateChessground();\n }\n };\n\n // Initialization\n onMounted(() => {\n if (!boardElement.value) return;\n\n questionUtils.question.value = new ChessPuzzle(props.data);\n chessEngine.value = new Chess(questionUtils.question.value.fen);\n playerColor.value = swapColor(toColor(chessEngine.value));\n\n chessBoard.value = Chessground(boardElement.value, {\n movable: {\n free: false,\n showDests: true,\n dests: toDests(chessEngine.value),\n events: {\n // [ ] typing\n // @ts-expect-error - `orig` and `dest` are well-formed\n after: checkMove,\n },\n },\n draggable: {\n showGhost: true,\n },\n fen: chessEngine.value.fen(),\n orientation: playerColor.value,\n coordinates: false,\n animation: {\n duration: ANIM_DELAY,\n enabled: true,\n },\n });\n\n // Make first move\n const firstMove = questionUtils.question.value.moves.shift()!;\n chessBoard.value.move(firstMove.substring(0, 2) as Key, firstMove.substring(2) as Key);\n chessEngine.value.move({\n from: firstMove.substring(0, 2),\n to: firstMove.substring(2),\n });\n updateChessground();\n });\n\n onUnmounted(() => {\n chessBoard.value?.destroy();\n chessEngine.value = undefined;\n });\n\n return {\n boardElement,\n playerColor,\n files,\n showPromotionDialog,\n promotionPieces,\n handlePromotion,\n ...viewableUtils,\n ...questionUtils,\n };\n },\n});\n</script>\n\n<style>\n@import '../../chessground/css/chessground.base.css';\n@import '../../chessground/css/chessground.brown.css';\n@import '../../chessground/css/chessground.cburnett.css';\n\n.puzzle-promotion-dialog {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n background: rgba(255, 255, 255, 0.95);\n padding: 15px;\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);\n z-index: 1000;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.puzzle-promotion-dialog button {\n padding: 10px 20px;\n font-size: 16px;\n border: none;\n background: #f0f0f0;\n border-radius: 4px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n width: 150px;\n}\n\n.puzzle-promotion-dialog button:hover {\n background: #e0e0e0;\n}\n\n/* Optional: Add piece symbols next to text */\n.puzzle-promotion-dialog button::before {\n content: attr(data-piece);\n font-size: 24px;\n}\n\n.puzzle-board-wrapper {\n display: flex;\n align-items: center;\n width: 440px;\n}\n\n.puzzle-ranks-labels {\n display: flex;\n flex-direction: column;\n justify-content: center;\n /* width: 0px; */\n height: 400px;\n margin-right: 10px;\n}\n\n.puzzle-ranks-labels.reversed {\n flex-direction: column-reverse;\n}\n\n.puzzle-ranks-labels div {\n height: 50px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.puzzle-board-and-files {\n display: flex;\n flex-direction: column;\n}\n\n.puzzle-files-labels {\n display: flex;\n justify-content: center;\n height: 20px;\n}\n\n.puzzle-files-labels.reversed {\n flex-direction: row-reverse;\n}\n\n.puzzle-files-labels div {\n width: 50px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n#cg {\n width: 400px;\n height: 400px;\n}\n</style>\n","import { Question, ViewComponent } from '@vue-skuilder/common-ui';\nimport {\n Answer,\n DataShape,\n ViewData,\n DataShapeName,\n Status,\n FieldType,\n} from '@vue-skuilder/common';\nimport PuzzleView from './puzzle.vue';\nimport { Key as cgKey } from '../../chessground/types';\n\nexport class ChessPuzzle extends Question {\n public static dataShapes: DataShape[] = [\n {\n name: DataShapeName.CHESS_puzzle,\n fields: [\n {\n name: 'puzzleData', // see https://database.lichess.org/#puzzles\n type: FieldType.CHESS_PUZZLE,\n validator: {\n instructions: 'insert a valid fen string',\n test: function (s: string) {\n console.log(`running puzzle validator on ${s}`);\n\n if (!s) {\n return {\n status: Status.error,\n msg: 'no defined input',\n };\n }\n\n const split = s.split(',');\n if (split.length < 10 || split.length > 11) {\n return {\n status: Status.error,\n msg: `puzzleData must have 10 or 11 comma-separated fields (got ${split.length})`,\n };\n } else {\n return {\n status: Status.ok,\n msg: '',\n };\n }\n },\n },\n tagger: () => {\n // [ ] not actually used\n return ['test'];\n },\n },\n ],\n },\n ];\n public static views: ViewComponent[] = [PuzzleView];\n public static acceptsUserData: boolean = true;\n\n public static readonly CHECKMATE = 'CHECKMATE';\n\n public fen: string;\n id: string;\n moves: string[];\n rating: number;\n themes: string[];\n\n constructor(data: ViewData[]) {\n super(data);\n\n const [id, fen, movesStr, rating, , , , themes] = (data[0].puzzleData as string).split(',');\n this.id = id;\n this.fen = fen;\n this.moves = movesStr.split(' ');\n this.rating = parseInt(rating, 10);\n this.themes = themes.split(' ');\n // this.fen = data[0].fen as string;\n }\n\n public checkMove = (orig: cgKey, dest: cgKey) => {\n alert('checkMove');\n console.log('checkMove', orig, dest);\n console.log('this.moves[0]', this.moves[0]);\n\n if (this.moves[0] === dest) {\n return true;\n } else {\n return false;\n }\n };\n\n evaluate(a: Answer, t: number) {\n return {\n isCorrect: this.isCorrect(a),\n performance: this.displayedSkill(a, t),\n };\n }\n displayedSkill(a: Answer, t: number) {\n if (this.isCorrect(a)) {\n if (t < 5000) {\n return 1;\n } else {\n // scale from 1 at t=5s to 0,5 at t>=15s\n return 1 - Math.min(1, (t - 5000) / 10000);\n }\n }\n\n return 0;\n }\n dataShapes() {\n return ChessPuzzle.dataShapes;\n }\n\n views(): Array<ViewComponent> {\n return ChessPuzzle.views;\n }\n\n isCorrect(a: Answer) {\n // player actions have exhausted the move tree\n const sequenceComplete = this.moves.length === 0;\n\n return a === ChessPuzzle.CHECKMATE || sequenceComplete;\n }\n}\n","import { CourseWare } from '../CourseWare';\nimport { ChessPuzzle } from './questions/puzzle';\n\nconst chess: CourseWare = new CourseWare('chess', [ChessPuzzle]);\n\nexport default chess;\n"],"x_google_ignoreList":[20],"mappings":"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"}
|