@lichess-org/pgn-viewer 2.5.5 → 2.5.7

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.
@@ -86,7 +86,9 @@ piece.fading {
86
86
 
87
87
  .cg-wrap cg-auto-pieces,
88
88
  .cg-wrap .cg-shapes,
89
- .cg-wrap .cg-custom-svgs {
89
+ .cg-wrap .cg-custom-svgs,
90
+ .cg-wrap .cg-shapes-below,
91
+ .cg-wrap .cg-custom-below {
90
92
  overflow: visible;
91
93
  position: absolute;
92
94
  top: 0px;
@@ -296,6 +298,7 @@ cg-board square.current-premove {
296
298
  color: #fff;
297
299
  }
298
300
  .lpv__fbt.disabled, .lpv__fbt[disabled] {
301
+ pointer-events: none;
299
302
  opacity: 0.4;
300
303
  cursor: default;
301
304
  }
@@ -2698,12 +2698,12 @@ var defaultTranslations = {
2698
2698
  "san.shortCastling": "short castling"
2699
2699
  };
2700
2700
 
2701
- // node_modules/.pnpm/@lichess-org+chessground@9.8.5/node_modules/@lichess-org/chessground/dist/types.js
2701
+ // node_modules/.pnpm/@lichess-org+chessground@10.0.1/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/@lichess-org+chessground@9.8.5/node_modules/@lichess-org/chessground/dist/util.js
2706
+ // node_modules/.pnpm/@lichess-org+chessground@10.0.1/node_modules/@lichess-org/chessground/dist/util.js
2707
2707
  var invRanks = [...ranks].reverse();
2708
2708
  var allKeys = files.flatMap((f) => ranks.map((r) => f + r));
2709
2709
  var pos2key = (pos) => pos.every((x) => x >= 0 && x <= 7) ? allKeys[8 * pos[0] + pos[1]] : void 0;
@@ -2797,7 +2797,6 @@ var rookDir = (x1, y1, x2, y2) => x1 === x2 !== (y1 === y2);
2797
2797
  var bishopDir = (x1, y1, x2, y2) => diff(x1, x2) === diff(y1, y2) && x1 !== x2;
2798
2798
  var queenDir = (x1, y1, x2, y2) => rookDir(x1, y1, x2, y2) || bishopDir(x1, y1, x2, y2);
2799
2799
  var kingDirNonCastling = (x1, y1, x2, y2) => Math.max(diff(x1, x2), diff(y1, y2)) === 1;
2800
- var pawnDirCapture = (x1, y1, x2, y2, isDirectionUp) => diff(x1, x2) === 1 && y2 === y1 + (isDirectionUp ? 1 : -1);
2801
2800
  var pawnDirAdvance = (x1, y1, x2, y2, isDirectionUp) => {
2802
2801
  const step2 = isDirectionUp ? 1 : -1;
2803
2802
  return x1 === x2 && (y2 === y1 + step2 || // allow 2 squares from first two ranks, for horde
@@ -2818,20 +2817,6 @@ var squaresBetween = (x1, y1, x2, y2) => {
2818
2817
  }
2819
2818
  return squares.map(pos2key).filter((k) => k !== void 0);
2820
2819
  };
2821
- var adjacentSquares = (square) => {
2822
- const pos = key2pos(square);
2823
- const adjacentSquares2 = [];
2824
- if (pos[0] > 0)
2825
- adjacentSquares2.push([pos[0] - 1, pos[1]]);
2826
- if (pos[0] < 7)
2827
- adjacentSquares2.push([pos[0] + 1, pos[1]]);
2828
- return adjacentSquares2.map(pos2key).filter((k) => k !== void 0);
2829
- };
2830
- var squareShiftedVertically = (square, delta) => {
2831
- const pos = key2pos(square);
2832
- pos[1] += delta;
2833
- return pos2key(pos);
2834
- };
2835
2820
 
2836
2821
  // src/path.ts
2837
2822
  var Path = class _Path {
@@ -3093,106 +3078,16 @@ var PgnViewer = class {
3093
3078
  }
3094
3079
  };
3095
3080
 
3096
- // node_modules/.pnpm/@lichess-org+chessground@9.8.5/node_modules/@lichess-org/chessground/dist/premove.js
3097
- var isDestOccupiedByFriendly = (ctx) => ctx.friendlies.has(ctx.dest.key);
3098
- var isDestOccupiedByEnemy = (ctx) => ctx.enemies.has(ctx.dest.key);
3099
- var anyPieceBetween = (orig, dest, pieces) => squaresBetween(...orig, ...dest).some((s) => pieces.has(s));
3100
- var canEnemyPawnAdvanceToSquare = (pawnStart, dest, ctx) => {
3101
- const piece = ctx.enemies.get(pawnStart);
3102
- if (piece?.role !== "pawn")
3103
- return false;
3104
- const step2 = piece.color === "white" ? 1 : -1;
3105
- const startPos = key2pos(pawnStart);
3106
- const destPos = key2pos(dest);
3107
- return pawnDirAdvance(...startPos, ...destPos, piece.color === "white") && !anyPieceBetween(startPos, [destPos[0], destPos[1] + step2], ctx.allPieces);
3108
- };
3109
- var canEnemyPawnCaptureOnSquare = (pawnStart, dest, ctx) => {
3110
- const enemyPawn = ctx.enemies.get(pawnStart);
3111
- 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));
3112
- };
3113
- var canSomeEnemyPawnAdvanceToDest = (ctx) => [...ctx.enemies.keys()].some((key) => canEnemyPawnAdvanceToSquare(key, ctx.dest.key, ctx));
3114
- var isDestControlledByEnemy = (ctx, pieceRolesExclude) => {
3115
- const square = ctx.dest.pos;
3116
- return [...ctx.enemies].some(([key, piece]) => {
3117
- const piecePos = key2pos(key);
3118
- 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));
3119
- });
3120
- };
3121
- var isFriendlyOnDestAndAttacked = (ctx) => isDestOccupiedByFriendly(ctx) && (canBeCapturedBySomeEnemyEnPassant(ctx.dest.key, ctx.friendlies, ctx.enemies, ctx.lastMove) || isDestControlledByEnemy(ctx));
3122
- var canBeCapturedBySomeEnemyEnPassant = (potentialSquareOfFriendlyPawn, friendlies, enemies, lastMove) => {
3123
- if (!potentialSquareOfFriendlyPawn || lastMove && potentialSquareOfFriendlyPawn !== lastMove[1])
3124
- return false;
3125
- const pos = key2pos(potentialSquareOfFriendlyPawn);
3126
- const friendly = friendlies.get(potentialSquareOfFriendlyPawn);
3127
- return friendly?.role === "pawn" && pos[1] === (friendly.color === "white" ? 3 : 4) && (!lastMove || diff(key2pos(lastMove[0])[1], pos[1]) === 2) && [1, -1].some((delta) => {
3128
- const k = pos2key([pos[0] + delta, pos[1]]);
3129
- return !!k && enemies.get(k)?.role === "pawn";
3130
- });
3131
- };
3132
- var isPathClearEnoughOfFriendliesForPremove = (ctx, isPawnAdvance) => {
3133
- if (ctx.unrestrictedPremoves)
3134
- return true;
3135
- const squaresBetween2 = squaresBetween(...ctx.orig.pos, ...ctx.dest.pos);
3136
- if (isPawnAdvance)
3137
- squaresBetween2.push(ctx.dest.key);
3138
- const squaresOfFriendliesBetween = squaresBetween2.filter((s) => ctx.friendlies.has(s));
3139
- if (!squaresOfFriendliesBetween.length)
3140
- return true;
3141
- const firstSquareOfFriendliesBetween = squaresOfFriendliesBetween[0];
3142
- const nextSquare = squareShiftedVertically(firstSquareOfFriendliesBetween, ctx.color === "white" ? -1 : 1);
3143
- return squaresOfFriendliesBetween.length === 1 && canBeCapturedBySomeEnemyEnPassant(firstSquareOfFriendliesBetween, ctx.friendlies, ctx.enemies, ctx.lastMove) && !!nextSquare && !squaresBetween2.includes(nextSquare);
3144
- };
3145
- var isPathClearEnoughOfEnemiesForPremove = (ctx, isPawnAdvance) => {
3146
- if (ctx.unrestrictedPremoves)
3147
- return true;
3148
- const squaresBetween2 = squaresBetween(...ctx.orig.pos, ...ctx.dest.pos);
3149
- if (isPawnAdvance)
3150
- squaresBetween2.push(ctx.dest.key);
3151
- const squaresOfEnemiesBetween = squaresBetween2.filter((s) => ctx.enemies.has(s));
3152
- if (squaresOfEnemiesBetween.length > 1)
3153
- return false;
3154
- if (!squaresOfEnemiesBetween.length)
3155
- return true;
3156
- const enemySquare = squaresOfEnemiesBetween[0];
3157
- const enemy = ctx.enemies.get(enemySquare);
3158
- if (!enemy || enemy.role !== "pawn")
3159
- return true;
3160
- const enemyStep = enemy.color === "white" ? 1 : -1;
3161
- const squareAbove = squareShiftedVertically(enemySquare, enemyStep);
3162
- const enemyPawnDests = squareAbove ? [
3163
- ...adjacentSquares(squareAbove).filter((s) => canEnemyPawnCaptureOnSquare(enemySquare, s, ctx)),
3164
- ...[squareAbove, squareShiftedVertically(squareAbove, enemyStep)].filter((s) => !!s).filter((s) => canEnemyPawnAdvanceToSquare(enemySquare, s, ctx))
3165
- ] : [];
3166
- const badSquares = [...squaresBetween2, ctx.orig.key];
3167
- return enemyPawnDests.some((square) => !badSquares.includes(square));
3168
- };
3169
- var isPathClearEnoughForPremove = (ctx, isPawnAdvance) => isPathClearEnoughOfFriendliesForPremove(ctx, isPawnAdvance) && isPathClearEnoughOfEnemiesForPremove(ctx, isPawnAdvance);
3170
- var pawn = (ctx) => {
3171
- const step2 = ctx.color === "white" ? 1 : -1;
3172
- if (diff(ctx.orig.pos[0], ctx.dest.pos[0]) > 1)
3173
- return false;
3174
- if (!diff(ctx.orig.pos[0], ctx.dest.pos[0]))
3175
- return pawnDirAdvance(...ctx.orig.pos, ...ctx.dest.pos, ctx.color === "white") && isPathClearEnoughForPremove(ctx, true);
3176
- if (ctx.dest.pos[1] !== ctx.orig.pos[1] + step2)
3177
- return false;
3178
- if (ctx.unrestrictedPremoves || isDestOccupiedByEnemy(ctx))
3179
- return true;
3180
- if (isDestOccupiedByFriendly(ctx))
3181
- return isDestControlledByEnemy(ctx);
3182
- else
3183
- return canSomeEnemyPawnAdvanceToDest(ctx) || canBeCapturedBySomeEnemyEnPassant(pos2key([ctx.dest.pos[0], ctx.dest.pos[1] + step2]), ctx.friendlies, ctx.enemies, ctx.lastMove) || isDestControlledByEnemy(ctx, ["pawn"]);
3184
- };
3185
- var knight = (ctx) => knightDir(...ctx.orig.pos, ...ctx.dest.pos) && (ctx.unrestrictedPremoves || !isDestOccupiedByFriendly(ctx) || isFriendlyOnDestAndAttacked(ctx));
3186
- var bishop = (ctx) => bishopDir(...ctx.orig.pos, ...ctx.dest.pos) && isPathClearEnoughForPremove(ctx, false) && (ctx.unrestrictedPremoves || !isDestOccupiedByFriendly(ctx) || isFriendlyOnDestAndAttacked(ctx));
3187
- var rook = (ctx) => rookDir(...ctx.orig.pos, ...ctx.dest.pos) && isPathClearEnoughForPremove(ctx, false) && (ctx.unrestrictedPremoves || !isDestOccupiedByFriendly(ctx) || isFriendlyOnDestAndAttacked(ctx));
3081
+ // node_modules/.pnpm/@lichess-org+chessground@10.0.1/node_modules/@lichess-org/chessground/dist/premove.js
3082
+ var pawn = (ctx) => diff(ctx.orig.pos[0], ctx.dest.pos[0]) <= 1 && (diff(ctx.orig.pos[0], ctx.dest.pos[0]) === 1 ? ctx.dest.pos[1] === ctx.orig.pos[1] + (ctx.color === "white" ? 1 : -1) : pawnDirAdvance(...ctx.orig.pos, ...ctx.dest.pos, ctx.color === "white"));
3083
+ var knight = (ctx) => knightDir(...ctx.orig.pos, ...ctx.dest.pos);
3084
+ var bishop = (ctx) => bishopDir(...ctx.orig.pos, ...ctx.dest.pos);
3085
+ var rook = (ctx) => rookDir(...ctx.orig.pos, ...ctx.dest.pos);
3188
3086
  var queen = (ctx) => bishop(ctx) || rook(ctx);
