valtech-components 4.0.573 → 4.0.576

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.
@@ -59,7 +59,7 @@ import fixWebmDuration from 'fix-webm-duration';
59
59
  * Current version of valtech-components.
60
60
  * This is automatically updated during the publish process.
61
61
  */
62
- const VERSION = '4.0.573';
62
+ const VERSION = '4.0.576';
63
63
 
64
64
  // Control de estado de refresco (singleton a nivel de módulo)
65
65
  let isRefreshing = false;
@@ -61711,28 +61711,250 @@ const CHESSIMALS_BOT_PROFILES = [
61711
61711
  },
61712
61712
  ];
61713
61713
  const BOT_STYLES = {
61714
- explorer: { advancement: 1.05, capture: 0.82, safety: 0.62, power: 0.8, center: 1.15, unlock: 1.05, reply: 0.7, randomness: 260, spread: 0.68, mobility: 0.75, trap: 0.5, endgame: 0.55 },
61715
- impulsive: { advancement: 0.9, capture: 1.45, safety: 0.48, power: 1.15, center: 0.8, unlock: 0.9, reply: 0.55, randomness: 290, spread: 0.62, mobility: 0.85, trap: 0.62, endgame: 0.5 },
61716
- runner: { advancement: 1.55, capture: 0.78, safety: 0.5, power: 0.95, center: 0.7, unlock: 1.1, reply: 0.55, randomness: 250, spread: 0.6, mobility: 0.72, trap: 0.45, endgame: 1.1 },
61717
- hunter: { advancement: 0.95, capture: 1.45, safety: 0.9, power: 1.05, center: 0.95, unlock: 0.95, reply: 1, randomness: 90, spread: 0.3, mobility: 0.95, trap: 0.82, endgame: 0.76 },
61718
- guardian: { advancement: 0.88, capture: 1, safety: 1.45, power: 0.85, center: 1.05, unlock: 1, reply: 1.15, randomness: 70, spread: 0.26, mobility: 0.82, trap: 0.72, endgame: 0.72 },
61719
- jumper: { advancement: 1.12, capture: 1, safety: 0.92, power: 1.42, center: 1.18, unlock: 1.08, reply: 0.95, randomness: 95, spread: 0.32, mobility: 1.15, trap: 0.9, endgame: 0.82 },
61720
- strategist: { advancement: 1.05, capture: 1.08, safety: 1.22, power: 1.08, center: 1.16, unlock: 1.1, reply: 1.25, randomness: 22, spread: 0.14, mobility: 1.08, trap: 1.06, endgame: 1 },
61721
- predator: { advancement: 0.98, capture: 1.68, safety: 1.02, power: 1.34, center: 1, unlock: 1, reply: 1.12, randomness: 28, spread: 0.16, mobility: 1.02, trap: 1.18, endgame: 0.82 },
61722
- sprinter: { advancement: 1.72, capture: 0.9, safety: 0.95, power: 1.08, center: 0.86, unlock: 1.18, reply: 1, randomness: 26, spread: 0.15, mobility: 0.95, trap: 0.78, endgame: 1.42 },
61723
- sentinel: { advancement: 0.9, capture: 1.12, safety: 1.72, power: 0.95, center: 1.28, unlock: 1.05, reply: 1.38, randomness: 18, spread: 0.12, mobility: 0.86, trap: 1.04, endgame: 0.84 },
61724
- oracle: { advancement: 1, capture: 1.12, safety: 1.42, power: 1.1, center: 1.18, unlock: 1.08, reply: 1.8, randomness: 8, spread: 0.08, mobility: 1.06, trap: 1.22, endgame: 1.08 },
61725
- ambusher: { advancement: 0.9, capture: 1.48, safety: 1.08, power: 1.46, center: 1.05, unlock: 1.02, reply: 1.32, randomness: 14, spread: 0.1, mobility: 1.12, trap: 1.72, endgame: 0.92 },
61726
- locksmith: { advancement: 0.88, capture: 1.04, safety: 1.55, power: 1.02, center: 1.48, unlock: 1.12, reply: 1.52, randomness: 12, spread: 0.1, mobility: 1.58, trap: 1.24, endgame: 0.86 },
61727
- storm: { advancement: 1.18, capture: 1.38, safety: 0.98, power: 1.62, center: 1.08, unlock: 1.18, reply: 1.22, randomness: 18, spread: 0.13, mobility: 1.36, trap: 1.28, endgame: 1.02 },
61728
- matriarch: { advancement: 0.96, capture: 1.18, safety: 1.64, power: 1.18, center: 1.22, unlock: 1.08, reply: 1.66, randomness: 10, spread: 0.08, mobility: 1.02, trap: 1.36, endgame: 1 },
61729
- endgame: { advancement: 1.46, capture: 1, safety: 1.28, power: 1.04, center: 0.94, unlock: 1.08, reply: 1.44, randomness: 10, spread: 0.09, mobility: 0.98, trap: 1.02, endgame: 1.86 },
61730
- magnus: { advancement: 1.04, capture: 1.22, safety: 1.9, power: 0.9, center: 1.42, unlock: 1.08, reply: 2.08, randomness: 3, spread: 0.04, mobility: 1.08, trap: 1.42, endgame: 1.86 },
61714
+ explorer: {
61715
+ advancement: 1.05,
61716
+ capture: 0.82,
61717
+ safety: 0.62,
61718
+ power: 0.8,
61719
+ center: 1.15,
61720
+ unlock: 1.05,
61721
+ reply: 0.7,
61722
+ randomness: 260,
61723
+ spread: 0.68,
61724
+ mobility: 0.75,
61725
+ trap: 0.5,
61726
+ endgame: 0.55,
61727
+ },
61728
+ impulsive: {
61729
+ advancement: 0.9,
61730
+ capture: 1.45,
61731
+ safety: 0.48,
61732
+ power: 1.15,
61733
+ center: 0.8,
61734
+ unlock: 0.9,
61735
+ reply: 0.55,
61736
+ randomness: 290,
61737
+ spread: 0.62,
61738
+ mobility: 0.85,
61739
+ trap: 0.62,
61740
+ endgame: 0.5,
61741
+ },
61742
+ runner: {
61743
+ advancement: 1.55,
61744
+ capture: 0.78,
61745
+ safety: 0.5,
61746
+ power: 0.95,
61747
+ center: 0.7,
61748
+ unlock: 1.1,
61749
+ reply: 0.55,
61750
+ randomness: 250,
61751
+ spread: 0.6,
61752
+ mobility: 0.72,
61753
+ trap: 0.45,
61754
+ endgame: 1.1,
61755
+ },
61756
+ hunter: {
61757
+ advancement: 0.95,
61758
+ capture: 1.45,
61759
+ safety: 0.9,
61760
+ power: 1.05,
61761
+ center: 0.95,
61762
+ unlock: 0.95,
61763
+ reply: 1,
61764
+ randomness: 90,
61765
+ spread: 0.3,
61766
+ mobility: 0.95,
61767
+ trap: 0.82,
61768
+ endgame: 0.76,
61769
+ },
61770
+ guardian: {
61771
+ advancement: 0.88,
61772
+ capture: 1,
61773
+ safety: 1.45,
61774
+ power: 0.85,
61775
+ center: 1.05,
61776
+ unlock: 1,
61777
+ reply: 1.15,
61778
+ randomness: 70,
61779
+ spread: 0.26,
61780
+ mobility: 0.82,
61781
+ trap: 0.72,
61782
+ endgame: 0.72,
61783
+ },
61784
+ jumper: {
61785
+ advancement: 1.12,
61786
+ capture: 1,
61787
+ safety: 0.92,
61788
+ power: 1.42,
61789
+ center: 1.18,
61790
+ unlock: 1.08,
61791
+ reply: 0.95,
61792
+ randomness: 95,
61793
+ spread: 0.32,
61794
+ mobility: 1.15,
61795
+ trap: 0.9,
61796
+ endgame: 0.82,
61797
+ },
61798
+ strategist: {
61799
+ advancement: 1.05,
61800
+ capture: 1.08,
61801
+ safety: 1.22,
61802
+ power: 1.08,
61803
+ center: 1.16,
61804
+ unlock: 1.1,
61805
+ reply: 1.25,
61806
+ randomness: 22,
61807
+ spread: 0.14,
61808
+ mobility: 1.08,
61809
+ trap: 1.06,
61810
+ endgame: 1,
61811
+ },
61812
+ predator: {
61813
+ advancement: 0.98,
61814
+ capture: 1.68,
61815
+ safety: 1.02,
61816
+ power: 1.34,
61817
+ center: 1,
61818
+ unlock: 1,
61819
+ reply: 1.12,
61820
+ randomness: 28,
61821
+ spread: 0.16,
61822
+ mobility: 1.02,
61823
+ trap: 1.18,
61824
+ endgame: 0.82,
61825
+ },
61826
+ sprinter: {
61827
+ advancement: 1.72,
61828
+ capture: 0.9,
61829
+ safety: 0.95,
61830
+ power: 1.08,
61831
+ center: 0.86,
61832
+ unlock: 1.18,
61833
+ reply: 1,
61834
+ randomness: 26,
61835
+ spread: 0.15,
61836
+ mobility: 0.95,
61837
+ trap: 0.78,
61838
+ endgame: 1.42,
61839
+ },
61840
+ sentinel: {
61841
+ advancement: 0.9,
61842
+ capture: 1.12,
61843
+ safety: 1.72,
61844
+ power: 0.95,
61845
+ center: 1.28,
61846
+ unlock: 1.05,
61847
+ reply: 1.38,
61848
+ randomness: 18,
61849
+ spread: 0.12,
61850
+ mobility: 0.86,
61851
+ trap: 1.04,
61852
+ endgame: 0.84,
61853
+ },
61854
+ oracle: {
61855
+ advancement: 1,
61856
+ capture: 1.12,
61857
+ safety: 1.42,
61858
+ power: 1.1,
61859
+ center: 1.18,
61860
+ unlock: 1.08,
61861
+ reply: 1.8,
61862
+ randomness: 8,
61863
+ spread: 0.08,
61864
+ mobility: 1.06,
61865
+ trap: 1.22,
61866
+ endgame: 1.08,
61867
+ },
61868
+ ambusher: {
61869
+ advancement: 0.9,
61870
+ capture: 1.48,
61871
+ safety: 1.08,
61872
+ power: 1.46,
61873
+ center: 1.05,
61874
+ unlock: 1.02,
61875
+ reply: 1.32,
61876
+ randomness: 14,
61877
+ spread: 0.1,
61878
+ mobility: 1.12,
61879
+ trap: 1.72,
61880
+ endgame: 0.92,
61881
+ },
61882
+ locksmith: {
61883
+ advancement: 0.88,
61884
+ capture: 1.04,
61885
+ safety: 1.55,
61886
+ power: 1.02,
61887
+ center: 1.48,
61888
+ unlock: 1.12,
61889
+ reply: 1.52,
61890
+ randomness: 12,
61891
+ spread: 0.1,
61892
+ mobility: 1.58,
61893
+ trap: 1.24,
61894
+ endgame: 0.86,
61895
+ },
61896
+ storm: {
61897
+ advancement: 1.18,
61898
+ capture: 1.38,
61899
+ safety: 0.98,
61900
+ power: 1.62,
61901
+ center: 1.08,
61902
+ unlock: 1.18,
61903
+ reply: 1.22,
61904
+ randomness: 18,
61905
+ spread: 0.13,
61906
+ mobility: 1.36,
61907
+ trap: 1.28,
61908
+ endgame: 1.02,
61909
+ },
61910
+ matriarch: {
61911
+ advancement: 0.96,
61912
+ capture: 1.18,
61913
+ safety: 1.64,
61914
+ power: 1.18,
61915
+ center: 1.22,
61916
+ unlock: 1.08,
61917
+ reply: 1.66,
61918
+ randomness: 10,
61919
+ spread: 0.08,
61920
+ mobility: 1.02,
61921
+ trap: 1.36,
61922
+ endgame: 1,
61923
+ },
61924
+ endgame: {
61925
+ advancement: 1.46,
61926
+ capture: 1,
61927
+ safety: 1.28,
61928
+ power: 1.04,
61929
+ center: 0.94,
61930
+ unlock: 1.08,
61931
+ reply: 1.44,
61932
+ randomness: 10,
61933
+ spread: 0.09,
61934
+ mobility: 0.98,
61935
+ trap: 1.02,
61936
+ endgame: 1.86,
61937
+ },
61938
+ magnus: {
61939
+ advancement: 1.04,
61940
+ capture: 1.22,
61941
+ safety: 1.9,
61942
+ power: 0.9,
61943
+ center: 1.42,
61944
+ unlock: 1.08,
61945
+ reply: 2.08,
61946
+ randomness: 3,
61947
+ spread: 0.04,
61948
+ mobility: 1.08,
61949
+ trap: 1.42,
61950
+ endgame: 1.86,
61951
+ },
61731
61952
  };
61732
61953
  const DEFAULT_BOT_PROFILE_BY_DIFFICULTY = {
61733
61954
  easy: 'explorer',
61734
61955
  normal: 'hunter',
61735
61956
  hard: 'strategist',
61957
+ master: 'magnus',
61736
61958
  };
61737
61959
  function createChessimalsGame(boardSize = 6, options = {}) {
61738
61960
  const pieces = [];
@@ -61772,12 +61994,12 @@ function createChessimalsGame(boardSize = 6, options = {}) {
61772
61994
  };
61773
61995
  }
