@alepot55/chessboardjs 2.3.5 → 2.3.6

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.
@@ -128,7 +128,6 @@ const ERROR_MESSAGES = Object.freeze({
128
128
  invalid_fadeTime: 'Invalid fadeTime: ',
129
129
  invalid_fadeAnimation: 'Invalid fadeAnimation: ',
130
130
  invalid_ratio: 'Invalid ratio: ',
131
- invalid_animationStyle: 'Invalid animationStyle: ',
132
131
  animation_failed: 'Animation failed: ',
133
132
 
134
133
  // Event handlers
@@ -380,7 +379,6 @@ const VALID_VALUES = Object.freeze({
380
379
  movableColors: ['w', 'b', 'white', 'black', 'both', 'none'],
381
380
  dropOffBoard: ['snapback', 'trash'],
382
381
  easingTypes: ['linear', 'ease', 'ease-in', 'ease-out', 'ease-in-out'],
383
- animationStyles: ['sequential', 'simultaneous'],
384
382
  modes: ['normal', 'creative', 'analysis'],
385
383
  promotionPieces: ['q', 'r', 'b', 'n', 'Q', 'R', 'B', 'N']
386
384
  });
@@ -709,14 +707,6 @@ class ValidationService {
709
707
  return this._validValues.easingTypes.includes(easing);
710
708
  }
711
709
 
712
- /**
713
- * Validates animation style
714
- * @param {string} style - Animation style to validate
715
- * @returns {boolean} True if valid
716
- */
717
- isValidAnimationStyle(style) {
718
- return this._validValues.animationStyles.includes(style);
719
- }
720
710
 
721
711
  /**
722
712
  * Validates CSS color format
@@ -913,11 +903,7 @@ class ValidationService {
913
903
  if (config.dropOffBoard && !this.isValidDropOffBoard(config.dropOffBoard)) {
914
904
  errors.push(ERROR_MESSAGES.invalid_dropOffBoard + config.dropOffBoard);
915
905
  }
916
-
917
- if (config.animationStyle && !this.isValidAnimationStyle(config.animationStyle)) {
918
- errors.push(ERROR_MESSAGES.invalid_animationStyle + config.animationStyle);
919
- }
920
-
906
+
921
907
  // Validate callbacks
922
908
  const callbacks = ['onMove', 'onMoveEnd', 'onChange', 'onDragStart', 'onDragMove', 'onDrop', 'onSnapbackEnd'];
923
909
  for (const callback of callbacks) {
@@ -1095,7 +1081,6 @@ const DEFAULT_CONFIG$1 = Object.freeze({
1095
1081
  fadeAnimation: 'ease',
1096
1082
  ratio: 0.9,
1097
1083
  piecesPath: '../assets/themes/default',
1098
- animationStyle: 'simultaneous',
1099
1084
  simultaneousAnimationDelay: 100,
1100
1085
  onMove: () => true,
1101
1086
  onMoveEnd: () => true,
@@ -1221,7 +1206,6 @@ class ChessboardConfig {
1221
1206
  this.fadeTime = this._setTime(config.fadeTime);
1222
1207
 
1223
1208
  // Animation style properties
1224
- this.animationStyle = this._validateAnimationStyle(config.animationStyle);
1225
1209
  this.simultaneousAnimationDelay = this._validateDelay(config.simultaneousAnimationDelay);
1226
1210
  }
1227
1211
 
@@ -1282,19 +1266,6 @@ class ChessboardConfig {
1282
1266
  return callback;
1283
1267
  }
1284
1268
 
1285
- /**
1286
- * Validates animation style
1287
- * @private
1288
- * @param {string} style - Animation style
1289
- * @returns {string} Validated style
1290
- * @throws {ConfigurationError} If style is invalid
1291
- */
1292
- _validateAnimationStyle(style) {
1293
- if (!this._validationService.isValidAnimationStyle(style)) {
1294
- throw new ConfigurationError('Invalid animation style', 'animationStyle', style);
1295
- }
1296
- return style;
1297
- }
1298
1269
 
1299
1270
  /**
1300
1271
  * Validates animation delay
@@ -1432,7 +1403,6 @@ class ChessboardConfig {
1432
1403
  fadeTime: this.fadeTime,
1433
1404
  fadeAnimation: this.fadeAnimation,
1434
1405
  piecesPath: this.piecesPath,
1435
- animationStyle: this.animationStyle,
1436
1406
  simultaneousAnimationDelay: this.simultaneousAnimationDelay,
1437
1407
  onlyLegalMoves: this.onlyLegalMoves
1438
1408
  };
@@ -4655,9 +4625,15 @@ class PieceService {
4655
4625
  console.debug(`[PieceService] addPieceOnSquare: ${piece.id} to ${square.id}`);
4656
4626
  square.putPiece(piece);
4657
4627
 
4628
+ // Imposta sempre il drag (touch e mouse)
4658
4629
  if (dragFunction) {
4659
4630
  piece.setDrag(dragFunction(square, piece));
4660
4631
  }
4632
+ // Forza il drag touch se manca (debug/robustezza)
4633
+ if (!piece.element.ontouchstart) {
4634
+ piece.element.ontouchstart = dragFunction ? dragFunction(square, piece) : () => { };
4635
+ console.debug(`[PieceService] Forzato ontouchstart su ${piece.id}`);
4636
+ }
4661
4637
 
4662
4638
  if (fade && this.config.fadeTime > 0) {
4663
4639
  piece.fadeIn(
@@ -4715,8 +4691,8 @@ class PieceService {
4715
4691
  */
4716
4692
  movePiece(piece, targetSquare, duration, callback) {
4717
4693
  console.debug(`[PieceService] movePiece: ${piece.id} to ${targetSquare.id}`);
4718
- if (!piece) {
4719
- console.warn('PieceService.movePiece: piece is null, skipping animation');
4694
+ if (!piece || !piece.element) {
4695
+ console.warn(`[PieceService] movePiece: piece or element is null, skipping animation`);
4720
4696
  if (callback) callback();
4721
4697
  return;
4722
4698
  }
@@ -4772,7 +4748,7 @@ class PieceService {
4772
4748
  };
4773
4749
 
4774
4750
  // Check if piece is currently being dragged
4775
- const isDragging = move.piece.element.classList.contains('dragging');
4751
+ const isDragging = move.piece.element && move.piece.element.classList.contains('dragging');
4776
4752
 
4777
4753
  if (isDragging) {
4778
4754
  // If piece is being dragged, don't animate - just move it immediately
@@ -7497,7 +7473,7 @@ let Chessboard$1 = class Chessboard {
7497
7473
  const capturedPiece = move.to.piece;
7498
7474
 
7499
7475
  // For castle moves in simultaneous mode, we need to coordinate both animations
7500
- if (isCastleMove && this.config.animationStyle === 'simultaneous') {
7476
+ if (isCastleMove) {
7501
7477
  // Start king animation
7502
7478
  this.pieceService.translatePiece(
7503
7479
  move,
@@ -7722,172 +7698,62 @@ let Chessboard$1 = class Chessboard {
7722
7698
  }
7723
7699
 
7724
7700
  /**
7725
- * Performs the actual board update
7701
+ * Aggiorna i pezzi sulla scacchiera con animazione e delay configurabile (greedy matching)
7726
7702
  * @private
7727
- * @param {boolean} [animation=false] - Whether to animate
7728
- * @param {boolean} [isPositionLoad=false] - Whether this is a position load (affects delay)
7703
+ * @param {boolean} [animation=false] - Se animare
7704
+ * @param {boolean} [isPositionLoad=false] - Se è un caricamento posizione (delay 0)
7729
7705
  */
7730
7706
  _doUpdateBoardPieces(animation = false, isPositionLoad = false) {
7731
- // Blocca update se un drag è in corso
7732
7707
  if (this._isDragging) return;
7733
- // Skip update if we're in the middle of a promotion
7734
- if (this._isPromoting) {
7735
- return;
7736
- }
7737
- if (!this.positionService || !this.positionService.getGame()) {
7738
- return;
7739
- }
7708
+ if (this._isPromoting) return;
7709
+ if (!this.positionService || !this.positionService.getGame()) return;
7740
7710
  const squares = this.boardService.getAllSquares();
7741
7711
  const gameStateBefore = this.positionService.getGame().fen();
7742
7712
  if (/^8\/8\/8\/8\/8\/8\/8\/8/.test(gameStateBefore)) {
7743
7713
  const boardContainer = document.getElementById(this.config.id_div);
7744
7714
  if (boardContainer) {
7745
7715
  const pieceElements = boardContainer.querySelectorAll('.piece');
7746
- pieceElements.forEach(element => {
7747
- element.remove();
7748
- });
7716
+ pieceElements.forEach(element => element.remove());
7749
7717
  }
7750
- Object.values(squares).forEach(sq => {
7751
- if (sq && sq.piece) {
7752
- sq.piece = null;
7753
- }
7754
- });
7718
+ Object.values(squares).forEach(sq => { if (sq && sq.piece) sq.piece = null; });
7755
7719
  this._clearVisualState();
7756
7720
  this._addListeners();
7757
7721
  if (this.config.onChange) this.config.onChange(gameStateBefore);
7758
7722
  return;
7759
7723
  }
7760
- const useSimultaneous = this.config.animationStyle === 'simultaneous';
7761
- if (useSimultaneous) {
7762
- this._doSimultaneousUpdate(squares, gameStateBefore, isPositionLoad);
7763
- } else {
7764
- this._doSequentialUpdate(squares, gameStateBefore, animation);
7765
- }
7766
- // Pulizia finale robusta: rimuovi tutti i pezzi orfani dal DOM e dal riferimento JS
7767
- Object.values(this.boardService.getAllSquares()).forEach(square => {
7768
- const expectedPieceId = this.positionService.getGamePieceId(square.id);
7769
- if (!expectedPieceId && typeof square.forceRemoveAllPieces === 'function') {
7770
- square.forceRemoveAllPieces();
7771
- }
7772
- });
7773
- }
7774
7724
 
7775
- /**
7776
- * Performs sequential piece updates (original behavior)
7777
- * @private
7778
- * @param {Object} squares - All squares
7779
- * @param {string} gameStateBefore - Game state before update
7780
- * @param {boolean} animation - Whether to animate
7781
- */
7782
- _doSequentialUpdate(squares, gameStateBefore, animation) {
7783
- // Mappa: squareId -> expectedPieceId
7784
- const expectedMap = {};
7785
- Object.values(squares).forEach(square => {
7786
- expectedMap[square.id] = this.positionService.getGamePieceId(square.id);
7787
- });
7788
-
7789
- Object.values(squares).forEach(square => {
7790
- const expectedPieceId = expectedMap[square.id];
7791
- const currentPiece = square.piece;
7792
- const currentPieceId = currentPiece ? currentPiece.getId() : null;
7793
-
7794
- // Se il pezzo attuale e quello atteso sono identici, non fare nulla
7795
- if (currentPieceId === expectedPieceId) {
7796
- return;
7797
- }
7798
-
7799
- // Se c'è un pezzo attuale ma non è quello atteso, rimuovilo
7800
- if (currentPiece && currentPieceId !== expectedPieceId) {
7801
- // Rimozione robusta: elimina tutti i pezzi orfani dal DOM e dal riferimento JS
7802
- if (typeof square.forceRemoveAllPieces === 'function') {
7803
- square.forceRemoveAllPieces();
7804
- } else {
7805
- this.pieceService.removePieceFromSquare(square, animation);
7806
- }
7807
- }
7808
-
7809
- // Se c'è un pezzo atteso ma non è quello attuale, aggiungilo
7810
- if (expectedPieceId && currentPieceId !== expectedPieceId) {
7811
- const newPiece = this.pieceService.convertPiece(expectedPieceId);
7812
- this.pieceService.addPieceOnSquare(
7813
- square,
7814
- newPiece,
7815
- animation,
7816
- this._createDragFunction.bind(this)
7817
- );
7818
- }
7819
- });
7820
-
7821
- this._addListeners();
7822
- const gameStateAfter = this.positionService.getGame().fen();
7823
- if (gameStateBefore !== gameStateAfter) {
7824
- this.config.onChange(gameStateAfter);
7825
- }
7826
- }
7827
-
7828
- /**
7829
- * Performs simultaneous piece updates
7830
- * @private
7831
- * @param {Object} squares - All squares
7832
- * @param {string} gameStateBefore - Game state before update
7833
- * @param {boolean} [isPositionLoad=false] - Whether this is a position load
7834
- */
7835
- _doSimultaneousUpdate(squares, gameStateBefore, isPositionLoad = false) {
7836
- // Matching greedy per distanza minima, robusto
7725
+ // --- Matching greedy tra attuale e atteso ---
7837
7726
  const currentMap = {};
7838
7727
  const expectedMap = {};
7839
-
7840
7728
  Object.values(squares).forEach(square => {
7841
7729
  const currentPiece = square.piece;
7842
7730
  const expectedPieceId = this.positionService.getGamePieceId(square.id);
7843
7731
  if (currentPiece) {
7844
- // Normalizza la chiave come 'color+type' lowercase
7845
7732
  const key = (currentPiece.color + currentPiece.type).toLowerCase();
7846
7733
  if (!currentMap[key]) currentMap[key] = [];
7847
- currentMap[key].push({ square, id: square.id });
7734
+ currentMap[key].push({ square, id: square.id, piece: currentPiece });
7848
7735
  }
7849
7736
  if (expectedPieceId) {
7850
- // Normalizza la chiave come 'color+type' lowercase
7851
7737
  const key = expectedPieceId.toLowerCase();
7852
7738
  if (!expectedMap[key]) expectedMap[key] = [];
7853
7739
  expectedMap[key].push({ square, id: square.id });
7854
7740
  }
7855
7741
  });
7856
-
7857
- let animationsCompleted = 0;
7742
+ const animationDelay = isPositionLoad ? 0 : this.config.simultaneousAnimationDelay || 0;
7858
7743
  let totalAnimations = 0;
7859
- const animationDelay = isPositionLoad ? 0 : this.config.simultaneousAnimationDelay;
7860
- let animationIndex = 0;
7861
-
7862
- Object.keys(expectedMap).forEach(key => {
7863
- totalAnimations += Math.max((currentMap[key] || []).length, expectedMap[key].length);
7864
- });
7865
-
7866
- if (totalAnimations === 0) {
7867
- this._addListeners();
7868
- const gameStateAfter = this.positionService.getGame().fen();
7869
- if (gameStateBefore !== gameStateAfter) {
7870
- this.config.onChange(gameStateAfter);
7871
- }
7872
- return;
7873
- }
7874
-
7875
- const onAnimationComplete = () => {
7876
- animationsCompleted++;
7877
- if (animationsCompleted === totalAnimations) {
7878
- this._addListeners();
7879
- const gameStateAfter = this.positionService.getGame().fen();
7880
- if (gameStateBefore !== gameStateAfter) {
7881
- this.config.onChange(gameStateAfter);
7882
- }
7883
- }
7884
- };
7744
+ let animationsCompleted = 0;
7885
7745
 
7746
+ // 1. Matching greedy: trova i movimenti
7747
+ const moves = [];
7748
+ const fromMatched = {};
7749
+ const toMatched = {};
7750
+ const unchanged = [];
7886
7751
  Object.keys(expectedMap).forEach(key => {
7887
7752
  const fromList = (currentMap[key] || []).slice();
7888
7753
  const toList = expectedMap[key].slice();
7889
-
7890
- // 1. Costruisci matrice delle distanze
7754
+ const localFromMatched = new Array(fromList.length).fill(false);
7755
+ const localToMatched = new Array(toList.length).fill(false);
7756
+ // Matrice delle distanze
7891
7757
  const distances = [];
7892
7758
  for (let i = 0; i < fromList.length; i++) {
7893
7759
  distances[i] = [];
@@ -7896,18 +7762,12 @@ let Chessboard$1 = class Chessboard {
7896
7762
  Math.abs(fromList[i].square.col - toList[j].square.col);
7897
7763
  }
7898
7764
  }
7899
-
7900
- // 2. Matching greedy: abbina i più vicini
7901
- const fromMatched = new Array(fromList.length).fill(false);
7902
- const toMatched = new Array(toList.length).fill(false);
7903
- const moves = [];
7904
-
7905
7765
  while (true) {
7906
7766
  let minDist = Infinity, minI = -1, minJ = -1;
7907
7767
  for (let i = 0; i < fromList.length; i++) {
7908
- if (fromMatched[i]) continue;
7768
+ if (localFromMatched[i]) continue;
7909
7769
  for (let j = 0; j < toList.length; j++) {
7910
- if (toMatched[j]) continue;
7770
+ if (localToMatched[j]) continue;
7911
7771
  if (distances[i][j] < minDist) {
7912
7772
  minDist = distances[i][j];
7913
7773
  minI = i;
@@ -7916,64 +7776,111 @@ let Chessboard$1 = class Chessboard {
7916
7776
  }
7917
7777
  }
7918
7778
  if (minI === -1 || minJ === -1) break;
7919
- // Se la posizione è la stessa, non fare nulla (pezzo unchanged)
7920
- if (fromList[minI].square === toList[minJ].square) {
7921
- fromMatched[minI] = true;
7922
- toMatched[minJ] = true;
7779
+ // Se la posizione è la stessa E il Piece è lo stesso oggetto, non fare nulla (pezzo unchanged)
7780
+ if (fromList[minI].square === toList[minJ].square && squares[toList[minJ].square.id].piece === fromList[minI].piece) {
7781
+ unchanged.push({ square: fromList[minI].square, piece: fromList[minI].piece });
7782
+ localFromMatched[minI] = true;
7783
+ localToMatched[minJ] = true;
7784
+ fromMatched[fromList[minI].square.id] = true;
7785
+ toMatched[toList[minJ].square.id] = true;
7923
7786
  continue;
7924
7787
  }
7925
7788
  // Altrimenti, sposta il pezzo
7926
- moves.push({ from: fromList[minI].square, to: toList[minJ].square, piece: fromList[minI].square.piece });
7927
- fromMatched[minI] = true;
7928
- toMatched[minJ] = true;
7789
+ moves.push({ from: fromList[minI].square, to: toList[minJ].square, piece: fromList[minI].piece });
7790
+ localFromMatched[minI] = true;
7791
+ localToMatched[minJ] = true;
7792
+ fromMatched[fromList[minI].square.id] = true;
7793
+ toMatched[toList[minJ].square.id] = true;
7929
7794
  }
7795
+ });
7930
7796
 
7931
- // 3. Rimuovi i pezzi non abbinati (presenti solo in fromList)
7932
- for (let i = 0; i < fromList.length; i++) {
7933
- if (!fromMatched[i]) {
7934
- setTimeout(() => {
7935
- // Rimozione robusta: elimina tutti i pezzi orfani dal DOM e dal riferimento JS
7936
- if (typeof fromList[i].square.forceRemoveAllPieces === 'function') {
7937
- fromList[i].square.forceRemoveAllPieces();
7938
- } else {
7939
- this.pieceService.removePieceFromSquare(fromList[i].square, true, onAnimationComplete);
7940
- }
7941
- onAnimationComplete();
7942
- }, animationIndex * animationDelay);
7943
- animationIndex++;
7797
+ // 2. Rimozione: pezzi presenti solo in attuale (non matched)
7798
+ const removes = [];
7799
+ Object.keys(currentMap).forEach(key => {
7800
+ currentMap[key].forEach(({ square, piece }) => {
7801
+ if (!fromMatched[square.id]) {
7802
+ removes.push({ square, piece });
7803
+ }
7804
+ });
7805
+ });
7806
+
7807
+ // 3. Aggiunta: pezzi presenti solo in atteso (non matched)
7808
+ const adds = [];
7809
+ Object.keys(expectedMap).forEach(key => {
7810
+ expectedMap[key].forEach(({ square, id }) => {
7811
+ if (!toMatched[square.id]) {
7812
+ adds.push({ square, pieceId: key });
7944
7813
  }
7814
+ });
7815
+ });
7816
+
7817
+ totalAnimations = moves.length + removes.length + adds.length;
7818
+ if (totalAnimations === 0) {
7819
+ this._addListeners();
7820
+ const gameStateAfter = this.positionService.getGame().fen();
7821
+ if (gameStateBefore !== gameStateAfter) {
7822
+ this.config.onChange(gameStateAfter);
7945
7823
  }
7824
+ return;
7825
+ }
7946
7826
 
7947
- // 4. Aggiungi i pezzi non abbinati (presenti solo in toList)
7948
- for (let j = 0; j < toList.length; j++) {
7949
- if (!toMatched[j]) {
7950
- setTimeout(() => {
7951
- const newPiece = this.pieceService.convertPiece(key);
7952
- this.pieceService.addPieceOnSquare(
7953
- toList[j].square,
7954
- newPiece,
7955
- true,
7956
- this._createDragFunction.bind(this),
7957
- onAnimationComplete
7958
- );
7959
- }, animationIndex * animationDelay);
7960
- animationIndex++;
7827
+ // Debug: logga i pezzi unchanged
7828
+ if (unchanged.length > 0) {
7829
+ console.debug('[Chessboard] Unchanged pieces:', unchanged.map(u => u.piece.id + '@' + u.square.id));
7830
+ }
7831
+
7832
+ const onAnimationComplete = () => {
7833
+ animationsCompleted++;
7834
+ if (animationsCompleted === totalAnimations) {
7835
+ // Pulizia finale robusta: rimuovi tutti i pezzi orfani dal DOM e dal riferimento JS
7836
+ Object.values(this.boardService.getAllSquares()).forEach(square => {
7837
+ const expectedPieceId = this.positionService.getGamePieceId(square.id);
7838
+ if (!expectedPieceId && typeof square.forceRemoveAllPieces === 'function') {
7839
+ square.forceRemoveAllPieces();
7840
+ }
7841
+ });
7842
+ this._addListeners();
7843
+ const gameStateAfter = this.positionService.getGame().fen();
7844
+ if (gameStateBefore !== gameStateAfter) {
7845
+ this.config.onChange(gameStateAfter);
7961
7846
  }
7962
7847
  }
7848
+ };
7963
7849
 
7964
- // 5. Anima i movimenti
7965
- moves.forEach(move => {
7966
- setTimeout(() => {
7967
- this.pieceService.translatePiece(
7968
- move,
7969
- false,
7970
- true,
7971
- this._createDragFunction.bind(this),
7972
- onAnimationComplete
7973
- );
7974
- }, animationIndex * animationDelay);
7975
- animationIndex++;
7976
- });
7850
+ // 4. Esegui tutte le animazioni con delay
7851
+ let idx = 0;
7852
+ moves.forEach(move => {
7853
+ setTimeout(() => {
7854
+ this.pieceService.translatePiece(
7855
+ move,
7856
+ false,
7857
+ animation,
7858
+ this._createDragFunction.bind(this),
7859
+ onAnimationComplete
7860
+ );
7861
+ }, idx++ * animationDelay);
7862
+ });
7863
+ removes.forEach(op => {
7864
+ setTimeout(() => {
7865
+ if (typeof op.square.forceRemoveAllPieces === 'function') {
7866
+ op.square.forceRemoveAllPieces();
7867
+ onAnimationComplete();
7868
+ } else {
7869
+ this.pieceService.removePieceFromSquare(op.square, animation, onAnimationComplete);
7870
+ }
7871
+ }, idx++ * animationDelay);
7872
+ });
7873
+ adds.forEach(op => {
7874
+ setTimeout(() => {
7875
+ const newPiece = this.pieceService.convertPiece(op.pieceId);
7876
+ this.pieceService.addPieceOnSquare(
7877
+ op.square,
7878
+ newPiece,
7879
+ animation,
7880
+ this._createDragFunction.bind(this),
7881
+ onAnimationComplete
7882
+ );
7883
+ }, idx++ * animationDelay);
7977
7884
  });
7978
7885
  }
7979
7886
 
@@ -8910,23 +8817,6 @@ let Chessboard$1 = class Chessboard {
8910
8817
  }
8911
8818
  }
8912
8819
 
8913
- /**
8914
- * Gets or sets the animation style
8915
- * @param {string} [style] - New animation style ('sequential' or 'simultaneous')
8916
- * @returns {string} Current animation style
8917
- */
8918
- animationStyle(style) {
8919
- if (style === undefined) {
8920
- return this.config.animationStyle;
8921
- }
8922
-
8923
- if (this.validationService.isValidAnimationStyle(style)) {
8924
- this.config.animationStyle = style;
8925
- }
8926
-
8927
- return this.config.animationStyle;
8928
- }
8929
-
8930
8820
  /**
8931
8821
  * Gets or sets the simultaneous animation delay
8932
8822
  * @param {number} [delay] - New delay in milliseconds
@@ -9494,7 +9384,6 @@ class ChessboardFactory {
9494
9384
  hints: true,
9495
9385
  clickable: true,
9496
9386
  moveHighlight: true,
9497
- animationStyle: 'simultaneous'
9498
9387
  });
9499
9388
 
9500
9389
  // Tournament template
@@ -9505,7 +9394,6 @@ class ChessboardFactory {
9505
9394
  clickable: true,
9506
9395
  moveHighlight: true,
9507
9396
  onlyLegalMoves: true,
9508
- animationStyle: 'sequential'
9509
9397
  });
9510
9398
 
9511
9399
  // Analysis template
@@ -9516,7 +9404,6 @@ class ChessboardFactory {
9516
9404
  clickable: true,
9517
9405
  moveHighlight: true,
9518
9406
  mode: 'analysis',
9519
- animationStyle: 'simultaneous'
9520
9407
  });
9521
9408
 
9522
9409
  // Puzzle template
@@ -9527,7 +9414,6 @@ class ChessboardFactory {
9527
9414
  clickable: true,
9528
9415
  moveHighlight: true,
9529
9416
  onlyLegalMoves: true,
9530
- animationStyle: 'sequential'
9531
9417
  });
9532
9418
 
9533
9419
  // Demo template
@@ -9537,7 +9423,6 @@ class ChessboardFactory {
9537
9423
  hints: false,
9538
9424
  clickable: false,
9539
9425
  moveHighlight: true,
9540
- animationStyle: 'simultaneous'
9541
9426
  });
9542
9427
  }
9543
9428
 
@@ -10345,11 +10230,7 @@ function validateConfig(config) {
10345
10230
  if (config.moveAnimation && !isValidEasing(config.moveAnimation)) {
10346
10231
  errors.push('Invalid moveAnimation. Must be a valid easing function');
10347
10232
  }
10348
-
10349
- if (config.animationStyle && !['sequential', 'simultaneous'].includes(config.animationStyle)) {
10350
- errors.push('Invalid animationStyle. Must be "sequential" or "simultaneous"');
10351
- }
10352
-
10233
+
10353
10234
  return {
10354
10235
  success: errors.length === 0,
10355
10236
  errors