UNPKG

chessground-haichess

Version:
1,357 lines 285 kB
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Chessground = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.render = exports.anim = void 0; const util = require("./util"); function anim(mutation, state) { return state.animation.enabled ? animate(mutation, state) : render(mutation, state); } exports.anim = anim; function render(mutation, state) { const result = mutation(state); state.dom.redraw(); return result; } exports.render = render; function makePiece(key, piece) { return { key: key, pos: util.key2pos(key), piece: piece, }; } function closer(piece, pieces) { return pieces.sort((p1, p2) => { return util.distanceSq(piece.pos, p1.pos) - util.distanceSq(piece.pos, p2.pos); })[0]; } function computePlan(prevPieces, current) { const anims = new Map(), animedOrigs = [], fadings = new Map(), missings = [], news = [], prePieces = new Map(); let curP, preP, vector; for (const [k, p] of prevPieces) { prePieces.set(k, makePiece(k, p)); } for (const key of util.allKeys) { curP = current.pieces.get(key); preP = prePieces.get(key); if (curP) { if (preP) { if (!util.samePiece(curP, preP.piece)) { missings.push(preP); news.push(makePiece(key, curP)); } } else news.push(makePiece(key, curP)); } else if (preP) missings.push(preP); } for (const newP of news) { preP = closer(newP, missings.filter(p => util.samePiece(newP.piece, p.piece))); if (preP) { vector = [preP.pos[0] - newP.pos[0], preP.pos[1] - newP.pos[1]]; anims.set(newP.key, vector.concat(vector)); animedOrigs.push(preP.key); } } for (const p of missings) { if (animedOrigs.indexOf(p.key) === -1) fadings.set(p.key, p.piece); } return { anims: anims, fadings: fadings, }; } function step(state, now) { const cur = state.animation.current; if (cur === undefined) { if (!state.dom.destroyed) state.dom.redrawNow(); return; } const rest = 1 - (now - cur.start) * cur.frequency; if (rest <= 0) { state.animation.current = undefined; state.dom.redrawNow(); } else { const ease = easing(rest); for (const cfg of cur.plan.anims.values()) { cfg[2] = cfg[0] * ease; cfg[3] = cfg[1] * ease; } state.dom.redrawNow(true); requestAnimationFrame((now = performance.now()) => step(state, now)); } } function animate(mutation, state) { const prevPieces = new Map(state.pieces); const result = mutation(state); const plan = computePlan(prevPieces, state); if (plan.anims.size || plan.fadings.size) { const alreadyRunning = state.animation.current && state.animation.current.start; state.animation.current = { start: performance.now(), frequency: 1 / state.animation.duration, plan: plan, }; if (!alreadyRunning) step(state, performance.now()); } else { state.dom.redraw(); } return result; } function easing(t) { return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1; } },{"./util":18}],2:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.start = void 0; const board = require("./board"); const fen_1 = require("./fen"); const config_1 = require("./config"); const anim_1 = require("./anim"); const drag_1 = require("./drag"); const explosion_1 = require("./explosion"); function start(state, redrawAll) { function toggleOrientation() { board.toggleOrientation(state); redrawAll(); } return { set(config) { if (config.orientation && config.orientation !== state.orientation) toggleOrientation(); (config.fen ? anim_1.anim : anim_1.render)(state => config_1.configure(state, config), state); }, state, getFen: () => fen_1.write(state.pieces), toggleOrientation, setPieces(pieces) { anim_1.anim(state => board.setPieces(state, pieces), state); }, selectSquare(key, force) { if (key) anim_1.anim(state => board.selectSquare(state, key, force), state); else if (state.selected) { board.unselect(state); state.dom.redraw(); } }, move(orig, dest) { anim_1.anim(state => board.baseMove(state, orig, dest), state); }, newPiece(piece, key) { anim_1.anim(state => board.baseNewPiece(state, piece, key), state); }, playPremove() { if (state.premovable.current) { if (anim_1.anim(board.playPremove, state)) return true; state.dom.redraw(); } return false; }, playPredrop(validate) { if (state.predroppable.current) { const result = board.playPredrop(state, validate); state.dom.redraw(); return result; } return false; }, cancelPremove() { anim_1.render(board.unsetPremove, state); }, cancelPredrop() { anim_1.render(board.unsetPredrop, state); }, cancelMove() { anim_1.render(state => { board.cancelMove(state); drag_1.cancel(state); }, state); }, stop() { anim_1.render(state => { board.stop(state); drag_1.cancel(state); }, state); }, explode(keys) { explosion_1.explosion(state, keys); }, setAutoShapes(shapes) { anim_1.render(state => (state.drawable.autoShapes = shapes), state); }, setShapes(shapes) { anim_1.render(state => (state.drawable.shapes = shapes), state); }, getKeyAtDomPos(pos) { return board.getKeyAtDomPos(pos, board.whitePov(state), state.dom.bounds()); }, redrawAll, dragNewPiece(piece, event, force) { drag_1.dragNewPiece(state, piece, event, force); }, destroy() { board.stop(state); state.dom.unbind && state.dom.unbind(); state.dom.destroyed = true; }, }; } exports.start = start; },{"./anim":1,"./board":3,"./config":5,"./drag":6,"./explosion":10,"./fen":11}],3:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.whitePov = exports.getSnappedKeyAtDomPos = exports.getKeyAtDomPos = exports.stop = exports.cancelMove = exports.playPredrop = exports.playPremove = exports.isDraggable = exports.canMove = exports.unselect = exports.setSelected = exports.selectSquare = exports.dropNewPiece = exports.userMove = exports.baseNewPiece = exports.baseMove = exports.unsetPredrop = exports.unsetPremove = exports.setCheck = exports.setPieces = exports.reset = exports.toggleOrientation = exports.callUserFunction = void 0; const util_1 = require("./util"); const premove_1 = require("./premove"); function callUserFunction(f, ...args) { if (f) setTimeout(() => f(...args), 1); } exports.callUserFunction = callUserFunction; function toggleOrientation(state) { state.orientation = util_1.opposite(state.orientation); state.animation.current = state.draggable.current = state.selected = undefined; } exports.toggleOrientation = toggleOrientation; function reset(state) { state.lastMove = undefined; unselect(state); unsetPremove(state); unsetPredrop(state); } exports.reset = reset; function setPieces(state, pieces) { for (const [key, piece] of pieces) { if (piece) state.pieces.set(key, piece); else state.pieces.delete(key); } } exports.setPieces = setPieces; function setCheck(state, color) { state.check = undefined; if (color === true) color = state.turnColor; if (color) for (const [k, p] of state.pieces) { if (p.role === 'king' && p.color === color) { state.check = k; } } } exports.setCheck = setCheck; function setPremove(state, orig, dest, meta) { unsetPredrop(state); state.premovable.current = [orig, dest]; callUserFunction(state.premovable.events.set, orig, dest, meta); } function unsetPremove(state) { if (state.premovable.current) { state.premovable.current = undefined; callUserFunction(state.premovable.events.unset); } } exports.unsetPremove = unsetPremove; function setPredrop(state, role, key) { unsetPremove(state); state.predroppable.current = { role, key }; callUserFunction(state.predroppable.events.set, role, key); } function unsetPredrop(state) { const pd = state.predroppable; if (pd.current) { pd.current = undefined; callUserFunction(pd.events.unset); } } exports.unsetPredrop = unsetPredrop; function tryAutoCastle(state, orig, dest) { if (!state.autoCastle) return false; const king = state.pieces.get(orig); if (!king || king.role !== 'king') return false; const origPos = util_1.key2pos(orig); const destPos = util_1.key2pos(dest); if ((origPos[1] !== 0 && origPos[1] !== 7) || origPos[1] !== destPos[1]) return false; if (origPos[0] === 4 && !state.pieces.has(dest)) { if (destPos[0] === 6) dest = util_1.pos2key([7, destPos[1]]); else if (destPos[0] === 2) dest = util_1.pos2key([0, destPos[1]]); } const rook = state.pieces.get(dest); if (!rook || rook.color !== king.color || rook.role !== 'rook') return false; state.pieces.delete(orig); state.pieces.delete(dest); if (origPos[0] < destPos[0]) { state.pieces.set(util_1.pos2key([6, destPos[1]]), king); state.pieces.set(util_1.pos2key([5, destPos[1]]), rook); } else { state.pieces.set(util_1.pos2key([2, destPos[1]]), king); state.pieces.set(util_1.pos2key([3, destPos[1]]), rook); } return true; } function baseMove(state, orig, dest) { const origPiece = state.pieces.get(orig), destPiece = state.pieces.get(dest); if (orig === dest || !origPiece) return false; const captured = destPiece && destPiece.color !== origPiece.color ? destPiece : undefined; if (dest === state.selected) unselect(state); callUserFunction(state.events.move, orig, dest, captured); if (!tryAutoCastle(state, orig, dest)) { state.pieces.set(dest, origPiece); state.pieces.delete(orig); } state.lastMove = [orig, dest]; state.check = undefined; callUserFunction(state.events.change); return captured || true; } exports.baseMove = baseMove; function baseNewPiece(state, piece, key, force) { if (state.pieces.has(key)) { if (force) state.pieces.delete(key); else return false; } callUserFunction(state.events.dropNewPiece, piece, key); state.pieces.set(key, piece); state.lastMove = [key]; state.check = undefined; callUserFunction(state.events.change); state.movable.dests = undefined; state.turnColor = util_1.opposite(state.turnColor); return true; } exports.baseNewPiece = baseNewPiece; function baseUserMove(state, orig, dest) { const result = baseMove(state, orig, dest); if (result) { state.movable.dests = undefined; state.turnColor = util_1.opposite(state.turnColor); state.animation.current = undefined; } return result; } function userMove(state, orig, dest) { if (canMove(state, orig, dest)) { const result = baseUserMove(state, orig, dest); if (result) { const holdTime = state.hold.stop(); unselect(state); const metadata = { premove: false, ctrlKey: state.stats.ctrlKey, holdTime, }; if (result !== true) metadata.captured = result; callUserFunction(state.movable.events.after, orig, dest, metadata); return true; } } else if (canPremove(state, orig, dest)) { setPremove(state, orig, dest, { ctrlKey: state.stats.ctrlKey, }); unselect(state); return true; } unselect(state); return false; } exports.userMove = userMove; function dropNewPiece(state, orig, dest, force) { const piece = state.pieces.get(orig); if (piece && (canDrop(state, orig, dest) || force)) { state.pieces.delete(orig); baseNewPiece(state, piece, dest, force); callUserFunction(state.movable.events.afterNewPiece, piece.role, dest, { premove: false, predrop: false, }); } else if (piece && canPredrop(state, orig, dest)) { setPredrop(state, piece.role, dest); } else { unsetPremove(state); unsetPredrop(state); } state.pieces.delete(orig); unselect(state); } exports.dropNewPiece = dropNewPiece; function selectSquare(state, key, force) { callUserFunction(state.events.select, key); if (state.selected) { if (state.selected === key && !state.draggable.enabled) { unselect(state); state.hold.cancel(); return; } else if ((state.selectable.enabled || force) && state.selected !== key) { if (userMove(state, state.selected, key)) { state.stats.dragged = false; return; } } } if (isMovable(state, key) || isPremovable(state, key)) { setSelected(state, key); state.hold.start(); } } exports.selectSquare = selectSquare; function setSelected(state, key) { state.selected = key; if (isPremovable(state, key)) { state.premovable.dests = premove_1.premove(state.pieces, key, state.premovable.castle); } else state.premovable.dests = undefined; } exports.setSelected = setSelected; function unselect(state) { state.selected = undefined; state.premovable.dests = undefined; state.hold.cancel(); } exports.unselect = unselect; function isMovable(state, orig) { const piece = state.pieces.get(orig); return (!!piece && (state.movable.color === 'both' || (state.movable.color === piece.color && state.turnColor === piece.color))); } function canMove(state, orig, dest) { var _a, _b; return (orig !== dest && isMovable(state, orig) && (state.movable.free || (!!state.movable.dests && !!state.movable.dests.get(orig) && ((_b = (_a = state.movable.dests) === null || _a === void 0 ? void 0 : _a.get(orig)) === null || _b === void 0 ? void 0 : _b.indexOf(dest)) !== -1))); } exports.canMove = canMove; function canDrop(state, orig, dest) { const piece = state.pieces.get(orig); return (!!piece && (orig === dest || !state.pieces.has(dest)) && (state.movable.color === 'both' || (state.movable.color === piece.color && state.turnColor === piece.color))); } function isPremovable(state, orig) { const piece = state.pieces.get(orig); return !!piece && state.premovable.enabled && state.movable.color === piece.color && state.turnColor !== piece.color; } function canPremove(state, orig, dest) { return (orig !== dest && isPremovable(state, orig) && premove_1.premove(state.pieces, orig, state.premovable.castle).indexOf(dest) !== -1); } function canPredrop(state, orig, dest) { const piece = state.pieces.get(orig); const destPiece = state.pieces.get(dest); return (!!piece && (!destPiece || destPiece.color !== state.movable.color) && state.predroppable.enabled && (piece.role !== 'pawn' || (dest[1] !== '1' && dest[1] !== '8')) && state.movable.color === piece.color && state.turnColor !== piece.color); } function isDraggable(state, orig) { const piece = state.pieces.get(orig); return (!!piece && state.draggable.enabled && (state.movable.color === 'both' || (state.movable.color === piece.color && (state.turnColor === piece.color || state.premovable.enabled)))); } exports.isDraggable = isDraggable; function playPremove(state) { const move = state.premovable.current; if (!move) return false; const orig = move[0], dest = move[1]; let success = false; if (canMove(state, orig, dest)) { const result = baseUserMove(state, orig, dest); if (result) { const metadata = { premove: true }; if (result !== true) metadata.captured = result; callUserFunction(state.movable.events.after, orig, dest, metadata); success = true; } } unsetPremove(state); return success; } exports.playPremove = playPremove; function playPredrop(state, validate) { const drop = state.predroppable.current; let success = false; if (!drop) return false; if (validate(drop)) { const piece = { role: drop.role, color: state.movable.color, }; if (baseNewPiece(state, piece, drop.key)) { callUserFunction(state.movable.events.afterNewPiece, drop.role, drop.key, { premove: false, predrop: true, }); success = true; } } unsetPredrop(state); return success; } exports.playPredrop = playPredrop; function cancelMove(state) { unsetPremove(state); unsetPredrop(state); unselect(state); } exports.cancelMove = cancelMove; function stop(state) { state.movable.color = state.movable.dests = state.animation.current = undefined; cancelMove(state); } exports.stop = stop; function getKeyAtDomPos(pos, asWhite, bounds) { let file = Math.floor((8 * (pos[0] - bounds.left)) / bounds.width); if (!asWhite) file = 7 - file; let rank = 7 - Math.floor((8 * (pos[1] - bounds.top)) / bounds.height); if (!asWhite) rank = 7 - rank; return file >= 0 && file < 8 && rank >= 0 && rank < 8 ? util_1.pos2key([file, rank]) : undefined; } exports.getKeyAtDomPos = getKeyAtDomPos; function getSnappedKeyAtDomPos(orig, pos, asWhite, bounds) { const origPos = util_1.key2pos(orig); const validSnapPos = util_1.allPos.filter(pos2 => { return premove_1.queen(origPos[0], origPos[1], pos2[0], pos2[1]) || premove_1.knight(origPos[0], origPos[1], pos2[0], pos2[1]); }); const validSnapCenters = validSnapPos.map(pos2 => util_1.computeSquareCenter(util_1.pos2key(pos2), asWhite, bounds)); const validSnapDistances = validSnapCenters.map(pos2 => util_1.distanceSq(pos, pos2)); const [, closestSnapIndex] = validSnapDistances.reduce((a, b, index) => (a[0] < b ? a : [b, index]), [ validSnapDistances[0], 0, ]); return util_1.pos2key(validSnapPos[closestSnapIndex]); } exports.getSnappedKeyAtDomPos = getSnappedKeyAtDomPos; function whitePov(s) { return s.orientation === 'white'; } exports.whitePov = whitePov; },{"./premove":13,"./util":18}],4:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Chessground = void 0; const api_1 = require("./api"); const config_1 = require("./config"); const state_1 = require("./state"); const wrap_1 = require("./wrap"); const events = require("./events"); const render_1 = require("./render"); const svg = require("./svg"); const util = require("./util"); function Chessground(element, config) { const maybeState = state_1.defaults(); config_1.configure(maybeState, config || {}); function redrawAll() { const prevUnbind = 'dom' in maybeState ? maybeState.dom.unbind : undefined; const relative = maybeState.viewOnly && !maybeState.drawable.visible, elements = wrap_1.renderWrap(element, maybeState, relative), bounds = util.memo(() => elements.board.getBoundingClientRect()), redrawNow = (skipSvg) => { render_1.render(state); if (!skipSvg && elements.svg) svg.renderSvg(state, elements.svg, elements.customSvg); }, boundsUpdated = () => { bounds.clear(); render_1.updateBounds(state); if (elements.svg) svg.renderSvg(state, elements.svg, elements.customSvg); }; const state = maybeState; state.dom = { elements, bounds, redraw: debounceRedraw(redrawNow), redrawNow, unbind: prevUnbind, relative, }; state.drawable.prevSvgHash = ''; redrawNow(false); events.bindBoard(state, boundsUpdated); if (!prevUnbind) state.dom.unbind = events.bindDocument(state, boundsUpdated); state.events.insert && state.events.insert(elements); return state; } return api_1.start(redrawAll(), redrawAll); } exports.Chessground = Chessground; function debounceRedraw(redrawNow) { let redrawing = false; return () => { if (redrawing) return; redrawing = true; requestAnimationFrame(() => { redrawNow(); redrawing = false; }); }; } },{"./api":2,"./config":5,"./events":9,"./render":14,"./state":15,"./svg":16,"./util":18,"./wrap":19}],5:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.configure = void 0; const board_1 = require("./board"); const fen_1 = require("./fen"); function configure(state, config) { var _a, _b; if ((_a = config.movable) === null || _a === void 0 ? void 0 : _a.dests) state.movable.dests = undefined; if ((_b = config.drawable) === null || _b === void 0 ? void 0 : _b.autoShapes) state.drawable.autoShapes = []; merge(state, config); if (config.fen) { state.pieces = fen_1.read(config.fen); state.drawable.shapes = []; } if ('check' in config) board_1.setCheck(state, config.check || false); if ('lastMove' in config && !config.lastMove) state.lastMove = undefined; else if (config.lastMove) state.lastMove = config.lastMove; if (state.selected) board_1.setSelected(state, state.selected); if (!state.animation.duration || state.animation.duration < 100) state.animation.enabled = false; if (!state.movable.rookCastle && state.movable.dests) { const rank = state.movable.color === 'white' ? '1' : '8', kingStartPos = ('e' + rank), dests = state.movable.dests.get(kingStartPos), king = state.pieces.get(kingStartPos); if (!dests || !king || king.role !== 'king') return; state.movable.dests.set(kingStartPos, dests.filter(d => !(d === 'a' + rank && dests.indexOf(('c' + rank)) !== -1) && !(d === 'h' + rank && dests.indexOf(('g' + rank)) !== -1))); } } exports.configure = configure; function merge(base, extend) { for (const key in extend) { if (isObject(base[key]) && isObject(extend[key])) merge(base[key], extend[key]); else base[key] = extend[key]; } } function isObject(o) { return typeof o === 'object'; } },{"./board":3,"./fen":11}],6:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.cancel = exports.end = exports.move = exports.dragNewPiece = exports.start = void 0; const board = require("./board"); const util = require("./util"); const draw_1 = require("./draw"); const anim_1 = require("./anim"); function start(s, e) { if (!e.isTrusted || (e.button !== undefined && e.button !== 0)) return; if (e.touches && e.touches.length > 1) return; const bounds = s.dom.bounds(), position = util.eventPosition(e), orig = board.getKeyAtDomPos(position, board.whitePov(s), bounds); if (!orig) return; const piece = s.pieces.get(orig); const previouslySelected = s.selected; if (!previouslySelected && s.drawable.enabled && (s.drawable.eraseOnClick || !piece || piece.color !== s.turnColor)) draw_1.clear(s); if (e.cancelable !== false && (!e.touches || !s.movable.color || piece || previouslySelected || pieceCloseTo(s, position))) e.preventDefault(); const hadPremove = !!s.premovable.current; const hadPredrop = !!s.predroppable.current; s.stats.ctrlKey = e.ctrlKey; if (s.selected && board.canMove(s, s.selected, orig)) { anim_1.anim(state => board.selectSquare(state, orig), s); } else { board.selectSquare(s, orig); } const stillSelected = s.selected === orig; const element = pieceElementByKey(s, orig); if (piece && element && stillSelected && board.isDraggable(s, orig)) { s.draggable.current = { orig, piece, origPos: position, pos: position, started: s.draggable.autoDistance && s.stats.dragged, element, previouslySelected, originTarget: e.target, }; element.cgDragging = true; element.classList.add('dragging'); const ghost = s.dom.elements.ghost; if (ghost) { ghost.className = `ghost ${piece.color} ${piece.role}`; util.translateAbs(ghost, util.posToTranslateAbs(bounds)(util.key2pos(orig), board.whitePov(s))); util.setVisible(ghost, true); } processDrag(s); } else { if (hadPremove) board.unsetPremove(s); if (hadPredrop) board.unsetPredrop(s); } s.dom.redraw(); } exports.start = start; function pieceCloseTo(s, pos) { const asWhite = board.whitePov(s), bounds = s.dom.bounds(), radiusSq = Math.pow(bounds.width / 8, 2); for (const key in s.pieces) { const center = util.computeSquareCenter(key, asWhite, bounds); if (util.distanceSq(center, pos) <= radiusSq) return true; } return false; } function dragNewPiece(s, piece, e, force) { const key = 'a0'; s.pieces.set(key, piece); s.dom.redraw(); const position = util.eventPosition(e); s.draggable.current = { orig: key, piece, origPos: position, pos: position, started: true, element: () => pieceElementByKey(s, key), originTarget: e.target, newPiece: true, force: !!force, }; processDrag(s); } exports.dragNewPiece = dragNewPiece; function processDrag(s) { requestAnimationFrame(() => { var _a; const cur = s.draggable.current; if (!cur) return; if ((_a = s.animation.current) === null || _a === void 0 ? void 0 : _a.plan.anims.has(cur.orig)) s.animation.current = undefined; const origPiece = s.pieces.get(cur.orig); if (!origPiece || !util.samePiece(origPiece, cur.piece)) cancel(s); else { if (!cur.started && util.distanceSq(cur.pos, cur.origPos) >= Math.pow(s.draggable.distance, 2)) cur.started = true; if (cur.started) { if (typeof cur.element === 'function') { const found = cur.element(); if (!found) return; found.cgDragging = true; found.classList.add('dragging'); cur.element = found; } const bounds = s.dom.bounds(); util.translateAbs(cur.element, [ cur.pos[0] - bounds.left - bounds.width / 16, cur.pos[1] - bounds.top - bounds.height / 16, ]); } } processDrag(s); }); } function move(s, e) { if (s.draggable.current && (!e.touches || e.touches.length < 2)) { s.draggable.current.pos = util.eventPosition(e); } } exports.move = move; function end(s, e) { const cur = s.draggable.current; if (!cur) return; if (e.type === 'touchend' && e.cancelable !== false) e.preventDefault(); if (e.type === 'touchend' && cur.originTarget !== e.target && !cur.newPiece) { s.draggable.current = undefined; return; } board.unsetPremove(s); board.unsetPredrop(s); const eventPos = util.eventPosition(e) || cur.pos; const dest = board.getKeyAtDomPos(eventPos, board.whitePov(s), s.dom.bounds()); if (dest && cur.started && cur.orig !== dest) { if (cur.newPiece) board.dropNewPiece(s, cur.orig, dest, cur.force); else { s.stats.ctrlKey = e.ctrlKey; if (board.userMove(s, cur.orig, dest)) s.stats.dragged = true; } } else if (cur.newPiece) { s.pieces.delete(cur.orig); } else if (s.draggable.deleteOnDropOff && !dest) { s.pieces.delete(cur.orig); board.callUserFunction(s.events.change); } if (cur.orig === cur.previouslySelected && (cur.orig === dest || !dest)) board.unselect(s); else if (!s.selectable.enabled) board.unselect(s); removeDragElements(s); s.draggable.current = undefined; s.dom.redraw(); } exports.end = end; function cancel(s) { const cur = s.draggable.current; if (cur) { if (cur.newPiece) s.pieces.delete(cur.orig); s.draggable.current = undefined; board.unselect(s); removeDragElements(s); s.dom.redraw(); } } exports.cancel = cancel; function removeDragElements(s) { const e = s.dom.elements; if (e.ghost) util.setVisible(e.ghost, false); } function pieceElementByKey(s, key) { let el = s.dom.elements.board.firstChild; while (el) { if (el.cgKey === key && el.tagName === 'PIECE') return el; el = el.nextSibling; } return; } },{"./anim":1,"./board":3,"./draw":7,"./util":18}],7:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.clear = exports.cancel = exports.end = exports.move = exports.processDraw = exports.start = void 0; const board_1 = require("./board"); const util_1 = require("./util"); const brushes = ['green', 'red', 'blue', 'yellow']; function start(state, e) { if (e.touches && e.touches.length > 1) return; e.stopPropagation(); e.preventDefault(); e.ctrlKey ? board_1.unselect(state) : board_1.cancelMove(state); const pos = util_1.eventPosition(e), orig = board_1.getKeyAtDomPos(pos, board_1.whitePov(state), state.dom.bounds()); if (!orig) return; state.drawable.current = { orig, pos, brush: eventBrush(e), snapToValidMove: state.drawable.defaultSnapToValidMove, }; processDraw(state); } exports.start = start; function processDraw(state) { requestAnimationFrame(() => { const cur = state.drawable.current; if (cur) { const keyAtDomPos = board_1.getKeyAtDomPos(cur.pos, board_1.whitePov(state), state.dom.bounds()); if (!keyAtDomPos) { cur.snapToValidMove = false; } const mouseSq = cur.snapToValidMove ? board_1.getSnappedKeyAtDomPos(cur.orig, cur.pos, board_1.whitePov(state), state.dom.bounds()) : keyAtDomPos; if (mouseSq !== cur.mouseSq) { cur.mouseSq = mouseSq; cur.dest = mouseSq !== cur.orig ? mouseSq : undefined; state.dom.redrawNow(); } processDraw(state); } }); } exports.processDraw = processDraw; function move(state, e) { if (state.drawable.current) state.drawable.current.pos = util_1.eventPosition(e); } exports.move = move; function end(state) { const cur = state.drawable.current; if (cur) { if (cur.mouseSq) addShape(state.drawable, cur); cancel(state); } } exports.end = end; function cancel(state) { if (state.drawable.current) { state.drawable.current = undefined; state.dom.redraw(); } } exports.cancel = cancel; function clear(state) { if (state.drawable.shapes.length) { state.drawable.shapes = []; state.dom.redraw(); onChange(state.drawable); } } exports.clear = clear; function eventBrush(e) { var _a; const modA = (e.shiftKey || e.ctrlKey) && util_1.isRightButton(e); const modB = e.altKey || e.metaKey || ((_a = e.getModifierState) === null || _a === void 0 ? void 0 : _a.call(e, 'AltGraph')); return brushes[(modA ? 1 : 0) + (modB ? 2 : 0)]; } function addShape(drawable, cur) { const sameShape = (s) => s.orig === cur.orig && s.dest === cur.dest; const similar = drawable.shapes.find(sameShape); if (similar) drawable.shapes = drawable.shapes.filter(s => !sameShape(s)); if (!similar || similar.brush !== cur.brush) drawable.shapes.push(cur); onChange(drawable); } function onChange(drawable) { if (drawable.onChange) drawable.onChange(drawable.shapes); } },{"./board":3,"./util":18}],8:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.drop = exports.cancelDropMode = exports.setDropMode = void 0; const board = require("./board"); const util = require("./util"); const drag_1 = require("./drag"); function setDropMode(s, piece) { s.dropmode = { active: true, piece, }; drag_1.cancel(s); } exports.setDropMode = setDropMode; function cancelDropMode(s) { s.dropmode = { active: false, }; } exports.cancelDropMode = cancelDropMode; function drop(s, e) { if (!s.dropmode.active) return; board.unsetPremove(s); board.unsetPredrop(s); const piece = s.dropmode.piece; if (piece) { s.pieces.set('a0', piece); const position = util.eventPosition(e); const dest = position && board.getKeyAtDomPos(position, board.whitePov(s), s.dom.bounds()); if (dest) board.dropNewPiece(s, 'a0', dest); } s.dom.redraw(); } exports.drop = drop; },{"./board":3,"./drag":6,"./util":18}],9:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.bindDocument = exports.bindBoard = void 0; const drag = require("./drag"); const draw = require("./draw"); const drop_1 = require("./drop"); const util_1 = require("./util"); function bindBoard(s, boundsUpdated) { const boardEl = s.dom.elements.board; if (!s.dom.relative && s.resizable && 'ResizeObserver' in window) { const observer = new window['ResizeObserver'](boundsUpdated); observer.observe(boardEl); } if (s.viewOnly) return; const onStart = startDragOrDraw(s); boardEl.addEventListener('touchstart', onStart, { passive: false, }); boardEl.addEventListener('mousedown', onStart, { passive: false, }); if (s.disableContextMenu || s.drawable.enabled) { boardEl.addEventListener('contextmenu', e => e.preventDefault()); } } exports.bindBoard = bindBoard; function bindDocument(s, boundsUpdated) { const unbinds = []; if (!s.dom.relative && s.resizable && !('ResizeObserver' in window)) { unbinds.push(unbindable(document.body, 'chessground.resize', boundsUpdated)); } if (!s.viewOnly) { const onmove = dragOrDraw(s, drag.move, draw.move); const onend = dragOrDraw(s, drag.end, draw.end); for (const ev of ['touchmove', 'mousemove']) unbinds.push(unbindable(document, ev, onmove)); for (const ev of ['touchend', 'mouseup']) unbinds.push(unbindable(document, ev, onend)); const onScroll = () => s.dom.bounds.clear(); unbinds.push(unbindable(document, 'scroll', onScroll, { capture: true, passive: true })); unbinds.push(unbindable(window, 'resize', onScroll, { passive: true })); } return () => unbinds.forEach(f => f()); } exports.bindDocument = bindDocument; function unbindable(el, eventName, callback, options) { el.addEventListener(eventName, callback, options); return () => el.removeEventListener(eventName, callback, options); } function startDragOrDraw(s) { return e => { if (s.draggable.current) drag.cancel(s); else if (s.drawable.current) draw.cancel(s); else if (e.shiftKey || util_1.isRightButton(e)) { if (s.drawable.enabled) draw.start(s, e); } else if (!s.viewOnly) { if (s.dropmode.active) drop_1.drop(s, e); else drag.start(s, e); } }; } function dragOrDraw(s, withDrag, withDraw) { return e => { if (s.drawable.current) { if (s.drawable.enabled) withDraw(s, e); } else if (!s.viewOnly) withDrag(s, e); }; } },{"./drag":6,"./draw":7,"./drop":8,"./util":18}],10:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.explosion = void 0; function explosion(state, keys) { state.exploding = { stage: 1, keys }; state.dom.redraw(); setTimeout(() => { setStage(state, 2); setTimeout(() => setStage(state, undefined), 120); }, 120); } exports.explosion = explosion; function setStage(state, stage) { if (state.exploding) { if (stage) state.exploding.stage = stage; else state.exploding = undefined; state.dom.redraw(); } } },{}],11:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.write = exports.read = exports.initial = void 0; const util_1 = require("./util"); const cg = require("./types"); exports.initial = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR'; const roles = { p: 'pawn', r: 'rook', n: 'knight', b: 'bishop', q: 'queen', k: 'king', }; const letters = { pawn: 'p', rook: 'r', knight: 'n', bishop: 'b', queen: 'q', king: 'k', }; function read(fen) { if (fen === 'start') fen = exports.initial; const pieces = new Map(); let row = 7, col = 0; for (const c of fen) { switch (c) { case ' ': return pieces; case '/': --row; if (row < 0) return pieces; col = 0; break; case '~': { const piece = pieces.get(util_1.pos2key([col, row])); if (piece) piece.promoted = true; break; } default: { const nb = c.charCodeAt(0); if (nb < 57) col += nb - 48; else { const role = c.toLowerCase(); pieces.set(util_1.pos2key([col, row]), { role: roles[role], color: c === role ? 'black' : 'white', }); ++col; } } } } return pieces; } exports.read = read; function write(pieces) { return util_1.invRanks .map(y => cg.files .map(x => { const piece = pieces.get((x + y)); if (piece) { const letter = letters[piece.role]; return piece.color === 'white' ? letter.toUpperCase() : letter; } else return '1'; }) .join('')) .join('/') .replace(/1{2,}/g, s => s.length.toString()); } exports.write = write; },{"./types":17,"./util":18}],12:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const chessground_1 = require("./chessground"); exports.default = chessground_1.Chessground; },{"./chessground":4}],13:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.premove = exports.queen = exports.knight = void 0; const util = require("./util"); function diff(a, b) { return Math.abs(a - b); } function pawn(color) { return (x1, y1, x2, y2) => diff(x1, x2) < 2 && (color === 'white' ? y2 === y1 + 1 || (y1 <= 1 && y2 === y1 + 2 && x1 === x2) : y2 === y1 - 1 || (y1 >= 6 && y2 === y1 - 2 && x1 === x2)); } exports.knight = (x1, y1, x2, y2) => { const xd = diff(x1, x2); const yd = diff(y1, y2); return (xd === 1 && yd === 2) || (xd === 2 && yd === 1); }; const bishop = (x1, y1, x2, y2) => { return diff(x1, x2) === diff(y1, y2); }; const rook = (x1, y1, x2, y2) => { return x1 === x2 || y1 === y2; }; exports.queen = (x1, y1, x2, y2) => { return bishop(x1, y1, x2, y2) || rook(x1, y1, x2, y2); }; function king(color, rookFiles, canCastle) { return (x1, y1, x2, y2) => (diff(x1, x2) < 2 && diff(y1, y2) < 2) || (canCastle && y1 === y2 && y1 === (color === 'white' ? 0 : 7) && ((x1 === 4 && ((x2 === 2 && rookFiles.indexOf(0) !== -1) || (x2 === 6 && rookFiles.indexOf(7) !== -1))) || rookFiles.indexOf(x2) !== -1)); } function rookFilesOf(pieces, color) { const backrank = color === 'white' ? '1' : '8'; const files = []; for (const [key, piece] of pieces) { if (key[1] === backrank && piece.color === color && piece.role === 'rook') { files.push(util.key2pos(key)[0]); } } return files; } function premove(pieces, key, canCastle) { const piece = pieces.get(key); if (!piece) return []; const pos = util.key2pos(key), r = piece.role, mobility = r === 'pawn' ? pawn(piece.color) : r === 'knight' ? exports.knight : r === 'bishop' ? bishop : r === 'rook' ? rook : r === 'queen' ? exports.queen : king(piece.color, rookFilesOf(pieces, piece.color), canCastle); return util.allPos .filter(pos2 => (pos[0] !== pos2[0] || pos[1] !== pos2[1]) && mobility(pos[0], pos[1], pos2[0], pos2[1])) .map(util.pos2key); } exports.premove = premove; },{"./util":18}],14:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.updateBounds = exports.render = void 0; const util_1 = require("./util"); const board_1 = require("./board"); function render(s) { const asWhite = board_1.whitePov(s), posToTranslate = s.dom.relative ? util_1.posToTranslateRel : util_1.posToTranslateAbs(s.dom.bounds()), translate = s.dom.relative ? util_1.translateRel : util_1.translateAbs, boardEl = s.dom.elements.board, pieces = s.pieces, curAnim = s.animation.current, anims = curAnim ? curAnim.plan.anims : new Map(), fadings = curAnim ? curAnim.plan.fadings : new Map(), curDrag = s.draggable.current, squares = computeSquareClasses(s), samePieces = new Set(), sameSquares = new Set(), movedPieces = new Map(), movedSquares = new Map(); let k, el, pieceAtKey, elPieceName, anim, fading, pMvdset, pMvd, sMvdset, sMvd; el = boardEl.firstChild; while (el) { k = el.cgKey; if (isPieceNode(el)) { pieceAtKey = pieces.get(k); anim = anims.get(k); fading = fadings.get(k); elPieceName = el.cgPiece; if (el.cgDragging && (!curDrag || curDrag.orig !== k)) { el.classList.remove('dragging'); translate(el, posToTranslate(util_1.key2pos(k), asWhite)); el.cgDragging = false; } if (!fading && el.cgFading) { el.cgFading = false; el.classList.remove('fading'); } if (pieceAtKey) { if (anim && el.cgAnimating && elPieceName === pieceNameOf(pieceAtKey)) { const pos = util_1.key2pos(k); pos[0] += anim[2]; pos[1] += anim[3]; el.classList.add('anim'); translate(el, posToTranslate(pos, asWhite)); } else if (el.cgAnimating) { el.cgAnimating = false; el.classList.remove('anim'); translate(el, posToTranslate(util_1.key2pos(k), asWhite)); if (s.addPieceZIndex) el.style.zIndex = posZIndex(util_1.key2pos(k), asWhite); } if (elPieceName === pieceNameOf(pieceAtKey) && (!fading || !el.cgFading)) { samePieces.add(k); } else { if (fading && elPieceName === pieceNameOf(fading)) { el.classList.add('fading'); el.cgFading = true; } else { appendValue(movedPieces, elPieceName, el); } } } else { appendValue(movedPieces, elPieceName, el); } } else if (isSquareNode(el)) { const cn = el.className; if (squares.get(k) === cn) sameSquares.add(k); else appendValue(movedSquares, cn, el); } el = el.nextSibling; } for (const [sk, className] of squares) { if (!sameSquares.has(sk)) { sMvdset = movedSquares.get(className); sMvd = sMvdset && sMvdset.pop(); const translation = posToTranslate(util_1.key2pos(sk), asWhite); if (sMvd) { sMvd.cgKey = sk; translate(sMvd, translation); } else { const squareNode = util_1.createEl('square', className); squareNode.cgKey = sk; translate(squareNode, translation); boardEl.insertBefore(squareNode, boardEl.firstChild); } } } for (const [k, p] of pieces) { anim = anims.get(k); if (!samePieces.has(k)) { pMvdset = movedPieces.get(pieceNameOf(p)); pMvd = pMvdset && pMvdset.pop(); if (pMvd) { pMvd.cgKey = k; if (pMvd.cgFading) { pMvd.classList.remove('fading'); pMvd.cgFading = false; } const pos = util_1.key2pos(k); if (s.addPieceZIndex) pMvd.style.zIndex = posZIndex(pos, asWhite); if (anim) { pMvd.cgAnimating = true; pMvd.classList.add('anim'); pos[0] += anim[2]; pos[1] += anim[3]; } translate(pMvd, posToTranslate(pos, asWhite)); } else { const pieceName = pieceNameOf(p), pieceNode = util_1.createEl('piece', pieceName), pos = util_1.key2pos(k); pieceNode.cgPiece = pieceName; pieceNode.cgKey = k; if (anim) { pieceNode.cg