@lichess-org/pgn-viewer 2.5.1 → 2.5.2

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.
@@ -2698,15 +2698,16 @@ var defaultTranslations = {
2698
2698
  "san.shortCastling": "short castling"
2699
2699
  };
2700
2700
 
2701
- // node_modules/.pnpm/chessground@9.2.1/node_modules/chessground/dist/types.js
2701
+ // node_modules/.pnpm/@lichess-org+chessground@9.8.2/node_modules/@lichess-org/chessground/dist/types.js
2702
2702
  var colors = ["white", "black"];
2703
2703
  var files = ["a", "b", "c", "d", "e", "f", "g", "h"];
2704
2704
  var ranks = ["1", "2", "3", "4", "5", "6", "7", "8"];
2705
2705
 
2706
- // node_modules/.pnpm/chessground@9.2.1/node_modules/chessground/dist/util.js
2706
+ // node_modules/.pnpm/@lichess-org+chessground@9.8.2/node_modules/@lichess-org/chessground/dist/util.js
2707
2707
  var invRanks = [...ranks].reverse();
2708
- var allKeys = Array.prototype.concat(...files.map((c) => ranks.map((r) => c + r)));
2709
- var pos2key = (pos) => allKeys[8 * pos[0] + pos[1]];
2708
+ var allKeys = files.flatMap((f) => ranks.map((r) => f + r));
2709
+ var pos2key = (pos) => pos.every((x) => x >= 0 && x <= 7) ? allKeys[8 * pos[0] + pos[1]] : void 0;
2710
+ var pos2keyUnsafe = (pos) => pos2key(pos);
2710
2711
  var key2pos = (k) => [k.charCodeAt(0) - 97, k.charCodeAt(1) - 49];