3189
- 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.
3190
- Note that for the Chess960 edge case of Kb1 "long castling", the check passes even if there is a piece in the way
3191
- on c1. But this is fine, since premoving from b1 to a1 as a normal move would have already returned true. */
3192
- 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 })));
3087
+ var king = (ctx) => kingDirNonCastling(...ctx.orig.pos, ...ctx.dest.pos) || 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]));
3193
3088
  var mobilityByRole = { pawn, knight, bishop, rook, queen, king };
3194
3089
  function premove(state, key) {
3195
- const pieces = state.pieces, canCastle = state.premovable.castle, unrestrictedPremoves = !!state.premovable.unrestrictedPremoves;
3090
+ const pieces = state.pieces;
3196
3091
  const piece = pieces.get(key);
3197
3092
  if (!piece || piece.color === state.turnColor)
3198
3093
  return [];
@@ -3202,16 +3097,14 @@ function premove(state, key) {
3202
3097
  allPieces: pieces,
3203
3098
  friendlies,
3204
3099
  enemies,
3205
- unrestrictedPremoves,
3206
3100
  color,
3207
- canCastle,
3208
3101
  rookFilesFriendlies: Array.from(pieces).filter(([k, p]) => k[1] === (color === "white" ? "1" : "8") && p.color === color && p.role === "rook").map(([k]) => key2pos(k)[0]),
3209
3102
  lastMove: state.lastMove
3210
3103
  };
3211
3104
  return allPosAndKey.filter((dest) => mobility({ ...partialCtx, dest })).map((pk) => pk.key);
3212
3105
  }