61774
61996
  function getChessimalsPieceAt(state, position) {
61775
- return activePieces(state).find((piece) => !piece.captured && piece.position.row === position.row && piece.position.col === position.col);
61997
+ return activePieces(state).find(piece => !piece.captured && piece.position.row === position.row && piece.position.col === position.col);
61776
61998
  }
61777
61999
  function getChessimalsLegalMoves(state, pieceId, animal) {
61778
62000
  if (state.status !== 'in_progress')
61779
62001
  return [];
61780
- const piece = activePieces(state).find((item) => item.id === pieceId && !item.captured);
62002
+ const piece = activePieces(state).find(item => item.id === pieceId && !item.captured);
61781
62003
  if (!piece || piece.color !== state.currentTurn)
61782
62004
  return [];
61783
62005
  if (animal) {
@@ -61816,9 +62038,18 @@ function chooseChessimalsBotMove(state, difficulty = 'normal', profileId = DEFAU
61816
62038
  const challengePressure = getChallengePressure(options.challengeRound);
61817
62039
  const style = tuneBotStyle(baseStyle, difficulty, challengePressure, options.nightmareMode);
61818
62040
  const quickScored = moves
61819
- .map((move) => ({ move, score: scoreBotMove(state, move, difficulty, style, challengePressure, false, options.nightmareMode) }))
62041
+ .map(move => ({
62042
+ move,
62043
+ score: scoreBotMove(state, move, difficulty, style, challengePressure, false, options.nightmareMode),
62044
+ }))
61820
62045
  .sort((a, b) => b.score - a.score);
61821
- const lookaheadLimit = options.nightmareMode === 'magnus' ? 48 : difficulty === 'hard' ? 32 : difficulty === 'normal' ? 24 : 0;
62046
+ const lookaheadLimit = options.nightmareMode === 'magnus' || difficulty === 'master'
62047
+ ? 48
62048
+ : difficulty === 'hard'
62049
+ ? 32
62050
+ : difficulty === 'normal'
62051
+ ? 24
62052
+ : 0;
61822
62053
  const scored = quickScored
61823
62054
  .map((item, index) => ({
61824
62055
  move: item.move,
@@ -61828,18 +62059,18 @@ function chooseChessimalsBotMove(state, difficulty = 'normal', profileId = DEFAU
61828
62059
  }))
61829
62060
  .sort((a, b) => b.score - a.score);
61830
62061
  if (difficulty === 'easy') {
61831
- const playable = scored.filter((item) => item.score > -3000);
62062
+ const playable = scored.filter(item => item.score > -3000);
61832
62063
  return pickNoisyBotMove(playable.length ? playable : scored, 0.55);
61833
62064
  }
61834
62065
  if (difficulty === 'normal') {
61835
62066
  return scored[0]?.move;
61836
62067
  }
61837
- const winningMove = scored.find((item) => item.score >= 10000);
62068
+ const winningMove = scored.find(item => item.score >= 10000);
61838
62069
  if (winningMove)
61839
62070
  return winningMove.move;
61840
- const opponentWinningTargets = new Set(getImmediateWinningMoves(state, otherColor(state.currentTurn)).map((move) => positionKey(move.to)));
62071
+ const opponentWinningTargets = new Set(getImmediateWinningMoves(state, otherColor(state.currentTurn)).map(move => positionKey(move.to)));
61841
62072
  if (opponentWinningTargets.size > 0) {
61842
- const blockingMove = scored.find((item) => item.move.capturesPieceId || opponentWinningTargets.has(positionKey(item.move.to)));
62073
+ const blockingMove = scored.find(item => item.move.capturesPieceId || opponentWinningTargets.has(positionKey(item.move.to)));
61843
62074
  if (blockingMove)
61844
62075
  return blockingMove.move;
61845
62076
  }
@@ -61855,15 +62086,15 @@ function chooseChessimalsBotMove(state, difficulty = 'normal', profileId = DEFAU
61855
62086
  return scored[0]?.move;
61856
62087
  }
61857
62088
  function applyChessimalsMove(state, candidate) {
61858
- const legalMove = getChessimalsLegalMoves(state, candidate.pieceId, candidate.animal).find((move) => samePosition(move.from, candidate.from) && samePosition(move.to, candidate.to));
62089
+ const legalMove = getChessimalsLegalMoves(state, candidate.pieceId, candidate.animal).find(move => samePosition(move.from, candidate.from) && samePosition(move.to, candidate.to));
61859
62090
  if (!legalMove) {
61860
62091
  throw new Error('CHESSIMALS_ILLEGAL_MOVE');
61861
62092
  }
61862
- const movedPiece = activePieces(state).find((piece) => piece.id === legalMove.pieceId);
62093
+ const movedPiece = activePieces(state).find(piece => piece.id === legalMove.pieceId);
61863
62094
  if (!movedPiece) {
61864
62095
  throw new Error('CHESSIMALS_PIECE_NOT_FOUND');
61865
62096
  }
61866
- const pieces = activePieces(state).map((piece) => {
62097
+ const pieces = activePieces(state).map(piece => {
61867
62098
  if (piece.id === legalMove.pieceId) {
61868
62099
  return { ...piece, position: { ...legalMove.to } };
61869
62100
  }
@@ -61893,7 +62124,7 @@ function applyChessimalsMove(state, candidate) {
61893
62124
  lastMove: legalMove,
61894
62125
  });
61895
62126
  const promoted = isPromotionRow(nextState.boardSize, movedPiece.color, legalMove.to);
61896
- const enemyPieces = activePieces(nextState).filter((piece) => piece.color !== movedPiece.color && !piece.captured);
62127
+ const enemyPieces = activePieces(nextState).filter(piece => piece.color !== movedPiece.color && !piece.captured);
61897
62128
  const enemyHasLegalMoves = getChessimalsAllLegalMoves(nextState, nextState.currentTurn).length > 0;
61898
62129
  const resolvedState = promoted || enemyPieces.length === 0 || !enemyHasLegalMoves
61899
62130
  ? {
@@ -61909,10 +62140,7 @@ function applyChessimalsMove(state, candidate) {
61909
62140
  : nextState;
61910
62141
  return {
61911
62142
  ...resolvedState,
61912
- moveHistory: [
61913
- ...ensureMoveHistory(state),
61914
- createMoveHistoryEntry(resolvedState, legalMove),
61915
- ],
62143
+ moveHistory: [...ensureMoveHistory(state), createMoveHistoryEntry(resolvedState, legalMove)],
61916
62144
  };
61917
62145
  }
61918
62146
  function createChessimalsReviewState(state, entry) {
@@ -61955,7 +62183,7 @@ function cloneMoveHistoryEntry(entry) {
61955
62183
  };
61956
62184
  }
61957
62185
  function clonePieces(pieces) {
61958
- return pieces.map((piece) => ({
62186
+ return pieces.map(piece => ({
61959
62187
  ...piece,
61960
62188
  position: { ...piece.position },
61961
62189
  }));
@@ -61979,10 +62207,7 @@ function resignChessimalsGame(state, color) {
61979
62207
  };
61980
62208
  return {
61981
62209
  ...resignedState,
61982
- moveHistory: [
61983
- ...ensureMoveHistory(state),
61984
- createMoveHistoryEntry(resignedState),
61985
- ],
62210
+ moveHistory: [...ensureMoveHistory(state), createMoveHistoryEntry(resignedState)],
61986
62211
  };
61987
62212
  }
61988
62213
  function positionKey(position) {
@@ -62109,12 +62334,16 @@ function getKangarooMoves(state, piece) {
62109
62334
  function scoreBotMove(state, move, difficulty, style, challengePressure = 0, includeTacticalPressure = true, nightmareMode = 'none') {
62110
62335
  const color = state.currentTurn;
62111
62336
  const targetPiece = move.capturesPieceId
62112
- ? activePieces(state).find((piece) => piece.id === move.capturesPieceId)
62337
+ ? activePieces(state).find(piece => piece.id === move.capturesPieceId)
62113
62338
  : undefined;
62114
62339
  const advancement = color === 'white' ? state.boardSize - 1 - move.to.row : move.to.row;
62115
62340
  let score = advancement * 24 * style.advancement;
62116
62341
  const stepsToPromotion = color === 'white' ? move.to.row : state.boardSize - 1 - move.to.row;
62117
- score += Math.max(0, state.boardSize - 1 - stepsToPromotion) * 10 * challengePressure * style.advancement;
62342
+ score +=
62343
+ Math.max(0, state.boardSize - 1 - stepsToPromotion) *
62344
+ 10 *
62345
+ challengePressure *
62346
+ style.advancement;
62118
62347
  if (move.kind === 'basic' && isPromotionRow(state.boardSize, color, move.to)) {
62119
62348
  score += 10000 + 2500 * challengePressure;
62120
62349
  }
@@ -62131,7 +62360,9 @@ function scoreBotMove(state, move, difficulty, style, challengePressure = 0, inc
62131
62360
  score += targetAdvancement * (16 + 8 * challengePressure) * style.capture;
62132
62361
  }
62133
62362
  if (move.kind === 'power') {
62134
- score += (targetPiece ? 120 : difficulty === 'hard' ? -60 - 170 * challengePressure : -30) * style.power;
62363
+ score +=
62364
+ (targetPiece ? 120 : difficulty === 'hard' ? -60 - 170 * challengePressure : -30) *
62365
+ style.power;
62135
62366
  }
62136
62367
  if (nightmareMode === 'magnus' && move.kind === 'power') {
62137
62368
  score += scoreMagnusPowerPatience(state, move, targetPiece, style);
@@ -62143,8 +62374,14 @@ function scoreBotMove(state, move, difficulty, style, challengePressure = 0, inc
62143
62374
  if (wouldUnlockPower(state, color, move.to))
62144
62375
  score += 90 * style.unlock;
62145
62376
  if (includeTacticalPressure && state.boardSize <= 6) {
62146
- score += countPowerReachAfterMove(state, move, color) * (difficulty === 'hard' ? 8 : 4) * style.mobility;
62147
- score += countProtectedThreatsAfterMove(state, move, color) * (difficulty === 'hard' ? 36 : 18) * style.trap;
62377
+ score +=
62378
+ countPowerReachAfterMove(state, move, color) *
62379
+ (difficulty === 'hard' ? 8 : 4) *
62380
+ style.mobility;
62381
+ score +=
62382
+ countProtectedThreatsAfterMove(state, move, color) *
62383
+ (difficulty === 'hard' ? 36 : 18) *
62384
+ style.trap;
62148
62385
  score += scoreEndgamePressure(state, move, color) * style.endgame;
62149
62386
  }
62150
62387
  else {
@@ -62163,30 +62400,83 @@ function scoreBotMoveWithLookahead(state, move, difficulty, style, challengePres
62163
62400
  if (afterMove.status === 'finished')
62164
62401
  return score + 5000;
62165
62402
  const opponentMoves = getChessimalsAllLegalMoves(afterMove);
62166
- const opponentImmediateWin = opponentMoves.some((opponentMove) => opponentMove.kind === 'basic' &&
62403
+ const opponentImmediateWin = opponentMoves.some(opponentMove => opponentMove.kind === 'basic' &&
62167
62404
  isPromotionRow(afterMove.boardSize, afterMove.currentTurn, opponentMove.to));
62168
62405
  if (opponentImmediateWin) {
62169
- score -= (difficulty === 'easy' ? 1800 : difficulty === 'normal' ? 5200 : 8000 + 4200 * challengePressure) * style.safety;
62170
- }
62171
- const movedPiece = afterMove.pieces.find((piece) => piece.id === move.pieceId && !piece.captured);
62406
+ score -=
62407
+ (difficulty === 'easy'
62408
+ ? 1800
62409
+ : difficulty === 'normal'
62410
+ ? 5200
62411
+ : 8000 + 4200 * challengePressure) * style.safety;
62412
+ }
62413
+ const movedPiece = afterMove.pieces.find(piece => piece.id === move.pieceId && !piece.captured);
62172
62414
  if (movedPiece) {
62173
- const canCaptureMovedPiece = opponentMoves.some((opponentMove) => opponentMove.capturesPieceId === move.pieceId);
62415
+ const canCaptureMovedPiece = opponentMoves.some(opponentMove => opponentMove.capturesPieceId === move.pieceId);
62174
62416
  if (canCaptureMovedPiece) {
62175
- score -= (move.capturesPieceId ? 180 : difficulty === 'easy' ? 120 : difficulty === 'normal' ? 360 : 560)
62176
- * style.safety
62177
- * (1 + challengePressure);
62417
+ score -=
62418
+ (move.capturesPieceId
62419
+ ? 180
62420
+ : difficulty === 'easy'
62421
+ ? 120
62422
+ : difficulty === 'normal'
62423
+ ? 360
62424
+ : 560) *
62425
+ style.safety *
62426
+ (1 + challengePressure);
62178
62427
  }
62179
62428
  const center = (afterMove.boardSize - 1) / 2;
62180
62429
  const centerControl = Math.max(0, afterMove.boardSize / 2 - Math.abs(movedPiece.position.col - center));
62181
62430
  score += centerControl * (difficulty === 'hard' ? 18 : 10) * style.center;
62182
62431
  }
62183
62432
  const opponentBestReply = opponentMoves
62184
- .map((opponentMove) => scoreBotMove(afterMove, opponentMove, difficulty, style, challengePressure, false, nightmareMode))
62433
+ .map(opponentMove => scoreBotMove(afterMove, opponentMove, difficulty, style, challengePressure, false, nightmareMode))
62185
62434
  .sort((a, b) => b - a)[0];
62186
62435
  if (opponentBestReply) {
62187
- const replyWeight = difficulty === 'easy' ? 0.12 : difficulty === 'normal' ? 0.32 + 0.08 * challengePressure : 0.48 + 0.16 * challengePressure;
62436
+ const replyWeight = difficulty === 'easy'
62437
+ ? 0.12
62438
+ : difficulty === 'normal'
62439
+ ? 0.4 + 0.1 * challengePressure
62440
+ : difficulty === 'master'
62441
+ ? 0.72 + 0.22 * challengePressure
62442
+ : nightmareMode && nightmareMode !== 'none'
62443
+ ? 0.82 + 0.18 * challengePressure
62444
+ : 0.48 + 0.16 * challengePressure;
62188
62445
  score -= opponentBestReply * replyWeight * style.reply;
62189
62446
  }
62447
+ if (difficulty === 'hard' || difficulty === 'master') {
62448
+ const topOppMoves = opponentMoves
62449
+ .map(m => ({
62450
+ move: m,
62451
+ score: scoreBotMove(afterMove, m, difficulty, style, challengePressure, false, nightmareMode),
62452
+ }))
62453
+ .sort((a, b) => b.score - a.score)
62454
+ .slice(0, 4);
62455
+ for (const { move: oppMove } of topOppMoves) {
62456
+ try {
62457
+ const s2 = applyChessimalsMove(afterMove, oppMove);
62458
+ if (s2.status === 'finished')
62459
+ continue;
62460
+ const myCounters = getChessimalsAllLegalMoves(s2);
62461
+ if (myCounters.length === 0)
62462
+ continue;
62463
+ const myBest = myCounters
62464
+ .map(m => scoreBotMove(s2, m, difficulty, style, challengePressure, false, nightmareMode))
62465
+ .sort((a, b) => b - a)[0] ?? 0;
62466
+ score +=
62467
+ myBest *
62468
+ (difficulty === 'master'
62469
+ ? 0.22
62470
+ : nightmareMode && nightmareMode !== 'none'
62471
+ ? 0.2
62472
+ : 0.14) *
62473
+ style.reply;
62474
+ }
62475
+ catch {
62476
+ // skip
62477
+ }
62478
+ }
62479
+ }
62190
62480
  }
62191
62481
  catch {
62192
62482
  score -= 1000;
@@ -62194,9 +62484,9 @@ function scoreBotMoveWithLookahead(state, move, difficulty, style, challengePres
62194
62484
  return score;
62195
62485
  }
62196
62486
  function getChallengePressure(round) {
62197
- if (!round || round <= 2)
62487
+ if (!round)
62198
62488
  return 0;
62199
- return Math.min(1, Math.max(0, (round - 2) / 6));
62489
+ return Math.min(1, Math.max(0, round / 8));
62200
62490
  }
62201
62491
  function tuneBotStyle(style, difficulty, challengePressure, nightmareMode = 'none') {
62202
62492
  if (nightmareMode === 'hunt') {
@@ -62234,9 +62524,28 @@ function tuneBotStyle(style, difficulty, challengePressure, nightmareMode = 'non
62234
62524
  endgame: style.endgame * 1.28,
62235
62525
  };
62236
62526
  }
62527
+ if (difficulty === 'master') {
62528
+ style = {
62529
+ ...style,
62530
+ capture: style.capture * 1.08,
62531
+ safety: style.safety * 1.22,
62532
+ reply: style.reply * 1.32,
62533
+ center: style.center * 1.12,
62534
+ randomness: Math.min(style.randomness, 3),
62535
+ spread: style.spread * 0.5,
62536
+ trap: style.trap * 1.14,
62537
+ endgame: style.endgame * 1.18,
62538
+ };
62539
+ }
62237
62540
  if (!challengePressure)
62238
62541
  return style;
62239
- const pressure = difficulty === 'easy' ? challengePressure * 0.45 : challengePressure;
62542
+ const pressure = difficulty === 'easy'
62543
+ ? challengePressure * 0.45
62544
+ : difficulty === 'master'
62545
+ ? challengePressure * 1.15
62546
+ : nightmareMode && nightmareMode !== 'none'
62547
+ ? challengePressure * 1.25
62548
+ : challengePressure;
62240
62549
  return {
62241
62550
  ...style,
62242
62551
  capture: style.capture * (1 + pressure * 0.28),
@@ -62251,7 +62560,7 @@ function chooseChallengeBasicCapture(scored, challengePressure) {
62251
62560
  if (challengePressure < 0.5)
62252
62561
  return undefined;
62253
62562
  const best = scored[0];
62254
- const bestBasicCapture = scored.find((item) => item.move.kind === 'basic' && item.move.capturesPieceId);
62563
+ const bestBasicCapture = scored.find(item => item.move.kind === 'basic' && item.move.capturesPieceId);
62255
62564
  if (!best || !bestBasicCapture)
62256
62565
  return undefined;
62257
62566
  if (best.move.kind === 'basic' && best.move.capturesPieceId)
@@ -62263,7 +62572,7 @@ function chooseNightmareCapture(scored, nightmareMode) {
62263
62572
  if (nightmareMode !== 'hunt')
62264
62573
  return undefined;
62265
62574
  const best = scored[0];
62266
- const capture = scored.find((item) => item.move.capturesPieceId);
62575
+ const capture = scored.find(item => item.move.capturesPieceId);
62267
62576
  if (!best || !capture)
62268
62577
  return undefined;
62269
62578
  return best.score - capture.score <= 1800 ? capture.move : undefined;
@@ -62288,7 +62597,7 @@ function countPowerReachAfterMove(state, move, color) {
62288
62597
  try {
62289
62598
  const afterMove = applyChessimalsMove(state, move);
62290
62599
  const evaluationState = { ...afterMove, currentTurn: color };
62291
- return getChessimalsAllLegalMoves(evaluationState, color).filter((nextMove) => nextMove.kind === 'power').length;
62600
+ return getChessimalsAllLegalMoves(evaluationState, color).filter(nextMove => nextMove.kind === 'power').length;
62292
62601
  }
62293
62602
  catch {
62294
62603
  return 0;
@@ -62299,15 +62608,15 @@ function countProtectedThreatsAfterMove(state, move, color) {
62299
62608
  const afterMove = applyChessimalsMove(state, move);
62300
62609
  const evaluationState = { ...afterMove, currentTurn: color };
62301
62610
  const ourMoves = getChessimalsAllLegalMoves(evaluationState, color);
62302
- const enemyPieces = activePieces(afterMove).filter((piece) => piece.color !== color && !piece.captured);
62303
- return enemyPieces.filter((piece) => ourMoves.some((nextMove) => nextMove.capturesPieceId === piece.id)).length;
62611
+ const enemyPieces = activePieces(afterMove).filter(piece => piece.color !== color && !piece.captured);
62612
+ return enemyPieces.filter(piece => ourMoves.some(nextMove => nextMove.capturesPieceId === piece.id)).length;
62304
62613
  }
62305
62614
  catch {
62306
62615
  return 0;
62307
62616
  }
62308
62617
  }
62309
62618
  function scoreEndgamePressure(state, move, color) {
62310
- const remainingEnemyPieces = activePieces(state).filter((piece) => piece.color !== color && !piece.captured).length;
62619
+ const remainingEnemyPieces = activePieces(state).filter(piece => piece.color !== color && !piece.captured).length;
62311
62620
  const urgency = remainingEnemyPieces <= Math.max(2, Math.floor(state.boardSize / 2)) ? 1.6 : 1;
62312
62621
  const distanceToPromotion = color === 'white' ? move.to.row : state.boardSize - 1 - move.to.row;
62313
62622
  return Math.max(0, state.boardSize - distanceToPromotion) * 14 * urgency;
@@ -62319,7 +62628,7 @@ function chooseConservativeHardCapture(state, scored) {
62319
62628
  if (!best || best.move.kind !== 'power' || !best.move.capturesPieceId || best.score >= 10000) {
62320
62629
  return undefined;
62321
62630
  }
62322
- const bestBasicCapture = scored.find((item) => item.move.kind === 'basic' && item.move.capturesPieceId);
62631
+ const bestBasicCapture = scored.find(item => item.move.kind === 'basic' && item.move.capturesPieceId);
62323
62632
  if (!bestBasicCapture)
62324
62633
  return undefined;
62325
62634
  return best.score - bestBasicCapture.score <= 650 ? bestBasicCapture.move : undefined;
@@ -62345,7 +62654,7 @@ function pickNoisyBotMove(scored, spread) {
62345
62654
  return pool[0]?.move;
62346
62655
  }
62347
62656
  function getImmediateWinningMoves(state, color) {
62348
- return getChessimalsAllLegalMoves(state, color).filter((move) => move.kind === 'basic' && isPromotionRow(state.boardSize, color, move.to));
62657
+ return getChessimalsAllLegalMoves(state, color).filter(move => move.kind === 'basic' && isPromotionRow(state.boardSize, color, move.to));
62349
62658
  }
62350
62659
  function wouldUnlockPower(state, color, position) {
62351
62660
  if (state.players[color].powerUnlocked)
@@ -62359,7 +62668,7 @@ function isSquareVulnerableAfterMove(state, move) {
62359
62668
  const afterMove = applyChessimalsMove(state, move);
62360
62669
  if (afterMove.status === 'finished')
62361
62670
  return false;
62362
- return getChessimalsAllLegalMoves(afterMove).some((enemyMove) => samePosition(enemyMove.to, move.to) && !!enemyMove.capturesPieceId);
62671
+ return getChessimalsAllLegalMoves(afterMove).some(enemyMove => samePosition(enemyMove.to, move.to) && !!enemyMove.capturesPieceId);
62363
62672
  }
62364
62673
  catch {
62365
62674
  return false;
@@ -62415,7 +62724,7 @@ function refreshChessimalsPowerUnlocks(state) {
62415
62724
  function hasCrossedCenter(state, color) {
62416
62725
  const centerTop = state.boardSize / 2 - 1;
62417
62726
  const centerBottom = state.boardSize / 2;
62418
- return activePieces(state).some((piece) => {
62727
+ return activePieces(state).some(piece => {
62419
62728
  if (piece.color !== color || piece.captured)
62420
62729
  return false;
62421
62730
  return color === 'white' ? piece.position.row <= centerTop : piece.position.row >= centerBottom;
@@ -62425,7 +62734,7 @@ function hasEnemyEnteredHome(state, color) {
62425
62734
  const centerTop = state.boardSize / 2 - 1;
62426
62735
  const centerBottom = state.boardSize / 2;
62427
62736
  const enemy = otherColor(color);
62428
- return activePieces(state).some((piece) => {
62737
+ return activePieces(state).some(piece => {
62429
62738
  if (piece.color !== enemy || piece.captured)
62430
62739
  return false;
62431
62740
  return color === 'white' ? piece.position.row >= centerBottom : piece.position.row <= centerTop;
@@ -64009,6 +64318,7 @@ const MINI_GAMES_I18N = {
64009
64318
  chessimalsBotEasy: 'Suave',
64010
64319
  chessimalsBotNormal: 'Normal',
64011
64320
  chessimalsBotHard: 'Maestro',
64321
+ chessimalsBotMaster: 'Experto',
64012
64322
  chessimalsBotNightmare: 'Pesadilla',
64013
64323
  chessimalsNightmareRivals: 'Rivales pesadilla',
64014
64324
  chessimalsNightmareMode: 'Modo pesadilla',
@@ -64803,6 +65113,7 @@ const MINI_GAMES_I18N = {
64803
65113
  chessimalsBotEasy: 'Gentle',
64804
65114
  chessimalsBotNormal: 'Normal',
64805
65115
  chessimalsBotHard: 'Master',
65116
+ chessimalsBotMaster: 'Expert',
64806
65117
  chessimalsBotNightmare: 'Nightmare',
64807
65118
  chessimalsNightmareRivals: 'Nightmare rivals',
64808
65119
  chessimalsNightmareMode: 'Nightmare mode',
@@ -66373,14 +66684,70 @@ const ANIMALS = [
66373
66684
  { type: 'lion', assetSrc: `${CHESSIMALS_POWER_ASSET_BASE}/lion-power.png`, tone: 392 },
66374
66685
  ];
66375
66686
  const CHESSIMALS_CHALLENGE_LADDER = [
66376
- { id: 'sprout', round: 1, profileId: 'explorer', difficulty: 'easy', boardSize: 6, introKey: 'chessimalsChallengeBotSproutIntro' },
66377
- { id: 'sentinel', round: 2, profileId: 'guardian', difficulty: 'normal', boardSize: 6, introKey: 'chessimalsChallengeBotSentinelIntro' },
66378
- { id: 'hunter', round: 3, profileId: 'hunter', difficulty: 'normal', boardSize: 6, introKey: 'chessimalsChallengeBotHunterIntro' },
66379
- { id: 'jumper', round: 4, profileId: 'jumper', difficulty: 'normal', boardSize: 6, introKey: 'chessimalsChallengeBotJumperIntro' },
66380
- { id: 'predator', round: 5, profileId: 'predator', difficulty: 'hard', boardSize: 8, introKey: 'chessimalsChallengeBotPredatorIntro' },
66381
- { id: 'oracle', round: 6, profileId: 'strategist', difficulty: 'hard', boardSize: 8, introKey: 'chessimalsChallengeBotOracleIntro' },
66382
- { id: 'sprinter', round: 7, profileId: 'sprinter', difficulty: 'hard', boardSize: 8, introKey: 'chessimalsChallengeBotSprinterIntro' },
66383
- { id: 'champion', round: 8, profileId: 'sentinel', difficulty: 'hard', boardSize: 8, introKey: 'chessimalsChallengeBotChampionIntro' },
66687
+ {
66688
+ id: 'sprout',
66689
+ round: 1,
66690
+ profileId: 'explorer',
66691
+ difficulty: 'easy',
66692
+ boardSize: 6,
66693
+ introKey: 'chessimalsChallengeBotSproutIntro',
66694
+ },
66695
+ {
66696
+ id: 'sentinel',
66697
+ round: 2,
66698
+ profileId: 'guardian',
66699
+ difficulty: 'normal',
66700
+ boardSize: 6,
66701
+ introKey: 'chessimalsChallengeBotSentinelIntro',
66702
+ },
66703
+ {
66704
+ id: 'hunter',
66705
+ round: 3,
66706
+ profileId: 'hunter',
66707
+ difficulty: 'normal',
66708
+ boardSize: 6,
66709
+ introKey: 'chessimalsChallengeBotHunterIntro',
66710
+ },
66711
+ {
66712
+ id: 'jumper',
66713
+ round: 4,
66714
+ profileId: 'jumper',
66715
+ difficulty: 'normal',
66716
+ boardSize: 6,
66717
+ introKey: 'chessimalsChallengeBotJumperIntro',
66718
+ },
66719
+ {
66720
+ id: 'predator',
66721
+ round: 5,
66722
+ profileId: 'predator',
66723
+ difficulty: 'hard',
66724
+ boardSize: 8,
66725
+ introKey: 'chessimalsChallengeBotPredatorIntro',
66726
+ },
66727
+ {
66728
+ id: 'oracle',
66729
+ round: 6,
66730
+ profileId: 'strategist',
66731
+ difficulty: 'hard',
66732
+ boardSize: 8,
66733
+ introKey: 'chessimalsChallengeBotOracleIntro',
66734
+ },
66735
+ {
66736
+ id: 'sprinter',
66737
+ round: 7,
66738
+ profileId: 'sprinter',
66739
+ difficulty: 'master',
66740
+ boardSize: 8,
66741
+ introKey: 'chessimalsChallengeBotSprinterIntro',
66742
+ },
66743
+ {
66744
+ id: 'champion',
66745
+ round: 8,
66746
+ profileId: 'magnus',
66747
+ difficulty: 'master',
66748
+ boardSize: 8,
66749
+ introKey: 'chessimalsChallengeBotChampionIntro',
66750
+ },
66384
66751
  ];
66385
66752
  class ChessimalsGameComponent {
66386
66753
  set onlineGameId(value) {
@@ -66410,7 +66777,7 @@ class ChessimalsGameComponent {
66410
66777
  this.turnTimerExpiredKey = '';
66411
66778
  this.boardSizes = [6, 8];
66412
66779
  this.localModes = ['one-device', 'bot'];
66413
- this.botDifficulties = ['easy', 'normal', 'hard', 'nightmare'];
66780
+ this.botDifficulties = ['easy', 'normal', 'hard', 'master', 'nightmare'];
66414
66781
  this.nightmareRivals = ['hunt', 'pride', 'magnus'];
66415
66782
  this.botProfiles = CHESSIMALS_BOT_PROFILES;
66416
66783
  this.challengeLadder = CHESSIMALS_CHALLENGE_LADDER;
@@ -66617,7 +66984,7 @@ class ChessimalsGameComponent {
66617
66984
  color: 'primary',
66618
66985
  startLabel: '0',
66619
66986
  endLabel: '100',
66620
- pinFormatter: (value) => `${value}%`,
66987
+ pinFormatter: value => `${value}%`,
66621
66988
  }));
66622
66989
  this.sfxVolumeProps = computed(() => ({
66623
66990
  control: this.sfxVolumeControl,
@@ -66629,30 +66996,39 @@ class ChessimalsGameComponent {
66629
66996
  color: 'primary',
66630
66997
  startLabel: '0',
66631
66998
  endLabel: '100',
66632
- pinFormatter: (value) => `${value}%`,
66999
+ pinFormatter: value => `${value}%`,
66633
67000
  }));
66634
67001
  this.availableBotProfiles = computed(() => {
66635
67002
  const difficulty = this.selectedBotDifficulty();
66636
67003
  if (difficulty === 'nightmare')
66637
67004
  return [];
66638
- return this.botProfiles.filter((profile) => profile.difficulty === difficulty && profile.id !== 'magnus');
67005
+ if (difficulty === 'master')
67006
+ return this.botProfiles.filter(profile => profile.id === 'magnus');
67007
+ return this.botProfiles.filter(profile => profile.difficulty === difficulty && profile.id !== 'magnus');
66639
67008
  });
66640
- this.selectedBotProfile = computed(() => this.botProfiles.find((profile) => profile.id === this.selectedBotProfileId()));
67009
+ this.selectedBotProfile = computed(() => this.botProfiles.find(profile => profile.id === this.selectedBotProfileId()));
66641
67010
  this.gameBotProfile = computed(() => {
66642
67011
  const profileId = this.gameBotProfileId();
66643
- return profileId ? this.botProfiles.find((profile) => profile.id === profileId) : undefined;
67012
+ return profileId ? this.botProfiles.find(profile => profile.id === profileId) : undefined;
67013
+ });
67014
+ this.challengeHeaderBot = computed(() => {
67015
+ if (!this.isChallengeActive())
67016
+ return undefined;
67017
+ if (this.challengePhase() === 'playing')
67018
+ return this.activeChallengeBot();
67019
+ return this.challengeLastBot() ?? this.activeChallengeBot();
66644
67020
  });
66645
67021
  this.botOpponentProfile = computed(() => {
66646
67022
  const game = this.game();
66647
67023
  if (game.mode !== 'local' || this.selectedLocalMode() !== 'bot')
66648
67024
  return undefined;
66649
- const challengeBot = this.isChallengeActive() ? this.activeChallengeBot() : undefined;
67025
+ const challengeBot = this.challengeHeaderBot();
66650
67026
  if (challengeBot)
66651
67027
  return this.challengeBotProfile(challengeBot);
66652
67028
  return this.gameBotProfile() ?? this.selectedBotProfile();
66653
67029
  });
66654
67030
  this.botOpponentEyebrow = computed(() => {
66655
- const challengeBot = this.isChallengeActive() ? this.activeChallengeBot() : undefined;
67031
+ const challengeBot = this.challengeHeaderBot();
66656
67032
  if (challengeBot)
66657
67033
  return this.challengeBotDifficultyLabel(challengeBot);
66658
67034
  return this.botDifficultyLabel(this.selectedBotDifficulty());
@@ -66663,7 +67039,7 @@ class ChessimalsGameComponent {
66663
67039
  return this.t('chessimalsBotReportVs').replace('{bot}', botName);
66664
67040
  });
66665
67041
  this.botOpponentDescription = computed(() => {
66666
- const challengeBot = this.isChallengeActive() ? this.activeChallengeBot() : undefined;
67042
+ const challengeBot = this.challengeHeaderBot();
66667
67043
  if (challengeBot)
66668
67044
  return this.challengeBotStyleLine(challengeBot);
66669
67045
  const profile = this.botOpponentProfile();
@@ -66673,7 +67049,7 @@ class ChessimalsGameComponent {
66673
67049
  const game = this.game();
66674
67050
  if (game.mode !== 'local' || this.selectedLocalMode() !== 'bot')
66675
67051
  return undefined;
66676
- const challengeBot = this.isChallengeActive() ? this.activeChallengeBot() : undefined;
67052
+ const challengeBot = this.challengeHeaderBot();
66677
67053
  if (challengeBot) {
66678
67054
  const profile = this.challengeBotProfile(challengeBot);
66679
67055
  const botName = profile ? this.botProfileLabel(profile) : this.t('chessimalsBotName');
@@ -66763,25 +67139,29 @@ class ChessimalsGameComponent {
66763
67139
  const expected = this.tutorialExpectedMove();
66764
67140
  if (!expected)
66765
67141
  return moves;
66766
- return moves.filter((move) => move.pieceId === expected.pieceId &&
67142
+ return moves.filter(move => move.pieceId === expected.pieceId &&
66767
67143
  positionKey(move.to) === positionKey(expected.to) &&
66768
67144
  (move.animal ?? undefined) === (expected.animal ?? undefined));
66769
67145
  });
66770
- this.legalMoveKeys = computed(() => new Set(this.legalMoves().map((move) => positionKey(move.to))));
66771
- this.captureMoveKeys = computed(() => new Set(this.legalMoves().filter((move) => !!move.capturesPieceId).map((move) => positionKey(move.to))));
67146
+ this.legalMoveKeys = computed(() => new Set(this.legalMoves().map(move => positionKey(move.to))));
67147
+ this.captureMoveKeys = computed(() => new Set(this.legalMoves()
67148
+ .filter(move => !!move.capturesPieceId)
67149
+ .map(move => positionKey(move.to))));
66772
67150
  this.winningMoveKeys = computed(() => {
66773
67151
  const game = this.game();
66774
67152
  if (game.status !== 'in_progress')
66775
67153
  return new Set();
66776
67154
  const promotionRow = game.currentTurn === 'white' ? 0 : game.boardSize - 1;
66777
- return new Set(this.legalMoves().filter((move) => move.to.row === promotionRow).map((move) => positionKey(move.to)));
67155
+ return new Set(this.legalMoves()
67156
+ .filter(move => move.to.row === promotionRow)
67157
+ .map(move => positionKey(move.to)));
66778
67158
  });
66779
67159
  this.captureReadyPieceIds = computed(() => {
66780
67160
  const game = this.game();
66781
67161
  if (this.activeReviewIndex() !== undefined || game.status !== 'in_progress')
66782
67162
  return new Set();
66783
- const moves = this.basicMovesForColor(game, game.currentTurn).filter((move) => !!move.capturesPieceId);
66784
- return new Set(moves.map((move) => move.pieceId));
67163
+ const moves = this.basicMovesForColor(game, game.currentTurn).filter(move => !!move.capturesPieceId);
67164
+ return new Set(moves.map(move => move.pieceId));
66785
67165
  });
66786
67166
  this.threatenedPieceIds = computed(() => {
66787
67167
  const game = this.game();
@@ -66789,7 +67169,7 @@ class ChessimalsGameComponent {
66789
67169
  return new Set();
66790
67170
  const opponent = game.currentTurn === 'white' ? 'black' : 'white';
66791
67171
  const threatened = this.basicMovesForColor(game, opponent)
66792
- .map((move) => move.capturesPieceId)
67172
+ .map(move => move.capturesPieceId)
66793
67173
  .filter((pieceId) => !!pieceId);
66794
67174
  return new Set(threatened);
66795
67175
  });
@@ -66805,7 +67185,7 @@ class ChessimalsGameComponent {
66805
67185
  if (this.tutorialMode())
66806
67186
  return 'white';
66807
67187
  if (game.mode === 'online')
66808
- return uid ? this.online.participantSide(game, uid) ?? 'white' : 'white';
67188
+ return uid ? (this.online.participantSide(game, uid) ?? 'white') : 'white';
66809
67189
  if (game.mode === 'local' && this.selectedLocalMode() === 'bot')
66810
67190
  return 'white';
66811
67191
  return game.currentTurn;
@@ -66953,15 +67333,15 @@ class ChessimalsGameComponent {
66953
67333
  const move = entry.move;
66954
67334
  if (!move?.capturesPieceId)
66955
67335
  continue;
66956
- const piece = entry.pieces.find((item) => item.id === move.pieceId);
67336
+ const piece = entry.pieces.find(item => item.id === move.pieceId);
66957
67337
  if (piece?.color)
66958
67338
  score[piece.color] += 1;
66959
67339
  }
66960
67340
  return score;
66961
67341
  });
66962
- this.resultCaptures = computed(() => this.replayEntries().filter((entry) => !!entry.move?.capturesPieceId).length);
67342
+ this.resultCaptures = computed(() => this.replayEntries().filter(entry => !!entry.move?.capturesPieceId).length);
66963
67343
  this.resultPowers = computed(() => this.replayEntries()
66964
- .map((entry) => entry.move?.animal)
67344
+ .map(entry => entry.move?.animal)
66965
67345
  .filter((animal) => !!animal));
66966
67346
  this.liveScore = computed(() => this.isChallengeActive() ? this.createGameScore(this.game(), 'W').score : this.createGameScore(this.game()).score);
66967
67347
  this.resultScore = computed(() => this.createGameScore(this.game()));
@@ -66991,7 +67371,7 @@ class ChessimalsGameComponent {
66991
67371
  const powers = this.resultPowers();
66992
67372
  if (!powers.length)
66993
67373
  return this.t('chessimalsResultNoPowers');
66994
- return powers.map((animal) => this.animalLabel(animal)).join(' · ');
67374
+ return powers.map(animal => this.animalLabel(animal)).join(' · ');
66995
67375
  });
66996
67376
  this.liveScoreLabel = computed(() => String(this.liveScore()));
66997
67377
  this.resultBestMoveLabel = computed(() => {
@@ -67012,12 +67392,10 @@ class ChessimalsGameComponent {
67012
67392
  });
67013
67393
  this.botReportBody = computed(() => {
67014
67394
  const profile = this.gameBotProfile();
67015
- const botMoves = this.replayEntries().filter((entry) => entry.move?.pieceId.startsWith('B'));
67016
- const captures = botMoves.filter((entry) => !!entry.move?.capturesPieceId).length;
67017
- const powers = botMoves.filter((entry) => !!entry.move?.animal).length;
67018
- const outcomeKey = this.game().winner === CHESSIMALS_BOT_COLOR
67019
- ? 'chessimalsBotReportOutcomeWon'
67020
- : 'chessimalsBotReportOutcomeLost';
67395
+ const botMoves = this.replayEntries().filter(entry => entry.move?.pieceId.startsWith('B'));
67396
+ const captures = botMoves.filter(entry => !!entry.move?.capturesPieceId).length;
67397
+ const powers = botMoves.filter(entry => !!entry.move?.animal).length;
67398
+ const outcomeKey = this.game().winner === CHESSIMALS_BOT_COLOR ? 'chessimalsBotReportOutcomeWon' : 'chessimalsBotReportOutcomeLost';
67021
67399
  return this.t('chessimalsBotReportBody')
67022
67400
  .replace('{outcome}', this.t(outcomeKey))
67023
67401
  .replace('{captures}', String(captures))
@@ -67028,15 +67406,15 @@ class ChessimalsGameComponent {
67028
67406
  const opponentUid = this.currentOpponentUid();
67029
67407
  if (!opponentUid)
67030
67408
  return [];
67031
- return this.onlineHistory().filter((entry) => entry.opponentUid === opponentUid && entry.status === 'finished');
67409
+ return this.onlineHistory().filter(entry => entry.opponentUid === opponentUid && entry.status === 'finished');
67032
67410
  });
67033
67411
  this.seriesScore = computed(() => {
67034
67412
  const games = this.seriesGames();
67035
67413
  if (!games.length)
67036
67414
  return undefined;
67037
67415
  return {
67038
- mine: games.filter((entry) => entry.outcome === 'won').length,
67039
- rival: games.filter((entry) => entry.outcome === 'lost').length,
67416
+ mine: games.filter(entry => entry.outcome === 'won').length,
67417
+ rival: games.filter(entry => entry.outcome === 'lost').length,
67040
67418
  total: games.length,
67041
67419
  };
67042
67420
  });
@@ -67160,14 +67538,14 @@ class ChessimalsGameComponent {
67160
67538
  this.audio.preloadChessimalsSamples();
67161
67539
  this.audio.stopMusic();
67162
67540
  this.startChessimalsMenuMusicSoon();
67163
- this.routeSubscription.add(this.musicEnabledControl.valueChanges.subscribe((enabled) => {
67541
+ this.routeSubscription.add(this.musicEnabledControl.valueChanges.subscribe(enabled => {
67164
67542
  this.audio.setMusicEnabled(enabled);
67165
67543
  if (enabled)
67166
67544
  this.syncChessimalsMusicAfterSettingsChange();
67167
67545
  }));
67168
- this.routeSubscription.add(this.sfxEnabledControl.valueChanges.subscribe((enabled) => this.audio.setSfxEnabled(enabled)));
67169
- this.routeSubscription.add(this.musicVolumeControl.valueChanges.subscribe((volume) => this.setMusicVolume(volume)));
67170
- this.routeSubscription.add(this.sfxVolumeControl.valueChanges.subscribe((volume) => this.setSfxVolume(volume)));
67546
+ this.routeSubscription.add(this.sfxEnabledControl.valueChanges.subscribe(enabled => this.audio.setSfxEnabled(enabled)));
67547
+ this.routeSubscription.add(this.musicVolumeControl.valueChanges.subscribe(volume => this.setMusicVolume(volume)));
67548
+ this.routeSubscription.add(this.sfxVolumeControl.valueChanges.subscribe(volume => this.setSfxVolume(volume)));
67171
67549
  effect(() => {
67172
67550
  const user = this.loggedInUser();
67173
67551
  if (user) {
@@ -67210,7 +67588,7 @@ class ChessimalsGameComponent {
67210
67588
  if (this.lastModeStatsHandledKey === key)
67211
67589
  return;
67212
67590
  this.lastModeStatsHandledKey = key;
67213
- void this.challengeProgress.recordModeResult(result.mode, result.won, result.roundStats).catch((error) => {
67591
+ void this.challengeProgress.recordModeResult(result.mode, result.won, result.roundStats).catch(error => {
67214
67592
  console.warn('[Chessimals] mode stats save failed', error);
67215
67593
  });
67216
67594
  }, { allowSignalWrites: true });
@@ -67248,7 +67626,7 @@ class ChessimalsGameComponent {
67248
67626
  this.challengeActiveRunSubscription?.unsubscribe();
67249
67627
  }
67250
67628
  ngOnInit() {
67251
- this.routeSubscription.add(this.router.events.subscribe((event) => {
67629
+ this.routeSubscription.add(this.router.events.subscribe(event => {
67252
67630
  if (event instanceof NavigationStart) {
67253
67631
  this.resetFinishedLocalGameForNextVisit(true);
67254
67632
  }
@@ -67269,7 +67647,7 @@ class ChessimalsGameComponent {
67269
67647
  return `${normalized.slice(0, 4)}…${normalized.slice(-4)}`;
67270
67648
  }
67271
67649
  rangeValueToNumber(value) {
67272
- const raw = typeof value === 'number' ? value : value.upper ?? value.lower ?? 0;
67650
+ const raw = typeof value === 'number' ? value : (value.upper ?? value.lower ?? 0);
67273
67651
  return Math.min(100, Math.max(0, Math.round(raw)));
67274
67652
  }
67275
67653
  startChallenge() {
@@ -67335,7 +67713,7 @@ class ChessimalsGameComponent {
67335
67713
  losses: 0,
67336
67714
  bestStreakInRun: 0,
67337
67715
  currentStreak: 0,
67338
- botLadder: this.challengeLadder.map((bot) => bot.id),
67716
+ botLadder: this.challengeLadder.map(bot => bot.id),
67339
67717
  roundResults: [],
67340
67718
  startedAt: now,
67341
67719
  lastEventAt: now,
@@ -67344,7 +67722,7 @@ class ChessimalsGameComponent {
67344
67722
  this.challengeRun.set(run);
67345
67723
  this.activeStoredChallengeRun.set(run);
67346
67724
  this.startChallengeRound(run);
67347
- void this.challengeProgress.recordChallengeStarted(this.challengeRun() ?? run).catch((error) => {
67725
+ void this.challengeProgress.recordChallengeStarted(this.challengeRun() ?? run).catch(error => {
67348
67726
  console.warn('[Chessimals] challenge run save failed', error);
67349
67727
  });
67350
67728
  }
@@ -67599,16 +67977,18 @@ class ChessimalsGameComponent {
67599
67977
  this.challengeLastWon.set(won);
67600
67978
  this.challengeLastBot.set(bot);
67601
67979
  this.challengeLastRoundStats.set(roundStats);
67602
- this.challengeNewRecord.set(roundIndex > this.challengeStats().bestRoundReached
67603
- || Math.max(run.bestStreakInRun, nextStreak) > this.challengeStats().bestWinStreak);
67980
+ this.challengeNewRecord.set(roundIndex > this.challengeStats().bestRoundReached ||
67981
+ Math.max(run.bestStreakInRun, nextStreak) > this.challengeStats().bestWinStreak);
67604
67982
  this.challengePhase.set(completed ? 'completed' : failed ? 'failed' : 'between');
67605
- void this.challengeProgress.applyRoundResult({
67983
+ void this.challengeProgress
67984
+ .applyRoundResult({
67606
67985
  run: nextRun,
67607
67986
  roundReached: roundIndex,
67608
67987
  won,
67609
67988
  completed,
67610
67989
  roundStats,
67611
- }).catch((error) => {
67990
+ })
67991
+ .catch(error => {
67612
67992
  console.warn('[Chessimals] challenge stats save failed', error);
67613
67993
  });
67614
67994
  }
@@ -67629,7 +68009,7 @@ class ChessimalsGameComponent {
67629
68009
  finishedAt: now,
67630
68010
  };
67631
68011
  this.activeStoredChallengeRun.set(undefined);
67632
- void this.challengeProgress.saveRun(nextRun).catch((error) => {
68012
+ void this.challengeProgress.saveRun(nextRun).catch(error => {
67633
68013
  console.warn('[Chessimals] challenge abandon save failed', error);
67634
68014
  });
67635
68015
  }
@@ -68066,7 +68446,7 @@ class ChessimalsGameComponent {
68066
68446
  moveHistory: [
68067
68447
  {
68068
68448
  moveNumber: 0,
68069
- pieces: pieces.map((piece) => ({ ...piece, position: { ...piece.position } })),
68449
+ pieces: pieces.map(piece => ({ ...piece, position: { ...piece.position } })),
68070
68450
  currentTurn: 'white',
68071
68451
  status: 'in_progress',
68072
68452
  },
@@ -68076,19 +68456,23 @@ class ChessimalsGameComponent {
68076
68456
  basicMovesForColor(game, color) {
68077
68457
  const turnState = color === game.currentTurn ? game : { ...game, currentTurn: color };
68078
68458
  return turnState.pieces
68079
- .filter((piece) => piece.color === color && !piece.captured)
68080
- .flatMap((piece) => getChessimalsLegalMoves(turnState, piece.id));
68459
+ .filter(piece => piece.color === color && !piece.captured)
68460
+ .flatMap(piece => getChessimalsLegalMoves(turnState, piece.id));
68081
68461
  }
68082
68462
  selectCell(position) {
68083
68463
  const game = this.game();
68084
- if (this.projectionMode || game.status !== 'in_progress' || !this.canPlayCurrentTurn() || this.movingPiece() || this.moveSyncing())
68464
+ if (this.projectionMode ||
68465
+ game.status !== 'in_progress' ||
68466
+ !this.canPlayCurrentTurn() ||
68467
+ this.movingPiece() ||
68468
+ this.moveSyncing())
68085
68469
  return;
68086
68470
  const piece = getChessimalsPieceAt(game, position);
68087
68471
  if (piece?.color === game.currentTurn) {
68088
68472
  this.selectedPieceId.set(piece.id);
68089
68473
  return;
68090
68474
  }
68091
- const move = this.legalMoves().find((item) => positionKey(item.to) === positionKey(position));
68475
+ const move = this.legalMoves().find(item => positionKey(item.to) === positionKey(position));
68092
68476
  if (!move)
68093
68477
  return;
68094
68478
  this.commitChessimalsMove(game, move);
@@ -68108,7 +68492,7 @@ class ChessimalsGameComponent {
68108
68492
  .then(() => {
68109
68493
  void this.haptics.impact(move.capturesPieceId ? 'medium' : 'light');
68110
68494
  })
68111
- .catch((error) => {
68495
+ .catch(error => {
68112
68496
  console.warn('[Chessimals] online move failed', { gameId: game.id, move, error });
68113
68497
  this.game.set(game);
68114
68498
  this.onlineError.set(this.t('chessimalsOnlineError'));
@@ -68218,14 +68602,14 @@ class ChessimalsGameComponent {
68218
68602
  }
68219
68603
  chooseAutomaticTurnMove(game) {
68220
68604
  const moves = game.pieces
68221
- .filter((piece) => piece.color === game.currentTurn && !piece.captured)
68222
- .flatMap((piece) => getChessimalsLegalMoves(game, piece.id));
68223
- const basicMoves = moves.filter((move) => move.kind === 'basic');
68224
- return basicMoves.find((move) => this.isPromotionMove(game, move))
68225
- ?? basicMoves.find((move) => !!move.capturesPieceId)
68226
- ?? basicMoves[0]
68227
- ?? moves.find((move) => !!move.capturesPieceId)
68228
- ?? moves[0];
68605
+ .filter(piece => piece.color === game.currentTurn && !piece.captured)
68606
+ .flatMap(piece => getChessimalsLegalMoves(game, piece.id));
68607
+ const basicMoves = moves.filter(move => move.kind === 'basic');
68608
+ return (basicMoves.find(move => this.isPromotionMove(game, move)) ??
68609
+ basicMoves.find(move => !!move.capturesPieceId) ??
68610
+ basicMoves[0] ??
68611
+ moves.find(move => !!move.capturesPieceId) ??
68612
+ moves[0]);
68229
68613
  }
68230
68614
  isPromotionMove(game, move) {
68231
68615
  return move.kind === 'basic' && move.to.row === (game.currentTurn === 'white' ? 0 : game.boardSize - 1);
@@ -68234,7 +68618,7 @@ class ChessimalsGameComponent {
68234
68618
  if (this.moveAnimationTimer)
68235
68619
  clearTimeout(this.moveAnimationTimer);
68236
68620
  this.queueMoveEffect(move);
68237
- const movingPiece = game.pieces.find((piece) => piece.id === move.pieceId);
68621
+ const movingPiece = game.pieces.find(piece => piece.id === move.pieceId);
68238
68622
  if (!movingPiece) {
68239
68623
  this.applyAnimatedMove(game, updated);
68240
68624
  return;
@@ -68292,7 +68676,7 @@ class ChessimalsGameComponent {
68292
68676
  updatedAt: new Date().toISOString(),
68293
68677
  };
68294
68678
  this.challengeRun.set(nextRun);
68295
- void this.challengeProgress.saveRun(nextRun).catch((error) => {
68679
+ void this.challengeProgress.saveRun(nextRun).catch(error => {
68296
68680
  console.warn('[Chessimals] challenge snapshot save failed', error);
68297
68681
  });
68298
68682
  }
@@ -68566,7 +68950,7 @@ class ChessimalsGameComponent {
68566
68950
  const next = current === animal.type ? undefined : animal.type;
68567
68951
  this.selectedAnimal.set(next);
68568
68952
  if (!this.selectedPieceId()) {
68569
- const firstPiece = this.game().pieces.find((piece) => !piece.captured && piece.color === this.game().currentTurn);
68953
+ const firstPiece = this.game().pieces.find(piece => !piece.captured && piece.color === this.game().currentTurn);
68570
68954
  this.selectedPieceId.set(firstPiece?.id);
68571
68955
  }
68572
68956
  if (next)
@@ -68710,7 +69094,7 @@ class ChessimalsGameComponent {
68710
69094
  .split(/\s+/)
68711
69095
  .filter(Boolean)
68712
69096
  .slice(0, 2)
68713
- .map((part) => part.charAt(0).toUpperCase())
69097
+ .map(part => part.charAt(0).toUpperCase())
68714
69098
  .join('');
68715
69099
  return initials || this.winnerSideLabel().charAt(0).toUpperCase();
68716
69100
  }
@@ -68836,10 +69220,7 @@ class ChessimalsGameComponent {
68836
69220
  canReviewPendingGuest() {
68837
69221
  const game = this.game();
68838
69222
  const uid = this.onlineUid();
68839
- return !!uid
68840
- && game.mode === 'online'
68841
- && this.online.isHostWaiting(game, uid)
68842
- && !!game.online.pendingGuest;
69223
+ return !!uid && game.mode === 'online' && this.online.isHostWaiting(game, uid) && !!game.online.pendingGuest;
68843
69224
  }
68844
69225
  pendingGuestName() {
68845
69226
  return this.game().online?.pendingGuest?.name ?? this.t('defaultPlayerName');
@@ -68857,7 +69238,7 @@ class ChessimalsGameComponent {
68857
69238
  .split(/\s+/)
68858
69239
  .filter(Boolean)
68859
69240
  .slice(0, 2)
68860
- .map((part) => part.charAt(0).toUpperCase())
69241
+ .map(part => part.charAt(0).toUpperCase())
68861
69242
  .join('');
68862
69243
  return initials || '?';
68863
69244
  }
@@ -68889,7 +69270,7 @@ class ChessimalsGameComponent {
68889
69270
  .split(/\s+/)
68890
69271
  .filter(Boolean)
68891
69272
  .slice(0, 2)
68892
- .map((part) => part.charAt(0).toUpperCase())
69273
+ .map(part => part.charAt(0).toUpperCase())
68893
69274
  .join('');
68894
69275
  return initials || '?';
68895
69276
  }
@@ -68972,7 +69353,7 @@ class ChessimalsGameComponent {
68972
69353
  historyOutcomeLabel(entry) {
68973
69354
  const outcomeKey = `chessimalsHistory${entry.outcome
68974
69355
  .split('_')
68975
- .map((part) => this.capitalize(part))
69356
+ .map(part => this.capitalize(part))
68976
69357
  .join('')}`;
68977
69358
  const opponent = entry.opponentName
68978
69359
  ? ` · ${this.t('chessimalsHistoryAgainst').replace('{player}', entry.opponentName)}`
@@ -69023,7 +69404,7 @@ class ChessimalsGameComponent {
69023
69404
  this.historyUid = uid;
69024
69405
  this.historySubscription?.unsubscribe();
69025
69406
  this.historySubscription = this.online.watchHistory(24).subscribe({
69026
- next: (history) => this.onlineHistory.set(history),
69407
+ next: history => this.onlineHistory.set(history),
69027
69408
  error: () => this.onlineHistory.set([]),
69028
69409
  });
69029
69410
  }
@@ -69031,15 +69412,15 @@ class ChessimalsGameComponent {
69031
69412
  if (this.challengeStatsSubscription)
69032
69413
  return;
69033
69414
  this.challengeStatsSubscription = this.challengeProgress.watchStats().subscribe({
69034
- next: (stats) => this.challengeStats.set(stats ?? this.challengeProgress.emptyStats()),
69415
+ next: stats => this.challengeStats.set(stats ?? this.challengeProgress.emptyStats()),
69035
69416
  error: () => this.challengeStats.set(this.challengeProgress.emptyStats()),
69036
69417
  });
69037
69418
  this.challengeRunsSubscription = this.challengeProgress.watchRecentRuns(4).subscribe({
69038
- next: (runs) => this.challengeHistory.set(runs),
69419
+ next: runs => this.challengeHistory.set(runs),
69039
69420
  error: () => this.challengeHistory.set([]),
69040
69421
  });
69041
69422
  this.challengeActiveRunSubscription = this.challengeProgress.watchActiveRun().subscribe({
69042
- next: (run) => this.activeStoredChallengeRun.set(this.isResumableChallengeRun(run) ? run : undefined),
69423
+ next: run => this.activeStoredChallengeRun.set(this.isResumableChallengeRun(run) ? run : undefined),
69043
69424
  error: () => this.activeStoredChallengeRun.set(undefined),
69044
69425
  });
69045
69426
  }
@@ -69060,7 +69441,7 @@ class ChessimalsGameComponent {
69060
69441
  return;
69061
69442
  }
69062
69443
  this.selectedNightmareMode.set('none');
69063
- const profile = this.botProfiles.find((item) => item.difficulty === difficulty);
69444
+ const profile = this.botProfiles.find(item => item.difficulty === difficulty);
69064
69445
  if (profile)
69065
69446
  this.selectedBotProfileId.set(profile.id);
69066
69447
  }
@@ -69121,6 +69502,8 @@ class ChessimalsGameComponent {
69121
69502
  return this.t('chessimalsBotEasy');
69122
69503
  if (difficulty === 'hard')
69123
69504
  return this.t('chessimalsBotHard');
69505
+ if (difficulty === 'master')
69506
+ return this.t('chessimalsBotMaster');
69124
69507
  if (difficulty === 'nightmare')
69125
69508
  return this.t('chessimalsBotNightmare');
69126
69509
  return this.t('chessimalsBotNormal');
@@ -69135,13 +69518,13 @@ class ChessimalsGameComponent {
69135
69518
  return this.t(`chessimalsBot${this.capitalize(profile.id)}Tendency`);
69136
69519
  }
69137
69520
  botProfileAvatar(profileId) {
69138
- return this.botProfiles.find((profile) => profile.id === profileId)?.avatar ?? '♟';
69521
+ return this.botProfiles.find(profile => profile.id === profileId)?.avatar ?? '♟';
69139
69522
  }
69140
69523
  botProfileAvatarSrc(profileId) {
69141
- return this.botProfiles.find((profile) => profile.id === profileId)?.avatarSrc ?? '';
69524
+ return this.botProfiles.find(profile => profile.id === profileId)?.avatarSrc ?? '';
69142
69525
  }
69143
69526
  challengeBotProfile(bot) {
69144
- return this.botProfiles.find((profile) => profile.id === bot.profileId);
69527
+ return this.botProfiles.find(profile => profile.id === bot.profileId);
69145
69528
  }
69146
69529
  challengeOpeningBot() {
69147
69530
  return this.challengeLadder[0];
@@ -69217,7 +69600,7 @@ class ChessimalsGameComponent {
69217
69600
  return this.challengePhase() !== 'idle' && !!this.challengeRun();
69218
69601
  }
69219
69602
  shouldShowChallengeInGamePanel() {
69220
- return !this.projectionMode && this.screen() === 'game' && this.challengePhase() === 'playing' && !!this.challengeRun();
69603
+ return (!this.projectionMode && this.screen() === 'game' && this.challengePhase() === 'playing' && !!this.challengeRun());
69221
69604
  }
69222
69605
  showChallengeIntro() {
69223
69606
  if (this.projectionMode || this.challengePhase() !== 'playing' || !this.activeChallengeBot())
@@ -69320,7 +69703,7 @@ class ChessimalsGameComponent {
69320
69703
  challengeRoundStageLabel() {
69321
69704
  const bot = this.challengePhase() === 'playing'
69322
69705
  ? this.activeChallengeBot()
69323
- : this.challengeLastBot() ?? this.activeChallengeBot();
69706
+ : (this.challengeLastBot() ?? this.activeChallengeBot());
69324
69707
  const run = this.challengeRun();
69325
69708
  const round = bot?.round ?? (run ? this.challengeRunRoundIndex(run) : 1);
69326
69709
  return this.t('chessimalsChallengeRoundStage')
@@ -69425,7 +69808,7 @@ class ChessimalsGameComponent {
69425
69808
  pathHighlights() {
69426
69809
  const stats = this.challengeStats();
69427
69810
  const favoritePower = this.favoritePowerLabel();
69428
- const nextAchievement = this.challengeAchievements().find((achievement) => !achievement.unlocked);
69811
+ const nextAchievement = this.challengeAchievements().find(achievement => !achievement.unlocked);
69429
69812
  return [
69430
69813
  {
69431
69814
  title: this.t('chessimalsPathWinsTitle'),
@@ -69548,8 +69931,8 @@ class ChessimalsGameComponent {
69548
69931
  challengeFeaturedAchievements() {
69549
69932
  const achievements = this.challengeAchievements();
69550
69933
  return [
69551
- ...achievements.filter((achievement) => achievement.unlocked),
69552
- ...achievements.filter((achievement) => !achievement.unlocked),
69934
+ ...achievements.filter(achievement => achievement.unlocked),
69935
+ ...achievements.filter(achievement => !achievement.unlocked),
69553
69936
  ].slice(0, 4);
69554
69937
  }
69555
69938
  challengeTensionMoment() {
@@ -69560,7 +69943,7 @@ class ChessimalsGameComponent {
69560
69943
  if (!run)
69561
69944
  return undefined;
69562
69945
  const nextBot = this.activeChallengeBot();
69563
- const lastBot = phase === 'playing' ? nextBot : this.challengeLastBot() ?? nextBot;
69946
+ const lastBot = phase === 'playing' ? nextBot : (this.challengeLastBot() ?? nextBot);
69564
69947
  const botName = lastBot ? this.challengeBotName(lastBot) : this.t('chessimalsBotName');
69565
69948
  if (run.livesRemaining <= 1) {
69566
69949
  return {
@@ -69649,11 +70032,11 @@ class ChessimalsGameComponent {
69649
70032
  scoreChessimalsMove(move, promotion, currentCombo) {
69650
70033
  const capture = !!move.capturesPieceId;
69651
70034
  const combo = capture ? currentCombo + 1 : 0;
69652
- const score = 1
69653
- + (capture ? (move.animal ? 5 : 3) : 0)
69654
- + (move.animal && !capture ? 1 : 0)
69655
- + (promotion ? 8 : 0)
69656
- + (combo > 1 ? combo - 1 : 0);
70035
+ const score = 1 +
70036
+ (capture ? (move.animal ? 5 : 3) : 0) +
70037
+ (move.animal && !capture ? 1 : 0) +
70038
+ (promotion ? 8 : 0) +
70039
+ (combo > 1 ? combo - 1 : 0);
69657
70040
  const labelKey = promotion
69658
70041
  ? 'chessimalsScorePromotion'
69659
70042
  : capture && move.animal
@@ -69740,7 +70123,7 @@ class ChessimalsGameComponent {
69740
70123
  return glyphs[type];
69741
70124
  }
69742
70125
  animalAssetSrc(type) {
69743
- return ANIMALS.find((animal) => animal.type === type)?.assetSrc ?? '';
70126
+ return ANIMALS.find(animal => animal.type === type)?.assetSrc ?? '';
69744
70127
  }
69745
70128
  powerCalloutTone(type) {
69746
70129
  const tones = {
@@ -69802,7 +70185,7 @@ class ChessimalsGameComponent {
69802
70185
  watchOnlineGame(gameId) {
69803
70186
  this.onlineSubscription?.unsubscribe();
69804
70187
  this.onlineSubscription = this.online.watchGame(gameId).subscribe({
69805
- next: (state) => {
70188
+ next: state => {
69806
70189
  this.ngZone.run(() => {
69807
70190
  if (!state) {
69808
70191
  this.onlineConnectionState.set('error');
@@ -69916,7 +70299,11 @@ class ChessimalsGameComponent {
69916
70299
 
69917
70300
  <section class="chessimals-panel">
69918
70301
  <section class="chessimals-home-actions" [attr.aria-label]="t('chessimalsHomeChoose')">
69919
- <button class="chessimals-home-action chessimals-home-action--play" type="button" (click)="openPlayOptionsModal()">
70302
+ <button
70303
+ class="chessimals-home-action chessimals-home-action--play"
70304
+ type="button"
70305
+ (click)="openPlayOptionsModal()"
70306
+ >
69920
70307
  <img
69921
70308
  class="chessimals-mode-icon"
69922
70309
  src="assets/games/chessimals/mode-icons/solo-borderless.png"
@@ -69970,60 +70357,60 @@ class ChessimalsGameComponent {
69970
70357
  </summary>
69971
70358
 
69972
70359
  <article class="chessimals-online">
69973
- <div>
69974
- <h2>{{ t('chessimalsOnlineTitle') }}</h2>
69975
- <p>{{ t('chessimalsOnlineBody') }}</p>
69976
- </div>
69977
- @if (onlineError()) {
69978
- <p class="chessimals-online__error">{{ onlineError() }}</p>
69979
- }
69980
- @if (onlineLoading()) {
69981
- <div class="chessimals-online__loading" role="status" aria-live="polite">
69982
- <span aria-hidden="true"></span>
69983
- <strong>{{ t('chessimalsOnlineLoading') }}</strong>
70360
+ <div>
70361
+ <h2>{{ t('chessimalsOnlineTitle') }}</h2>
70362
+ <p>{{ t('chessimalsOnlineBody') }}</p>
70363
+ </div>
70364
+ @if (onlineError()) {
70365
+ <p class="chessimals-online__error">{{ onlineError() }}</p>
70366
+ }
70367
+ @if (onlineLoading()) {
70368
+ <div class="chessimals-online__loading" role="status" aria-live="polite">
70369
+ <span aria-hidden="true"></span>
70370
+ <strong>{{ t('chessimalsOnlineLoading') }}</strong>
70371
+ </div>
70372
+ }
70373
+ <div class="chessimals-online__create">
70374
+ <button
70375
+ class="chessimals-primary"
70376
+ type="button"
70377
+ [class.is-working]="onlineAction() === 'create'"
70378
+ [attr.aria-busy]="onlineAction() === 'create'"
70379
+ [disabled]="onlineLoading()"
70380
+ (click)="createOnlineGame()"
70381
+ >
70382
+ @if (onlineAction() === 'create') {
70383
+ <span class="chessimals-button-spinner" aria-hidden="true"></span>
70384
+ }
70385
+ {{ t('chessimalsCreateOnline') }}
70386
+ </button>
70387
+ <small>{{ t('chessimalsCreateOnlineHint') }}</small>
70388
+ </div>
70389
+ <div class="chessimals-online__join">
70390
+ <strong>{{ t('chessimalsJoinOnlineTitle') }}</strong>
70391
+ <label class="chessimals-online-code">
70392
+ <span>{{ t('chessimalsJoinCode') }}</span>
70393
+ <input
70394
+ type="text"
70395
+ [value]="onlineJoinCode()"
70396
+ [placeholder]="t('chessimalsJoinCodePlaceholder')"
70397
+ (input)="onlineJoinCode.set(normalizeGameId($any($event.target).value))"
70398
+ />
70399
+ </label>
70400
+ <button
70401
+ class="chessimals-primary"
70402
+ type="button"
70403
+ [class.is-working]="onlineAction() === 'join'"
70404
+ [attr.aria-busy]="onlineAction() === 'join'"
70405
+ [disabled]="onlineLoading() || !onlineJoinCode()"
70406
+ (click)="joinOnlineGameByCode()"
70407
+ >
70408
+ @if (onlineAction() === 'join') {
70409
+ <span class="chessimals-button-spinner" aria-hidden="true"></span>
70410
+ }
70411
+ {{ t('chessimalsJoinOnline') }}
70412
+ </button>
69984
70413
  </div>
69985
- }
69986
- <div class="chessimals-online__create">
69987
- <button
69988
- class="chessimals-primary"
69989
- type="button"
69990
- [class.is-working]="onlineAction() === 'create'"
69991
- [attr.aria-busy]="onlineAction() === 'create'"
69992
- [disabled]="onlineLoading()"
69993
- (click)="createOnlineGame()"
69994
- >
69995
- @if (onlineAction() === 'create') {
69996
- <span class="chessimals-button-spinner" aria-hidden="true"></span>
69997
- }
69998
- {{ t('chessimalsCreateOnline') }}
69999
- </button>
70000
- <small>{{ t('chessimalsCreateOnlineHint') }}</small>
70001
- </div>
70002
- <div class="chessimals-online__join">
70003
- <strong>{{ t('chessimalsJoinOnlineTitle') }}</strong>
70004
- <label class="chessimals-online-code">
70005
- <span>{{ t('chessimalsJoinCode') }}</span>
70006
- <input
70007
- type="text"
70008
- [value]="onlineJoinCode()"
70009
- [placeholder]="t('chessimalsJoinCodePlaceholder')"
70010
- (input)="onlineJoinCode.set(normalizeGameId($any($event.target).value))"
70011
- />
70012
- </label>
70013
- <button
70014
- class="chessimals-primary"
70015
- type="button"
70016
- [class.is-working]="onlineAction() === 'join'"
70017
- [attr.aria-busy]="onlineAction() === 'join'"
70018
- [disabled]="onlineLoading() || !onlineJoinCode()"
70019
- (click)="joinOnlineGameByCode()"
70020
- >
70021
- @if (onlineAction() === 'join') {
70022
- <span class="chessimals-button-spinner" aria-hidden="true"></span>
70023
- }
70024
- {{ t('chessimalsJoinOnline') }}
70025
- </button>
70026
- </div>
70027
70414
  </article>
70028
70415
  </details>
70029
70416
 
@@ -70106,7 +70493,12 @@ class ChessimalsGameComponent {
70106
70493
  <strong>{{ challengeBotName(challengeMenuBot()) }}</strong>
70107
70494
  <p>{{ t(challengeMenuBot().introKey) }}</p>
70108
70495
  <em>
70109
- {{ t('chessimalsChallengeBoardLabel').replace('{size}', challengeMenuBot().boardSize + 'x' + challengeMenuBot().boardSize) }}
70496
+ {{
70497
+ t('chessimalsChallengeBoardLabel').replace(
70498
+ '{size}',
70499
+ challengeMenuBot().boardSize + 'x' + challengeMenuBot().boardSize
70500
+ )
70501
+ }}
70110
70502
  , {{ challengeBotDifficultyLabel(challengeMenuBot()) }}
70111
70503
  </em>
70112
70504
  </div>
@@ -70368,7 +70760,10 @@ class ChessimalsGameComponent {
70368
70760
  @if (pendingGuestAvatarUrl()) {
70369
70761
  <val-user-avatar [props]="pendingGuestAvatarProps()" />
70370
70762
  } @else {
70371
- <span class="chessimals-player-strip__avatar chessimals-player-strip__avatar--initials" aria-hidden="true">
70763
+ <span
70764
+ class="chessimals-player-strip__avatar chessimals-player-strip__avatar--initials"
70765
+ aria-hidden="true"
70766
+ >
70372
70767
  {{ pendingGuestInitials() }}
70373
70768
  </span>
70374
70769
  }
@@ -70428,26 +70823,26 @@ class ChessimalsGameComponent {
70428
70823
  @if (isChallengeActive() || turnSecondsRemaining() !== undefined) {
70429
70824
  <div class="chessimals-status chessimals-status--simple">
70430
70825
  @if (isChallengeActive()) {
70431
- <div>
70432
- <small>{{ t('chessimalsChallengeRound') }}</small>
70433
- <strong>{{ challengeRoundLabel() }}</strong>
70434
- </div>
70435
- <div>
70436
- <small>{{ t('chessimalsChallengeLives') }}</small>
70437
- <strong>{{ challengeLivesLabel() }}</strong>
70438
- </div>
70826
+ <div>
70827
+ <small>{{ t('chessimalsChallengeRound') }}</small>
70828
+ <strong>{{ challengeRoundLabel() }}</strong>
70829
+ </div>
70830
+ <div>
70831
+ <small>{{ t('chessimalsChallengeLives') }}</small>
70832
+ <strong>{{ challengeLivesLabel() }}</strong>
70833
+ </div>
70439
70834
  }
70440
70835
  @if (turnSecondsRemaining() !== undefined) {
70441
- <div
70442
- class="chessimals-status__timer"
70443
- [class.is-low]="isTurnTimerLow()"
70444
- [style.--timer-progress]="turnTimerProgress()"
70445
- role="timer"
70446
- aria-live="polite"
70447
- >
70448
- <small>{{ t('chessimalsTurnTimer') }}</small>
70449
- <strong>{{ turnTimerLabel() }}</strong>
70450
- </div>
70836
+ <div
70837
+ class="chessimals-status__timer"
70838
+ [class.is-low]="isTurnTimerLow()"
70839
+ [style.--timer-progress]="turnTimerProgress()"
70840
+ role="timer"
70841
+ aria-live="polite"
70842
+ >
70843
+ <small>{{ t('chessimalsTurnTimer') }}</small>
70844
+ <strong>{{ turnTimerLabel() }}</strong>
70845
+ </div>
70451
70846
  }
70452
70847
  </div>
70453
70848
  }
@@ -70545,7 +70940,14 @@ class ChessimalsGameComponent {
70545
70940
  [class.effect-bull]="isMoveEffectCell(row, col, 'bull')"
70546
70941
  [class.effect-kangaroo]="isMoveEffectCell(row, col, 'kangaroo')"
70547
70942
  [class.effect-lion]="isMoveEffectCell(row, col, 'lion')"
70548
- [disabled]="projectionMode || game().status !== 'in_progress' || !canPlayCurrentTurn() || !!movingPiece() || botThinking() || moveSyncing()"
70943
+ [disabled]="
70944
+ projectionMode ||
70945
+ game().status !== 'in_progress' ||
70946
+ !canPlayCurrentTurn() ||
70947
+ !!movingPiece() ||
70948
+ botThinking() ||
70949
+ moveSyncing()
70950
+ "
70549
70951
  (click)="selectCell({ row, col })"
70550
70952
  >
70551
70953
  <span class="chessimals-cell-texture" aria-hidden="true"></span>
@@ -70698,7 +71100,11 @@ class ChessimalsGameComponent {
70698
71100
  type="button"
70699
71101
  [class.is-selected]="selectedAnimal() === animal.type"
70700
71102
  [class.is-used]="powerPlayer().cards[animal.type].used"
70701
- [disabled]="!canUsePowerCards() || powerPlayer().cards[animal.type].used || isPowerCardBlockedByTutorial(animal.type)"
71103
+ [disabled]="
71104
+ !canUsePowerCards() ||
71105
+ powerPlayer().cards[animal.type].used ||
71106
+ isPowerCardBlockedByTutorial(animal.type)
71107
+ "
70702
71108
  (click)="toggleAnimal(animal)"
70703
71109
  >
70704
71110
  <span class="chessimals-animal-face" aria-hidden="true">
@@ -70793,11 +71199,19 @@ class ChessimalsGameComponent {
70793
71199
  </div>
70794
71200
  <div class="chessimals-challenge-summary__actions">
70795
71201
  @if (challengePhase() === 'between') {
70796
- <button class="chessimals-primary chessimals-challenge-summary__play" type="button" (click)="continueChallenge()">
71202
+ <button
71203
+ class="chessimals-primary chessimals-challenge-summary__play"
71204
+ type="button"
71205
+ (click)="continueChallenge()"
71206
+ >
70797
71207
  {{ challengeContinueLabel() }}
70798
71208
  </button>
70799
71209
  } @else {
70800
- <button class="chessimals-primary chessimals-challenge-summary__play" type="button" (click)="startChallenge()">
71210
+ <button
71211
+ class="chessimals-primary chessimals-challenge-summary__play"
71212
+ type="button"
71213
+ (click)="startChallenge()"
71214
+ >
70801
71215
  {{ t('chessimalsChallengePlayAgain') }}
70802
71216
  </button>
70803
71217
  }
@@ -70872,7 +71286,10 @@ class ChessimalsGameComponent {
70872
71286
  @if (rematchOpponentAvatarUrl()) {
70873
71287
  <val-user-avatar [props]="rematchOpponentAvatarProps()" />
70874
71288
  } @else {
70875
- <span class="chessimals-player-strip__avatar chessimals-player-strip__avatar--initials" aria-hidden="true">
71289
+ <span
71290
+ class="chessimals-player-strip__avatar chessimals-player-strip__avatar--initials"
71291
+ aria-hidden="true"
71292
+ >
70876
71293
  {{ rematchOpponentInitials() }}
70877
71294
  </span>
70878
71295
  }
@@ -70995,7 +71412,9 @@ class ChessimalsGameComponent {
70995
71412
 
70996
71413
  <article class="chessimals-play-options__group">
70997
71414
  <h3 id="chessimals-play-bot">
70998
- {{ selectedBotDifficulty() === 'nightmare' ? t('chessimalsNightmareRivals') : t('chessimalsBotStyle') }}
71415
+ {{
71416
+ selectedBotDifficulty() === 'nightmare' ? t('chessimalsNightmareRivals') : t('chessimalsBotStyle')
71417
+ }}
70999
71418
  </h3>
71000
71419
  <div class="chessimals-bots" role="radiogroup" aria-labelledby="chessimals-play-bot">
71001
71420
  @if (selectedBotDifficulty() === 'nightmare') {
@@ -71275,7 +71694,16 @@ class ChessimalsGameComponent {
71275
71694
  }
71276
71695
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChessimalsGameComponent, decorators: [{
71277
71696
  type: Component,
71278
- args: [{ selector: 'val-chessimals-game', standalone: true, imports: [IonModal, MiniGameCalloutComponent, MiniGameScorePopComponent, ModalLayoutComponent, RangeInputComponent, ToggleInputComponent, ButtonComponent, UserAvatarComponent], template: `
71697
+ args: [{ selector: 'val-chessimals-game', standalone: true, imports: [
71698
+ IonModal,
71699
+ MiniGameCalloutComponent,
71700
+ MiniGameScorePopComponent,
71701
+ ModalLayoutComponent,
71702
+ RangeInputComponent,
71703
+ ToggleInputComponent,
71704
+ ButtonComponent,
71705
+ UserAvatarComponent,
71706
+ ], template: `
71279
71707
  <main class="chessimals-shell" [class.chessimals-shell--projection]="projectionMode">
71280
71708
  @if (screen() === 'home') {
71281
71709
  <section class="chessimals-hero">
@@ -71298,7 +71726,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
71298
71726
 
71299
71727
  <section class="chessimals-panel">
71300
71728
  <section class="chessimals-home-actions" [attr.aria-label]="t('chessimalsHomeChoose')">
71301
- <button class="chessimals-home-action chessimals-home-action--play" type="button" (click)="openPlayOptionsModal()">
71729
+ <button
71730
+ class="chessimals-home-action chessimals-home-action--play"
71731
+ type="button"
71732
+ (click)="openPlayOptionsModal()"
71733
+ >
71302
71734
  <img
71303
71735
  class="chessimals-mode-icon"
71304
71736
  src="assets/games/chessimals/mode-icons/solo-borderless.png"
@@ -71352,60 +71784,60 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
71352
71784
  </summary>
71353
71785
 
71354
71786
  <article class="chessimals-online">
71355
- <div>
71356
- <h2>{{ t('chessimalsOnlineTitle') }}</h2>
71357
- <p>{{ t('chessimalsOnlineBody') }}</p>
71358
- </div>
71359
- @if (onlineError()) {
71360
- <p class="chessimals-online__error">{{ onlineError() }}</p>
71361
- }
71362
- @if (onlineLoading()) {
71363
- <div class="chessimals-online__loading" role="status" aria-live="polite">
71364
- <span aria-hidden="true"></span>
71365
- <strong>{{ t('chessimalsOnlineLoading') }}</strong>
71787
+ <div>
71788
+ <h2>{{ t('chessimalsOnlineTitle') }}</h2>
71789
+ <p>{{ t('chessimalsOnlineBody') }}</p>
71790
+ </div>
71791
+ @if (onlineError()) {
71792
+ <p class="chessimals-online__error">{{ onlineError() }}</p>
71793
+ }
71794
+ @if (onlineLoading()) {
71795
+ <div class="chessimals-online__loading" role="status" aria-live="polite">
71796
+ <span aria-hidden="true"></span>
71797
+ <strong>{{ t('chessimalsOnlineLoading') }}</strong>
71798
+ </div>
71799
+ }
71800
+ <div class="chessimals-online__create">
71801
+ <button
71802
+ class="chessimals-primary"
71803
+ type="button"
71804
+ [class.is-working]="onlineAction() === 'create'"
71805
+ [attr.aria-busy]="onlineAction() === 'create'"
71806
+ [disabled]="onlineLoading()"
71807
+ (click)="createOnlineGame()"
71808
+ >
71809
+ @if (onlineAction() === 'create') {
71810
+ <span class="chessimals-button-spinner" aria-hidden="true"></span>
71811
+ }
71812
+ {{ t('chessimalsCreateOnline') }}
71813
+ </button>
71814
+ <small>{{ t('chessimalsCreateOnlineHint') }}</small>
71815
+ </div>
71816
+ <div class="chessimals-online__join">
71817
+ <strong>{{ t('chessimalsJoinOnlineTitle') }}</strong>
71818
+ <label class="chessimals-online-code">
71819
+ <span>{{ t('chessimalsJoinCode') }}</span>
71820
+ <input
71821
+ type="text"
71822
+ [value]="onlineJoinCode()"
71823
+ [placeholder]="t('chessimalsJoinCodePlaceholder')"
71824
+ (input)="onlineJoinCode.set(normalizeGameId($any($event.target).value))"
71825
+ />
71826
+ </label>
71827
+ <button
71828
+ class="chessimals-primary"
71829
+ type="button"
71830
+ [class.is-working]="onlineAction() === 'join'"
71831
+ [attr.aria-busy]="onlineAction() === 'join'"
71832
+ [disabled]="onlineLoading() || !onlineJoinCode()"
71833
+ (click)="joinOnlineGameByCode()"
71834
+ >
71835
+ @if (onlineAction() === 'join') {
71836
+ <span class="chessimals-button-spinner" aria-hidden="true"></span>
71837
+ }
71838
+ {{ t('chessimalsJoinOnline') }}
71839
+ </button>
71366
71840
  </div>
71367
- }
71368
- <div class="chessimals-online__create">
71369
- <button
71370
- class="chessimals-primary"
71371
- type="button"
71372
- [class.is-working]="onlineAction() === 'create'"
71373
- [attr.aria-busy]="onlineAction() === 'create'"
71374
- [disabled]="onlineLoading()"
71375
- (click)="createOnlineGame()"
71376
- >
71377
- @if (onlineAction() === 'create') {
71378
- <span class="chessimals-button-spinner" aria-hidden="true"></span>
71379
- }
71380
- {{ t('chessimalsCreateOnline') }}
71381
- </button>
71382
- <small>{{ t('chessimalsCreateOnlineHint') }}</small>
71383
- </div>
71384
- <div class="chessimals-online__join">
71385
- <strong>{{ t('chessimalsJoinOnlineTitle') }}</strong>
71386
- <label class="chessimals-online-code">
71387
- <span>{{ t('chessimalsJoinCode') }}</span>
71388
- <input
71389
- type="text"
71390
- [value]="onlineJoinCode()"
71391
- [placeholder]="t('chessimalsJoinCodePlaceholder')"
71392
- (input)="onlineJoinCode.set(normalizeGameId($any($event.target).value))"
71393
- />
71394
- </label>
71395
- <button
71396
- class="chessimals-primary"
71397
- type="button"
71398
- [class.is-working]="onlineAction() === 'join'"
71399
- [attr.aria-busy]="onlineAction() === 'join'"
71400
- [disabled]="onlineLoading() || !onlineJoinCode()"
71401
- (click)="joinOnlineGameByCode()"
71402
- >
71403
- @if (onlineAction() === 'join') {
71404
- <span class="chessimals-button-spinner" aria-hidden="true"></span>
71405
- }
71406
- {{ t('chessimalsJoinOnline') }}
71407
- </button>
71408
- </div>
71409
71841
  </article>
71410
71842
  </details>
71411
71843
 
@@ -71488,7 +71920,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
71488
71920
  <strong>{{ challengeBotName(challengeMenuBot()) }}</strong>
71489
71921
  <p>{{ t(challengeMenuBot().introKey) }}</p>
71490
71922
  <em>
71491
- {{ t('chessimalsChallengeBoardLabel').replace('{size}', challengeMenuBot().boardSize + 'x' + challengeMenuBot().boardSize) }}
71923
+ {{
71924
+ t('chessimalsChallengeBoardLabel').replace(
71925
+ '{size}',
71926
+ challengeMenuBot().boardSize + 'x' + challengeMenuBot().boardSize
71927
+ )
71928
+ }}
71492
71929
  , {{ challengeBotDifficultyLabel(challengeMenuBot()) }}
71493
71930
  </em>
71494
71931
  </div>
@@ -71750,7 +72187,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
71750
72187
  @if (pendingGuestAvatarUrl()) {
71751
72188
  <val-user-avatar [props]="pendingGuestAvatarProps()" />
71752
72189
  } @else {
71753
- <span class="chessimals-player-strip__avatar chessimals-player-strip__avatar--initials" aria-hidden="true">
72190
+ <span
72191
+ class="chessimals-player-strip__avatar chessimals-player-strip__avatar--initials"
72192
+ aria-hidden="true"
72193
+ >
71754
72194
  {{ pendingGuestInitials() }}
71755
72195
  </span>
71756
72196
  }
@@ -71810,26 +72250,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
71810
72250
  @if (isChallengeActive() || turnSecondsRemaining() !== undefined) {
71811
72251
  <div class="chessimals-status chessimals-status--simple">
71812
72252
  @if (isChallengeActive()) {
71813
- <div>
71814
- <small>{{ t('chessimalsChallengeRound') }}</small>
71815
- <strong>{{ challengeRoundLabel() }}</strong>
71816
- </div>
71817
- <div>
71818
- <small>{{ t('chessimalsChallengeLives') }}</small>
71819
- <strong>{{ challengeLivesLabel() }}</strong>
71820
- </div>
72253
+ <div>
72254
+ <small>{{ t('chessimalsChallengeRound') }}</small>
72255
+ <strong>{{ challengeRoundLabel() }}</strong>
72256
+ </div>
72257
+ <div>
72258
+ <small>{{ t('chessimalsChallengeLives') }}</small>
72259
+ <strong>{{ challengeLivesLabel() }}</strong>
72260
+ </div>
71821
72261
  }
71822
72262
  @if (turnSecondsRemaining() !== undefined) {
71823
- <div
71824
- class="chessimals-status__timer"
71825
- [class.is-low]="isTurnTimerLow()"
71826
- [style.--timer-progress]="turnTimerProgress()"
71827
- role="timer"
71828
- aria-live="polite"
71829
- >
71830
- <small>{{ t('chessimalsTurnTimer') }}</small>
71831
- <strong>{{ turnTimerLabel() }}</strong>
71832
- </div>
72263
+ <div
72264
+ class="chessimals-status__timer"
72265
+ [class.is-low]="isTurnTimerLow()"
72266
+ [style.--timer-progress]="turnTimerProgress()"
72267
+ role="timer"
72268
+ aria-live="polite"
72269
+ >
72270
+ <small>{{ t('chessimalsTurnTimer') }}</small>
72271
+ <strong>{{ turnTimerLabel() }}</strong>
72272
+ </div>
71833
72273
  }
71834
72274
  </div>
71835
72275
  }
@@ -71927,7 +72367,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
71927
72367
  [class.effect-bull]="isMoveEffectCell(row, col, 'bull')"
71928
72368
  [class.effect-kangaroo]="isMoveEffectCell(row, col, 'kangaroo')"
71929
72369
  [class.effect-lion]="isMoveEffectCell(row, col, 'lion')"
71930
- [disabled]="projectionMode || game().status !== 'in_progress' || !canPlayCurrentTurn() || !!movingPiece() || botThinking() || moveSyncing()"
72370
+ [disabled]="
72371
+ projectionMode ||
72372
+ game().status !== 'in_progress' ||
72373
+ !canPlayCurrentTurn() ||
72374
+ !!movingPiece() ||
72375
+ botThinking() ||
72376
+ moveSyncing()
72377
+ "
71931
72378
  (click)="selectCell({ row, col })"
71932
72379
  >
71933
72380
  <span class="chessimals-cell-texture" aria-hidden="true"></span>
@@ -72080,7 +72527,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
72080
72527
  type="button"
72081
72528
  [class.is-selected]="selectedAnimal() === animal.type"
72082
72529
  [class.is-used]="powerPlayer().cards[animal.type].used"
72083
- [disabled]="!canUsePowerCards() || powerPlayer().cards[animal.type].used || isPowerCardBlockedByTutorial(animal.type)"
72530
+ [disabled]="
72531
+ !canUsePowerCards() ||
72532
+ powerPlayer().cards[animal.type].used ||
72533
+ isPowerCardBlockedByTutorial(animal.type)
72534
+ "
72084
72535
  (click)="toggleAnimal(animal)"
72085
72536
  >
72086
72537
  <span class="chessimals-animal-face" aria-hidden="true">
@@ -72175,11 +72626,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
72175
72626
  </div>
72176
72627
  <div class="chessimals-challenge-summary__actions">
72177
72628
  @if (challengePhase() === 'between') {
72178
- <button class="chessimals-primary chessimals-challenge-summary__play" type="button" (click)="continueChallenge()">
72629
+ <button
72630
+ class="chessimals-primary chessimals-challenge-summary__play"
72631
+ type="button"
72632
+ (click)="continueChallenge()"
72633
+ >
72179
72634
  {{ challengeContinueLabel() }}
72180
72635
  </button>
72181
72636
  } @else {
72182
- <button class="chessimals-primary chessimals-challenge-summary__play" type="button" (click)="startChallenge()">
72637
+ <button
72638
+ class="chessimals-primary chessimals-challenge-summary__play"
72639
+ type="button"
72640
+ (click)="startChallenge()"
72641
+ >
72183
72642
  {{ t('chessimalsChallengePlayAgain') }}
72184
72643
  </button>
72185
72644
  }
@@ -72254,7 +72713,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
72254
72713
  @if (rematchOpponentAvatarUrl()) {
72255
72714
  <val-user-avatar [props]="rematchOpponentAvatarProps()" />
72256
72715
  } @else {
72257
- <span class="chessimals-player-strip__avatar chessimals-player-strip__avatar--initials" aria-hidden="true">
72716
+ <span
72717
+ class="chessimals-player-strip__avatar chessimals-player-strip__avatar--initials"
72718
+ aria-hidden="true"
72719
+ >
72258
72720
  {{ rematchOpponentInitials() }}
72259
72721
  </span>
72260
72722
  }
@@ -72377,7 +72839,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
72377
72839
 
72378
72840
  <article class="chessimals-play-options__group">
72379
72841
  <h3 id="chessimals-play-bot">
72380
- {{ selectedBotDifficulty() === 'nightmare' ? t('chessimalsNightmareRivals') : t('chessimalsBotStyle') }}
72842
+ {{
72843
+ selectedBotDifficulty() === 'nightmare' ? t('chessimalsNightmareRivals') : t('chessimalsBotStyle')
72844
+ }}
72381
72845
  </h3>
72382
72846
  <div class="chessimals-bots" role="radiogroup" aria-labelledby="chessimals-play-bot">
72383
72847
  @if (selectedBotDifficulty() === 'nightmare') {