2711
2712
  var uciToMove = (uci) => {
2712
2713
  if (!uci)
@@ -2716,6 +2717,7 @@ var uciToMove = (uci) => {
2716
2717
  return [uci.slice(0, 2), uci.slice(2, 4)];
2717
2718
  };
2718
2719
  var allPos = allKeys.map(key2pos);
2720
+ var allPosAndKey = allKeys.map((key, i) => ({ key, pos: allPos[i] }));
2719
2721
  function memo(f) {
2720
2722
  let v;
2721
2723
  const ret = () => {
@@ -2747,11 +2749,9 @@ var timer = () => {
2747
2749
  };
2748
2750
  };
2749
2751
  var opposite2 = (c) => c === "white" ? "black" : "white";
2750
- var distanceSq = (pos1, pos2) => {
2751
- const dx = pos1[0] - pos2[0], dy = pos1[1] - pos2[1];
2752
- return dx * dx + dy * dy;
2753
- };
2752
+ var distanceSq = (pos1, pos2) => (pos1[0] - pos2[0]) ** 2 + (pos1[1] - pos2[1]) ** 2;
2754
2753
  var samePiece = (p1, p2) => p1.role === p2.role && p1.color === p2.color;
2754
+ var samePos = (p1, p2) => p1[0] === p2[0] && p1[1] === p2[1];
2755
2755
  var posToTranslate = (bounds) => (pos, asWhite) => [
2756
2756
  (asWhite ? pos[0] : 7 - pos[0]) * bounds.width / 8,
2757
2757
  (asWhite ? 7 - pos[1] : pos[1]) * bounds.height / 8
@@ -2766,10 +2766,9 @@ var setVisible = (el, v) => {
2766
2766
  el.style.visibility = v ? "visible" : "hidden";
2767
2767
  };
2768
2768
  var eventPosition = (e) => {
2769
- var _a;
2770
2769
  if (e.clientX || e.clientX === 0)
2771
2770
  return [e.clientX, e.clientY];
2772
- if ((_a = e.targetTouches) === null || _a === void 0 ? void 0 : _a[0])
2771
+ if (e.targetTouches?.[0])
2773
2772
  return [e.targetTouches[0].clientX, e.targetTouches[0].clientY];
2774
2773
  return;
2775
2774
  };
@@ -2791,6 +2790,47 @@ function computeSquareCenter(key, asWhite, bounds) {
2791
2790
  bounds.top + bounds.height * (7 - pos[1]) / 8 + bounds.height / 16
2792
2791
  ];
2793
2792
  }
2793
+ var diff = (a, b) => Math.abs(a - b);
2794
+ var knightDir = (x1, y1, x2, y2) => diff(x1, x2) * diff(y1, y2) === 2;
2795
+ var rookDir = (x1, y1, x2, y2) => x1 === x2 !== (y1 === y2);
2796
+ var bishopDir = (x1, y1, x2, y2) => diff(x1, x2) === diff(y1, y2) && x1 !== x2;
2797
+ var queenDir = (x1, y1, x2, y2) => rookDir(x1, y1, x2, y2) || bishopDir(x1, y1, x2, y2);
2798
+ var kingDirNonCastling = (x1, y1, x2, y2) => Math.max(diff(x1, x2), diff(y1, y2)) === 1;
2799
+ var pawnDirCapture = (x1, y1, x2, y2, isDirectionUp) => diff(x1, x2) === 1 && y2 === y1 + (isDirectionUp ? 1 : -1);
2800
+ var pawnDirAdvance = (x1, y1, x2, y2, isDirectionUp) => {
2801
+ const step2 = isDirectionUp ? 1 : -1;
2802
+ return x1 === x2 && (y2 === y1 + step2 || // allow 2 squares from first two ranks, for horde
2803
+ y2 === y1 + 2 * step2 && (isDirectionUp ? y1 <= 1 : y1 >= 6));
2804
+ };
2805
+ var squaresBetween = (x1, y1, x2, y2) => {
2806
+ const dx = x2 - x1;
2807
+ const dy = y2 - y1;
2808
+ if (dx && dy && Math.abs(dx) !== Math.abs(dy))
2809
+ return [];
2810
+ const stepX = Math.sign(dx), stepY = Math.sign(dy);
2811
+ const squares = [];
2812
+ let x = x1 + stepX, y = y1 + stepY;
2813
+ while (x !== x2 || y !== y2) {
2814
+ squares.push([x, y]);
2815
+ x += stepX;
2816
+ y += stepY;
2817
+ }
2818
+ return squares.map(pos2key).filter((k) => k !== void 0);
2819
+ };
2820
+ var adjacentSquares = (square) => {
2821
+ const pos = key2pos(square);
2822
+ const adjacentSquares2 = [];
2823
+ if (pos[0] > 0)
2824
+ adjacentSquares2.push([pos[0] - 1, pos[1]]);
2825
+ if (pos[0] < 7)
2826
+ adjacentSquares2.push([pos[0] + 1, pos[1]]);
2827
+ return adjacentSquares2.map(pos2key).filter((k) => k !== void 0);
2828
+ };
2829
+ var squareShiftedVertically = (square, delta) => {
2830
+ const pos = key2pos(square);
2831
+ pos[1] += delta;
2832
+ return pos2key(pos);
2833
+ };
2794
2834
 
2795
2835
  // src/path.ts
2796
2836
  var Path = class _Path {
@@ -3042,46 +3082,125 @@ var PgnViewer = class {
3042
3082
  }
3043
3083
  };
3044
3084
 
3045
- // node_modules/.pnpm/chessground@9.2.1/node_modules/chessground/dist/premove.js
3046
- var diff = (a, b) => Math.abs(a - b);
3047
- var pawn = (color) => (x1, y1, x2, y2) => diff(x1, x2) < 2 && (color === "white" ? (
3048
- // allow 2 squares from first two ranks, for horde
3049
- y2 === y1 + 1 || y1 <= 1 && y2 === y1 + 2 && x1 === x2
3050
- ) : y2 === y1 - 1 || y1 >= 6 && y2 === y1 - 2 && x1 === x2);
3051
- var knight = (x1, y1, x2, y2) => {
3052
- const xd = diff(x1, x2);
3053
- const yd = diff(y1, y2);
3054
- return xd === 1 && yd === 2 || xd === 2 && yd === 1;
3085
+ // node_modules/.pnpm/@lichess-org+chessground@9.8.2/node_modules/@lichess-org/chessground/dist/premove.js
3086
+ var isDestOccupiedByFriendly = (ctx) => ctx.friendlies.has(ctx.dest.key);
3087
+ var isDestOccupiedByEnemy = (ctx) => ctx.enemies.has(ctx.dest.key);
3088
+ var anyPieceBetween = (orig, dest, pieces) => squaresBetween(...orig, ...dest).some((s) => pieces.has(s));
3089
+ var canEnemyPawnAdvanceToSquare = (pawnStart, dest, ctx) => {
3090
+ const piece = ctx.enemies.get(pawnStart);
3091
+ if (piece?.role !== "pawn")
3092
+ return false;
3093
+ const step2 = piece.color === "white" ? 1 : -1;
3094
+ const startPos = key2pos(pawnStart);
3095
+ const destPos = key2pos(dest);
3096
+ return pawnDirAdvance(...startPos, ...destPos, piece.color === "white") && !anyPieceBetween(startPos, [destPos[0], destPos[1] + step2], ctx.allPieces);
3055
3097
  };
3056
- var bishop = (x1, y1, x2, y2) => {
3057
- return diff(x1, x2) === diff(y1, y2);
3098
+ var canEnemyPawnCaptureOnSquare = (pawnStart, dest, ctx) => {
3099
+ const enemyPawn = ctx.enemies.get(pawnStart);
3100
+ return enemyPawn?.role === "pawn" && pawnDirCapture(...key2pos(pawnStart), ...key2pos(dest), enemyPawn.color === "white") && (ctx.friendlies.has(dest) || canBeCapturedBySomeEnemyEnPassant(squareShiftedVertically(dest, enemyPawn.color === "white" ? -1 : 1), ctx.friendlies, ctx.enemies, ctx.lastMove));
3058
3101
  };
3059
- var rook = (x1, y1, x2, y2) => {
3060
- return x1 === x2 || y1 === y2;
3102
+ var canSomeEnemyPawnAdvanceToDest = (ctx) => [...ctx.enemies.keys()].some((key) => canEnemyPawnAdvanceToSquare(key, ctx.dest.key, ctx));
3103
+ var isDestControlledByEnemy = (ctx, pieceRolesExclude) => {
3104
+ const square = ctx.dest.pos;
3105
+ return [...ctx.enemies].some(([key, piece]) => {
3106
+ const piecePos = key2pos(key);
3107
+ return !pieceRolesExclude?.includes(piece.role) && (piece.role === "pawn" && pawnDirCapture(...piecePos, ...square, piece.color === "white") || piece.role === "knight" && knightDir(...piecePos, ...square) || piece.role === "bishop" && bishopDir(...piecePos, ...square) || piece.role === "rook" && rookDir(...piecePos, ...square) || piece.role === "queen" && queenDir(...piecePos, ...square) || piece.role === "king" && kingDirNonCastling(...piecePos, ...square)) && (!["bishop", "rook", "queen"].includes(piece.role) || !anyPieceBetween(piecePos, square, ctx.allPieces));
3108
+ });
3061
3109
  };
3062
- var queen = (x1, y1, x2, y2) => {
3063
- return bishop(x1, y1, x2, y2) || rook(x1, y1, x2, y2);
3110
+ var isFriendlyOnDestAndAttacked = (ctx) => isDestOccupiedByFriendly(ctx) && (canBeCapturedBySomeEnemyEnPassant(ctx.dest.key, ctx.friendlies, ctx.enemies, ctx.lastMove) || isDestControlledByEnemy(ctx));
3111
+ var canBeCapturedBySomeEnemyEnPassant = (potentialSquareOfFriendlyPawn, friendlies, enemies, lastMove) => {
3112
+ if (!potentialSquareOfFriendlyPawn || lastMove && potentialSquareOfFriendlyPawn !== lastMove[1])
3113
+ return false;
3114
+ const pos = key2pos(potentialSquareOfFriendlyPawn);
3115
+ const friendly = friendlies.get(potentialSquareOfFriendlyPawn);
3116
+ return friendly?.role === "pawn" && pos[1] === (friendly.color === "white" ? 3 : 4) && (!lastMove || diff(key2pos(lastMove[0])[1], pos[1]) === 2) && [1, -1].some((delta) => {
3117
+ const k = pos2key([pos[0] + delta, pos[1]]);
3118
+ return !!k && enemies.get(k)?.role === "pawn";
3119
+ });
3064
3120
  };
3065
- var king = (color, rookFiles, canCastle) => (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.includes(0) || x2 === 6 && rookFiles.includes(7)) || rookFiles.includes(x2));
3066
- function rookFilesOf(pieces, color) {
3067
- const backrank = color === "white" ? "1" : "8";
3068
- const files2 = [];
3069
- for (const [key, piece] of pieces) {
3070
- if (key[1] === backrank && piece.color === color && piece.role === "rook") {
3071
- files2.push(key2pos(key)[0]);
3072
- }
3073
- }
3074
- return files2;
3075
- }
3076
- function premove(pieces, key, canCastle) {
3121
+ var isPathClearEnoughOfFriendliesForPremove = (ctx, isPawnAdvance) => {
3122
+ if (ctx.unrestrictedPremoves)
3123
+ return true;
3124
+ const squaresBetween2 = squaresBetween(...ctx.orig.pos, ...ctx.dest.pos);
3125
+ if (isPawnAdvance)
3126
+ squaresBetween2.push(ctx.dest.key);
3127
+ const squaresOfFriendliesBetween = squaresBetween2.filter((s) => ctx.friendlies.has(s));
3128
+ if (!squaresOfFriendliesBetween.length)
3129
+ return true;
3130
+ const firstSquareOfFriendliesBetween = squaresOfFriendliesBetween[0];
3131
+ const nextSquare = squareShiftedVertically(firstSquareOfFriendliesBetween, ctx.color === "white" ? -1 : 1);
3132
+ return squaresOfFriendliesBetween.length === 1 && canBeCapturedBySomeEnemyEnPassant(firstSquareOfFriendliesBetween, ctx.friendlies, ctx.enemies, ctx.lastMove) && !!nextSquare && !squaresBetween2.includes(nextSquare);
3133
+ };
3134
+ var isPathClearEnoughOfEnemiesForPremove = (ctx, isPawnAdvance) => {
3135
+ if (ctx.unrestrictedPremoves)
3136
+ return true;
3137
+ const squaresBetween2 = squaresBetween(...ctx.orig.pos, ...ctx.dest.pos);
3138
+ if (isPawnAdvance)
3139
+ squaresBetween2.push(ctx.dest.key);
3140
+ const squaresOfEnemiesBetween = squaresBetween2.filter((s) => ctx.enemies.has(s));
3141
+ if (squaresOfEnemiesBetween.length > 1)
3142
+ return false;
3143
+ if (!squaresOfEnemiesBetween.length)
3144
+ return true;
3145
+ const enemySquare = squaresOfEnemiesBetween[0];
3146
+ const enemy = ctx.enemies.get(enemySquare);
3147
+ if (!enemy || enemy.role !== "pawn")
3148
+ return true;
3149
+ const enemyStep = enemy.color === "white" ? 1 : -1;
3150
+ const squareAbove = squareShiftedVertically(enemySquare, enemyStep);
3151
+ const enemyPawnDests = squareAbove ? [
3152
+ ...adjacentSquares(squareAbove).filter((s) => canEnemyPawnCaptureOnSquare(enemySquare, s, ctx)),
3153
+ ...[squareAbove, squareShiftedVertically(squareAbove, enemyStep)].filter((s) => !!s).filter((s) => canEnemyPawnAdvanceToSquare(enemySquare, s, ctx))
3154
+ ] : [];
3155
+ const badSquares = [...squaresBetween2, ctx.orig.key];
3156
+ return enemyPawnDests.some((square) => !badSquares.includes(square));
3157
+ };
3158
+ var isPathClearEnoughForPremove = (ctx, isPawnAdvance) => isPathClearEnoughOfFriendliesForPremove(ctx, isPawnAdvance) && isPathClearEnoughOfEnemiesForPremove(ctx, isPawnAdvance);
3159
+ var pawn = (ctx) => {
3160
+ const step2 = ctx.color === "white" ? 1 : -1;
3161
+ if (diff(ctx.orig.pos[0], ctx.dest.pos[0]) > 1)
3162
+ return false;
3163
+ if (!diff(ctx.orig.pos[0], ctx.dest.pos[0]))
3164
+ return pawnDirAdvance(...ctx.orig.pos, ...ctx.dest.pos, ctx.color === "white") && isPathClearEnoughForPremove(ctx, true);
3165
+ if (ctx.dest.pos[1] !== ctx.orig.pos[1] + step2)
3166
+ return false;
3167
+ if (ctx.unrestrictedPremoves || isDestOccupiedByEnemy(ctx))
3168
+ return true;
3169
+ if (isDestOccupiedByFriendly(ctx))
3170
+ return isDestControlledByEnemy(ctx);
3171
+ else
3172
+ return canSomeEnemyPawnAdvanceToDest(ctx) || canBeCapturedBySomeEnemyEnPassant(pos2key([ctx.dest.pos[0], ctx.dest.pos[1] + step2]), ctx.friendlies, ctx.enemies, ctx.lastMove) || isDestControlledByEnemy(ctx, ["pawn"]);
3173
+ };
3174
+ var knight = (ctx) => knightDir(...ctx.orig.pos, ...ctx.dest.pos) && (ctx.unrestrictedPremoves || !isDestOccupiedByFriendly(ctx) || isFriendlyOnDestAndAttacked(ctx));
3175
+ var bishop = (ctx) => bishopDir(...ctx.orig.pos, ...ctx.dest.pos) && isPathClearEnoughForPremove(ctx, false) && (ctx.unrestrictedPremoves || !isDestOccupiedByFriendly(ctx) || isFriendlyOnDestAndAttacked(ctx));
3176
+ var rook = (ctx) => rookDir(...ctx.orig.pos, ...ctx.dest.pos) && isPathClearEnoughForPremove(ctx, false) && (ctx.unrestrictedPremoves || !isDestOccupiedByFriendly(ctx) || isFriendlyOnDestAndAttacked(ctx));
3177
+ var queen = (ctx) => bishop(ctx) || rook(ctx);
3178
+ var king = (ctx) => kingDirNonCastling(...ctx.orig.pos, ...ctx.dest.pos) && (ctx.unrestrictedPremoves || !isDestOccupiedByFriendly(ctx) || isFriendlyOnDestAndAttacked(ctx)) || ctx.canCastle && ctx.orig.pos[1] === ctx.dest.pos[1] && ctx.orig.pos[1] === (ctx.color === "white" ? 0 : 7) && (ctx.orig.pos[0] === 4 && (ctx.dest.pos[0] === 2 && ctx.rookFilesFriendlies.includes(0) || ctx.dest.pos[0] === 6 && ctx.rookFilesFriendlies.includes(7)) || ctx.rookFilesFriendlies.includes(ctx.dest.pos[0])) && (ctx.unrestrictedPremoves || /* The following checks if no non-rook friendly piece is in the way between the king and its castling destination.
3179
+ Note that for the Chess960 edge case of Kb1 "long castling", the check passes even if there is a piece in the way
3180
+ on c1. But this is fine, since premoving from b1 to a1 as a normal move would have already returned true. */
3181
+ squaresBetween(...ctx.orig.pos, ctx.dest.pos[0] > ctx.orig.pos[0] ? 7 : 1, ctx.dest.pos[1]).map((s) => ctx.allPieces.get(s)).every((p) => !p || samePiece(p, { role: "rook", color: ctx.color })));
3182
+ var mobilityByRole = { pawn, knight, bishop, rook, queen, king };
3183
+ function premove(state, key) {
3184
+ const pieces = state.pieces, canCastle = state.premovable.castle, unrestrictedPremoves = !!state.premovable.unrestrictedPremoves;
3077
3185
  const piece = pieces.get(key);
3078
- if (!piece)
3186
+ if (!piece || piece.color === state.turnColor)
3079
3187
  return [];
3080
- const pos = key2pos(key), r = piece.role, mobility = r === "pawn" ? pawn(piece.color) : r === "knight" ? knight : r === "bishop" ? bishop : r === "rook" ? rook : r === "queen" ? queen : king(piece.color, rookFilesOf(pieces, piece.color), canCastle);
3081
- return allPos.filter((pos2) => (pos[0] !== pos2[0] || pos[1] !== pos2[1]) && mobility(pos[0], pos[1], pos2[0], pos2[1])).map(pos2key);
3188
+ const color = piece.color, friendlies = new Map([...pieces].filter(([_, p]) => p.color === color)), enemies = new Map([...pieces].filter(([_, p]) => p.color === opposite2(color))), orig = { key, pos: key2pos(key) }, mobility = (ctx) => mobilityByRole[piece.role](ctx) && state.premovable.additionalPremoveRequirements(ctx), partialCtx = {
3189
+ orig,
3190
+ role: piece.role,
3191
+ allPieces: pieces,
3192
+ friendlies,
3193
+ enemies,
3194
+ unrestrictedPremoves,
3195
+ color,
3196
+ canCastle,
3197
+ rookFilesFriendlies: Array.from(pieces).filter(([k, p]) => k[1] === (color === "white" ? "1" : "8") && p.color === color && p.role === "rook").map(([k]) => key2pos(k)[0]),
3198
+ lastMove: state.lastMove
3199
+ };
3200
+ return allPosAndKey.filter((dest) => mobility({ ...partialCtx, dest })).map((pk) => pk.key);
3082
3201
  }
3083
3202
 
3084
- // node_modules/.pnpm/chessground@9.2.1/node_modules/chessground/dist/board.js
3203
+ // node_modules/.pnpm/@lichess-org+chessground@9.8.2/node_modules/@lichess-org/chessground/dist/board.js
3085
3204
  function callUserFunction(f, ...args) {
3086
3205
  if (f)
3087
3206
  setTimeout(() => f(...args), 1);
@@ -3144,9 +3263,9 @@ function tryAutoCastle(state, orig, dest) {
3144
3263
  return false;
3145
3264
  if (origPos[0] === 4 && !state.pieces.has(dest)) {
3146
3265
  if (destPos[0] === 6)
3147
- dest = pos2key([7, destPos[1]]);
3266
+ dest = pos2keyUnsafe([7, destPos[1]]);
3148
3267
  else if (destPos[0] === 2)
3149
- dest = pos2key([0, destPos[1]]);
3268
+ dest = pos2keyUnsafe([0, destPos[1]]);
3150
3269
  }
3151
3270
  const rook2 = state.pieces.get(dest);
3152
3271
  if (!rook2 || rook2.color !== king2.color || rook2.role !== "rook")
@@ -3154,11 +3273,11 @@ function tryAutoCastle(state, orig, dest) {
3154
3273
  state.pieces.delete(orig);
3155
3274
  state.pieces.delete(dest);
3156
3275
  if (origPos[0] < destPos[0]) {
3157
- state.pieces.set(pos2key([6, destPos[1]]), king2);
3158
- state.pieces.set(pos2key([5, destPos[1]]), rook2);
3276
+ state.pieces.set(pos2keyUnsafe([6, destPos[1]]), king2);
3277
+ state.pieces.set(pos2keyUnsafe([5, destPos[1]]), rook2);
3159
3278
  } else {
3160
- state.pieces.set(pos2key([2, destPos[1]]), king2);
3161
- state.pieces.set(pos2key([3, destPos[1]]), rook2);
3279
+ state.pieces.set(pos2keyUnsafe([2, destPos[1]]), king2);
3280
+ state.pieces.set(pos2keyUnsafe([3, destPos[1]]), rook2);
3162
3281
  }
3163
3282
  return true;
3164
3283
  }
@@ -3269,12 +3388,10 @@ function selectSquare(state, key, force) {
3269
3388
  }
3270
3389
  function setSelected(state, key) {
3271
3390
  state.selected = key;
3272
- if (isPremovable(state, key)) {
3273
- if (!state.premovable.customDests) {
3274
- state.premovable.dests = premove(state.pieces, key, state.premovable.castle);
3275
- }
3276
- } else
3391
+ if (!isPremovable(state, key))
3277
3392
  state.premovable.dests = void 0;
3393
+ else if (!state.premovable.customDests)
3394
+ state.premovable.dests = premove(state, key);
3278
3395
  }
3279
3396
  function unselect(state) {
3280
3397
  state.selected = void 0;
@@ -3285,10 +3402,7 @@ function isMovable(state, orig) {
3285
3402
  const piece = state.pieces.get(orig);
3286
3403
  return !!piece && (state.movable.color === "both" || state.movable.color === piece.color && state.turnColor === piece.color);
3287
3404
  }
3288
- var canMove = (state, orig, dest) => {
3289
- var _a, _b;
3290
- return orig !== dest && isMovable(state, orig) && (state.movable.free || !!((_b = (_a = state.movable.dests) === null || _a === void 0 ? void 0 : _a.get(orig)) === null || _b === void 0 ? void 0 : _b.includes(dest)));
3291
- };
3405
+ var canMove = (state, orig, dest) => orig !== dest && isMovable(state, orig) && (state.movable.free || !!state.movable.dests?.get(orig)?.includes(dest));
3292
3406
  function canDrop(state, orig, dest) {
3293
3407
  const piece = state.pieces.get(orig);
3294
3408
  return !!piece && (orig === dest || !state.pieces.has(dest)) && (state.movable.color === "both" || state.movable.color === piece.color && state.turnColor === piece.color);
@@ -3297,11 +3411,7 @@ function isPremovable(state, orig) {
3297
3411
  const piece = state.pieces.get(orig);
3298
3412
  return !!piece && state.premovable.enabled && state.movable.color === piece.color && state.turnColor !== piece.color;
3299
3413
  }
3300
- function canPremove(state, orig, dest) {
3301
- var _a, _b;
3302
- const validPremoves = (_b = (_a = state.premovable.customDests) === null || _a === void 0 ? void 0 : _a.get(orig)) !== null && _b !== void 0 ? _b : premove(state.pieces, orig, state.premovable.castle);
3303
- return orig !== dest && isPremovable(state, orig) && validPremoves.includes(dest);
3304
- }
3414
+ var canPremove = (state, orig, dest) => orig !== dest && isPremovable(state, orig) && (state.premovable.customDests?.get(orig) ?? premove(state, orig)).includes(dest);
3305
3415
  function canPredrop(state, orig, dest) {
3306
3416
  const piece = state.pieces.get(orig);
3307
3417
  const destPiece = state.pieces.get(dest);
@@ -3371,15 +3481,15 @@ function getKeyAtDomPos(pos, asWhite, bounds) {
3371
3481
  }
3372
3482
  function getSnappedKeyAtDomPos(orig, pos, asWhite, bounds) {
3373
3483
  const origPos = key2pos(orig);
3374
- const validSnapPos = allPos.filter((pos2) => queen(origPos[0], origPos[1], pos2[0], pos2[1]) || knight(origPos[0], origPos[1], pos2[0], pos2[1]));
3375
- const validSnapCenters = validSnapPos.map((pos2) => computeSquareCenter(pos2key(pos2), asWhite, bounds));
3484
+ const validSnapPos = allPos.filter((pos2) => samePos(origPos, pos2) || queenDir(origPos[0], origPos[1], pos2[0], pos2[1]) || knightDir(origPos[0], origPos[1], pos2[0], pos2[1]));
3485
+ const validSnapCenters = validSnapPos.map((pos2) => computeSquareCenter(pos2keyUnsafe(pos2), asWhite, bounds));
3376
3486
  const validSnapDistances = validSnapCenters.map((pos2) => distanceSq(pos, pos2));
3377
3487
  const [, closestSnapIndex] = validSnapDistances.reduce((a, b, index) => a[0] < b ? a : [b, index], [validSnapDistances[0], 0]);
3378
3488
  return pos2key(validSnapPos[closestSnapIndex]);
3379
3489
  }
3380
3490
  var whitePov = (s) => s.orientation === "white";
3381
3491
 
3382
- // node_modules/.pnpm/chessground@9.2.1/node_modules/chessground/dist/fen.js
3492
+ // node_modules/.pnpm/@lichess-org+chessground@9.8.2/node_modules/@lichess-org/chessground/dist/fen.js
3383
3493
  var initial = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR";
3384
3494
  var roles = {
3385
3495
  p: "pawn",
@@ -3414,7 +3524,8 @@ function read(fen) {
3414
3524
  col = 0;
3415
3525
  break;
3416
3526
  case "~": {
3417
- const piece = pieces.get(pos2key([col - 1, row]));
3527
+ const k = pos2key([col - 1, row]);
3528
+ const piece = k && pieces.get(k);
3418
3529
  if (piece)
3419
3530
  piece.promoted = true;
3420
3531
  break;
@@ -3425,10 +3536,12 @@ function read(fen) {
3425
3536
  col += nb - 48;
3426
3537
  else {
3427
3538
  const role = c.toLowerCase();
3428
- pieces.set(pos2key([col, row]), {
3429
- role: roles[role],
3430
- color: c === role ? "black" : "white"
3431
- });
3539
+ const key = pos2key([col, row]);
3540
+ if (key)
3541
+ pieces.set(key, {
3542
+ role: roles[role],
3543
+ color: c === role ? "black" : "white"
3544
+ });
3432
3545
  ++col;
3433
3546
  }
3434
3547
  }
@@ -3451,7 +3564,7 @@ function write(pieces) {
3451
3564
  }).join("")).join("/").replace(/1{2,}/g, (s) => s.length.toString());
3452
3565
  }
3453
3566
 
3454
- // node_modules/.pnpm/chessground@9.2.1/node_modules/chessground/dist/config.js
3567
+ // node_modules/.pnpm/@lichess-org+chessground@9.8.2/node_modules/@lichess-org/chessground/dist/config.js
3455
3568
  function applyAnimation(state, config) {
3456
3569
  if (config.animation) {
3457
3570
  deepMerge(state.animation, config.animation);
@@ -3460,15 +3573,14 @@ function applyAnimation(state, config) {
3460
3573
  }
3461
3574
  }
3462
3575
  function configure(state, config) {
3463
- var _a, _b, _c;
3464
- if ((_a = config.movable) === null || _a === void 0 ? void 0 : _a.dests)
3576
+ if (config.movable?.dests)
3465
3577
  state.movable.dests = void 0;
3466
- if ((_b = config.drawable) === null || _b === void 0 ? void 0 : _b.autoShapes)
3578
+ if (config.drawable?.autoShapes)
3467
3579
  state.drawable.autoShapes = [];
3468
3580
  deepMerge(state, config);
3469
3581
  if (config.fen) {
3470
3582
  state.pieces = read(config.fen);
3471
- state.drawable.shapes = ((_c = config.drawable) === null || _c === void 0 ? void 0 : _c.shapes) || [];
3583
+ state.drawable.shapes = config.drawable?.shapes || [];
3472
3584
  }
3473
3585
  if ("check" in config)
3474
3586
  setCheck(state, config.check || false);
@@ -3503,7 +3615,7 @@ function isPlainObject(o) {
3503
3615
  return proto === Object.prototype || proto === null;
3504
3616
  }
3505
3617
 
3506
- // node_modules/.pnpm/chessground@9.2.1/node_modules/chessground/dist/anim.js
3618
+ // node_modules/.pnpm/@lichess-org+chessground@9.8.2/node_modules/@lichess-org/chessground/dist/anim.js
3507
3619
  var anim = (mutation, state) => state.animation.enabled ? animate(mutation, state) : render(mutation, state);
3508
3620
  function render(mutation, state) {
3509
3621
  const result = mutation(state);
@@ -3594,7 +3706,7 @@ function animate(mutation, state) {
3594
3706
  }
3595
3707
  var easing = (t) => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
3596
3708
 
3597
- // node_modules/.pnpm/chessground@9.2.1/node_modules/chessground/dist/draw.js
3709
+ // node_modules/.pnpm/@lichess-org+chessground@9.8.2/node_modules/@lichess-org/chessground/dist/draw.js
3598
3710
  var brushes = ["green", "red", "blue", "yellow"];
3599
3711
  function start(state, e) {
3600
3712
  if (e.touches && e.touches.length > 1)
@@ -3657,9 +3769,8 @@ function clear(state) {
3657
3769
  }
3658
3770
  }
3659
3771
  function eventBrush(e) {
3660
- var _a;
3661
3772
  const modA = (e.shiftKey || e.ctrlKey) && isRightButton(e);
3662
- const modB = e.altKey || e.metaKey || ((_a = e.getModifierState) === null || _a === void 0 ? void 0 : _a.call(e, "AltGraph"));
3773
+ const modB = e.altKey || e.metaKey || e.getModifierState?.("AltGraph");
3663
3774
  return brushes[(modA ? 1 : 0) + (modB ? 2 : 0)];
3664
3775
  }
3665
3776
  function addShape(drawable, cur) {
@@ -3680,7 +3791,7 @@ function onChange(drawable) {
3680
3791
  drawable.onChange(drawable.shapes);
3681
3792
  }
3682
3793
 
3683
- // node_modules/.pnpm/chessground@9.2.1/node_modules/chessground/dist/drag.js
3794
+ // node_modules/.pnpm/@lichess-org+chessground@9.8.2/node_modules/@lichess-org/chessground/dist/drag.js
3684
3795
  function start2(s, e) {
3685
3796
  if (!(s.trustAllEvents || e.isTrusted))
3686
3797
  return;
@@ -3693,8 +3804,8 @@ function start2(s, e) {
3693
3804
  return;
3694
3805
  const piece = s.pieces.get(orig);
3695
3806
  const previouslySelected = s.selected;
3696
- if (!previouslySelected && s.drawable.enabled && (s.drawable.eraseOnClick || !piece || piece.color !== s.turnColor))
3697
- clear(s);
3807
+ if (!previouslySelected && s.drawable.enabled && (s.drawable.eraseOnMovablePieceClick || !piece || piece.color !== s.turnColor))
3808
+ s.pixelCoordsOfMouchDownToMaybeClearShapes = position;
3698
3809
  if (e.cancelable !== false && (!e.touches || s.blockTouchScroll || piece || previouslySelected || pieceCloseTo(s, position)))
3699
3810
  e.preventDefault();
3700
3811
  else if (e.touches)
@@ -3739,7 +3850,7 @@ function start2(s, e) {
3739
3850
  s.dom.redraw();
3740
3851
  }
3741
3852
  function pieceCloseTo(s, pos) {
3742
- const asWhite = whitePov(s), bounds = s.dom.bounds(), radiusSq = Math.pow(bounds.width / 8, 2);
3853
+ const asWhite = whitePov(s), bounds = s.dom.bounds(), radiusSq = Math.pow(s.touchIgnoreRadius * bounds.width / 16, 2) * 2;
3743
3854
  for (const key of s.pieces.keys()) {
3744
3855
  const center = computeSquareCenter(key, asWhite, bounds);
3745
3856
  if (distanceSq(center, pos) <= radiusSq)
@@ -3768,11 +3879,10 @@ function dragNewPiece(s, piece, e, force) {
3768
3879
  }
3769
3880
  function processDrag(s) {
3770
3881
  requestAnimationFrame(() => {
3771
- var _a;
3772
3882
  const cur = s.draggable.current;
3773
3883
  if (!cur)
3774
3884
  return;
3775
- if ((_a = s.animation.current) === null || _a === void 0 ? void 0 : _a.plan.anims.has(cur.orig))
3885
+ if (s.animation.current?.plan.anims.has(cur.orig))
3776
3886
  s.animation.current = void 0;
3777
3887
  const origPiece = s.pieces.get(cur.orig);
3778
3888
  if (!origPiece || !samePiece(origPiece, cur.piece))
@@ -3806,6 +3916,10 @@ function move2(s, e) {
3806
3916
  }
3807
3917
  }
3808
3918
  function end2(s, e) {
3919
+ const position = eventPosition(e);
3920
+ if (position && s.pixelCoordsOfMouchDownToMaybeClearShapes && samePos(position, s.pixelCoordsOfMouchDownToMaybeClearShapes))
3921
+ clear(s);
3922
+ s.pixelCoordsOfMouchDownToMaybeClearShapes = void 0;
3809
3923
  const cur = s.draggable.current;
3810
3924
  if (!cur)
3811
3925
  return;
@@ -3867,7 +3981,7 @@ function pieceElementByKey(s, key) {
3867
3981
  return;
3868
3982
  }
3869
3983
 
3870
- // node_modules/.pnpm/chessground@9.2.1/node_modules/chessground/dist/explosion.js
3984
+ // node_modules/.pnpm/@lichess-org+chessground@9.8.2/node_modules/@lichess-org/chessground/dist/explosion.js
3871
3985
  function explosion(state, keys) {
3872
3986
  state.exploding = { stage: 1, keys };
3873
3987
  state.dom.redraw();
@@ -3886,7 +4000,7 @@ function setStage(state, stage) {
3886
4000
  }
3887
4001
  }
3888
4002
 
3889
- // node_modules/.pnpm/chessground@9.2.1/node_modules/chessground/dist/api.js
4003
+ // node_modules/.pnpm/@lichess-org+chessground@9.8.2/node_modules/@lichess-org/chessground/dist/api.js
3890
4004
  function start3(state, redrawAll) {
3891
4005
  function toggleOrientation2() {
3892
4006
  toggleOrientation(state);
@@ -3960,7 +4074,7 @@ function start3(state, redrawAll) {
3960
4074
  render((state2) => state2.drawable.autoShapes = shapes, state);
3961
4075
  },
3962
4076
  setShapes(shapes) {
3963
- render((state2) => state2.drawable.shapes = shapes, state);
4077
+ render((state2) => state2.drawable.shapes = shapes.slice(), state);
3964
4078
  },
3965
4079
  getKeyAtDomPos(pos) {
3966
4080
  return getKeyAtDomPos(pos, whitePov(state), state.dom.bounds());
@@ -3977,7 +4091,7 @@ function start3(state, redrawAll) {
3977
4091
  };
3978
4092
  }
3979
4093
 
3980
- // node_modules/.pnpm/chessground@9.2.1/node_modules/chessground/dist/state.js
4094
+ // node_modules/.pnpm/@lichess-org+chessground@9.8.2/node_modules/@lichess-org/chessground/dist/state.js
3981
4095
  function defaults() {
3982
4096
  return {
3983
4097
  pieces: read(initial),
@@ -3991,6 +4105,7 @@ function defaults() {
3991
4105
  disableContextMenu: false,
3992
4106
  addPieceZIndex: false,
3993
4107
  blockTouchScroll: false,
4108
+ touchIgnoreRadius: 1,
3994
4109
  pieceKey: false,
3995
4110
  trustAllEvents: false,
3996
4111
  highlight: {
@@ -4012,6 +4127,7 @@ function defaults() {
4012
4127
  enabled: true,
4013
4128
  showDests: true,
4014
4129
  castle: true,
4130
+ additionalPremoveRequirements: (_) => true,
4015
4131
  events: {}
4016
4132
  },
4017
4133
  predroppable: {
@@ -4043,7 +4159,7 @@ function defaults() {
4043
4159
  visible: true,
4044
4160
  // can view
4045
4161
  defaultSnapToValidMove: true,
4046
- eraseOnClick: true,
4162
+ eraseOnMovablePieceClick: true,
4047
4163
  shapes: [],
4048
4164
  autoShapes: [],
4049
4165
  brushes: {
@@ -4062,7 +4178,8 @@ function defaults() {
4062
4178
  },
4063
4179
  purple: { key: "purple", color: "#68217a", opacity: 0.65, lineWidth: 10 },
4064
4180
  pink: { key: "pink", color: "#ee2080", opacity: 0.5, lineWidth: 10 },
4065
- white: { key: "white", color: "white", opacity: 1, lineWidth: 10 }
4181
+ white: { key: "white", color: "white", opacity: 1, lineWidth: 10 },
4182
+ paleWhite: { key: "pwhite", color: "white", opacity: 0.6, lineWidth: 10 }
4066
4183
  },
4067
4184
  prevSvgHash: ""
4068
4185
  },
@@ -4070,35 +4187,31 @@ function defaults() {
4070
4187
  };
4071
4188
  }
4072
4189
 
4073
- // node_modules/.pnpm/chessground@9.2.1/node_modules/chessground/dist/svg.js
4074
- var hilites = {
4075
- hilitePrimary: { key: "hilitePrimary", color: "#3291ff", opacity: 1, lineWidth: 1 },
4076
- hiliteWhite: { key: "hiliteWhite", color: "#ffffff", opacity: 1, lineWidth: 1 }
4077
- };
4190
+ // node_modules/.pnpm/@lichess-org+chessground@9.8.2/node_modules/@lichess-org/chessground/dist/svg.js
4078
4191
  function createDefs() {
4079
4192
  const defs = createElement("defs");
4080
4193
  const filter = setAttributes(createElement("filter"), { id: "cg-filter-blur" });
4081
- filter.appendChild(setAttributes(createElement("feGaussianBlur"), { stdDeviation: "0.019" }));
4194
+ filter.appendChild(setAttributes(createElement("feGaussianBlur"), { stdDeviation: "0.013" }));
4082
4195
  defs.appendChild(filter);
4083
4196
  return defs;
4084
4197
  }
4085
- function renderSvg(state, shapesEl, customsEl) {
4086
- var _a;
4198
+ function renderSvg(state, els) {
4087
4199
  const d = state.drawable, curD = d.current, cur = curD && curD.mouseSq ? curD : void 0, dests = /* @__PURE__ */ new Map(), bounds = state.dom.bounds(), nonPieceAutoShapes = d.autoShapes.filter((autoShape) => !autoShape.piece);
4088
4200
  for (const s of d.shapes.concat(nonPieceAutoShapes).concat(cur ? [cur] : [])) {
4089
4201
  if (!s.dest)
4090
4202
  continue;
4091
- const sources = (_a = dests.get(s.dest)) !== null && _a !== void 0 ? _a : /* @__PURE__ */ new Set(), from = pos2user(orient(key2pos(s.orig), state.orientation), bounds), to = pos2user(orient(key2pos(s.dest), state.orientation), bounds);
4203
+ const sources = dests.get(s.dest) ?? /* @__PURE__ */ new Set(), from = pos2user(orient(key2pos(s.orig), state.orientation), bounds), to = pos2user(orient(key2pos(s.dest), state.orientation), bounds);
4092
4204
  sources.add(moveAngle(from, to));
4093
4205
  dests.set(s.dest, sources);
4094
4206
  }
4095
- const shapes = d.shapes.concat(nonPieceAutoShapes).map((s) => {
4096
- return {
4207
+ const shapes = [];
4208
+ for (const s of d.shapes.concat(nonPieceAutoShapes)) {
4209
+ shapes.push({
4097
4210
  shape: s,
4098
4211
  current: false,
4099
4212
  hash: shapeHash(s, isShort(s.dest, dests), false, bounds)
4100
- };
4101
- });
4213
+ });
4214
+ }
4102
4215
  if (cur)
4103
4216
  shapes.push({
4104
4217
  shape: cur,
@@ -4109,60 +4222,68 @@ function renderSvg(state, shapesEl, customsEl) {
4109
4222
  if (fullHash === state.drawable.prevSvgHash)
4110
4223
  return;
4111
4224
  state.drawable.prevSvgHash = fullHash;
4112
- const defsEl = shapesEl.querySelector("defs");
4113
- syncDefs(d, shapes, defsEl);
4114
- syncShapes(shapes, shapesEl.querySelector("g"), customsEl.querySelector("g"), (s) => renderShape(state, s, d.brushes, dests, bounds));
4115
- }
4116
- function syncDefs(d, shapes, defsEl) {
4117
- var _a;
4118
- const brushes2 = /* @__PURE__ */ new Map();
4119
- let brush;
4120
- for (const s of shapes.filter((s2) => s2.shape.dest && s2.shape.brush)) {
4121
- brush = makeCustomBrush(d.brushes[s.shape.brush], s.shape.modifiers);
4122
- if ((_a = s.shape.modifiers) === null || _a === void 0 ? void 0 : _a.hilite)
4123
- brushes2.set(hilite(brush).key, hilite(brush));
4124
- brushes2.set(brush.key, brush);
4125
- }
4126
- const keysInDom = /* @__PURE__ */ new Set();
4127
- let el = defsEl.firstElementChild;
4128
- while (el) {
4129
- keysInDom.add(el.getAttribute("cgKey"));
4130
- el = el.nextElementSibling;
4131
- }
4132
- for (const [key, brush2] of brushes2.entries()) {
4133
- if (!keysInDom.has(key))
4134
- defsEl.appendChild(renderMarker(brush2));
4135
- }
4136
- }
4137
- function syncShapes(syncables, shapes, customs, renderShape3) {
4138
- const hashesInDom = /* @__PURE__ */ new Map();
4139
- for (const sc of syncables)
4140
- hashesInDom.set(sc.hash, false);
4141
- for (const root of [shapes, customs]) {
4142
- const toRemove = [];
4143
- let el = root.firstElementChild, elHash;
4225
+ syncDefs(d, shapes, els);
4226
+ syncShapes(shapes, els, (s) => renderShape(state, s, d.brushes, dests, bounds));
4227
+ }
4228
+ function syncDefs(d, shapes, els) {
4229
+ for (const shapesEl of [els.shapes, els.shapesBelow]) {
4230
+ const defsEl = shapesEl.querySelector("defs");
4231
+ const thisPlane = shapes.filter((s) => shapesEl === els.shapesBelow === !!s.shape.below);
4232
+ const brushes2 = /* @__PURE__ */ new Map();
4233
+ for (const s of thisPlane.filter((s2) => s2.shape.dest && s2.shape.brush)) {
4234
+ const brush = makeCustomBrush(d.brushes[s.shape.brush], s.shape.modifiers);
4235
+ const { key, color } = hiliteOf(s.shape);
4236
+ if (key && color)
4237
+ brushes2.set(key, { key, color, opacity: 1, lineWidth: 1 });
4238
+ brushes2.set(brush.key, brush);
4239
+ }
4240
+ const keysInDom = /* @__PURE__ */ new Set();
4241
+ let el = defsEl.firstElementChild;
4144
4242
  while (el) {
4145
- elHash = el.getAttribute("cgHash");
4146
- if (hashesInDom.has(elHash))
4147
- hashesInDom.set(elHash, true);
4148
- else
4149
- toRemove.push(el);
4243
+ keysInDom.add(el.getAttribute("cgKey"));
4150
4244
  el = el.nextElementSibling;
4151
4245
  }
4152
- for (const el2 of toRemove)
4153
- root.removeChild(el2);
4154
- }
4155
- for (const sc of syncables.filter((s) => !hashesInDom.get(s.hash))) {
4156
- for (const svg of renderShape3(sc)) {
4157
- if (svg.isCustom)
4158
- customs.appendChild(svg.el);
4159
- else
4160
- shapes.appendChild(svg.el);
4246
+ for (const [key, brush] of brushes2.entries()) {
4247
+ if (!keysInDom.has(key))
4248
+ defsEl.appendChild(renderMarker(brush));
4249
+ }
4250
+ }
4251
+ }
4252
+ function syncShapes(shapes, els, renderShape3) {
4253
+ for (const [shapesEl, customEl] of [
4254
+ [els.shapes, els.custom],
4255
+ [els.shapesBelow, els.customBelow]
4256
+ ]) {
4257
+ const [shapesG, customG] = [shapesEl, customEl].map((el) => el.querySelector("g"));
4258
+ const thisPlane = shapes.filter((s) => shapesEl === els.shapesBelow === !!s.shape.below);
4259
+ const hashesInDom = /* @__PURE__ */ new Map();
4260
+ for (const sc of thisPlane)
4261
+ hashesInDom.set(sc.hash, false);
4262
+ for (const root of [shapesG, customG]) {
4263
+ const toRemove = [];
4264
+ let el = root.firstElementChild, elHash;
4265
+ while (el) {
4266
+ elHash = el.getAttribute("cgHash");
4267
+ if (hashesInDom.has(elHash))
4268
+ hashesInDom.set(elHash, true);
4269
+ else
4270
+ toRemove.push(el);
4271
+ el = el.nextElementSibling;
4272
+ }
4273
+ for (const el2 of toRemove)
4274
+ root.removeChild(el2);
4275
+ }
4276
+ for (const sc of thisPlane.filter((s) => !hashesInDom.get(s.hash))) {
4277
+ for (const svg of renderShape3(sc)) {
4278
+ if (svg.isCustom)
4279
+ customG.appendChild(svg.el);
4280
+ else
4281
+ shapesG.appendChild(svg.el);
4282
+ }
4161
4283
  }
4162
4284
  }
4163
4285
  }
4164
- function shapeHash({ orig, dest, brush, piece, modifiers, customSvg, label }, shorten, current, bounds) {
4165
- var _a, _b;
4286
+ function shapeHash({ orig, dest, brush, piece, modifiers, customSvg, label, below }, shorten, current, bounds) {
4166
4287
  return [
4167
4288
  bounds.width,
4168
4289
  bounds.height,
@@ -4173,15 +4294,16 @@ function shapeHash({ orig, dest, brush, piece, modifiers, customSvg, label }, sh
4173
4294
  shorten && "-",
4174
4295
  piece && pieceHash(piece),
4175
4296
  modifiers && modifiersHash(modifiers),
4176
- customSvg && `custom-${textHash(customSvg.html)},${(_b = (_a = customSvg.center) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : "o"}`,
4177
- label && `label-${textHash(label.text)}`
4297
+ customSvg && `custom-${textHash(customSvg.html)},${customSvg.center?.[0] ?? "o"}`,
4298
+ label && `label-${textHash(label.text)}`,
4299
+ below && "below"
4178
4300
  ].filter((x) => x).join(",");
4179
4301
  }
4180
4302
  function pieceHash(piece) {
4181
4303
  return [piece.color, piece.role, piece.scale].filter((x) => x).join(",");
4182
4304
  }
4183
4305
  function modifiersHash(m) {
4184
- return [m.lineWidth, m.hilite && "*"].filter((x) => x).join(",");
4306
+ return [m.lineWidth, m.hilite].filter((x) => x).join(",");
4185
4307
  }
4186
4308
  function textHash(s) {
4187
4309
  let h2 = 0;
@@ -4191,7 +4313,6 @@ function textHash(s) {
4191
4313
  return h2.toString();
4192
4314
  }
4193
4315
  function renderShape(state, { shape, current, hash: hash2 }, brushes2, dests, bounds) {
4194
- var _a, _b;
4195
4316
  const from = pos2user(orient(key2pos(shape.orig), state.orientation), bounds), to = shape.dest ? pos2user(orient(key2pos(shape.dest), state.orientation), bounds) : from, brush = shape.brush && makeCustomBrush(brushes2[shape.brush], shape.modifiers), slots = dests.get(shape.dest), svgs = [];
4196
4317
  if (brush) {
4197
4318
  const el = setAttributes(createElement("g"), { cgHash: hash2 });
@@ -4203,12 +4324,12 @@ function renderShape(state, { shape, current, hash: hash2 }, brushes2, dests, bo
4203
4324
  }
4204
4325
  if (shape.label) {
4205
4326
  const label = shape.label;
4206
- (_a = label.fill) !== null && _a !== void 0 ? _a : label.fill = shape.brush && brushes2[shape.brush].color;
4327
+ label.fill ?? (label.fill = shape.brush && brushes2[shape.brush].color);
4207
4328
  const corner = shape.brush ? void 0 : "tr";
4208
4329
  svgs.push({ el: renderLabel(label, hash2, from, to, slots, corner), isCustom: true });
4209
4330
  }
4210
4331
  if (shape.customSvg) {
4211
- const on = (_b = shape.customSvg.center) !== null && _b !== void 0 ? _b : "orig";
4332
+ const on = shape.customSvg.center ?? "orig";
4212
4333
  const [x, y] = on === "label" ? labelCoords(from, to, slots).map((c) => c - 0.5) : on === "dest" ? to : from;
4213
4334
  const el = setAttributes(createElement("g"), { transform: `translate(${x},${y})`, cgHash: hash2 });
4214
4335
  el.innerHTML = `<svg width="1" height="1" viewBox="0 0 100 100">${shape.customSvg.html}</svg>`;
@@ -4228,29 +4349,25 @@ function renderCircle(brush, at, current, bounds) {
4228
4349
  r: radius - widths[1] / 2
4229
4350
  });
4230
4351
  }
4231
- function hilite(brush) {
4232
- return ["#ffffff", "#fff", "white"].includes(brush.color) ? hilites["hilitePrimary"] : hilites["hiliteWhite"];
4233
- }
4234
4352
  function renderArrow(s, brush, from, to, current, shorten) {
4235
- var _a;
4236
4353
  function renderLine(isHilite) {
4237
- var _a2;
4238
4354
  const m = arrowMargin(shorten && !current), dx = to[0] - from[0], dy = to[1] - from[1], angle = Math.atan2(dy, dx), xo = Math.cos(angle) * m, yo = Math.sin(angle) * m;
4355
+ const hilite = hiliteOf(s);
4239
4356
  return setAttributes(createElement("line"), {
4240
- stroke: isHilite ? hilite(brush).color : brush.color,
4241
- "stroke-width": lineWidth(brush, current) + (isHilite ? 0.04 : 0),
4357
+ stroke: isHilite ? hilite.color : brush.color,
4358
+ "stroke-width": lineWidth(brush, current) * (isHilite ? 1.14 : 1),
4242
4359
  "stroke-linecap": "round",
4243
- "marker-end": `url(#arrowhead-${isHilite ? hilite(brush).key : brush.key})`,
4244
- opacity: ((_a2 = s.modifiers) === null || _a2 === void 0 ? void 0 : _a2.hilite) ? 1 : opacity(brush, current),
4360
+ "marker-end": `url(#arrowhead-${isHilite ? hilite.key : brush.key})`,
4361
+ opacity: s.modifiers?.hilite ? 1 : opacity(brush, current),
4245
4362
  x1: from[0],
4246
4363
  y1: from[1],
4247
4364
  x2: to[0] - xo,
4248
4365
  y2: to[1] - yo
4249
4366
  });
4250
4367
  }
4251
- if (!((_a = s.modifiers) === null || _a === void 0 ? void 0 : _a.hilite))
4368
+ if (!s.modifiers?.hilite)
4252
4369
  return renderLine(false);
4253
- const g = createElement("g");
4370
+ const g = setAttributes(createElement("g"), { opacity: brush.opacity });
4254
4371
  const blurred = setAttributes(createElement("g"), { filter: "url(#cg-filter-blur)" });
4255
4372
  blurred.appendChild(filterBox(from, to));
4256
4373
  blurred.appendChild(renderLine(true));
@@ -4276,7 +4393,6 @@ function renderMarker(brush) {
4276
4393
  return marker;
4277
4394
  }
4278
4395
  function renderLabel(label, hash2, from, to, slots, corner) {
4279
- var _a;
4280
4396
  const labelSize = 0.4, fontSize = labelSize * 0.75 ** label.text.length, at = labelCoords(from, to, slots), cornerOff = corner === "tr" ? 0.4 : 0, g = setAttributes(createElement("g"), {
4281
4397
  transform: `translate(${at[0] + cornerOff},${at[1] - cornerOff})`,
4282
4398
  cgHash: hash2
@@ -4286,7 +4402,7 @@ function renderLabel(label, hash2, from, to, slots, corner) {
4286
4402
  "fill-opacity": corner ? 1 : 0.8,
4287
4403
  "stroke-opacity": corner ? 1 : 0.7,
4288
4404
  "stroke-width": 0.03,
4289
- fill: (_a = label.fill) !== null && _a !== void 0 ? _a : "#666",
4405
+ fill: label.fill ?? "#666",
4290
4406
  stroke: "white"
4291
4407
  }));
4292
4408
  const labelEl = setAttributes(createElement("text"), {
@@ -4330,6 +4446,10 @@ function circleWidth() {
4330
4446
  function lineWidth(brush, current) {
4331
4447
  return (brush.lineWidth || 10) * (current ? 0.85 : 1) / 64;
4332
4448
  }
4449
+ function hiliteOf(shape) {
4450
+ const hilite = shape.modifiers?.hilite;
4451
+ return { key: hilite && `hilite-${hilite.replace("#", "")}`, color: hilite };
4452
+ }
4333
4453
  function opacity(brush, current) {
4334
4454
  return (brush.opacity || 1) * (current ? 0.9 : 1);
4335
4455
  }
@@ -4379,7 +4499,7 @@ function labelCoords(from, to, slots) {
4379
4499
  return [from[0] - Math.cos(angle) * mag, from[1] - Math.sin(angle) * mag].map((c) => c + 0.5);
4380
4500
  }
4381
4501
 
4382
- // node_modules/.pnpm/chessground@9.2.1/node_modules/chessground/dist/wrap.js
4502
+ // node_modules/.pnpm/@lichess-org+chessground@9.8.2/node_modules/@lichess-org/chessground/dist/wrap.js
4383
4503
  function renderWrap(element, s) {
4384
4504
  element.innerHTML = "";
4385
4505
  element.classList.add("cg-wrap");
@@ -4390,26 +4510,19 @@ function renderWrap(element, s) {
4390
4510
  element.appendChild(container);
4391
4511
  const board = createEl("cg-board");
4392
4512
  container.appendChild(board);
4393
- let svg;
4394
- let customSvg;
4513
+ let shapesBelow;
4514
+ let shapes;
4515
+ let customBelow;
4516
+ let custom;
4395
4517
  let autoPieces;
4396
4518
  if (s.drawable.visible) {
4397
- svg = setAttributes(createElement("svg"), {
4398
- class: "cg-shapes",
4399
- viewBox: "-4 -4 8 8",
4400
- preserveAspectRatio: "xMidYMid slice"
4401
- });
4402
- svg.appendChild(createDefs());
4403
- svg.appendChild(createElement("g"));
4404
- customSvg = setAttributes(createElement("svg"), {
4405
- class: "cg-custom-svgs",
4406
- viewBox: "-3.5 -3.5 8 8",
4407
- preserveAspectRatio: "xMidYMid slice"
4408
- });
4409
- customSvg.appendChild(createElement("g"));
4519
+ [shapesBelow, shapes] = ["cg-shapes-below", "cg-shapes"].map((cls) => svgContainer(cls, true));
4520
+ [customBelow, custom] = ["cg-custom-below", "cg-custom-svgs"].map((cls) => svgContainer(cls, false));
4410
4521
  autoPieces = createEl("cg-auto-pieces");
4411
- container.appendChild(svg);
4412
- container.appendChild(customSvg);
4522
+ container.appendChild(shapesBelow);
4523
+ container.appendChild(customBelow);
4524
+ container.appendChild(shapes);
4525
+ container.appendChild(custom);
4413
4526
  container.appendChild(autoPieces);
4414
4527
  }
4415
4528
  if (s.coordinates) {
@@ -4429,15 +4542,18 @@ function renderWrap(element, s) {
4429
4542
  setVisible(ghost, false);
4430
4543
  container.appendChild(ghost);
4431
4544
  }
4432
- return {
4433
- board,
4434
- container,
4435
- wrap: element,
4436
- ghost,
4437
- svg,
4438
- customSvg,
4439
- autoPieces
4440
- };
4545
+ return { board, container, wrap: element, ghost, shapes, shapesBelow, custom, customBelow, autoPieces };
4546
+ }
4547
+ function svgContainer(cls, isShapes) {
4548
+ const svg = setAttributes(createElement("svg"), {
4549
+ class: cls,
4550
+ viewBox: isShapes ? "-4 -4 8 8" : "-3.5 -3.5 8 8",
4551
+ preserveAspectRatio: "xMidYMid slice"
4552
+ });
4553
+ if (isShapes)
4554
+ svg.appendChild(createDefs());
4555
+ svg.appendChild(createElement("g"));
4556
+ return svg;
4441
4557
  }
4442
4558
  function renderCoords(elems, className) {
4443
4559
  const el = createEl("coords", className);
@@ -4450,7 +4566,7 @@ function renderCoords(elems, className) {
4450
4566
  return el;
4451
4567
  }
4452
4568
 
4453
- // node_modules/.pnpm/chessground@9.2.1/node_modules/chessground/dist/drop.js
4569
+ // node_modules/.pnpm/@lichess-org+chessground@9.8.2/node_modules/@lichess-org/chessground/dist/drop.js
4454
4570
  function drop(s, e) {
4455
4571
  if (!s.dropmode.active)
4456
4572
  return;
@@ -4467,7 +4583,7 @@ function drop(s, e) {
4467
4583
  s.dom.redraw();
4468
4584
  }
4469
4585
 
4470
- // node_modules/.pnpm/chessground@9.2.1/node_modules/chessground/dist/events.js
4586
+ // node_modules/.pnpm/@lichess-org+chessground@9.8.2/node_modules/@lichess-org/chessground/dist/events.js
4471
4587
  function bindBoard(s, onResize) {
4472
4588
  const boardEl = s.dom.elements.board;
4473
4589
  if ("ResizeObserver" in window)
@@ -4529,7 +4645,7 @@ var dragOrDraw = (s, withDrag, withDraw) => (e) => {
4529
4645
  withDrag(s, e);
4530
4646
  };
4531
4647
 
4532
- // node_modules/.pnpm/chessground@9.2.1/node_modules/chessground/dist/render.js
4648
+ // node_modules/.pnpm/@lichess-org+chessground@9.8.2/node_modules/@lichess-org/chessground/dist/render.js
4533
4649
  function render2(s) {
4534
4650
  const asWhite = whitePov(s), posToTranslate2 = posToTranslate(s.dom.bounds()), boardEl = s.dom.elements.board, pieces = s.pieces, curAnim = s.animation.current, anims = curAnim ? curAnim.plan.anims : /* @__PURE__ */ new Map(), fadings = curAnim ? curAnim.plan.fadings : /* @__PURE__ */ new Map(), curDrag = s.draggable.current, squares = computeSquareClasses(s), samePieces = /* @__PURE__ */ new Set(), sameSquares = /* @__PURE__ */ new Set(), movedPieces = /* @__PURE__ */ new Map(), movedSquares = /* @__PURE__ */ new Map();
4535
4651
  let k, el, pieceAtKey, elPieceName, anim2, fading, pMvdset, pMvd, sMvdset, sMvd;
@@ -4655,7 +4771,6 @@ function renderResized(s) {
4655
4771
  }
4656
4772
  }
4657
4773
  function updateBounds(s) {
4658
- var _a, _b;
4659
4774
  const bounds = s.dom.elements.wrap.getBoundingClientRect();
4660
4775
  const container = s.dom.elements.container;
4661
4776
  const ratio = bounds.height / bounds.width;
@@ -4664,8 +4779,8 @@ function updateBounds(s) {
4664
4779
  container.style.width = width + "px";
4665
4780
  container.style.height = height + "px";
4666
4781
  s.dom.bounds.clear();
4667
- (_a = s.addDimensionsCssVarsTo) === null || _a === void 0 ? void 0 : _a.style.setProperty("---cg-width", width + "px");
4668
- (_b = s.addDimensionsCssVarsTo) === null || _b === void 0 ? void 0 : _b.style.setProperty("---cg-height", height + "px");
4782
+ s.addDimensionsCssVarsTo?.style.setProperty("---cg-width", width + "px");
4783
+ s.addDimensionsCssVarsTo?.style.setProperty("---cg-height", height + "px");
4669
4784
  }
4670
4785
  var isPieceNode = (el) => el.tagName === "PIECE";
4671
4786
  var isSquareNode = (el) => el.tagName === "SQUARE";
@@ -4681,7 +4796,6 @@ function posZIndex(pos, asWhite) {
4681
4796
  }
4682
4797
  var pieceNameOf = (piece) => `${piece.color} ${piece.role}`;
4683
4798
  function computeSquareClasses(s) {
4684
- var _a, _b, _c;
4685
4799
  const squares = /* @__PURE__ */ new Map();
4686
4800
  if (s.lastMove && s.highlight.lastMove)
4687
4801
  for (const k of s.lastMove) {
@@ -4692,12 +4806,12 @@ function computeSquareClasses(s) {
4692
4806
  if (s.selected) {
4693
4807
  addSquare(squares, s.selected, "selected");
4694
4808
  if (s.movable.showDests) {
4695
- const dests = (_a = s.movable.dests) === null || _a === void 0 ? void 0 : _a.get(s.selected);
4809
+ const dests = s.movable.dests?.get(s.selected);
4696
4810
  if (dests)
4697
4811
  for (const k of dests) {
4698
4812
  addSquare(squares, k, "move-dest" + (s.pieces.has(k) ? " oc" : ""));
4699
4813
  }
4700
- const pDests = (_c = (_b = s.premovable.customDests) === null || _b === void 0 ? void 0 : _b.get(s.selected)) !== null && _c !== void 0 ? _c : s.premovable.dests;
4814
+ const pDests = s.premovable.customDests?.get(s.selected) ?? s.premovable.dests;
4701
4815
  if (pDests)
4702
4816
  for (const k of pDests) {
4703
4817
  addSquare(squares, k, "premove-dest" + (s.pieces.has(k) ? " oc" : ""));
@@ -4736,7 +4850,7 @@ function appendValue(map, key, value) {
4736
4850
  map.set(key, [value]);
4737
4851
  }
4738
4852
 
4739
- // node_modules/.pnpm/chessground@9.2.1/node_modules/chessground/dist/sync.js
4853
+ // node_modules/.pnpm/@lichess-org+chessground@9.8.2/node_modules/@lichess-org/chessground/dist/sync.js
4740
4854
  function syncShapes2(shapes, root, renderShape3) {
4741
4855
  const hashesInDom = /* @__PURE__ */ new Map(), toRemove = [];
4742
4856
  for (const sc of shapes)
@@ -4758,7 +4872,7 @@ function syncShapes2(shapes, root, renderShape3) {
4758
4872
  }
4759
4873
  }
4760
4874
 
4761
- // node_modules/.pnpm/chessground@9.2.1/node_modules/chessground/dist/autoPieces.js
4875
+ // node_modules/.pnpm/@lichess-org+chessground@9.8.2/node_modules/@lichess-org/chessground/dist/autoPieces.js
4762
4876
  function render3(state, autoPieceEl) {
4763
4877
  const autoPieces = state.drawable.autoShapes.filter((autoShape) => autoShape.piece);
4764
4878
  const autoPieceShapes = autoPieces.map((s) => {
@@ -4771,20 +4885,18 @@ function render3(state, autoPieceEl) {
4771
4885
  syncShapes2(autoPieceShapes, autoPieceEl, (shape) => renderShape2(state, shape, state.dom.bounds()));
4772
4886
  }
4773
4887
  function renderResized2(state) {
4774
- var _a;
4775
4888
  const asWhite = whitePov(state), posToTranslate2 = posToTranslate(state.dom.bounds());
4776
- let el = (_a = state.dom.elements.autoPieces) === null || _a === void 0 ? void 0 : _a.firstChild;
4889
+ let el = state.dom.elements.autoPieces?.firstChild;
4777
4890
  while (el) {
4778
4891
  translateAndScale(el, posToTranslate2(key2pos(el.cgKey), asWhite), el.cgScale);
4779
4892
  el = el.nextSibling;
4780
4893
  }
4781
4894
  }
4782
4895
  function renderShape2(state, { shape, hash: hash2 }, bounds) {
4783
- var _a, _b, _c;
4784
4896
  const orig = shape.orig;
4785
- const role = (_a = shape.piece) === null || _a === void 0 ? void 0 : _a.role;
4786
- const color = (_b = shape.piece) === null || _b === void 0 ? void 0 : _b.color;
4787
- const scale = (_c = shape.piece) === null || _c === void 0 ? void 0 : _c.scale;
4897
+ const role = shape.piece?.role;
4898
+ const color = shape.piece?.color;
4899
+ const scale = shape.piece?.scale;
4788
4900
  const pieceEl = createEl("piece", `${role} ${color}`);
4789
4901
  pieceEl.setAttribute("cgHash", hash2);
4790
4902
  pieceEl.cgKey = orig;
@@ -4792,12 +4904,9 @@ function renderShape2(state, { shape, hash: hash2 }, bounds) {
4792
4904
  translateAndScale(pieceEl, posToTranslate(bounds)(key2pos(orig), whitePov(state)), scale);
4793
4905
  return pieceEl;
4794
4906
  }
4795
- var hash = (autoPiece) => {
4796
- var _a, _b, _c;
4797
- return [autoPiece.orig, (_a = autoPiece.piece) === null || _a === void 0 ? void 0 : _a.role, (_b = autoPiece.piece) === null || _b === void 0 ? void 0 : _b.color, (_c = autoPiece.piece) === null || _c === void 0 ? void 0 : _c.scale].join(",");
4798
- };
4907
+ var hash = (autoPiece) => [autoPiece.orig, autoPiece.piece?.role, autoPiece.piece?.color, autoPiece.piece?.scale].join(",");
4799
4908
 
4800
- // node_modules/.pnpm/chessground@9.2.1/node_modules/chessground/dist/chessground.js
4909
+ // node_modules/.pnpm/@lichess-org+chessground@9.8.2/node_modules/@lichess-org/chessground/dist/chessground.js
4801
4910
  function Chessground(element, config) {
4802
4911
  const maybeState = defaults();
4803
4912
  configure(maybeState, config || {});
@@ -4807,8 +4916,8 @@ function Chessground(element, config) {
4807
4916
  render2(state);
4808
4917
  if (elements.autoPieces)
4809
4918
  render3(state, elements.autoPieces);
4810
- if (!skipSvg && elements.svg)
4811
- renderSvg(state, elements.svg, elements.customSvg);
4919
+ if (!skipSvg && elements.shapes)
4920
+ renderSvg(state, elements);
4812
4921
  }, onResize = () => {
4813
4922
  updateBounds(state);
4814
4923
  renderResized(state);