3213
3106
 
3214
- // node_modules/.pnpm/@lichess-org+chessground@9.8.5/node_modules/@lichess-org/chessground/dist/board.js
3107
+ // node_modules/.pnpm/@lichess-org+chessground@10.0.1/node_modules/@lichess-org/chessground/dist/board.js
3215
3108
  function callUserFunction(f, ...args) {
3216
3109
  if (f)
3217
3110
  setTimeout(() => f(...args), 1);
@@ -3500,7 +3393,7 @@ function getSnappedKeyAtDomPos(orig, pos, asWhite, bounds) {
3500
3393
  }
3501
3394
  var whitePov = (s) => s.orientation === "white";
3502
3395
 
3503
- // node_modules/.pnpm/@lichess-org+chessground@9.8.5/node_modules/@lichess-org/chessground/dist/fen.js
3396
+ // node_modules/.pnpm/@lichess-org+chessground@10.0.1/node_modules/@lichess-org/chessground/dist/fen.js
3504
3397
  var initial = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR";
3505
3398
  var roles = {
3506
3399
  p: "pawn",
@@ -3575,7 +3468,7 @@ function write(pieces) {
3575
3468
  }).join("")).join("/").replace(/1{2,}/g, (s) => s.length.toString());
3576
3469
  }
3577
3470
 
