@maxr0ssi/chaos-chess 0.1.7 → 0.2.1

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.
@@ -1,161 +1,400 @@
1
- import { jsx as a, jsxs as C } from "react/jsx-runtime";
2
- import Ze, { useRef as y, useState as d, useCallback as N, useEffect as F } from "react";
3
- import { Chess as oe } from "chess.js";
4
- function pe(t) {
5
- return t.isGameOver() ? t.isCheckmate() ? { isGameOver: !0, result: "checkmate", winner: t.turn() === "w" ? "b" : "w", inCheck: t.turn() } : t.isStalemate() ? { isGameOver: !0, result: "stalemate", winner: null, inCheck: null } : t.isInsufficientMaterial() ? { isGameOver: !0, result: "insufficient", winner: null, inCheck: null } : t.isThreefoldRepetition() ? { isGameOver: !0, result: "threefold", winner: null, inCheck: null } : { isGameOver: !0, result: "draw", winner: null, inCheck: null } : { isGameOver: !1, result: null, winner: null, inCheck: t.inCheck() ? t.turn() : null };
6
- }
7
- function et() {
8
- const t = y(new oe()), [e, n] = d(t.current.fen()), [s, o] = d(t.current.turn()), [r, c] = d(null), [i, l] = d([]), [w, f] = d(pe(t.current)), [_, P] = d(null), [g, v] = d([]), [k, R] = d(null), [$, I] = d(null), [x, b] = d(t.current.board()), h = N(() => {
9
- c(null), l([]);
10
- }, []), D = N(() => {
11
- n(t.current.fen()), o(t.current.turn()), b(t.current.board()), f(pe(t.current));
12
- }, []), le = N((T) => {
13
- const m = t.current, M = m.turn();
14
- if (_ || pe(m).isGameOver)
1
+ import { jsx as l, jsxs as L } from "react/jsx-runtime";
2
+ import At, { useState as k, useRef as w, useCallback as S, useEffect as O, useLayoutEffect as st } from "react";
3
+ import { Chess as de } from "chess.js";
4
+ const Et = {
5
+ p: 1,
6
+ n: 3,
7
+ b: 3,
8
+ r: 5,
9
+ q: 9,
10
+ k: 0
11
+ }, Le = "abcdefgh";
12
+ function Y(t) {
13
+ const e = t.trim().split(/\s+/);
14
+ return {
15
+ position: e[0],
16
+ activeColor: e[1] ?? "w",
17
+ castling: e[2] ?? "-",
18
+ enPassant: e[3] ?? "-",
19
+ halfmove: e[4] ?? "0",
20
+ fullmove: e[5] ?? "1"
21
+ };
22
+ }
23
+ function K(t) {
24
+ const e = [], n = t.split("/");
25
+ for (const r of n) {
26
+ const o = [];
27
+ for (const i of r) {
28
+ const a = parseInt(i);
29
+ if (isNaN(a)) {
30
+ const s = i === i.toUpperCase() ? "w" : "b", c = i.toLowerCase();
31
+ o.push({ type: c, color: s });
32
+ } else
33
+ for (let s = 0; s < a; s++) o.push(null);
34
+ }
35
+ e.push(o);
36
+ }
37
+ return e;
38
+ }
39
+ function at(t) {
40
+ return t.map((e) => {
41
+ let n = "", r = 0;
42
+ for (const o of e)
43
+ if (o === null)
44
+ r++;
45
+ else {
46
+ r > 0 && (n += r, r = 0);
47
+ const i = o.color === "w" ? o.type.toUpperCase() : o.type;
48
+ n += i;
49
+ }
50
+ return r > 0 && (n += r), n;
51
+ }).join("/");
52
+ }
53
+ function Ie(t) {
54
+ return `${t.position} ${t.activeColor} ${t.castling} ${t.enPassant} ${t.halfmove} ${t.fullmove}`;
55
+ }
56
+ function It(t) {
57
+ const { position: e } = Y(t), n = K(e);
58
+ let r = 0, o = 0;
59
+ for (const i of n)
60
+ for (const a of i)
61
+ if (a) {
62
+ const s = Et[a.type];
63
+ a.color === "w" ? r += s : o += s;
64
+ }
65
+ return { white: r, black: o };
66
+ }
67
+ function qt(t) {
68
+ const { position: e } = Y(t), n = K(e), r = [];
69
+ for (let o = 0; o < 8; o++)
70
+ for (let i = 0; i < 8; i++)
71
+ n[o][i] === null && r.push(`${Le[i]}${8 - o}`);
72
+ return r;
73
+ }
74
+ function Ft(t, e, n = !0) {
75
+ const { position: r } = Y(t), o = K(r), i = [];
76
+ for (let a = 0; a < 8; a++)
77
+ for (let s = 0; s < 8; s++) {
78
+ const c = o[a][s];
79
+ if (c && c.color === e) {
80
+ if (n && c.type === "k") continue;
81
+ i.push(`${Le[s]}${8 - a}`);
82
+ }
83
+ }
84
+ return i;
85
+ }
86
+ function qe(t) {
87
+ const e = Le.indexOf(t[0]);
88
+ return [8 - parseInt(t[1]), e];
89
+ }
90
+ function jt(t, e, n, r) {
91
+ const o = Y(t), i = K(o.position), [a, s] = qe(e);
92
+ return i[a][s] = { type: n, color: r }, o.position = at(i), W(Ie(o));
93
+ }
94
+ function xt(t, e) {
95
+ const n = Y(t), r = K(n.position), [o, i] = qe(e);
96
+ return r[o][i] = null, n.position = at(r), W(Ie(n));
97
+ }
98
+ const $t = {
99
+ K: ["e1", "h1", "w"],
100
+ Q: ["e1", "a1", "w"],
101
+ k: ["e8", "h8", "b"],
102
+ q: ["e8", "a8", "b"]
103
+ };
104
+ function le(t, e) {
105
+ const [n, r] = qe(e);
106
+ return t[n]?.[r] ?? null;
107
+ }
108
+ function ct(t, e) {
109
+ return !t || t === "-" ? "-" : ["K", "Q", "k", "q"].filter((r) => {
110
+ if (!t.includes(r)) return !1;
111
+ const o = $t[r], [i, a, s] = o, c = le(e, i), m = le(e, a);
112
+ return c?.type === "k" && c.color === s && m?.type === "r" && m.color === s;
113
+ }).join("") || "-";
114
+ }
115
+ function lt(t, e, n) {
116
+ if (!t || t === "-") return "-";
117
+ const r = t[0], o = parseInt(t[1]), i = e === "w" ? 6 : 3;
118
+ if (!Le.includes(r) || o !== i) return "-";
119
+ const a = e === "w" ? 5 : 4, s = e === "w" ? 7 : 2, c = le(n, `${r}${a}`), m = e === "w" ? "b" : "w";
120
+ return c?.type !== "p" || c.color !== m || le(n, t) !== null || le(n, `${r}${s}`) !== null ? "-" : t;
121
+ }
122
+ function W(t) {
123
+ const e = Y(t), n = K(e.position);
124
+ return e.castling = ct(e.castling, n), e.enPassant = lt(e.enPassant, e.activeColor, n), Ie(e);
125
+ }
126
+ function ue(t) {
127
+ const e = t.findPiece({ type: "k", color: "w" }).length > 0, n = t.findPiece({ type: "k", color: "b" }).length > 0;
128
+ return !e || !n ? { isGameOver: !0, result: "king-captured", winner: e ? "w" : n ? "b" : null, inCheck: null } : t.isGameOver() ? t.isCheckmate() ? { isGameOver: !0, result: "checkmate", winner: t.turn() === "w" ? "b" : "w", inCheck: t.turn() } : t.isStalemate() ? { isGameOver: !0, result: "stalemate", winner: null, inCheck: null } : t.isInsufficientMaterial() ? { isGameOver: !0, result: "insufficient", winner: null, inCheck: null } : t.isThreefoldRepetition() ? { isGameOver: !0, result: "threefold", winner: null, inCheck: null } : t.isDrawByFiftyMoves() ? { isGameOver: !0, result: "fifty-move", winner: null, inCheck: null } : { isGameOver: !0, result: "draw", winner: null, inCheck: null } : { isGameOver: !1, result: null, winner: null, inCheck: t.inCheck() ? t.turn() : null };
129
+ }
130
+ function Dt(t) {
131
+ if (t)
132
+ try {
133
+ return new de(W(t));
134
+ } catch {
135
+ }
136
+ return new de();
137
+ }
138
+ function Gt(t) {
139
+ const [e] = k(() => Dt(t)), n = w(e), [r, o] = k(() => e.fen()), [i, a] = k(() => e.turn()), [s, c] = k(null), [m, y] = k([]), [g, _] = k(() => ue(e)), [d, v] = k(null), [C, x] = k([]), [R, q] = k(null), [G, B] = k(null), [$, ne] = k(() => e.board()), p = S(() => {
140
+ c(null), y([]);
141
+ }, []), M = S(() => {
142
+ o(n.current.fen()), a(n.current.turn()), ne(n.current.board()), _(ue(n.current));
143
+ }, []), F = S((f) => {
144
+ q({ from: f.from, to: f.to }), B({ captured: !!f.captured, check: f.san.includes("+") || f.san.includes("#") }), x((b) => [
145
+ ...b,
146
+ { san: f.san, fen: n.current.fen(), color: f.color }
147
+ ]);
148
+ }, []), re = S((f) => {
149
+ const b = n.current, z = b.turn();
150
+ if (d || ue(b).isGameOver)
15
151
  return;
16
- if (r && i.includes(T)) {
17
- const q = m.get(r);
18
- if (q?.type === "p" && (q.color === "w" && T[1] === "8" || q.color === "b" && T[1] === "1")) {
19
- P({ from: r, to: T }), h();
152
+ if (s && m.includes(f)) {
153
+ const T = b.get(s);
154
+ if (T?.type === "p" && (T.color === "w" && f[1] === "8" || T.color === "b" && f[1] === "1")) {
155
+ v({ from: s, to: f }), p();
20
156
  return;
21
157
  }
22
158
  try {
23
- const S = m.move({ from: r, to: T });
24
- S && (R({ from: S.from, to: S.to }), I({ captured: !!S.captured, check: S.san.includes("+") || S.san.includes("#") }), v((L) => [
25
- ...L,
26
- { san: S.san, fen: m.fen(), color: S.color }
27
- ]));
159
+ const X = b.move({ from: s, to: f });
160
+ X && F(X);
28
161
  } catch {
29
162
  }
30
- h(), D();
163
+ p(), M();
31
164
  return;
32
165
  }
33
- const H = m.get(T);
34
- if (H && H.color === M) {
35
- if (T === r) {
36
- h();
166
+ const P = b.get(f);
167
+ if (P && P.color === z) {
168
+ if (f === s) {
169
+ p();
37
170
  return;
38
171
  }
39
- c(T);
40
- const q = m.moves({ square: T, verbose: !0 });
41
- l(q.map((S) => S.to));
172
+ c(f);
173
+ const T = b.moves({ square: f, verbose: !0 });
174
+ y(T.map((X) => X.to));
42
175
  return;
43
176
  }
44
- h();
45
- }, [r, i, _, h, D]), W = N((T) => {
46
- if (!_) return;
47
- const m = t.current;
177
+ p();
178
+ }, [s, m, d, p, M, F]), I = S((f) => {
179
+ if (!d) return;
180
+ const b = n.current;
48
181
  try {
49
- const M = m.move({
50
- from: _.from,
51
- to: _.to,
52
- promotion: T
182
+ const z = b.move({
183
+ from: d.from,
184
+ to: d.to,
185
+ promotion: f
53
186
  });
54
- M && (R({ from: M.from, to: M.to }), I({ captured: !!M.captured, check: M.san.includes("+") || M.san.includes("#") }), v((H) => [
55
- ...H,
56
- { san: M.san, fen: m.fen(), color: M.color }
57
- ]));
187
+ z && F(z);
188
+ } catch {
189
+ }
190
+ v(null), p(), M();
191
+ }, [d, p, M, F]), fe = S((f) => {
192
+ const b = n.current;
193
+ try {
194
+ b.load(W(f)), p(), M();
58
195
  } catch {
59
196
  }
60
- P(null), h(), D();
61
- }, [_, h, D]), Z = N((T) => {
62
- const m = t.current;
197
+ }, [p, M]), Me = S((f, b) => {
198
+ const z = n.current;
199
+ if (b !== void 0 && z.fen() !== b) return !1;
200
+ let P;
63
201
  try {
64
- m.load(T), h(), D();
202
+ P = z.move(f);
65
203
  } catch {
204
+ return !1;
66
205
  }
67
- }, [h, D]), ue = N(() => {
68
- t.current.reset(), h(), v([]), R(null), I(null), P(null), D();
69
- }, [h, D]);
206
+ return F(P), p(), M(), !0;
207
+ }, [F, p, M]), Se = S(() => {
208
+ n.current.reset(), p(), x([]), q(null), B(null), v(null), M();
209
+ }, [p, M]);
70
210
  return {
71
- fen: e,
72
- turn: s,
73
- selectedSquare: r,
74
- legalMoves: i,
75
- gameStatus: w,
76
- promotionPending: _,
77
- moveHistory: g,
78
- lastMove: k,
79
- lastMoveDetail: $,
80
- board: x,
81
- handleSquareClick: le,
82
- handlePromotion: W,
83
- applyFen: Z,
84
- handleRestart: ue
211
+ fen: r,
212
+ turn: i,
213
+ selectedSquare: s,
214
+ legalMoves: m,
215
+ gameStatus: g,
216
+ promotionPending: d,
217
+ moveHistory: C,
218
+ lastMove: R,
219
+ lastMoveDetail: G,
220
+ board: $,
221
+ handleSquareClick: re,
222
+ handlePromotion: I,
223
+ applyFen: fe,
224
+ applyMove: Me,
225
+ handleRestart: Se
85
226
  };
86
227
  }
87
- class tt {
228
+ const zt = 2e4, Ut = 8e3, ut = 3, Vt = 5e3, Ht = 1e4, Ze = 2e3;
229
+ class ae extends Error {
230
+ constructor() {
231
+ super("Search cancelled"), this.name = "StockfishCancelledError";
232
+ }
233
+ }
234
+ class Ne extends Error {
235
+ constructor() {
236
+ super("Stockfish worker restarted"), this.name = "StockfishRestartedError";
237
+ }
238
+ }
239
+ class Ae extends Error {
240
+ constructor() {
241
+ super("Stockfish is unavailable"), this.name = "StockfishUnavailableError";
242
+ }
243
+ }
244
+ class Re extends Error {
245
+ constructor(e) {
246
+ super(`Stockfish timed out during ${e}`), this.name = "StockfishTimeoutError";
247
+ }
248
+ }
249
+ class Wt {
88
250
  worker = null;
89
- resolveMove = null;
90
- rejectMove = null;
91
- currentListener = null;
92
- timeoutId = null;
251
+ ready = null;
252
+ pending = null;
253
+ waiters = [];
254
+ /** True from `go` until its `bestmove`, including after `stop`. */
255
+ searching = !1;
93
256
  searchId = 0;
257
+ destroyed = !1;
258
+ initFailures = 0;
259
+ hasStarted = !1;
94
260
  workerPath;
95
261
  constructor(e = "/stockfish/stockfish-18-lite-single.js") {
96
262
  this.workerPath = e;
97
263
  }
98
- async init() {
99
- return new Promise((e, n) => {
100
- try {
101
- this.worker = new Worker(this.workerPath);
102
- const s = (o) => {
103
- (typeof o.data == "string" ? o.data : "").includes("uciok") && (this.worker?.removeEventListener("message", s), e());
104
- };
105
- this.worker.addEventListener("message", s), this.worker.addEventListener("error", (o) => {
106
- n(new Error(`Stockfish worker error: ${o.message}`));
107
- }), this.worker.postMessage("uci");
108
- } catch (s) {
109
- n(s);
110
- }
111
- });
264
+ get isDestroyed() {
265
+ return this.destroyed;
112
266
  }
113
- /** Cancel any in-flight search and clean up its listener/promise/timer. */
114
- cancelPending() {
115
- this.timeoutId !== null && (clearTimeout(this.timeoutId), this.timeoutId = null), this.currentListener && this.worker && (this.worker.removeEventListener("message", this.currentListener), this.currentListener = null), this.rejectMove && (this.rejectMove(new Error("Search cancelled")), this.resolveMove = null, this.rejectMove = null), this.stop();
267
+ /** True after MAX_INIT_FAILURES failed starts in a row. */
268
+ get isUnavailable() {
269
+ return this.initFailures >= ut;
116
270
  }
117
271
  /**
118
- * Send `isready` and wait for `readyok`.
119
- * This flushes any stale `bestmove` from a prior `stop` command,
120
- * guaranteeing the message queue is clean before a new search starts.
272
+ * Start the worker and wait for `uciok`. Concurrent calls share one start.
273
+ * Rejects with StockfishUnavailableError once starting has failed
274
+ * MAX_INIT_FAILURES times in a row.
121
275
  */
122
- waitReady() {
123
- return new Promise((e) => {
124
- if (!this.worker) {
125
- e();
126
- return;
276
+ init(e) {
277
+ if (this.destroyed) return Promise.reject(new Error("Stockfish engine destroyed"));
278
+ if (this.isUnavailable) return Promise.reject(new Ae());
279
+ if (!this.ready) {
280
+ const n = e ?? (this.hasStarted ? Ut : zt), r = this.spawn(n).then(
281
+ () => {
282
+ this.initFailures = 0, this.hasStarted = !0;
283
+ },
284
+ (o) => {
285
+ throw this.initFailures++, this.ready === r && (this.ready = null), this.isUnavailable ? new Ae() : o;
286
+ }
287
+ );
288
+ this.ready = r;
289
+ }
290
+ return this.ready;
291
+ }
292
+ async spawn(e) {
293
+ const n = new Worker(this.workerPath);
294
+ this.worker = n, this.searching = !1, n.addEventListener("message", (r) => this.handleMessage(n, r)), n.addEventListener("error", (r) => this.handleWorkerError(n, r)), n.postMessage("uci");
295
+ try {
296
+ await this.waitFor((r) => r.includes("uciok"), e, "init");
297
+ } catch (r) {
298
+ throw this.terminate(n), r;
299
+ }
300
+ }
301
+ handleMessage(e, n) {
302
+ if (e !== this.worker) return;
303
+ const r = typeof n.data == "string" ? n.data : "";
304
+ if (r.startsWith("bestmove")) {
305
+ this.searching = !1;
306
+ const o = this.pending;
307
+ if (o) {
308
+ this.pending = null, o.timer !== null && clearTimeout(o.timer);
309
+ const i = r.split(" ")[1];
310
+ o.resolve(i && i !== "(none)" ? i : null);
127
311
  }
128
- const n = (s) => {
129
- (typeof s.data == "string" ? s.data : "") === "readyok" && (this.worker?.removeEventListener("message", n), e());
312
+ }
313
+ for (const o of [...this.waiters])
314
+ o.match(r) && (this.waiters = this.waiters.filter((i) => i !== o), o.resolve(r));
315
+ }
316
+ handleWorkerError(e, n) {
317
+ if (e !== this.worker) return;
318
+ const r = new Error(`Stockfish worker error: ${n.message}`);
319
+ console.warn("[ChaosChess] Stockfish worker error, restarting:", n.message), this.failPending(r), this.terminate(e, r);
320
+ }
321
+ /** Wait for a message from the current worker, with a timeout. */
322
+ waitFor(e, n, r) {
323
+ return new Promise((o, i) => {
324
+ const a = setTimeout(() => {
325
+ this.waiters = this.waiters.filter((c) => c !== s), i(new Re(r));
326
+ }, n), s = {
327
+ match: e,
328
+ resolve: (c) => {
329
+ clearTimeout(a), o(c);
330
+ },
331
+ // Called when the worker is terminated, so callers fail fast
332
+ reject: (c) => {
333
+ clearTimeout(a), i(c);
334
+ }
130
335
  };
131
- this.worker.addEventListener("message", n), this.worker.postMessage("isready");
336
+ this.waiters.push(s);
132
337
  });
133
338
  }
339
+ /** Terminate a worker. If it is the current one, the next search starts a new one. */
340
+ terminate(e, n = new Ne()) {
341
+ try {
342
+ e.terminate();
343
+ } catch {
344
+ }
345
+ if (e !== this.worker) return;
346
+ this.worker = null, this.ready = null, this.searching = !1;
347
+ const r = this.waiters;
348
+ this.waiters = [];
349
+ for (const o of r) o.reject(n);
350
+ }
351
+ /** Reject the in-flight search and clear its timer. */
352
+ failPending(e) {
353
+ const n = this.pending;
354
+ n && (this.pending = null, n.timer !== null && clearTimeout(n.timer), n.reject(e));
355
+ }
356
+ /** Cancel any in-flight search. Its bestmove is drained before the next search. */
357
+ cancelPending() {
358
+ this.failPending(new ae()), this.searching && this.stop();
359
+ }
360
+ /**
361
+ * Cancel whatever this engine is doing, including a search that is still
362
+ * waiting to start. The engine stays usable.
363
+ */
364
+ cancel() {
365
+ this.searchId++, this.cancelPending();
366
+ }
134
367
  /**
135
368
  * Get the best move for a given FEN position at the specified depth.
136
- * Returns a UCI move string like "e2e4".
137
- * Calling this while a search is in-flight cancels the previous search.
369
+ * Returns a UCI move string like "e2e4", or null when Stockfish reports
370
+ * no move ("(none)").
371
+ *
372
+ * Calling this while a search is in-flight cancels the previous search,
373
+ * which rejects with StockfishCancelledError. A search that passes
374
+ * `timeoutMs` is stopped and resolves with the best move found so far. If
375
+ * the engine does not answer even then, the worker is replaced and the
376
+ * search rejects with StockfishTimeoutError.
138
377
  */
139
- async getBestMove(e, n, s = 1e4) {
140
- this.cancelPending(), await this.waitReady();
141
- const o = ++this.searchId;
142
- return new Promise((r, c) => {
143
- if (!this.worker) {
144
- c(new Error("Stockfish not initialized"));
145
- return;
146
- }
147
- this.resolveMove = r, this.rejectMove = c, this.timeoutId = setTimeout(() => {
148
- this.searchId === o && this.cancelPending();
149
- }, s);
150
- const i = (l) => {
151
- const w = typeof l.data == "string" ? l.data : "";
152
- if (w.startsWith("bestmove")) {
153
- this.timeoutId !== null && (clearTimeout(this.timeoutId), this.timeoutId = null), this.worker?.removeEventListener("message", i), this.currentListener = null;
154
- const f = w.split(" ")[1];
155
- this.resolveMove && (this.resolveMove(f && f !== "(none)" ? f : null), this.resolveMove = null, this.rejectMove = null);
156
- }
157
- };
158
- this.currentListener = i, this.worker.addEventListener("message", i), this.worker.postMessage("ucinewgame"), this.worker.postMessage(`position fen ${e}`), this.worker.postMessage(`go depth ${n}`);
378
+ async getBestMove(e, n, r = Ht) {
379
+ const o = Number.isFinite(n) ? Math.min(20, Math.max(1, Math.round(n))) : 10, i = ++this.searchId;
380
+ this.cancelPending(), await this.init();
381
+ const a = this.worker;
382
+ if (!a) throw new Error("Stockfish not initialized");
383
+ if (i !== this.searchId) throw new ae();
384
+ try {
385
+ this.searching && await this.waitFor((s) => s.startsWith("bestmove"), Ze, "stop"), a.postMessage("isready"), await this.waitFor((s) => s === "readyok", Vt, "isready");
386
+ } catch (s) {
387
+ throw i !== this.searchId ? new ae() : (s instanceof Re && this.terminate(a), s);
388
+ }
389
+ if (i !== this.searchId) throw new ae();
390
+ if (a !== this.worker || this.searching) throw new Ne();
391
+ return new Promise((s, c) => {
392
+ const m = { resolve: s, reject: c, timer: null };
393
+ m.timer = setTimeout(() => {
394
+ this.pending === m && (a.postMessage("stop"), m.timer = setTimeout(() => {
395
+ this.pending === m && (this.failPending(new Re("search")), this.terminate(a));
396
+ }, Ze));
397
+ }, r), this.pending = m, this.searching = !0, a.postMessage("ucinewgame"), a.postMessage(`position fen ${W(e)}`), a.postMessage(`go depth ${o}`);
159
398
  });
160
399
  }
161
400
  /**
@@ -168,234 +407,205 @@ class tt {
168
407
  * Terminate the worker.
169
408
  */
170
409
  destroy() {
171
- this.cancelPending(), this.worker?.postMessage("quit"), this.worker?.terminate(), this.worker = null;
410
+ this.destroyed = !0, this.cancel();
411
+ const e = this.worker;
412
+ e && (e.postMessage("quit"), this.terminate(e, new Error("Stockfish engine destroyed")));
413
+ }
414
+ }
415
+ const Yt = 300 * 1e3, ce = /* @__PURE__ */ new Map();
416
+ function dt(t) {
417
+ return t ?? "";
418
+ }
419
+ function Kt(t) {
420
+ const e = dt(t), n = ce.get(e);
421
+ for (; n && n.length > 0; ) {
422
+ const r = n.pop();
423
+ if (clearTimeout(r.timer), !r.engine.isDestroyed && !r.engine.isUnavailable) return r.engine;
424
+ r.engine.destroy();
172
425
  }
426
+ return new Wt(t);
427
+ }
428
+ function Xt(t, e) {
429
+ t.cancel();
430
+ const n = dt(e), r = ce.get(n) ?? [];
431
+ if (r.some((i) => i.engine === t)) return;
432
+ const o = {
433
+ engine: t,
434
+ timer: setTimeout(() => {
435
+ const i = ce.get(n);
436
+ i && ce.set(n, i.filter((a) => a !== o)), t.destroy();
437
+ }, Yt)
438
+ };
439
+ r.push(o), ce.set(n, r);
173
440
  }
174
- function nt(t) {
175
- const e = y(null), [n, s] = d(!1), [o, r] = d(!1), c = y(0);
176
- F(() => {
177
- const l = new tt(t);
178
- return e.current = l, l.init().then(() => s(!0)).catch((w) => {
179
- console.warn("Stockfish failed to load:", w.message);
180
- }), () => {
181
- l.destroy(), e.current = null;
441
+ const Qt = 2e3, et = 45e3;
442
+ function Jt(t) {
443
+ const e = w(null), [n, r] = k("loading"), [o, i] = k(!1), a = w(0);
444
+ O(() => {
445
+ const y = Kt(t);
446
+ e.current = y;
447
+ let g = !1, _ = null;
448
+ r("loading");
449
+ const d = (v) => {
450
+ y.init().then(() => {
451
+ g || r("ready");
452
+ }).catch((C) => {
453
+ g || (console.warn(`Stockfish failed to load (attempt ${v}/${ut}):`, C.message), y.isUnavailable ? r("failed") : _ = setTimeout(() => d(v + 1), Qt));
454
+ });
182
455
  };
183
- }, []);
184
- const i = N(
185
- async (l, w) => {
186
- if (!e.current || !n) return null;
187
- const f = ++c.current;
188
- r(!0);
189
- const _ = setTimeout(() => {
190
- c.current === f && (console.warn("[ChaosChess] Safety timeout: clearing isThinking after 15s"), r(!1));
191
- }, 15e3);
456
+ return d(1), () => {
457
+ g = !0, _ && clearTimeout(_), Xt(y, t), e.current = null;
458
+ };
459
+ }, [t]);
460
+ const s = n === "ready", c = S(
461
+ async (y, g) => {
462
+ if (!e.current || !s) return null;
463
+ const _ = ++a.current;
464
+ i(!0);
465
+ const d = setTimeout(() => {
466
+ a.current === _ && (console.warn(`[ChaosChess] Safety timeout: clearing isThinking after ${et / 1e3}s`), i(!1));
467
+ }, et);
192
468
  try {
193
- return await e.current.getBestMove(l, w);
469
+ return await e.current.getBestMove(y, g);
470
+ } catch (v) {
471
+ throw v instanceof Ae && r("failed"), v;
194
472
  } finally {
195
- clearTimeout(_), c.current === f && r(!1);
473
+ clearTimeout(d), a.current === _ && i(!1);
196
474
  }
197
475
  },
198
- [n]
199
- );
200
- return { isReady: n, isThinking: o, getBestMove: i };
476
+ [s]
477
+ ), m = S(() => {
478
+ e.current?.cancel();
479
+ }, []);
480
+ return { status: n, isReady: s, isThinking: o, getBestMove: c, cancel: m };
201
481
  }
202
- const st = {
203
- p: 1,
204
- n: 3,
205
- b: 3,
206
- r: 5,
207
- q: 9,
208
- k: 0
209
- }, ie = {
210
- wk: "♚︎",
211
- wq: "♛︎",
212
- wr: "♜︎",
213
- wb: "♝︎",
214
- wn: "♞︎",
215
- wp: "♟︎",
216
- bk: "♔︎",
217
- bq: "♕︎",
218
- br: "♖︎",
219
- bb: "♗︎",
220
- bn: "♘︎",
221
- bp: "♙︎"
222
- }, fe = "abcdefgh";
223
- function X(t) {
224
- const e = t.split(" ");
225
- return {
226
- position: e[0],
227
- activeColor: e[1],
228
- castling: e[2],
229
- enPassant: e[3],
230
- halfmove: e[4],
231
- fullmove: e[5]
232
- };
482
+ const Zt = ["p", "n", "b", "r", "q"], ht = 10, ft = 16, pt = 8;
483
+ function en(t, e) {
484
+ return t > e ? Math.random() < 0.7 ? "help_black" : "help_white" : e > t ? Math.random() < 0.7 ? "help_white" : "help_black" : Math.random() < 0.5 ? "help_white" : "help_black";
233
485
  }
234
- function J(t) {
235
- const e = [], n = t.split("/");
236
- for (const s of n) {
237
- const o = [];
238
- for (const r of s) {
239
- const c = parseInt(r);
240
- if (isNaN(c)) {
241
- const i = r === r.toUpperCase() ? "w" : "b", l = r.toLowerCase();
242
- o.push({ type: l, color: i });
243
- } else
244
- for (let i = 0; i < c; i++) o.push(null);
245
- }
246
- e.push(o);
486
+ function Ee(t) {
487
+ return t[Math.floor(Math.random() * t.length)];
488
+ }
489
+ function tn(t) {
490
+ const e = [...t];
491
+ for (let n = e.length - 1; n > 0; n--) {
492
+ const r = Math.floor(Math.random() * (n + 1));
493
+ [e[n], e[r]] = [e[r], e[n]];
247
494
  }
248
495
  return e;
249
496
  }
250
- function Ne(t) {
251
- return t.map((e) => {
252
- let n = "", s = 0;
253
- for (const o of e)
254
- if (o === null)
255
- s++;
256
- else {
257
- s > 0 && (n += s, s = 0);
258
- const r = o.color === "w" ? o.type.toUpperCase() : o.type;
259
- n += r;
260
- }
261
- return s > 0 && (n += s), n;
262
- }).join("/");
497
+ function nn(t, e) {
498
+ const n = parseInt(t[1]);
499
+ return Ee(!e || n === 1 || n === 8 ? ["n", "b", "r", "q"] : Zt);
263
500
  }
264
- function Re(t) {
265
- return `${t.position} ${t.activeColor} ${t.castling} ${t.enPassant} ${t.halfmove} ${t.fullmove}`;
501
+ function rn(t, e) {
502
+ const n = K(Y(t).position);
503
+ let r = 0, o = 0;
504
+ for (const i of n)
505
+ for (const a of i)
506
+ a && a.color === e && (r++, a.type === "p" && o++);
507
+ return { total: r, pawns: o };
266
508
  }
267
- function rt(t) {
268
- const { position: e } = X(t), n = J(e);
269
- let s = 0, o = 0;
270
- for (const r of n)
271
- for (const c of r)
272
- if (c) {
273
- const i = st[c.type];
274
- c.color === "w" ? s += i : o += i;
275
- }
276
- return { white: s, black: o };
277
- }
278
- function ot(t) {
279
- const { position: e } = X(t), n = J(e), s = [];
280
- for (let o = 0; o < 8; o++)
281
- for (let r = 0; r < 8; r++)
282
- n[o][r] === null && s.push(`${fe[r]}${8 - o}`);
283
- return s;
284
- }
285
- function it(t, e, n = !0) {
286
- const { position: s } = X(t), o = J(s), r = [];
287
- for (let c = 0; c < 8; c++)
288
- for (let i = 0; i < 8; i++) {
289
- const l = o[c][i];
290
- if (l && l.color === e) {
291
- if (n && l.type === "k") continue;
292
- r.push(`${fe[i]}${8 - c}`);
293
- }
294
- }
295
- return r;
296
- }
297
- function Ie(t) {
298
- const e = fe.indexOf(t[0]);
299
- return [8 - parseInt(t[1]), e];
300
- }
301
- function at(t, e, n, s) {
302
- const o = X(t), r = J(o.position), [c, i] = Ie(e);
303
- return r[c][i] = { type: n, color: s }, o.position = Ne(r), Re(o);
304
- }
305
- function ct(t, e) {
306
- const n = X(t), s = J(n.position), [o, r] = Ie(e);
307
- return s[o][r] = null, n.position = Ne(s), Re(n);
308
- }
309
- const lt = ["p", "n", "b", "r", "q"], qe = 3;
310
- function ut(t, e) {
311
- return t > e ? Math.random() < 0.7 ? "help_black" : "help_white" : e > t ? Math.random() < 0.7 ? "help_white" : "help_black" : Math.random() < 0.5 ? "help_white" : "help_black";
312
- }
313
- function ae(t) {
314
- return t[Math.floor(Math.random() * t.length)];
315
- }
316
- function dt(t) {
317
- const e = parseInt(t[1]);
318
- return ae(e === 1 || e === 8 ? ["n", "b", "r", "q"] : lt);
319
- }
320
- function Fe(t) {
509
+ function he(t) {
510
+ let e;
321
511
  try {
322
- return new oe().load(t), !0;
512
+ e = new de(t);
323
513
  } catch {
324
514
  return !1;
325
515
  }
516
+ const { position: n, activeColor: r, castling: o, enPassant: i } = Y(t), a = K(n), s = { w: 0, b: 0 }, c = { w: 0, b: 0 }, m = { w: [], b: [] };
517
+ for (let g = 0; g < 8; g++)
518
+ for (let _ = 0; _ < 8; _++) {
519
+ const d = a[g][_];
520
+ if (d) {
521
+ if (s[d.color]++, d.type === "p") {
522
+ if (g === 0 || g === 7) return !1;
523
+ c[d.color]++;
524
+ }
525
+ d.type === "k" && m[d.color].push(`${"abcdefgh"[_]}${8 - g}`);
526
+ }
527
+ }
528
+ for (const g of ["w", "b"])
529
+ if (m[g].length !== 1 || s[g] > ft || c[g] > pt) return !1;
530
+ if (ct(o, a) !== o || lt(i, r, a) !== i) return !1;
531
+ const y = e.turn() === "w" ? "b" : "w";
532
+ return !e.isAttacked(m[y][0], e.turn());
326
533
  }
327
- function Se(t, e) {
328
- const n = ot(t);
534
+ function tt(t, e) {
535
+ const n = qt(t);
329
536
  if (n.length === 0) return null;
330
- for (let s = 0; s < qe; s++) {
331
- const o = ae(n), r = dt(o), c = at(t, o, r, e);
332
- if (Fe(c))
333
- return { newFen: c, square: o, piece: r };
537
+ const { total: r, pawns: o } = rn(t, e);
538
+ if (r >= ft) return null;
539
+ const i = o < pt;
540
+ for (let a = 0; a < ht; a++) {
541
+ const s = Ee(n), c = nn(s, i), m = jt(t, s, c, e);
542
+ if (he(m))
543
+ return { newFen: m, square: s, piece: c };
334
544
  }
335
545
  return null;
336
546
  }
337
- function Be(t, e) {
338
- const n = it(t, e, !0);
547
+ function nt(t, e) {
548
+ const n = Ft(t, e, !0);
339
549
  if (n.length === 0) return null;
340
- for (let s = 0; s < qe; s++) {
341
- const o = ae(n), r = ct(t, o);
342
- if (Fe(r))
343
- return { newFen: r, square: o };
550
+ for (const r of tn(n).slice(0, ht)) {
551
+ const o = xt(t, r);
552
+ if (he(o))
553
+ return { newFen: o, square: r };
344
554
  }
345
555
  return null;
346
556
  }
347
- function ht(t) {
348
- const { white: e, black: n } = rt(t), s = ut(e, n), o = Math.random() < 0.5 ? "add" : "remove", r = s === "help_white" ? "w" : "b", c = s === "help_white" ? "b" : "w";
557
+ function on(t) {
558
+ const { white: e, black: n } = It(t), r = en(e, n), o = Math.random() < 0.5 ? "add" : "remove", i = r === "help_white" ? "w" : "b", a = r === "help_white" ? "b" : "w";
349
559
  if (o === "add") {
350
- const i = Se(t, r);
351
- if (i)
560
+ const s = tt(t, i);
561
+ if (s)
352
562
  return {
353
- newFen: i.newFen,
563
+ newFen: s.newFen,
354
564
  action: {
355
565
  type: "add",
356
- target: s,
357
- square: i.square,
358
- piece: i.piece,
359
- color: r,
566
+ target: r,
567
+ square: s.square,
568
+ piece: s.piece,
569
+ color: i,
360
570
  whiteMaterial: e,
361
571
  blackMaterial: n
362
572
  }
363
573
  };
364
- const l = Be(t, c);
365
- if (l)
574
+ const c = nt(t, a);
575
+ if (c)
366
576
  return {
367
- newFen: l.newFen,
577
+ newFen: c.newFen,
368
578
  action: {
369
579
  type: "remove",
370
- target: s,
371
- square: l.square,
580
+ target: r,
581
+ square: c.square,
372
582
  whiteMaterial: e,
373
583
  blackMaterial: n
374
584
  }
375
585
  };
376
586
  } else {
377
- const i = Be(t, c);
378
- if (i)
587
+ const s = nt(t, a);
588
+ if (s)
379
589
  return {
380
- newFen: i.newFen,
590
+ newFen: s.newFen,
381
591
  action: {
382
592
  type: "remove",
383
- target: s,
384
- square: i.square,
593
+ target: r,
594
+ square: s.square,
385
595
  whiteMaterial: e,
386
596
  blackMaterial: n
387
597
  }
388
598
  };
389
- const l = Se(t, r);
390
- if (l)
599
+ const c = tt(t, i);
600
+ if (c)
391
601
  return {
392
- newFen: l.newFen,
602
+ newFen: c.newFen,
393
603
  action: {
394
604
  type: "add",
395
- target: s,
396
- square: l.square,
397
- piece: l.piece,
398
- color: r,
605
+ target: r,
606
+ square: c.square,
607
+ piece: c.piece,
608
+ color: i,
399
609
  whiteMaterial: e,
400
610
  blackMaterial: n
401
611
  }
@@ -403,7 +613,7 @@ function ht(t) {
403
613
  }
404
614
  return null;
405
615
  }
406
- const mt = [
616
+ const sn = [
407
617
  [12, 20],
408
618
  // level 1
409
619
  [8, 15],
@@ -415,267 +625,320 @@ const mt = [
415
625
  [1, 4]
416
626
  // level 5
417
627
  ];
418
- function pt(t = 3) {
419
- const e = Math.max(0, Math.min(4, t - 1)), [n, s] = mt[e];
420
- return (n + Math.random() * (s - n)) * 1e3;
628
+ function an(t = 3) {
629
+ const e = Number.isFinite(t) ? Math.round(t) : 3, n = Math.max(0, Math.min(4, e - 1)), [r, o] = sn[n];
630
+ return (r + Math.random() * (o - r)) * 1e3;
421
631
  }
422
- function ft({
632
+ const cn = 200, ln = 1e3;
633
+ function rt() {
634
+ return typeof document < "u" && document.visibilityState === "hidden";
635
+ }
636
+ function un({
423
637
  fen: t,
424
638
  isPaused: e,
425
639
  stupidLevel: n,
426
- onChaosAction: s
640
+ onChaosAction: r,
641
+ resetKey: o = 0
427
642
  }) {
428
- const [o, r] = d(0), [c, i] = d(0), [l, w] = d(null), [f, _] = d(null), P = y(t), g = y(e), v = y(n), k = y(s), R = y(0), $ = y(null);
429
- P.current = t, g.current = e, v.current = n, k.current = s;
430
- const I = N(() => {
431
- const b = pt(v.current), h = Math.ceil(b / 1e3);
432
- i(h), r(h), R.current = Date.now() + b;
643
+ const [i, a] = k(0), [s, c] = k(0), [m, y] = k(null), [g, _] = k(null), d = w(t), v = w(e), C = w(n), x = w(r), R = w(0), q = w(0), G = w(!1), B = w(!1);
644
+ d.current = t, v.current = e, C.current = n, x.current = r;
645
+ const $ = S(() => {
646
+ const p = an(C.current), M = Math.ceil(p / 1e3);
647
+ c(M), a(M), R.current = p;
433
648
  }, []);
434
- F(() => (I(), $.current = setInterval(() => {
435
- if (g.current) return;
436
- const b = Math.max(0, Math.ceil((R.current - Date.now()) / 1e3));
437
- if (r(b), b <= 0) {
438
- if (g.current) {
439
- I();
649
+ st(() => {
650
+ e && (G.current = !0);
651
+ }, [e]), O(() => {
652
+ $();
653
+ }, [n, $]);
654
+ const ne = w(!0);
655
+ return O(() => {
656
+ if (ne.current) {
657
+ ne.current = !1;
658
+ return;
659
+ }
660
+ y(null), _(null), $();
661
+ }, [o, $]), O(() => {
662
+ B.current = rt();
663
+ const p = () => {
664
+ B.current = rt(), q.current = Date.now(), B.current && (G.current = !0);
665
+ };
666
+ return document.addEventListener("visibilitychange", p), () => document.removeEventListener("visibilitychange", p);
667
+ }, []), O(() => {
668
+ q.current = Date.now();
669
+ let p = null;
670
+ const M = setInterval(() => {
671
+ const F = Date.now(), re = F - q.current;
672
+ if (q.current = F, v.current || B.current) {
673
+ G.current = !0;
440
674
  return;
441
675
  }
442
- const h = ht(P.current);
443
- h && (w(h.action), _(h.action.square), k.current(h.newFen), setTimeout(() => _(null), 600)), I();
444
- }
445
- }, 200), () => {
446
- $.current && clearInterval($.current);
447
- }), [I]);
448
- const x = y(null);
449
- return F(() => {
450
- if (e)
451
- x.current = Date.now();
452
- else if (x.current !== null) {
453
- const b = Date.now() - x.current;
454
- R.current += b, x.current = null;
455
- }
456
- }, [e]), { countdown: o, maxCountdown: c, lastAction: l, chaosSquare: f };
457
- }
458
- const vt = "_square_1tsnw_1", _t = "_light_1tsnw_14", gt = "_dark_1tsnw_18", kt = "_selected_1tsnw_22", yt = "_legalMove_1tsnw_26", wt = "_legalCapture_1tsnw_39", Ct = "_check_1tsnw_54", bt = "_lastMoveFrom_1tsnw_58", Tt = "_lastMoveTo_1tsnw_62", Lt = "_chaosFlash_1tsnw_66", Pt = "_piece_1tsnw_70", Mt = "_pieceWhite_1tsnw_78", St = "_pieceBlack_1tsnw_83", O = {
459
- square: vt,
460
- light: _t,
461
- dark: gt,
462
- selected: kt,
463
- legalMove: yt,
464
- legalCapture: wt,
465
- check: Ct,
466
- lastMoveFrom: bt,
467
- lastMoveTo: Tt,
468
- chaosFlash: Lt,
469
- piece: Pt,
470
- pieceWhite: Mt,
471
- pieceBlack: St
676
+ if (G.current) {
677
+ G.current = !1, R.current = Math.max(R.current, ln), a(Math.ceil(R.current / 1e3));
678
+ return;
679
+ }
680
+ if (R.current -= re, a(Math.max(0, Math.ceil(R.current / 1e3))), R.current > 0) return;
681
+ const I = on(d.current);
682
+ I && x.current(I.newFen) !== !1 && (y(I.action), _(I.action.square), p && clearTimeout(p), p = setTimeout(() => _(null), 600)), $();
683
+ }, cn);
684
+ return () => {
685
+ clearInterval(M), p && clearTimeout(p);
686
+ };
687
+ }, [$]), { countdown: i, maxCountdown: s, lastAction: m, chaosSquare: g };
688
+ }
689
+ const dn = {
690
+ wk: '<g style="stroke:var(--cc-pw-line)" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"><path stroke-linejoin="miter" d="M22.5 11.63V6M20 8h5"/><path style="fill:var(--cc-pw-body)" stroke-linecap="butt" stroke-linejoin="miter" d="M22.5 25s4.5-7.5 3-10.5c0 0-1-2.5-3-2.5s-3 2.5-3 2.5c-1.5 3 3 10.5 3 10.5"/><path style="fill:var(--cc-pw-body)" d="M12.5 37c5.5 3.5 14.5 3.5 20 0v-7s9-4.5 6-10.5c-4-6.5-13.5-3.5-16 4V27v-3.5c-2.5-7.5-12-10.5-16-4-3 6 6 10.5 6 10.5v7"/><path d="M12.5 30c5.5-3 14.5-3 20 0m-20 3.5c5.5-3 14.5-3 20 0m-20 3.5c5.5-3 14.5-3 20 0"/></g>',
691
+ wq: '<g style="fill:var(--cc-pw-body);stroke:var(--cc-pw-line)" stroke-width="1.5" stroke-linejoin="round"><path d="M 9,26 C 17.5,24.5 30,24.5 36,26 L 38.5,13.5 L 31,25 L 30.7,10.9 L 25.5,24.5 L 22.5,10 L 19.5,24.5 L 14.3,10.9 L 14,25 L 6.5,13.5 L 9,26 z"/><path d="M 9,26 C 9,28 10.5,28 11.5,30 C 12.5,31.5 12.5,31 12,33.5 C 10.5,34.5 11,36 11,36 C 9.5,37.5 11,38.5 11,38.5 C 17.5,39.5 27.5,39.5 34,38.5 C 34,38.5 35.5,37.5 34,36 C 34,36 34.5,34.5 33,33.5 C 32.5,31 32.5,31.5 33.5,30 C 34.5,28 36,28 36,26 C 27.5,24.5 17.5,24.5 9,26 z"/><path d="M 11.5,30 C 15,29 30,29 33.5,30" fill="none"/><path d="M 12,33.5 C 18,32.5 27,32.5 33,33.5" fill="none"/><circle cx="6" cy="12" r="2" /><circle cx="14" cy="9" r="2" /><circle cx="22.5" cy="8" r="2" /><circle cx="31" cy="9" r="2" /><circle cx="39" cy="12" r="2" /></g>',
692
+ wr: '<g style="fill:var(--cc-pw-body);stroke:var(--cc-pw-line)" fill-rule="evenodd" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" transform="translate(0,0.3)"><path d="M 9,39 L 36,39 L 36,36 L 9,36 L 9,39 z " stroke-linecap="butt" /><path d="M 12,36 L 12,32 L 33,32 L 33,36 L 12,36 z " stroke-linecap="butt" /><path d="M 11,14 L 11,9 L 15,9 L 15,11 L 20,11 L 20,9 L 25,9 L 25,11 L 30,11 L 30,9 L 34,9 L 34,14" stroke-linecap="butt" /><path d="M 34,14 L 31,17 L 14,17 L 11,14" /><path d="M 31,17 L 31,29.5 L 14,29.5 L 14,17" stroke-linecap="butt" stroke-linejoin="miter" /><path d="M 31,29.5 L 32.5,32 L 12.5,32 L 14,29.5" /><path style="stroke:var(--cc-pw-line)" d="M 11,14 L 34,14" fill="none" stroke-linejoin="miter" /></g>',
693
+ wb: '<g style="stroke:var(--cc-pw-line)" fill="none" fill-rule="evenodd" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" transform="translate(0,0.6)"><g style="fill:var(--cc-pw-body);stroke:var(--cc-pw-line)" stroke-linecap="butt"><path d="M 9,36 C 12.39,35.03 19.11,36.43 22.5,34 C 25.89,36.43 32.61,35.03 36,36 C 36,36 37.65,36.54 39,38 C 38.32,38.97 37.35,38.99 36,38.5 C 32.61,37.53 25.89,38.96 22.5,37.5 C 19.11,38.96 12.39,37.53 9,38.5 C 7.65,38.99 6.68,38.97 6,38 C 7.35,36.54 9,36 9,36 z"/><path d="M 15,32 C 17.5,34.5 27.5,34.5 30,32 C 30.5,30.5 30,30 30,30 C 30,27.5 27.5,26 27.5,26 C 33,24.5 33.5,14.5 22.5,10.5 C 11.5,14.5 12,24.5 17.5,26 C 17.5,26 15,27.5 15,30 C 15,30 14.5,30.5 15,32 z"/><path d="M 25 8 A 2.5 2.5 0 1 1 20,8 A 2.5 2.5 0 1 1 25 8 z"/></g><path style="stroke:var(--cc-pw-line)" d="M 17.5,26 L 27.5,26 M 15,30 L 30,30 M 22.5,15.5 L 22.5,20.5 M 20,18 L 25,18" fill="none" stroke-linejoin="miter"/></g>',
694
+ wn: '<g style="stroke:var(--cc-pw-line)" fill="none" fill-rule="evenodd" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" transform="translate(0,0.3)"><path style="fill:var(--cc-pw-body);stroke:var(--cc-pw-line)" d="M 22,10 C 32.5,11 38.5,18 38,39 L 15,39 C 15,30 25,32.5 23,18" /><path style="fill:var(--cc-pw-body);stroke:var(--cc-pw-line)" d="M 24,18 C 24.38,20.91 18.45,25.37 16,27 C 13,29 13.18,31.34 11,31 C 9.958,30.06 12.41,27.96 11,28 C 10,28 11.19,29.23 10,30 C 9,30 5.997,31 6,26 C 6,24 12,14 12,14 C 12,14 13.89,12.1 14,10.5 C 13.27,9.506 13.5,8.5 13.5,7.5 C 14.5,6.5 16.5,10 16.5,10 L 18.5,10 C 18.5,10 19.28,8.008 21,7 C 22,7 22,10 22,10" /><path style="fill:var(--cc-pw-line);stroke:var(--cc-pw-line)" d="M 9.5 25.5 A 0.5 0.5 0 1 1 8.5,25.5 A 0.5 0.5 0 1 1 9.5 25.5 z" /><path style="fill:var(--cc-pw-line);stroke:var(--cc-pw-line)" d="M 15 15.5 A 0.5 1.5 0 1 1 14,15.5 A 0.5 1.5 0 1 1 15 15.5 z" transform="matrix(0.866,0.5,-0.5,0.866,9.693,-5.173)" /></g>',
695
+ wp: '<path style="fill:var(--cc-pw-body);stroke:var(--cc-pw-line)" d="m 22.5,9 c -2.21,0 -4,1.79 -4,4 0,0.89 0.29,1.71 0.78,2.38 C 17.33,16.5 16,18.59 16,21 c 0,2.03 0.94,3.84 2.41,5.03 C 15.41,27.09 11,31.58 11,39.5 H 34 C 34,31.58 29.59,27.09 26.59,26.03 28.06,24.84 29,23.03 29,21 29,18.59 27.67,16.5 25.72,15.38 26.21,14.71 26.5,13.89 26.5,13 c 0,-2.21 -1.79,-4 -4,-4 z" fill-rule="nonzero" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="miter"/>',
696
+ bk: '<g style="stroke:var(--cc-pb-line)" fill="none" fill-rule="evenodd" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path style="stroke:var(--cc-pb-line)" d="M 22.5,11.63 L 22.5,6" fill="none" stroke-linejoin="miter" id="path6570"/><path style="fill:var(--cc-pb-body)" d="M 22.5,25 C 22.5,25 27,17.5 25.5,14.5 C 25.5,14.5 24.5,12 22.5,12 C 20.5,12 19.5,14.5 19.5,14.5 C 18,17.5 22.5,25 22.5,25" stroke-linecap="butt" stroke-linejoin="miter"/><path style="fill:var(--cc-pb-body);stroke:var(--cc-pb-line)" d="M 12.5,37 C 18,40.5 27,40.5 32.5,37 L 32.5,30 C 32.5,30 41.5,25.5 38.5,19.5 C 34.5,13 25,16 22.5,23.5 L 22.5,27 L 22.5,23.5 C 20,16 10.5,13 6.5,19.5 C 3.5,25.5 12.5,30 12.5,30 L 12.5,37"/><path style="stroke:var(--cc-pb-line)" d="M 20,8 L 25,8" fill="none" stroke-linejoin="miter"/><path style="stroke:var(--cc-pb-detail)" d="M 32,29.5 C 32,29.5 40.5,25.5 38.03,19.85 C 34.15,14 25,18 22.5,24.5 L 22.5,26.6 L 22.5,24.5 C 20,18 10.85,14 6.97,19.85 C 4.5,25.5 13,29.5 13,29.5" fill="none"/><path style="stroke:var(--cc-pb-detail)" d="M 12.5,30 C 18,27 27,27 32.5,30 M 12.5,33.5 C 18,30.5 27,30.5 32.5,33.5 M 12.5,37 C 18,34 27,34 32.5,37" fill="none"/></g>',
697
+ bq: '<g style="fill:var(--cc-pb-body);stroke:var(--cc-pb-line)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path style="fill:var(--cc-pb-body)" d="M 9,26 C 17.5,24.5 30,24.5 36,26 L 38.5,13.5 L 31,25 L 30.7,10.9 L 25.5,24.5 L 22.5,10 L 19.5,24.5 L 14.3,10.9 L 14,25 L 6.5,13.5 L 9,26 z" stroke-linecap="butt" /><path d="m 9,26 c 0,2 1.5,2 2.5,4 1,1.5 1,1 0.5,3.5 -1.5,1 -1,2.5 -1,2.5 -1.5,1.5 0,2.5 0,2.5 6.5,1 16.5,1 23,0 0,0 1.5,-1 0,-2.5 0,0 0.5,-1.5 -1,-2.5 -0.5,-2.5 -0.5,-2 0.5,-3.5 1,-2 2.5,-2 2.5,-4 -8.5,-1.5 -18.5,-1.5 -27,0 z" /><path d="M 11.5,30 C 15,29 30,29 33.5,30" /><path d="m 12,33.5 c 6,-1 15,-1 21,0" /><circle cx="6" cy="12" r="2" /><circle cx="14" cy="9" r="2" /><circle cx="22.5" cy="8" r="2" /><circle cx="31" cy="9" r="2" /><circle cx="39" cy="12" r="2" /><path style="stroke:var(--cc-pb-line)" d="M 11,38.5 A 35,35 1 0 0 34,38.5" fill="none" stroke-linecap="butt" /><g style="stroke:var(--cc-pb-detail)" fill="none"><path d="M 11,29 A 35,35 1 0 1 34,29" /><path d="M 12.5,31.5 L 32.5,31.5" /><path d="M 11.5,34.5 A 35,35 1 0 0 33.5,34.5" /><path d="M 10.5,37.5 A 35,35 1 0 0 34.5,37.5" /></g></g>',
698
+ br: '<g style="fill:var(--cc-pb-body);stroke:var(--cc-pb-line)" fill-rule="evenodd" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" transform="translate(0,0.3)"><path d="M 9,39 L 36,39 L 36,36 L 9,36 L 9,39 z " stroke-linecap="butt" /><path d="M 12.5,32 L 14,29.5 L 31,29.5 L 32.5,32 L 12.5,32 z " stroke-linecap="butt" /><path d="M 12,36 L 12,32 L 33,32 L 33,36 L 12,36 z " stroke-linecap="butt" /><path d="M 14,29.5 L 14,16.5 L 31,16.5 L 31,29.5 L 14,29.5 z " stroke-linecap="butt" stroke-linejoin="miter" /><path d="M 14,16.5 L 11,14 L 34,14 L 31,16.5 L 14,16.5 z " stroke-linecap="butt" /><path d="M 11,14 L 11,9 L 15,9 L 15,11 L 20,11 L 20,9 L 25,9 L 25,11 L 30,11 L 30,9 L 34,9 L 34,14 L 11,14 z " stroke-linecap="butt" /><path style="stroke:var(--cc-pb-detail)" d="M 12,35.5 L 33,35.5 L 33,35.5" fill="none" stroke-width="1" stroke-linejoin="miter" /><path style="stroke:var(--cc-pb-detail)" d="M 13,31.5 L 32,31.5" fill="none" stroke-width="1" stroke-linejoin="miter" /><path style="stroke:var(--cc-pb-detail)" d="M 14,29.5 L 31,29.5" fill="none" stroke-width="1" stroke-linejoin="miter" /><path style="stroke:var(--cc-pb-detail)" d="M 14,16.5 L 31,16.5" fill="none" stroke-width="1" stroke-linejoin="miter" /><path style="stroke:var(--cc-pb-detail)" d="M 11,14 L 34,14" fill="none" stroke-width="1" stroke-linejoin="miter" /></g>',
699
+ bb: '<g style="stroke:var(--cc-pb-line)" fill="none" fill-rule="evenodd" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" transform="translate(0,0.6)"><g style="fill:var(--cc-pb-body);stroke:var(--cc-pb-line)" stroke-linecap="butt"><path d="M 9,36 C 12.39,35.03 19.11,36.43 22.5,34 C 25.89,36.43 32.61,35.03 36,36 C 36,36 37.65,36.54 39,38 C 38.32,38.97 37.35,38.99 36,38.5 C 32.61,37.53 25.89,38.96 22.5,37.5 C 19.11,38.96 12.39,37.53 9,38.5 C 7.65,38.99 6.68,38.97 6,38 C 7.35,36.54 9,36 9,36 z"/><path d="M 15,32 C 17.5,34.5 27.5,34.5 30,32 C 30.5,30.5 30,30 30,30 C 30,27.5 27.5,26 27.5,26 C 33,24.5 33.5,14.5 22.5,10.5 C 11.5,14.5 12,24.5 17.5,26 C 17.5,26 15,27.5 15,30 C 15,30 14.5,30.5 15,32 z"/><path d="M 25 8 A 2.5 2.5 0 1 1 20,8 A 2.5 2.5 0 1 1 25 8 z"/></g><path style="stroke:var(--cc-pb-detail)" d="M 17.5,26 L 27.5,26 M 15,30 L 30,30 M 22.5,15.5 L 22.5,20.5 M 20,18 L 25,18" fill="none" stroke-linejoin="miter"/></g>',
700
+ bn: '<g style="stroke:var(--cc-pb-line)" fill="none" fill-rule="evenodd" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" transform="translate(0,0.3)"><path style="fill:var(--cc-pb-body);stroke:var(--cc-pb-line)" d="M 22,10 C 32.5,11 38.5,18 38,39 L 15,39 C 15,30 25,32.5 23,18" /><path style="fill:var(--cc-pb-body);stroke:var(--cc-pb-line)" d="M 24,18 C 24.38,20.91 18.45,25.37 16,27 C 13,29 13.18,31.34 11,31 C 9.958,30.06 12.41,27.96 11,28 C 10,28 11.19,29.23 10,30 C 9,30 5.997,31 6,26 C 6,24 12,14 12,14 C 12,14 13.89,12.1 14,10.5 C 13.27,9.506 13.5,8.5 13.5,7.5 C 14.5,6.5 16.5,10 16.5,10 L 18.5,10 C 18.5,10 19.28,8.008 21,7 C 22,7 22,10 22,10" /><path style="fill:var(--cc-pb-detail);stroke:var(--cc-pb-detail)" d="M 9.5 25.5 A 0.5 0.5 0 1 1 8.5,25.5 A 0.5 0.5 0 1 1 9.5 25.5 z" /><path style="fill:var(--cc-pb-detail);stroke:var(--cc-pb-detail)" d="M 15 15.5 A 0.5 1.5 0 1 1 14,15.5 A 0.5 1.5 0 1 1 15 15.5 z" transform="matrix(0.866,0.5,-0.5,0.866,9.693,-5.173)" /><path style="fill:var(--cc-pb-detail)" d="M 24.55,10.4 L 24.1,11.85 L 24.6,12 C 27.75,13 30.25,14.49 32.5,18.75 C 34.75,23.01 35.75,29.06 35.25,39 L 35.2,39.5 L 37.45,39.5 L 37.5,39 C 38,28.94 36.62,22.15 34.25,17.66 C 31.88,13.17 28.46,11.02 25.06,10.5 L 24.55,10.4 z " stroke="none" /></g>',
701
+ bp: '<path style="fill:var(--cc-pb-body);stroke:var(--cc-pb-line)" d="m 22.5,9 c -2.21,0 -4,1.79 -4,4 0,0.89 0.29,1.71 0.78,2.38 C 17.33,16.5 16,18.59 16,21 c 0,2.03 0.94,3.84 2.41,5.03 C 15.41,27.09 11,31.58 11,39.5 H 34 C 34,31.58 29.59,27.09 26.59,26.03 28.06,24.84 29,23.03 29,21 29,18.59 27.67,16.5 25.72,15.38 26.21,14.71 26.5,13.89 26.5,13 c 0,-2.21 -1.79,-4 -4,-4 z" fill-rule="nonzero" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="miter"/>'
702
+ }, hn = "_square_u4pju_1", fn = "_light_u4pju_15", pn = "_dark_u4pju_20", mn = "_selected_u4pju_26", vn = "_check_u4pju_27", kn = "_lastMoveFrom_u4pju_28", gn = "_lastMoveTo_u4pju_29", yn = "_legalMove_u4pju_37", _n = "_legalCapture_u4pju_50", wn = "_chaosFlash_u4pju_77", Cn = "_pieceArt_u4pju_82", bn = "_piece_u4pju_82", Ln = "_pieceWhite_u4pju_96", Mn = "_pieceBlack_u4pju_97", E = {
703
+ square: hn,
704
+ light: fn,
705
+ dark: pn,
706
+ selected: mn,
707
+ check: vn,
708
+ lastMoveFrom: kn,
709
+ lastMoveTo: gn,
710
+ legalMove: yn,
711
+ legalCapture: _n,
712
+ chaosFlash: wn,
713
+ pieceArt: Cn,
714
+ piece: bn,
715
+ pieceWhite: Ln,
716
+ pieceBlack: Mn
717
+ }, Sn = {
718
+ k: "king",
719
+ q: "queen",
720
+ r: "rook",
721
+ b: "bishop",
722
+ n: "knight",
723
+ p: "pawn"
472
724
  };
473
- function De({ type: t, color: e, className: n }) {
474
- const s = `${e}${t}`, o = ie[s];
475
- if (!o) return null;
476
- const r = e === "w" ? O.pieceWhite : O.pieceBlack;
477
- return /* @__PURE__ */ a("span", { className: `${n ?? ""} ${r}`, children: o });
478
- }
479
- const Bt = "_board_1jwdv_1", Ot = "_rankLabel_1jwdv_13", Nt = "_fileLabel_1jwdv_24", Rt = "_boardLocked_1jwdv_35", ce = {
480
- board: Bt,
481
- rankLabel: Ot,
482
- fileLabel: Nt,
483
- boardLocked: Rt
725
+ function mt(t, e) {
726
+ return `${e === "w" ? "white" : "black"} ${Sn[t]}`;
727
+ }
728
+ function we({ type: t, color: e, className: n }) {
729
+ const r = dn[`${e}${t}`];
730
+ if (!r) return null;
731
+ const o = e === "w" ? E.pieceWhite : E.pieceBlack;
732
+ return /* @__PURE__ */ l(
733
+ "svg",
734
+ {
735
+ viewBox: "0 0 45 45",
736
+ role: "img",
737
+ "aria-label": mt(t, e),
738
+ className: `${E.pieceArt} ${n ?? ""} ${o}`,
739
+ dangerouslySetInnerHTML: { __html: r }
740
+ }
741
+ );
742
+ }
743
+ const Tn = "_board_8cqhv_1", Pn = "_rankLabel_8cqhv_16", Bn = "_fileLabel_8cqhv_28", On = "_boardLocked_8cqhv_40", Ce = {
744
+ board: Tn,
745
+ rankLabel: Pn,
746
+ fileLabel: Bn,
747
+ boardLocked: On
484
748
  };
485
- function It({
749
+ function Rn({
486
750
  square: t,
487
751
  piece: e,
488
752
  isLight: n,
489
- isSelected: s,
753
+ isSelected: r,
490
754
  isLegalMove: o,
491
- isCheck: r,
492
- isLastMoveFrom: c,
493
- isLastMoveTo: i,
494
- isChaosFlash: l,
495
- rankLabel: w,
496
- fileLabel: f,
497
- onClick: _
755
+ isCheck: i,
756
+ isLastMoveFrom: a,
757
+ isLastMoveTo: s,
758
+ isChaosFlash: c,
759
+ rankLabel: m,
760
+ fileLabel: y,
761
+ onClick: g
498
762
  }) {
499
- const P = [
500
- O.square,
501
- n ? O.light : O.dark,
502
- s && O.selected,
503
- o && (e ? O.legalCapture : O.legalMove),
504
- r && O.check,
505
- !s && !r && c && O.lastMoveFrom,
506
- !s && !r && i && O.lastMoveTo,
507
- l && O.chaosFlash
763
+ const _ = [
764
+ E.square,
765
+ n ? E.light : E.dark,
766
+ r && E.selected,
767
+ o && (e ? E.legalCapture : E.legalMove),
768
+ i && E.check,
769
+ !r && !i && a && E.lastMoveFrom,
770
+ !r && !i && s && E.lastMoveTo,
771
+ c && E.chaosFlash
508
772
  ].filter(Boolean).join(" ");
509
- return /* @__PURE__ */ C("div", { className: P, onClick: () => _(t), children: [
510
- e && /* @__PURE__ */ a(
511
- De,
773
+ return /* @__PURE__ */ L("div", { className: _, onClick: () => g(t), children: [
774
+ e && /* @__PURE__ */ l(
775
+ we,
512
776
  {
513
777
  type: e.type,
514
778
  color: e.color,
515
- className: O.piece
779
+ className: E.piece
516
780
  }
517
781
  ),
518
- w != null && /* @__PURE__ */ a("span", { className: ce.rankLabel, children: w }),
519
- f != null && /* @__PURE__ */ a("span", { className: ce.fileLabel, children: f })
782
+ m != null && /* @__PURE__ */ l("span", { className: Ce.rankLabel, children: m }),
783
+ y != null && /* @__PURE__ */ l("span", { className: Ce.fileLabel, children: y })
520
784
  ] });
521
785
  }
522
- const $e = "abcdefgh";
523
- function Oe(t, e) {
524
- return `${$e[e]}${8 - t}`;
786
+ const vt = "abcdefgh";
787
+ function ot(t, e) {
788
+ return `${vt[e]}${8 - t}`;
525
789
  }
526
- function qt(t, e) {
790
+ function Nn(t, e) {
527
791
  return (t + e) % 2 === 0;
528
792
  }
529
- const Ft = Ze.memo(function({
793
+ const An = At.memo(function({
530
794
  board: e,
531
795
  selectedSquare: n,
532
- legalMoves: s,
796
+ legalMoves: r,
533
797
  inCheck: o,
534
- lastMove: r,
535
- chaosSquare: c,
536
- flipped: i,
537
- locked: l,
538
- onSquareClick: w
798
+ lastMove: i,
799
+ chaosSquare: a,
800
+ flipped: s,
801
+ locked: c,
802
+ onSquareClick: m
539
803
  }) {
540
- let f = null;
804
+ let y = null;
541
805
  if (o)
542
- for (let g = 0; g < 8; g++)
806
+ for (let d = 0; d < 8; d++)
543
807
  for (let v = 0; v < 8; v++) {
544
- const k = e[g][v];
545
- k?.type === "k" && k.color === o && (f = Oe(g, v));
808
+ const C = e[d][v];
809
+ C?.type === "k" && C.color === o && (y = ot(d, v));
546
810
  }
547
- const _ = i ? [7, 6, 5, 4, 3, 2, 1, 0] : [0, 1, 2, 3, 4, 5, 6, 7], P = i ? [7, 6, 5, 4, 3, 2, 1, 0] : [0, 1, 2, 3, 4, 5, 6, 7];
548
- return /* @__PURE__ */ a("div", { className: `${ce.board}${l ? ` ${ce.boardLocked}` : ""}`, children: _.map(
549
- (g) => P.map((v) => {
550
- const k = Oe(g, v), R = e[g][v], $ = _.indexOf(g), I = P.indexOf(v);
551
- return /* @__PURE__ */ a(
552
- It,
811
+ const g = s ? [7, 6, 5, 4, 3, 2, 1, 0] : [0, 1, 2, 3, 4, 5, 6, 7], _ = s ? [7, 6, 5, 4, 3, 2, 1, 0] : [0, 1, 2, 3, 4, 5, 6, 7];
812
+ return /* @__PURE__ */ l("div", { className: `${Ce.board}${c ? ` ${Ce.boardLocked}` : ""}`, children: g.map(
813
+ (d) => _.map((v) => {
814
+ const C = ot(d, v), x = e[d][v], R = g.indexOf(d), q = _.indexOf(v);
815
+ return /* @__PURE__ */ l(
816
+ Rn,
553
817
  {
554
- square: k,
555
- piece: R,
556
- isLight: qt(g, v),
557
- isSelected: k === n,
558
- isLegalMove: s.includes(k),
559
- isCheck: k === f,
560
- isLastMoveFrom: r?.from === k,
561
- isLastMoveTo: r?.to === k,
562
- isChaosFlash: c === k,
563
- rankLabel: I === 0 ? 8 - g : void 0,
564
- fileLabel: $ === 7 ? $e[v] : void 0,
565
- onClick: w
818
+ square: C,
819
+ piece: x,
820
+ isLight: Nn(d, v),
821
+ isSelected: C === n,
822
+ isLegalMove: r.includes(C),
823
+ isCheck: C === y,
824
+ isLastMoveFrom: i?.from === C,
825
+ isLastMoveTo: i?.to === C,
826
+ isChaosFlash: a === C,
827
+ rankLabel: q === 0 ? 8 - d : void 0,
828
+ fileLabel: R === 7 ? vt[v] : void 0,
829
+ onClick: m
566
830
  },
567
- k
831
+ C
568
832
  );
569
833
  })
570
834
  ) });
571
- }), Dt = "_promotionOverlay_1p5vy_2", $t = "_promotionDialog_1p5vy_14", xt = "_promotionTitle_1p5vy_27", Gt = "_promotionOptions_1p5vy_34", At = "_promotionBtn_1p5vy_39", Et = "_gameOverOverlay_1p5vy_61", Vt = "_gameOverBanner_1p5vy_73", jt = "_gameOverResult_1p5vy_86", Wt = "_gameOverDetail_1p5vy_95", Ht = "_restartBtn_1p5vy_102", Ut = "_chaosBar_1p5vy_121", Yt = "_chaosBarLabel_1p5vy_129", zt = "_chaosBarTrack_1p5vy_138", Qt = "_chaosBarFill_1p5vy_146", Kt = "_difficultySelector_1p5vy_155", Xt = "_difficultyLabel_1p5vy_162", Jt = "_difficultySlider_1p5vy_168", Zt = "_difficultyValue_1p5vy_199", en = "_sidePickerOverlay_1p5vy_206", tn = "_sidePickerCard_1p5vy_214", nn = "_sidePickerTitle_1p5vy_227", sn = "_sidePickerOptions_1p5vy_235", rn = "_sidePickerBtn_1p5vy_240", on = "_sidePickerIcon_1p5vy_260", an = "_sidePickerWhite_1p5vy_265", cn = "_sidePickerBlack_1p5vy_270", ln = "_sidePickerLabel_1p5vy_275", un = "_sidePickerSettings_1p5vy_282", dn = "_stupidLevel_1p5vy_291", hn = "_stupidLevelHeader_1p5vy_298", mn = "_stupidLevelLabel_1p5vy_304", pn = "_stupidLevelValue_1p5vy_312", fn = "_stupidLevelSlider_1p5vy_319", vn = "_muteBtn_1p5vy_351", _n = "_muteBtnMuted_1p5vy_371", gn = "_chaosToast_1p5vy_381", kn = "_chaosToastFading_1p5vy_401", u = {
572
- promotionOverlay: Dt,
573
- promotionDialog: $t,
574
- promotionTitle: xt,
575
- promotionOptions: Gt,
576
- promotionBtn: At,
577
- gameOverOverlay: Et,
578
- gameOverBanner: Vt,
579
- gameOverResult: jt,
580
- gameOverDetail: Wt,
581
- restartBtn: Ht,
582
- chaosBar: Ut,
583
- chaosBarLabel: Yt,
584
- chaosBarTrack: zt,
585
- chaosBarFill: Qt,
586
- difficultySelector: Kt,
587
- difficultyLabel: Xt,
588
- difficultySlider: Jt,
589
- difficultyValue: Zt,
590
- sidePickerOverlay: en,
591
- sidePickerCard: tn,
592
- sidePickerTitle: nn,
593
- sidePickerOptions: sn,
594
- sidePickerBtn: rn,
595
- sidePickerIcon: on,
596
- sidePickerWhite: an,
597
- sidePickerBlack: cn,
598
- sidePickerLabel: ln,
599
- sidePickerSettings: un,
600
- stupidLevel: dn,
601
- stupidLevelHeader: hn,
602
- stupidLevelLabel: mn,
603
- stupidLevelValue: pn,
604
- stupidLevelSlider: fn,
605
- muteBtn: vn,
606
- muteBtnMuted: _n,
607
- chaosToast: gn,
608
- chaosToastFading: kn
609
- }, yn = [
835
+ }), En = "_promotionOverlay_eh63o_2", In = "_promotionDialog_eh63o_14", qn = "_promotionTitle_eh63o_27", Fn = "_promotionOptions_eh63o_34", jn = "_promotionBtn_eh63o_39", xn = "_gameOverOverlay_eh63o_66", $n = "_gameOverBanner_eh63o_78", Dn = "_gameOverResult_eh63o_91", Gn = "_gameOverDetail_eh63o_100", zn = "_restartBtn_eh63o_107", Un = "_chaosBar_eh63o_126", Vn = "_chaosBarLabel_eh63o_134", Hn = "_chaosBarTrack_eh63o_143", Wn = "_chaosBarFill_eh63o_151", Yn = "_difficultySelector_eh63o_160", Kn = "_difficultyLabel_eh63o_167", Xn = "_difficultySlider_eh63o_176", Qn = "_difficultyValue_eh63o_207", Jn = "_sidePickerOverlay_eh63o_214", Zn = "_sidePickerCard_eh63o_222", er = "_sidePickerTitle_eh63o_235", tr = "_sidePickerOptions_eh63o_243", nr = "_sidePickerBtn_eh63o_248", rr = "_sidePickerIcon_eh63o_268", or = "_sidePickerLabel_eh63o_278", ir = "_sidePickerSettings_eh63o_285", sr = "_stupidLevel_eh63o_294", ar = "_stupidLevelHeader_eh63o_301", cr = "_stupidLevelLabel_eh63o_307", lr = "_stupidLevelValue_eh63o_316", ur = "_stupidLevelSlider_eh63o_323", dr = "_muteBtn_eh63o_355", hr = "_muteBtnMuted_eh63o_380", fr = "_chaosToast_eh63o_390", pr = "_chaosToastFading_eh63o_410", u = {
836
+ promotionOverlay: En,
837
+ promotionDialog: In,
838
+ promotionTitle: qn,
839
+ promotionOptions: Fn,
840
+ promotionBtn: jn,
841
+ gameOverOverlay: xn,
842
+ gameOverBanner: $n,
843
+ gameOverResult: Dn,
844
+ gameOverDetail: Gn,
845
+ restartBtn: zn,
846
+ chaosBar: Un,
847
+ chaosBarLabel: Vn,
848
+ chaosBarTrack: Hn,
849
+ chaosBarFill: Wn,
850
+ difficultySelector: Yn,
851
+ difficultyLabel: Kn,
852
+ difficultySlider: Xn,
853
+ difficultyValue: Qn,
854
+ sidePickerOverlay: Jn,
855
+ sidePickerCard: Zn,
856
+ sidePickerTitle: er,
857
+ sidePickerOptions: tr,
858
+ sidePickerBtn: nr,
859
+ sidePickerIcon: rr,
860
+ sidePickerLabel: or,
861
+ sidePickerSettings: ir,
862
+ stupidLevel: sr,
863
+ stupidLevelHeader: ar,
864
+ stupidLevelLabel: cr,
865
+ stupidLevelValue: lr,
866
+ stupidLevelSlider: ur,
867
+ muteBtn: dr,
868
+ muteBtnMuted: hr,
869
+ chaosToast: fr,
870
+ chaosToastFading: pr
871
+ }, mr = [
610
872
  { type: "q", label: "Queen" },
611
873
  { type: "r", label: "Rook" },
612
874
  { type: "b", label: "Bishop" },
613
875
  { type: "n", label: "Knight" }
614
876
  ];
615
- function wn({ color: t, onSelect: e }) {
616
- return /* @__PURE__ */ a("div", { className: u.promotionOverlay, children: /* @__PURE__ */ C("div", { className: u.promotionDialog, children: [
617
- /* @__PURE__ */ a("h3", { className: u.promotionTitle, children: "Promote pawn" }),
618
- /* @__PURE__ */ a("div", { className: u.promotionOptions, children: yn.map(({ type: n, label: s }) => /* @__PURE__ */ a(
877
+ function vr({ color: t, onSelect: e }) {
878
+ return /* @__PURE__ */ l("div", { className: u.promotionOverlay, children: /* @__PURE__ */ L("div", { className: u.promotionDialog, children: [
879
+ /* @__PURE__ */ l("h3", { className: u.promotionTitle, children: "Promote pawn" }),
880
+ /* @__PURE__ */ l("div", { className: u.promotionOptions, children: mr.map(({ type: n, label: r }) => /* @__PURE__ */ l(
619
881
  "button",
620
882
  {
883
+ type: "button",
621
884
  className: u.promotionBtn,
622
885
  onClick: () => e(n),
623
- title: s,
624
- children: /* @__PURE__ */ a(De, { type: n, color: t })
886
+ title: r,
887
+ children: /* @__PURE__ */ l(we, { type: n, color: t })
625
888
  },
626
889
  n
627
890
  )) })
628
891
  ] }) });
629
892
  }
630
- function Cn(t, e) {
631
- return t.result === "checkmate" ? t.winner === e ? { title: "You Win!", detail: "Checkmate" } : { title: "You Lose", detail: "Checkmate" } : t.result === "stalemate" ? { title: "Draw", detail: "Stalemate" } : t.result === "insufficient" ? { title: "Draw", detail: "Insufficient material" } : t.result === "threefold" ? { title: "Draw", detail: "Threefold repetition" } : { title: "Draw", detail: "Game over" };
893
+ function kr(t, e) {
894
+ return t.result === "checkmate" ? t.winner === e ? { title: "You Win!", detail: "Checkmate" } : { title: "You Lose", detail: "Checkmate" } : t.result === "stalemate" ? { title: "Draw", detail: "Stalemate" } : t.result === "insufficient" ? { title: "Draw", detail: "Insufficient material" } : t.result === "threefold" ? { title: "Draw", detail: "Threefold repetition" } : t.result === "fifty-move" ? { title: "Draw", detail: "Fifty-move rule" } : t.result === "king-captured" ? { title: t.winner === e ? "You Win!" : "You Lose", detail: "King captured" } : { title: "Draw", detail: "Game over" };
632
895
  }
633
- function bn({ status: t, humanColor: e, onRestart: n }) {
634
- const { title: s, detail: o } = Cn(t, e);
635
- return /* @__PURE__ */ a("div", { className: u.gameOverOverlay, children: /* @__PURE__ */ C("div", { className: u.gameOverBanner, children: [
636
- /* @__PURE__ */ a("h2", { className: u.gameOverResult, children: s }),
637
- /* @__PURE__ */ a("p", { className: u.gameOverDetail, children: o }),
638
- /* @__PURE__ */ a("button", { className: u.restartBtn, onClick: n, children: "Play Again" })
896
+ function gr({ status: t, humanColor: e, onRestart: n }) {
897
+ const { title: r, detail: o } = kr(t, e);
898
+ return /* @__PURE__ */ l("div", { className: u.gameOverOverlay, children: /* @__PURE__ */ L("div", { className: u.gameOverBanner, children: [
899
+ /* @__PURE__ */ l("h2", { className: u.gameOverResult, children: r }),
900
+ /* @__PURE__ */ l("p", { className: u.gameOverDetail, children: o }),
901
+ /* @__PURE__ */ l("button", { type: "button", className: u.restartBtn, onClick: n, children: "Play Again" })
639
902
  ] }) });
640
903
  }
641
- function Tn({ countdown: t, maxCountdown: e }) {
642
- const n = e > 0 ? (e - t) / e * 100 : 0, s = 1 - (t / e || 0);
643
- return /* @__PURE__ */ C("div", { className: u.chaosBar, children: [
644
- /* @__PURE__ */ a("span", { className: u.chaosBarLabel, children: "STUPIDITY" }),
645
- /* @__PURE__ */ a("div", { className: u.chaosBarTrack, children: /* @__PURE__ */ a(
904
+ function yr({ countdown: t, maxCountdown: e }) {
905
+ const n = e > 0 ? (e - t) / e * 100 : 0, r = 1 - (t / e || 0);
906
+ return /* @__PURE__ */ L("div", { className: u.chaosBar, children: [
907
+ /* @__PURE__ */ l("span", { className: u.chaosBarLabel, children: "STUPIDITY" }),
908
+ /* @__PURE__ */ l("div", { className: u.chaosBarTrack, children: /* @__PURE__ */ l(
646
909
  "div",
647
910
  {
648
911
  className: u.chaosBarFill,
649
912
  style: {
650
913
  width: `${n}%`,
651
- "--glow": s
914
+ "--glow": r
652
915
  }
653
916
  }
654
917
  ) })
655
918
  ] });
656
919
  }
657
- function Ln({ action: t }) {
658
- const [e, n] = d(!1), [s, o] = d(!1), [r, c] = d(null), i = y(void 0);
659
- if (F(() => {
920
+ function _r({ action: t }) {
921
+ const [e, n] = k(!1), [r, o] = k(!1), [i, a] = k(null), s = w(void 0);
922
+ if (O(() => {
660
923
  if (t)
661
- return i.current && clearTimeout(i.current), c(t), o(!1), n(!0), i.current = setTimeout(() => {
662
- o(!0), i.current = setTimeout(() => {
924
+ return s.current && clearTimeout(s.current), a(t), o(!1), n(!0), s.current = setTimeout(() => {
925
+ o(!0), s.current = setTimeout(() => {
663
926
  n(!1), o(!1);
664
927
  }, 400);
665
928
  }, 1600), () => {
666
- i.current && clearTimeout(i.current);
929
+ s.current && clearTimeout(s.current);
667
930
  };
668
- }, [t]), !e || !r) return null;
669
- const l = r.type === "add" && r.piece && r.color ? `A ${ie[`${r.color}${r.piece}`]} appeared on ${r.square}!` : `The piece on ${r.square} vanished!`;
670
- return /* @__PURE__ */ a("div", { className: `${u.chaosToast} ${s ? u.chaosToastFading : ""}`, children: l });
931
+ }, [t]), !e || !i) return null;
932
+ const c = i.type === "add" && i.piece && i.color ? `A ${mt(i.piece, i.color)} appeared on ${i.square}!` : `The piece on ${i.square} vanished!`;
933
+ return /* @__PURE__ */ l("div", { className: `${u.chaosToast} ${r ? u.chaosToastFading : ""}`, children: c });
671
934
  }
672
- function xe({ depth: t, onChange: e }) {
673
- return /* @__PURE__ */ C("div", { className: u.difficultySelector, children: [
674
- /* @__PURE__ */ C("span", { className: u.difficultyLabel, children: [
935
+ function kt({ depth: t, onChange: e }) {
936
+ return /* @__PURE__ */ L("div", { className: u.difficultySelector, children: [
937
+ /* @__PURE__ */ L("span", { className: u.difficultyLabel, children: [
675
938
  "AI Depth: ",
676
- /* @__PURE__ */ a("span", { className: u.difficultyValue, children: t })
939
+ /* @__PURE__ */ l("span", { className: u.difficultyValue, children: t })
677
940
  ] }),
678
- /* @__PURE__ */ a(
941
+ /* @__PURE__ */ l(
679
942
  "input",
680
943
  {
681
944
  className: u.difficultySlider,
@@ -688,14 +951,14 @@ function xe({ depth: t, onChange: e }) {
688
951
  )
689
952
  ] });
690
953
  }
691
- const Pn = ["OFF", "CHILL", "MID", "STUPID", "CHAOS", "LOL"];
692
- function Ge({ level: t, onChange: e }) {
693
- return /* @__PURE__ */ C("div", { className: u.stupidLevel, children: [
694
- /* @__PURE__ */ C("div", { className: u.stupidLevelHeader, children: [
695
- /* @__PURE__ */ a("span", { className: u.stupidLevelLabel, children: "STUPID" }),
696
- /* @__PURE__ */ a("span", { className: u.stupidLevelValue, children: Pn[t] })
954
+ const wr = ["OFF", "CHILL", "MID", "STUPID", "CHAOS", "LOL"];
955
+ function gt({ level: t, onChange: e }) {
956
+ return /* @__PURE__ */ L("div", { className: u.stupidLevel, children: [
957
+ /* @__PURE__ */ L("div", { className: u.stupidLevelHeader, children: [
958
+ /* @__PURE__ */ l("span", { className: u.stupidLevelLabel, children: "Stupid level" }),
959
+ /* @__PURE__ */ l("span", { className: u.stupidLevelValue, children: wr[t] })
697
960
  ] }),
698
- /* @__PURE__ */ a(
961
+ /* @__PURE__ */ l(
699
962
  "input",
700
963
  {
701
964
  type: "range",
@@ -709,274 +972,382 @@ function Ge({ level: t, onChange: e }) {
709
972
  )
710
973
  ] });
711
974
  }
712
- function Mn({ depth: t, onDepthChange: e, stupidLevel: n, onStupidLevelChange: s, onSelectSide: o }) {
713
- return /* @__PURE__ */ a("div", { className: u.sidePickerOverlay, children: /* @__PURE__ */ C("div", { className: u.sidePickerCard, children: [
714
- /* @__PURE__ */ a("h2", { className: u.sidePickerTitle, children: "Choose Your Side" }),
715
- /* @__PURE__ */ C("div", { className: u.sidePickerOptions, children: [
716
- /* @__PURE__ */ C(
975
+ function Cr({ depth: t, onDepthChange: e, stupidLevel: n, onStupidLevelChange: r, onSelectSide: o }) {
976
+ return /* @__PURE__ */ l("div", { className: u.sidePickerOverlay, children: /* @__PURE__ */ L("div", { className: u.sidePickerCard, children: [
977
+ /* @__PURE__ */ l("h2", { className: u.sidePickerTitle, children: "Choose Your Side" }),
978
+ /* @__PURE__ */ L("div", { className: u.sidePickerOptions, children: [
979
+ /* @__PURE__ */ L(
717
980
  "button",
718
981
  {
982
+ type: "button",
719
983
  className: u.sidePickerBtn,
720
984
  onClick: () => o("w"),
721
985
  children: [
722
- /* @__PURE__ */ a("span", { className: `${u.sidePickerIcon} ${u.sidePickerWhite}`, children: ie.wk }),
723
- /* @__PURE__ */ a("span", { className: u.sidePickerLabel, children: "White" })
986
+ /* @__PURE__ */ l(we, { type: "k", color: "w", className: u.sidePickerIcon }),
987
+ /* @__PURE__ */ l("span", { className: u.sidePickerLabel, children: "White" })
724
988
  ]
725
989
  }
726
990
  ),
727
- /* @__PURE__ */ C(
991
+ /* @__PURE__ */ L(
728
992
  "button",
729
993
  {
994
+ type: "button",
730
995
  className: u.sidePickerBtn,
731
996
  onClick: () => o("b"),
732
997
  children: [
733
- /* @__PURE__ */ a("span", { className: `${u.sidePickerIcon} ${u.sidePickerBlack}`, children: ie.bk }),
734
- /* @__PURE__ */ a("span", { className: u.sidePickerLabel, children: "Black" })
998
+ /* @__PURE__ */ l(we, { type: "k", color: "b", className: u.sidePickerIcon }),
999
+ /* @__PURE__ */ l("span", { className: u.sidePickerLabel, children: "Black" })
735
1000
  ]
736
1001
  }
737
1002
  )
738
1003
  ] }),
739
- /* @__PURE__ */ C("div", { className: u.sidePickerSettings, children: [
740
- /* @__PURE__ */ a(xe, { depth: t, onChange: e }),
741
- /* @__PURE__ */ a(Ge, { level: n, onChange: s })
1004
+ /* @__PURE__ */ L("div", { className: u.sidePickerSettings, children: [
1005
+ /* @__PURE__ */ l(kt, { depth: t, onChange: e }),
1006
+ /* @__PURE__ */ l(gt, { level: n, onChange: r })
742
1007
  ] })
743
1008
  ] }) });
744
1009
  }
745
- function Sn({ muted: t, onToggle: e }) {
746
- return /* @__PURE__ */ a(
1010
+ function br({ muted: t, onToggle: e }) {
1011
+ const n = t ? "Unmute" : "Mute";
1012
+ return /* @__PURE__ */ l(
747
1013
  "button",
748
1014
  {
1015
+ type: "button",
749
1016
  className: `${u.muteBtn} ${t ? u.muteBtnMuted : ""}`,
750
1017
  onClick: e,
751
- title: t ? "Unmute" : "Mute",
752
- children: t ? "🔇" : "🔊"
1018
+ title: n,
1019
+ "aria-label": n,
1020
+ "aria-pressed": t,
1021
+ children: /* @__PURE__ */ L(
1022
+ "svg",
1023
+ {
1024
+ viewBox: "0 0 24 24",
1025
+ width: "16",
1026
+ height: "16",
1027
+ fill: "none",
1028
+ stroke: "currentColor",
1029
+ strokeWidth: "2",
1030
+ strokeLinecap: "round",
1031
+ strokeLinejoin: "round",
1032
+ "aria-hidden": "true",
1033
+ children: [
1034
+ /* @__PURE__ */ l("path", { d: "M11 5 6 9H3v6h3l5 4V5z" }),
1035
+ t ? /* @__PURE__ */ l("path", { d: "m22 9-6 6M16 9l6 6" }) : /* @__PURE__ */ l("path", { d: "M15.5 8.5a5 5 0 0 1 0 7M18.5 5.5a9 9 0 0 1 0 13" })
1036
+ ]
1037
+ }
1038
+ )
753
1039
  }
754
1040
  );
755
1041
  }
756
- class Bn {
757
- ctx = null;
758
- muted = !1;
1042
+ let se = null;
1043
+ class Lr {
1044
+ muted;
1045
+ constructor(e = !1) {
1046
+ this.muted = e;
1047
+ }
759
1048
  getCtx() {
760
1049
  if (this.muted) return null;
761
- if (!this.ctx)
1050
+ if (!se)
762
1051
  try {
763
- this.ctx = new AudioContext();
1052
+ se = new AudioContext();
764
1053
  } catch {
765
1054
  return null;
766
1055
  }
767
- return this.ctx.state === "suspended" && this.ctx.resume(), this.ctx;
1056
+ return se.state === "suspended" && se.resume(), se;
768
1057
  }
769
1058
  setMuted(e) {
770
1059
  this.muted = e;
771
1060
  }
1061
+ get isMuted() {
1062
+ return this.muted;
1063
+ }
772
1064
  playMove() {
773
1065
  const e = this.getCtx();
774
1066
  if (!e) return;
775
- const n = e.createOscillator(), s = e.createGain();
776
- n.type = "sine", n.frequency.value = 200, s.gain.setValueAtTime(0.15, e.currentTime), s.gain.exponentialRampToValueAtTime(1e-3, e.currentTime + 0.08), n.connect(s).connect(e.destination), n.start(), n.stop(e.currentTime + 0.08);
1067
+ const n = e.createOscillator(), r = e.createGain();
1068
+ n.type = "sine", n.frequency.value = 200, r.gain.setValueAtTime(0.15, e.currentTime), r.gain.exponentialRampToValueAtTime(1e-3, e.currentTime + 0.08), n.connect(r).connect(e.destination), n.start(), n.stop(e.currentTime + 0.08);
777
1069
  }
778
1070
  playCapture() {
779
1071
  const e = this.getCtx();
780
1072
  if (!e) return;
781
- const n = e.sampleRate * 0.1, s = e.createBuffer(1, n, e.sampleRate), o = s.getChannelData(0);
782
- for (let l = 0; l < n; l++)
783
- o[l] = (Math.random() * 2 - 1) * Math.exp(-l / (e.sampleRate * 0.015));
784
- const r = e.createBufferSource();
785
- r.buffer = s;
786
- const c = e.createBiquadFilter();
787
- c.type = "bandpass", c.frequency.value = 3e3, c.Q.value = 2;
788
- const i = e.createGain();
789
- i.gain.setValueAtTime(0.35, e.currentTime), i.gain.exponentialRampToValueAtTime(1e-3, e.currentTime + 0.1), r.connect(c).connect(i).connect(e.destination), r.start(), r.stop(e.currentTime + 0.1);
1073
+ const n = e.sampleRate * 0.1, r = e.createBuffer(1, n, e.sampleRate), o = r.getChannelData(0);
1074
+ for (let c = 0; c < n; c++)
1075
+ o[c] = (Math.random() * 2 - 1) * Math.exp(-c / (e.sampleRate * 0.015));
1076
+ const i = e.createBufferSource();
1077
+ i.buffer = r;
1078
+ const a = e.createBiquadFilter();
1079
+ a.type = "bandpass", a.frequency.value = 3e3, a.Q.value = 2;
1080
+ const s = e.createGain();
1081
+ s.gain.setValueAtTime(0.35, e.currentTime), s.gain.exponentialRampToValueAtTime(1e-3, e.currentTime + 0.1), i.connect(a).connect(s).connect(e.destination), i.start(), i.stop(e.currentTime + 0.1);
790
1082
  }
791
1083
  playCheck() {
792
1084
  const e = this.getCtx();
793
1085
  if (!e) return;
794
- const n = e.createOscillator(), s = e.createGain();
795
- n.type = "triangle", n.frequency.value = 800, s.gain.setValueAtTime(0.18, e.currentTime), s.gain.exponentialRampToValueAtTime(1e-3, e.currentTime + 0.12), n.connect(s).connect(e.destination), n.start(), n.stop(e.currentTime + 0.12);
1086
+ const n = e.createOscillator(), r = e.createGain();
1087
+ n.type = "triangle", n.frequency.value = 800, r.gain.setValueAtTime(0.18, e.currentTime), r.gain.exponentialRampToValueAtTime(1e-3, e.currentTime + 0.12), n.connect(r).connect(e.destination), n.start(), n.stop(e.currentTime + 0.12);
796
1088
  }
797
1089
  playChaos() {
798
1090
  const e = this.getCtx();
799
1091
  if (!e) return;
800
- const n = e.createOscillator(), s = e.createGain();
801
- n.type = "sine", n.frequency.setValueAtTime(520, e.currentTime), n.frequency.exponentialRampToValueAtTime(320, e.currentTime + 0.18), s.gain.setValueAtTime(0.07, e.currentTime), s.gain.exponentialRampToValueAtTime(1e-3, e.currentTime + 0.18), n.connect(s).connect(e.destination), n.start(), n.stop(e.currentTime + 0.18);
1092
+ const n = e.createOscillator(), r = e.createGain();
1093
+ n.type = "sine", n.frequency.setValueAtTime(520, e.currentTime), n.frequency.exponentialRampToValueAtTime(320, e.currentTime + 0.18), r.gain.setValueAtTime(0.07, e.currentTime), r.gain.exponentialRampToValueAtTime(1e-3, e.currentTime + 0.18), n.connect(r).connect(e.destination), n.start(), n.stop(e.currentTime + 0.18);
802
1094
  }
803
1095
  playGameOver() {
804
1096
  const e = this.getCtx();
805
1097
  if (!e) return;
806
1098
  const n = [261.63, 329.63, 392];
807
- for (const s of n) {
808
- const o = e.createOscillator(), r = e.createGain();
809
- o.type = "sine", o.frequency.value = s, r.gain.setValueAtTime(0.1, e.currentTime), r.gain.exponentialRampToValueAtTime(1e-3, e.currentTime + 0.4), o.connect(r).connect(e.destination), o.start(), o.stop(e.currentTime + 0.4);
1099
+ for (const r of n) {
1100
+ const o = e.createOscillator(), i = e.createGain();
1101
+ o.type = "sine", o.frequency.value = r, i.gain.setValueAtTime(0.1, e.currentTime), i.gain.exponentialRampToValueAtTime(1e-3, e.currentTime + 0.4), o.connect(i).connect(e.destination), o.start(), o.stop(e.currentTime + 0.4);
810
1102
  }
811
1103
  }
812
1104
  }
813
- const Y = new Bn(), On = "_container_hob8y_1", Nn = "_topBar_hob8y_11", Rn = "_topBarLeft_hob8y_19", In = "_statusText_hob8y_25", qn = "_thinking_hob8y_31", Fn = "_bottomBar_hob8y_41", z = {
814
- container: On,
815
- topBar: Nn,
816
- topBarLeft: Rn,
817
- statusText: In,
818
- thinking: qn,
819
- bottomBar: Fn
820
- };
821
- function An(t) {
1105
+ function be(t) {
1106
+ return typeof t == "number" && Number.isFinite(t);
1107
+ }
1108
+ function Mr(t) {
1109
+ return be(t) ? Math.min(20, Math.max(1, Math.round(t))) : 10;
1110
+ }
1111
+ function Sr(t) {
1112
+ return be(t) ? Math.min(5, Math.max(0, Math.round(t))) : 3;
1113
+ }
1114
+ function Tr(t) {
1115
+ if (!t || typeof t != "object") return null;
1116
+ const e = t;
1117
+ if (e.version !== 1 || e.phase !== "setup" && e.phase !== "playing" || e.humanColor !== "w" && e.humanColor !== "b" || !be(e.depth) || !be(e.stupidLevel) || typeof e.fen != "string") return null;
1118
+ let n;
1119
+ try {
1120
+ n = W(e.fen);
1121
+ } catch {
1122
+ return null;
1123
+ }
1124
+ return he(n) ? {
1125
+ version: 1,
1126
+ phase: e.phase,
1127
+ fen: n,
1128
+ humanColor: e.humanColor,
1129
+ depth: Mr(e.depth),
1130
+ stupidLevel: Sr(e.stupidLevel),
1131
+ muted: e.muted === !0
1132
+ } : null;
1133
+ }
1134
+ const Pr = "_container_25ulv_1", Br = "_topBar_25ulv_11", Or = "_topBarLeft_25ulv_23", Rr = "_topBarRight_25ulv_29", Nr = "_newGameBtn_25ulv_35", Ar = "_aiUnavailable_25ulv_59", Er = "_statusText_25ulv_65", Ir = "_thinking_25ulv_71", qr = "_bottomBar_25ulv_81", H = {
1135
+ container: Pr,
1136
+ topBar: Br,
1137
+ topBarLeft: Or,
1138
+ topBarRight: Rr,
1139
+ newGameBtn: Nr,
1140
+ aiUnavailable: Ar,
1141
+ statusText: Er,
1142
+ thinking: Ir,
1143
+ bottomBar: qr
1144
+ }, it = 2;
1145
+ function $r(t) {
822
1146
  const {
823
1147
  defaultDepth: e = 10,
824
1148
  defaultStupidLevel: n = 3,
825
- defaultHumanColor: s,
1149
+ defaultHumanColor: r,
826
1150
  defaultMuted: o = !1,
827
- depth: r,
828
- onDepthChange: c,
829
- stupidLevel: i,
830
- onStupidLevelChange: l,
831
- stockfishWorkerPath: w,
832
- skipSetup: f = !1,
833
- showControls: _ = !0,
834
- showMuteButton: P = !0,
835
- onGameOver: g,
836
- onMove: v,
837
- onChaosAction: k,
838
- onRestart: R,
839
- className: $
840
- } = t, [I, x] = d(e), b = r ?? I, h = c ?? x, [D, le] = d(n), W = i ?? D, Z = l ?? le, [ue, T] = d(s ?? "w"), m = ue, [M, H] = d(o), [q, S] = d(
841
- f || s ? "playing" : "setup"
842
- ), {
843
- fen: L,
844
- turn: Q,
845
- selectedSquare: Ae,
846
- legalMoves: Ee,
847
- gameStatus: B,
848
- promotionPending: ve,
849
- lastMove: Ve,
850
- lastMoveDetail: ee,
851
- moveHistory: G,
852
- board: je,
853
- handleSquareClick: _e,
854
- handlePromotion: We,
855
- applyFen: te,
856
- handleRestart: ge
857
- } = et(), { isReady: K, isThinking: A, getBestMove: ne } = nt(w), se = K, E = Q === m, ke = W > 0, He = q !== "playing" || !ke || !E || A || !!ve || B.isGameOver, { countdown: Ue, maxCountdown: Ye, lastAction: V, chaosSquare: de } = ft({
858
- fen: L,
859
- isPaused: He,
860
- stupidLevel: Math.max(1, W),
861
- onChaosAction: N((p) => {
862
- const j = new oe(he.current);
863
- j.turn() === we.current && (j.isGameOver() || te(p));
864
- }, [te])
865
- }), ye = y(V);
866
- F(() => {
867
- V && V !== ye.current && k?.(V, L), ye.current = V;
868
- }, [V, L, k]);
869
- const he = y(L);
870
- he.current = L;
871
- const we = y(m);
872
- we.current = m;
873
- const U = y(null), re = N((p) => {
874
- const j = p.slice(0, 2), Je = p.slice(2, 4), Le = p.length > 4 ? p[4] : void 0;
875
- try {
876
- const Pe = new oe(he.current), Me = { from: j, to: Je };
877
- Le && (Me.promotion = Le), Pe.move(Me) ? te(Pe.fen()) : console.warn("[ChaosChess] Stockfish move invalid for current position, will retry");
878
- } catch {
879
- console.warn("[ChaosChess] Stockfish move threw, will retry");
880
- }
881
- }, [te]), ze = N((p) => {
882
- T(p), S("playing");
883
- }, []), Qe = N(() => {
884
- ge(), S(f || s ? "playing" : "setup"), R?.();
885
- }, [ge, f, s, R]);
886
- F(() => {
887
- Y.setMuted(M);
888
- }, [M]);
889
- const Ce = y(G.length);
890
- F(() => {
891
- if (G.length > Ce.current) {
892
- ee && (ee.check ? Y.playCheck() : ee.captured ? Y.playCapture() : Y.playMove());
893
- const p = G[G.length - 1];
894
- p && v?.(p.fen, p.san, p.color);
1151
+ depth: i,
1152
+ onDepthChange: a,
1153
+ stupidLevel: s,
1154
+ onStupidLevelChange: c,
1155
+ stockfishWorkerPath: m,
1156
+ skipSetup: y = !1,
1157
+ showControls: g = !0,
1158
+ showMuteButton: _ = !0,
1159
+ initialState: d,
1160
+ onStateChange: v,
1161
+ onGameOver: C,
1162
+ onMove: x,
1163
+ onChaosAction: R,
1164
+ onRestart: q,
1165
+ className: G
1166
+ } = t, [B] = k(() => {
1167
+ if (!d) return null;
1168
+ const h = Tr(d);
1169
+ return h || console.warn("[ChaosChess] Ignoring invalid initialState"), h;
1170
+ }), [$, ne] = k(B?.depth ?? e), p = i ?? $, M = a ?? ne, [F, re] = k(B?.stupidLevel ?? n), I = s ?? F, fe = c ?? re, [Me, Se] = k(
1171
+ B?.humanColor ?? r ?? "w"
1172
+ ), f = Me, [b, z] = k(B?.muted ?? o), [P] = k(() => new Lr(B?.muted ?? o)), [T, X] = k(
1173
+ B?.phase ?? (y || r ? "playing" : "setup")
1174
+ ), [yt, _t] = k(0), {
1175
+ fen: N,
1176
+ turn: oe,
1177
+ selectedSquare: wt,
1178
+ legalMoves: Ct,
1179
+ gameStatus: A,
1180
+ promotionPending: Fe,
1181
+ lastMove: bt,
1182
+ lastMoveDetail: pe,
1183
+ moveHistory: Q,
1184
+ board: Lt,
1185
+ handleSquareClick: je,
1186
+ handlePromotion: Mt,
1187
+ applyFen: xe,
1188
+ applyMove: $e,
1189
+ handleRestart: De
1190
+ } = Gt(B?.fen), {
1191
+ status: Te,
1192
+ isReady: me,
1193
+ isThinking: J,
1194
+ getBestMove: Ge,
1195
+ cancel: ze
1196
+ } = Jt(m), ve = Te !== "failed", Z = oe === f, ke = w(N), Ue = w(f), Pe = w(T);
1197
+ st(() => {
1198
+ ke.current = N, Ue.current = f, Pe.current = T;
1199
+ }, [N, f, T]);
1200
+ const Be = w(0), Ve = I > 0, St = T !== "playing" || !Ve || !Z || J || !!Fe || A.isGameOver, { countdown: Tt, maxCountdown: Pt, lastAction: ee, chaosSquare: Oe } = un({
1201
+ fen: N,
1202
+ isPaused: St,
1203
+ stupidLevel: Math.max(1, I),
1204
+ resetKey: yt,
1205
+ onChaosAction: S((h) => {
1206
+ const j = new de(ke.current);
1207
+ if (j.turn() !== Ue.current || ue(j).isGameOver) return !1;
1208
+ const U = W(h);
1209
+ return he(U) ? (xe(U), !0) : !1;
1210
+ }, [xe])
1211
+ }), He = w(ee);
1212
+ O(() => {
1213
+ ee && ee !== He.current && R?.(ee, N), He.current = ee;
1214
+ }, [ee, N, R]);
1215
+ const We = w(v);
1216
+ O(() => {
1217
+ We.current = v;
1218
+ }, [v]), O(() => {
1219
+ const h = {
1220
+ version: 1,
1221
+ phase: T,
1222
+ fen: N,
1223
+ humanColor: f,
1224
+ depth: p,
1225
+ stupidLevel: I,
1226
+ muted: b
1227
+ };
1228
+ We.current?.(h);
1229
+ }, [T, N, f, p, I, b]);
1230
+ const ie = w(null), ge = w({ fen: "", count: 0 }), ye = S((h, j) => $e(
1231
+ {
1232
+ from: j.slice(0, 2),
1233
+ to: j.slice(2, 4),
1234
+ promotion: j.length > 4 ? j[4] : void 0
1235
+ },
1236
+ h
1237
+ ), [$e]), Ye = S((h, j) => {
1238
+ if (ke.current !== h || Pe.current !== "playing") return !0;
1239
+ const U = new de(h);
1240
+ if (ue(U).isGameOver) return !1;
1241
+ const V = U.moves({ verbose: !0 });
1242
+ if (V.length === 0) return !1;
1243
+ const te = V[Math.floor(Math.random() * V.length)];
1244
+ return console.warn(`[ChaosChess] ${j}; playing random move ${te.lan}`), ye(h, te.lan);
1245
+ }, [ye]), _e = S((h) => {
1246
+ const j = Be.current, U = () => Be.current !== j || Pe.current !== "playing", V = (D) => {
1247
+ U() || Ye(h, D) || (ie.current = h);
1248
+ };
1249
+ if (!he(W(h))) {
1250
+ V("Position not supported by Stockfish");
1251
+ return;
895
1252
  }
896
- Ce.current = G.length;
897
- }, [G.length, ee, G, v]), F(() => {
898
- de && Y.playChaos();
899
- }, [de]);
900
- const be = y(!1);
901
- F(() => {
902
- B.isGameOver && !be.current && (Y.playGameOver(), g?.(B)), be.current = B.isGameOver;
903
- }, [B, g]);
904
- const me = y(!1);
905
- F(() => {
906
- if (q !== "playing") {
907
- me.current = !1;
1253
+ const te = ge.current.fen === h ? ge.current.count : 0;
1254
+ if (te >= it) {
1255
+ V("Stockfish keeps failing on this position");
908
1256
  return;
909
1257
  }
910
- E || B.isGameOver || !K || A || U.current !== L && (m === "b" && !me.current && (me.current = !0), ne(L, b).then((p) => {
911
- if (!p) {
912
- U.current = L;
913
- return;
914
- }
915
- U.current = null, re(p);
916
- }).catch(() => {
917
- }));
918
- }, [q, L, E, B.isGameOver, K, A, m, ne, b, re]), F(() => {
919
- if (q !== "playing" || E || A || B.isGameOver || !K || U.current === L) return;
920
- const p = setTimeout(() => {
921
- ne(L, b).then((j) => {
922
- if (!j) {
923
- U.current = L;
1258
+ const Nt = te > 0 ? Math.max(1, Math.floor(p / 2)) : p;
1259
+ Ge(h, Nt).then((D) => {
1260
+ if (!U() && ke.current === h) {
1261
+ if (!D) {
1262
+ V("Stockfish returned no move");
924
1263
  return;
925
1264
  }
926
- U.current = null, re(j);
927
- }).catch(() => {
928
- });
929
- }, 3e3);
930
- return () => clearTimeout(p);
931
- }, [q, E, A, B.isGameOver, K, L, b, ne, re]);
932
- const Ke = N(
933
- (p) => {
934
- se && Q !== m || _e(p);
1265
+ ie.current = null, ye(h, D) || V(`Stockfish move ${D} is not legal here`);
1266
+ }
1267
+ }).catch((D) => {
1268
+ U() || D instanceof ae || D instanceof Ne || (ge.current = { fen: h, count: te + 1 }, te + 1 >= it && V(`Stockfish failed (${D?.message ?? D})`));
1269
+ });
1270
+ }, [Ge, p, ye, Ye]), Bt = S((h) => {
1271
+ Se(h), X("playing");
1272
+ }, []), Ke = S(() => {
1273
+ Be.current++, ze(), De(), ie.current = null, ge.current = { fen: "", count: 0 }, _t((h) => h + 1), X(y || r ? "playing" : "setup"), q?.();
1274
+ }, [De, ze, y, r, q]);
1275
+ O(() => {
1276
+ P.setMuted(b);
1277
+ }, [P, b]);
1278
+ const Xe = w(Q.length);
1279
+ O(() => {
1280
+ if (Q.length > Xe.current) {
1281
+ pe && (pe.check ? P.playCheck() : pe.captured ? P.playCapture() : P.playMove());
1282
+ const h = Q[Q.length - 1];
1283
+ h && x?.(h.fen, h.san, h.color);
1284
+ }
1285
+ Xe.current = Q.length;
1286
+ }, [Q.length, pe, Q, x, P]), O(() => {
1287
+ Oe && P.playChaos();
1288
+ }, [Oe, P]);
1289
+ const Qe = w(A.isGameOver);
1290
+ O(() => {
1291
+ A.isGameOver && !Qe.current && (P.playGameOver(), C?.(A)), Qe.current = A.isGameOver;
1292
+ }, [A, C, P]), O(() => {
1293
+ T === "playing" && (Z || A.isGameOver || !me || J || ie.current !== N && _e(N));
1294
+ }, [T, N, Z, A.isGameOver, me, J, _e]), O(() => {
1295
+ if (T !== "playing" || Z || J || A.isGameOver || !me || ie.current === N) return;
1296
+ const h = setTimeout(() => _e(N), 3e3);
1297
+ return () => clearTimeout(h);
1298
+ }, [T, Z, J, A.isGameOver, me, N, _e]);
1299
+ const Ot = S(
1300
+ (h) => {
1301
+ ve && oe !== f || je(h);
935
1302
  },
936
- [se, Q, m, _e]
937
- ), Xe = B.isGameOver ? "Game Over" : A ? "" : se ? E ? "Your turn" : "Opponent thinking..." : `${Q === "w" ? "White" : "Black"} to move`, Te = [z.container, $].filter(Boolean).join(" ");
938
- return q === "setup" ? /* @__PURE__ */ a("div", { className: Te, "data-chaos-chess": "", children: /* @__PURE__ */ a(
939
- Mn,
1303
+ [ve, oe, f, je]
1304
+ ), Rt = A.isGameOver ? "Game Over" : J ? "" : ve ? Z ? "Your turn" : Te === "loading" ? "Loading engine..." : "Opponent thinking..." : `${oe === "w" ? "White" : "Black"} to move`, Je = [H.container, G].filter(Boolean).join(" ");
1305
+ return T === "setup" ? /* @__PURE__ */ l("div", { className: Je, "data-chaos-chess": "", children: /* @__PURE__ */ l(
1306
+ Cr,
940
1307
  {
941
- depth: b,
942
- onDepthChange: h,
943
- stupidLevel: W,
944
- onStupidLevelChange: Z,
945
- onSelectSide: ze
1308
+ depth: p,
1309
+ onDepthChange: M,
1310
+ stupidLevel: I,
1311
+ onStupidLevelChange: fe,
1312
+ onSelectSide: Bt
946
1313
  }
947
- ) }) : /* @__PURE__ */ C("div", { className: Te, "data-chaos-chess": "", children: [
948
- /* @__PURE__ */ C("div", { className: z.topBar, children: [
949
- /* @__PURE__ */ C("div", { className: z.topBarLeft, children: [
950
- /* @__PURE__ */ a("span", { className: z.statusText, children: Xe }),
951
- A && /* @__PURE__ */ a("span", { className: z.thinking, children: "AI thinking..." })
1314
+ ) }) : /* @__PURE__ */ L("div", { className: Je, "data-chaos-chess": "", children: [
1315
+ /* @__PURE__ */ L("div", { className: H.topBar, children: [
1316
+ /* @__PURE__ */ L("div", { className: H.topBarLeft, children: [
1317
+ /* @__PURE__ */ l("span", { className: H.statusText, children: Rt }),
1318
+ J && /* @__PURE__ */ l("span", { className: H.thinking, children: "AI thinking..." }),
1319
+ Te === "failed" && /* @__PURE__ */ l("span", { className: H.aiUnavailable, role: "status", children: "AI unavailable" })
952
1320
  ] }),
953
- P && /* @__PURE__ */ a(Sn, { muted: M, onToggle: () => H((p) => !p) })
1321
+ /* @__PURE__ */ L("div", { className: H.topBarRight, children: [
1322
+ /* @__PURE__ */ l("button", { type: "button", className: H.newGameBtn, onClick: Ke, title: "Start a new game", children: "New game" }),
1323
+ _ && /* @__PURE__ */ l(br, { muted: b, onToggle: () => z((h) => !h) })
1324
+ ] })
954
1325
  ] }),
955
- ke && /* @__PURE__ */ a(Tn, { countdown: Ue, maxCountdown: Ye }),
956
- /* @__PURE__ */ a(
957
- Ft,
1326
+ Ve && /* @__PURE__ */ l(yr, { countdown: Tt, maxCountdown: Pt }),
1327
+ /* @__PURE__ */ l(
1328
+ An,
958
1329
  {
959
- board: je,
960
- selectedSquare: Ae,
961
- legalMoves: Ee,
962
- inCheck: B.inCheck,
963
- lastMove: Ve,
964
- chaosSquare: de,
965
- flipped: m === "b",
966
- locked: se && !E,
967
- onSquareClick: Ke
1330
+ board: Lt,
1331
+ selectedSquare: wt,
1332
+ legalMoves: Ct,
1333
+ inCheck: A.inCheck,
1334
+ lastMove: bt,
1335
+ chaosSquare: Oe,
1336
+ flipped: f === "b",
1337
+ locked: ve && !Z,
1338
+ onSquareClick: Ot
968
1339
  }
969
1340
  ),
970
- _ && /* @__PURE__ */ C("div", { className: z.bottomBar, children: [
971
- /* @__PURE__ */ a(xe, { depth: b, onChange: h }),
972
- /* @__PURE__ */ a(Ge, { level: W, onChange: Z })
1341
+ g && /* @__PURE__ */ L("div", { className: H.bottomBar, children: [
1342
+ /* @__PURE__ */ l(kt, { depth: p, onChange: M }),
1343
+ /* @__PURE__ */ l(gt, { level: I, onChange: fe })
973
1344
  ] }),
974
- /* @__PURE__ */ a(Ln, { action: V }),
975
- ve && /* @__PURE__ */ a(wn, { color: Q, onSelect: We }),
976
- B.isGameOver && /* @__PURE__ */ a(bn, { status: B, humanColor: m, onRestart: Qe })
1345
+ /* @__PURE__ */ l(_r, { action: ee }),
1346
+ Fe && /* @__PURE__ */ l(vr, { color: oe, onSelect: Mt }),
1347
+ A.isGameOver && /* @__PURE__ */ l(gr, { status: A, humanColor: f, onRestart: Ke })
977
1348
  ] });
978
1349
  }
979
1350
  export {
980
- An as ChaosChess
1351
+ $r as ChaosChess
981
1352
  };
982
1353
  //# sourceMappingURL=chaos-chess.js.map