3578
- // node_modules/.pnpm/@lichess-org+chessground@9.8.5/node_modules/@lichess-org/chessground/dist/config.js
3471
+ // node_modules/.pnpm/@lichess-org+chessground@10.0.1/node_modules/@lichess-org/chessground/dist/config.js
3579
3472
  function applyAnimation(state, config) {
3580
3473
  if (config.animation) {
3581
3474
  deepMerge(state.animation, config.animation);
@@ -3626,7 +3519,7 @@ function isPlainObject(o) {
3626
3519
  return proto === Object.prototype || proto === null;
3627
3520
  }
3628
3521
 
3629
- // node_modules/.pnpm/@lichess-org+chessground@9.8.5/node_modules/@lichess-org/chessground/dist/anim.js
3522
+ // node_modules/.pnpm/@lichess-org+chessground@10.0.1/node_modules/@lichess-org/chessground/dist/anim.js
3630
3523
  var anim = (mutation, state) => state.animation.enabled ? animate(mutation, state) : render(mutation, state);
3631
3524
  function render(mutation, state) {
3632
3525
  const result = mutation(state);
@@ -3717,7 +3610,7 @@ function animate(mutation, state) {
3717
3610
  }
3718
3611
  var easing = (t) => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
3719
3612
 
3720
- // node_modules/.pnpm/@lichess-org+chessground@9.8.5/node_modules/@lichess-org/chessground/dist/draw.js
3613
+ // node_modules/.pnpm/@lichess-org+chessground@10.0.1/node_modules/@lichess-org/chessground/dist/draw.js
3721
3614
  var brushes = ["green", "red", "blue", "yellow"];
3722
3615
  function start(state, e) {
3723
3616
  if (e.touches && e.touches.length > 1)
@@ -3803,7 +3696,7 @@ function onChange(drawable) {
3803
3696
  drawable.onChange(drawable.shapes);
3804
3697
  }
3805
3698
 
3806
- // node_modules/.pnpm/@lichess-org+chessground@9.8.5/node_modules/@lichess-org/chessground/dist/drag.js
3699
+ // node_modules/.pnpm/@lichess-org+chessground@10.0.1/node_modules/@lichess-org/chessground/dist/drag.js
3807
3700
  function start2(s, e) {
3808
3701
  if (!(s.trustAllEvents || e.isTrusted))
3809
3702
  return;
@@ -3989,7 +3882,7 @@ function pieceElementByKey(s, key) {
3989
3882
  return;
3990
3883
  }
3991
3884
 
3992
- // node_modules/.pnpm/@lichess-org+chessground@9.8.5/node_modules/@lichess-org/chessground/dist/explosion.js
3885
+ // node_modules/.pnpm/@lichess-org+chessground@10.0.1/node_modules/@lichess-org/chessground/dist/explosion.js
3993
3886
  function explosion(state, keys) {
3994
3887
  state.exploding = { stage: 1, keys };
3995
3888
  state.dom.redraw();
@@ -4008,7 +3901,7 @@ function setStage(state, stage) {
4008
3901
  }
4009
3902
  }
4010
3903
 
4011
- // node_modules/.pnpm/@lichess-org+chessground@9.8.5/node_modules/@lichess-org/chessground/dist/api.js
3904
+ // node_modules/.pnpm/@lichess-org+chessground@10.0.1/node_modules/@lichess-org/chessground/dist/api.js
4012
3905
  function start3(state, redrawAll) {
4013
3906
  function toggleOrientation2() {
4014
3907
  toggleOrientation(state);
@@ -4099,7 +3992,7 @@ function start3(state, redrawAll) {
4099
3992
  };
4100
3993
  }
4101
3994
 
4102
- // node_modules/.pnpm/@lichess-org+chessground@9.8.5/node_modules/@lichess-org/chessground/dist/state.js
3995
+ // node_modules/.pnpm/@lichess-org+chessground@10.0.1/node_modules/@lichess-org/chessground/dist/state.js
4103
3996
  function defaults() {
4104
3997
  return {
4105
3998
  pieces: read(initial),
@@ -4195,7 +4088,7 @@ function defaults() {
4195
4088
  };
4196
4089
  }
4197
4090
 
4198
- // node_modules/.pnpm/@lichess-org+chessground@9.8.5/node_modules/@lichess-org/chessground/dist/svg.js
4091
+ // node_modules/.pnpm/@lichess-org+chessground@10.0.1/node_modules/@lichess-org/chessground/dist/svg.js
4199
4092
  function createDefs() {
4200
4093
  const defs = createElement("defs");
4201
4094
  const filter = setAttributes(createElement("filter"), { id: "cg-filter-blur" });
@@ -4209,7 +4102,7 @@ function renderSvg(state, els) {
4209
4102
  if (!s.dest)
4210
4103
  continue;
4211
4104
  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);
4212
- sources.add(moveAngle(from, to));
4105
+ sources.add(angleToSlot(moveAngle(from, to)));
4213
4106
  dests.set(s.dest, sources);
4214
4107
  }
4215
4108
  const shapes = [];
@@ -4220,14 +4113,14 @@ function renderSvg(state, els) {
4220
4113
  shape: s,
4221
4114
  current: false,
4222
4115
  pendingErase: isPendingErase,
4223
- hash: shapeHash(s, isShort(s.dest, dests), false, bounds, isPendingErase)
4116
+ hash: shapeHash(s, isShort(s.dest, dests), false, bounds, isPendingErase, angleCount(s.dest, dests))
4224
4117
  });
4225
4118
  }
4226
4119
  if (cur && pendingEraseIdx === -1)
4227
4120
  shapes.push({
4228
4121
  shape: cur,
4229
4122
  current: true,
4230
- hash: shapeHash(cur, isShort(cur.dest, dests), true, bounds, false),
4123
+ hash: shapeHash(cur, isShort(cur.dest, dests), true, bounds, false, angleCount(cur.dest, dests)),
4231
4124
  pendingErase: false
4232
4125
  });
4233
4126
  const fullHash = shapes.map((sc) => sc.hash).join(";");
@@ -4295,12 +4188,13 @@ function syncShapes(shapes, els, renderShape3) {
4295
4188
  }
4296
4189
  }
4297
4190
  }
4298
- function shapeHash({ orig, dest, brush, piece, modifiers, customSvg, label, below }, shorten, current, bounds, pendingErase) {
4191
+ function shapeHash({ orig, dest, brush, piece, modifiers, customSvg, label, below }, shorten, current, bounds, pendingErase, angleCountOfDest) {
4299
4192
  return [
4300
4193
  bounds.width,
4301
4194
  bounds.height,
4302
4195
  current,
4303
4196
  pendingErase && "pendingErase",
4197
+ angleCountOfDest,
4304
4198
  orig,
4305
4199
  dest,
4306
4200
  brush,
@@ -4312,12 +4206,8 @@ function shapeHash({ orig, dest, brush, piece, modifiers, customSvg, label, belo
4312
4206
  below && "below"
4313
4207
  ].filter((x) => x).join(",");
4314
4208
  }
4315
- function pieceHash(piece) {
4316
- return [piece.color, piece.role, piece.scale].filter((x) => x).join(",");
4317
- }
4318
- function modifiersHash(m) {
4319
- return [m.lineWidth, m.hilite].filter((x) => x).join(",");
4320
- }
4209
+ var pieceHash = (piece) => [piece.color, piece.role, piece.scale].filter((x) => x).join(",");
4210
+ var modifiersHash = (m) => [m.lineWidth, m.hilite].filter((x) => x).join(",");
4321
4211
  function textHash(s) {
4322
4212
  let h2 = 0;
4323
4213
  for (let i = 0; i < s.length; i++) {
@@ -4429,15 +4319,13 @@ function renderLabel(label, hash2, from, to, slots, corner) {
4429
4319
  g.appendChild(labelEl);
4430
4320
  return g;
4431
4321
  }
4432
- function orient(pos, color) {
4433
- return color === "white" ? pos : [7 - pos[0], 7 - pos[1]];
4434
- }
4435
- function isShort(dest, dests) {
4436
- return true === (dest && dests.has(dest) && dests.get(dest).size > 1);
4437
- }
4438
- function createElement(tagName2) {
4439
- return document.createElementNS("http://www.w3.org/2000/svg", tagName2);
4440
- }
4322
+ var orient = (pos, color) => color === "white" ? pos : [7 - pos[0], 7 - pos[1]];
4323
+ var mod = (n, m) => (n % m + m) % m;
4324
+ var rotateAngleSlot = (slot, steps) => mod(slot + steps, 16);
4325
+ var anyTwoCloserThan90Degrees = (slots) => [...slots].some((slot) => [-3, -2, -1, 1, 2, 3].some((i) => slots.has(rotateAngleSlot(slot, i))));
4326
+ var isShort = (dest, dests) => !!dest && dests.has(dest) && anyTwoCloserThan90Degrees(dests.get(dest));
4327
+ var createElement = (tagName2) => document.createElementNS("http://www.w3.org/2000/svg", tagName2);
4328
+ var angleCount = (dest, dests) => dest && dests.has(dest) ? dests.get(dest).size : 0;
4441
4329
  function setAttributes(el, attrs) {
4442
4330
  for (const key in attrs) {
4443
4331
  if (Object.prototype.hasOwnProperty.call(attrs, key))
@@ -4445,30 +4333,20 @@ function setAttributes(el, attrs) {
4445
4333
  }
4446
4334
  return el;
4447
4335
  }
4448
- function makeCustomBrush(base, modifiers) {
4449
- return !modifiers ? base : {
4450
- color: base.color,
4451
- opacity: Math.round(base.opacity * 10) / 10,
4452
- lineWidth: Math.round(modifiers.lineWidth || base.lineWidth),
4453
- key: [base.key, modifiers.lineWidth].filter((x) => x).join("")
4454
- };
4455
- }
4456
- function circleWidth() {
4457
- return [3 / 64, 4 / 64];
4458
- }
4459
- function lineWidth(brush, current) {
4460
- return (brush.lineWidth || 10) * (current ? 0.85 : 1) / 64;
4461
- }
4336
+ var makeCustomBrush = (base, modifiers) => !modifiers ? base : {
4337
+ color: base.color,
4338
+ opacity: Math.round(base.opacity * 10) / 10,
4339
+ lineWidth: Math.round(modifiers.lineWidth || base.lineWidth),
4340
+ key: [base.key, modifiers.lineWidth].filter((x) => x).join("")
4341
+ };
4342
+ var circleWidth = () => [3 / 64, 4 / 64];
4343
+ var lineWidth = (brush, current) => (brush.lineWidth || 10) * (current ? 0.85 : 1) / 64;
4462
4344
  function hiliteOf(shape) {
4463
4345
  const hilite = shape.modifiers?.hilite;
4464
4346
  return { key: hilite && `hilite-${hilite.replace("#", "")}`, color: hilite };
4465
4347
  }
4466
- function opacity(brush, current, pendingErase) {
4467
- return (brush.opacity || 1) * (pendingErase ? 0.6 : current ? 0.9 : 1);
4468
- }
4469
- function arrowMargin(shorten) {
4470
- return (shorten ? 20 : 10) / 64;
4471
- }
4348
+ var opacity = (brush, current, pendingErase) => (brush.opacity || 1) * (pendingErase ? 0.6 : current ? 0.9 : 1);
4349
+ var arrowMargin = (shorten) => (shorten ? 20 : 10) / 64;
4472
4350
  function pos2user(pos, bounds) {
4473
4351
  const xScale = Math.min(1, bounds.width / bounds.height);
4474
4352
  const yScale = Math.min(1, bounds.height / bounds.width);
@@ -4488,31 +4366,25 @@ function filterBox(from, to) {
4488
4366
  stroke: "none"
4489
4367
  });
4490
4368
  }
4491
- function moveAngle(from, to, asSlot = true) {
4492
- const angle = Math.atan2(to[1] - from[1], to[0] - from[0]) + Math.PI;
4493
- return asSlot ? (Math.round(angle * 8 / Math.PI) + 16) % 16 : angle;
4494
- }
4495
- function dist(from, to) {
4496
- return Math.sqrt([from[0] - to[0], from[1] - to[1]].reduce((acc, x) => acc + x * x, 0));
4497
- }
4369
+ var angleToSlot = (angle) => mod(Math.round(angle * 8 / Math.PI), 16);
4370
+ var moveAngle = (from, to) => Math.atan2(to[1] - from[1], to[0] - from[0]) + Math.PI;
4371
+ var dist = (from, to) => Math.sqrt([from[0] - to[0], from[1] - to[1]].reduce((acc, x) => acc + x * x, 0));
4498
4372
  function labelCoords(from, to, slots) {
4499
4373
  let mag = dist(from, to);
4500
- const angle = moveAngle(from, to, false);
4374
+ const angle = moveAngle(from, to);
4501
4375
  if (slots) {
4502
4376
  mag -= 33 / 64;
4503
- if (slots.size > 1) {
4377
+ if (anyTwoCloserThan90Degrees(slots)) {
4504
4378
  mag -= 10 / 64;
4505
- const slot = moveAngle(from, to);
4506
- if (slots.has((slot + 1) % 16) || slots.has((slot + 15) % 16)) {
4507
- if (slot & 1)
4508
- mag -= 0.4;
4509
- }
4379
+ const slot = angleToSlot(angle);
4380
+ if (slot & 1 && [-1, 1].some((s) => slots.has(rotateAngleSlot(slot, s))))
4381
+ mag -= 0.4;
4510
4382
  }
4511
4383
  }
4512
4384
  return [from[0] - Math.cos(angle) * mag, from[1] - Math.sin(angle) * mag].map((c) => c + 0.5);
4513
4385
  }
4514
4386
 
4515
- // node_modules/.pnpm/@lichess-org+chessground@9.8.5/node_modules/@lichess-org/chessground/dist/wrap.js
4387
+ // node_modules/.pnpm/@lichess-org+chessground@10.0.1/node_modules/@lichess-org/chessground/dist/wrap.js
4516
4388
  function renderWrap(element, s) {
4517
4389
  element.innerHTML = "";
4518
4390
  element.classList.add("cg-wrap");
@@ -4543,10 +4415,10 @@ function renderWrap(element, s) {
4543
4415
  const ranksPositionClass = s.ranksPosition === "left" ? " left" : "";
4544
4416
  if (s.coordinatesOnSquares) {
4545
4417
  const rankN = s.orientation === "white" ? (i) => i + 1 : (i) => 8 - i;
4546
- files.forEach((f, i) => container.appendChild(renderCoords(ranks.map((r) => f + r), "squares rank" + rankN(i) + orientClass + ranksPositionClass)));
4418
+ files.forEach((f, i) => container.appendChild(renderCoords(ranks.map((r) => f + r), "squares rank" + rankN(i) + orientClass + ranksPositionClass, i % 2 === 0 ? "black" : "white")));
4547
4419
  } else {
4548
- container.appendChild(renderCoords(ranks, "ranks" + orientClass + ranksPositionClass));
4549
- container.appendChild(renderCoords(files, "files" + orientClass));
4420
+ container.appendChild(renderCoords(ranks, "ranks" + orientClass + ranksPositionClass, s.ranksPosition === "right" === (s.orientation === "white") ? "white" : "black"));
4421
+ container.appendChild(renderCoords(files, "files" + orientClass, opposite2(s.orientation)));
4550
4422
  }
4551
4423
  }
4552
4424
  let ghost;
@@ -4568,18 +4440,19 @@ function svgContainer(cls, isShapes) {
4568
4440
  svg.appendChild(createElement("g"));
4569
4441
  return svg;
4570
4442
  }
4571
- function renderCoords(elems, className) {
4443
+ function renderCoords(elems, className, firstColor) {
4572
4444
  const el = createEl("coords", className);
4573
4445
  let f;
4574
- for (const elem of elems) {
4575
- f = createEl("coord");
4446
+ elems.forEach((elem, i) => {
4447
+ const light = i % 2 === (firstColor === "white" ? 0 : 1);
4448
+ f = createEl("coord", `coord-${light ? "light" : "dark"}`);
4576
4449
  f.textContent = elem;
4577
4450
  el.appendChild(f);
4578
- }
4451
+ });
4579
4452
  return el;
4580
4453
  }
4581
4454
 
4582
- // node_modules/.pnpm/@lichess-org+chessground@9.8.5/node_modules/@lichess-org/chessground/dist/drop.js
4455
+ // node_modules/.pnpm/@lichess-org+chessground@10.0.1/node_modules/@lichess-org/chessground/dist/drop.js
4583
4456
  function drop(s, e) {
4584
4457
  if (!s.dropmode.active)
4585
4458
  return;
@@ -4596,7 +4469,7 @@ function drop(s, e) {
4596
4469
  s.dom.redraw();
4597
4470
  }
4598
4471
 
4599
- // node_modules/.pnpm/@lichess-org+chessground@9.8.5/node_modules/@lichess-org/chessground/dist/events.js
4472
+ // node_modules/.pnpm/@lichess-org+chessground@10.0.1/node_modules/@lichess-org/chessground/dist/events.js
4600
4473
  function bindBoard(s, onResize) {
4601
4474
  const boardEl = s.dom.elements.board;
4602
4475
  if ("ResizeObserver" in window)
@@ -4658,10 +4531,10 @@ var dragOrDraw = (s, withDrag, withDraw) => (e) => {
4658
4531
  withDrag(s, e);
4659
4532
  };
4660
4533
 
4661
- // node_modules/.pnpm/@lichess-org+chessground@9.8.5/node_modules/@lichess-org/chessground/dist/render.js
4534
+ // node_modules/.pnpm/@lichess-org+chessground@10.0.1/node_modules/@lichess-org/chessground/dist/render.js
4662
4535
  function render2(s) {
4663
- 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();
4664
- let k, el, pieceAtKey, elPieceName, anim2, fading, pMvdset, pMvd, sMvdset, sMvd;
4536
+ 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, samePieces = /* @__PURE__ */ new Set(), movedPieces = /* @__PURE__ */ new Map(), desiredSquares = computeSquareClasses(s), availableSquares = /* @__PURE__ */ new Map();
4537
+ let k, el, pieceAtKey, elPieceName, anim2, fading, pMvdset, pMvd, sAvail;
4665
4538
  el = boardEl.firstChild;
4666
4539
  while (el) {
4667
4540
  k = el.cgKey;
@@ -4693,44 +4566,43 @@ function render2(s) {
4693
4566
  if (s.addPieceZIndex)
4694
4567
  el.style.zIndex = posZIndex(key2pos(k), asWhite);
4695
4568
  }
4696
- if (elPieceName === pieceNameOf(pieceAtKey) && (!fading || !el.cgFading)) {
4569
+ if (elPieceName === pieceNameOf(pieceAtKey) && (!fading || !el.cgFading))
4697
4570
  samePieces.add(k);
4698
- } else {
4699
- if (fading && elPieceName === pieceNameOf(fading)) {
4700
- el.classList.add("fading");
4701
- el.cgFading = true;
4702
- } else {
4703
- appendValue(movedPieces, elPieceName, el);
4704
- }
4705
- }
4706
- } else {
4571
+ else if (fading && elPieceName === pieceNameOf(fading)) {
4572
+ el.classList.add("fading");
4573
+ el.cgFading = true;
4574
+ } else
4575
+ appendValue(movedPieces, elPieceName, el);
4576
+ } else
4707
4577
  appendValue(movedPieces, elPieceName, el);
4708
- }
4709
4578
  } else if (isSquareNode(el)) {
4710
- const cn = el.className;
4711
- if (squares.get(k) === cn)
4712
- sameSquares.add(k);
4713
- else
4714
- appendValue(movedSquares, cn, el);
4579
+ const cls = el.className;
4580
+ if (desiredSquares.get(k) === cls) {
4581
+ setVisible(el, true);
4582
+ desiredSquares.delete(k);
4583
+ } else
4584
+ appendValue(availableSquares, cls, el);
4715
4585
  }
4716
4586
  el = el.nextSibling;
4717
4587
  }
4718
- for (const [sk, className] of squares) {
4719
- if (!sameSquares.has(sk)) {
4720
- sMvdset = movedSquares.get(className);
4721
- sMvd = sMvdset && sMvdset.pop();
4722
- const translation = posToTranslate2(key2pos(sk), asWhite);
4723
- if (sMvd) {
4724
- sMvd.cgKey = sk;
4725
- translate2(sMvd, translation);
4726
- } else {
4727
- const squareNode = createEl("square", className);
4728
- squareNode.cgKey = sk;
4729
- translate2(squareNode, translation);
4730
- boardEl.insertBefore(squareNode, boardEl.firstChild);
4731
- }
4588
+ for (const [sk, className] of desiredSquares) {
4589
+ sAvail = availableSquares.get(className)?.pop();
4590
+ const translation = posToTranslate2(key2pos(sk), asWhite);
4591
+ if (sAvail) {
4592
+ sAvail.cgKey = sk;
4593
+ translate2(sAvail, translation);
4594
+ setVisible(sAvail, true);
4595
+ } else {
4596
+ const squareNode = createEl("square", className);
4597
+ squareNode.cgKey = sk;
4598
+ translate2(squareNode, translation);
4599
+ boardEl.insertBefore(squareNode, boardEl.firstChild);
4732
4600
  }
4733
4601
  }
4602
+ for (const [_, nodes] of availableSquares.entries()) {
4603
+ for (const node of nodes)
4604
+ setVisible(node, false);
4605
+ }
4734
4606
  for (const [k2, p] of pieces) {
4735
4607
  anim2 = anims.get(k2);
4736
4608
  if (!samePieces.has(k2)) {
@@ -4770,8 +4642,6 @@ function render2(s) {
4770
4642
  }
4771
4643
  for (const nodes of movedPieces.values())
4772
4644
  removeNodes(s, nodes);
4773
- for (const nodes of movedSquares.values())
4774
- removeNodes(s, nodes);
4775
4645
  }
4776
4646
  function renderResized(s) {
4777
4647
  const asWhite = whitePov(s), posToTranslate2 = posToTranslate(s.dom.bounds());
@@ -4808,27 +4678,21 @@ function posZIndex(pos, asWhite) {
4808
4678
  return `${z}`;
4809
4679
  }
4810
4680
  var pieceNameOf = (piece) => `${piece.color} ${piece.role}`;
4681
+ var normalizeLastMoveStandardRookCastle = (s, k) => !!s.lastMove?.[1] && !s.pieces.has(s.lastMove[1]) && s.lastMove[0][0] === "e" && ["h", "a"].includes(s.lastMove[1][0]) && s.lastMove[0][1] === s.lastMove[1][1] && squaresBetween(...key2pos(s.lastMove[0]), ...key2pos(s.lastMove[1])).some((sq) => s.pieces.has(sq)) ? (k > s.lastMove[0] ? "g" : "c") + k[1] : k;
4811
4682
  function computeSquareClasses(s) {
4812
4683
  const squares = /* @__PURE__ */ new Map();
4813
4684
  if (s.lastMove && s.highlight.lastMove)
4814
- for (const k of s.lastMove) {
4815
- addSquare(squares, k, "last-move");
4816
- }
4685
+ for (const [i, k] of s.lastMove.entries())
4686
+ addSquare(squares, i === 1 ? normalizeLastMoveStandardRookCastle(s, k) : k, "last-move");
4817
4687
  if (s.check && s.highlight.check)
4818
4688
  addSquare(squares, s.check, "check");
4819
4689
  if (s.selected) {
4820
4690
  addSquare(squares, s.selected, "selected");
4821
4691
  if (s.movable.showDests) {
4822
- const dests = s.movable.dests?.get(s.selected);
4823
- if (dests)
4824
- for (const k of dests) {
4825
- addSquare(squares, k, "move-dest" + (s.pieces.has(k) ? " oc" : ""));
4826
- }
4827
- const pDests = s.premovable.customDests?.get(s.selected) ?? s.premovable.dests;
4828
- if (pDests)
4829
- for (const k of pDests) {
4830
- addSquare(squares, k, "premove-dest" + (s.pieces.has(k) ? " oc" : ""));
4831
- }
4692
+ for (const k of s.movable.dests?.get(s.selected) ?? [])
4693
+ addSquare(squares, k, "move-dest" + (s.pieces.has(k) ? " oc" : ""));
4694
+ for (const k of s.premovable.customDests?.get(s.selected) ?? s.premovable.dests ?? [])
4695
+ addSquare(squares, k, "premove-dest" + (s.pieces.has(k) ? " oc" : ""));
4832
4696
  }
4833
4697
  }
4834
4698
  const premove2 = s.premovable.current;
@@ -4863,7 +4727,7 @@ function appendValue(map, key, value) {
4863
4727
  map.set(key, [value]);
4864
4728
  }
4865
4729
 
4866
- // node_modules/.pnpm/@lichess-org+chessground@9.8.5/node_modules/@lichess-org/chessground/dist/sync.js
4730
+ // node_modules/.pnpm/@lichess-org+chessground@10.0.1/node_modules/@lichess-org/chessground/dist/sync.js
4867
4731
  function syncShapes2(shapes, root, renderShape3) {
4868
4732
  const hashesInDom = /* @__PURE__ */ new Map(), toRemove = [];
4869
4733
  for (const sc of shapes)
@@ -4885,7 +4749,7 @@ function syncShapes2(shapes, root, renderShape3) {
4885
4749
  }
4886
4750
  }
4887
4751
 
4888
- // node_modules/.pnpm/@lichess-org+chessground@9.8.5/node_modules/@lichess-org/chessground/dist/autoPieces.js
4752
+ // node_modules/.pnpm/@lichess-org+chessground@10.0.1/node_modules/@lichess-org/chessground/dist/autoPieces.js
4889
4753
  function render3(state, autoPieceEl) {
4890
4754
  const autoPieces = state.drawable.autoShapes.filter((autoShape) => autoShape.piece);
4891
4755
  const autoPieceShapes = autoPieces.map((s) => {
@@ -4920,7 +4784,7 @@ function renderShape2(state, { shape, hash: hash2 }, bounds) {
4920
4784
  }
4921
4785
  var hash = (autoPiece) => [autoPiece.orig, autoPiece.piece?.role, autoPiece.piece?.color, autoPiece.piece?.scale].join(",");
4922
4786
 
4923
- // node_modules/.pnpm/@lichess-org+chessground@9.8.5/node_modules/@lichess-org/chessground/dist/chessground.js
4787
+ // node_modules/.pnpm/@lichess-org+chessground@10.0.1/node_modules/@lichess-org/chessground/dist/chessground.js
4924
4788
  function Chessground(element, config) {
4925
4789
  const maybeState = defaults();
4926
4790
  configure(maybeState, config || {});